Index: zrignore
===================================================================
--- .bzrignore	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ 	(revision )
@@ -1,2 +1,0 @@
-HelenOS.sparc64.simics
-make_settings
Index: HelenOS.config
===================================================================
--- HelenOS.config	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ HelenOS.config	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -58,4 +58,5 @@
 
 % Machine type
+@ "gta02" GTA02 / Neo FreeRunner
 @ "testarm" GXEmul Testarm
 @ "integratorcp" Integratorcp
@@ -359,6 +360,12 @@
 ! CONFIG_LOG (n/y)
 
+% Kernel function tracing
+! CONFIG_TRACE (n/y)
+
 % Compile kernel tests
 ! CONFIG_TEST (y/n)
+
+% Use link-time optimization
+! [COMPILER=gcc_cross|COMPILER=gcc_native] CONFIG_LTO (n/y)
 
 
@@ -383,5 +390,5 @@
 % Output device class
 @ "generic" Monitor or serial line
-! [PLATFORM=arm32&MACHINE=integratorcp] CONFIG_HID_OUT (choice)
+! [PLATFORM=arm32&(MACHINE=gta02|MACHINE=integratorcp)] CONFIG_HID_OUT (choice)
 
 % Output device class
@@ -431,4 +438,10 @@
 ! [(CONFIG_HID_IN=generic|CONFIG_HID_IN=serial)&PLATFORM=ia64&MACHINE=i460GX] CONFIG_NS16550 (y/n)
 
+% Support for Samsung S3C24XX on-chip UART
+! [(CONFIG_HID_OUT=generic|CONFIG_HID_OUT=serial)&PLATFORM=arm32&MACHINE=gta02] CONFIG_S3C24XX_UART (y/n)
+
+% Support for Samsung S3C24XX on-chip interrupt controller
+! [PLATFORM=arm32&MACHINE=gta02] CONFIG_S3C24XX_IRQC (y)
+
 % Support for Z8530 controller
 ! [(CONFIG_HID_IN=generic|CONFIG_HID_IN=keyboard)&PLATFORM=sparc64&MACHINE=generic] CONFIG_Z8530 (y/n)
@@ -459,5 +472,5 @@
 
 % Serial line input module
-! [CONFIG_DSRLNIN=y|(PLATFORM=ia64&MACHINE=i460GX&CONFIG_NS16550=y)|(PLATFORM=ia64&MACHINE=ski)|(PLATFORM=sparc64&MACHINE=serengeti&CONFIG_SGCN_KBD=y)|(PLATFORM=sparc64&PROCESSOR=sun4v)] CONFIG_SRLN (y)
+! [CONFIG_DSRLNIN=y|(PLATFORM=arm32&MACHINE=gta02)|(PLATFORM=ia64&MACHINE=i460GX&CONFIG_NS16550=y)|(PLATFORM=ia64&MACHINE=ski)|(PLATFORM=sparc64&MACHINE=serengeti&CONFIG_SGCN_KBD=y)|(PLATFORM=sparc64&PROCESSOR=sun4v)] CONFIG_SRLN (y)
 
 % EGA support
@@ -485,4 +498,6 @@
 @ "1152x720"
 @ "1152x864"
+@ "1280x720"
+@ "1280x800"
 @ "1280x960"
 @ "1280x1024"
@@ -519,7 +534,4 @@
 ! CONFIG_WRITE_CORE_FILES (n/y)
 
-% Bundle netif/nil network layer
-! CONFIG_NETIF_NIL_BUNDLE (n/y)
-
 % Strip binaries
 ! CONFIG_STRIP_BINARIES (n/y)
@@ -531,2 +543,4 @@
 ! CONFIG_BAREBONE (n/y)
 
+% Line debugging information
+! [CONFIG_STRIP_BINARIES!=y] CONFIG_LINE_DEBUG (n/y)
Index: boot/Makefile
===================================================================
--- boot/Makefile	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ boot/Makefile	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -48,5 +48,5 @@
 endif
 ifeq ($(RDFMT),fat)
-	$(MKFAT) $(DIST_PATH) $@
+	$(MKFAT) 1048576 $(DIST_PATH) $@
 endif
 
@@ -80,6 +80,5 @@
 
 clean_dist:
-	rm -f $(INITRD).fs $(INITRD).img $(COMPS_H) $(COMPS_C) $(LINK) *.co
-	rm -f -r "$(DIST_PATH)/$(DRVS_PATH)" 
+	rm -f $(INITRD).fs $(INITRD).img $(COMPS_H) $(COMPS_C) $(LINK) $(LINK).comp *.co
 	rm -f $(USPACE_PATH)/dist/srv/*
 	rm -f $(USPACE_PATH)/dist/app/*
Index: boot/Makefile.build
===================================================================
--- boot/Makefile.build	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ boot/Makefile.build	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -41,9 +41,9 @@
 	-Wall -Wextra -Wno-unused-parameter -Wmissing-prototypes \
 	-Werror-implicit-function-declaration -Wwrite-strings \
-	-Werror -pipe
+	-pipe
 
 ICC_CFLAGS = -I$(INCLUDES) -O$(OPTIMIZATION) -imacros $(CONFIG_HEADER) \
 	-ffreestanding -fno-builtin -nostdlib -nostdinc -Wall -Wmissing-prototypes \
-	-Werror-implicit-function-declaration -Werror -wd170
+	-Werror-implicit-function-declaration -wd170
 
 SUNCC_CFLAGS = -I$(INCLUDES) -xO$(OPTIMIZATION) \
@@ -57,4 +57,16 @@
 	-Werror-implicit-function-declaration -Wwrite-strings \
 	-pipe -arch $(CLANG_ARCH)
+
+ifeq ($(CONFIG_DEBUG),y)
+	GCC_CFLAGS += -Werror
+	ICC_CFLAGS += -Werror
+endif
+
+ifeq ($(CONFIG_LINE_DEBUG),y)
+	GCC_CFLAGS += -g
+	ICC_CFLAGS += -g
+	SUNCC_CFLAGS += -g
+	CLANG_CFLAGS += -g
+endif
 
 ifeq ($(COMPILER),gcc_native)
@@ -101,4 +113,7 @@
 	$(LD) -N $(LFLAGS) -T $(LINK) -M -Map $(MAP) -o $@ $(COMPONENT_OBJECTS) $(OBJECTS)
 
+$(LINK): $(LINK).comp $(DEPEND)
+	$(GCC) $(DEFS) $(GCC_CFLAGS) -D__ASM__ -D__LINKER__ -E -x c $(LINK).comp | grep -v "^\#" > $(LINK)
+
 %.o: %.S $(DEPEND)
 	$(CC) $(DEFS) $(CFLAGS) -D__ASM__ -c $< -o $@
Index: boot/Makefile.common
===================================================================
--- boot/Makefile.common	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ boot/Makefile.common	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -56,4 +56,5 @@
 MKTMPFS = $(TOOLS_PATH)/mktmpfs.py
 MKFAT = $(TOOLS_PATH)/mkfat.py
+MKUIMAGE = $(TOOLS_PATH)/mkuimage.py
 
 JOBFILE = $(ROOT_PATH)/tools/jobfile.py
Index: boot/Makefile.empty
===================================================================
--- boot/Makefile.empty	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
+++ boot/Makefile.empty	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -0,0 +1,35 @@
+#
+# Copyright (c) 2010 Martin Decky
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# - Redistributions of source code must retain the above copyright
+#   notice, this list of conditions and the following disclaimer.
+# - Redistributions in binary form must reproduce the above copyright
+#   notice, this list of conditions and the following disclaimer in the
+#   documentation and/or other materials provided with the distribution.
+# - The name of the author may not be used to endorse or promote products
+#   derived from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+
+.PHONY: all clean
+
+include Makefile.common
+
+all:
+
+clean:
Index: boot/Makefile.uboot
===================================================================
--- boot/Makefile.uboot	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
+++ boot/Makefile.uboot	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -0,0 +1,46 @@
+#
+# 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.
+#
+
+.PHONY: all clean
+
+include Makefile.common
+
+IMAGE_NAME=HelenOS-$(RELEASE)
+BIN_OUTPUT=image.bin
+
+all: $(POST_OUTPUT)
+
+$(BIN_OUTPUT): $(BOOT_OUTPUT)
+	$(OBJCOPY) -O binary $< $@
+
+$(POST_OUTPUT): $(BIN_OUTPUT)
+	$(MKUIMAGE) -name "$(IMAGE_NAME)" -laddr 0x30008000 -saddr 0x30008000 \
+    $< $@
+
+clean:
+	rm -f $(BIN_OUTPUT)
Index: boot/arch/abs32le/Makefile.inc
===================================================================
--- boot/arch/abs32le/Makefile.inc	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
+++ boot/arch/abs32le/Makefile.inc	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -0,0 +1,34 @@
+#
+# Copyright (c) 2010 Martin Decky
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# - Redistributions of source code must retain the above copyright
+#   notice, this list of conditions and the following disclaimer.
+# - Redistributions in binary form must reproduce the above copyright
+#   notice, this list of conditions and the following disclaimer in the
+#   documentation and/or other materials provided with the distribution.
+# - The name of the author may not be used to endorse or promote products
+#   derived from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+
+BOOT_OUTPUT =
+RAW =
+JOB =
+MAP =
+PREBUILD =
+BUILD = Makefile.empty
Index: boot/arch/arm32/Makefile.inc
===================================================================
--- boot/arch/arm32/Makefile.inc	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ boot/arch/arm32/Makefile.inc	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -27,4 +27,10 @@
 #
 
+ifeq ($(MACHINE), gta02)
+	BOOT_OUTPUT = image.boot
+	POST_OUTPUT = $(ROOT_PATH)/uImage.bin
+	POSTBUILD = Makefile.uboot
+endif
+
 BFD_NAME = elf32-littlearm
 BFD_OUTPUT = $(BFD_NAME)
@@ -35,5 +41,7 @@
 PAGE_SIZE = 4096
 
-RD_SRVS_ESSENTIAL +=
+RD_SRVS_ESSENTIAL += \
+	$(USPACE_PATH)/srv/hid/s3c24xx_ts/s3c24ts \
+	$(USPACE_PATH)/srv/hw/char/s3c24xx_uart/s3c24ser
 
 RD_SRVS_NON_ESSENTIAL += \
@@ -47,4 +55,5 @@
 	$(COMPS_C) \
 	genarch/src/division.c \
+	generic/src/memstr.c \
 	generic/src/printf_core.c \
 	generic/src/vprintf.c \
Index: boot/arch/arm32/_link.ld.in
===================================================================
--- boot/arch/arm32/_link.ld.in	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ boot/arch/arm32/_link.ld.in	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -1,11 +1,13 @@
+#include <arch/arch.h>
+
 ENTRY(start)
 
 SECTIONS {
-	. = 0x0000;
+	. = BOOT_BASE;
 	.text : {
 		*(BOOTSTRAP);
 		*(.text);
 	}
-	. = 0x8000;
+	. = BOOT_BASE + 0x8000;
 	.data : {
 		*(BOOTPT);      /* bootstrap page table */
Index: boot/arch/arm32/include/arch.h
===================================================================
--- boot/arch/arm32/include/arch.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ boot/arch/arm32/include/arch.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -36,5 +36,15 @@
 #define PTL0_ENTRY_SIZE  4
 
-#define BOOT_OFFSET  0xa00000
+/*
+ * Address where the boot stage image starts (beginning of usable physical
+ * memory).
+ */
+#ifdef MACHINE_gta02
+#define BOOT_BASE	0x30008000
+#else
+#define BOOT_BASE	0x00000000
+#endif
+
+#define BOOT_OFFSET	(BOOT_BASE + 0xa00000)
 
 #ifndef __ASM__
Index: boot/arch/arm32/include/main.h
===================================================================
--- boot/arch/arm32/include/main.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ boot/arch/arm32/include/main.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -1,4 +1,5 @@
 /*
  * Copyright (c) 2007 Michal Kebrt
+ * Copyright (c) 2010 Jiri Svoboda
  * All rights reserved.
  *
@@ -38,11 +39,21 @@
 
 /** Address where characters to be printed are expected. */
-#ifdef MACHINE_testarm
-	#define VIDEORAM_ADDRESS  0x10000000
-#endif
 
-#ifdef MACHINE_integratorcp
-	#define VIDEORAM_ADDRESS  0x16000000
-#endif
+/** GTA02 serial console UART register addresses.
+ *
+ * This is UART channel 2 of the S3C24xx CPU
+ */
+#define GTA02_SCONS_UTRSTAT	0x50008010
+#define GTA02_SCONS_UTXH	0x50008020
+
+/* Bits in UTXH register */
+#define S3C24XX_UTXH_TX_EMPTY	0x00000004
+
+
+/** GXemul testarm serial console output register */
+#define TESTARM_SCONS_ADDR 	0x10000000
+
+/** IntegratorCP serial console output register */
+#define ICP_SCONS_ADDR 		0x16000000
 
 extern void bootstrap(void);
Index: boot/arch/arm32/src/asm.S
===================================================================
--- boot/arch/arm32/src/asm.S	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ boot/arch/arm32/src/asm.S	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -35,5 +35,4 @@
 .global boot_stack
 .global halt
-.global memcpy
 .global jump_to_kernel
 
@@ -55,63 +54,4 @@
 	b halt
 
-memcpy:
-	add r3, r1, #3
-	bic r3, r3, #3
-	cmp r1, r3
-	stmdb sp!, {r4, r5, lr}
-	mov r5, r0
-	beq 4f
-	
-	1:
-		cmp r2, #0
-		movne ip, #0
-		beq 3f
-	
-	2:
-		ldrb r3, [ip, r1]
-		strb r3, [ip, r0]
-		add ip, ip, #1
-		cmp ip, r2
-		bne 2b
-	
-	3:
-		mov r0, r5
-		ldmia sp!, {r4, r5, pc}
-	
-	4:
-		add r3, r0, #3
-		bic r3, r3, #3
-		cmp r0, r3
-		bne 1b
-		movs r4, r2, lsr #2
-		moveq lr, r4
-		beq 6f
-		mov lr, #0
-		mov ip, lr
-	
-	5:
-		ldr r3, [ip, r1]
-		add lr, lr, #1
-		cmp lr, r4
-		str r3, [ip, r0]
-		add ip, ip, #4
-		bne 5b
-	
-	6:
-		ands r4, r2, #3
-		beq 3b
-		mov r3, lr, lsl #2
-		add r0, r3, r0
-		add ip, r3, r1
-		mov r2, #0
-	
-	7:
-		ldrb r3, [r2, ip]
-		strb r3, [r2, r0]
-		add r2, r2, #1
-		cmp r2, r4
-		bne 7b
-		b 3b
-
 jump_to_kernel:
 	#
Index: boot/arch/arm32/src/putchar.c
===================================================================
--- boot/arch/arm32/src/putchar.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ boot/arch/arm32/src/putchar.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -2,4 +2,5 @@
  * Copyright (c) 2007 Michal Kebrt
  * Copyright (c) 2009 Vineeth Pillai
+ * Copyright (c) 2010 Jiri Svoboda
  * All rights reserved.
  *
@@ -40,13 +41,84 @@
 #include <str.h>
 
+#ifdef MACHINE_gta02
+
+/** Send a byte to the gta02 serial console.
+ *
+ * @param byte		Byte to send.
+ */
+static void scons_sendb_gta02(uint8_t byte)
+{
+	volatile uint32_t *utrstat;
+	volatile uint32_t *utxh;
+
+	utrstat = (volatile uint32_t *) GTA02_SCONS_UTRSTAT;
+	utxh    = (volatile uint32_t *) GTA02_SCONS_UTXH;
+
+	/* Wait until transmitter is empty. */
+	while ((*utrstat & S3C24XX_UTXH_TX_EMPTY) == 0)
+		;
+
+	/* Transmit byte. */
+	*utxh = (uint32_t) byte;
+}
+
+#endif
+
+#ifdef MACHINE_testarm
+
+/** Send a byte to the GXemul testarm serial console.
+ *
+ * @param byte		Byte to send.
+ */
+static void scons_sendb_testarm(uint8_t byte)
+{
+	*((volatile uint8_t *) TESTARM_SCONS_ADDR) = byte;
+}
+
+#endif
+
+#ifdef MACHINE_integratorcp
+
+/** Send a byte to the IntegratorCP serial console.
+ *
+ * @param byte		Byte to send.
+ */
+static void scons_sendb_icp(uint8_t byte)
+{
+	*((volatile uint8_t *) ICP_SCONS_ADDR) = byte;
+}
+
+#endif
+
+/** Send a byte to the serial console.
+ *
+ * @param byte		Byte to send.
+ */
+static void scons_sendb(uint8_t byte)
+{
+#ifdef MACHINE_gta02
+	scons_sendb_gta02(byte);
+#endif
+#ifdef MACHINE_testarm
+	scons_sendb_testarm(byte);
+#endif
+#ifdef MACHINE_integratorcp
+	scons_sendb_icp(byte);
+#endif
+}
+
+/** Display a character
+ *
+ * @param ch	Character to display
+ */
 void putchar(const wchar_t ch)
 {
 	if (ch == '\n')
-		*((volatile char *) VIDEORAM_ADDRESS) = '\r';
-	
+		scons_sendb('\r');
+
 	if (ascii_check(ch))
-		*((volatile char *) VIDEORAM_ADDRESS) = ch;
+		scons_sendb((uint8_t) ch);
 	else
-		*((volatile char *) VIDEORAM_ADDRESS) = U_SPECIAL;
+		scons_sendb(U_SPECIAL);
 }
 
Index: boot/arch/ia64/Makefile.inc
===================================================================
--- boot/arch/ia64/Makefile.inc	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
+++ boot/arch/ia64/Makefile.inc	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -0,0 +1,62 @@
+#
+# 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.
+#
+
+BFD_NAME = elf64-ia64-little
+BFD_OUTPUT = $(BFD_NAME)
+BFD_ARCH = ia64
+
+BITS = 64
+ENDIANESS = LE
+PAGE_SIZE = 16384
+EXTRA_CFLAGS = -fno-unwind-tables -mfixed-range=f32-f127 -mno-pic
+
+RD_SRVS_NON_ESSENTIAL +=
+
+RD_SRVS_ESSENTIAL += \
+	$(USPACE_PATH)/srv/hw/char/i8042/i8042
+
+SOURCES = \
+	arch/$(BARCH)/src/boot.S \
+	arch/$(BARCH)/src/asm.S \
+	arch/$(BARCH)/src/main.c \
+	arch/$(BARCH)/src/putchar.c \
+	$(COMPS_C) \
+	genarch/src/division.c \
+	generic/src/balloc.c \
+	generic/src/memstr.c \
+	generic/src/printf_core.c \
+	generic/src/vprintf.c \
+	generic/src/printf.c \
+	generic/src/str.c \
+	generic/src/version.c \
+	generic/src/inflate.c
+
+ifeq ($(MACHINE),ski)
+SOURCES += \
+	arch/$(BARCH)/src/ski.c
+endif
Index: boot/arch/ia64/_link.ld.in
===================================================================
--- boot/arch/ia64/_link.ld.in	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
+++ boot/arch/ia64/_link.ld.in	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -0,0 +1,25 @@
+OUTPUT_FORMAT("elf64-ia64-little")
+ENTRY(start)
+
+SECTIONS {
+	.boot 0x4400000: AT (0x4400000) {
+		*(BOOTSTRAP);
+		*(.text);
+		*(.sdata);
+		*(.sdata2);
+		*(.sbss);
+		*(.rodata);
+		*(.rodata.*);
+		*(.data);               /* initialized data */
+		_got = . ;
+		*(.got .got.*);
+		*(.bss);                /* uninitialized static variables */
+		*(COMMON);
+[[COMPONENTS]]
+	}
+
+	/DISCARD/ : {
+		*(.comment);
+		*(.note*);
+	}
+}
Index: boot/arch/ia64/include/arch.h
===================================================================
--- boot/arch/ia64/include/arch.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
+++ boot/arch/ia64/include/arch.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2006 Martin Decky
+ * Copyright (c) 2006 Jakub Jermar
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef BOOT_ia64_ARCH_H_
+#define BOOT_ia64_ARCH_H_
+
+#define PAGE_WIDTH  14
+#define PAGE_SIZE   (1 << PAGE_WIDTH)
+
+#define LOADER_ADDRESS  0x4400000
+#define KERNEL_ADDRESS  0x4800000
+
+#define STACK_SIZE                   8192
+#define STACK_ALIGNMENT              16
+
+#endif
Index: boot/arch/ia64/include/asm.h
===================================================================
--- boot/arch/ia64/include/asm.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
+++ boot/arch/ia64/include/asm.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2006 Martin Decky
+ * Copyright (c) 2006 Jakub Jermar 
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef BOOT_ia64_ASM_H_
+#define BOOT_ia64_ASM_H_
+
+extern void jump_to_kernel(void *) __attribute__((noreturn));
+
+#endif
Index: boot/arch/ia64/include/main.h
===================================================================
--- boot/arch/ia64/include/main.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
+++ boot/arch/ia64/include/main.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -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.
+ */
+
+#ifndef BOOT_ia64_MAIN_H_
+#define BOOT_ia64_MAIN_H_
+
+extern void bootstrap(void);
+
+#endif
Index: boot/arch/ia64/include/ski.h
===================================================================
--- boot/arch/ia64/include/ski.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
+++ boot/arch/ia64/include/ski.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2005 Jakub Jermar
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef BOOT_ia64_SKI_H_
+#define BOOT_ia64_SKI_H_
+
+#include <str.h>
+
+extern void ski_putchar(const wchar_t);
+
+#endif
Index: boot/arch/ia64/include/types.h
===================================================================
--- boot/arch/ia64/include/types.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
+++ boot/arch/ia64/include/types.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -0,0 +1,70 @@
+/*
+ * 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.
+ */
+
+#ifndef BOOT_ia64_TYPES_H_
+#define BOOT_ia64_TYPES_H_
+
+#define TASKMAP_MAX_RECORDS		32
+#define BOOTINFO_TASK_NAME_BUFLEN	32
+#define MEMMAP_ITEMS			128	
+
+typedef uint64_t size_t;
+typedef uint64_t unative_t;
+typedef uint64_t uintptr_t;
+
+typedef struct {
+	void *addr;
+	size_t size;
+	char name[BOOTINFO_TASK_NAME_BUFLEN];
+} binit_task_t;
+
+typedef struct {
+	size_t cnt;
+	binit_task_t tasks[TASKMAP_MAX_RECORDS];
+} binit_t;
+
+typedef struct {
+	unsigned int type;
+	unsigned long base;
+	unsigned long size;
+} efi_memmap_item_t;
+
+typedef struct {
+	binit_t taskmap;
+
+	efi_memmap_item_t memmap[MEMMAP_ITEMS];
+	unsigned int memmap_items;
+
+	unative_t *sapic;
+	unsigned long sys_freq;
+	unsigned long freq_scale;
+	unsigned int wakeup_intno;
+	int hello_configured;
+} bootinfo_t;
+
+#endif
Index: boot/arch/ia64/src/asm.S
===================================================================
--- boot/arch/ia64/src/asm.S	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
+++ boot/arch/ia64/src/asm.S	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -0,0 +1,46 @@
+#
+# Copyright (c) 2006 Martin Decky
+# 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.
+#
+
+#include <arch/arch.h>
+
+.text
+
+.global halt
+.global memcpy
+.global jump_to_kernel
+
+halt:
+	br halt
+
+jump_to_kernel:
+	alloc loc0 = ar.pfs, 1, 1, 0, 0
+	mov r2 = in0 ;;			# Pass bootinfo address
+	movl r8 = KERNEL_ADDRESS;;
+	mov b1 = r8 ;;
+	br.call.sptk.many b0 = b1;;
Index: boot/arch/ia64/src/boot.S
===================================================================
--- boot/arch/ia64/src/boot.S	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
+++ boot/arch/ia64/src/boot.S	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -0,0 +1,67 @@
+#
+# Copyright (c) 2006 Martin Decky
+# 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.
+#
+
+#include <arch/arch.h>
+
+.section BOOTSTRAP, "ax"
+
+.global start
+start:
+	movl gp = LOADER_ADDRESS
+
+	#
+	# Initialize the register stack to some sane value.
+	#
+	mov ar.rsc = r0
+	movl r8 = initial_stack ;;
+	mov ar.bspstore = r8
+	loadrs
+
+	#
+	# Initialize memory stack to some sane value and allocate a scratch area
+	# on it.
+	#
+	movl r12 = initial_stack_top ;;
+	add r12 = -16, r12
+
+	#
+	# Disable Floating-point High register set (f32 - f127)
+	#
+	ssm (1 << 19) ;;
+	srlz.i
+	srlz.d ;;
+
+	br.call.sptk.many rp = bootstrap
+
+.bss
+
+.align STACK_SIZE
+initial_stack:
+	.space STACK_SIZE
+initial_stack_top:
Index: boot/arch/ia64/src/main.c
===================================================================
--- boot/arch/ia64/src/main.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
+++ boot/arch/ia64/src/main.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -0,0 +1,143 @@
+/*
+ * Copyright (c) 2005 Martin Decky
+ * 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.
+ */
+
+
+#include <arch/main.h>
+#include <arch/arch.h>
+#include <arch/asm.h>
+#include <arch/_components.h>
+#include <halt.h>
+#include <printf.h>
+#include <memstr.h>
+#include <version.h>
+#include <macros.h>
+#include <align.h>
+#include <str.h>
+#include <errno.h>
+#include <inflate.h>
+
+#define DEFAULT_MEMORY_BASE		0x4000000ULL
+#define DEFAULT_MEMORY_SIZE		0x4000000ULL
+#define DEFAULT_LEGACY_IO_BASE		0x00000FFFFC000000ULL
+#define DEFAULT_LEGACY_IO_SIZE		0x4000000ULL
+
+#define DEFAULT_FREQ_SCALE		0x0000000100000001ULL	/* 1/1 */
+#define DEFAULT_SYS_FREQ		100000000ULL		/* 100MHz */
+
+#define EFI_MEMMAP_FREE_MEM		0
+#define EFI_MEMMAP_IO			1
+#define EFI_MEMMAP_IO_PORTS		2
+
+static bootinfo_t bootinfo;
+
+void bootstrap(void)
+{
+	version_print();
+	
+	printf(" %p|%p: boot info structure\n", &bootinfo, &bootinfo);
+	printf(" %p|%p: kernel entry point\n", KERNEL_ADDRESS, KERNEL_ADDRESS);
+	printf(" %p|%p: loader entry point\n", LOADER_ADDRESS, LOADER_ADDRESS);
+	
+	size_t i;
+	for (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, components[i].size);
+	
+	void *dest[COMPONENTS];
+	size_t top = KERNEL_ADDRESS;
+	size_t cnt = 0;
+	bootinfo.taskmap.cnt = 0;
+	for (i = 0; i < min(COMPONENTS, TASKMAP_MAX_RECORDS); i++) {
+		top = ALIGN_UP(top, PAGE_SIZE);
+		
+		if (i > 0) {
+			bootinfo.taskmap.tasks[bootinfo.taskmap.cnt].addr =
+			    (void *) top;
+			bootinfo.taskmap.tasks[bootinfo.taskmap.cnt].size =
+			    components[i].inflated;
+			
+			str_cpy(bootinfo.taskmap.tasks[bootinfo.taskmap.cnt].name,
+			    BOOTINFO_TASK_NAME_BUFLEN, components[i].name);
+			
+			bootinfo.taskmap.cnt++;
+		}
+		
+		dest[i] = (void *) top;
+		top += components[i].inflated;
+		cnt++;
+	}
+	
+	printf("\nInflating components ... ");
+	
+	for (i = cnt; i > 0; i--) {
+		printf("%s ", components[i - 1].name);
+		
+		int err = inflate(components[i - 1].start, components[i - 1].size,
+		    dest[i - 1], components[i - 1].inflated);
+		
+		if (err != EOK) {
+			printf("\n%s: Inflating error %d, halting.\n",
+			    components[i - 1].name, err);
+			halt();
+		}
+	}
+	
+	printf(".\n");
+	
+	if (!bootinfo.hello_configured) {	/* XXX */
+		/*
+		 * Load configuration defaults for simulators.
+		 */
+		 bootinfo.memmap_items = 0;
+		 
+		 bootinfo.memmap[bootinfo.memmap_items].base =
+		     DEFAULT_MEMORY_BASE;
+		 bootinfo.memmap[bootinfo.memmap_items].size =
+		     DEFAULT_MEMORY_SIZE;
+		 bootinfo.memmap[bootinfo.memmap_items].type =
+		     EFI_MEMMAP_FREE_MEM;
+		 bootinfo.memmap_items++;
+
+		 bootinfo.memmap[bootinfo.memmap_items].base =
+		     DEFAULT_LEGACY_IO_BASE;
+		 bootinfo.memmap[bootinfo.memmap_items].size =
+		     DEFAULT_LEGACY_IO_SIZE;
+		 bootinfo.memmap[bootinfo.memmap_items].type =
+		     EFI_MEMMAP_IO_PORTS;
+		 bootinfo.memmap_items++;
+		 
+		 bootinfo.freq_scale = DEFAULT_FREQ_SCALE;
+		 bootinfo.sys_freq = DEFAULT_SYS_FREQ;
+	}
+	
+	
+	printf("Booting the kernel ...\n");
+	jump_to_kernel(&bootinfo);
+}
Index: boot/arch/ia64/src/putchar.c
===================================================================
--- boot/arch/ia64/src/putchar.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
+++ boot/arch/ia64/src/putchar.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -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.
+ */
+
+#include <typedefs.h>
+#include <arch/arch.h>
+#include <putchar.h>
+#include <str.h>
+#include <arch/ski.h>
+
+void putchar(const wchar_t ch)
+{
+#ifdef MACHINE_ski
+	if (ascii_check(ch))
+		ski_putchar(ch);
+	else
+		ski_putchar(U_SPECIAL);
+#endif
+}
Index: boot/arch/ia64/src/ski.c
===================================================================
--- boot/arch/ia64/src/ski.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
+++ boot/arch/ia64/src/ski.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2005 Jakub Jermar
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <arch/ski.h>
+#include <typedefs.h>
+
+#define SKI_INIT_CONSOLE	20
+#define	SKI_PUTCHAR		31
+
+static void ski_console_init(void)
+{
+	static bool initialized = false;
+	
+	if (initialized)
+		return;
+
+	asm volatile (
+		"mov r15 = %[cmd]\n"
+		"break 0x80000\n"
+		:
+		: [cmd] "i" (SKI_INIT_CONSOLE)
+		: "r15", "r8"
+	);
+	
+	initialized = true;
+}
+
+void ski_putchar(const wchar_t ch)
+{
+	ski_console_init();
+
+	if (ch == '\n')
+		ski_putchar('\r');
+
+	asm volatile (
+		"mov r15 = %[cmd]\n"
+		"mov r32 = %[ch]\n"   /* r32 is in0 */
+		"break 0x80000\n"     /* modifies r8 */
+		:
+		: [cmd] "i" (SKI_PUTCHAR), [ch] "r" (ch)
+		: "r15", "in0", "r8"
+	);
+}
Index: boot/arch/mips32/Makefile.inc
===================================================================
--- boot/arch/mips32/Makefile.inc	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ boot/arch/mips32/Makefile.inc	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -61,4 +61,5 @@
 	genarch/src/division.c \
 	genarch/src/multiplication.c \
+	generic/src/memstr.c \
 	generic/src/printf_core.c \
 	generic/src/vprintf.c \
Index: boot/arch/mips32/src/Makefile
===================================================================
--- boot/arch/mips32/src/Makefile	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ boot/arch/mips32/src/Makefile	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -32,9 +32,13 @@
 .PHONY: all clean
 
-all: ../../../../version ../../../../Makefile.config ../../../../config.h ../../../../config.defs
+all: ../../../../version ../../../../Makefile.common ../../../../Makefile.config ../../../../config.h
 	-[ -f $(DEPEND) ] && mv -f $(DEPEND) $(DEPEND_PREV)
 	$(MAKE) -f Makefile.build PRECHECK=$(PRECHECK)
 
 clean:
+	rm -f $(USPACEDIR)/dist/srv/*
+	rm -f $(USPACEDIR)/dist/app/*
+	rm -f $(USPACEDIR)/dist/cfg/net/*
+
 	for file in $(RD_SRVS) ; do \
 		rm -f $(USPACEDIR)/dist/srv/`basename $$file` ; \
@@ -43,4 +47,7 @@
 		rm -f $(USPACEDIR)/dist/app/`basename $$file` ; \
 	done
+	for file in $(NET_CFG) ; do \
+		rm -f $(USPACEDIR)/dist/cfg/net/`basename $$file` ; \
+	done
 	rm -f $(DEPEND) $(DEPEND_PREV) $(JOB) $(OUTPUT) $(RAW) $(COMPS).h $(COMPS).c $(LINK) $(INITRD).img $(INITRD).fs
 	find . -name '*.o' -follow -exec rm \{\} \;
Index: boot/arch/mips32/src/Makefile.build
===================================================================
--- boot/arch/mips32/src/Makefile.build	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ boot/arch/mips32/src/Makefile.build	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -32,6 +32,6 @@
 
 include ../../../../version
+include ../../../../Makefile.common
 include ../../../../Makefile.config
-include ../../../../config.defs
 include Makefile.common
 include Makefile.toolchain
@@ -77,4 +77,8 @@
 
 $(DEPEND):
+	rm -f $(USPACEDIR)/dist/srv/*
+	rm -f $(USPACEDIR)/dist/app/*
+	rm -f $(USPACEDIR)/dist/cfg/net/*
+
 	for file in $(RD_SRVS) ; do \
 		cp $$file $(USPACEDIR)/dist/srv/ ; \
@@ -82,4 +86,7 @@
 	for file in $(RD_APPS) ; do \
 		cp $$file $(USPACEDIR)/dist/app/ ; \
+	done
+	for file in $(NET_CFG) ; do \
+		cp $$file $(USPACEDIR)/dist/cfg/net/ ; \
 	done
 ifeq ($(RDFMT),tmpfs)
Index: boot/arch/mips32/src/Makefile.toolchain
===================================================================
--- boot/arch/mips32/src/Makefile.toolchain	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ boot/arch/mips32/src/Makefile.toolchain	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -27,14 +27,5 @@
 #
 
-## Toolchain configuration
-#
-
-ifndef CROSS_PREFIX
-	CROSS_PREFIX = /usr/local
-endif
-
 BFD_ARCH = mips
-TARGET = mipsel-linux-gnu
-TOOLCHAIN_DIR = $(CROSS_PREFIX)/mips32/bin
 
 JOBFILE = ../../../../tools/jobfile.py
@@ -48,6 +39,4 @@
 	BFD_NAME = elf32-tradbigmips
 	BFD = ecoff-bigmips
-	TOOLCHAIN_DIR = $(CROSS_PREFIX)/mips32eb/bin
-	TARGET = mips-linux-gnu
 endif
 
@@ -55,20 +44,4 @@
 	BFD_NAME = elf32-tradlittlemips
 	BFD = binary
-endif
-
-ifeq ($(COMPILER),gcc_native)
-	CC = gcc
-	AS = as
-	LD = ld
-	OBJCOPY = objcopy
-	OBJDUMP = objdump
-endif
-
-ifeq ($(COMPILER),gcc_cross)
-	CC = $(TOOLCHAIN_DIR)/$(TARGET)-gcc
-	AS = $(TOOLCHAIN_DIR)/$(TARGET)-as
-	LD = $(TOOLCHAIN_DIR)/$(TARGET)-ld
-	OBJCOPY = $(TOOLCHAIN_DIR)/$(TARGET)-objcopy
-	OBJDUMP = $(TOOLCHAIN_DIR)/$(TARGET)-objdump
 endif
 
Index: boot/arch/mips32/src/asm.S
===================================================================
--- boot/arch/mips32/src/asm.S	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ boot/arch/mips32/src/asm.S	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -36,5 +36,4 @@
 .global start
 .global halt
-.global memcpy
 .global jump_to_kernel
 
@@ -127,70 +126,4 @@
 	nop
 
-memcpy:
-	addiu $v0, $a1, 3
-	li $v1, -4
-	and $v0, $v0, $v1
-	beq $a1, $v0, 3f
-	move $t0, $a0
-	move $t2, $a0
-	
-	0:
-		beq $a2, $zero, 2f
-		move $a3, $zero
-	
-	1:
-		addu $v0, $a1, $a3
-		lbu $a0, 0($v0)
-		addu $v1, $t0, $a3
-		addiu $a3, $a3, 1
-		bne $a3, $a2, 1b
-		sb $a0, 0($v1)
-	
-	2:
-		jr $ra
-		move $v0, $t2
-	
-	3:
-		addiu $v0, $a0, 3
-		and $v0, $v0, $v1
-		bne $a0, $v0, 0b
-		srl $t1, $a2, 2
-		
-		beq $t1, $zero, 5f
-		move $a3, $zero
-		
-		move $a3, $zero
-		move $a0, $zero
-	
-	4:
-		addu $v0, $a1, $a0
-		lw $v1, 0($v0)
-		addiu $a3, $a3, 1
-		addu $v0, $t0, $a0
-		sw $v1, 0($v0)
-		bne $a3, $t1, 4b
-		addiu $a0, $a0, 4
-	
-	5:
-		andi $a2, $a2, 0x3
-		beq $a2, $zero, 2b
-		nop
-		
-		sll $v0, $a3, 2
-		addu $t1, $v0, $t0
-		move $a3, $zero
-		addu $t0, $v0, $a1
-	
-	6:
-		addu $v0, $t0, $a3
-		lbu $a0, 0($v0)
-		addu $v1, $t1, $a3
-		addiu $a3, $a3, 1
-		bne $a3, $a2, 6b
-		sb $a0, 0($v1)
-		
-		jr $ra
-		move $v0, $t2
-
 jump_to_kernel:
 	#
Index: boot/arch/ppc32/Makefile.inc
===================================================================
--- boot/arch/ppc32/Makefile.inc	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ boot/arch/ppc32/Makefile.inc	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -56,4 +56,5 @@
 	genarch/src/multiplication.c \
 	generic/src/balloc.c \
+	generic/src/memstr.c \
 	generic/src/printf_core.c \
 	generic/src/vprintf.c \
Index: boot/arch/ppc32/src/asm.S
===================================================================
--- boot/arch/ppc32/src/asm.S	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ boot/arch/ppc32/src/asm.S	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -60,5 +60,4 @@
 .global start
 .global halt
-.global memcpy
 .global jump_to_kernel
 .global real_mode
@@ -78,60 +77,4 @@
 halt:
 	b halt
-
-memcpy:
-	srwi. r7, r5, 3
-	addi r6, r3, -4
-	addi r4, r4, -4
-	beq 2f
-	
-	andi. r0, r6, 3
-	mtctr r7
-	bne 5f
-	
-	1:
-		lwz r7, 4(r4)
-		lwzu r8, 8(r4)
-		stw r7, 4(r6)
-		stwu r8, 8(r6)
-		bdnz 1b
-		
-		andi. r5, r5, 7
-	
-	2:
-		cmplwi 0, r5, 4
-		blt 3f
-		
-		lwzu r0, 4(r4)
-		addi r5, r5, -4
-		stwu r0, 4(r6)
-	
-	3:
-		cmpwi 0, r5, 0
-		beqlr
-		mtctr r5
-		addi r4, r4, 3
-		addi r6, r6, 3
-	
-	4:
-		lbzu r0, 1(r4)
-		stbu r0, 1(r6)
-		bdnz 4b
-		blr
-	
-	5:
-		subfic r0, r0, 4
-		mtctr r0
-	
-	6:
-		lbz r7, 4(r4)
-		addi r4, r4, 1
-		stb r7, 4(r6)
-		addi r6, r6, 1
-		bdnz 6b
-		subf r5, r0, r5
-		rlwinm. r7, r5, 32-3, 3, 31
-		beq 2b
-		mtctr r7
-		b 1b
 
 jump_to_kernel:
Index: boot/arch/sparc64/Makefile.inc
===================================================================
--- boot/arch/sparc64/Makefile.inc	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ boot/arch/sparc64/Makefile.inc	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -38,5 +38,5 @@
 ENDIANESS = BE
 PAGE_SIZE = 16384
-EXTRA_CFLAGS = -mcpu=ultrasparc -m64 -mno-fpu
+EXTRA_CFLAGS = -mcpu=ultrasparc -m64 -mno-fpu -mcmodel=medlow
 
 RD_SRVS_NON_ESSENTIAL +=
@@ -54,4 +54,5 @@
 	genarch/src/ofw_tree.c \
 	generic/src/balloc.c \
+	generic/src/memstr.c \
 	generic/src/printf_core.c \
 	generic/src/vprintf.c \
Index: boot/arch/sparc64/src/asm.S
===================================================================
--- boot/arch/sparc64/src/asm.S	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ boot/arch/sparc64/src/asm.S	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -42,5 +42,4 @@
 .global start
 .global halt
-.global memcpy
 .global jump_to_kernel
 
@@ -98,73 +97,4 @@
 	ba %xcc, halt
 	nop
-
-memcpy:
-	! Save dst
-	
-	mov %o0, %o3
-	add %o1, 7, %g1
-	and %g1, -8, %g1
-	cmp %o1, %g1
-	be,pn %xcc, 3f
-	add %o0, 7, %g1
-	mov 0, %g3
-	
-	0:
-		brz,pn %o2, 2f
-		mov 0, %g2
-	
-	1:
-		ldub [%g3 + %o1], %g1
-		add %g2, 1, %g2
-		cmp %o2, %g2
-		stb %g1, [%g3 + %o0]
-		bne,pt %xcc, 1b
-		mov %g2, %g3
-	
-	2:
-		! Exit point
-		
-		jmp %o7 + 8
-		mov %o3, %o0
-	
-	3:
-		and %g1, -8, %g1
-		cmp %o0, %g1
-		bne,pt %xcc, 0b
-		mov 0, %g3
-		srlx %o2, 3, %g4
-		brz,pn %g4, 5f
-		mov 0, %g5
-	
-	4:
-		sllx %g3, 3, %g2
-		add %g5, 1, %g3
-		ldx [%o1 + %g2], %g1
-		mov %g3, %g5
-		cmp %g4, %g3
-		bne,pt %xcc, 4b
-		stx %g1, [%o0 + %g2]
-	
-	5:
-		and %o2, 7, %o2
-		brz,pn %o2, 2b
-		sllx %g4, 3, %g1
-		mov 0, %g2
-		add %g1, %o0, %o0
-		add %g1, %o1, %g4
-		mov 0, %g3
-	
-	6:
-		ldub [%g2 + %g4], %g1
-		stb %g1, [%g2 + %o0]
-		add %g3, 1, %g2
-		cmp %o2, %g2
-		bne,pt %xcc, 6b
-		mov %g2, %g3
-	
-	! Exit point
-	
-	jmp %o7 + 8
-	mov %o3, %o0
 
 jump_to_kernel:
Index: boot/arch/sparc64/src/main.c
===================================================================
--- boot/arch/sparc64/src/main.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ boot/arch/sparc64/src/main.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -213,5 +213,5 @@
 	printf(" %p|%p: boot info structure\n", &bootinfo, bootinfo_pa);
 	printf(" %p|%p: kernel entry point\n", KERNEL_ADDRESS, kernel_address_pa);
-	printf(" %p|%p: loader entry pount\n", LOADER_ADDRESS, loader_address_pa);
+	printf(" %p|%p: loader entry point\n", LOADER_ADDRESS, loader_address_pa);
 	
 	size_t i;
Index: boot/genarch/src/multiplication.c
===================================================================
--- boot/genarch/src/multiplication.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ boot/genarch/src/multiplication.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -33,14 +33,10 @@
 
 #include <genarch/multiplication.h>
+#include <typedefs.h>
 
-/** Set 1 to return MAX_INT64 or MIN_INT64 on overflow */
+/** Set 1 to return INT64_MAX or INT64_MIN on overflow */
 #ifndef SOFTINT_CHECK_OF
-	#define SOFTINT_CHECK_OF 0
+	#define SOFTINT_CHECK_OF  0
 #endif
-
-#define MAX_UINT16  (0xFFFFu)
-#define MAX_UINT32  (0xFFFFFFFFu)
-#define MAX_INT64   (0x7FFFFFFFFFFFFFFFll)
-#define MIN_INT64   (0x8000000000000000ll)
 
 /** Multiply two integers and return long long as result.
@@ -51,7 +47,7 @@
 static unsigned long long mul(unsigned int a, unsigned int b) {
 	unsigned int a1 = a >> 16;
-	unsigned int a2 = a & MAX_UINT16;
+	unsigned int a2 = a & UINT16_MAX;
 	unsigned int b1 = b >> 16;
-	unsigned int b2 = b & MAX_UINT16;
+	unsigned int b2 = b & UINT16_MAX;
 	
 	unsigned long long t1 = a1 * b1;
@@ -85,10 +81,10 @@
 	unsigned long long b1 = b >> 32;
 	
-	unsigned long long a2 = a & (MAX_UINT32);
-	unsigned long long b2 = b & (MAX_UINT32);
+	unsigned long long a2 = a & (UINT32_MAX);
+	unsigned long long b2 = b & (UINT32_MAX);
 	
 	if (SOFTINT_CHECK_OF && (a1 != 0) && (b1 != 0)) {
 		/* Error (overflow) */
-		return (neg ? MIN_INT64 : MAX_INT64);
+		return (neg ? INT64_MIN : INT64_MAX);
 	}
 	
@@ -98,7 +94,7 @@
 	unsigned long long t1 = mul(a1, b2) + mul(b1, a2);
 	
-	if ((SOFTINT_CHECK_OF) && (t1 > MAX_UINT32)) {
+	if ((SOFTINT_CHECK_OF) && (t1 > UINT32_MAX)) {
 		/* Error (overflow) */
-		return (neg ? MIN_INT64 : MAX_INT64);
+		return (neg ? INT64_MIN : INT64_MAX);
 	}
 	
@@ -112,5 +108,5 @@
 	if ((SOFTINT_CHECK_OF) && ((t2 < t1) || (t2 & (1ull << 63)))) {
 		/* Error (overflow) */
-		return (neg ? MIN_INT64 : MAX_INT64);
+		return (neg ? INT64_MIN : INT64_MAX);
 	}
 	
Index: boot/generic/include/stdint.h
===================================================================
--- boot/generic/include/stdint.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
+++ boot/generic/include/stdint.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -0,0 +1,62 @@
+/*
+ * 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.
+ */
+
+/** @file
+ */
+
+#ifndef BOOT_STDINT_H_
+#define BOOT_STDINT_H_
+
+#define INT8_MIN  (0x80)
+#define INT8_MAX  (0x7F)
+
+#define UINT8_MIN  (0u)
+#define UINT8_MAX  (0xFFu)
+
+#define INT16_MIN  (0x8000)
+#define INT16_MAX  (0x7FFF)
+
+#define UINT16_MIN  (0u)
+#define UINT16_MAX  (0xFFFFu)
+
+#define INT32_MIN  (0x80000000l)
+#define INT32_MAX  (0x7FFFFFFFl)
+
+#define UINT32_MIN  (0ul)
+#define UINT32_MAX  (0xFFFFFFFFul)
+
+#define INT64_MIN  (0x8000000000000000ll)
+#define INT64_MAX  (0x7FFFFFFFFFFFFFFFll)
+
+#define UINT64_MIN  (0ull)
+#define UINT64_MAX  (0xFFFFFFFFFFFFFFFFull)
+
+#endif
+
+/** @}
+ */
Index: boot/generic/include/typedefs.h
===================================================================
--- boot/generic/include/typedefs.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ boot/generic/include/typedefs.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -33,4 +33,5 @@
 #define BOOT_TYPEDEFS_H_
 
+#include <stdint.h>
 #include <arch/common.h>
 #include <arch/types.h>
Index: boot/generic/src/memstr.c
===================================================================
--- boot/generic/src/memstr.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
+++ boot/generic/src/memstr.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -0,0 +1,54 @@
+/*
+ * 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.
+ */
+
+#include <memstr.h>
+#include <typedefs.h>
+
+/** Copy block of memory.
+ *
+ * Copy cnt bytes from src address to dst address.The source and destination
+ * memory areas cannot overlap.
+ *
+ * @param src		Source address to copy from.
+ * @param dst		Destination address to copy to.
+ * @param cnt		Number of bytes to copy.
+ *
+ * @return		Destination address.
+ */
+void *memcpy(void *dst, const void *src, size_t cnt)
+{
+	size_t i;
+
+	for (i = 0; i < cnt; i++)
+		((uint8_t *) dst)[i] = ((uint8_t *) src)[i];
+
+	return dst;
+}
+
+/** @}
+ */
Index: contrib/arch/uspace/lib/libc/devmap_device_connect
===================================================================
--- contrib/arch/uspace/lib/libc/devmap_device_connect	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
+++ contrib/arch/uspace/lib/libc/devmap_device_connect	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -0,0 +1,2 @@
+[devmap_get_phone] ;
+!dev.IPC_M_CONNECT_ME_TO
Index: contrib/arch/uspace/lib/libc/devmap_device_get_count
===================================================================
--- contrib/arch/uspace/lib/libc/devmap_device_get_count	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
+++ contrib/arch/uspace/lib/libc/devmap_device_get_count	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -0,0 +1,2 @@
+[devmap_get_phone] ;
+!devmap.DEVMAP_DEVICE_GET_COUNT
Index: contrib/arch/uspace/lib/libc/devmap_device_get_devices
===================================================================
--- contrib/arch/uspace/lib/libc/devmap_device_get_devices	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
+++ contrib/arch/uspace/lib/libc/devmap_device_get_devices	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -0,0 +1,3 @@
+[devmap_get_phone] ;
+!devmap.DEVMAP_DEVICE_GET_DEVICES ;
+!devmap.IPC_M_DATA_READ
Index: contrib/arch/uspace/lib/libc/devmap_device_get_handle
===================================================================
--- contrib/arch/uspace/lib/libc/devmap_device_get_handle	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
+++ contrib/arch/uspace/lib/libc/devmap_device_get_handle	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -0,0 +1,3 @@
+[devmap_get_phone] ;
+!devmap.DEVMAP_DEVICE_GET_HANDLE ;
+!devmap.IPC_M_DATA_WRITE /* name */
Index: contrib/arch/uspace/lib/libc/devmap_get_phone
===================================================================
--- contrib/arch/uspace/lib/libc/devmap_get_phone	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
+++ contrib/arch/uspace/lib/libc/devmap_get_phone	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -0,0 +1,2 @@
+!ns.IPC_M_CONNECT_ME_TO /* devmap */ +
+NULL
Index: contrib/conf/ia32-qe.sh
===================================================================
--- contrib/conf/ia32-qe.sh	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ contrib/conf/ia32-qe.sh	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -5,5 +5,5 @@
 # Create a disk image if it does not exist
 if [ ! -f "$DISK_IMG" ]; then
-	tools/mkfat.py uspace/dist/data "$DISK_IMG"
+	tools/mkfat.py 1048576 uspace/dist/data "$DISK_IMG"
 fi
 
Index: contrib/conf/mips32-gx.sh
===================================================================
--- contrib/conf/mips32-gx.sh	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ contrib/conf/mips32-gx.sh	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -5,5 +5,5 @@
 # Create a disk image if it does not exist
 if [ ! -f "$DISK_IMG" ]; then
-	tools/mkfat.py uspace/dist/data "$DISK_IMG"
+	tools/mkfat.py 1048576 uspace/dist/data "$DISK_IMG"
 fi
 
Index: defaults/amd64/Makefile.config
===================================================================
--- defaults/amd64/Makefile.config	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ defaults/amd64/Makefile.config	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -32,4 +32,7 @@
 CONFIG_LOG = n
 
+# Kernel function tracing
+CONFIG_TRACE = n
+
 # Compile kernel tests
 CONFIG_TEST = y
Index: defaults/arm32/Makefile.config
===================================================================
--- defaults/arm32/Makefile.config	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ defaults/arm32/Makefile.config	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -23,4 +23,7 @@
 CONFIG_LOG = n
 
+# Kernel function tracing
+CONFIG_TRACE = n
+
 # Compile kernel tests
 CONFIG_TEST = y
Index: defaults/arm32/gta02/Makefile.config
===================================================================
--- defaults/arm32/gta02/Makefile.config	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
+++ defaults/arm32/gta02/Makefile.config	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -0,0 +1,14 @@
+# Machine type
+MACHINE = gta02
+
+# RAM disk format
+RDFMT = tmpfs
+
+# Support for userspace debuggers
+CONFIG_UDEBUG = n
+
+# Compile kernel tests
+CONFIG_TEST = n
+
+# Barebone build with essential binaries only
+CONFIG_BAREBONE = y
Index: defaults/ia32/Makefile.config
===================================================================
--- defaults/ia32/Makefile.config	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ defaults/ia32/Makefile.config	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -38,4 +38,7 @@
 CONFIG_LOG = n
 
+# Kernel function tracing
+CONFIG_TRACE = n
+
 # Compile kernel tests
 CONFIG_TEST = y
Index: defaults/ia64/Makefile.config
===================================================================
--- defaults/ia64/Makefile.config	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ defaults/ia64/Makefile.config	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -35,4 +35,7 @@
 CONFIG_LOG = n
 
+# Kernel function tracing
+CONFIG_TRACE = n
+
 # Compile kernel tests
 CONFIG_TEST = y
Index: defaults/mips32/Makefile.config
===================================================================
--- defaults/mips32/Makefile.config	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ defaults/mips32/Makefile.config	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -29,4 +29,7 @@
 CONFIG_LOG = n
 
+# Kernel function tracing
+CONFIG_TRACE = n
+
 # Compile kernel tests
 CONFIG_TEST = y
Index: defaults/ppc32/Makefile.config
===================================================================
--- defaults/ppc32/Makefile.config	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ defaults/ppc32/Makefile.config	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -23,4 +23,7 @@
 CONFIG_LOG = n
 
+# Kernel function tracing
+CONFIG_TRACE = n
+
 # Compile kernel tests
 CONFIG_TEST = y
Index: defaults/sparc64/Makefile.config
===================================================================
--- defaults/sparc64/Makefile.config	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ defaults/sparc64/Makefile.config	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -38,4 +38,7 @@
 CONFIG_LOG = n
 
+# Kernel function tracing
+CONFIG_TRACE = n
+
 # Compile kernel tests
 CONFIG_TEST = y
Index: defaults/special/Makefile.config
===================================================================
--- defaults/special/Makefile.config	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ defaults/special/Makefile.config	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -23,4 +23,7 @@
 CONFIG_LOG = n
 
+# Kernel function tracing
+CONFIG_TRACE = n
+
 # Compile kernel tests
 CONFIG_TEST = y
Index: kernel/Makefile
===================================================================
--- kernel/Makefile	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/Makefile	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -84,7 +84,7 @@
 
 ifeq ($(CONFIG_OPTIMIZE_FOR_SIZE),y)
-OPTIMIZATION = s
-else
-OPTIMIZATION = 3
+	OPTIMIZATION = s
+else
+	OPTIMIZATION = 3
 endif
 
@@ -96,9 +96,9 @@
 	-Wall -Wextra -Wno-unused-parameter -Wmissing-prototypes \
 	-Werror-implicit-function-declaration -Wwrite-strings \
-	-Werror -pipe
+	-pipe
 
 ICC_CFLAGS = -I$(INCLUDES) -O$(OPTIMIZATION) -imacros $(CONFIG_HEADER) \
 	-ffreestanding -fno-builtin -nostdlib -nostdinc -Wall -Wmissing-prototypes \
-	-Werror-implicit-function-declaration -Werror -wd170
+	-Werror-implicit-function-declaration -wd170
 
 SUNCC_CFLAGS = -I$(INCLUDES) -xO$(OPTIMIZATION) \
@@ -113,4 +113,31 @@
 	-pipe -arch $(CLANG_ARCH)
 
+ifeq ($(CONFIG_DEBUG),y)
+	GCC_CFLAGS += -Werror
+	ICC_CFLAGS += -Werror
+endif
+
+ifeq ($(CONFIG_LTO),y)
+	GCC_CFLAGS += -flto
+endif
+
+ifeq ($(CONFIG_LINE_DEBUG),y)
+	GCC_CFLAGS += -g
+	ICC_CFLAGS += -g
+	SUNCC_CFLAGS += -g
+	CLANG_CFLAGS += -g
+endif
+
+#
+# Mind the mutual ordering with the inclusion of the arch Makefile.inc.
+# AFLAGS and LFLAGS must be initialized before the inclusion.
+#
+AFLAGS =
+LFLAGS = -N -T $(LINK) -M
+
+#
+# Mind the mutual ordering with the initialization of AFLAGS and LFLAGS.
+# The arch Makefile.inc must be included after the initialization.
+#
 -include arch/$(KARCH)/Makefile.inc
 -include genarch/Makefile.inc
@@ -140,4 +167,5 @@
 	CFLAGS = $(GCC_CFLAGS)
 	DEPEND_DEFS = $(DEFS) $(CONFIG_DEFS)
+	INSTRUMENTATION = -finstrument-functions
 endif
 
@@ -145,4 +173,5 @@
 	CFLAGS = $(GCC_CFLAGS)
 	DEPEND_DEFS = $(DEFS) $(CONFIG_DEFS)
+	INSTRUMENTATION = -finstrument-functions
 endif
 
@@ -150,4 +179,5 @@
 	CFLAGS = $(ICC_CFLAGS)
 	DEPEND_DEFS = $(DEFS) $(CONFIG_DEFS)
+	INSTRUMENTATION =
 endif
 
@@ -156,4 +186,5 @@
 	DEFS += $(CONFIG_DEFS)
 	DEPEND_DEFS = $(DEFS)
+	INSTRUMENTATION =
 endif
 
@@ -161,5 +192,7 @@
 	CFLAGS = $(CLANG_CFLAGS)
 	DEPEND_DEFS = $(DEFS) $(CONFIG_DEFS)
-endif
+	INSTRUMENTATION =
+endif
+
 
 ## Generic kernel sources
@@ -180,4 +213,6 @@
 	generic/src/debug/symtab.c \
 	generic/src/debug/stacktrace.c \
+	generic/src/debug/panic.c \
+	generic/src/debug/debug.c \
 	generic/src/interrupt/interrupt.c \
 	generic/src/main/main.c \
@@ -220,5 +255,4 @@
 	generic/src/synch/spinlock.c \
 	generic/src/synch/condvar.c \
-	generic/src/synch/rwlock.c \
 	generic/src/synch/mutex.c \
 	generic/src/synch/semaphore.c \
@@ -273,9 +307,4 @@
 		test/mm/slab1.c \
 		test/mm/slab2.c \
-		test/synch/rwlock1.c \
-		test/synch/rwlock2.c \
-		test/synch/rwlock3.c \
-		test/synch/rwlock4.c \
-		test/synch/rwlock5.c \
 		test/synch/semaphore1.c \
 		test/synch/semaphore2.c \
@@ -339,8 +368,34 @@
 endif
 
+## Sources where instrumentation is enabled
+#
+
+ifeq ($(CONFIG_TRACE),y)
+	INSTRUMENTED_SOURCES = \
+		generic/src/adt/btree.c \
+		generic/src/cpu/cpu.c \
+		generic/src/ddi/ddi.c \
+		generic/src/interrupt/interrupt.c \
+		generic/src/main/main.c \
+		generic/src/main/kinit.c \
+		generic/src/proc/the.c \
+		generic/src/proc/tasklet.c \
+		generic/src/mm/frame.c \
+		generic/src/mm/page.c \
+		generic/src/mm/tlb.c \
+		generic/src/mm/as.c \
+		generic/src/mm/slab.c \
+		generic/src/sysinfo/sysinfo.c \
+		generic/src/console/kconsole.c
+else
+	INSTRUMENTED_SOURCES =
+endif
+
 GENERIC_OBJECTS := $(addsuffix .o,$(basename $(GENERIC_SOURCES)))
 ARCH_OBJECTS := $(addsuffix .o,$(basename $(ARCH_SOURCES)))
 GENARCH_OBJECTS := $(addsuffix .o,$(basename $(GENARCH_SOURCES)))
 
+LFLAGS_LTO := $(addprefix -Xlinker ,$(LFLAGS))
+
 ifeq ($(CONFIG_SYMTAB),y)
 	SYMTAB_OBJECTS := generic/src/debug/real_map.o
@@ -353,10 +408,18 @@
 
 $(DISASM): $(RAW)
+ifeq ($(CONFIG_LINE_DEBUG),y)
+	$(OBJDUMP) -d -S $< > $@
+else
 	$(OBJDUMP) -d $< > $@
+endif
 
 $(RAW): $(LINK) $(ARCH_OBJECTS) $(GENARCH_OBJECTS) $(GENERIC_OBJECTS) $(SYMTAB_OBJECTS)
-	$(LD) -N $(LFLAGS) -T $(LINK) -M -Map $(MAP) -o $@ $(ARCH_OBJECTS) $(GENARCH_OBJECTS) $(GENERIC_OBJECTS) $(EXTRA_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)
+else
+	$(LD) $(LFLAGS) -Map $(MAP) -o $@ $(ARCH_OBJECTS) $(GENARCH_OBJECTS) $(GENERIC_OBJECTS) $(EXTRA_OBJECTS) $(SYMTAB_OBJECTS)
+endif
 ifeq ($(CONFIG_STRIP_BINARIES),y)
-	$(STRIP) $(RAW) 
+	$(STRIP) $(RAW)
 endif
 
@@ -365,5 +428,5 @@
 
 %.o: %.S $(DEPEND)
-	$(GCC) $(DEFS) $(GCC_CFLAGS) -D__ASM__ -c $< -o $@
+	$(GCC) $(DEFS) $(GCC_CFLAGS) -D__ASM__ -c -o $@ $<
 ifeq ($(PRECHECK),y)
 	$(JOBFILE) $(JOB) $< $@ as asm/preproc $(DEFS) $(GCC_CFLAGS) -D__ASM__
@@ -382,5 +445,5 @@
 
 test/fpu/%.o: test/fpu/%.c $(DEPEND)
-	$(CC) $(DEFS) $(CFLAGS) $(EXTRA_FLAGS) -c $< -o $@
+	$(CC) $(DEFS) $(CFLAGS) $(EXTRA_FLAGS) -c -o $@ $<
 ifeq ($(PRECHECK),y)
 	$(JOBFILE) $(JOB) $< $@ cc test $(DEFS) $(CFLAGS) $(EXTRA_FLAGS)
@@ -392,5 +455,5 @@
 
 %.o: %.c $(DEPEND)
-	$(CC) $(DEFS) $(CFLAGS) $(EXTRA_FLAGS) $(FPU_NO_CFLAGS) -c $< -o $@
+	$(CC) $(DEFS) $(CFLAGS) $(EXTRA_FLAGS) $(FPU_NO_CFLAGS) $(if $(findstring $<,$(INSTRUMENTED_SOURCES)),$(INSTRUMENTATION)) -c -o $@ $<
 ifeq ($(PRECHECK),y)
 	$(JOBFILE) $(JOB) $< $@ cc core $(DEFS) $(CFLAGS) $(EXTRA_FLAGS) $(FPU_NO_CFLAGS)
@@ -402,5 +465,9 @@
 $(REAL_MAP).bin: $(LINK) $(ARCH_OBJECTS) $(GENARCH_OBJECTS) $(GENERIC_OBJECTS)
 	echo $(SYMTAB_SECTION) | $(AS) $(AFLAGS) -o $(EMPTY_MAP)
-	$(LD) -N $(LFLAGS) -T $(LINK) -M -Map $(MAP_PREV) -o $@ $(ARCH_OBJECTS) $(GENARCH_OBJECTS) $(GENERIC_OBJECTS) $(EXTRA_OBJECTS) $(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)
+else
+	$(LD) $(LFLAGS) -Map $(MAP_PREV) -o $@ $(ARCH_OBJECTS) $(GENARCH_OBJECTS) $(GENERIC_OBJECTS) $(EXTRA_OBJECTS) $(EMPTY_MAP)
+endif
 	$(OBJDUMP) -t $(ARCH_OBJECTS) $(GENARCH_OBJECTS) $(GENERIC_OBJECTS) > $(DUMP)
 	$(GENMAP) $(MAP_PREV) $(DUMP) $@
@@ -410,5 +477,9 @@
 	
 	echo $(SYMTAB_SECTION)" .incbin \"$@\"" | $(AS) $(AFLAGS) -o $(SIZEOK_MAP)
-	$(LD) -N $(LFLAGS) -T $(LINK) -M -Map $(MAP_PREV) -o $@ $(ARCH_OBJECTS) $(GENARCH_OBJECTS) $(GENERIC_OBJECTS) $(EXTRA_OBJECTS) $(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)
+else
+	$(LD) $(LFLAGS) -Map $(MAP_PREV) -o $@ $(ARCH_OBJECTS) $(GENARCH_OBJECTS) $(GENERIC_OBJECTS) $(EXTRA_OBJECTS) $(SIZEOK_MAP)
+endif
 	$(OBJDUMP) -t $(ARCH_OBJECTS) $(GENARCH_OBJECTS) $(GENERIC_OBJECTS) > $(DUMP)
 	$(GENMAP) $(MAP_PREV) $(DUMP) $@
Index: kernel/arch/abs32le/include/asm.h
===================================================================
--- kernel/arch/abs32le/include/asm.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/abs32le/include/asm.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -38,10 +38,11 @@
 #include <typedefs.h>
 #include <config.h>
-
-static inline void asm_delay_loop(uint32_t usec)
-{
-}
-
-static inline __attribute__((noreturn)) void cpu_halt(void)
+#include <trace.h>
+
+NO_TRACE static inline void asm_delay_loop(uint32_t usec)
+{
+}
+
+NO_TRACE static inline __attribute__((noreturn)) void cpu_halt(void)
 {
 	/* On real hardware this should stop processing further
@@ -53,5 +54,5 @@
 }
 
-static inline void cpu_sleep(void)
+NO_TRACE static inline void cpu_sleep(void)
 {
 	/* On real hardware this should put the CPU into low-power
@@ -61,5 +62,5 @@
 }
 
-static inline void pio_write_8(ioport8_t *port, uint8_t val)
+NO_TRACE static inline void pio_write_8(ioport8_t *port, uint8_t val)
 {
 }
@@ -73,5 +74,5 @@
  *
  */
-static inline void pio_write_16(ioport16_t *port, uint16_t val)
+NO_TRACE static inline void pio_write_16(ioport16_t *port, uint16_t val)
 {
 }
@@ -85,5 +86,5 @@
  *
  */
-static inline void pio_write_32(ioport32_t *port, uint32_t val)
+NO_TRACE static inline void pio_write_32(ioport32_t *port, uint32_t val)
 {
 }
@@ -97,5 +98,5 @@
  *
  */
-static inline uint8_t pio_read_8(ioport8_t *port)
+NO_TRACE static inline uint8_t pio_read_8(ioport8_t *port)
 {
 	return 0;
@@ -110,5 +111,5 @@
  *
  */
-static inline uint16_t pio_read_16(ioport16_t *port)
+NO_TRACE static inline uint16_t pio_read_16(ioport16_t *port)
 {
 	return 0;
@@ -123,62 +124,72 @@
  *
  */
-static inline uint32_t pio_read_32(ioport32_t *port)
-{
-	return 0;
-}
-
-static inline ipl_t interrupts_enable(void)
-{
-	/* On real hardware this unconditionally enables preemption
-	   by internal and external interrupts.
-	   
-	   The return value stores the previous interrupt level. */
-	
-	return 0;
-}
-
-static inline ipl_t interrupts_disable(void)
-{
-	/* On real hardware this disables preemption by the usual
-	   set of internal and external interrupts. This does not
-	   apply to special non-maskable interrupts and sychronous
-	   CPU exceptions.
-	   
-	   The return value stores the previous interrupt level. */
-	
-	return 0;
-}
-
-static inline void interrupts_restore(ipl_t ipl)
-{
-	/* On real hardware this either enables or disables preemption
-	   according to the interrupt level value from the argument. */
-}
-
-static inline ipl_t interrupts_read(void)
-{
-	/* On real hardware the return value stores the current interrupt
-	   level. */
-	
-	return 0;
-}
-
-static inline uintptr_t get_stack_base(void)
-{
-	/* On real hardware this returns the address of the bottom
-	   of the current CPU stack. The the_t structure is stored
-	   on the bottom of stack and this is used to identify the
-	   current CPU, current task, current thread and current
-	   address space. */
-	
-	return 0;
-}
-
-static inline uintptr_t *get_ip()
-{
-	/* On real hardware this returns the current instruction
-	   pointer value. The value certainly changes with each
-	   instruction, but it can be still used to identify
-	   a specific function. */
+NO_TRACE static inline uint32_t pio_read_32(ioport32_t *port)
+{
+	return 0;
+}
+
+NO_TRACE static inline ipl_t interrupts_enable(void)
+{
+	/*
+	 * On real hardware this unconditionally enables preemption
+	 * by internal and external interrupts.
+	 *
+	 * The return value stores the previous interrupt level.
+	 */
+	
+	return 0;
+}
+
+NO_TRACE static inline ipl_t interrupts_disable(void)
+{
+	/*
+	 * On real hardware this disables preemption by the usual
+	 * set of internal and external interrupts. This does not
+	 * apply to special non-maskable interrupts and sychronous
+	 * CPU exceptions.
+	 *
+	 * The return value stores the previous interrupt level.
+	 */
+	
+	return 0;
+}
+
+NO_TRACE static inline void interrupts_restore(ipl_t ipl)
+{
+	/*
+	 * On real hardware this either enables or disables preemption
+	 * according to the interrupt level value from the argument.
+	 */
+}
+
+NO_TRACE static inline ipl_t interrupts_read(void)
+{
+	/*
+	 * On real hardware the return value stores the current interrupt
+	 * level.
+	 */
+	
+	return 0;
+}
+
+NO_TRACE static inline bool interrupts_disabled(void)
+{
+	/*
+	 * On real hardware the return value is true iff interrupts are
+	 * disabled.
+	 */
+	
+	return false;
+}
+
+NO_TRACE static inline uintptr_t get_stack_base(void)
+{
+	/*
+	 * On real hardware this returns the address of the bottom
+	 * of the current CPU stack. The the_t structure is stored
+	 * on the bottom of stack and this is used to identify the
+	 * current CPU, current task, current thread and current
+	 * address space.
+	 */
 	
 	return 0;
Index: kernel/arch/abs32le/include/atomic.h
===================================================================
--- kernel/arch/abs32le/include/atomic.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/abs32le/include/atomic.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -39,6 +39,12 @@
 #include <arch/barrier.h>
 #include <preemption.h>
+#include <verify.h>
+#include <trace.h>
 
-static inline void atomic_inc(atomic_t *val) {
+NO_TRACE ATOMIC static inline void atomic_inc(atomic_t *val)
+    WRITES(&val->count)
+    REQUIRES_EXTENT_MUTABLE(val)
+    REQUIRES(val->count < ATOMIC_COUNT_MAX)
+{
 	/* On real hardware the increment has to be done
 	   as an atomic action. */
@@ -47,12 +53,19 @@
 }
 
-static inline void atomic_dec(atomic_t *val) {
+NO_TRACE ATOMIC static inline void atomic_dec(atomic_t *val)
+    WRITES(&val->count)
+    REQUIRES_EXTENT_MUTABLE(val)
+    REQUIRES(val->count > ATOMIC_COUNT_MIN)
+{
 	/* On real hardware the decrement has to be done
 	   as an atomic action. */
 	
-	val->count++;
+	val->count--;
 }
 
-static inline atomic_count_t atomic_postinc(atomic_t *val)
+NO_TRACE ATOMIC static inline atomic_count_t atomic_postinc(atomic_t *val)
+    WRITES(&val->count)
+    REQUIRES_EXTENT_MUTABLE(val)
+    REQUIRES(val->count < ATOMIC_COUNT_MAX)
 {
 	/* On real hardware both the storing of the previous
@@ -66,5 +79,8 @@
 }
 
-static inline atomic_count_t atomic_postdec(atomic_t *val)
+NO_TRACE ATOMIC static inline atomic_count_t atomic_postdec(atomic_t *val)
+    WRITES(&val->count)
+    REQUIRES_EXTENT_MUTABLE(val)
+    REQUIRES(val->count > ATOMIC_COUNT_MIN)
 {
 	/* On real hardware both the storing of the previous
@@ -81,6 +97,12 @@
 #define atomic_predec(val)  (atomic_postdec(val) - 1)
 
-static inline atomic_count_t test_and_set(atomic_t *val)
+NO_TRACE ATOMIC static inline atomic_count_t test_and_set(atomic_t *val)
+    WRITES(&val->count)
+    REQUIRES_EXTENT_MUTABLE(val)
 {
+	/* On real hardware the retrieving of the original
+	   value and storing 1 have to be done as a single
+	   atomic action. */
+	
 	atomic_count_t prev = val->count;
 	val->count = 1;
@@ -88,5 +110,7 @@
 }
 
-static inline void atomic_lock_arch(atomic_t *val)
+NO_TRACE static inline void atomic_lock_arch(atomic_t *val)
+    WRITES(&val->count)
+    REQUIRES_EXTENT_MUTABLE(val)
 {
 	do {
Index: kernel/arch/abs32le/include/cycle.h
===================================================================
--- kernel/arch/abs32le/include/cycle.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/abs32le/include/cycle.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -36,5 +36,7 @@
 #define KERN_abs32le_CYCLE_H_
 
-static inline uint64_t get_cycle(void)
+#include <trace.h>
+
+NO_TRACE static inline uint64_t get_cycle(void)
 {
 	return 0;
Index: rnel/arch/abs32le/include/debug.h
===================================================================
--- kernel/arch/abs32le/include/debug.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ 	(revision )
@@ -1,45 +1,0 @@
-/*
- * Copyright (c) 2010 Martin Decky
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/** @addtogroup abs32ledebug
- * @{
- */
-/** @file
- */
-
-#ifndef KERN_abs32le_DEBUG_H_
-#define KERN_abs32le_DEBUG_H_
-
-#include <arch/asm.h>
-
-#define HERE  get_ip()
-
-#endif
-
-/** @}
- */
Index: kernel/arch/abs32le/include/interrupt.h
===================================================================
--- kernel/arch/abs32le/include/interrupt.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/abs32le/include/interrupt.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -37,4 +37,6 @@
 
 #include <typedefs.h>
+#include <verify.h>
+#include <trace.h>
 
 #define IVT_ITEMS  0
@@ -53,5 +55,6 @@
 } istate_t;
 
-static inline int istate_from_uspace(istate_t *istate)
+NO_TRACE static inline int istate_from_uspace(istate_t *istate)
+    REQUIRES_EXTENT_MUTABLE(istate)
 {
 	/* On real hardware this checks whether the interrupted
@@ -61,5 +64,7 @@
 }
 
-static inline void istate_set_retaddr(istate_t *istate, uintptr_t retaddr)
+NO_TRACE static inline void istate_set_retaddr(istate_t *istate,
+    uintptr_t retaddr)
+    WRITES(&istate->ip)
 {
 	/* On real hardware this sets the instruction pointer. */
@@ -68,5 +73,6 @@
 }
 
-static inline unative_t istate_get_pc(istate_t *istate)
+NO_TRACE static inline unative_t istate_get_pc(istate_t *istate)
+    REQUIRES_EXTENT_MUTABLE(istate)
 {
 	/* On real hardware this returns the instruction pointer. */
@@ -75,5 +81,6 @@
 }
 
-static inline unative_t istate_get_fp(istate_t *istate)
+NO_TRACE static inline unative_t istate_get_fp(istate_t *istate)
+    REQUIRES_EXTENT_MUTABLE(istate)
 {
 	/* On real hardware this returns the frame pointer. */
Index: kernel/arch/abs32le/include/mm/page.h
===================================================================
--- kernel/arch/abs32le/include/mm/page.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/abs32le/include/mm/page.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -37,4 +37,5 @@
 
 #include <arch/mm/frame.h>
+#include <trace.h>
 
 #define PAGE_WIDTH  FRAME_WIDTH
@@ -139,18 +140,23 @@
 } __attribute__((packed)) pte_t;
 
-static inline unsigned int get_pt_flags(pte_t *pt, size_t i)
+NO_TRACE static inline unsigned int get_pt_flags(pte_t *pt, size_t i)
+    REQUIRES_ARRAY_MUTABLE(pt, PTL0_ENTRIES_ARCH)
 {
 	pte_t *p = &pt[i];
 	
-	return ((!p->page_cache_disable) << PAGE_CACHEABLE_SHIFT |
-	    (!p->present) << PAGE_PRESENT_SHIFT |
-	    p->uaccessible << PAGE_USER_SHIFT |
-	    1 << PAGE_READ_SHIFT |
-	    p->writeable << PAGE_WRITE_SHIFT |
-	    1 << PAGE_EXEC_SHIFT |
-	    p->global << PAGE_GLOBAL_SHIFT);
+	return (
+	    ((unsigned int) (!p->page_cache_disable) << PAGE_CACHEABLE_SHIFT) |
+	    ((unsigned int) (!p->present) << PAGE_PRESENT_SHIFT) |
+	    ((unsigned int) p->uaccessible << PAGE_USER_SHIFT) |
+	    (1 << PAGE_READ_SHIFT) |
+	    ((unsigned int) p->writeable << PAGE_WRITE_SHIFT) |
+	    (1 << PAGE_EXEC_SHIFT) |
+	    ((unsigned int) p->global << PAGE_GLOBAL_SHIFT)
+	);
 }
 
-static inline void set_pt_flags(pte_t *pt, size_t i, int flags)
+NO_TRACE static inline void set_pt_flags(pte_t *pt, size_t i, int flags)
+    WRITES(ARRAY_RANGE(pt, PTL0_ENTRIES_ARCH))
+    REQUIRES_ARRAY_MUTABLE(pt, PTL0_ENTRIES_ARCH)
 {
 	pte_t *p = &pt[i];
@@ -170,5 +176,5 @@
 
 extern void page_arch_init(void);
-extern void page_fault(int, istate_t *);
+extern void page_fault(unsigned int, istate_t *);
 
 #endif /* KERNEL */
Index: kernel/arch/abs32le/include/types.h
===================================================================
--- kernel/arch/abs32le/include/types.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/abs32le/include/types.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -35,4 +35,7 @@
 #ifndef KERN_abs32le_TYPES_H_
 #define KERN_abs32le_TYPES_H_
+
+#define ATOMIC_COUNT_MIN  UINT32_MIN
+#define ATOMIC_COUNT_MAX  UINT32_MAX
 
 typedef uint32_t size_t;
Index: kernel/arch/abs32le/src/abs32le.c
===================================================================
--- kernel/arch/abs32le/src/abs32le.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/abs32le/src/abs32le.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -114,13 +114,7 @@
 }
 
-void panic_printf(const char *fmt, ...)
+void istate_decode(istate_t *istate)
 {
-	va_list args;
-	
-	va_start(args, fmt);
-	vprintf(fmt, args);
-	va_end(args);
-	
-	halt();
+	(void) istate;
 }
 
@@ -157,4 +151,8 @@
 }
 
+void early_putchar(wchar_t ch)
+{
+}
+
 /** @}
  */
Index: kernel/arch/abs32le/src/debug/stacktrace.c
===================================================================
--- kernel/arch/abs32le/src/debug/stacktrace.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/abs32le/src/debug/stacktrace.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -37,30 +37,30 @@
 #include <typedefs.h>
 
-bool kernel_frame_pointer_validate(uintptr_t fp)
+bool kernel_stack_trace_context_validate(stack_trace_context_t *ctx)
 {
 	return true;
 }
 
-bool kernel_frame_pointer_prev(uintptr_t fp, uintptr_t *prev)
+bool kernel_frame_pointer_prev(stack_trace_context_t *ctx, uintptr_t *prev)
 {
 	return true;
 }
 
-bool kernel_return_address_get(uintptr_t fp, uintptr_t *ra)
+bool kernel_return_address_get(stack_trace_context_t *ctx, uintptr_t *ra)
 {
 	return true;
 }
 
-bool uspace_frame_pointer_validate(uintptr_t fp)
+bool uspace_stack_trace_context_validate(stack_trace_context_t *ctx)
 {
 	return true;
 }
 
-bool uspace_frame_pointer_prev(uintptr_t fp, uintptr_t *prev)
+bool uspace_frame_pointer_prev(stack_trace_context_t *ctx, uintptr_t *prev)
 {
 	return true;
 }
 
-bool uspace_return_address_get(uintptr_t fp, uintptr_t *ra)
+bool uspace_return_address_get(stack_trace_context_t *ctx, uintptr_t *ra)
 {
 	return true;
Index: kernel/arch/abs32le/src/mm/page.c
===================================================================
--- kernel/arch/abs32le/src/mm/page.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/abs32le/src/mm/page.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -62,5 +62,5 @@
 }
 
-void page_fault(int n __attribute__((unused)), istate_t *istate)
+void page_fault(unsigned int n __attribute__((unused)), istate_t *istate)
 {
 }
Index: kernel/arch/amd64/Makefile.inc
===================================================================
--- kernel/arch/amd64/Makefile.inc	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/amd64/Makefile.inc	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -33,5 +33,5 @@
 
 FPU_NO_CFLAGS = -mno-sse -mno-sse2
-CMN1 = -m64 -mcmodel=kernel -mno-red-zone -fno-unwind-tables -fno-omit-frame-pointer
+CMN1 = -m64 -mcmodel=large -mno-red-zone -fno-unwind-tables -fno-omit-frame-pointer
 GCC_CFLAGS += $(CMN1)
 ICC_CFLAGS += $(CMN1)
@@ -71,5 +71,5 @@
 	arch/$(KARCH)/src/mm/page.c \
 	arch/$(KARCH)/src/mm/tlb.c \
-	arch/$(KARCH)/src/asm_utils.S \
+	arch/$(KARCH)/src/asm.S \
 	arch/$(KARCH)/src/cpu/cpu.c \
 	arch/$(KARCH)/src/proc/scheduler.c \
Index: kernel/arch/amd64/_link.ld.in
===================================================================
--- kernel/arch/amd64/_link.ld.in	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/amd64/_link.ld.in	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -1,10 +1,10 @@
 /** AMD64 linker script
- *  
+ *
  * umapped section:
- * 	kernel text
- * 	kernel data
+ *  kernel text
+ *  kernel data
  * mapped section:
- *	kernel text
- *	kernel data 
+ *  kernel text
+ *  kernel data
  */
 
@@ -17,5 +17,5 @@
 		*(K_TEXT_START);
 		unmapped_ktext_end = .;
-
+		
 		unmapped_kdata_start = .;
 		*(K_DATA_START);
@@ -23,13 +23,13 @@
 		unmapped_kdata_end = .;
 	}
-
+	
 	.mapped (PA2KA(BOOT_OFFSET)+SIZEOF(.unmapped)) : AT (SIZEOF(.unmapped)) {
 		ktext_start = .;
 		*(.text);
 		ktext_end = .;
-
+		
 		kdata_start = .;
-		*(.data);		/* initialized data */
-		*(.rodata*);		/* string literals */
+		*(.data);       /* initialized data */
+		*(.rodata*);    /* string literals */
 		hardcoded_load_address = .;
 		QUAD(PA2KA(BOOT_OFFSET));
@@ -42,26 +42,38 @@
 		hardcoded_unmapped_kdata_size = .;
 		QUAD(unmapped_kdata_end - unmapped_kdata_start);
-		*(COMMON);		/* global variables */
-
+		*(COMMON);      /* global variables */
+		
 		. = ALIGN(8);
 		symbol_table = .;
-		*(symtab.*);            /* Symbol table, must be LAST symbol!*/
-
-		*(.bss);		/* uninitialized static variables */
-
+		*(symtab.*);    /* Symbol table, must be LAST symbol!*/
+		
+		*(.bss);        /* uninitialized static variables */
+		
 		kdata_end = .;
 	}
-
+	
+#ifdef CONFIG_LINE_DEBUG
+	.comment 0 : { *(.comment); }
+	.debug_abbrev 0 : { *(.debug_abbrev); }
+	.debug_aranges 0 : { *(.debug_aranges); }
+	.debug_info 0 : { *(.debug_info); }
+	.debug_line 0 : { *(.debug_line); }
+	.debug_loc 0 : { *(.debug_loc); }
+	.debug_pubnames 0 : { *(.debug_pubnames); }
+	.debug_pubtypes 0 : { *(.debug_pubtypes); }
+	.debug_ranges 0 : { *(.debug_ranges); }
+	.debug_str 0 : { *(.debug_str); }
+#endif
+	
 	/DISCARD/ : {
 		*(*);
 	}
 	
-#ifdef CONFIG_SMP	
+#ifdef CONFIG_SMP
 	_hardcoded_unmapped_size = (unmapped_ktext_end - unmapped_ktext_start) + (unmapped_kdata_end - unmapped_kdata_start);
 	ap_boot = unmapped_ap_boot - BOOT_OFFSET + AP_BOOT_OFFSET;
 	ap_gdtr = unmapped_ap_gdtr - BOOT_OFFSET + AP_BOOT_OFFSET;
 	protected_ap_gdtr = PA2KA(ap_gdtr);
-
 #endif /* CONFIG_SMP */
-
+	
 }
Index: kernel/arch/amd64/include/arch.h
===================================================================
--- kernel/arch/amd64/include/arch.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/amd64/include/arch.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -27,5 +27,5 @@
  */
 
-/** @addtogroup amd64	
+/** @addtogroup amd64
  * @{
  */
Index: kernel/arch/amd64/include/asm.h
===================================================================
--- kernel/arch/amd64/include/asm.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/amd64/include/asm.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -38,7 +38,6 @@
 #include <config.h>
 #include <typedefs.h>
-
-extern void asm_delay_loop(uint32_t t);
-extern void asm_fake_loop(uint32_t t);
+#include <arch/cpu.h>
+#include <trace.h>
 
 /** Return base address of current stack.
@@ -49,5 +48,5 @@
  *
  */
-static inline uintptr_t get_stack_base(void)
+NO_TRACE static inline uintptr_t get_stack_base(void)
 {
 	uintptr_t v;
@@ -56,5 +55,5 @@
 		"andq %%rsp, %[v]\n"
 		: [v] "=r" (v)
-		: "0" (~((uint64_t) STACK_SIZE-1))
+		: "0" (~((uint64_t) STACK_SIZE - 1))
 	);
 	
@@ -62,10 +61,12 @@
 }
 
-static inline void cpu_sleep(void)
-{
-	asm volatile ("hlt\n");
-}
-
-static inline void __attribute__((noreturn)) cpu_halt(void)
+NO_TRACE static inline void cpu_sleep(void)
+{
+	asm volatile (
+		"hlt\n"
+	);
+}
+
+NO_TRACE static inline void __attribute__((noreturn)) cpu_halt(void)
 {
 	while (true) {
@@ -76,5 +77,4 @@
 }
 
-
 /** Byte from port
  *
@@ -85,5 +85,5 @@
  *
  */
-static inline uint8_t pio_read_8(ioport8_t *port)
+NO_TRACE static inline uint8_t pio_read_8(ioport8_t *port)
 {
 	uint8_t val;
@@ -106,5 +106,5 @@
  *
  */
-static inline uint16_t pio_read_16(ioport16_t *port)
+NO_TRACE static inline uint16_t pio_read_16(ioport16_t *port)
 {
 	uint16_t val;
@@ -127,5 +127,5 @@
  *
  */
-static inline uint32_t pio_read_32(ioport32_t *port)
+NO_TRACE static inline uint32_t pio_read_32(ioport32_t *port)
 {
 	uint32_t val;
@@ -148,9 +148,10 @@
  *
  */
-static inline void pio_write_8(ioport8_t *port, uint8_t val)
+NO_TRACE static inline void pio_write_8(ioport8_t *port, uint8_t val)
 {
 	asm volatile (
 		"outb %b[val], %w[port]\n"
-		:: [val] "a" (val), [port] "d" (port)
+		:: [val] "a" (val),
+		   [port] "d" (port)
 	);
 }
@@ -164,9 +165,10 @@
  *
  */
-static inline void pio_write_16(ioport16_t *port, uint16_t val)
+NO_TRACE static inline void pio_write_16(ioport16_t *port, uint16_t val)
 {
 	asm volatile (
 		"outw %w[val], %w[port]\n"
-		:: [val] "a" (val), [port] "d" (port)
+		:: [val] "a" (val),
+		   [port] "d" (port)
 	);
 }
@@ -180,16 +182,19 @@
  *
  */
-static inline void pio_write_32(ioport32_t *port, uint32_t val)
+NO_TRACE static inline void pio_write_32(ioport32_t *port, uint32_t val)
 {
 	asm volatile (
 		"outl %[val], %w[port]\n"
-		:: [val] "a" (val), [port] "d" (port)
+		:: [val] "a" (val),
+		   [port] "d" (port)
 	);
 }
 
 /** Swap Hidden part of GS register with visible one */
-static inline void swapgs(void)
-{
-	asm volatile("swapgs");
+NO_TRACE static inline void swapgs(void)
+{
+	asm volatile (
+		"swapgs"
+	);
 }
 
@@ -202,5 +207,5 @@
  *
  */
-static inline ipl_t interrupts_enable(void) {
+NO_TRACE static inline ipl_t interrupts_enable(void) {
 	ipl_t v;
 	
@@ -223,5 +228,5 @@
  *
  */
-static inline ipl_t interrupts_disable(void) {
+NO_TRACE static inline ipl_t interrupts_disable(void) {
 	ipl_t v;
 	
@@ -243,5 +248,5 @@
  *
  */
-static inline void interrupts_restore(ipl_t ipl) {
+NO_TRACE static inline void interrupts_restore(ipl_t ipl) {
 	asm volatile (
 		"pushq %[ipl]\n"
@@ -258,5 +263,5 @@
  *
  */
-static inline ipl_t interrupts_read(void) {
+NO_TRACE static inline ipl_t interrupts_read(void) {
 	ipl_t v;
 	
@@ -270,6 +275,24 @@
 }
 
+/** Check interrupts state.
+ *
+ * @return True if interrupts are disabled.
+ *
+ */
+NO_TRACE static inline bool interrupts_disabled(void)
+{
+	ipl_t v;
+	
+	asm volatile (
+		"pushfq\n"
+		"popq %[v]\n"
+		: [v] "=r" (v)
+	);
+	
+	return ((v & RFLAGS_IF) == 0);
+}
+
 /** Write to MSR */
-static inline void write_msr(uint32_t msr, uint64_t value)
+NO_TRACE static inline void write_msr(uint32_t msr, uint64_t value)
 {
 	asm volatile (
@@ -281,5 +304,5 @@
 }
 
-static inline unative_t read_msr(uint32_t msr)
+NO_TRACE static inline unative_t read_msr(uint32_t msr)
 {
 	uint32_t ax, dx;
@@ -294,5 +317,4 @@
 }
 
-
 /** Enable local APIC
  *
@@ -300,5 +322,5 @@
  *
  */
-static inline void enable_l_apic_in_msr()
+NO_TRACE static inline void enable_l_apic_in_msr()
 {
 	asm volatile (
@@ -308,18 +330,6 @@
 		"orl $(0xfee00000),%%eax\n"
 		"wrmsr\n"
-		::: "%eax","%ecx","%edx"
-	);
-}
-
-static inline uintptr_t * get_ip() 
-{
-	uintptr_t *ip;
-	
-	asm volatile (
-		"mov %%rip, %[ip]"
-		: [ip] "=r" (ip)
-	);
-	
-	return ip;
+		::: "%eax", "%ecx", "%edx"
+	);
 }
 
@@ -329,5 +339,5 @@
  *
  */
-static inline void invlpg(uintptr_t addr)
+NO_TRACE static inline void invlpg(uintptr_t addr)
 {
 	asm volatile (
@@ -342,5 +352,5 @@
  *
  */
-static inline void gdtr_load(ptr_16_64_t *gdtr_reg)
+NO_TRACE static inline void gdtr_load(ptr_16_64_t *gdtr_reg)
 {
 	asm volatile (
@@ -355,5 +365,5 @@
  *
  */
-static inline void gdtr_store(ptr_16_64_t *gdtr_reg)
+NO_TRACE static inline void gdtr_store(ptr_16_64_t *gdtr_reg)
 {
 	asm volatile (
@@ -368,5 +378,5 @@
  *
  */
-static inline void idtr_load(ptr_16_64_t *idtr_reg)
+NO_TRACE static inline void idtr_load(ptr_16_64_t *idtr_reg)
 {
 	asm volatile (
@@ -380,5 +390,5 @@
  *
  */
-static inline void tr_load(uint16_t sel)
+NO_TRACE static inline void tr_load(uint16_t sel)
 {
 	asm volatile (
@@ -388,5 +398,5 @@
 }
 
-#define GEN_READ_REG(reg) static inline unative_t read_ ##reg (void) \
+#define GEN_READ_REG(reg) NO_TRACE static inline unative_t read_ ##reg (void) \
 	{ \
 		unative_t res; \
@@ -398,5 +408,5 @@
 	}
 
-#define GEN_WRITE_REG(reg) static inline void write_ ##reg (unative_t regn) \
+#define GEN_WRITE_REG(reg) NO_TRACE static inline void write_ ##reg (unative_t regn) \
 	{ \
 		asm volatile ( \
@@ -425,6 +435,71 @@
 GEN_WRITE_REG(dr7)
 
-extern size_t interrupt_handler_size;
-extern void interrupt_handlers(void);
+extern void asm_delay_loop(uint32_t);
+extern void asm_fake_loop(uint32_t);
+
+extern uintptr_t int_0;
+extern uintptr_t int_1;
+extern uintptr_t int_2;
+extern uintptr_t int_3;
+extern uintptr_t int_4;
+extern uintptr_t int_5;
+extern uintptr_t int_6;
+extern uintptr_t int_7;
+extern uintptr_t int_8;
+extern uintptr_t int_9;
+extern uintptr_t int_10;
+extern uintptr_t int_11;
+extern uintptr_t int_12;
+extern uintptr_t int_13;
+extern uintptr_t int_14;
+extern uintptr_t int_15;
+extern uintptr_t int_16;
+extern uintptr_t int_17;
+extern uintptr_t int_18;
+extern uintptr_t int_19;
+extern uintptr_t int_20;
+extern uintptr_t int_21;
+extern uintptr_t int_22;
+extern uintptr_t int_23;
+extern uintptr_t int_24;
+extern uintptr_t int_25;
+extern uintptr_t int_26;
+extern uintptr_t int_27;
+extern uintptr_t int_28;
+extern uintptr_t int_29;
+extern uintptr_t int_30;
+extern uintptr_t int_31;
+extern uintptr_t int_32;
+extern uintptr_t int_33;
+extern uintptr_t int_34;
+extern uintptr_t int_35;
+extern uintptr_t int_36;
+extern uintptr_t int_37;
+extern uintptr_t int_38;
+extern uintptr_t int_39;
+extern uintptr_t int_40;
+extern uintptr_t int_41;
+extern uintptr_t int_42;
+extern uintptr_t int_43;
+extern uintptr_t int_44;
+extern uintptr_t int_45;
+extern uintptr_t int_46;
+extern uintptr_t int_47;
+extern uintptr_t int_48;
+extern uintptr_t int_49;
+extern uintptr_t int_50;
+extern uintptr_t int_51;
+extern uintptr_t int_52;
+extern uintptr_t int_53;
+extern uintptr_t int_54;
+extern uintptr_t int_55;
+extern uintptr_t int_56;
+extern uintptr_t int_57;
+extern uintptr_t int_58;
+extern uintptr_t int_59;
+extern uintptr_t int_60;
+extern uintptr_t int_61;
+extern uintptr_t int_62;
+extern uintptr_t int_63;
 
 #endif
Index: kernel/arch/amd64/include/atomic.h
===================================================================
--- kernel/arch/amd64/include/atomic.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/amd64/include/atomic.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -39,6 +39,7 @@
 #include <arch/barrier.h>
 #include <preemption.h>
+#include <trace.h>
 
-static inline void atomic_inc(atomic_t *val)
+NO_TRACE static inline void atomic_inc(atomic_t *val)
 {
 #ifdef CONFIG_SMP
@@ -55,5 +56,5 @@
 }
 
-static inline void atomic_dec(atomic_t *val)
+NO_TRACE static inline void atomic_dec(atomic_t *val)
 {
 #ifdef CONFIG_SMP
@@ -70,5 +71,5 @@
 }
 
-static inline atomic_count_t atomic_postinc(atomic_t *val)
+NO_TRACE static inline atomic_count_t atomic_postinc(atomic_t *val)
 {
 	atomic_count_t r = 1;
@@ -83,5 +84,5 @@
 }
 
-static inline atomic_count_t atomic_postdec(atomic_t *val)
+NO_TRACE static inline atomic_count_t atomic_postdec(atomic_t *val)
 {
 	atomic_count_t r = -1;
@@ -99,5 +100,5 @@
 #define atomic_predec(val)  (atomic_postdec(val) - 1)
 
-static inline atomic_count_t test_and_set(atomic_t *val)
+NO_TRACE static inline atomic_count_t test_and_set(atomic_t *val)
 {
 	atomic_count_t v = 1;
@@ -113,5 +114,5 @@
 
 /** amd64 specific fast spinlock */
-static inline void atomic_lock_arch(atomic_t *val)
+NO_TRACE static inline void atomic_lock_arch(atomic_t *val)
 {
 	atomic_count_t tmp;
@@ -120,13 +121,13 @@
 	asm volatile (
 		"0:\n"
-		"pause\n"
-		"mov %[count], %[tmp]\n"
-		"testq %[tmp], %[tmp]\n"
-		"jnz 0b\n"       /* lightweight looping on locked spinlock */
+		"	pause\n"
+		"	mov %[count], %[tmp]\n"
+		"	testq %[tmp], %[tmp]\n"
+		"	jnz 0b\n"       /* lightweight looping on locked spinlock */
 		
-		"incq %[tmp]\n"  /* now use the atomic operation */
-		"xchgq %[count], %[tmp]\n"
-		"testq %[tmp], %[tmp]\n"
-		"jnz 0b\n"
+		"	incq %[tmp]\n"  /* now use the atomic operation */
+		"	xchgq %[count], %[tmp]\n"
+		"	testq %[tmp], %[tmp]\n"
+		"	jnz 0b\n"
 		: [count] "+m" (val->count),
 		  [tmp] "=&r" (tmp)
Index: kernel/arch/amd64/include/boot/boot.h
===================================================================
--- kernel/arch/amd64/include/boot/boot.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/amd64/include/boot/boot.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -27,5 +27,5 @@
  */
 
-/** @addtogroup amd64	
+/** @addtogroup amd64
  * @{
  */
@@ -36,10 +36,10 @@
 #define KERN_amd64_BOOT_H_
 
-#define BOOT_OFFSET		0x108000
-#define AP_BOOT_OFFSET		0x8000
-#define BOOT_STACK_SIZE		0x400
+#define BOOT_OFFSET      0x108000
+#define AP_BOOT_OFFSET   0x008000
+#define BOOT_STACK_SIZE  0x000400
 
-#define MULTIBOOT_HEADER_MAGIC	0x1BADB002
-#define MULTIBOOT_HEADER_FLAGS	0x00010003
+#define MULTIBOOT_HEADER_MAGIC  0x1BADB002
+#define MULTIBOOT_HEADER_FLAGS  0x00010003
 
 #ifndef __ASM__
Index: kernel/arch/amd64/include/context.h
===================================================================
--- kernel/arch/amd64/include/context.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/amd64/include/context.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -59,16 +59,16 @@
  */
 typedef struct {
-    uintptr_t sp;
-    uintptr_t pc;
-    
-    uint64_t rbx;
-    uint64_t rbp;
-
-    uint64_t r12;
-    uint64_t r13;
-    uint64_t r14;
-    uint64_t r15;
-
-    ipl_t ipl;
+	uintptr_t sp;
+	uintptr_t pc;
+	
+	uint64_t rbx;
+	uint64_t rbp;
+	
+	uint64_t r12;
+	uint64_t r13;
+	uint64_t r14;
+	uint64_t r15;
+	
+	ipl_t ipl;
 } __attribute__ ((packed)) context_t;
 
Index: kernel/arch/amd64/include/cpu.h
===================================================================
--- kernel/arch/amd64/include/cpu.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/amd64/include/cpu.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -45,4 +45,5 @@
 #define RFLAGS_DF	(1 << 10)
 #define RFLAGS_OF	(1 << 11)
+#define RFLAGS_NT	(1 << 14)
 #define RFLAGS_RF	(1 << 16)
 
Index: kernel/arch/amd64/include/cycle.h
===================================================================
--- kernel/arch/amd64/include/cycle.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/amd64/include/cycle.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -36,5 +36,19 @@
 #define KERN_amd64_CYCLE_H_
 
-extern uint64_t get_cycle(void);
+#include <trace.h>
+
+NO_TRACE static inline uint64_t get_cycle(void)
+{
+	uint32_t lower;
+	uint32_t upper;
+	
+	asm volatile (
+		"rdtsc\n"
+		: "=a" (lower),
+		  "=d" (upper)
+	);
+	
+	return ((uint64_t) lower) | (((uint64_t) upper) << 32);
+}
 
 #endif
Index: kernel/arch/amd64/include/ddi/ddi.h
===================================================================
--- kernel/arch/amd64/include/ddi/ddi.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/amd64/include/ddi/ddi.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -33,5 +33,5 @@
 /**
  * @file
- * @brief	amd64 specific DDI declarations and macros.
+ * @brief amd64 specific DDI declarations and macros.
  */
 
Index: rnel/arch/amd64/include/debug.h
===================================================================
--- kernel/arch/amd64/include/debug.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ 	(revision )
@@ -1,1 +1,0 @@
-../../ia32/include/debug.h
Index: kernel/arch/amd64/include/debugger.h
===================================================================
--- kernel/arch/amd64/include/debugger.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/amd64/include/debugger.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -38,17 +38,17 @@
 #include <typedefs.h>
 
-#define BKPOINTS_MAX 4
+#define BKPOINTS_MAX  4
 
 /* Flags that are passed to breakpoint_add function */
-#define BKPOINT_INSTR        0x1
-#define BKPOINT_WRITE        0x2 
-#define BKPOINT_READ_WRITE   0x4
+#define BKPOINT_INSTR       0x1
+#define BKPOINT_WRITE       0x2
+#define BKPOINT_READ_WRITE  0x4
 
-#define BKPOINT_CHECK_ZERO   0x8
+#define BKPOINT_CHECK_ZERO  0x8
 
 
 extern void debugger_init(void);
-extern int breakpoint_add(const void *where, const int flags, int curidx);
-extern void breakpoint_del(int slot);
+extern int breakpoint_add(const void *, const unsigned int, int);
+extern void breakpoint_del(int);
 
 #endif
Index: kernel/arch/amd64/include/elf.h
===================================================================
--- kernel/arch/amd64/include/elf.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/amd64/include/elf.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -27,5 +27,5 @@
  */
 
-/** @addtogroup amd64	
+/** @addtogroup amd64
  * @{
  */
@@ -36,7 +36,7 @@
 #define KERN_amd64_ELF_H_
 
-#define	ELF_MACHINE		EM_X86_64
-#define ELF_DATA_ENCODING	ELFDATA2LSB
-#define ELF_CLASS		ELFCLASS64
+#define ELF_MACHINE        EM_X86_64
+#define ELF_DATA_ENCODING  ELFDATA2LSB
+#define ELF_CLASS          ELFCLASS64
 
 #endif
Index: kernel/arch/amd64/include/faddr.h
===================================================================
--- kernel/arch/amd64/include/faddr.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/amd64/include/faddr.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -27,5 +27,5 @@
  */
 
-/** @addtogroup amd64	
+/** @addtogroup amd64
  * @{
  */
@@ -38,5 +38,5 @@
 #include <typedefs.h>
 
-#define FADDR(fptr)		((uintptr_t) (fptr))
+#define FADDR(fptr)  ((uintptr_t) (fptr))
 
 #endif
Index: kernel/arch/amd64/include/interrupt.h
===================================================================
--- kernel/arch/amd64/include/interrupt.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/amd64/include/interrupt.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -38,24 +38,25 @@
 #include <typedefs.h>
 #include <arch/pm.h>
+#include <trace.h>
 
-#define IVT_ITEMS		IDT_ITEMS
-#define IVT_FIRST		0
+#define IVT_ITEMS  IDT_ITEMS
+#define IVT_FIRST  0
 
-#define EXC_COUNT		32
-#define IRQ_COUNT		16
+#define EXC_COUNT  32
+#define IRQ_COUNT  16
 
-#define IVT_EXCBASE		0
-#define IVT_IRQBASE		(IVT_EXCBASE + EXC_COUNT)
-#define IVT_FREEBASE		(IVT_IRQBASE + IRQ_COUNT)
+#define IVT_EXCBASE   0
+#define IVT_IRQBASE   (IVT_EXCBASE + EXC_COUNT)
+#define IVT_FREEBASE  (IVT_IRQBASE + IRQ_COUNT)
 
-#define IRQ_CLK			0
-#define IRQ_KBD			1
-#define IRQ_PIC1		2
-#define IRQ_PIC_SPUR		7
-#define IRQ_MOUSE		12
-#define IRQ_DP8390		9
+#define IRQ_CLK       0
+#define IRQ_KBD       1
+#define IRQ_PIC1      2
+#define IRQ_PIC_SPUR  7
+#define IRQ_MOUSE     12
+#define IRQ_DP8390    9
 
-/* this one must have four least significant bits set to ones */
-#define VECTOR_APIC_SPUR	(IVT_ITEMS - 1)
+/* This one must have four least significant bits set to ones */
+#define VECTOR_APIC_SPUR  (IVT_ITEMS - 1)
 
 #if (((VECTOR_APIC_SPUR + 1) % 16) || VECTOR_APIC_SPUR >= IVT_ITEMS)
@@ -63,59 +64,68 @@
 #endif
 
-#define VECTOR_DEBUG			1
-#define VECTOR_CLK			(IVT_IRQBASE + IRQ_CLK)
-#define VECTOR_PIC_SPUR			(IVT_IRQBASE + IRQ_PIC_SPUR)
-#define VECTOR_SYSCALL			IVT_FREEBASE
-#define VECTOR_TLB_SHOOTDOWN_IPI	(IVT_FREEBASE + 1)
-#define VECTOR_DEBUG_IPI		(IVT_FREEBASE + 2)
+#define VECTOR_DEBUG              1
+#define VECTOR_CLK                (IVT_IRQBASE + IRQ_CLK)
+#define VECTOR_PIC_SPUR           (IVT_IRQBASE + IRQ_PIC_SPUR)
+#define VECTOR_SYSCALL            IVT_FREEBASE
+#define VECTOR_TLB_SHOOTDOWN_IPI  (IVT_FREEBASE + 1)
+#define VECTOR_DEBUG_IPI          (IVT_FREEBASE + 2)
 
 /** This is passed to interrupt handlers */
 typedef struct istate {
 	uint64_t rax;
+	uint64_t rbx;
 	uint64_t rcx;
 	uint64_t rdx;
 	uint64_t rsi;
 	uint64_t rdi;
+	uint64_t rbp;
 	uint64_t r8;
 	uint64_t r9;
 	uint64_t r10;
 	uint64_t r11;
-	uint64_t rbp;
-	uint64_t error_word;
+	uint64_t r12;
+	uint64_t r13;
+	uint64_t r14;
+	uint64_t r15;
+	uint64_t alignment;	/* align rbp_frame on multiple of 16 */
+	uint64_t rbp_frame;	/* imitation of frame pointer linkage */
+	uint64_t rip_frame;	/* imitation of return address linkage */
+	uint64_t error_word;	/* real or fake error word */
 	uint64_t rip;
 	uint64_t cs;
 	uint64_t rflags;
-	uint64_t stack[]; /* Additional data on stack */
+	uint64_t rsp;		/* only if istate_t is from uspace */
+	uint64_t ss;		/* only if istate_t is from uspace */
 } istate_t;
 
 /** Return true if exception happened while in userspace */
-static inline int istate_from_uspace(istate_t *istate)
+NO_TRACE static inline int istate_from_uspace(istate_t *istate)
 {
 	return !(istate->rip & 0x8000000000000000);
 }
 
-static inline void istate_set_retaddr(istate_t *istate, uintptr_t retaddr)
+NO_TRACE static inline void istate_set_retaddr(istate_t *istate,
+    uintptr_t retaddr)
 {
 	istate->rip = retaddr;
 }
-static inline unative_t istate_get_pc(istate_t *istate)
+
+NO_TRACE static inline unative_t istate_get_pc(istate_t *istate)
 {
 	return istate->rip;
 }
-static inline unative_t istate_get_fp(istate_t *istate)
+
+NO_TRACE static inline unative_t istate_get_fp(istate_t *istate)
 {
 	return istate->rbp;
 }
 
-extern void (* disable_irqs_function)(uint16_t irqmask);
-extern void (* enable_irqs_function)(uint16_t irqmask);
+extern void (* disable_irqs_function)(uint16_t);
+extern void (* enable_irqs_function)(uint16_t);
 extern void (* eoi_function)(void);
 
-extern void decode_istate(int n, istate_t *istate);
 extern void interrupt_init(void);
-extern void trap_virtual_enable_irqs(uint16_t irqmask);
-extern void trap_virtual_disable_irqs(uint16_t irqmask);
-/* AMD64 - specific page handler */
-extern void ident_page_fault(int n, istate_t *istate);
+extern void trap_virtual_enable_irqs(uint16_t);
+extern void trap_virtual_disable_irqs(uint16_t);
 
 #endif
Index: kernel/arch/amd64/include/mm/as.h
===================================================================
--- kernel/arch/amd64/include/mm/as.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/amd64/include/mm/as.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -27,5 +27,5 @@
  */
 
-/** @addtogroup amd64mm	
+/** @addtogroup amd64mm
  * @{
  */
@@ -36,16 +36,18 @@
 #define KERN_amd64_AS_H_
 
-#define KERNEL_ADDRESS_SPACE_SHADOWED_ARCH	0
+#define KERNEL_ADDRESS_SPACE_SHADOWED_ARCH  0
 
-#define KERNEL_ADDRESS_SPACE_START_ARCH		(unsigned long) 0xffff800000000000
-#define KERNEL_ADDRESS_SPACE_END_ARCH		(unsigned long) 0xffffffff80000000
-#define USER_ADDRESS_SPACE_START_ARCH		(unsigned long) 0x0000000000000000
-#define USER_ADDRESS_SPACE_END_ARCH		(unsigned long) 0x00007fffffffffff
+#define KERNEL_ADDRESS_SPACE_START_ARCH  (unsigned long) 0xffff800000000000
+#define KERNEL_ADDRESS_SPACE_END_ARCH    (unsigned long) 0xffffffffffffffff
 
-#define USTACK_ADDRESS_ARCH	(USER_ADDRESS_SPACE_END_ARCH-(PAGE_SIZE-1))
+#define USER_ADDRESS_SPACE_START_ARCH    (unsigned long) 0x0000000000000000
+#define USER_ADDRESS_SPACE_END_ARCH      (unsigned long) 0x00007fffffffffff
 
-#define as_constructor_arch(as, flags)		(as != as)
-#define as_destructor_arch(as)			(as != as)
-#define as_create_arch(as, flags)		(as != as)
+#define USTACK_ADDRESS_ARCH  (USER_ADDRESS_SPACE_END_ARCH - (PAGE_SIZE - 1))
+
+#define as_constructor_arch(as, flags)  (as != as)
+#define as_destructor_arch(as)          (as != as)
+#define as_create_arch(as, flags)       (as != as)
+
 #define as_install_arch(as)
 #define as_deinstall_arch(as)
Index: kernel/arch/amd64/include/mm/frame.h
===================================================================
--- kernel/arch/amd64/include/mm/frame.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/amd64/include/mm/frame.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -36,16 +36,18 @@
 #define KERN_amd64_FRAME_H_
 
-#ifndef __ASM__
-#include <typedefs.h>
-#endif /* __ASM__ */
-
 #define FRAME_WIDTH  12  /* 4K */
 #define FRAME_SIZE   (1 << FRAME_WIDTH)
 
+#ifdef KERNEL
 #ifndef __ASM__
+
+#include <typedefs.h>
+
 extern uintptr_t last_frame;
 extern void frame_arch_init(void);
 extern void physmem_print(void);
+
 #endif /* __ASM__ */
+#endif /* KERNEL */
 
 #endif
Index: kernel/arch/amd64/include/mm/page.h
===================================================================
--- kernel/arch/amd64/include/mm/page.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/amd64/include/mm/page.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -35,12 +35,9 @@
 /** Paging on AMD64
  *
- * The space is divided in positive numbers - userspace and
- * negative numbers - kernel space. The 'negative' space starting
- * with 0xffff800000000000 and ending with 0xffffffff80000000
- * (-2GB) is identically mapped physical memory. The area
- * (0xffffffff80000000 ... 0xffffffffffffffff is again identically
- * mapped first 2GB.
- *
- * ATTENTION - PA2KA(KA2PA(x)) != x if 'x' is in kernel
+ * The space is divided in positive numbers (uspace) and
+ * negative numbers (kernel). The 'negative' space starting
+ * with 0xffff800000000000 and ending with 0xffffffffffffffff
+ * is identically mapped physical memory.
+ *
  */
 
@@ -49,48 +46,40 @@
 
 #include <arch/mm/frame.h>
-
-#define PAGE_WIDTH	FRAME_WIDTH
-#define PAGE_SIZE	FRAME_SIZE
+#include <trace.h>
+
+#define PAGE_WIDTH  FRAME_WIDTH
+#define PAGE_SIZE   FRAME_SIZE
 
 #ifdef KERNEL
 
 #ifndef __ASM__
-#	include <mm/mm.h>
-#	include <typedefs.h>
-#	include <arch/interrupt.h>
-
-static inline uintptr_t ka2pa(uintptr_t x)
-{
-	if (x > 0xffffffff80000000)
-		return x - 0xffffffff80000000;
-	else 
-		return x - 0xffff800000000000;
-}
-
-#	define KA2PA(x)		ka2pa((uintptr_t) x)
-#	define PA2KA_CODE(x)	(((uintptr_t) (x)) + 0xffffffff80000000)
-#	define PA2KA(x)		(((uintptr_t) (x)) + 0xffff800000000000)
-#else
-#	define KA2PA(x)		((x) - 0xffffffff80000000)
-#	define PA2KA(x)		((x) + 0xffffffff80000000)
-#endif
+
+#define KA2PA(x)  (((uintptr_t) (x)) - 0xffff800000000000)
+#define PA2KA(x)  (((uintptr_t) (x)) + 0xffff800000000000)
+
+#else /* __ASM__ */
+
+#define KA2PA(x)  ((x) - 0xffff800000000000)
+#define PA2KA(x)  ((x) + 0xffff800000000000)
+
+#endif /* __ASM__ */
 
 /* Number of entries in each level. */
-#define PTL0_ENTRIES_ARCH	512
-#define PTL1_ENTRIES_ARCH	512
-#define PTL2_ENTRIES_ARCH	512
-#define PTL3_ENTRIES_ARCH	512
+#define PTL0_ENTRIES_ARCH  512
+#define PTL1_ENTRIES_ARCH  512
+#define PTL2_ENTRIES_ARCH  512
+#define PTL3_ENTRIES_ARCH  512
 
 /* Page table sizes for each level. */
-#define PTL0_SIZE_ARCH		ONE_FRAME
-#define PTL1_SIZE_ARCH		ONE_FRAME
-#define PTL2_SIZE_ARCH		ONE_FRAME
-#define PTL3_SIZE_ARCH		ONE_FRAME
+#define PTL0_SIZE_ARCH  ONE_FRAME
+#define PTL1_SIZE_ARCH  ONE_FRAME
+#define PTL2_SIZE_ARCH  ONE_FRAME
+#define PTL3_SIZE_ARCH  ONE_FRAME
 
 /* Macros calculating indices into page tables in each level. */
-#define PTL0_INDEX_ARCH(vaddr)	(((vaddr) >> 39) & 0x1ff)
-#define PTL1_INDEX_ARCH(vaddr)	(((vaddr) >> 30) & 0x1ff)
-#define PTL2_INDEX_ARCH(vaddr)	(((vaddr) >> 21) & 0x1ff)
-#define PTL3_INDEX_ARCH(vaddr)	(((vaddr) >> 12) & 0x1ff)
+#define PTL0_INDEX_ARCH(vaddr)  (((vaddr) >> 39) & 0x1ff)
+#define PTL1_INDEX_ARCH(vaddr)  (((vaddr) >> 30) & 0x1ff)
+#define PTL2_INDEX_ARCH(vaddr)  (((vaddr) >> 21) & 0x1ff)
+#define PTL3_INDEX_ARCH(vaddr)  (((vaddr) >> 12) & 0x1ff)
 
 /* Get PTE address accessors for each level. */
@@ -156,4 +145,8 @@
 #ifndef __ASM__
 
+#include <mm/mm.h>
+#include <arch/interrupt.h>
+#include <typedefs.h>
+
 /* Page fault error codes. */
 
@@ -161,39 +154,39 @@
  * page.
  */
-#define PFERR_CODE_P            (1 << 0)  
+#define PFERR_CODE_P  (1 << 0)
 
 /** When bit on this position is 1, the page fault was caused by a write. */
-#define PFERR_CODE_RW           (1 << 1)
+#define PFERR_CODE_RW  (1 << 1)
 
 /** When bit on this position is 1, the page fault was caused in user mode. */
-#define PFERR_CODE_US           (1 << 2)
+#define PFERR_CODE_US  (1 << 2)
 
 /** When bit on this position is 1, a reserved bit was set in page directory. */
-#define PFERR_CODE_RSVD         (1 << 3)
+#define PFERR_CODE_RSVD  (1 << 3)
 
 /** When bit on this position os 1, the page fault was caused during instruction
  * fecth.
  */
-#define PFERR_CODE_ID		(1 << 4)
+#define PFERR_CODE_ID  (1 << 4)
 
 /** Page Table Entry. */
 typedef struct {
-	unsigned present : 1;
-	unsigned writeable : 1;
-	unsigned uaccessible : 1;
-	unsigned page_write_through : 1;
-	unsigned page_cache_disable : 1;
-	unsigned accessed : 1;
-	unsigned dirty : 1;
-	unsigned unused: 1;
-	unsigned global : 1;
-	unsigned soft_valid : 1;		/**< Valid content even if present bit is cleared. */
-	unsigned avl : 2;
-	unsigned addr_12_31 : 30;
-	unsigned addr_32_51 : 21;
-	unsigned no_execute : 1;
+	unsigned int present : 1;
+	unsigned int writeable : 1;
+	unsigned int uaccessible : 1;
+	unsigned int page_write_through : 1;
+	unsigned int page_cache_disable : 1;
+	unsigned int accessed : 1;
+	unsigned int dirty : 1;
+	unsigned int unused: 1;
+	unsigned int global : 1;
+	unsigned int soft_valid : 1;  /**< Valid content even if present bit is cleared. */
+	unsigned int avl : 2;
+	unsigned int addr_12_31 : 30;
+	unsigned int addr_32_51 : 21;
+	unsigned int no_execute : 1;
 } __attribute__ ((packed)) pte_t;
 
-static inline unsigned int get_pt_flags(pte_t *pt, size_t i)
+NO_TRACE static inline unsigned int get_pt_flags(pte_t *pt, size_t i)
 {
 	pte_t *p = &pt[i];
@@ -208,13 +201,13 @@
 }
 
-static inline void set_pt_addr(pte_t *pt, size_t i, uintptr_t a)
+NO_TRACE static inline void set_pt_addr(pte_t *pt, size_t i, uintptr_t a)
 {
 	pte_t *p = &pt[i];
-
+	
 	p->addr_12_31 = (a >> 12) & 0xfffff;
 	p->addr_32_51 = a >> 32;
 }
 
-static inline void set_pt_flags(pte_t *pt, size_t i, int flags)
+NO_TRACE static inline void set_pt_flags(pte_t *pt, size_t i, int flags)
 {
 	pte_t *p = &pt[i];
@@ -234,5 +227,5 @@
 
 extern void page_arch_init(void);
-extern void page_fault(int n, istate_t *istate);
+extern void page_fault(unsigned int, istate_t *);
 
 #endif /* __ASM__ */
Index: kernel/arch/amd64/include/mm/ptl.h
===================================================================
--- kernel/arch/amd64/include/mm/ptl.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/amd64/include/mm/ptl.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -27,5 +27,5 @@
  */
 
-/** @addtogroup amd64mm	
+/** @addtogroup amd64mm
  * @{
  */
@@ -36,12 +36,12 @@
 #define KERN_amd64_PTL_H_
 
-#define PTL_NO_EXEC       (1<<63)
-#define PTL_ACCESSED      (1<<5)
-#define PTL_CACHE_DISABLE (1<<4)
-#define PTL_CACHE_THROUGH (1<<3)
-#define PTL_USER          (1<<2)
-#define PTL_WRITABLE      (1<<1)
-#define PTL_PRESENT       1
-#define PTL_2MB_PAGE      (1<<7)
+#define PTL_NO_EXEC        (1 << 63)
+#define PTL_ACCESSED       (1 << 5)
+#define PTL_CACHE_DISABLE  (1 << 4)
+#define PTL_CACHE_THROUGH  (1 << 3)
+#define PTL_USER           (1 << 2)
+#define PTL_WRITABLE       (1 << 1)
+#define PTL_PRESENT        1
+#define PTL_2MB_PAGE       (1 << 7)
 
 
Index: kernel/arch/amd64/include/mm/tlb.h
===================================================================
--- kernel/arch/amd64/include/mm/tlb.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/amd64/include/mm/tlb.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -27,5 +27,5 @@
  */
 
-/** @addtogroup amd64mm	
+/** @addtogroup amd64mm
  * @{
  */
Index: kernel/arch/amd64/include/pm.h
===================================================================
--- kernel/arch/amd64/include/pm.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/amd64/include/pm.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -65,11 +65,10 @@
 #endif /* CONFIG_FB */
 
-#define gdtselector(des)  ((des) << 3)
-#define idtselector(des)  ((des) << 4)
+#define GDT_SELECTOR(des)  ((des) << 3)
 
 #define PL_KERNEL  0
 #define PL_USER    3
 
-#define AR_PRESENT   ( 1 << 7)
+#define AR_PRESENT    (1 << 7)
 #define AR_DATA       (2 << 3)
 #define AR_CODE       (3 << 3)
@@ -168,5 +167,4 @@
 
 extern ptr_16_64_t gdtr;
-extern ptr_16_32_t bootstrap_gdtr;
 extern ptr_16_32_t protected_ap_gdtr;
 
Index: kernel/arch/amd64/include/proc/thread.h
===================================================================
--- kernel/arch/amd64/include/proc/thread.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/amd64/include/proc/thread.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -37,11 +37,11 @@
 
 /* CAUTION: keep these in sync with low level assembly code in syscall_entry */
-#define SYSCALL_USTACK_RSP	0
-#define SYSCALL_KSTACK_RSP	1
+#define SYSCALL_USTACK_RSP  0
+#define SYSCALL_KSTACK_RSP  1
 
 typedef struct {
 	unative_t tls;
 	/** User and kernel RSP for syscalls. */
-	uint64_t syscall_rsp[2];	
+	uint64_t syscall_rsp[2];
 } thread_arch_t;
 
Index: kernel/arch/amd64/include/types.h
===================================================================
--- kernel/arch/amd64/include/types.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/amd64/include/types.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -50,9 +50,9 @@
 } fncptr_t;
 
-/**< Formats for uintptr_t, size_t */
+/* Formats for uintptr_t, size_t */
 #define PRIp  "llx"
 #define PRIs  "llu"
 
-/**< Formats for (u)int8_t, (u)int16_t, (u)int32_t, (u)int64_t and (u)native_t */
+/* Formats for (u)int8_t, (u)int16_t, (u)int32_t, (u)int64_t and (u)native_t */
 #define PRId8   "d"
 #define PRId16  "d"
Index: kernel/arch/amd64/src/amd64.c
===================================================================
--- kernel/arch/amd64/src/amd64.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/amd64/src/amd64.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -122,5 +122,5 @@
 	/* Enable FPU */
 	cpu_setup_fpu();
-
+	
 	/* Initialize segmentation */
 	pm_init();
@@ -132,5 +132,5 @@
 	/* Disable alignment check */
 	clean_AM_flag();
-
+	
 	if (config.cpu_active == 1) {
 		interrupt_init();
@@ -260,4 +260,5 @@
 	THREAD->arch.tls = addr;
 	write_msr(AMD_MSR_FS, addr);
+	
 	return 0;
 }
Index: kernel/arch/amd64/src/asm.S
===================================================================
--- kernel/arch/amd64/src/asm.S	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
+++ kernel/arch/amd64/src/asm.S	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -0,0 +1,533 @@
+/*
+ * Copyright (c) 2005 Ondrej Palkovsky
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <arch/pm.h>
+#include <arch/mm/page.h>
+
+.text
+.global interrupt_handlers
+.global syscall_entry
+.global cpuid
+.global has_cpuid
+.global read_efer_flag
+.global set_efer_flag
+.global memsetb
+.global memsetw
+.global memcpy
+.global memcpy_from_uspace
+.global memcpy_to_uspace
+.global memcpy_from_uspace_failover_address
+.global memcpy_to_uspace_failover_address
+.global early_putchar
+
+/* Wrapper for generic memsetb */
+memsetb:
+	jmp _memsetb
+
+/* Wrapper for generic memsetw */
+memsetw:
+	jmp _memsetw
+
+#define MEMCPY_DST   %rdi
+#define MEMCPY_SRC   %rsi
+#define MEMCPY_SIZE  %rdx
+
+/**
+ * Copy memory from/to userspace.
+ *
+ * This is almost conventional memcpy().
+ * The difference is that there is a failover part
+ * to where control is returned from a page fault if
+ * the page fault occurs during copy_from_uspace()
+ * or copy_to_uspace().
+ *
+ * @param MEMCPY_DST  Destination address.
+ * @param MEMCPY_SRC  Source address.
+ * @param MEMCPY_SIZE Number of bytes to copy.
+ *
+ * @retrun MEMCPY_DST on success, 0 on failure.
+ *
+ */
+memcpy:
+memcpy_from_uspace:
+memcpy_to_uspace:
+	movq MEMCPY_DST, %rax
+	
+	movq MEMCPY_SIZE, %rcx
+	shrq $3, %rcx           /* size / 8 */
+	
+	rep movsq               /* copy as much as possible word by word */
+	
+	movq MEMCPY_SIZE, %rcx
+	andq $7, %rcx           /* size % 8 */
+	jz 0f
+	
+	rep movsb               /* copy the rest byte by byte */
+	
+	0:
+		ret                 /* return MEMCPY_SRC, success */
+
+memcpy_from_uspace_failover_address:
+memcpy_to_uspace_failover_address:
+	xorq %rax, %rax         /* return 0, failure */
+	ret
+
+/** Determine CPUID support
+*
+* @return 0 in EAX if CPUID is not support, 1 if supported.
+*
+*/
+has_cpuid:
+	/* Load RFLAGS */
+	pushfq
+	popq %rax
+	movq %rax, %rdx
+	
+	/* Flip the ID bit */
+	btcl $21, %edx
+	
+	/* Store RFLAGS */
+	pushq %rdx
+	popfq
+	pushfq
+	
+	/* Get the ID bit again */
+	popq %rdx
+	andl $(1 << 21), %eax
+	andl $(1 << 21), %edx
+	
+	/* 0 if not supported, 1 if supported */
+	xorl %edx, %eax
+	ret
+
+cpuid:
+	/* Preserve %rbx across function calls */
+	movq %rbx, %r10
+	
+	/* Load the command into %eax */
+	movl %edi, %eax
+	
+	cpuid
+	movl %eax, 0(%rsi)
+	movl %ebx, 4(%rsi)
+	movl %ecx, 8(%rsi)
+	movl %edx, 12(%rsi)
+	
+	movq %r10, %rbx
+	ret
+
+set_efer_flag:
+	movq $0xc0000080, %rcx
+	rdmsr
+	btsl %edi, %eax
+	wrmsr
+	ret
+
+read_efer_flag:
+	movq $0xc0000080, %rcx
+	rdmsr
+	ret
+
+#define ISTATE_OFFSET_RAX		0
+#define ISTATE_OFFSET_RBX		8
+#define ISTATE_OFFSET_RCX		16
+#define ISTATE_OFFSET_RDX		24
+#define ISTATE_OFFSET_RSI		32
+#define ISTATE_OFFSET_RDI		40
+#define ISTATE_OFFSET_RBP		48
+#define ISTATE_OFFSET_R8		56
+#define ISTATE_OFFSET_R9		64
+#define ISTATE_OFFSET_R10		72
+#define ISTATE_OFFSET_R11		80
+#define ISTATE_OFFSET_R12		88	
+#define ISTATE_OFFSET_R13 		96
+#define ISTATE_OFFSET_R14		104
+#define ISTATE_OFFSET_R15		112
+#define ISTATE_OFFSET_ALIGNMENT		120
+#define ISTATE_OFFSET_RBP_FRAME		128
+#define ISTATE_OFFSET_RIP_FRAME		136
+#define ISTATE_OFFSET_ERROR_WORD	144
+#define ISTATE_OFFSET_RIP		152
+#define ISTATE_OFFSET_CS		160
+#define ISTATE_OFFSET_RFLAGS		168
+#define ISTATE_OFFSET_RSP		176
+#define ISTATE_OFFSET_SS		184
+
+/*
+ * Size of the istate structure without the hardware-saved part and without the
+ * error word.
+ */
+#define ISTATE_SOFT_SIZE	144
+
+/**
+ * Mask for interrupts 0 - 31 (bits 0 - 31) where 0 means that int
+ * has no error word  and 1 means interrupt with error word
+ *
+ */
+#define ERROR_WORD_INTERRUPT_LIST  0x00027D00
+
+.macro handler i
+.global int_\i
+int_\i:
+
+	/*
+	 * Choose between version with error code and version without error
+	 * code.
+	 */
+	
+	.iflt \i-32
+		.if (1 << \i) & ERROR_WORD_INTERRUPT_LIST
+			/*
+			 * Version with error word.
+			 */
+			subq $ISTATE_SOFT_SIZE, %rsp
+		.else
+			/*
+			 * Version without error word.
+			 */
+			subq $(ISTATE_SOFT_SIZE + 8), %rsp
+		.endif
+	.else
+		/*
+		 * Version without error word.
+		 */
+		subq $(ISTATE_SOFT_SIZE + 8), %rsp
+	.endif
+	
+	/*
+	 * Save the general purpose registers.
+	 */
+	movq %rax, ISTATE_OFFSET_RAX(%rsp)
+	movq %rbx, ISTATE_OFFSET_RBX(%rsp)
+	movq %rcx, ISTATE_OFFSET_RCX(%rsp)
+	movq %rdx, ISTATE_OFFSET_RDX(%rsp)
+	movq %rsi, ISTATE_OFFSET_RSI(%rsp)
+	movq %rdi, ISTATE_OFFSET_RDI(%rsp)
+	movq %rbp, ISTATE_OFFSET_RBP(%rsp)
+	movq %r8, ISTATE_OFFSET_R8(%rsp)
+	movq %r9, ISTATE_OFFSET_R9(%rsp)
+	movq %r10, ISTATE_OFFSET_R10(%rsp)
+	movq %r11, ISTATE_OFFSET_R11(%rsp)
+	movq %r12, ISTATE_OFFSET_R12(%rsp)
+	movq %r13, ISTATE_OFFSET_R13(%rsp)
+	movq %r14, ISTATE_OFFSET_R14(%rsp)
+	movq %r15, ISTATE_OFFSET_R15(%rsp)
+
+	/*
+	 * Imitate a regular stack frame linkage.
+	 * Stop stack traces here if we came from userspace.
+	 */
+	xorq %rdx, %rdx
+	cmpq $(GDT_SELECTOR(KTEXT_DES)), ISTATE_OFFSET_CS(%rsp)
+	cmovnzq %rdx, %rbp
+
+	movq %rbp, ISTATE_OFFSET_RBP_FRAME(%rsp)
+	movq ISTATE_OFFSET_RIP(%rsp), %rax
+	movq %rax, ISTATE_OFFSET_RIP_FRAME(%rsp)
+	leaq ISTATE_OFFSET_RBP_FRAME(%rsp), %rbp
+
+	movq $(\i), %rdi   /* pass intnum in the first argument */
+	movq %rsp, %rsi    /* pass istate address in the second argument */
+	
+	cld
+
+	/* Call exc_dispatch(i, istate) */
+	call exc_dispatch
+
+	/*
+	 * Restore all scratch registers and the preserved registers we have
+	 * clobbered in this handler (i.e. RBP).
+	 */
+	movq ISTATE_OFFSET_RAX(%rsp), %rax
+	movq ISTATE_OFFSET_RCX(%rsp), %rcx
+	movq ISTATE_OFFSET_RDX(%rsp), %rdx
+	movq ISTATE_OFFSET_RSI(%rsp), %rsi
+	movq ISTATE_OFFSET_RDI(%rsp), %rdi
+	movq ISTATE_OFFSET_RBP(%rsp), %rbp
+	movq ISTATE_OFFSET_R8(%rsp), %r8
+	movq ISTATE_OFFSET_R9(%rsp), %r9
+	movq ISTATE_OFFSET_R10(%rsp), %r10
+	movq ISTATE_OFFSET_R11(%rsp), %r11
+	
+	/* $8 = Skip error word */
+	addq $(ISTATE_SOFT_SIZE + 8), %rsp
+	iretq
+.endm
+
+#define LIST_0_63 \
+	0, 1, 2, 3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,\
+	28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,\
+	53,54,55,56,57,58,59,60,61,62,63
+
+interrupt_handlers:
+.irp cnt, LIST_0_63
+	handler \cnt 
+.endr
+
+/** Low-level syscall handler
+ *
+ * Registers on entry:
+ *
+ * @param %rcx Userspace return address.
+ * @param %r11 Userspace RLFAGS.
+ *
+ * @param %rax Syscall number.
+ * @param %rdi 1st syscall argument.
+ * @param %rsi 2nd syscall argument.
+ * @param %rdx 3rd syscall argument.
+ * @param %r10 4th syscall argument. Used instead of RCX because
+ *             the SYSCALL instruction clobbers it.
+ * @param %r8  5th syscall argument.
+ * @param %r9  6th syscall argument.
+ *
+ * @return Return value is in %rax.
+ *
+ */
+syscall_entry:
+	/* Switch to hidden %gs */
+	swapgs
+	
+	/*
+	 * %gs:0 Scratch space for this thread's user RSP
+	 * %gs:8 Address to be used as this thread's kernel RSP
+	 */
+	
+	movq %rsp, %gs:0  /* save this thread's user RSP */
+	movq %gs:8, %rsp  /* set this thread's kernel RSP */
+	
+	/*
+	 * Note that the space needed for the imitated istate structure has been
+	 * preallocated for us in thread_create_arch() and set in
+	 * before_thread_runs_arch().
+	 */
+
+	/*
+	 * Save the general purpose registers and push the 7th argument (syscall
+	 * number) onto the stack. Note that the istate structure has a layout
+	 * which supports this.
+	 */
+	movq %rax, ISTATE_OFFSET_RAX(%rsp)  /* 7th argument, passed on stack */
+	movq %rbx, ISTATE_OFFSET_RBX(%rsp)  /* observability */
+	movq %rcx, ISTATE_OFFSET_RCX(%rsp)  /* userspace RIP */
+	movq %rdx, ISTATE_OFFSET_RDX(%rsp)  /* 3rd argument, observability */
+	movq %rsi, ISTATE_OFFSET_RSI(%rsp)  /* 2nd argument, observability */ 
+	movq %rdi, ISTATE_OFFSET_RDI(%rsp)  /* 1st argument, observability */
+	movq %rbp, ISTATE_OFFSET_RBP(%rsp)  /* need to preserve userspace RBP */
+	movq %r8, ISTATE_OFFSET_R8(%rsp)    /* 5th argument, observability */
+	movq %r9, ISTATE_OFFSET_R9(%rsp)    /* 6th argument, observability */
+	movq %r10, ISTATE_OFFSET_R10(%rsp)  /* 4th argument, observability */
+	movq %r11, ISTATE_OFFSET_R11(%rsp)  /* low 32 bits userspace RFLAGS */
+	movq %r12, ISTATE_OFFSET_R12(%rsp)  /* observability */
+	movq %r13, ISTATE_OFFSET_R13(%rsp)  /* observability */
+	movq %r14, ISTATE_OFFSET_R14(%rsp)  /* observability */
+	movq %r15, ISTATE_OFFSET_R15(%rsp)  /* observability */
+
+	/*
+	 * Save the return address and the userspace stack on locations that
+	 * would normally be taken by them.
+	 */
+	movq %gs:0, %rax
+	movq %rax, ISTATE_OFFSET_RSP(%rsp)
+	movq %rcx, ISTATE_OFFSET_RIP(%rsp)
+
+	/*
+	 * Imitate a regular stack frame linkage.
+	 */
+	movq $0, ISTATE_OFFSET_RBP_FRAME(%rsp)
+	movq %rcx, ISTATE_OFFSET_RIP_FRAME(%rsp)
+	leaq ISTATE_OFFSET_RBP_FRAME(%rsp), %rbp
+
+	/* Switch back to normal %gs */
+	swapgs
+	sti
+	
+	/* Copy the 4th argument where it is expected  */
+	movq %r10, %rcx
+
+	/*
+	 * Call syscall_handler() with the 7th argument passed on stack.
+	 */
+	call syscall_handler
+	
+	cli
+	
+	/*
+	 * Restore registers needed for return via the SYSRET instruction and
+	 * the clobbered preserved registers (i.e. RBP).
+	 */
+	movq ISTATE_OFFSET_RBP(%rsp), %rbp
+	movq ISTATE_OFFSET_RCX(%rsp), %rcx
+	movq ISTATE_OFFSET_R11(%rsp), %r11
+	movq ISTATE_OFFSET_RSP(%rsp), %rsp
+
+	sysretq
+
+/** Print Unicode character to EGA display.
+ *
+ * If CONFIG_EGA is undefined or CONFIG_FB is defined
+ * then this function does nothing.
+ *
+ * Since the EGA can only display Extended ASCII (usually
+ * ISO Latin 1) characters, some of the Unicode characters
+ * can be displayed in a wrong way. Only newline and backspace
+ * are interpreted, all other characters (even unprintable) are
+ * printed verbatim.
+ *
+ * @param %rdi Unicode character to be printed.
+ *
+ */
+early_putchar:
+	
+#if ((defined(CONFIG_EGA)) && (!defined(CONFIG_FB)))
+	
+	/* Prologue, save preserved registers */
+	pushq %rbp
+	movq %rsp, %rbp
+	pushq %rbx
+	
+	movq %rdi, %rsi
+	movq $(PA2KA(0xb8000)), %rdi  /* base of EGA text mode memory */
+	xorq %rax, %rax
+	
+	/* Read bits 8 - 15 of the cursor address */
+	movw $0x3d4, %dx
+	movb $0xe, %al
+	outb %al, %dx
+	
+	movw $0x3d5, %dx
+	inb %dx, %al
+	shl $8, %ax
+	
+	/* Read bits 0 - 7 of the cursor address */
+	movw $0x3d4, %dx
+	movb $0xf, %al
+	outb %al, %dx
+	
+	movw $0x3d5, %dx
+	inb %dx, %al
+	
+	/* Sanity check for the cursor on screen */
+	cmp $2000, %ax
+	jb early_putchar_cursor_ok
+	
+		movw $1998, %ax
+	
+	early_putchar_cursor_ok:
+	
+	movw %ax, %bx
+	shl $1, %rax
+	addq %rax, %rdi
+	
+	movq %rsi, %rax
+	
+	cmp $0x0a, %al
+	jne early_putchar_backspace
+	
+		/* Interpret newline */
+		
+		movw %bx, %ax  /* %bx -> %dx:%ax */
+		xorw %dx, %dx
+		
+		movw $80, %cx
+		idivw %cx, %ax  /* %dx = %bx % 80 */
+		
+		/* %bx <- %bx + 80 - (%bx % 80) */
+		addw %cx, %bx
+		subw %dx, %bx
+		
+		jmp early_putchar_skip
+	
+	early_putchar_backspace:
+	
+		cmp $0x08, %al
+		jne early_putchar_print
+		
+		/* Interpret backspace */
+		
+		cmp $0x0000, %bx
+		je early_putchar_skip
+		
+		dec %bx
+		jmp early_putchar_skip
+	
+	early_putchar_print:
+	
+		/* Print character */
+		
+		movb $0x0e, %ah  /* black background, yellow foreground */
+		stosw
+		inc %bx
+	
+	early_putchar_skip:
+	
+	/* Sanity check for the cursor on the last line */
+	cmp $2000, %bx
+	jb early_putchar_no_scroll
+	
+		/* Scroll the screen (24 rows) */
+		movq $(PA2KA(0xb80a0)), %rsi
+		movq $(PA2KA(0xb8000)), %rdi
+		movq $480, %rcx
+		rep movsq
+		
+		/* Clear the 24th row */
+		xorq %rax, %rax
+		movq $20, %rcx
+		rep stosq
+		
+		/* Go to row 24 */
+		movw $1920, %bx
+	
+	early_putchar_no_scroll:
+	
+	/* Write bits 8 - 15 of the cursor address */
+	movw $0x3d4, %dx
+	movb $0xe, %al
+	outb %al, %dx
+	
+	movw $0x3d5, %dx
+	movb %bh, %al
+	outb %al, %dx
+	
+	/* Write bits 0 - 7 of the cursor address */
+	movw $0x3d4, %dx
+	movb $0xf, %al
+	outb %al, %dx
+	
+	movw $0x3d5, %dx
+	movb %bl, %al
+	outb %al, %dx
+	
+	/* Epilogue, restore preserved registers */
+	popq %rbx
+	leave
+	
+#endif
+	
+	ret
+
Index: rnel/arch/amd64/src/asm_utils.S
===================================================================
--- kernel/arch/amd64/src/asm_utils.S	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ 	(revision )
@@ -1,314 +1,0 @@
-#
-# Copyright (c) 2005 Ondrej Palkovsky
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions
-# are met:
-#
-# - Redistributions of source code must retain the above copyright
-#   notice, this list of conditions and the following disclaimer.
-# - Redistributions in binary form must reproduce the above copyright
-#   notice, this list of conditions and the following disclaimer in the
-#   documentation and/or other materials provided with the distribution.
-# - The name of the author may not be used to endorse or promote products
-#   derived from this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
-# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
-# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
-# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
-# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
-# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-#
-
-#define IREGISTER_SPACE	80
-
-#define IOFFSET_RAX	0x0
-#define IOFFSET_RCX	0x8
-#define IOFFSET_RDX	0x10
-#define IOFFSET_RSI	0x18
-#define IOFFSET_RDI	0x20
-#define IOFFSET_R8	0x28
-#define IOFFSET_R9	0x30
-#define IOFFSET_R10	0x38
-#define IOFFSET_R11	0x40
-#define IOFFSET_RBP	0x48
-
-#  Mask for interrupts 0 - 31 (bits 0 - 31) where 0 means that int has no error word
-# and 1 means interrupt with error word
-#define ERROR_WORD_INTERRUPT_LIST 0x00027D00
-
-#include <arch/pm.h>
-#include <arch/mm/page.h>
-	
-.text
-.global interrupt_handlers
-.global syscall_entry
-.global panic_printf
-
-panic_printf:
-	movq $halt, (%rsp)
-	jmp printf
-
-.global cpuid
-.global has_cpuid
-.global get_cycle
-.global read_efer_flag
-.global set_efer_flag
-.global memsetb
-.global memsetw
-.global memcpy
-.global memcpy_from_uspace
-.global memcpy_to_uspace
-.global memcpy_from_uspace_failover_address
-.global memcpy_to_uspace_failover_address
-
-# Wrapper for generic memsetb
-memsetb:
-	jmp _memsetb
-
-# Wrapper for generic memsetw
-memsetw:
-	jmp _memsetw
-
-#define MEMCPY_DST	%rdi
-#define MEMCPY_SRC	%rsi
-#define MEMCPY_SIZE	%rdx
-
-/**
- * Copy memory from/to userspace.
- *
- * This is almost conventional memcpy().
- * The difference is that there is a failover part
- * to where control is returned from a page fault if
- * the page fault occurs during copy_from_uspace()
- * or copy_to_uspace().
- *
- * @param MEMCPY_DST	Destination address.
- * @param MEMCPY_SRC	Source address.
- * @param MEMCPY_SIZE	Number of bytes to copy.
- *
- * @retrun MEMCPY_DST on success, 0 on failure.
- */
-memcpy:
-memcpy_from_uspace:
-memcpy_to_uspace:
-	movq MEMCPY_DST, %rax
-
-	movq MEMCPY_SIZE, %rcx
-	shrq $3, %rcx			/* size / 8 */
-	
-	rep movsq			/* copy as much as possible word by word */
-
-	movq MEMCPY_SIZE, %rcx
-	andq $7, %rcx			/* size % 8 */
-	jz 0f
-	
-	rep movsb			/* copy the rest byte by byte */
-	
-0:
-	ret				/* return MEMCPY_SRC, success */
-
-memcpy_from_uspace_failover_address:
-memcpy_to_uspace_failover_address:
-	xorq %rax, %rax			/* return 0, failure */
-	ret
-
-## Determine CPUID support
-#
-# Return 0 in EAX if CPUID is not support, 1 if supported.
-#
-has_cpuid:
-	pushfq			# store flags
-	popq %rax		# read flags
-	movq %rax,%rdx		# copy flags
-	btcl $21,%edx		# swap the ID bit
-	pushq %rdx
-	popfq			# propagate the change into flags
-	pushfq
-	popq %rdx		# read flags	
-	andl $(1<<21),%eax	# interested only in ID bit
-	andl $(1<<21),%edx
-	xorl %edx,%eax		# 0 if not supported, 1 if supported
-	ret
-
-cpuid:
-	movq %rbx, %r10  # we have to preserve rbx across function calls
-
-	movl %edi,%eax	# load the command into %eax
-
-	cpuid	
-	movl %eax,0(%rsi)
-	movl %ebx,4(%rsi)
-	movl %ecx,8(%rsi)
-	movl %edx,12(%rsi)
-
-	movq %r10, %rbx
-	ret
-
-get_cycle:
-	xorq %rax,%rax
-	rdtsc
-	ret
-
-set_efer_flag:
-	movq $0xc0000080, %rcx
-	rdmsr
-	btsl %edi, %eax
-	wrmsr
-	ret
-	
-read_efer_flag:	
-	movq $0xc0000080, %rcx
-	rdmsr
-	ret 		
-
-# Push all volatile general purpose registers on stack
-.macro save_all_gpr
-	movq %rax, IOFFSET_RAX(%rsp)
-	movq %rcx, IOFFSET_RCX(%rsp)
-	movq %rdx, IOFFSET_RDX(%rsp)
-	movq %rsi, IOFFSET_RSI(%rsp)
-	movq %rdi, IOFFSET_RDI(%rsp)
-	movq %r8, IOFFSET_R8(%rsp)
-	movq %r9, IOFFSET_R9(%rsp)
-	movq %r10, IOFFSET_R10(%rsp)
-	movq %r11, IOFFSET_R11(%rsp)
-	movq %rbp, IOFFSET_RBP(%rsp)
-.endm
-
-.macro restore_all_gpr
-	movq IOFFSET_RAX(%rsp), %rax
-	movq IOFFSET_RCX(%rsp), %rcx
-	movq IOFFSET_RDX(%rsp), %rdx
-	movq IOFFSET_RSI(%rsp), %rsi
-	movq IOFFSET_RDI(%rsp), %rdi
-	movq IOFFSET_R8(%rsp), %r8
-	movq IOFFSET_R9(%rsp), %r9
-	movq IOFFSET_R10(%rsp), %r10
-	movq IOFFSET_R11(%rsp), %r11
-	movq IOFFSET_RBP(%rsp), %rbp
-.endm
-
-#define INTERRUPT_ALIGN 128
-	
-## Declare interrupt handlers
-#
-# Declare interrupt handlers for n interrupt
-# vectors starting at vector i.
-#
-# The handlers call exc_dispatch().
-#
-.macro handler i n
-
-	/*
-	 * Choose between version with error code and version without error
-	 * code. Both versions have to be of the same size. amd64 assembly is,
-	 * however, a little bit tricky. For instance, subq $0x80, %rsp and
-	 * subq $0x78, %rsp can result in two instructions with different
-	 * op-code lengths.
-	 * Therefore we align the interrupt handlers.
-	 */
-
-	.iflt \i-32
-		.if (1 << \i) & ERROR_WORD_INTERRUPT_LIST
-			/*
-			 * Version with error word.
-			 */
-			subq $IREGISTER_SPACE, %rsp
-		.else
-			/*
-			 * Version without error word,
-			 */
-			subq $(IREGISTER_SPACE+8), %rsp
-		.endif
-	.else
-		/*
-		 * Version without error word,
-		 */
-		subq $(IREGISTER_SPACE+8), %rsp
-	.endif	
-
-	save_all_gpr
-	cld
-
-	# Stop stack traces here
-	xorq %rbp, %rbp
-
-	movq $(\i), %rdi   	# %rdi - first parameter
-	movq %rsp, %rsi   	# %rsi - pointer to istate
-	call exc_dispatch 	# exc_dispatch(i, istate)
-	
-	restore_all_gpr
-	# $8 = Skip error word
-	addq $(IREGISTER_SPACE+8), %rsp
-	iretq
-
-	.align INTERRUPT_ALIGN
-	.if (\n-\i)-1
-	handler "(\i+1)",\n
-	.endif
-.endm
-
-.align INTERRUPT_ALIGN
-interrupt_handlers:
-h_start:
-	handler 0 IDT_ITEMS
-h_end:
-
-## Low-level syscall handler
-# 
-# Registers on entry:
-#
-# @param rcx		Userspace return address.
-# @param r11		Userspace RLFAGS.
-#
-# @param rax		Syscall number.
-# @param rdi		1st syscall argument.
-# @param rsi		2nd syscall argument.
-# @param rdx		3rd syscall argument.
-# @param r10		4th syscall argument. Used instead of RCX because the
-#			SYSCALL instruction clobbers it.
-# @param r8		5th syscall argument.
-# @param r9		6th syscall argument.
-#
-# @return		Return value is in rax.
-#
-syscall_entry:
-	swapgs			# Switch to hidden gs	
-	# 
-	# %gs:0			Scratch space for this thread's user RSP
-	# %gs:8			Address to be used as this thread's kernel RSP
-	#
-	movq %rsp, %gs:0	# Save this thread's user RSP
-	movq %gs:8, %rsp	# Set this thread's kernel RSP
-	swapgs			# Switch back to remain consistent
-	sti
-	
-	pushq %rcx
-	pushq %r11
-
-	movq %r10, %rcx		# Copy the 4th argument where it is expected 
-	pushq %rax
-	call syscall_handler
-	addq $8, %rsp
-		
-	popq %r11
-	popq %rcx
-
-	cli
-	swapgs
-	movq %gs:0, %rsp	# Restore the user RSP
-	swapgs
-
-	sysretq
-
-.data
-.global interrupt_handler_size
-
-interrupt_handler_size: .quad (h_end-h_start)/IDT_ITEMS
Index: kernel/arch/amd64/src/boot/boot.S
===================================================================
--- kernel/arch/amd64/src/boot/boot.S	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/amd64/src/boot/boot.S	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -1,35 +1,35 @@
-#
-# Copyright (c) 2005 Ondrej Palkovsky
-# Copyright (c) 2006 Martin Decky
-# 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.
-#
+/*
+ * Copyright (c) 2005 Ondrej Palkovsky
+ * Copyright (c) 2006 Martin Decky
+ * 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.
+ */
 
 #include <arch/boot/boot.h>
 #include <arch/boot/memmap.h>
-#include <arch/mm/page.h>	
+#include <arch/mm/page.h>
 #include <arch/mm/ptl.h>
 #include <arch/pm.h>
@@ -37,9 +37,30 @@
 #include <arch/cpuid.h>
 
-#define START_STACK	(BOOT_OFFSET - BOOT_STACK_SIZE)
+#define START_STACK  (BOOT_OFFSET - BOOT_STACK_SIZE)
 
 .section K_TEXT_START, "ax"
 
 .code32
+
+.macro pm_error msg
+	movl \msg, %esi
+	jmp pm_error_halt
+.endm
+
+.macro pm_status msg
+#ifdef CONFIG_EGA
+	pushl %esi
+	movl \msg, %esi
+	call pm_early_puts
+	popl %esi
+#endif
+.endm
+
+.macro pm2_status msg
+#ifndef CONFIG_FB
+	pm_status \msg
+#endif
+.endm
+
 .align 4
 .global multiboot_image_start
@@ -47,5 +68,5 @@
 	.long MULTIBOOT_HEADER_MAGIC
 	.long MULTIBOOT_HEADER_FLAGS
-	.long -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS)  # checksum
+	.long -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS)  /* checksum */
 	.long multiboot_header
 	.long unmapped_ktext_start
@@ -56,31 +77,33 @@
 multiboot_image_start:
 	cld
-	movl $START_STACK, %esp             # initialize stack pointer
-	lgdtl bootstrap_gdtr                # initialize Global Descriptor Table register
-	
-	movw $gdtselector(KDATA_DES), %cx
+	
+	/* Initialize stack pointer */
+	movl $START_STACK, %esp
+	
+	/* Initialize Global Descriptor Table register */
+	lgdtl bootstrap_gdtr
+	
+	/* Kernel data + stack */
+	movw $GDT_SELECTOR(KDATA_DES), %cx
 	movw %cx, %es
-	movw %cx, %ds                       # kernel data + stack
+	movw %cx, %ds
 	movw %cx, %ss
 	
-	#
-	# Simics seems to remove hidden part of GS on entering user mode
-	# when _visible_ part of GS does not point to user-mode segment.
-	#
-	
-	movw $gdtselector(UDATA_DES), %cx
+	/*
+	 * Simics seems to remove hidden part of GS on entering user mode
+	 * when _visible_ part of GS does not point to user-mode segment.
+	 */
+	movw $GDT_SELECTOR(UDATA_DES), %cx
 	movw %cx, %fs
 	movw %cx, %gs
 	
-	jmpl $gdtselector(KTEXT32_DES), $multiboot_meeting_point
+	jmpl $GDT_SELECTOR(KTEXT32_DES), $multiboot_meeting_point
 	multiboot_meeting_point:
 	
-	movl %eax, grub_eax                 # save parameters from GRUB
+	/* Save GRUB arguments */
+	movl %eax, grub_eax
 	movl %ebx, grub_ebx
 	
-	#
-	# Protected 32-bit. We want to reuse the code-seg descriptor,
-	# the Default operand size must not be 1 when entering long mode.
-	#
+	pm_status $status_prot
 	
 	movl $(INTEL_CPUID_EXTENDED), %eax
@@ -89,6 +112,5 @@
 	ja extended_cpuid_supported
 	
-		movl $extended_cpuid_msg, %esi
-		jmp error_halt
+		pm_error $err_extended_cpuid
 	
 	extended_cpuid_supported:
@@ -99,6 +121,5 @@
 	jc long_mode_supported
 	
-		movl $long_mode_msg, %esi
-		jmp error_halt
+		pm_error $err_long_mode
 	
 	long_mode_supported:
@@ -107,6 +128,5 @@
 	jc noexecute_supported
 	
-		movl $noexecute_msg, %esi
-		jmp error_halt
+		pm_error $err_noexecute
 	
 	noexecute_supported:
@@ -117,6 +137,5 @@
 	jc fx_supported
 	
-		movl $fx_msg, %esi
-		jmp error_halt
+		pm_error $err_fx
 	
 	fx_supported:
@@ -125,15 +144,21 @@
 	jc sse2_supported
 	
-		movl $sse2_msg, %esi
-		jmp error_halt
+		pm_error $err_sse2
 	
 	sse2_supported:
-
+	
 #include "vesa_prot.inc"
-
-	#
-	# Enable 64-bit page translation entries - CR4.PAE = 1.
-	# Paging is not enabled until after long mode is enabled.
-	#
+	
+	/*
+	 * Protected 32-bit. We want to reuse the code-seg descriptor,
+	 * the Default operand size must not be 1 when entering long mode.
+	 */
+	
+	pm2_status $status_prot2
+	
+	/*
+	 * Enable 64-bit page translation entries - CR4.PAE = 1.
+	 * Paging is not enabled until after long mode is enabled.
+	 */
 	
 	movl %cr4, %eax
@@ -141,45 +166,276 @@
 	movl %eax, %cr4
 	
-	# set up paging tables
-	
+	/* Set up paging tables */
 	leal ptl_0, %eax
 	movl %eax, %cr3
 	
-	# enable long mode
-	
-	movl $EFER_MSR_NUM, %ecx            # EFER MSR number
-	rdmsr                               # read EFER
-	btsl $AMD_LME_FLAG, %eax            # set LME = 1
-	wrmsr                               # write EFER
-	
-	# enable paging to activate long mode (set CR0.PG = 1)
-	
+	/* Enable long mode */
+	movl $EFER_MSR_NUM, %ecx
+	rdmsr                     /* read EFER */
+	btsl $AMD_LME_FLAG, %eax  /* set LME = 1 */
+	wrmsr
+	
+	/* Enable paging to activate long mode (set CR0.PG = 1) */
 	movl %cr0, %eax
 	btsl $31, %eax
 	movl %eax, %cr0
 	
-	# at this point we are in compatibility mode
-	
-	jmpl $gdtselector(KTEXT_DES), $start64
+	/* At this point we are in compatibility mode */
+	jmpl $GDT_SELECTOR(KTEXT_DES), $start64
+
+/** Print string to EGA display (in light red) and halt.
+ *
+ * Should be executed from 32 bit protected mode with paging
+ * turned off. Stack is not required. This routine is used even
+ * if CONFIG_EGA is not enabled. Since we are going to halt the
+ * CPU anyway, it is always better to at least try to print
+ * some hints.
+ *
+ * @param %esi Pointer to the NULL-terminated string
+ *             to be print.
+ *
+ */
+pm_error_halt:
+	movl $0xb8000, %edi  /* base of EGA text mode memory */
+	xorl %eax, %eax
+	
+	/* Read bits 8 - 15 of the cursor address */
+	movw $0x3d4, %dx
+	movb $0xe, %al
+	outb %al, %dx
+	
+	movw $0x3d5, %dx
+	inb %dx, %al
+	shl $8, %ax
+	
+	/* Read bits 0 - 7 of the cursor address */
+	movw $0x3d4, %dx
+	movb $0xf, %al
+	outb %al, %dx
+	
+	movw $0x3d5, %dx
+	inb %dx, %al
+	
+	/* Sanity check for the cursor on screen */
+	cmp $2000, %ax
+	jb err_cursor_ok
+	
+		movw $1998, %ax
+	
+	err_cursor_ok:
+	
+	movw %ax, %bx
+	shl $1, %eax
+	addl %eax, %edi
+	
+	err_ploop:
+		lodsb
+		
+		cmp $0, %al
+		je err_ploop_end
+		
+		movb $0x0c, %ah  /* black background, light red foreground */
+		stosw
+		
+		/* Sanity check for the cursor on the last line */
+		inc %bx
+		cmp $2000, %bx
+		jb err_ploop
+		
+		/* Scroll the screen (24 rows) */
+		movl %esi, %edx
+		movl $0xb80a0, %esi
+		movl $0xb8000, %edi
+		movl $960, %ecx
+		rep movsl
+		
+		/* Clear the 24th row */
+		xorl %eax, %eax
+		movl $40, %ecx
+		rep stosl
+		
+		/* Go to row 24 */
+		movl %edx, %esi
+		movl $0xb8f00, %edi
+		movw $1920, %bx
+		
+		jmp err_ploop
+	err_ploop_end:
+	
+	/* Write bits 8 - 15 of the cursor address */
+	movw $0x3d4, %dx
+	movb $0xe, %al
+	outb %al, %dx
+	
+	movw $0x3d5, %dx
+	movb %bh, %al
+	outb %al, %dx
+	
+	/* Write bits 0 - 7 of the cursor address */
+	movw $0x3d4, %dx
+	movb $0xf, %al
+	outb %al, %dx
+	
+	movw $0x3d5, %dx
+	movb %bl, %al
+	outb %al, %dx
+	
+	cli
+	hlt1:
+		hlt
+		jmp hlt1
+
+/** Print string to EGA display (in light green).
+ *
+ * Should be called from 32 bit protected mode with paging
+ * turned off. A stack space of at least 24 bytes is required,
+ * but the function does not establish a stack frame.
+ *
+ * Macros such as pm_status and pm2_status take care that
+ * this function is used only when CONFIG_EGA is enabled
+ * and CONFIG_FB is disabled.
+ *
+ * @param %esi Pointer to the NULL-terminated string
+ *             to be print.
+ *
+ */
+pm_early_puts:
+	pushl %eax
+	pushl %ebx
+	pushl %ecx
+	pushl %edx
+	pushl %edi
+	
+	movl $0xb8000, %edi  /* base of EGA text mode memory */
+	xorl %eax, %eax
+	
+	/* Read bits 8 - 15 of the cursor address */
+	movw $0x3d4, %dx
+	movb $0xe, %al
+	outb %al, %dx
+	
+	movw $0x3d5, %dx
+	inb %dx, %al
+	shl $8, %ax
+	
+	/* Read bits 0 - 7 of the cursor address */
+	movw $0x3d4, %dx
+	movb $0xf, %al
+	outb %al, %dx
+	
+	movw $0x3d5, %dx
+	inb %dx, %al
+	
+	/* Sanity check for the cursor on screen */
+	cmp $2000, %ax
+	jb pm_puts_cursor_ok
+	
+		movw $1998, %ax
+	
+	pm_puts_cursor_ok:
+	
+	movw %ax, %bx
+	shl $1, %eax
+	addl %eax, %edi
+	
+	pm_puts_ploop:
+		lodsb
+		
+		cmp $0, %al
+		je pm_puts_ploop_end
+		
+		movb $0x0a, %ah  /* black background, light green foreground */
+		stosw
+		
+		/* Sanity check for the cursor on the last line */
+		inc %bx
+		cmp $2000, %bx
+		jb pm_puts_ploop
+		
+		/* Scroll the screen (24 rows) */
+		movl %esi, %edx
+		movl $0xb80a0, %esi
+		movl $0xb8000, %edi
+		movl $960, %ecx
+		rep movsl
+		
+		/* Clear the 24th row */
+		xorl %eax, %eax
+		movl $40, %ecx
+		rep stosl
+		
+		/* Go to row 24 */
+		movl %edx, %esi
+		movl $0xb8f00, %edi
+		movw $1920, %bx
+		
+		jmp pm_puts_ploop
+	pm_puts_ploop_end:
+	
+	/* Write bits 8 - 15 of the cursor address */
+	movw $0x3d4, %dx
+	movb $0xe, %al
+	outb %al, %dx
+	
+	movw $0x3d5, %dx
+	movb %bh, %al
+	outb %al, %dx
+	
+	/* Write bits 0 - 7 of the cursor address */
+	movw $0x3d4, %dx
+	movb $0xf, %al
+	outb %al, %dx
+	
+	movw $0x3d5, %dx
+	movb %bl, %al
+	outb %al, %dx
+	
+	popl %edi
+	popl %edx
+	popl %ecx
+	popl %ebx
+	popl %eax
+	
+	ret
 
 .code64
+
+.macro long_status msg
+	pushq %rdi
+	movq \msg, %rdi
+	call early_puts
+	popq %rdi
+.endm
+
 start64:
+	
+	/*
+	 * Long mode.
+	 */
+	
 	movq $(PA2KA(START_STACK)), %rsp
 	
-	# call arch_pre_main(grub_eax, grub_ebx)
+	/* Create the first stack frame */
+	pushq $0
+	movq %rsp, %rbp
+	
+	long_status $status_long
+	
+	/* Call arch_pre_main(grub_eax, grub_ebx) */
 	xorq %rdi, %rdi
 	movl grub_eax, %edi
 	xorq %rsi, %rsi
 	movl grub_ebx, %esi
-	call arch_pre_main
-	
-	# create the first stack frame
-	pushq $0
-	movq %rsp, %rbp
-
-	call main_bsp
-	
-	# not reached
-	
+	
+	movabsq $arch_pre_main, %rax
+	callq *%rax
+	
+	long_status $status_main
+	
+	/* Call main_bsp() */
+	movabsq $main_bsp, %rax
+	call *%rax
+	
+	/* Not reached */
 	cli
 	hlt0:
@@ -187,10 +443,32 @@
 		jmp hlt0
 
-# Print string from %esi to EGA display (in red) and halt
-error_halt:
-	movl $0xb8000, %edi       # base of EGA text mode memory
-	xorl %eax, %eax
-	
-	movw $0x3d4, %dx          # read bits 8 - 15 of the cursor address
+/** Print string to EGA display.
+ *
+ * Should be called from long mode (with paging enabled
+ * and stack established). This function is ABI compliant
+ * (without red-zone).
+ *
+ * If CONFIG_EGA is undefined or CONFIG_FB is defined
+ * then this function does nothing.
+ *
+ * @param %rdi Pointer to the NULL-terminated string
+ *             to be printed.
+ *
+ */
+early_puts:
+	
+#if ((defined(CONFIG_EGA)) && (!defined(CONFIG_FB)))
+	
+	/* Prologue, save preserved registers */
+	pushq %rbp
+	movq %rsp, %rbp
+	pushq %rbx
+	
+	movq %rdi, %rsi
+	movq $(PA2KA(0xb8000)), %rdi  /* base of EGA text mode memory */
+	xorq %rax, %rax
+	
+	/* Read bits 8 - 15 of the cursor address */
+	movw $0x3d4, %dx
 	movb $0xe, %al
 	outb %al, %dx
@@ -200,5 +478,6 @@
 	shl $8, %ax
 	
-	movw $0x3d4, %dx          # read bits 0 - 7 of the cursor address
+	/* Read bits 0 - 7 of the cursor address */
+	movw $0x3d4, %dx
 	movb $0xf, %al
 	outb %al, %dx
@@ -207,27 +486,52 @@
 	inb %dx, %al
 	
-	cmp $1920, %ax
-	jbe cursor_ok
-	
-		movw $1920, %ax       # sanity check for the cursor on the last line
-	
-	cursor_ok:
+	/* Sanity check for the cursor on screen */
+	cmp $2000, %ax
+	jb early_puts_cursor_ok
+	
+		movw $1998, %ax
+	
+	early_puts_cursor_ok:
 	
 	movw %ax, %bx
-	shl $1, %eax
-	addl %eax, %edi
-	
-	movw $0x0c00, %ax         # black background, light red foreground
-	
-	ploop:
+	shl $1, %rax
+	addq %rax, %rdi
+	
+	early_puts_ploop:
 		lodsb
+		
 		cmp $0, %al
-		je ploop_end
+		je early_puts_ploop_end
+		
+		movb $0x0e, %ah  /* black background, yellow foreground */
 		stosw
+		
+		/* Sanity check for the cursor on the last line */
 		inc %bx
-		jmp ploop
-	ploop_end:
-	
-	movw $0x3d4, %dx          # write bits 8 - 15 of the cursor address
+		cmp $2000, %bx
+		jb early_puts_ploop
+		
+		/* Scroll the screen (24 rows) */
+		movq %rsi, %rdx
+		movq $(PA2KA(0xb80a0)), %rsi
+		movq $(PA2KA(0xb8000)), %rdi
+		movq $480, %rcx
+		rep movsq
+		
+		/* Clear the 24th row */
+		xorq %rax, %rax
+		movq $20, %rcx
+		rep stosq
+		
+		/* Go to row 24 */
+		movq %rdx, %rsi
+		movq $(PA2KA(0xb8f00)), %rdi
+		movw $1920, %bx
+		
+		jmp early_puts_ploop
+	early_puts_ploop_end:
+	
+	/* Write bits 8 - 15 of the cursor address */
+	movw $0x3d4, %dx
 	movb $0xe, %al
 	outb %al, %dx
@@ -237,5 +541,6 @@
 	outb %al, %dx
 	
-	movw $0x3d4, %dx          # write bits 0 - 7 of the cursor address
+	/* Write bits 0 - 7 of the cursor address */
+	movw $0x3d4, %dx
 	movb $0xf, %al
 	outb %al, %dx
@@ -245,8 +550,11 @@
 	outb %al, %dx
 	
-	cli
-	hlt1:
-		hlt
-		jmp hlt1
+	/* Epilogue, restore preserved registers */
+	popq %rbx
+	leave
+	
+#endif
+	
+	ret
 
 #include "vesa_real.inc"
@@ -254,59 +562,76 @@
 .section K_INI_PTLS, "aw", @progbits
 
-#
-# Macro for generating initial page table contents.
-# @param cnt Number of entries to generat. Must be multiple of 8.
-# @param g   Number of GB that will be added to the mapping.
-#
-.macro ptl2gen cnt g 
-.if \cnt
-	ptl2gen "\cnt - 8" \g 
-	.quad ((\cnt - 8) * 0x200000) + (\g * 1024 * 1024 * 1024) | (PTL_WRITABLE | PTL_PRESENT | PTL_2MB_PAGE)
-	.quad ((\cnt - 7) * 0x200000) + (\g * 1024 * 1024 * 1024) | (PTL_WRITABLE | PTL_PRESENT | PTL_2MB_PAGE)
-	.quad ((\cnt - 6) * 0x200000) + (\g * 1024 * 1024 * 1024) | (PTL_WRITABLE | PTL_PRESENT | PTL_2MB_PAGE)
-	.quad ((\cnt - 5) * 0x200000) + (\g * 1024 * 1024 * 1024) | (PTL_WRITABLE | PTL_PRESENT | PTL_2MB_PAGE)
-	.quad ((\cnt - 4) * 0x200000) + (\g * 1024 * 1024 * 1024) | (PTL_WRITABLE | PTL_PRESENT | PTL_2MB_PAGE)
-	.quad ((\cnt - 3) * 0x200000) + (\g * 1024 * 1024 * 1024) | (PTL_WRITABLE | PTL_PRESENT | PTL_2MB_PAGE)
-	.quad ((\cnt - 2) * 0x200000) + (\g * 1024 * 1024 * 1024) | (PTL_WRITABLE | PTL_PRESENT | PTL_2MB_PAGE)
-	.quad ((\cnt - 1) * 0x200000) + (\g * 1024 * 1024 * 1024) | (PTL_WRITABLE | PTL_PRESENT | PTL_2MB_PAGE)
-.endif
+/** Generate initial page table contents.
+ *
+ * @param cnt Number of entries to generate. Must be multiple of 8.
+ * @param g   Number of GB that will be added to the mapping.
+ *
+ */
+.macro ptl2gen cnt g
+	.if \cnt
+		ptl2gen "\cnt - 8" \g
+		.quad ((\cnt - 8) * 0x200000) + (\g * 1024 * 1024 * 1024) | (PTL_WRITABLE | PTL_PRESENT | PTL_2MB_PAGE)
+		.quad ((\cnt - 7) * 0x200000) + (\g * 1024 * 1024 * 1024) | (PTL_WRITABLE | PTL_PRESENT | PTL_2MB_PAGE)
+		.quad ((\cnt - 6) * 0x200000) + (\g * 1024 * 1024 * 1024) | (PTL_WRITABLE | PTL_PRESENT | PTL_2MB_PAGE)
+		.quad ((\cnt - 5) * 0x200000) + (\g * 1024 * 1024 * 1024) | (PTL_WRITABLE | PTL_PRESENT | PTL_2MB_PAGE)
+		.quad ((\cnt - 4) * 0x200000) + (\g * 1024 * 1024 * 1024) | (PTL_WRITABLE | PTL_PRESENT | PTL_2MB_PAGE)
+		.quad ((\cnt - 3) * 0x200000) + (\g * 1024 * 1024 * 1024) | (PTL_WRITABLE | PTL_PRESENT | PTL_2MB_PAGE)
+		.quad ((\cnt - 2) * 0x200000) + (\g * 1024 * 1024 * 1024) | (PTL_WRITABLE | PTL_PRESENT | PTL_2MB_PAGE)
+		.quad ((\cnt - 1) * 0x200000) + (\g * 1024 * 1024 * 1024) | (PTL_WRITABLE | PTL_PRESENT | PTL_2MB_PAGE)
+	.endif
 .endm
 
-# Page table for pages in the first gigabyte.
-.align 4096
-.global ptl_2_0g
-ptl_2_0g:	
+/* Page table for pages in the 1st gigabyte. */
+.align 4096
+ptl_2_0g:
 	ptl2gen 512 0
 
-# Page table for pages in the second gigabyte.
-.align 4096
-.global ptl_2_1g
+/* Page table for pages in the 2nd gigabyte. */
+.align 4096
 ptl_2_1g:
 	ptl2gen 512 1
 
-# Page table for pages in the third gigabyte.
-.align 4096
-.global ptl_2_2g
+/* Page table for pages in the 3rd gigabyte. */
+.align 4096
 ptl_2_2g:
 	ptl2gen 512 2
 
-# Page table for pages in the fourth gigabyte.
-.align 4096
-.global ptl_2_3g
+/* Page table for pages in the 4th gigabyte. */
+.align 4096
 ptl_2_3g:
 	ptl2gen 512 3
 
-.align 4096
-.global ptl_1
+/* Page table for pages in the 5th gigabyte. */
+.align 4096
+ptl_2_4g:
+	ptl2gen 512 4
+
+/* Page table for pages in the 6th gigabyte. */
+.align 4096
+ptl_2_5g:
+	ptl2gen 512 5
+
+/* Page table for pages in the 7th gigabyte. */
+.align 4096
+ptl_2_6g:
+	ptl2gen 512 6
+
+/* Page table for pages in the 8th gigabyte. */
+.align 4096
+ptl_2_7g:
+	ptl2gen 512 7
+
+.align 4096
 ptl_1:
-	# Identity mapping for [0; 4G)
+	/* Identity mapping for [0; 8G) */
 	.quad ptl_2_0g + (PTL_WRITABLE | PTL_PRESENT)
-	.quad ptl_2_1g + (PTL_WRITABLE | PTL_PRESENT) 
+	.quad ptl_2_1g + (PTL_WRITABLE | PTL_PRESENT)
 	.quad ptl_2_2g + (PTL_WRITABLE | PTL_PRESENT)
 	.quad ptl_2_3g + (PTL_WRITABLE | PTL_PRESENT)
-	.fill 506, 8, 0
-	# Mapping of [0; 1G) at -2G
-	.quad ptl_2_0g + (PTL_WRITABLE | PTL_PRESENT)
-	.fill 1, 8, 0
+	.quad ptl_2_4g + (PTL_WRITABLE | PTL_PRESENT)
+	.quad ptl_2_5g + (PTL_WRITABLE | PTL_PRESENT)
+	.quad ptl_2_6g + (PTL_WRITABLE | PTL_PRESENT)
+	.quad ptl_2_7g + (PTL_WRITABLE | PTL_PRESENT)
+	.fill 504, 8, 0
 
 .align 4096
@@ -314,14 +639,12 @@
 ptl_0:
 	.quad ptl_1 + (PTL_WRITABLE | PTL_PRESENT)
-	.fill 255,8,0
+	.fill 255, 8, 0
 	.quad ptl_1 + (PTL_WRITABLE | PTL_PRESENT)
-	.fill 254,8,0
-	.quad ptl_1 + (PTL_WRITABLE | PTL_PRESENT)
+	.fill 255, 8, 0
 
 .section K_DATA_START, "aw", @progbits
 
-.global bootstrap_gdtr
 bootstrap_gdtr:
-	.word gdtselector(GDT_ITEMS)
+	.word GDT_SELECTOR(GDT_ITEMS)
 	.long KA2PA(gdt)
 
@@ -332,12 +655,27 @@
 	.long 0
 
-extended_cpuid_msg:
+err_extended_cpuid:
 	.asciz "Error: Extended CPUID not supported -- CPU is not 64-bit. System halted."
-long_mode_msg:
+err_long_mode:
 	.asciz "Error: 64-bit long mode not supported. System halted."
-noexecute_msg:
+err_noexecute:
 	.asciz "Error: No-execute pages not supported. System halted."
-fx_msg:
+err_fx:
 	.asciz "Error: FXSAVE/FXRESTORE instructions not supported. System halted."
-sse2_msg:
+err_sse2:
 	.asciz "Error: SSE2 instructions not supported. System halted."
+
+status_prot:
+	.asciz "[prot] "
+status_vesa_copy:
+	.asciz "[vesa_copy] "
+status_grub_cmdline:
+	.asciz "[grub_cmdline] "
+status_vesa_real:
+	.asciz "[vesa_real] "
+status_prot2:
+	.asciz "[prot2] "
+status_long:
+	.asciz "[long] "
+status_main:
+	.asciz "[main] "
Index: kernel/arch/amd64/src/boot/vesa_ret.inc
===================================================================
--- kernel/arch/amd64/src/boot/vesa_ret.inc	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/amd64/src/boot/vesa_ret.inc	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -1,19 +1,23 @@
 .code32
 vesa_init_protected:
-	movw $gdtselector(KDATA_DES), %cx
+	cld
+	
+	/* Initialize stack pointer */
+	movl $START_STACK, %esp
+	
+	/* Kernel data + stack */
+	movw $GDT_SELECTOR(KDATA_DES), %cx
 	movw %cx, %es
-	movw %cx, %ds                       # kernel data + stack
+	movw %cx, %ds
 	movw %cx, %ss
 	
-	#
-	# Simics seems to remove hidden part of GS on entering user mode
-	# when _visible_ part of GS does not point to user-mode segment.
-	#
+	/*
+	 * Simics seems to remove hidden part of GS on entering user mode
+	 * when _visible_ part of GS does not point to user-mode segment.
+	 */
 	
-	movw $gdtselector(UDATA_DES), %cx
+	movw $GDT_SELECTOR(UDATA_DES), %cx
 	movw %cx, %fs
 	movw %cx, %gs
 	
-	movl $START_STACK, %esp             # initialize stack pointer
-	
-	jmpl $gdtselector(KTEXT32_DES), $vesa_meeting_point
+	jmpl $GDT_SELECTOR(KTEXT32_DES), $vesa_meeting_point
Index: kernel/arch/amd64/src/context.S
===================================================================
--- kernel/arch/amd64/src/context.S	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/amd64/src/context.S	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -41,9 +41,9 @@
 context_save_arch:
 	movq (%rsp), %rdx     # the caller's return %eip
-
-	# In %edi is passed 1st argument
-	CONTEXT_SAVE_ARCH_CORE %rdi %rdx 
 	
-	xorq %rax,%rax		# context_save returns 1
+	# 1st argument passed in %edi
+	CONTEXT_SAVE_ARCH_CORE %rdi %rdx
+	
+	xorq %rax, %rax       # context_save returns 1
 	incq %rax
 	ret
@@ -55,10 +55,9 @@
 # pointed by the 1st argument. Returns 0 in EAX.
 #
-context_restore_arch:	
-
+context_restore_arch:
 	CONTEXT_RESTORE_ARCH_CORE %rdi %rdx
-
-	movq %rdx,(%rsp)
-
-	xorq %rax,%rax		# context_restore returns 0
+	
+	movq %rdx, (%rsp)
+	
+	xorq %rax, %rax       # context_restore returns 0
 	ret
Index: kernel/arch/amd64/src/cpu/cpu.c
===================================================================
--- kernel/arch/amd64/src/cpu/cpu.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/amd64/src/cpu/cpu.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -47,11 +47,11 @@
  * Contains only non-MP-Specification specific SMP code.
  */
-#define AMD_CPUID_EBX	0x68747541
-#define AMD_CPUID_ECX 	0x444d4163
-#define AMD_CPUID_EDX 	0x69746e65
+#define AMD_CPUID_EBX  0x68747541
+#define AMD_CPUID_ECX  0x444d4163
+#define AMD_CPUID_EDX  0x69746e65
 
-#define INTEL_CPUID_EBX	0x756e6547
-#define INTEL_CPUID_ECX 0x6c65746e
-#define INTEL_CPUID_EDX 0x49656e69
+#define INTEL_CPUID_EBX  0x756e6547
+#define INTEL_CPUID_ECX  0x6c65746e
+#define INTEL_CPUID_EDX  0x49656e69
 
 
@@ -127,31 +127,31 @@
 {
 	cpu_info_t info;
-
+	
 	CPU->arch.vendor = VendorUnknown;
 	if (has_cpuid()) {
 		cpuid(INTEL_CPUID_LEVEL, &info);
-
+		
 		/*
 		 * Check for AMD processor.
 		 */
-		if (info.cpuid_ebx == AMD_CPUID_EBX &&
-		    info.cpuid_ecx == AMD_CPUID_ECX &&
-		    info.cpuid_edx == AMD_CPUID_EDX) {
+		if ((info.cpuid_ebx == AMD_CPUID_EBX) &&
+		    (info.cpuid_ecx == AMD_CPUID_ECX) &&
+		    (info.cpuid_edx == AMD_CPUID_EDX)) {
 			CPU->arch.vendor = VendorAMD;
 		}
-
+		
 		/*
 		 * Check for Intel processor.
-		 */		
-		if (info.cpuid_ebx == INTEL_CPUID_EBX &&
-		    info.cpuid_ecx == INTEL_CPUID_ECX &&
-		    info.cpuid_edx == INTEL_CPUID_EDX) {
+		 */
+		if ((info.cpuid_ebx == INTEL_CPUID_EBX) &&
+		    (info.cpuid_ecx == INTEL_CPUID_ECX) &&
+		    (info.cpuid_edx == INTEL_CPUID_EDX)) {
 			CPU->arch.vendor = VendorIntel;
 		}
-				
+		
 		cpuid(INTEL_CPUID_STANDARD, &info);
 		CPU->arch.family = (info.cpuid_eax >> 8) & 0xf;
 		CPU->arch.model = (info.cpuid_eax >> 4) & 0xf;
-		CPU->arch.stepping = (info.cpuid_eax >> 0) & 0xf;						
+		CPU->arch.stepping = (info.cpuid_eax >> 0) & 0xf;
 	}
 }
Index: kernel/arch/amd64/src/ddi/ddi.c
===================================================================
--- kernel/arch/amd64/src/ddi/ddi.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/amd64/src/ddi/ddi.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -49,30 +49,27 @@
  * Interrupts are disabled and task is locked.
  *
- * @param task Task.
+ * @param task   Task.
  * @param ioaddr Startign I/O space address.
- * @param size Size of the enabled I/O range.
+ * @param size   Size of the enabled I/O range.
  *
  * @return 0 on success or an error code from errno.h.
+ *
  */
 int ddi_iospace_enable_arch(task_t *task, uintptr_t ioaddr, size_t size)
 {
-	size_t bits;
-	
-	bits = ioaddr + size;
+	size_t bits = ioaddr + size;
 	if (bits > IO_PORTS)
 		return ENOENT;
 	
 	if (task->arch.iomap.bits < bits) {
-		bitmap_t oldiomap;
-		uint8_t *newmap;
-		
 		/*
 		 * The I/O permission bitmap is too small and needs to be grown.
 		 */
 		
-		newmap = (uint8_t *) malloc(BITS2BYTES(bits), FRAME_ATOMIC);
+		uint8_t *newmap = (uint8_t *) malloc(BITS2BYTES(bits), FRAME_ATOMIC);
 		if (!newmap)
 			return ENOMEM;
 		
+		bitmap_t oldiomap;
 		bitmap_initialize(&oldiomap, task->arch.iomap.map,
 		    task->arch.iomap.bits);
@@ -115,23 +112,20 @@
  *
  * Interrupts must be disabled prior this call.
+ *
  */
 void io_perm_bitmap_install(void)
 {
-	size_t bits;
-	ptr_16_64_t cpugdtr;
-	descriptor_t *gdt_p;
-	tss_descriptor_t *tss_desc;
-	size_t ver;
-	
 	/* First, copy the I/O Permission Bitmap. */
-	spinlock_lock(&TASK->lock);
-	ver = TASK->arch.iomapver;
-	if ((bits = TASK->arch.iomap.bits)) {
+	irq_spinlock_lock(&TASK->lock, false);
+	size_t ver = TASK->arch.iomapver;
+	size_t bits = TASK->arch.iomap.bits;
+	if (bits) {
+		ASSERT(TASK->arch.iomap.map);
+		
 		bitmap_t iomap;
-	
-		ASSERT(TASK->arch.iomap.map);
 		bitmap_initialize(&iomap, CPU->arch.tss->iomap,
 		    TSS_IOMAP_SIZE * 8);
 		bitmap_copy(&iomap, &TASK->arch.iomap, TASK->arch.iomap.bits);
+		
 		/*
 		 * It is safe to set the trailing eight bits because of the
@@ -140,5 +134,5 @@
 		bitmap_set_range(&iomap, ALIGN_UP(TASK->arch.iomap.bits, 8), 8);
 	}
-	spinlock_unlock(&TASK->lock);
+	irq_spinlock_unlock(&TASK->lock, false);
 	
 	/*
@@ -146,6 +140,8 @@
 	 * Take the extra ending byte will all bits set into account. 
 	 */
+	ptr_16_64_t cpugdtr;
 	gdtr_store(&cpugdtr);
-	gdt_p = (descriptor_t *) cpugdtr.base;
+	
+	descriptor_t *gdt_p = (descriptor_t *) cpugdtr.base;
 	gdt_tss_setlimit(&gdt_p[TSS_DES], TSS_BASIC_SIZE + BITS2BYTES(bits));
 	gdtr_load(&cpugdtr);
@@ -155,7 +151,7 @@
 	 * type must be changed to describe inactive TSS.
 	 */
-	tss_desc = (tss_descriptor_t *) &gdt_p[TSS_DES];
+	tss_descriptor_t *tss_desc = (tss_descriptor_t *) &gdt_p[TSS_DES];
 	tss_desc->type = AR_TSS;
-	tr_load(gdtselector(TSS_DES));
+	tr_load(GDT_SELECTOR(TSS_DES));
 	
 	/*
Index: kernel/arch/amd64/src/debug/stacktrace.c
===================================================================
--- kernel/arch/amd64/src/debug/stacktrace.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/amd64/src/debug/stacktrace.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -37,41 +37,43 @@
 #include <typedefs.h>
 
-#define FRAME_OFFSET_FP_PREV	0
-#define FRAME_OFFSET_RA		1
+#define FRAME_OFFSET_FP_PREV  0
+#define FRAME_OFFSET_RA       1
 
-bool kernel_frame_pointer_validate(uintptr_t fp)
+bool kernel_stack_trace_context_validate(stack_trace_context_t *ctx)
 {
-	return fp != 0;
+	return ctx->fp != 0;
 }
 
-bool kernel_frame_pointer_prev(uintptr_t fp, uintptr_t *prev)
+bool kernel_frame_pointer_prev(stack_trace_context_t *ctx, uintptr_t *prev)
 {
-	uint64_t *stack = (void *) fp;
+	uint64_t *stack = (void *) ctx->fp;
 	*prev = stack[FRAME_OFFSET_FP_PREV];
+	
 	return true;
 }
 
-bool kernel_return_address_get(uintptr_t fp, uintptr_t *ra)
+bool kernel_return_address_get(stack_trace_context_t *ctx, uintptr_t *ra)
 {
-	uint64_t *stack = (void *) fp;
+	uint64_t *stack = (void *) ctx->fp;
 	*ra = stack[FRAME_OFFSET_RA];
+	
 	return true;
 }
 
-bool uspace_frame_pointer_validate(uintptr_t fp)
+bool uspace_stack_trace_context_validate(stack_trace_context_t *ctx)
 {
-	return fp != 0;
+	return ctx->fp != 0;
 }
 
-bool uspace_frame_pointer_prev(uintptr_t fp, uintptr_t *prev)
+bool uspace_frame_pointer_prev(stack_trace_context_t *ctx, uintptr_t *prev)
 {
 	return !copy_from_uspace((void *) prev,
-	    (uint64_t *) fp + FRAME_OFFSET_FP_PREV, sizeof(*prev));
+	    (uint64_t *) ctx->fp + FRAME_OFFSET_FP_PREV, sizeof(*prev));
 }
 
-bool uspace_return_address_get(uintptr_t fp, uintptr_t *ra)
+bool uspace_return_address_get(stack_trace_context_t *ctx, uintptr_t *ra)
 {
-	return !copy_from_uspace((void *) ra, (uint64_t *) fp + FRAME_OFFSET_RA,
-	    sizeof(*ra));
+	return !copy_from_uspace((void *) ra,
+	    (uint64_t *) ctx->fp + FRAME_OFFSET_RA, sizeof(*ra));
 }
 
Index: kernel/arch/amd64/src/debugger.c
===================================================================
--- kernel/arch/amd64/src/debugger.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/amd64/src/debugger.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -46,16 +46,27 @@
 #include <symtab.h>
 
+#ifdef __64_BITS__
+	#define getip(x)  ((x)->rip)
+#endif
+
+#ifdef __32_BITS__
+	#define getip(x)  ((x)->eip)
+#endif
+
 typedef struct  {
-	uintptr_t address;      /**< Breakpoint address */
-	int flags;              /**< Flags regarding breakpoint */
-	int counter;            /**< How many times the exception occured */
+	uintptr_t address;   /**< Breakpoint address */
+	unsigned int flags;  /**< Flags regarding breakpoint */
+	size_t counter;      /**< How many times the exception occured */
 } bpinfo_t;
 
 static bpinfo_t breakpoints[BKPOINTS_MAX];
-SPINLOCK_INITIALIZE(bkpoint_lock);
+IRQ_SPINLOCK_STATIC_INITIALIZE(bkpoint_lock);
 
 #ifdef CONFIG_KCONSOLE
 
-static int cmd_print_breakpoints(cmd_arg_t *argv);
+static int cmd_print_breakpoints(cmd_arg_t *);
+static int cmd_del_breakpoint(cmd_arg_t *);
+static int cmd_add_breakpoint(cmd_arg_t *);
+
 static cmd_info_t bkpts_info = {
 	.name = "bkpts",
@@ -65,11 +76,11 @@
 };
 
-static int cmd_del_breakpoint(cmd_arg_t *argv);
 static cmd_arg_t del_argv = {
 	.type = ARG_TYPE_INT
 };
+
 static cmd_info_t delbkpt_info = {
 	.name = "delbkpt",
-	.description = "delbkpt <number> - Delete breakpoint.",
+	.description = "Delete breakpoint.",
 	.func = cmd_del_breakpoint,
 	.argc = 1,
@@ -77,11 +88,11 @@
 };
 
-static int cmd_add_breakpoint(cmd_arg_t *argv);
 static cmd_arg_t add_argv = {
 	.type = ARG_TYPE_INT
 };
+
 static cmd_info_t addbkpt_info = {
 	.name = "addbkpt",
-	.description = "addbkpt <&symbol> - new breakpoint.",
+	.description = "Add breakpoint.",
 	.func = cmd_add_breakpoint,
 	.argc = 1,
@@ -92,7 +103,8 @@
 	.type = ARG_TYPE_INT
 };
+
 static cmd_info_t addwatchp_info = {
 	.name = "addwatchp",
-	.description = "addbwatchp <&symbol> - new write watchpoint.",
+	.description = "Add write watchpoint.",
 	.func = cmd_add_breakpoint,
 	.argc = 1,
@@ -102,16 +114,20 @@
 #endif /* CONFIG_KCONSOLE */
 
-/* Setup DR register according to table */
+/** Setup DR register according to table
+ *
+ */
 static void setup_dr(int curidx)
 {
-	unative_t dr7;
+	ASSERT(curidx >= 0);
+	
 	bpinfo_t *cur = &breakpoints[curidx];
-	int flags = breakpoints[curidx].flags;
-
+	unsigned int flags = breakpoints[curidx].flags;
+	
 	/* Disable breakpoint in DR7 */
-	dr7 = read_dr7();
-	dr7 &= ~(0x2 << (curidx*2));
-
-	if (cur->address) { /* Setup DR register */
+	unative_t dr7 = read_dr7();
+	dr7 &= ~(0x2 << (curidx * 2));
+	
+	/* Setup DR register */
+	if (cur->address) {
 		/* Set breakpoint to debug registers */
 		switch (curidx) {
@@ -129,15 +145,14 @@
 			break;
 		}
+		
 		/* Set type to requested breakpoint & length*/
-		dr7 &= ~ (0x3 << (16 + 4*curidx));
-		dr7 &= ~ (0x3 << (18 + 4*curidx));
-		if ((flags & BKPOINT_INSTR)) {
-			;
-		} else {
+		dr7 &= ~(0x3 << (16 + 4 * curidx));
+		dr7 &= ~(0x3 << (18 + 4 * curidx));
 		
+		if (!(flags & BKPOINT_INSTR)) {
 #ifdef __32_BITS__
 			dr7 |= ((unative_t) 0x3) << (18 + 4 * curidx);
 #endif
-
+			
 #ifdef __64_BITS__
 			dr7 |= ((unative_t) 0x2) << (18 + 4 * curidx);
@@ -149,87 +164,81 @@
 				dr7 |= ((unative_t) 0x3) << (16 + 4 * curidx);
 		}
-
+		
 		/* Enable global breakpoint */
 		dr7 |= 0x2 << (curidx * 2);
-
+		
 		write_dr7(dr7);
-		
-	} 
-}
-	
+	}
+}
+
 /** Enable hardware breakpoint
  *
  * @param where Address of HW breakpoint
  * @param flags Type of breakpoint (EXECUTE, WRITE)
+ *
  * @return Debug slot on success, -1 - no available HW breakpoint
- */
-int breakpoint_add(const void *where, const int flags, int curidx)
-{
-	ipl_t ipl;
-	int i;
-	bpinfo_t *cur;
-
+ *
+ */
+int breakpoint_add(const void *where, const unsigned int flags, int curidx)
+{
 	ASSERT(flags & (BKPOINT_INSTR | BKPOINT_WRITE | BKPOINT_READ_WRITE));
-
-	ipl = interrupts_disable();
-	spinlock_lock(&bkpoint_lock);
+	
+	irq_spinlock_lock(&bkpoint_lock, true);
 	
 	if (curidx == -1) {
 		/* Find free space in slots */
-		for (i = 0; i < BKPOINTS_MAX; i++)
+		unsigned int i;
+		for (i = 0; i < BKPOINTS_MAX; i++) {
 			if (!breakpoints[i].address) {
 				curidx = i;
 				break;
 			}
+		}
+		
 		if (curidx == -1) {
 			/* Too many breakpoints */
-			spinlock_unlock(&bkpoint_lock);
-			interrupts_restore(ipl);
+			irq_spinlock_unlock(&bkpoint_lock, true);
 			return -1;
 		}
 	}
-	cur = &breakpoints[curidx];
-
+	
+	bpinfo_t *cur = &breakpoints[curidx];
+	
 	cur->address = (uintptr_t) where;
 	cur->flags = flags;
 	cur->counter = 0;
-
+	
 	setup_dr(curidx);
-
-	spinlock_unlock(&bkpoint_lock);
-	interrupts_restore(ipl);
-
+	
+	irq_spinlock_unlock(&bkpoint_lock, true);
+	
 	/* Send IPI */
 //	ipi_broadcast(VECTOR_DEBUG_IPI);
-
+	
 	return curidx;
 }
 
-#ifdef __64_BITS__
-	#define getip(x)  ((x)->rip)
-#else
-	#define getip(x)  ((x)->eip)
-#endif
-
 static void handle_exception(int slot, istate_t *istate)
 {
+	ASSERT(slot >= 0);
 	ASSERT(breakpoints[slot].address);
-
+	
 	/* Handle zero checker */
-	if (! (breakpoints[slot].flags & BKPOINT_INSTR)) {
+	if (!(breakpoints[slot].flags & BKPOINT_INSTR)) {
 		if ((breakpoints[slot].flags & BKPOINT_CHECK_ZERO)) {
 			if (*((unative_t *) breakpoints[slot].address) != 0)
 				return;
-			printf("*** Found ZERO on address %lx (slot %d) ***\n",
+			
+			printf("*** Found ZERO on address %" PRIp " (slot %d) ***\n",
 			    breakpoints[slot].address, slot);
 		} else {
-			printf("Data watchpoint - new data: %lx\n",
+			printf("Data watchpoint - new data: %" PRIp "\n",
 			    *((unative_t *) breakpoints[slot].address));
 		}
 	}
-
-	printf("Reached breakpoint %d:%lx (%s)\n", slot, getip(istate),
+	
+	printf("Reached breakpoint %d:%" PRIp " (%s)\n", slot, getip(istate),
 	    symtab_fmt_name_lookup(getip(istate)));
-
+	
 #ifdef CONFIG_KCONSOLE
 	atomic_set(&haltstate, 1);
@@ -241,42 +250,37 @@
 void breakpoint_del(int slot)
 {
-	bpinfo_t *cur;
-	ipl_t ipl;
-
-	ipl = interrupts_disable();
-	spinlock_lock(&bkpoint_lock);
-
-	cur = &breakpoints[slot];
+	ASSERT(slot >= 0);
+	
+	irq_spinlock_lock(&bkpoint_lock, true);
+	
+	bpinfo_t *cur = &breakpoints[slot];
 	if (!cur->address) {
-		spinlock_unlock(&bkpoint_lock);
-		interrupts_restore(ipl);
+		irq_spinlock_unlock(&bkpoint_lock, true);
 		return;
 	}
-
+	
 	cur->address = NULL;
-
+	
 	setup_dr(slot);
-
-	spinlock_unlock(&bkpoint_lock);
-	interrupts_restore(ipl);
+	
+	irq_spinlock_unlock(&bkpoint_lock, true);
 //	ipi_broadcast(VECTOR_DEBUG_IPI);
 }
 
-
-
-static void debug_exception(int n __attribute__((unused)), istate_t *istate)
-{
-	unative_t dr6;
-	int i;
-	
+static void debug_exception(unsigned int n __attribute__((unused)), istate_t *istate)
+{
 	/* Set RF to restart the instruction  */
 #ifdef __64_BITS__
 	istate->rflags |= RFLAGS_RF;
-#else
+#endif
+	
+#ifdef __32_BITS__
 	istate->eflags |= EFLAGS_RF;
 #endif
-
-	dr6 = read_dr6();
-	for (i=0; i < BKPOINTS_MAX; i++) {
+	
+	unative_t dr6 = read_dr6();
+	
+	unsigned int i;
+	for (i = 0; i < BKPOINTS_MAX; i++) {
 		if (dr6 & (1 << i)) {
 			dr6 &= ~ (1 << i);
@@ -289,38 +293,39 @@
 
 #ifdef CONFIG_SMP
-static void
-debug_ipi(int n __attribute__((unused)),
+static void debug_ipi(unsigned int n __attribute__((unused)),
     istate_t *istate __attribute__((unused)))
 {
-	int i;
-
-	spinlock_lock(&bkpoint_lock);
+	irq_spinlock_lock(&bkpoint_lock, false);
+	
+	unsigned int i;
 	for (i = 0; i < BKPOINTS_MAX; i++)
 		setup_dr(i);
-	spinlock_unlock(&bkpoint_lock);
-}
-#endif
-
-/** Initialize debugger */
+	
+	irq_spinlock_unlock(&bkpoint_lock, false);
+}
+#endif /* CONFIG_SMP */
+
+/** Initialize debugger
+ *
+ */
 void debugger_init()
 {
-	int i;
-
+	unsigned int i;
 	for (i = 0; i < BKPOINTS_MAX; i++)
 		breakpoints[i].address = NULL;
-
+	
 #ifdef CONFIG_KCONSOLE
 	cmd_initialize(&bkpts_info);
 	if (!cmd_register(&bkpts_info))
 		printf("Cannot register command %s\n", bkpts_info.name);
-
+	
 	cmd_initialize(&delbkpt_info);
 	if (!cmd_register(&delbkpt_info))
 		printf("Cannot register command %s\n", delbkpt_info.name);
-
+	
 	cmd_initialize(&addbkpt_info);
 	if (!cmd_register(&addbkpt_info))
 		printf("Cannot register command %s\n", addbkpt_info.name);
-
+	
 	cmd_initialize(&addwatchp_info);
 	if (!cmd_register(&addwatchp_info))
@@ -328,48 +333,53 @@
 #endif /* CONFIG_KCONSOLE */
 	
-	exc_register(VECTOR_DEBUG, "debugger", debug_exception);
+	exc_register(VECTOR_DEBUG, "debugger", true,
+	    debug_exception);
+	
 #ifdef CONFIG_SMP
-	exc_register(VECTOR_DEBUG_IPI, "debugger_smp", debug_ipi);
-#endif
+	exc_register(VECTOR_DEBUG_IPI, "debugger_smp", true,
+	    debug_ipi);
+#endif /* CONFIG_SMP */
 }
 
 #ifdef CONFIG_KCONSOLE
-/** Print table of active breakpoints */
+/** Print table of active breakpoints
+ *
+ */
 int cmd_print_breakpoints(cmd_arg_t *argv __attribute__((unused)))
 {
+#ifdef __32_BITS__
+	printf("[nr] [count] [address ] [in symbol\n");
+#endif
+	
+#ifdef __64_BITS__
+	printf("[nr] [count] [address         ] [in symbol\n");
+#endif
+	
 	unsigned int i;
-
-#ifdef __32_BITS__
-	printf("#  Count Address    In symbol\n");
-	printf("-- ----- ---------- ---------\n");
-#endif
-
-#ifdef __64_BITS__
-	printf("#  Count Address            In symbol\n");
-	printf("-- ----- ------------------ ---------\n");
-#endif
-	
-	for (i = 0; i < BKPOINTS_MAX; i++)
+	for (i = 0; i < BKPOINTS_MAX; i++) {
 		if (breakpoints[i].address) {
 			const char *symbol = symtab_fmt_name_lookup(
 			    breakpoints[i].address);
-
+			
 #ifdef __32_BITS__
-			printf("%-2u %-5d %#10zx %s\n", i,
+			printf("%-4u %7" PRIs " %p %s\n", i,
 			    breakpoints[i].counter, breakpoints[i].address,
 			    symbol);
 #endif
-
+			
 #ifdef __64_BITS__
-			printf("%-2u %-5d %#18zx %s\n", i,
+			printf("%-4u %7" PRIs " %p %s\n", i,
 			    breakpoints[i].counter, breakpoints[i].address,
 			    symbol);
 #endif
-
-		}
+		}
+	}
+	
 	return 1;
 }
 
-/** Remove breakpoint from table */
+/** Remove breakpoint from table
+ *
+ */
 int cmd_del_breakpoint(cmd_arg_t *argv)
 {
@@ -379,21 +389,23 @@
 		return 0;
 	}
+	
 	breakpoint_del(argv->intval);
 	return 1;
 }
 
-/** Add new breakpoint to table */
+/** Add new breakpoint to table
+ *
+ */
 static int cmd_add_breakpoint(cmd_arg_t *argv)
 {
-	int flags;
-	int id;
-
-	if (argv == &add_argv) {
+	unsigned int flags;
+	if (argv == &add_argv)
 		flags = BKPOINT_INSTR;
-	} else { /* addwatchp */
+	else
 		flags = BKPOINT_WRITE;
-	}
+	
 	printf("Adding breakpoint on address: %p\n", argv->intval);
-	id = breakpoint_add((void *)argv->intval, flags, -1);
+	
+	int id = breakpoint_add((void *)argv->intval, flags, -1);
 	if (id < 0)
 		printf("Add breakpoint failed.\n");
Index: kernel/arch/amd64/src/delay.S
===================================================================
--- kernel/arch/amd64/src/delay.S	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/amd64/src/delay.S	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -37,10 +37,14 @@
 
 asm_delay_loop:
-0:	dec %rdi
-	jnz 0b
+	0:
+		dec %rdi
+		jnz 0b
+	
 	ret
 
 asm_fake_loop:
-0:	dec %rdi
-	jz 0b
+	0:
+		dec %rdi
+		jz 0b
+	
 	ret
Index: kernel/arch/amd64/src/fpu_context.c
===================================================================
--- kernel/arch/amd64/src/fpu_context.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/amd64/src/fpu_context.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -27,5 +27,5 @@
  */
 
-/** @addtogroup amd64	
+/** @addtogroup amd64
  * @{
  */
Index: kernel/arch/amd64/src/interrupt.c
===================================================================
--- kernel/arch/amd64/src/interrupt.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/amd64/src/interrupt.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -63,22 +63,21 @@
 void (* eoi_function)(void) = NULL;
 
-void decode_istate(int n, istate_t *istate)
-{
-	const char *symbol = symtab_fmt_name_lookup(istate->rip);
-	
-	printf("-----EXCEPTION(%d) OCCURED----- ( %s )\n", n, __func__);
-	printf("%%rip: %#llx (%s)\n", istate->rip, symbol);
-	printf("ERROR_WORD=%#llx\n", istate->error_word);
-	printf("%%cs=%#llx, rflags=%#llx, %%cr0=%#llx\n", istate->cs,
-	    istate->rflags, read_cr0());
-	printf("%%rax=%#llx, %%rcx=%#llx, %%rdx=%#llx\n", istate->rax,
-	    istate->rcx, istate->rdx);
-	printf("%%rsi=%#llx, %%rdi=%#llx, %%r8=%#llx\n", istate->rsi,
-	    istate->rdi, istate->r8);
-	printf("%%r9=%#llx, %%r10=%#llx, %%r11=%#llx\n", istate->r9,
-	    istate->r10, istate->r11);
-	printf("%%rsp=%#llx\n", &istate->stack[0]);
-	
-	stack_trace_istate(istate);
+void istate_decode(istate_t *istate)
+{
+	printf("cs =%p\trip=%p\trfl=%p\terr=%p\n",
+	    istate->cs, istate->rip, istate->rflags, istate->error_word);
+
+	if (istate_from_uspace(istate))
+		printf("ss =%p\n", istate->ss);
+	
+	printf("rax=%p\trbx=%p\trcx=%p\trdx=%p\n",
+	    istate->rax, istate->rbx, istate->rcx, istate->rdx);
+	printf("rsi=%p\trdi=%p\trbp=%p\trsp=%p\n",
+	    istate->rsi, istate->rdi, istate->rbp,
+	    istate_from_uspace(istate) ? istate->rsp : (uintptr_t)&istate->rsp);
+	printf("r8 =%p\tr9 =%p\tr10=%p\tr11=%p\n",
+	    istate->r8, istate->r9, istate->r10, istate->r11);
+	printf("r12=%p\tr13=%p\tr14=%p\tr15=%p\n",
+	    istate->r12, istate->r13, istate->r14, istate->r15);
 }
 
@@ -92,28 +91,26 @@
 }
 
-static void null_interrupt(int n, istate_t *istate)
-{
-	fault_if_from_uspace(istate, "Unserviced interrupt: %d.", n);
-	decode_istate(n, istate);
-	panic("Unserviced interrupt.");
-}
-
-static void de_fault(int n, istate_t *istate)
+static void null_interrupt(unsigned int n, istate_t *istate)
+{
+	fault_if_from_uspace(istate, "Unserviced interrupt: %u.", n);
+	panic_badtrap(istate, n, "Unserviced interrupt.");
+}
+
+static void de_fault(unsigned int n, istate_t *istate)
 {
 	fault_if_from_uspace(istate, "Divide error.");
-	decode_istate(n, istate);
-	panic("Divide error.");
-}
-
-/** General Protection Fault. */
-static void gp_fault(int n, istate_t *istate)
+	panic_badtrap(istate, n, "Divide error.");
+}
+
+/** General Protection Fault.
+ *
+ */
+static void gp_fault(unsigned int n, istate_t *istate)
 {
 	if (TASK) {
-		size_t ver;
-
-		spinlock_lock(&TASK->lock);
-		ver = TASK->arch.iomapver;
-		spinlock_unlock(&TASK->lock);
-
+		irq_spinlock_lock(&TASK->lock, false);
+		size_t ver = TASK->arch.iomapver;
+		irq_spinlock_unlock(&TASK->lock, false);
+		
 		if (CPU->arch.iomapver_copy != ver) {
 			/*
@@ -129,17 +126,14 @@
 		fault_if_from_uspace(istate, "General protection fault.");
 	}
-
-	decode_istate(n, istate);
-	panic("General protection fault.");
-}
-
-static void ss_fault(int n, istate_t *istate)
+	panic_badtrap(istate, n, "General protection fault.");
+}
+
+static void ss_fault(unsigned int n, istate_t *istate)
 {
 	fault_if_from_uspace(istate, "Stack fault.");
-	decode_istate(n, istate);
-	panic("Stack fault.");
-}
-
-static void nm_fault(int n, istate_t *istate)
+	panic_badtrap(istate, n, "Stack fault.");
+}
+
+static void nm_fault(unsigned int n, istate_t *istate)
 {
 #ifdef CONFIG_FPU_LAZY
@@ -152,5 +146,5 @@
 
 #ifdef CONFIG_SMP
-static void tlb_shootdown_ipi(int n, istate_t *istate)
+static void tlb_shootdown_ipi(unsigned int n, istate_t *istate)
 {
 	trap_virtual_eoi();
@@ -159,10 +153,12 @@
 #endif
 
-/** Handler of IRQ exceptions */
-static void irq_interrupt(int n, istate_t *istate)
+/** Handler of IRQ exceptions.
+ *
+ */
+static void irq_interrupt(unsigned int n, istate_t *istate)
 {
 	ASSERT(n >= IVT_IRQBASE);
 	
-	int inum = n - IVT_IRQBASE;
+	unsigned int inum = n - IVT_IRQBASE;
 	bool ack = false;
 	ASSERT(inum < IRQ_COUNT);
@@ -174,5 +170,5 @@
 		 * The IRQ handler was found.
 		 */
-		 
+		
 		if (irq->preack) {
 			/* Send EOI before processing the interrupt */
@@ -181,5 +177,5 @@
 		}
 		irq->handler(irq);
-		spinlock_unlock(&irq->lock);
+		irq_spinlock_unlock(&irq->lock, false);
 	} else {
 		/*
@@ -187,5 +183,5 @@
 		 */
 #ifdef CONFIG_DEBUG
-		printf("cpu%d: spurious interrupt (inum=%d)\n", CPU->id, inum);
+		printf("cpu%u: spurious interrupt (inum=%u)\n", CPU->id, inum);
 #endif
 	}
@@ -197,24 +193,23 @@
 void interrupt_init(void)
 {
-	int i;
+	unsigned int i;
 	
 	for (i = 0; i < IVT_ITEMS; i++)
-		exc_register(i, "null", (iroutine) null_interrupt);
+		exc_register(i, "null", false, (iroutine_t) null_interrupt);
 	
 	for (i = 0; i < IRQ_COUNT; i++) {
 		if ((i != IRQ_PIC_SPUR) && (i != IRQ_PIC1))
-			exc_register(IVT_IRQBASE + i, "irq",
-			    (iroutine) irq_interrupt);
+			exc_register(IVT_IRQBASE + i, "irq", true,
+			    (iroutine_t) irq_interrupt);
 	}
 	
-	exc_register(0, "de_fault", (iroutine) de_fault);
-	exc_register(7, "nm_fault", (iroutine) nm_fault);
-	exc_register(12, "ss_fault", (iroutine) ss_fault);
-	exc_register(13, "gp_fault", (iroutine) gp_fault);
-	exc_register(14, "ident_mapper", (iroutine) ident_page_fault);
+	exc_register(0, "de_fault", true, (iroutine_t) de_fault);
+	exc_register(7, "nm_fault", true, (iroutine_t) nm_fault);
+	exc_register(12, "ss_fault", true, (iroutine_t) ss_fault);
+	exc_register(13, "gp_fault", true, (iroutine_t) gp_fault);
 	
 #ifdef CONFIG_SMP
-	exc_register(VECTOR_TLB_SHOOTDOWN_IPI, "tlb_shootdown",
-	    (iroutine) tlb_shootdown_ipi);
+	exc_register(VECTOR_TLB_SHOOTDOWN_IPI, "tlb_shootdown", true,
+	    (iroutine_t) tlb_shootdown_ipi);
 #endif
 }
Index: kernel/arch/amd64/src/mm/page.c
===================================================================
--- kernel/arch/amd64/src/mm/page.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/amd64/src/mm/page.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -39,5 +39,4 @@
 #include <mm/frame.h>
 #include <mm/as.h>
-#include <arch/interrupt.h>
 #include <arch/asm.h>
 #include <config.h>
@@ -48,138 +47,37 @@
 #include <align.h>
 
-/* Definitions for identity page mapper */
-pte_t helper_ptl1[512] __attribute__((aligned (PAGE_SIZE)));
-pte_t helper_ptl2[512] __attribute__((aligned (PAGE_SIZE)));
-pte_t helper_ptl3[512] __attribute__((aligned (PAGE_SIZE)));
-extern pte_t ptl_0; /* From boot.S */
-
-#define PTL1_PRESENT(ptl0, page) (!(GET_PTL1_FLAGS_ARCH(ptl0, PTL0_INDEX_ARCH(page)) & PAGE_NOT_PRESENT))
-#define PTL2_PRESENT(ptl1, page) (!(GET_PTL2_FLAGS_ARCH(ptl1, PTL1_INDEX_ARCH(page)) & PAGE_NOT_PRESENT))
-#define PTL3_PRESENT(ptl2, page) (!(GET_PTL3_FLAGS_ARCH(ptl2, PTL2_INDEX_ARCH(page)) & PAGE_NOT_PRESENT))
-
-#define PTL1_ADDR(ptl0, page) ((pte_t *)PA2KA(GET_PTL1_ADDRESS_ARCH(ptl0, PTL0_INDEX_ARCH(page))))
-#define PTL2_ADDR(ptl1, page) ((pte_t *)PA2KA(GET_PTL2_ADDRESS_ARCH(ptl1, PTL1_INDEX_ARCH(page))))
-#define PTL3_ADDR(ptl2, page) ((pte_t *)PA2KA(GET_PTL3_ADDRESS_ARCH(ptl2, PTL2_INDEX_ARCH(page))))
-
-#define SETUP_PTL1(ptl0, page, tgt)  {	\
-	SET_PTL1_ADDRESS_ARCH(ptl0, PTL0_INDEX_ARCH(page), (uintptr_t)KA2PA(tgt)); \
-        SET_PTL1_FLAGS_ARCH(ptl0, PTL0_INDEX_ARCH(page), PAGE_WRITE | PAGE_EXEC); \
-    }
-#define SETUP_PTL2(ptl1, page, tgt)  {	\
-	SET_PTL2_ADDRESS_ARCH(ptl1, PTL1_INDEX_ARCH(page), (uintptr_t)KA2PA(tgt)); \
-        SET_PTL2_FLAGS_ARCH(ptl1, PTL1_INDEX_ARCH(page), PAGE_WRITE | PAGE_EXEC); \
-    }
-#define SETUP_PTL3(ptl2, page, tgt)  {	\
-	SET_PTL3_ADDRESS_ARCH(ptl2, PTL2_INDEX_ARCH(page), (uintptr_t)KA2PA(tgt)); \
-        SET_PTL3_FLAGS_ARCH(ptl2, PTL2_INDEX_ARCH(page), PAGE_WRITE | PAGE_EXEC); \
-    }
-#define SETUP_FRAME(ptl3, page, tgt)  {	\
-	SET_FRAME_ADDRESS_ARCH(ptl3, PTL3_INDEX_ARCH(page), (uintptr_t)KA2PA(tgt)); \
-        SET_FRAME_FLAGS_ARCH(ptl3, PTL3_INDEX_ARCH(page), PAGE_WRITE | PAGE_EXEC); \
-    }
-
-
 void page_arch_init(void)
 {
-	uintptr_t cur;
-	unsigned int i;
-	int identity_flags = PAGE_CACHEABLE | PAGE_EXEC | PAGE_GLOBAL | PAGE_WRITE;
-
 	if (config.cpu_active == 1) {
+		uintptr_t cur;
+		unsigned int identity_flags =
+		    PAGE_CACHEABLE | PAGE_EXEC | PAGE_GLOBAL | PAGE_WRITE;
+		
 		page_mapping_operations = &pt_mapping_operations;
-
+		
+		page_table_lock(AS_KERNEL, true);
+		
 		/*
 		 * PA2KA(identity) mapping for all frames.
 		 */
-		for (cur = 0; cur < last_frame; cur += FRAME_SIZE) {
-			/* Standard identity mapping */
+		for (cur = 0; cur < last_frame; cur += FRAME_SIZE)
 			page_mapping_insert(AS_KERNEL, PA2KA(cur), cur, identity_flags);
-		}
 		
-		/* Upper kernel mapping
-		 * - from zero to top of kernel (include bottom addresses
-		 *   because some are needed for init)
-		 */
-		for (cur = PA2KA_CODE(0); cur < config.base + config.kernel_size; cur += FRAME_SIZE)
-			page_mapping_insert(AS_KERNEL, cur, KA2PA(cur), identity_flags);
+		page_table_unlock(AS_KERNEL, true);
 		
-		for (cur = config.stack_base; cur < config.stack_base + config.stack_size; cur += FRAME_SIZE)
-			page_mapping_insert(AS_KERNEL, cur, KA2PA(cur), identity_flags);
-		
-		for (i = 0; i < init.cnt; i++) {
-			for (cur = init.tasks[i].addr; cur < init.tasks[i].addr + init.tasks[i].size; cur += FRAME_SIZE)
-				page_mapping_insert(AS_KERNEL, PA2KA_CODE(KA2PA(cur)), KA2PA(cur), identity_flags);
-		}
-
-		exc_register(14, "page_fault", (iroutine) page_fault);
+		exc_register(14, "page_fault", true, (iroutine_t) page_fault);
 		write_cr3((uintptr_t) AS_KERNEL->genarch.page_table);
-	} else 
+	} else
 		write_cr3((uintptr_t) AS_KERNEL->genarch.page_table);
 }
 
-
-/** Identity page mapper
- *
- * We need to map whole physical memory identically before the page subsystem
- * is initializaed. This thing clears page table and fills in the specific
- * items.
- */
-void ident_page_fault(int n, istate_t *istate)
+void page_fault(unsigned int n, istate_t *istate)
 {
-	uintptr_t page;
-	static uintptr_t oldpage = 0;
-	pte_t *aptl_1, *aptl_2, *aptl_3;
-
-	page = read_cr2();
-	if (oldpage) {
-		/* Unmap old address */
-		aptl_1 = PTL1_ADDR(&ptl_0, oldpage);
-		aptl_2 = PTL2_ADDR(aptl_1, oldpage);
-		aptl_3 = PTL3_ADDR(aptl_2, oldpage);
-
-		SET_FRAME_FLAGS_ARCH(aptl_3, PTL3_INDEX_ARCH(oldpage), PAGE_NOT_PRESENT);
-		if (KA2PA(aptl_3) == KA2PA(helper_ptl3))
-			SET_PTL3_FLAGS_ARCH(aptl_2, PTL2_INDEX_ARCH(oldpage), PAGE_NOT_PRESENT);
-		if (KA2PA(aptl_2) == KA2PA(helper_ptl2))
-			SET_PTL2_FLAGS_ARCH(aptl_1, PTL1_INDEX_ARCH(oldpage), PAGE_NOT_PRESENT);
-		if (KA2PA(aptl_1) == KA2PA(helper_ptl1))
-			SET_PTL1_FLAGS_ARCH(&ptl_0, PTL0_INDEX_ARCH(oldpage), PAGE_NOT_PRESENT);
-	}
-	if (PTL1_PRESENT(&ptl_0, page))
-		aptl_1 = PTL1_ADDR(&ptl_0, page);
-	else {
-		SETUP_PTL1(&ptl_0, page, helper_ptl1);
-		aptl_1 = helper_ptl1;
-	}
-	    
-	if (PTL2_PRESENT(aptl_1, page)) 
-		aptl_2 = PTL2_ADDR(aptl_1, page);
-	else {
-		SETUP_PTL2(aptl_1, page, helper_ptl2);
-		aptl_2 = helper_ptl2;
-	}
-
-	if (PTL3_PRESENT(aptl_2, page))
-		aptl_3 = PTL3_ADDR(aptl_2, page);
-	else {
-		SETUP_PTL3(aptl_2, page, helper_ptl3);
-		aptl_3 = helper_ptl3;
-	}
-	
-	SETUP_FRAME(aptl_3, page, page);
-
-	oldpage = page;
-}
-
-
-void page_fault(int n, istate_t *istate)
-{
-	uintptr_t page;
-	pf_access_t access;
-	
-	page = read_cr2();
+	uintptr_t page = read_cr2();
 	
 	if (istate->error_word & PFERR_CODE_RSVD)
 		panic("Reserved bit set in page table entry.");
+	
+	pf_access_t access;
 	
 	if (istate->error_word & PFERR_CODE_RW)
@@ -192,22 +90,23 @@
 	if (as_page_fault(page, access, istate) == AS_PF_FAULT) {
 		fault_if_from_uspace(istate, "Page fault: %#x.", page);
-
-		decode_istate(n, istate);
-		printf("Page fault address: %llx.\n", page);
-		panic("Page fault.");
+		panic_memtrap(istate, access, page, NULL);
 	}
 }
-
 
 uintptr_t hw_map(uintptr_t physaddr, size_t size)
 {
 	if (last_frame + ALIGN_UP(size, PAGE_SIZE) > KA2PA(KERNEL_ADDRESS_SPACE_END_ARCH))
-		panic("Unable to map physical memory %p (%d bytes).", physaddr,
+		panic("Unable to map physical memory %p (%" PRIs " bytes).", physaddr,
 		    size);
 	
 	uintptr_t virtaddr = PA2KA(last_frame);
 	pfn_t i;
+	
+	page_table_lock(AS_KERNEL, true);
+	
 	for (i = 0; i < ADDR2PFN(ALIGN_UP(size, PAGE_SIZE)); i++)
 		page_mapping_insert(AS_KERNEL, virtaddr + PFN2ADDR(i), physaddr + PFN2ADDR(i), PAGE_NOT_CACHEABLE | PAGE_WRITE);
+	
+	page_table_unlock(AS_KERNEL, true);
 	
 	last_frame = ALIGN_UP(last_frame + size, FRAME_SIZE);
Index: kernel/arch/amd64/src/pm.c
===================================================================
--- kernel/arch/amd64/src/pm.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/amd64/src/pm.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -171,12 +171,75 @@
 
 		d->unused = 0;
-		d->selector = gdtselector(KTEXT_DES);
+		d->selector = GDT_SELECTOR(KTEXT_DES);
 
 		d->present = 1;
 		d->type = AR_INTERRUPT;	/* masking interrupt */
-
-		idt_setoffset(d, ((uintptr_t) interrupt_handlers) +
-		    i * interrupt_handler_size);
 	}
+
+	d = &idt[0];
+	idt_setoffset(d++, (uintptr_t) &int_0);
+	idt_setoffset(d++, (uintptr_t) &int_1);
+	idt_setoffset(d++, (uintptr_t) &int_2);
+	idt_setoffset(d++, (uintptr_t) &int_3);
+	idt_setoffset(d++, (uintptr_t) &int_4);
+	idt_setoffset(d++, (uintptr_t) &int_5);
+	idt_setoffset(d++, (uintptr_t) &int_6);
+	idt_setoffset(d++, (uintptr_t) &int_7);
+	idt_setoffset(d++, (uintptr_t) &int_8);
+	idt_setoffset(d++, (uintptr_t) &int_9);
+	idt_setoffset(d++, (uintptr_t) &int_10);
+	idt_setoffset(d++, (uintptr_t) &int_11);
+	idt_setoffset(d++, (uintptr_t) &int_12);
+	idt_setoffset(d++, (uintptr_t) &int_13);
+	idt_setoffset(d++, (uintptr_t) &int_14);
+	idt_setoffset(d++, (uintptr_t) &int_15);
+	idt_setoffset(d++, (uintptr_t) &int_16);
+	idt_setoffset(d++, (uintptr_t) &int_17);
+	idt_setoffset(d++, (uintptr_t) &int_18);
+	idt_setoffset(d++, (uintptr_t) &int_19);
+	idt_setoffset(d++, (uintptr_t) &int_20);
+	idt_setoffset(d++, (uintptr_t) &int_21);
+	idt_setoffset(d++, (uintptr_t) &int_22);
+	idt_setoffset(d++, (uintptr_t) &int_23);
+	idt_setoffset(d++, (uintptr_t) &int_24);
+	idt_setoffset(d++, (uintptr_t) &int_25);
+	idt_setoffset(d++, (uintptr_t) &int_26);
+	idt_setoffset(d++, (uintptr_t) &int_27);
+	idt_setoffset(d++, (uintptr_t) &int_28);
+	idt_setoffset(d++, (uintptr_t) &int_29);
+	idt_setoffset(d++, (uintptr_t) &int_30);
+	idt_setoffset(d++, (uintptr_t) &int_31);
+	idt_setoffset(d++, (uintptr_t) &int_32);
+	idt_setoffset(d++, (uintptr_t) &int_33);
+	idt_setoffset(d++, (uintptr_t) &int_34);
+	idt_setoffset(d++, (uintptr_t) &int_35);
+	idt_setoffset(d++, (uintptr_t) &int_36);
+	idt_setoffset(d++, (uintptr_t) &int_37);
+	idt_setoffset(d++, (uintptr_t) &int_38);
+	idt_setoffset(d++, (uintptr_t) &int_39);
+	idt_setoffset(d++, (uintptr_t) &int_40);
+	idt_setoffset(d++, (uintptr_t) &int_41);
+	idt_setoffset(d++, (uintptr_t) &int_42);
+	idt_setoffset(d++, (uintptr_t) &int_43);
+	idt_setoffset(d++, (uintptr_t) &int_44);
+	idt_setoffset(d++, (uintptr_t) &int_45);
+	idt_setoffset(d++, (uintptr_t) &int_46);
+	idt_setoffset(d++, (uintptr_t) &int_47);
+	idt_setoffset(d++, (uintptr_t) &int_48);
+	idt_setoffset(d++, (uintptr_t) &int_49);
+	idt_setoffset(d++, (uintptr_t) &int_50);
+	idt_setoffset(d++, (uintptr_t) &int_51);
+	idt_setoffset(d++, (uintptr_t) &int_52);
+	idt_setoffset(d++, (uintptr_t) &int_53);
+	idt_setoffset(d++, (uintptr_t) &int_54);
+	idt_setoffset(d++, (uintptr_t) &int_55);
+	idt_setoffset(d++, (uintptr_t) &int_56);
+	idt_setoffset(d++, (uintptr_t) &int_57);
+	idt_setoffset(d++, (uintptr_t) &int_58);
+	idt_setoffset(d++, (uintptr_t) &int_59);
+	idt_setoffset(d++, (uintptr_t) &int_60);
+	idt_setoffset(d++, (uintptr_t) &int_61);
+	idt_setoffset(d++, (uintptr_t) &int_62);
+	idt_setoffset(d++, (uintptr_t) &int_63);
 }
 
@@ -228,5 +291,5 @@
 	 * to its own TSS. We just need to load the TR register.
 	 */
-	tr_load(gdtselector(TSS_DES));
+	tr_load(GDT_SELECTOR(TSS_DES));
 }
 
Index: kernel/arch/amd64/src/proc/scheduler.c
===================================================================
--- kernel/arch/amd64/src/proc/scheduler.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/amd64/src/proc/scheduler.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -38,5 +38,4 @@
 #include <proc/thread.h>
 #include <arch.h>
-#include <arch/context.h>	/* SP_DELTA */
 #include <arch/asm.h>
 #include <print.h>
@@ -57,13 +56,13 @@
 {
 	CPU->arch.tss->rsp0 =
-	    (uintptr_t) &THREAD->kstack[THREAD_STACK_SIZE - SP_DELTA];
-
+	    (uintptr_t) &THREAD->kstack[THREAD_STACK_SIZE];
+	
 	/*
 	 * Syscall support.
 	 */
 	swapgs();
-	write_msr(AMD_MSR_GS, (uintptr_t)THREAD->arch.syscall_rsp);
+	write_msr(AMD_MSR_GS, (uintptr_t) THREAD->arch.syscall_rsp);
 	swapgs();
-
+	
 	/* TLS support - set FS to thread local storage */
 	write_msr(AMD_MSR_FS, THREAD->arch.tls);
Index: kernel/arch/amd64/src/proc/task.c
===================================================================
--- kernel/arch/amd64/src/proc/task.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/amd64/src/proc/task.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -39,20 +39,22 @@
 /** Perform amd64 specific task initialization.
  *
- * @param t Task to be initialized.
+ * @param task Task to be initialized.
+ *
  */
-void task_create_arch(task_t *t)
+void task_create_arch(task_t *task)
 {
-	t->arch.iomapver = 0;
-	bitmap_initialize(&t->arch.iomap, NULL, 0);
+	task->arch.iomapver = 0;
+	bitmap_initialize(&task->arch.iomap, NULL, 0);
 }
 
 /** Perform amd64 specific task destruction.
  *
- * @param t Task to be initialized.
+ * @param task Task to be initialized.
+ *
  */
-void task_destroy_arch(task_t *t)
+void task_destroy_arch(task_t *task)
 {
-	if (t->arch.iomap.map)
-		free(t->arch.iomap.map);
+	if (task->arch.iomap.map)
+		free(task->arch.iomap.map);
 }
 
Index: kernel/arch/amd64/src/proc/thread.c
===================================================================
--- kernel/arch/amd64/src/proc/thread.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/amd64/src/proc/thread.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -34,18 +34,21 @@
 
 #include <proc/thread.h>
+#include <arch/interrupt.h>
 
 /** Perform amd64 specific thread initialization.
  *
- * @param t Thread to be initialized.
+ * @param thread Thread to be initialized.
+ *
  */
-void thread_create_arch(thread_t *t)
+void thread_create_arch(thread_t *thread)
 {
-	t->arch.tls = 0;
-	t->arch.syscall_rsp[SYSCALL_USTACK_RSP] = 0;
+	thread->arch.tls = 0;
+	thread->arch.syscall_rsp[SYSCALL_USTACK_RSP] = 0;
+	
 	/*
 	 * Kernel RSP can be precalculated at thread creation time.
 	 */
-	t->arch.syscall_rsp[SYSCALL_KSTACK_RSP] =
-	    (uintptr_t) &t->kstack[PAGE_SIZE - sizeof(uint64_t)];
+	thread->arch.syscall_rsp[SYSCALL_KSTACK_RSP] =
+	    (uintptr_t) &thread->kstack[PAGE_SIZE - sizeof(istate_t)];
 }
 
Index: kernel/arch/amd64/src/smp/ap.S
===================================================================
--- kernel/arch/amd64/src/smp/ap.S	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/amd64/src/smp/ap.S	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -55,22 +55,22 @@
 	xorw %ax, %ax
 	movw %ax, %ds
-
-	lgdtl ap_gdtr		# initialize Global Descriptor Table register
+	
+	lgdtl ap_gdtr       # initialize Global Descriptor Table register
 	
 	movl %cr0, %eax
 	orl $1, %eax
-	movl %eax, %cr0		# switch to protected mode
-	jmpl $gdtselector(KTEXT32_DES), $jump_to_kernel - BOOT_OFFSET + AP_BOOT_OFFSET
-	
+	movl %eax, %cr0     # switch to protected mode
+	jmpl $GDT_SELECTOR(KTEXT32_DES), $jump_to_kernel - BOOT_OFFSET + AP_BOOT_OFFSET
+
 jump_to_kernel:
 .code32
-	movw $gdtselector(KDATA_DES), %ax
+	movw $GDT_SELECTOR(KDATA_DES), %ax
 	movw %ax, %ds
 	movw %ax, %es
 	movw %ax, %ss
-	movw $gdtselector(UDATA_DES), %ax
+	movw $GDT_SELECTOR(UDATA_DES), %ax
 	movw %ax, %gs
 	
-	# Enable 64-bit page transaltion entries - CR4.PAE = 1.
+	# Enable 64-bit page transaltion entries (CR4.PAE = 1).
 	# Paging is not enabled until after long mode is enabled
 	
@@ -78,15 +78,15 @@
 	btsl $5, %eax
 	movl %eax, %cr4
-
+	
 	leal ptl_0, %eax
 	movl %eax, %cr3
 	
 	# Enable long mode
-	movl $EFER_MSR_NUM, %ecx	# EFER MSR number
-	rdmsr				# Read EFER
-	btsl $AMD_LME_FLAG, %eax	# Set LME=1
-	wrmsr				# Write EFER
+	movl $EFER_MSR_NUM, %ecx  # EFER MSR number
+	rdmsr                     # Read EFER
+	btsl $AMD_LME_FLAG, %eax  # Set LME=1
+	wrmsr                     # Write EFER
 	
-	# Enable paging to activate long mode (set CR0.PG=1)
+	# Enable paging to activate long mode (set CR0.PG = 1)
 	movl %cr0, %eax
 	btsl $31, %eax
@@ -94,12 +94,16 @@
 	
 	# At this point we are in compatibility mode
-	jmpl $gdtselector(KTEXT_DES), $start64 - BOOT_OFFSET + AP_BOOT_OFFSET
+	jmpl $GDT_SELECTOR(KTEXT_DES), $start64 - BOOT_OFFSET + AP_BOOT_OFFSET
 
 .code64
 start64:
-	movq (ctx), %rsp
+	movabsq $ctx, %rsp
+	movq (%rsp), %rsp
+	
 	pushq $0
 	movq %rsp, %rbp
-	call main_ap - AP_BOOT_OFFSET + BOOT_OFFSET   # never returns
+	
+	movabsq $main_ap, %rax
+	callq *%rax   # never returns
 
 #endif /* CONFIG_SMP */
Index: kernel/arch/amd64/src/syscall.c
===================================================================
--- kernel/arch/amd64/src/syscall.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/amd64/src/syscall.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -58,6 +58,6 @@
 	 */
 	write_msr(AMD_MSR_STAR,
-	    ((uint64_t)(gdtselector(KDATA_DES) | PL_USER) << 48) |
-	    ((uint64_t)(gdtselector(KTEXT_DES) | PL_KERNEL) << 32));
+	    ((uint64_t) (GDT_SELECTOR(KDATA_DES) | PL_USER) << 48) |
+	    ((uint64_t) (GDT_SELECTOR(KTEXT_DES) | PL_KERNEL) << 32));
 	write_msr(AMD_MSR_LSTAR, (uint64_t)syscall_entry);
 	/* Mask RFLAGS on syscall 
@@ -66,6 +66,7 @@
 	 * - clear DF so that the string instructions operate in
 	 *   the right direction
+	 * - clear NT to prevent a #GP should the flag proliferate to an IRET
 	 */
-	write_msr(AMD_MSR_SFMASK, RFLAGS_IF | RFLAGS_DF);
+	write_msr(AMD_MSR_SFMASK, RFLAGS_IF | RFLAGS_DF | RFLAGS_NT);
 }
 
Index: kernel/arch/amd64/src/userspace.c
===================================================================
--- kernel/arch/amd64/src/userspace.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/amd64/src/userspace.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -65,8 +65,8 @@
 		"xorq %%rdi, %%rdi\n"
 		"iretq\n"
-		:: [udata_des] "i" (gdtselector(UDATA_DES) | PL_USER),
+		:: [udata_des] "i" (GDT_SELECTOR(UDATA_DES) | PL_USER),
 		   [stack_size] "r" (kernel_uarg->uspace_stack + THREAD_STACK_SIZE),
 		   [ipl] "r" (ipl),
-		   [utext_des] "i" (gdtselector(UTEXT_DES) | PL_USER),
+		   [utext_des] "i" (GDT_SELECTOR(UTEXT_DES) | PL_USER),
 		   [entry] "r" (kernel_uarg->uspace_entry),
 		   [uarg] "r" (kernel_uarg->uspace_uarg)
Index: kernel/arch/arm32/Makefile.inc
===================================================================
--- kernel/arch/arm32/Makefile.inc	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/arm32/Makefile.inc	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -46,5 +46,4 @@
 	arch/$(KARCH)/src/context.S \
 	arch/$(KARCH)/src/dummy.S \
-	arch/$(KARCH)/src/panic.S \
 	arch/$(KARCH)/src/cpu/cpu.c \
 	arch/$(KARCH)/src/ddi/ddi.c \
@@ -61,4 +60,8 @@
 	arch/$(KARCH)/src/ras.c
 
+ifeq ($(MACHINE),gta02)
+	ARCH_SOURCES += arch/$(KARCH)/src/mach/gta02/gta02.c
+endif
+
 ifeq ($(MACHINE),testarm)
 	ARCH_SOURCES += arch/$(KARCH)/src/mach/testarm/testarm.c
Index: kernel/arch/arm32/_link.ld.in
===================================================================
--- kernel/arch/arm32/_link.ld.in	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/arm32/_link.ld.in	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -7,5 +7,9 @@
  */
 
+#ifdef MACHINE_gta02
+#define KERNEL_LOAD_ADDRESS 0xb0a08000
+#else
 #define KERNEL_LOAD_ADDRESS 0x80a00000
+#endif
 
 OUTPUT_ARCH(arm)
Index: kernel/arch/arm32/include/asm.h
===================================================================
--- kernel/arch/arm32/include/asm.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/arm32/include/asm.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -41,36 +41,37 @@
 #include <config.h>
 #include <arch/interrupt.h>
+#include <trace.h>
 
 /** No such instruction on ARM to sleep CPU. */
-static inline void cpu_sleep(void)
+NO_TRACE static inline void cpu_sleep(void)
 {
 }
 
-static inline void pio_write_8(ioport8_t *port, uint8_t v)
+NO_TRACE static inline void pio_write_8(ioport8_t *port, uint8_t v)
 {
 	*port = v;
 }
 
-static inline void pio_write_16(ioport16_t *port, uint16_t v)
+NO_TRACE static inline void pio_write_16(ioport16_t *port, uint16_t v)
 {
 	*port = v;
 }
 
-static inline void pio_write_32(ioport32_t *port, uint32_t v)
+NO_TRACE static inline void pio_write_32(ioport32_t *port, uint32_t v)
 {
 	*port = v;
 }
 
-static inline uint8_t pio_read_8(ioport8_t *port)
+NO_TRACE static inline uint8_t pio_read_8(ioport8_t *port)
 {
 	return *port;
 }
 
-static inline uint16_t pio_read_16(ioport16_t *port)
+NO_TRACE static inline uint16_t pio_read_16(ioport16_t *port)
 {
 	return *port;
 }
 
-static inline uint32_t pio_read_32(ioport32_t *port)
+NO_TRACE static inline uint32_t pio_read_32(ioport32_t *port)
 {
 	return *port;
@@ -84,7 +85,8 @@
  *
  */
-static inline uintptr_t get_stack_base(void)
+NO_TRACE static inline uintptr_t get_stack_base(void)
 {
 	uintptr_t v;
+	
 	asm volatile (
 		"and %[v], sp, %[size]\n" 
@@ -92,4 +94,5 @@
 		: [size] "r" (~(STACK_SIZE - 1))
 	);
+	
 	return v;
 }
Index: kernel/arch/arm32/include/atomic.h
===================================================================
--- kernel/arch/arm32/include/atomic.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/arm32/include/atomic.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -38,4 +38,5 @@
 
 #include <arch/asm.h>
+#include <trace.h>
 
 /** Atomic addition.
@@ -47,5 +48,6 @@
  *
  */
-static inline atomic_count_t atomic_add(atomic_t *val, atomic_count_t i)
+NO_TRACE static inline atomic_count_t atomic_add(atomic_t *val,
+    atomic_count_t i)
 {
 	/*
@@ -66,5 +68,5 @@
  *
  */
-static inline void atomic_inc(atomic_t *val)
+NO_TRACE static inline void atomic_inc(atomic_t *val)
 {
 	atomic_add(val, 1);
@@ -76,5 +78,5 @@
  *
  */
-static inline void atomic_dec(atomic_t *val) {
+NO_TRACE static inline void atomic_dec(atomic_t *val) {
 	atomic_add(val, -1);
 }
@@ -86,5 +88,5 @@
  *
  */
-static inline atomic_count_t atomic_preinc(atomic_t *val)
+NO_TRACE static inline atomic_count_t atomic_preinc(atomic_t *val)
 {
 	return atomic_add(val, 1);
@@ -97,5 +99,5 @@
  *
  */
-static inline atomic_count_t atomic_predec(atomic_t *val)
+NO_TRACE static inline atomic_count_t atomic_predec(atomic_t *val)
 {
 	return atomic_add(val, -1);
@@ -108,5 +110,5 @@
  *
  */
-static inline atomic_count_t atomic_postinc(atomic_t *val)
+NO_TRACE static inline atomic_count_t atomic_postinc(atomic_t *val)
 {
 	return atomic_add(val, 1) - 1;
@@ -119,5 +121,5 @@
  *
  */
-static inline atomic_count_t atomic_postdec(atomic_t *val)
+NO_TRACE static inline atomic_count_t atomic_postdec(atomic_t *val)
 {
 	return atomic_add(val, -1) + 1;
Index: kernel/arch/arm32/include/cycle.h
===================================================================
--- kernel/arch/arm32/include/cycle.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/arm32/include/cycle.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -37,11 +37,14 @@
 #define KERN_arm32_CYCLE_H_
 
-/** Returns count of CPU cycles.
+#include <trace.h>
+
+/** Return count of CPU cycles.
  *
- *  No such instruction on ARM to get count of cycles.
+ * No such instruction on ARM to get count of cycles.
  *
- *  @return Count of CPU cycles.
+ * @return Count of CPU cycles.
+ *
  */
-static inline uint64_t get_cycle(void)
+NO_TRACE static inline uint64_t get_cycle(void)
 {
 	return 0;
Index: rnel/arch/arm32/include/debug.h
===================================================================
--- kernel/arch/arm32/include/debug.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ 	(revision )
@@ -1,42 +1,0 @@
-/*
- * Copyright (c) 2005 Jakub Jermar 
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/** @addtogroup arm32debug
- * @{
- */
-/** @file
- *  @brief Empty.
- */
-
-#ifndef KERN_arm32_DEBUG_H_
-#define KERN_arm32_DEBUG_H_
-
-#endif
-
-/** @}
- */
Index: kernel/arch/arm32/include/exception.h
===================================================================
--- kernel/arch/arm32/include/exception.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/arm32/include/exception.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -28,5 +28,5 @@
  */
 
-/** @addtogroup arm32	
+/** @addtogroup arm32
  * @{
  */
@@ -40,4 +40,5 @@
 #include <typedefs.h>
 #include <arch/regutils.h>
+#include <trace.h>
 
 /** If defined, forces using of high exception vectors. */
@@ -45,17 +46,17 @@
 
 #ifdef HIGH_EXCEPTION_VECTORS
-	#define EXC_BASE_ADDRESS	0xffff0000
+	#define EXC_BASE_ADDRESS  0xffff0000
 #else
-	#define EXC_BASE_ADDRESS	0x0
+	#define EXC_BASE_ADDRESS  0x0
 #endif
 
 /* Exception Vectors */
-#define EXC_RESET_VEC          (EXC_BASE_ADDRESS + 0x0)
-#define EXC_UNDEF_INSTR_VEC    (EXC_BASE_ADDRESS + 0x4)
-#define EXC_SWI_VEC            (EXC_BASE_ADDRESS + 0x8)
-#define EXC_PREFETCH_ABORT_VEC (EXC_BASE_ADDRESS + 0xc)
-#define EXC_DATA_ABORT_VEC     (EXC_BASE_ADDRESS + 0x10)
-#define EXC_IRQ_VEC            (EXC_BASE_ADDRESS + 0x18)
-#define EXC_FIQ_VEC            (EXC_BASE_ADDRESS + 0x1c)
+#define EXC_RESET_VEC           (EXC_BASE_ADDRESS + 0x0)
+#define EXC_UNDEF_INSTR_VEC     (EXC_BASE_ADDRESS + 0x4)
+#define EXC_SWI_VEC             (EXC_BASE_ADDRESS + 0x8)
+#define EXC_PREFETCH_ABORT_VEC  (EXC_BASE_ADDRESS + 0xc)
+#define EXC_DATA_ABORT_VEC      (EXC_BASE_ADDRESS + 0x10)
+#define EXC_IRQ_VEC             (EXC_BASE_ADDRESS + 0x18)
+#define EXC_FIQ_VEC             (EXC_BASE_ADDRESS + 0x1c)
 
 /* Exception numbers */
@@ -68,12 +69,11 @@
 #define EXC_FIQ             6
 
-
 /** Kernel stack pointer.
  *
  * It is set when thread switches to user mode,
  * and then used for exception handling.
+ *
  */
 extern uintptr_t supervisor_sp;
-
 
 /** Temporary exception stack pointer.
@@ -81,7 +81,7 @@
  * Temporary stack is used in exceptions handling routines
  * before switching to thread's kernel stack.
+ *
  */
 extern uintptr_t exc_stack;
-
 
 /** Struct representing CPU state saved when an exception occurs. */
@@ -90,5 +90,5 @@
 	uint32_t sp;
 	uint32_t lr;
-
+	
 	uint32_t r0;
 	uint32_t r1;
@@ -104,42 +104,39 @@
 	uint32_t fp;
 	uint32_t r12;
-
+	
 	uint32_t pc;
 } istate_t;
 
-
-/** Sets Program Counter member of given istate structure.
+/** Set Program Counter member of given istate structure.
  *
- * @param istate istate structure
+ * @param istate  istate structure
  * @param retaddr new value of istate's PC member
+ *
  */
-static inline void istate_set_retaddr(istate_t *istate, uintptr_t retaddr)
+NO_TRACE static inline void istate_set_retaddr(istate_t *istate,
+    uintptr_t retaddr)
 {
- 	istate->pc = retaddr;
+	istate->pc = retaddr;
 }
 
-
-/** Returns true if exception happened while in userspace. */
-static inline int istate_from_uspace(istate_t *istate)
+/** Return true if exception happened while in userspace. */
+NO_TRACE static inline int istate_from_uspace(istate_t *istate)
 {
- 	return (istate->spsr & STATUS_REG_MODE_MASK) == USER_MODE;
+	return (istate->spsr & STATUS_REG_MODE_MASK) == USER_MODE;
 }
 
-
-/** Returns Program Counter member of given istate structure. */
-static inline unative_t istate_get_pc(istate_t *istate)
+/** Return Program Counter member of given istate structure. */
+NO_TRACE static inline unative_t istate_get_pc(istate_t *istate)
 {
- 	return istate->pc;
+	return istate->pc;
 }
 
-static inline unative_t istate_get_fp(istate_t *istate)
+NO_TRACE static inline unative_t istate_get_fp(istate_t *istate)
 {
 	return istate->fp;
 }
 
-
 extern void install_exception_handlers(void);
 extern void exception_init(void);
-extern void print_istate(istate_t *istate);
 extern void reset_exception_entry(void);
 extern void irq_exception_entry(void);
@@ -150,5 +147,4 @@
 extern void swi_exception_entry(void);
 
-
 #endif
 
Index: kernel/arch/arm32/include/faddr.h
===================================================================
--- kernel/arch/arm32/include/faddr.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/arm32/include/faddr.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -27,5 +27,5 @@
  */
 
-/** @addtogroup arm32	
+/** @addtogroup arm32
  * @{
  */
@@ -42,6 +42,7 @@
  *
  * @param fptr Function pointer.
+ *
  */
-#define FADDR(fptr)		((uintptr_t) (fptr))
+#define FADDR(fptr)  ((uintptr_t) (fptr))
 
 #endif
Index: kernel/arch/arm32/include/interrupt.h
===================================================================
--- kernel/arch/arm32/include/interrupt.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/arm32/include/interrupt.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -41,9 +41,8 @@
 
 /** Initial size of exception dispatch table. */
-#define IVT_ITEMS 	6
+#define IVT_ITEMS  6
 
 /** Index of the first item in exception dispatch table. */
-#define IVT_FIRST	0
-
+#define IVT_FIRST  0
 
 extern void interrupt_init(void);
@@ -52,5 +51,5 @@
 extern void interrupts_restore(ipl_t ipl);
 extern ipl_t interrupts_read(void);
-
+extern bool interrupts_disabled(void);
 
 #endif
Index: kernel/arch/arm32/include/mach/gta02/gta02.h
===================================================================
--- kernel/arch/arm32/include/mach/gta02/gta02.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
+++ kernel/arch/arm32/include/mach/gta02/gta02.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -0,0 +1,51 @@
+/*
+ * 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 arm32gta02 GTA02
+ *  @brief Openmoko GTA02 platform.
+ *  @ingroup arm32
+ * @{
+ */
+/** @file
+ *  @brief Openmoko GTA02 platform driver.
+ */
+
+#ifndef KERN_arm32_gta02_H_
+#define KERN_arm32_gta02_H_
+
+#include <arch/machine_func.h>
+
+extern struct arm_machine_ops gta02_machine_ops;
+
+/** Size of GTA02 IRQ number range (starting from 0) */
+#define GTA02_IRQ_COUNT 32
+
+#endif
+
+/** @}
+ */
Index: kernel/arch/arm32/include/mach/integratorcp/integratorcp.h
===================================================================
--- kernel/arch/arm32/include/mach/integratorcp/integratorcp.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/arm32/include/mach/integratorcp/integratorcp.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -36,6 +36,6 @@
  */
 
-#ifndef KERN_arm32_MACHINE_H_
-#define KERN_arm32_MACHINE_H_
+#ifndef KERN_arm32_icp_H_
+#define KERN_arm32_icp_H_
 
 #include <arch/machine_func.h>
@@ -102,7 +102,13 @@
 extern void icp_timer_irq_start(void);
 extern void icp_cpu_halt(void);
-extern void icp_irq_exception(int exc_no, istate_t *istate);
-extern uintptr_t icp_get_memory_size(void);
+extern void icp_irq_exception(unsigned int, istate_t *);
+extern void icp_get_memory_extents(uintptr_t *, uintptr_t *);
 extern void icp_frame_init(void);
+extern size_t icp_get_irq_count(void);
+
+extern struct arm_machine_ops icp_machine_ops;
+
+/** Size of IntegratorCP IRQ number range (starting from 0) */
+#define ICP_IRQ_COUNT 8
 
 #endif
Index: kernel/arch/arm32/include/mach/testarm/testarm.h
===================================================================
--- kernel/arch/arm32/include/mach/testarm/testarm.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/arm32/include/mach/testarm/testarm.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -37,15 +37,13 @@
  */
 
-#ifndef KERN_arm32_MACHINE_H_
-#define KERN_arm32_MACHINE_H_
+#ifndef KERN_arm32_testarm_H_
+#define KERN_arm32_testarm_H_
 
 #include <arch/machine_func.h>
 
-/** Last interrupt number (beginning from 0) whose status is probed
- * from interrupt controller
- */
-#define GXEMUL_IRQC_MAX_IRQ  8
-#define GXEMUL_KBD_IRQ       2
-#define GXEMUL_TIMER_IRQ     4
+/** Size of GXemul IRQ number range (starting from 0) */
+#define GXEMUL_IRQ_COUNT	32
+#define GXEMUL_KBD_IRQ		2
+#define GXEMUL_TIMER_IRQ	4
 
 /** Timer frequency */
@@ -72,8 +70,10 @@
 extern void gxemul_timer_irq_start(void);
 extern void gxemul_cpu_halt(void);
-extern void gxemul_irq_exception(int exc_no, istate_t *istate);
-extern uintptr_t gxemul_get_memory_size(void);
+extern void gxemul_irq_exception(unsigned int, istate_t *);
+extern void gxemul_get_memory_extents(uintptr_t *, uintptr_t *);
 extern void gxemul_frame_init(void);
+extern size_t gxemul_get_irq_count(void);
 
+extern struct arm_machine_ops gxemul_machine_ops;
 
 #endif
Index: kernel/arch/arm32/include/machine_func.h
===================================================================
--- kernel/arch/arm32/include/machine_func.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/arm32/include/machine_func.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -46,19 +46,21 @@
 #include <arch/exception.h>
 
-#define MACHINE_GENFUNC	machine_genfunc
-
 struct arm_machine_ops {
-	void		(*machine_init)(void);
-	void		(*machine_timer_irq_start)(void);
-	void		(*machine_cpu_halt)(void);
-	uintptr_t	(*machine_get_memory_size)(void);
-	void		(*machine_irq_exception)(int, istate_t*);
-	void		(*machine_frame_init)(void);
-	void		(*machine_output_init)(void);
-	void		(*machine_input_init)(void);
+	void (*machine_init)(void);
+	void (*machine_timer_irq_start)(void);
+	void (*machine_cpu_halt)(void);
+	void (*machine_get_memory_extents)(uintptr_t *, uintptr_t *);
+	void (*machine_irq_exception)(unsigned int, istate_t *);
+	void (*machine_frame_init)(void);
+	void (*machine_output_init)(void);
+	void (*machine_input_init)(void);
+	size_t (*machine_get_irq_count)(void);
 };
 
-extern struct arm_machine_ops machine_ops;
+/** Pointer to arm_machine_ops structure being used. */
+extern struct arm_machine_ops *machine_ops;
 
+/** Initialize machine_ops pointer. */
+extern void machine_ops_init(void);
 
 /** Maps HW devices to the kernel address space using #hw_map. */
@@ -73,11 +75,10 @@
 extern void machine_cpu_halt(void);
 
-
-/** Returns size of available memory.
+/** Get extents of available memory.
  *
- *  @return Size of available memory.
+ * @param start		Place to store memory start address.
+ * @param size		Place to store memory size.
  */
-extern uintptr_t machine_get_memory_size(void);
-
+extern void machine_get_memory_extents(uintptr_t *start, uintptr_t *size);
 
 /** Interrupt exception handler.
@@ -86,5 +87,5 @@
  * @param istate Saved processor state.
  */
-extern void machine_irq_exception(int exc_no, istate_t *istate);
+extern void machine_irq_exception(unsigned int exc_no, istate_t *istate);
 
 
@@ -104,5 +105,6 @@
 extern void machine_input_init(void);
 
-extern void machine_genfunc(void);
+extern size_t machine_get_irq_count(void);
+
 #endif
 
Index: kernel/arch/arm32/include/mm/frame.h
===================================================================
--- kernel/arch/arm32/include/mm/frame.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/arm32/include/mm/frame.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -46,8 +46,19 @@
 
 #define BOOT_PAGE_TABLE_SIZE     0x4000
-#define BOOT_PAGE_TABLE_ADDRESS  0x8000
+
+#ifdef MACHINE_gta02
+#define BOOT_PAGE_TABLE_ADDRESS  0x30010000
+#else
+#define BOOT_PAGE_TABLE_ADDRESS  0x00008000
+#endif
 
 #define BOOT_PAGE_TABLE_START_FRAME     (BOOT_PAGE_TABLE_ADDRESS >> FRAME_WIDTH)
 #define BOOT_PAGE_TABLE_SIZE_IN_FRAMES  (BOOT_PAGE_TABLE_SIZE >> FRAME_WIDTH)
+
+#ifdef MACHINE_gta02
+#define PHYSMEM_START_ADDR	0x30008000
+#else
+#define PHYSMEM_START_ADDR	0x00000000
+#endif
 
 extern uintptr_t last_frame;
Index: kernel/arch/arm32/include/mm/page.h
===================================================================
--- kernel/arch/arm32/include/mm/page.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/arm32/include/mm/page.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -27,5 +27,5 @@
  */
 
-/** @addtogroup arm32mm	
+/** @addtogroup arm32mm
  * @{
  */
@@ -40,4 +40,5 @@
 #include <mm/mm.h>
 #include <arch/exception.h>
+#include <trace.h>
 
 #define PAGE_WIDTH	FRAME_WIDTH
@@ -192,7 +193,8 @@
 /** Sets the address of level 0 page table.
  *
- * @param pt    Pointer to the page table to set.
- */   
-static inline void set_ptl0_addr(pte_t *pt)
+ * @param pt Pointer to the page table to set.
+ *
+ */
+NO_TRACE static inline void set_ptl0_addr(pte_t *pt)
 {
 	asm volatile (
@@ -205,12 +207,13 @@
 /** Returns level 0 page table entry flags.
  *
- *  @param pt     Level 0 page table.
- *  @param i      Index of the entry to return.
- */
-static inline int get_pt_level0_flags(pte_t *pt, size_t i)
+ * @param pt Level 0 page table.
+ * @param i  Index of the entry to return.
+ *
+ */
+NO_TRACE static inline int get_pt_level0_flags(pte_t *pt, size_t i)
 {
 	pte_level0_t *p = &pt[i].l0;
 	int np = (p->descriptor_type == PTE_DESCRIPTOR_NOT_PRESENT);
-
+	
 	return (np << PAGE_PRESENT_SHIFT) | (1 << PAGE_USER_SHIFT) |
 	    (1 << PAGE_READ_SHIFT) | (1 << PAGE_WRITE_SHIFT) |
@@ -220,14 +223,15 @@
 /** Returns level 1 page table entry flags.
  *
- *  @param pt     Level 1 page table.
- *  @param i      Index of the entry to return.
- */
-static inline int get_pt_level1_flags(pte_t *pt, size_t i)
+ * @param pt Level 1 page table.
+ * @param i  Index of the entry to return.
+ *
+ */
+NO_TRACE static inline int get_pt_level1_flags(pte_t *pt, size_t i)
 {
 	pte_level1_t *p = &pt[i].l1;
-
+	
 	int dt = p->descriptor_type;
 	int ap = p->access_permission_0;
-
+	
 	return ((dt == PTE_DESCRIPTOR_NOT_PRESENT) << PAGE_PRESENT_SHIFT) |
 	    ((ap == PTE_AP_USER_RO_KERNEL_RW) << PAGE_READ_SHIFT) |
@@ -241,15 +245,15 @@
 }
 
-
 /** Sets flags of level 0 page table entry.
  *
- *  @param pt     level 0 page table
- *  @param i      index of the entry to be changed
- *  @param flags  new flags
- */
-static inline void set_pt_level0_flags(pte_t *pt, size_t i, int flags)
+ * @param pt    level 0 page table
+ * @param i     index of the entry to be changed
+ * @param flags new flags
+ *
+ */
+NO_TRACE static inline void set_pt_level0_flags(pte_t *pt, size_t i, int flags)
 {
 	pte_level0_t *p = &pt[i].l0;
-
+	
 	if (flags & PAGE_NOT_PRESENT) {
 		p->descriptor_type = PTE_DESCRIPTOR_NOT_PRESENT;
@@ -262,5 +266,5 @@
 		p->descriptor_type = PTE_DESCRIPTOR_COARSE_TABLE;
 		p->should_be_zero = 0;
-    }
+	}
 }
 
@@ -268,13 +272,14 @@
 /** Sets flags of level 1 page table entry.
  *
- *  We use same access rights for the whole page. When page is not preset we
- *  store 1 in acess_rigts_3 so that at least one bit is 1 (to mark correct
- *  page entry, see #PAGE_VALID_ARCH).
- *
- *  @param pt     Level 1 page table.
- *  @param i      Index of the entry to be changed.
- *  @param flags  New flags.
- */  
-static inline void set_pt_level1_flags(pte_t *pt, size_t i, int flags)
+ * We use same access rights for the whole page. When page
+ * is not preset we store 1 in acess_rigts_3 so that at least
+ * one bit is 1 (to mark correct page entry, see #PAGE_VALID_ARCH).
+ *
+ * @param pt    Level 1 page table.
+ * @param i     Index of the entry to be changed.
+ * @param flags New flags.
+ *
+ */
+NO_TRACE static inline void set_pt_level1_flags(pte_t *pt, size_t i, int flags)
 {
 	pte_level1_t *p = &pt[i].l1;
@@ -287,12 +292,12 @@
 		p->access_permission_3 = p->access_permission_0;
 	}
-  
+	
 	p->cacheable = p->bufferable = (flags & PAGE_CACHEABLE) != 0;
-
+	
 	/* default access permission */
 	p->access_permission_0 = p->access_permission_1 = 
 	    p->access_permission_2 = p->access_permission_3 =
 	    PTE_AP_USER_NO_KERNEL_RW;
-
+	
 	if (flags & PAGE_USER)  {
 		if (flags & PAGE_READ) {
Index: kernel/arch/arm32/include/mm/page_fault.h
===================================================================
--- kernel/arch/arm32/include/mm/page_fault.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/arm32/include/mm/page_fault.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -81,6 +81,6 @@
 } instruction_union_t;
 
-extern void prefetch_abort(int n, istate_t *istate);
-extern void data_abort(int n, istate_t *istate);
+extern void prefetch_abort(unsigned int, istate_t *);
+extern void data_abort(unsigned int, istate_t *);
 
 #endif
Index: kernel/arch/arm32/include/mm/tlb.h
===================================================================
--- kernel/arch/arm32/include/mm/tlb.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/arm32/include/mm/tlb.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -27,5 +27,5 @@
  */
 
-/** @addtogroup arm32mm	
+/** @addtogroup arm32mm
  * @{
  */
Index: kernel/arch/arm32/include/ras.h
===================================================================
--- kernel/arch/arm32/include/ras.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/arm32/include/ras.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2009 Jakub Jermar 
+ * Copyright (c) 2009 Jakub Jermar
  * All rights reserved.
  *
@@ -40,11 +40,11 @@
 #include <typedefs.h>
 
-#define RAS_START	0
-#define RAS_END		1
+#define RAS_START  0
+#define RAS_END    1
 
 extern uintptr_t *ras_page;
 
 extern void ras_init(void);
-extern void ras_check(int, istate_t *);
+extern void ras_check(unsigned int, istate_t *);
 
 #endif
Index: kernel/arch/arm32/src/arm32.c
===================================================================
--- kernel/arch/arm32/src/arm32.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/arm32/src/arm32.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -45,17 +45,9 @@
 #include <interrupt.h>
 #include <arch/regutils.h>
+#include <arch/machine_func.h>
 #include <userspace.h>
 #include <macros.h>
 #include <str.h>
 #include <arch/ras.h>
-
-#ifdef MACHINE_testarm
-	#include <arch/mach/testarm/testarm.h>
-#endif
-
-#ifdef MACHINE_integratorcp
-	#include <arch/mach/integratorcp/integratorcp.h>
-#endif
-
 
 /** Performs arm32-specific initialization before main_bsp() is called. */
@@ -71,4 +63,7 @@
 		    bootinfo->tasks[i].name);
 	}
+
+	/* Initialize machine_ops pointer. */
+	machine_ops_init();
 }
 
Index: kernel/arch/arm32/src/asm.S
===================================================================
--- kernel/arch/arm32/src/asm.S	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/arm32/src/asm.S	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -1,31 +1,30 @@
-#
-# Copyright (c) 2007 Michal Kebrt
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions
-# are met:
-#
-# - Redistributions of source code must retain the above copyright
-#   notice, this list of conditions and the following disclaimer.
-# - Redistributions in binary form must reproduce the above copyright
-#   notice, this list of conditions and the following disclaimer in the
-#   documentation and/or other materials provided with the distribution.
-# - The name of the author may not be used to endorse or promote products
-#   derived from this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
-# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
-# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
-# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
-# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
-# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-#
+/*
+ * Copyright (c) 2007 Michal Kebrt
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
 
-	
 .text
 
@@ -37,4 +36,5 @@
 .global memcpy_from_uspace_failover_address
 .global memcpy_to_uspace_failover_address
+.global early_putchar
 
 memsetb:
@@ -47,57 +47,67 @@
 memcpy_from_uspace:
 memcpy_to_uspace:
-	add     r3, r1, #3
-	bic     r3, r3, #3
-	cmp     r1, r3
-	stmdb   sp!, {r4, r5, lr}
-	mov	r5, r0			/* save dst */
-	beq     4f
-1:
-	cmp     r2, #0
-	movne   ip, #0
-	beq     3f
-2:
-	ldrb    r3, [ip, r1]
-	strb    r3, [ip, r0]
-	add     ip, ip, #1
-	cmp     ip, r2
-	bne     2b
-3:
-	mov     r0, r5
-	ldmia   sp!, {r4, r5, pc}
-4:
-	add     r3, r0, #3
-	bic     r3, r3, #3
-	cmp     r0, r3
-	bne     1b
-	movs    r4, r2, lsr #2
-	moveq   lr, r4
-	beq     6f
-	mov     lr, #0
-	mov     ip, lr
-5:
-	ldr     r3, [ip, r1]
-	add     lr, lr, #1
-	cmp     lr, r4
-	str     r3, [ip, r0]
-	add     ip, ip, #4
-	bne     5b
-6:
-	ands    r4, r2, #3
-	beq     3b
-	mov     r3, lr, lsl #2
-	add     r0, r3, r0
-	add     ip, r3, r1
-	mov     r2, #0
-7:
-	ldrb    r3, [r2, ip]
-	strb    r3, [r2, r0]
-	add     r2, r2, #1
-	cmp     r2, r4
-	bne     7b
-	b       3b
+	add r3, r1, #3
+	bic r3, r3, #3
+	cmp r1, r3
+	stmdb sp!, {r4, r5, lr}
+	mov r5, r0 /* save dst */
+	beq 4f
+	
+	1:
+		cmp r2, #0
+		movne ip, #0
+		beq 3f
+	
+	2:
+		ldrb r3, [ip, r1]
+		strb r3, [ip, r0]
+		add ip, ip, #1
+		cmp ip, r2
+		bne 2b
+	
+	3:
+		mov r0, r5
+		ldmia sp!, {r4, r5, pc}
+	
+	4:
+		add r3, r0, #3
+		bic r3, r3, #3
+		cmp r0, r3
+		bne 1b
+		movs r4, r2, lsr #2
+		moveq lr, r4
+		beq 6f
+		mov lr, #0
+		mov ip, lr
+	
+	5:
+		ldr r3, [ip, r1]
+		add lr, lr, #1
+		cmp lr, r4
+		str r3, [ip, r0]
+		add ip, ip, #4
+		bne 5b
+	
+	6:
+		ands r4, r2, #3
+		beq 3b
+		mov r3, lr, lsl #2
+		add r0, r3, r0
+		add ip, r3, r1
+		mov r2, #0
+	
+	7:
+		ldrb r3, [r2, ip]
+		strb r3, [r2, r0]
+		add r2, r2, #1
+		cmp r2, r4
+		bne 7b
+		b 3b
 
 memcpy_from_uspace_failover_address:
 memcpy_to_uspace_failover_address:
-	mov	r0, #0
-	ldmia   sp!, {r4, r5, pc}
+	mov r0, #0
+	ldmia sp!, {r4, r5, pc}
+
+early_putchar:
+	mov pc, lr
Index: kernel/arch/arm32/src/debug/stacktrace.c
===================================================================
--- kernel/arch/arm32/src/debug/stacktrace.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/arm32/src/debug/stacktrace.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -40,12 +40,12 @@
 #define FRAME_OFFSET_RA		-1
 
-bool kernel_frame_pointer_validate(uintptr_t fp)
+bool kernel_stack_trace_context_validate(stack_trace_context_t *ctx)
 {
-	return fp != 0;
+	return ctx->fp != 0;
 }
 
-bool kernel_frame_pointer_prev(uintptr_t fp, uintptr_t *prev)
+bool kernel_frame_pointer_prev(stack_trace_context_t *ctx, uintptr_t *prev)
 {
-	uint32_t *stack = (void *) fp;
+	uint32_t *stack = (void *) ctx->fp;
 
 	*prev = stack[FRAME_OFFSET_FP_PREV];
@@ -53,7 +53,7 @@
 }
 
-bool kernel_return_address_get(uintptr_t fp, uintptr_t *ra)
+bool kernel_return_address_get(stack_trace_context_t *ctx, uintptr_t *ra)
 {
-	uint32_t *stack = (void *) fp;
+	uint32_t *stack = (void *) ctx->fp;
 
 	*ra = stack[FRAME_OFFSET_RA];
@@ -61,19 +61,19 @@
 }
 
-bool uspace_frame_pointer_validate(uintptr_t fp)
+bool uspace_stack_trace_context_validate(stack_trace_context_t *ctx)
 {
-	return fp != 0;
+	return ctx->fp != 0;
 }
 
-bool uspace_frame_pointer_prev(uintptr_t fp, uintptr_t *prev)
+bool uspace_frame_pointer_prev(stack_trace_context_t *ctx, uintptr_t *prev)
 {
 	return !copy_from_uspace((void *) prev,
-	    (uint32_t *) fp + FRAME_OFFSET_FP_PREV, sizeof(*prev));
+	    (uint32_t *) ctx->fp + FRAME_OFFSET_FP_PREV, sizeof(*prev));
 }
 
-bool uspace_return_address_get(uintptr_t fp, uintptr_t *ra)
+bool uspace_return_address_get(stack_trace_context_t *ctx, uintptr_t *ra)
 {
-	return !copy_from_uspace((void *) ra, (uint32_t *) fp + FRAME_OFFSET_RA,
-	    sizeof(*ra));
+	return !copy_from_uspace((void *) ra,
+	    (uint32_t *) ctx->fp + FRAME_OFFSET_RA, sizeof(*ra));
 }
 
Index: kernel/arch/arm32/src/exc_handler.S
===================================================================
--- kernel/arch/arm32/src/exc_handler.S	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/arm32/src/exc_handler.S	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -96,6 +96,13 @@
 	ldmfd r3!, {r4-r7}
 	stmfd r13!, {r4-r7}
-	stmfd r13!, {r13, lr}^
+	mov r4, r13
+	stmfd r4, {r13, lr}^
+	nop			/* Cannot access r13 immediately after stm(2) */
+	sub r13, r13, #8
 	stmfd r13!, {r2}
+
+	# Stop stack traces here
+	mov fp, #0
+	
 	b 2f
 
@@ -123,6 +130,4 @@
 	stmfd r13!, {r2}
 2:
-	# Stop stack traces here
-	mov fp, #0
 .endm
 
@@ -135,5 +140,8 @@
 
 	# return to user mode
-	ldmfd r13!, {r13, lr}^
+	mov r0, r13
+	ldmfd r0, {r13, lr}^
+	nop			/* Cannot access r13 immediately after ldm(2) */
+	add r13, r13, #8
 	b 2f
 
@@ -150,5 +158,5 @@
 	mov r0, #0
 	mov r1, r13
-	bl ras_check 
+	bl ras_check
 	LOAD_REGS_FROM_STACK
 
@@ -158,5 +166,5 @@
 	mov r0, #5
 	mov r1, r13
-	bl ras_check 
+	bl ras_check
 	LOAD_REGS_FROM_STACK
 
@@ -166,5 +174,5 @@
 	mov r0, #6
 	mov r1, r13
-	bl ras_check 
+	bl ras_check
 	LOAD_REGS_FROM_STACK
 
@@ -173,5 +181,5 @@
 	mov r0, #1
 	mov r1, r13
-	bl ras_check 
+	bl ras_check
 	LOAD_REGS_FROM_STACK
 
@@ -181,5 +189,5 @@
 	mov r0, #3
 	mov r1, r13
-	bl ras_check 
+	bl ras_check
 	LOAD_REGS_FROM_STACK
 
@@ -189,5 +197,5 @@
 	mov r0, #4
 	mov r1, r13
-	bl ras_check 
+	bl ras_check
 	LOAD_REGS_FROM_STACK
 
Index: kernel/arch/arm32/src/exception.c
===================================================================
--- kernel/arch/arm32/src/exception.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/arm32/src/exception.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -37,4 +37,5 @@
 #include <arch/memstr.h>
 #include <arch/regutils.h>
+#include <arch/machine_func.h>
 #include <interrupt.h>
 #include <arch/mm/page_fault.h>
@@ -43,12 +44,4 @@
 #include <syscall/syscall.h>
 #include <stacktrace.h>
-
-#ifdef MACHINE_testarm
-	#include <arch/mach/testarm/testarm.h>
-#endif
-
-#ifdef MACHINE_integratorcp
-	#include <arch/mach/integratorcp/integratorcp.h>
-#endif
 
 /** Offset used in calculation of exception handler's relative address.
@@ -91,6 +84,7 @@
  *
  * Dispatches the syscall.
+ *
  */
-static void swi_exception(int exc_no, istate_t *istate)
+static void swi_exception(unsigned int exc_no, istate_t *istate)
 {
 	istate->r0 = syscall_handler(istate->r0, istate->r1, istate->r2,
@@ -148,5 +142,5 @@
  * Determines the sources of interrupt and calls their handlers.
  */
-static void irq_exception(int exc_no, istate_t *istate)
+static void irq_exception(unsigned int exc_no, istate_t *istate)
 {
 	machine_irq_exception(exc_no, istate);
@@ -165,9 +159,12 @@
 	install_exception_handlers();
 	
-	exc_register(EXC_IRQ, "interrupt", (iroutine) irq_exception);
-	exc_register(EXC_PREFETCH_ABORT, "prefetch abort",
-	    (iroutine) prefetch_abort);
-	exc_register(EXC_DATA_ABORT, "data abort", (iroutine) data_abort);
-	exc_register(EXC_SWI, "software interrupt", (iroutine) swi_exception);
+	exc_register(EXC_IRQ, "interrupt", true,
+	    (iroutine_t) irq_exception);
+	exc_register(EXC_PREFETCH_ABORT, "prefetch abort", true,
+	    (iroutine_t) prefetch_abort);
+	exc_register(EXC_DATA_ABORT, "data abort", true,
+	    (iroutine_t) data_abort);
+	exc_register(EXC_SWI, "software interrupt", true,
+	    (iroutine_t) swi_exception);
 }
 
@@ -176,20 +173,14 @@
  * @param istate Structure to be printed.
  */
-void print_istate(istate_t *istate)
+void istate_decode(istate_t *istate)
 {
-	printf("istate dump:\n");
-	
-	printf(" r0: %x    r1: %x    r2: %x    r3: %x\n",
+	printf("r0 =%#0.8lx\tr1 =%#0.8lx\tr2 =%#0.8lx\tr3 =%#0.8lx\n",
 	    istate->r0, istate->r1, istate->r2, istate->r3);
-	printf(" r4: %x    r5: %x    r6: %x    r7: %x\n", 
+	printf("r4 =%#0.8lx\tr5 =%#0.8lx\tr6 =%#0.8lx\tr7 =%#0.8lx\n",
 	    istate->r4, istate->r5, istate->r6, istate->r7);
-	printf(" r8: %x    r8: %x   r10: %x    fp: %x\n", 
+	printf("r8 =%#0.8lx\tr9 =%#0.8lx\tr10=%#0.8lx\tfp =%#0.8lx\n",
 	    istate->r8, istate->r9, istate->r10, istate->fp);
-	printf(" r12: %x    sp: %x    lr: %x  spsr: %x\n",
+	printf("r12=%#0.8lx\tsp =%#0.8lx\tlr =%#0.8lx\tspsr=%#0.8lx\n",
 	    istate->r12, istate->sp, istate->lr, istate->spsr);
-	
-	printf(" pc: %x\n", istate->pc);
-
-	stack_trace_istate(istate);
 }
 
Index: kernel/arch/arm32/src/interrupt.c
===================================================================
--- kernel/arch/arm32/src/interrupt.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/arm32/src/interrupt.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -36,18 +36,8 @@
 #include <arch/asm.h>
 #include <arch/regutils.h>
+#include <arch/machine_func.h>
 #include <ddi/irq.h>
 #include <ddi/device.h>
 #include <interrupt.h>
-
-#ifdef MACHINE_testarm
-	#include <arch/mach/testarm/testarm.h>
-#endif
-
-#ifdef MACHINE_integratorcp
-	#include <arch/mach/integratorcp/integratorcp.h>
-#endif
-
-/** Initial size of a table holding interrupt handlers. */
-#define IRQ_COUNT 8
 
 /** Disable interrupts.
@@ -97,4 +87,14 @@
 }
 
+/** Check interrupts state.
+ *
+ * @return True if interrupts are disabled.
+ *
+ */
+bool interrupts_disabled(void)
+{
+	return current_status_reg_read() & STATUS_REG_IRQ_DISABLED_BIT;
+}
+
 /** Initialize basic tables for exception dispatching
  * and starts the timer.
@@ -102,5 +102,9 @@
 void interrupt_init(void)
 {
-	irq_init(IRQ_COUNT, IRQ_COUNT);
+	size_t irq_count;
+
+	irq_count = machine_get_irq_count();
+	irq_init(irq_count, irq_count);
+
 	machine_timer_irq_start();
 }
Index: kernel/arch/arm32/src/mach/gta02/gta02.c
===================================================================
--- kernel/arch/arm32/src/mach/gta02/gta02.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
+++ kernel/arch/arm32/src/mach/gta02/gta02.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -0,0 +1,308 @@
+/*
+ * 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 arm32gxemul
+ * @{
+ */
+/** @file
+ *  @brief Openmoko GTA02 (Neo FreeRunner) platform driver.
+ */
+
+#include <arch/exception.h>
+#include <arch/mach/gta02/gta02.h>
+#include <arch/mm/page.h>
+#include <mm/page.h>
+#include <genarch/fb/fb.h>
+#include <genarch/fb/visuals.h>
+#include <genarch/drivers/s3c24xx_uart/s3c24xx_uart.h>
+#include <genarch/drivers/s3c24xx_irqc/s3c24xx_irqc.h>
+#include <genarch/drivers/s3c24xx_timer/s3c24xx_timer.h>
+#include <genarch/srln/srln.h>
+#include <sysinfo/sysinfo.h>
+#include <interrupt.h>
+#include <ddi/ddi.h>
+#include <ddi/device.h>
+
+#define GTA02_MEMORY_START	0x30000000	/* physical */
+#define GTA02_MEMORY_SIZE	0x08000000	/* 128 MB */
+#define GTA02_MEMORY_SKIP	0x8000
+
+/** GTA02 serial console UART address (UART S3C24XX CPU UART channel 2). */
+#define GTA02_SCONS_BASE	0x50008000
+
+/** GTA02 framebuffer base address */
+#define GTA02_FB_BASE		0x08800000
+
+/** IRQ number used for clock */
+#define GTA02_TIMER_IRQ		S3C24XX_INT_TIMER0
+
+static void gta02_init(void);
+static void gta02_timer_irq_start(void);
+static void gta02_cpu_halt(void);
+static void gta02_get_memory_extents(uintptr_t *start, uintptr_t *size);
+static void gta02_irq_exception(unsigned int exc_no, istate_t *istate);
+static void gta02_frame_init(void);
+static void gta02_output_init(void);
+static void gta02_input_init(void);
+static size_t gta02_get_irq_count(void);
+
+static void gta02_timer_irq_init(void);
+static void gta02_timer_start(void);
+static irq_ownership_t gta02_timer_irq_claim(irq_t *irq);
+static void gta02_timer_irq_handler(irq_t *irq);
+
+static outdev_t *gta02_scons_dev;
+static s3c24xx_irqc_t gta02_irqc;
+static s3c24xx_timer_t *gta02_timer;
+
+static irq_t gta02_timer_irq;
+
+struct arm_machine_ops gta02_machine_ops = {
+	gta02_init,
+	gta02_timer_irq_start,
+	gta02_cpu_halt,
+	gta02_get_memory_extents,
+	gta02_irq_exception,
+	gta02_frame_init,
+	gta02_output_init,
+	gta02_input_init,
+	gta02_get_irq_count
+};
+
+static void gta02_init(void)
+{
+	s3c24xx_irqc_regs_t *irqc_regs;
+
+	gta02_timer = (void *) hw_map(S3C24XX_TIMER_ADDRESS, PAGE_SIZE);
+	irqc_regs = (void *) hw_map(S3C24XX_IRQC_ADDRESS, PAGE_SIZE);
+
+	/* Initialize interrupt controller. */
+	s3c24xx_irqc_init(&gta02_irqc, irqc_regs);
+}
+
+static void gta02_timer_irq_start(void)
+{
+	gta02_timer_irq_init();
+	gta02_timer_start();
+}
+
+static void gta02_cpu_halt(void)
+{
+}
+
+/** Get extents of available memory.
+ *
+ * @param start		Place to store memory start address (physical).
+ * @param size		Place to store memory size.
+ */
+static void gta02_get_memory_extents(uintptr_t *start, uintptr_t *size)
+{
+	*start = GTA02_MEMORY_START + GTA02_MEMORY_SKIP;
+	*size  = GTA02_MEMORY_SIZE - GTA02_MEMORY_SKIP;
+}
+
+static void gta02_irq_exception(unsigned int exc_no, istate_t *istate)
+{
+	uint32_t inum;
+
+	/* Determine IRQ number. */
+	inum = s3c24xx_irqc_inum_get(&gta02_irqc);
+
+	/* Clear interrupt condition in the interrupt controller. */
+	s3c24xx_irqc_clear(&gta02_irqc, inum);
+
+	irq_t *irq = irq_dispatch_and_lock(inum);
+	if (irq) {
+		/* The IRQ handler was found. */
+		irq->handler(irq);
+		spinlock_unlock(&irq->lock);
+	} else {
+		/* Spurious interrupt.*/
+		printf("cpu%d: spurious interrupt (inum=%d)\n",
+		    CPU->id, inum);
+	}
+}
+
+static void gta02_frame_init(void)
+{
+}
+
+static void gta02_output_init(void)
+{
+#ifdef CONFIG_FB
+	parea_t fb_parea;
+
+	fb_properties_t prop = {
+		.addr = GTA02_FB_BASE,
+		.offset = 0,
+		.x = 480,
+		.y = 640,
+		.scan = 960,
+		.visual = VISUAL_RGB_5_6_5_LE
+	};
+
+	outdev_t *fb_dev = fb_init(&prop);
+	if (fb_dev) {
+		stdout_wire(fb_dev);
+		fb_parea.pbase = GTA02_FB_BASE;
+		fb_parea.frames = 150;
+		ddi_parea_register(&fb_parea);
+	}
+#endif
+
+	/* Initialize serial port of the debugging console. */
+	s3c24xx_uart_io_t *scons_io;
+
+	scons_io = (void *) hw_map(GTA02_SCONS_BASE, PAGE_SIZE);
+	gta02_scons_dev = s3c24xx_uart_init(scons_io, S3C24XX_INT_UART2);
+
+	if (gta02_scons_dev) {
+		/* Create output device. */
+		stdout_wire(gta02_scons_dev);
+	}
+
+	/*
+	 * This is the necessary evil until the userspace driver is entirely
+	 * self-sufficient.
+	 */
+	sysinfo_set_item_val("s3c24xx_uart", NULL, true);
+	sysinfo_set_item_val("s3c24xx_uart.inr", NULL, S3C24XX_INT_UART2);
+	sysinfo_set_item_val("s3c24xx_uart.address.physical", NULL,
+	    (uintptr_t) GTA02_SCONS_BASE);
+
+}
+
+static void gta02_input_init(void)
+{
+	s3c24xx_uart_t *scons_inst;
+
+	if (gta02_scons_dev) {
+		/* Create input device. */
+		scons_inst = (void *) gta02_scons_dev->data;
+
+		srln_instance_t *srln_instance = srln_init();
+		if (srln_instance) {
+			indev_t *sink = stdin_wire();
+			indev_t *srln = srln_wire(srln_instance, sink);
+			s3c24xx_uart_input_wire(scons_inst, srln);
+
+			/* Enable interrupts from UART2 */
+			s3c24xx_irqc_src_enable(&gta02_irqc,
+			    S3C24XX_INT_UART2);
+
+			/* Enable interrupts from UART2 RXD */
+			s3c24xx_irqc_subsrc_enable(&gta02_irqc,
+			    S3C24XX_SUBINT_RXD2);
+		}
+	}
+
+	/* Enable interrupts from ADC */
+	s3c24xx_irqc_src_enable(&gta02_irqc, S3C24XX_INT_ADC);
+
+	/* Enable interrupts from ADC sub-sources */
+	s3c24xx_irqc_subsrc_enable(&gta02_irqc, S3C24XX_SUBINT_ADC_S);
+	s3c24xx_irqc_subsrc_enable(&gta02_irqc, S3C24XX_SUBINT_TC);
+}
+
+size_t gta02_get_irq_count(void)
+{
+	return GTA02_IRQ_COUNT;
+}
+
+static void gta02_timer_irq_init(void)
+{
+	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;
+	gta02_timer_irq.handler = gta02_timer_irq_handler;
+
+	irq_register(&gta02_timer_irq);
+}
+
+static irq_ownership_t gta02_timer_irq_claim(irq_t *irq)
+{
+	return IRQ_ACCEPT;
+}
+
+static void gta02_timer_irq_handler(irq_t *irq)
+{
+	/*
+	 * We are holding a lock which prevents preemption.
+	 * Release the lock, call clock() and reacquire the lock again.
+	 */
+	spinlock_unlock(&irq->lock);
+	clock();
+	spinlock_lock(&irq->lock);
+}
+
+static void gta02_timer_start(void)
+{
+	s3c24xx_timer_t *timer = gta02_timer;
+
+	/*
+	 * See S3C2442B user manual chapter 10 (PWM Timer) for description
+	 * of timer operation. Starting a timer is described in the
+	 * section 'Timer initialization using manual update bit and
+	 * inverter bit'.
+	 */
+
+	/*
+	 * GTA02 PCLK should be 100 MHz.
+	 * Timer input freq. = PCLK / divider / (1+prescaler)
+	 * 100 MHz / 2 / (1+7) / 62500 ~= 100 Hz
+	 */
+#if HZ != 100
+#warning Other HZ than 100 not suppored.
+#endif
+
+	/* Set prescaler values. No pre-divison, no dead zone. */
+	pio_write_32(&timer->tcfg0, 7); /* prescale 1/8 */
+
+	/* No DMA request, divider value = 2 for all timers. */
+	pio_write_32(&timer->tcfg1, 0);
+
+	/* Stop all timers. */
+	pio_write_32(&timer->tcon, 0);
+
+	/* Start counting from 64k-1. Compare value is irrelevant. */
+	pio_write_32(&timer->timer[0].cntb, 62500);
+	pio_write_32(&timer->timer[0].cmpb, 0);
+
+	/* Enable interrupts from timer0 */
+	s3c24xx_irqc_src_enable(&gta02_irqc, S3C24XX_INT_TIMER0);
+
+	/* Load data from tcntb0/tcmpb0 into tcnt0/tcmp0. */
+	pio_write_32(&timer->tcon, TCON_T0_AUTO_RLD | TCON_T0_MUPDATE);
+
+	/* Start timer 0. Inverter is off. */
+	pio_write_32(&timer->tcon, TCON_T0_AUTO_RLD | TCON_T0_START);
+}
+
+/** @}
+ */
Index: kernel/arch/arm32/src/mach/integratorcp/integratorcp.c
===================================================================
--- kernel/arch/arm32/src/mach/integratorcp/integratorcp.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/arm32/src/mach/integratorcp/integratorcp.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -56,13 +56,14 @@
 static icp_hw_map_t icp_hw_map;
 static irq_t icp_timer_irq;
-struct arm_machine_ops machine_ops = {
+struct arm_machine_ops icp_machine_ops = {
 	icp_init,
 	icp_timer_irq_start,
 	icp_cpu_halt,
-	icp_get_memory_size,
+	icp_get_memory_extents,
 	icp_irq_exception,
 	icp_frame_init,
 	icp_output_init,
-	icp_input_init
+	icp_input_init,
+	icp_get_irq_count
 };
 
@@ -214,16 +215,19 @@
 }
 
-/** Returns the size of emulated memory.
- *
- * @return Size in bytes.
- */
-size_t icp_get_memory_size(void) 
-{
+/** Get extents of available memory.
+ *
+ * @param start		Place to store memory start address.
+ * @param size		Place to store memory size.
+ */
+void icp_get_memory_extents(uintptr_t *start, uintptr_t *size)
+{
+	*start = 0;
+
 	if (hw_map_init_called) {
-		return (sdram[((*(uint32_t *)icp_hw_map.sdramcr & ICP_SDRAM_MASK) >> 2)]);
+		*size = (sdram[((*(uint32_t *)icp_hw_map.sdramcr &
+		    ICP_SDRAM_MASK) >> 2)]);
 	} else {
-		return SDRAM_SIZE;
-	}
-	
+		*size = SDRAM_SIZE;
+	}
 }
 
@@ -242,8 +246,8 @@
  * @param istate Saved processor state.
  */
-void icp_irq_exception(int exc_no, istate_t *istate)
+void icp_irq_exception(unsigned int exc_no, istate_t *istate)
 {
 	uint32_t sources = icp_irqc_get_sources();
-	int i;
+	unsigned int i;
 	
 	for (i = 0; i < ICP_IRQC_MAX_IRQ; i++) {
@@ -333,4 +337,8 @@
 }
 
+size_t icp_get_irq_count(void)
+{
+	return ICP_IRQ_COUNT;
+}
 
 /** @}
Index: kernel/arch/arm32/src/mach/testarm/testarm.c
===================================================================
--- kernel/arch/arm32/src/mach/testarm/testarm.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/arm32/src/mach/testarm/testarm.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -56,13 +56,14 @@
 static irq_t gxemul_timer_irq;
 
-struct arm_machine_ops machine_ops = {
+struct arm_machine_ops gxemul_machine_ops = {
 	gxemul_init,
 	gxemul_timer_irq_start,
 	gxemul_cpu_halt,
-	gxemul_get_memory_size,
+	gxemul_get_memory_extents,
 	gxemul_irq_exception,
 	gxemul_frame_init,
 	gxemul_output_init,
-	gxemul_input_init
+	gxemul_input_init,
+	gxemul_get_irq_count
 };
 
@@ -126,4 +127,9 @@
 }
 
+size_t gxemul_get_irq_count(void)
+{
+	return GXEMUL_IRQ_COUNT;
+}
+
 /** Starts gxemul Real Time Clock device, which asserts regular interrupts.
  *
@@ -185,13 +191,14 @@
 }
 
-/** Returns the size of emulated memory.
- *
- * @return Size in bytes.
- */
-uintptr_t gxemul_get_memory_size(void)
-{
-        return  *((uintptr_t *) (GXEMUL_MP_ADDRESS + GXEMUL_MP_MEMSIZE_OFFSET));
-}
-
+/** Get extents of available memory.
+ *
+ * @param start		Place to store memory start address.
+ * @param size		Place to store memory size.
+ */
+void gxemul_get_memory_extents(uintptr_t *start, uintptr_t *size)
+{
+	*start = 0;
+        *size = *((uintptr_t *) (GXEMUL_MP_ADDRESS + GXEMUL_MP_MEMSIZE_OFFSET));
+}
 
 /** Returns the mask of active interrupts. */
@@ -205,10 +212,10 @@
  * Determines the sources of interrupt and calls their handlers.
  */
-void gxemul_irq_exception(int exc_no, istate_t *istate)
+void gxemul_irq_exception(unsigned int exc_no, istate_t *istate)
 {
 	uint32_t sources = gxemul_irqc_get_sources();
 	unsigned int i;
 
-	for (i = 0; i < GXEMUL_IRQC_MAX_IRQ; i++) {
+	for (i = 0; i < GXEMUL_IRQ_COUNT; i++) {
 		if (sources & (1 << i)) {
 			irq_t *irq = irq_dispatch_and_lock(i);
Index: kernel/arch/arm32/src/machine_func.c
===================================================================
--- kernel/arch/arm32/src/machine_func.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/arm32/src/machine_func.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -39,10 +39,29 @@
 
 #include <arch/machine_func.h>
+#include <arch/mach/gta02/gta02.h>
+#include <arch/mach/integratorcp/integratorcp.h>
+#include <arch/mach/testarm/testarm.h>
 
+/** Pointer to machine_ops structure being used. */
+struct arm_machine_ops *machine_ops;
+
+/** Initialize machine_ops pointer. */
+void machine_ops_init(void)
+{
+#if defined(MACHINE_gta02)
+	machine_ops = &gta02_machine_ops;
+#elif defined(MACHINE_testarm)
+	machine_ops = &gxemul_machine_ops;
+#elif defined(MACHINE_integratorcp)
+	machine_ops = &icp_machine_ops;
+#else
+#error Machine type not defined.
+#endif
+}
 
 /** Maps HW devices to the kernel address space using #hw_map. */
 void machine_init(void)
 {
-	(machine_ops.machine_init)();
+	(machine_ops->machine_init)();
 }
 
@@ -51,5 +70,5 @@
 void machine_timer_irq_start(void)
 {
-	(machine_ops.machine_timer_irq_start)();
+	(machine_ops->machine_timer_irq_start)();
 }
 
@@ -58,15 +77,15 @@
 void machine_cpu_halt(void)
 {
-	(machine_ops.machine_cpu_halt)();
+	(machine_ops->machine_cpu_halt)();
 }
 
-
-/** Returns size of available memory.
+/** Get extents of available memory.
  *
- *  @return Size of available memory.
+ * @param start		Place to store memory start address.
+ * @param size		Place to store memory size.
  */
-uintptr_t machine_get_memory_size(void)
+void machine_get_memory_extents(uintptr_t *start, uintptr_t *size)
 {
-	return (machine_ops.machine_get_memory_size)();
+	(machine_ops->machine_get_memory_extents)(start, size);
 }
 
@@ -76,7 +95,7 @@
  * @param istate Saved processor state.
  */
-void machine_irq_exception(int exc_no, istate_t *istate)
+void machine_irq_exception(unsigned int exc_no, istate_t *istate)
 {
-	(machine_ops.machine_irq_exception)(exc_no, istate);
+	(machine_ops->machine_irq_exception)(exc_no, istate);
 }
 
@@ -87,5 +106,5 @@
 void machine_frame_init(void)
 {
-	(machine_ops.machine_frame_init)();
+	(machine_ops->machine_frame_init)();
 }
 
@@ -95,5 +114,5 @@
 void machine_output_init(void)
 {
-	(machine_ops.machine_output_init)();
+	(machine_ops->machine_output_init)();
 }
 
@@ -103,12 +122,11 @@
 void machine_input_init(void)
 {
-	(machine_ops.machine_input_init)();
+	(machine_ops->machine_input_init)();
 }
 
-/*
- * Generic function to use, if sepcific function doesn't define any of the above functions.
- */
-void machine_genfunc()
+/** Get IRQ number range used by machine. */
+size_t machine_get_irq_count(void)
 {
+	return (machine_ops->machine_get_irq_count)();
 }
 
Index: kernel/arch/arm32/src/mm/frame.c
===================================================================
--- kernel/arch/arm32/src/mm/frame.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/arm32/src/mm/frame.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -36,13 +36,7 @@
 #include <mm/frame.h>
 #include <arch/mm/frame.h>
+#include <arch/machine_func.h>
 #include <config.h>
-
-#ifdef MACHINE_testarm
-	#include <arch/mach/testarm/testarm.h>
-#endif
-
-#ifdef MACHINE_integratorcp
-	#include <arch/mach/integratorcp/integratorcp.h>
-#endif
+#include <align.h>
 
 /** Address of the last frame in the memory. */
@@ -52,8 +46,15 @@
 void frame_arch_init(void)
 {
-	last_frame = machine_get_memory_size();
+	uintptr_t mem_start, mem_size;
+	uintptr_t first_frame;
+	uintptr_t num_frames;
+
+	machine_get_memory_extents(&mem_start, &mem_size);
+	first_frame = ALIGN_UP(mem_start, FRAME_SIZE);
+	last_frame = ALIGN_DOWN(mem_start + mem_size, FRAME_SIZE);
+	num_frames = (last_frame - first_frame) >> FRAME_WIDTH;
 	
 	/* All memory as one zone */
-	zone_create(0, ADDR2PFN(last_frame),
+	zone_create(first_frame >> FRAME_WIDTH, num_frames,
 	    BOOT_PAGE_TABLE_START_FRAME + BOOT_PAGE_TABLE_SIZE_IN_FRAMES, 0);
 	
Index: kernel/arch/arm32/src/mm/page.c
===================================================================
--- kernel/arch/arm32/src/mm/page.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/arm32/src/mm/page.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -27,5 +27,5 @@
  */
 
-/** @addtogroup arm32mm	
+/** @addtogroup arm32mm
  * @{
  */
@@ -53,8 +53,10 @@
 	int flags = PAGE_CACHEABLE;
 	page_mapping_operations = &pt_mapping_operations;
+
+	page_table_lock(AS_KERNEL, true);
 	
 	uintptr_t cur;
 	/* Kernel identity mapping */
-	for (cur = 0; cur < last_frame; cur += FRAME_SIZE)
+	for (cur = PHYSMEM_START_ADDR; cur < last_frame; cur += FRAME_SIZE)
 		page_mapping_insert(AS_KERNEL, PA2KA(cur), cur, flags);
 	
@@ -66,4 +68,8 @@
 #error "Only high exception vector supported now"
 #endif
+	cur = ALIGN_DOWN(0x50008010, FRAME_SIZE);
+	page_mapping_insert(AS_KERNEL, PA2KA(cur), cur, flags);
+
+	page_table_unlock(AS_KERNEL, true);
 	
 	as_switch(NULL, AS_KERNEL);
@@ -92,4 +98,6 @@
 	uintptr_t virtaddr = PA2KA(last_frame);
 	pfn_t i;
+
+	page_table_lock(AS_KERNEL, true);
 	for (i = 0; i < ADDR2PFN(ALIGN_UP(size, PAGE_SIZE)); i++) {
 		page_mapping_insert(AS_KERNEL, virtaddr + PFN2ADDR(i),
@@ -97,4 +105,5 @@
 		    PAGE_NOT_CACHEABLE | PAGE_READ | PAGE_WRITE | PAGE_KERNEL);
 	}
+	page_table_unlock(AS_KERNEL, true);
 	
 	last_frame = ALIGN_UP(last_frame + size, FRAME_SIZE);
Index: kernel/arch/arm32/src/mm/page_fault.c
===================================================================
--- kernel/arch/arm32/src/mm/page_fault.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/arm32/src/mm/page_fault.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -167,8 +167,9 @@
 /** Handles "data abort" exception (load or store at invalid address).
  *
- * @param exc_no	Exception number.
- * @param istate	CPU state when exception occured.
- */
-void data_abort(int exc_no, istate_t *istate)
+ * @param exc_no Exception number.
+ * @param istate CPU state when exception occured.
+ *
+ */
+void data_abort(unsigned int exc_no, istate_t *istate)
 {
 	fault_status_t fsr __attribute__ ((unused)) =
@@ -182,10 +183,5 @@
 	if (ret == AS_PF_FAULT) {
 		fault_if_from_uspace(istate, "Page fault: %#x.", badvaddr);
-		print_istate(istate);
-		printf("page fault - pc: %x, va: %x, status: %x(%x), "
-		    "access:%d\n", istate->pc, badvaddr, fsr.status, fsr,
-		    access);
-		
-		panic("Page fault.");
+		panic_memtrap(istate, access, badvaddr, NULL);
 	}
 }
@@ -193,16 +189,16 @@
 /** Handles "prefetch abort" exception (instruction couldn't be executed).
  *
- * @param exc_no	Exception number.
- * @param istate	CPU state when exception occured.
- */
-void prefetch_abort(int exc_no, istate_t *istate)
+ * @param exc_no Exception number.
+ * @param istate CPU state when exception occured.
+ *
+ */
+void prefetch_abort(unsigned int exc_no, istate_t *istate)
 {
 	int ret = as_page_fault(istate->pc, PF_ACCESS_EXEC, istate);
 
 	if (ret == AS_PF_FAULT) {
-		printf("prefetch_abort\n");
-		print_istate(istate);
-		panic("page fault - prefetch_abort at address: %x.",
-		    istate->pc);
+		fault_if_from_uspace(istate,
+		    "Page fault - prefetch_abort: %#x.", istate->pc);
+		panic_memtrap(istate, PF_ACCESS_EXEC, istate->pc, NULL);
 	}
 }
Index: rnel/arch/arm32/src/panic.S
===================================================================
--- kernel/arch/arm32/src/panic.S	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ 	(revision )
@@ -1,35 +1,0 @@
-#
-# Copyright (c) 2007 Michal Kebrt
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions
-# are met:
-#
-# - Redistributions of source code must retain the above copyright
-#   notice, this list of conditions and the following disclaimer.
-# - Redistributions in binary form must reproduce the above copyright
-#   notice, this list of conditions and the following disclaimer in the
-#   documentation and/or other materials provided with the distribution.
-# - The name of the author may not be used to endorse or promote products
-#   derived from this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
-# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
-# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
-# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
-# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
-# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-#
-
-.text
-
-.global panic_printf
-
-panic_printf:
-	bl printf
-	bl cpu_halt
Index: kernel/arch/arm32/src/ras.c
===================================================================
--- kernel/arch/arm32/src/ras.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/arm32/src/ras.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2009 Jakub Jermar 
+ * Copyright (c) 2009 Jakub Jermar
  * All rights reserved.
  *
@@ -66,5 +66,5 @@
 }
 
-void ras_check(int n, istate_t *istate)
+void ras_check(unsigned int n, istate_t *istate)
 {
 	uintptr_t rewrite_pc = istate->pc;
Index: kernel/arch/arm32/src/userspace.c
===================================================================
--- kernel/arch/arm32/src/userspace.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/arm32/src/userspace.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -97,5 +97,7 @@
 		"mov sp, %[ustate]\n"
 		"msr spsr_c, %[user_mode]\n"
-		"ldmfd sp!, {r0-r12, sp, lr}^\n"
+		"ldmfd sp, {r0-r12, sp, lr}^\n"
+		"nop\n"		/* Cannot access sp immediately after ldm(2) */
+		"add sp, sp, #(15*4)\n"
 		"ldmfd sp!, {pc}^\n"
 		:: [ustate] "r" (&ustate), [user_mode] "r" (user_mode)
Index: kernel/arch/ia32/Makefile.inc
===================================================================
--- kernel/arch/ia32/Makefile.inc	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/ia32/Makefile.inc	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -76,5 +76,4 @@
 ARCH_SOURCES = \
 	arch/$(KARCH)/src/context.S \
-	arch/$(KARCH)/src/debug/panic.s \
 	arch/$(KARCH)/src/debug/stacktrace.c \
 	arch/$(KARCH)/src/debug/stacktrace_asm.S \
Index: kernel/arch/ia32/include/asm.h
===================================================================
--- kernel/arch/ia32/include/asm.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/ia32/include/asm.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -38,19 +38,8 @@
 
 #include <arch/pm.h>
+#include <arch/cpu.h>
 #include <typedefs.h>
 #include <config.h>
-
-extern uint32_t interrupt_handler_size;
-
-extern void paging_on(void);
-
-extern void interrupt_handlers(void);
-
-extern void enable_l_apic_in_msr(void);
-
-
-extern void asm_delay_loop(uint32_t t);
-extern void asm_fake_loop(uint32_t t);
-
+#include <trace.h>
 
 /** Halt CPU
@@ -59,5 +48,5 @@
  *
  */
-static inline __attribute__((noreturn)) void cpu_halt(void)
+NO_TRACE static inline __attribute__((noreturn)) void cpu_halt(void)
 {
 	while (true) {
@@ -68,10 +57,12 @@
 }
 
-static inline void cpu_sleep(void)
-{
-	asm volatile ("hlt\n");
-}
-
-#define GEN_READ_REG(reg) static inline unative_t read_ ##reg (void) \
+NO_TRACE static inline void cpu_sleep(void)
+{
+	asm volatile (
+		"hlt\n"
+	);
+}
+
+#define GEN_READ_REG(reg) NO_TRACE static inline unative_t read_ ##reg (void) \
 	{ \
 		unative_t res; \
@@ -83,5 +74,5 @@
 	}
 
-#define GEN_WRITE_REG(reg) static inline void write_ ##reg (unative_t regn) \
+#define GEN_WRITE_REG(reg) NO_TRACE static inline void write_ ##reg (unative_t regn) \
 	{ \
 		asm volatile ( \
@@ -118,9 +109,10 @@
  *
  */
-static inline void pio_write_8(ioport8_t *port, uint8_t val)
+NO_TRACE static inline void pio_write_8(ioport8_t *port, uint8_t val)
 {
 	asm volatile (
 		"outb %b[val], %w[port]\n"
-		:: [val] "a" (val), [port] "d" (port)
+		:: [val] "a" (val),
+		   [port] "d" (port)
 	);
 }
@@ -134,9 +126,10 @@
  *
  */
-static inline void pio_write_16(ioport16_t *port, uint16_t val)
+NO_TRACE static inline void pio_write_16(ioport16_t *port, uint16_t val)
 {
 	asm volatile (
 		"outw %w[val], %w[port]\n"
-		:: [val] "a" (val), [port] "d" (port)
+		:: [val] "a" (val),
+		   [port] "d" (port)
 	);
 }
@@ -150,9 +143,10 @@
  *
  */
-static inline void pio_write_32(ioport32_t *port, uint32_t val)
+NO_TRACE static inline void pio_write_32(ioport32_t *port, uint32_t val)
 {
 	asm volatile (
 		"outl %[val], %w[port]\n"
-		:: [val] "a" (val), [port] "d" (port)
+		:: [val] "a" (val),
+		   [port] "d" (port)
 	);
 }
@@ -166,5 +160,5 @@
  *
  */
-static inline uint8_t pio_read_8(ioport8_t *port)
+NO_TRACE static inline uint8_t pio_read_8(ioport8_t *port)
 {
 	uint8_t val;
@@ -187,5 +181,5 @@
  *
  */
-static inline uint16_t pio_read_16(ioport16_t *port)
+NO_TRACE static inline uint16_t pio_read_16(ioport16_t *port)
 {
 	uint16_t val;
@@ -208,5 +202,5 @@
  *
  */
-static inline uint32_t pio_read_32(ioport32_t *port)
+NO_TRACE static inline uint32_t pio_read_32(ioport32_t *port)
 {
 	uint32_t val;
@@ -229,5 +223,5 @@
  *
  */
-static inline ipl_t interrupts_enable(void)
+NO_TRACE static inline ipl_t interrupts_enable(void)
 {
 	ipl_t v;
@@ -251,5 +245,5 @@
  *
  */
-static inline ipl_t interrupts_disable(void)
+NO_TRACE static inline ipl_t interrupts_disable(void)
 {
 	ipl_t v;
@@ -272,5 +266,5 @@
  *
  */
-static inline void interrupts_restore(ipl_t ipl)
+NO_TRACE static inline void interrupts_restore(ipl_t ipl)
 {
 	asm volatile (
@@ -286,5 +280,5 @@
  *
  */
-static inline ipl_t interrupts_read(void)
+NO_TRACE static inline ipl_t interrupts_read(void)
 {
 	ipl_t v;
@@ -299,15 +293,34 @@
 }
 
+/** Check interrupts state.
+ *
+ * @return True if interrupts are disabled.
+ *
+ */
+NO_TRACE static inline bool interrupts_disabled(void)
+{
+	ipl_t v;
+	
+	asm volatile (
+		"pushf\n"
+		"popl %[v]\n"
+		: [v] "=r" (v)
+	);
+	
+	return ((v & EFLAGS_IF) == 0);
+}
+
 /** Write to MSR */
-static inline void write_msr(uint32_t msr, uint64_t value)
+NO_TRACE static inline void write_msr(uint32_t msr, uint64_t value)
 {
 	asm volatile (
 		"wrmsr"
-		:: "c" (msr), "a" ((uint32_t) (value)),
+		:: "c" (msr),
+		   "a" ((uint32_t) (value)),
 		   "d" ((uint32_t) (value >> 32))
 	);
 }
 
-static inline uint64_t read_msr(uint32_t msr)
+NO_TRACE static inline uint64_t read_msr(uint32_t msr)
 {
 	uint32_t ax, dx;
@@ -315,5 +328,6 @@
 	asm volatile (
 		"rdmsr"
-		: "=a" (ax), "=d" (dx)
+		: "=a" (ax),
+		  "=d" (dx)
 		: "c" (msr)
 	);
@@ -330,5 +344,5 @@
  *
  */
-static inline uintptr_t get_stack_base(void)
+NO_TRACE static inline uintptr_t get_stack_base(void)
 {
 	uintptr_t v;
@@ -343,17 +357,4 @@
 }
 
-/** Return current IP address */
-static inline uintptr_t * get_ip() 
-{
-	uintptr_t *ip;
-	
-	asm volatile (
-		"mov %%eip, %[ip]"
-		: [ip] "=r" (ip)
-	);
-	
-	return ip;
-}
-
 /** Invalidate TLB Entry.
  *
@@ -361,5 +362,5 @@
  *
  */
-static inline void invlpg(uintptr_t addr)
+NO_TRACE static inline void invlpg(uintptr_t addr)
 {
 	asm volatile (
@@ -374,5 +375,5 @@
  *
  */
-static inline void gdtr_load(ptr_16_32_t *gdtr_reg)
+NO_TRACE static inline void gdtr_load(ptr_16_32_t *gdtr_reg)
 {
 	asm volatile (
@@ -387,5 +388,5 @@
  *
  */
-static inline void gdtr_store(ptr_16_32_t *gdtr_reg)
+NO_TRACE static inline void gdtr_store(ptr_16_32_t *gdtr_reg)
 {
 	asm volatile (
@@ -400,5 +401,5 @@
  *
  */
-static inline void idtr_load(ptr_16_32_t *idtr_reg)
+NO_TRACE static inline void idtr_load(ptr_16_32_t *idtr_reg)
 {
 	asm volatile (
@@ -413,5 +414,5 @@
  *
  */
-static inline void tr_load(uint16_t sel)
+NO_TRACE static inline void tr_load(uint16_t sel)
 {
 	asm volatile (
@@ -421,4 +422,77 @@
 }
 
+extern void paging_on(void);
+extern void enable_l_apic_in_msr(void);
+
+extern void asm_delay_loop(uint32_t);
+extern void asm_fake_loop(uint32_t);
+
+extern uintptr_t int_syscall;
+
+extern uintptr_t int_0;
+extern uintptr_t int_1;
+extern uintptr_t int_2;
+extern uintptr_t int_3;
+extern uintptr_t int_4;
+extern uintptr_t int_5;
+extern uintptr_t int_6;
+extern uintptr_t int_7;
+extern uintptr_t int_8;
+extern uintptr_t int_9;
+extern uintptr_t int_10;
+extern uintptr_t int_11;
+extern uintptr_t int_12;
+extern uintptr_t int_13;
+extern uintptr_t int_14;
+extern uintptr_t int_15;
+extern uintptr_t int_16;
+extern uintptr_t int_17;
+extern uintptr_t int_18;
+extern uintptr_t int_19;
+extern uintptr_t int_20;
+extern uintptr_t int_21;
+extern uintptr_t int_22;
+extern uintptr_t int_23;
+extern uintptr_t int_24;
+extern uintptr_t int_25;
+extern uintptr_t int_26;
+extern uintptr_t int_27;
+extern uintptr_t int_28;
+extern uintptr_t int_29;
+extern uintptr_t int_30;
+extern uintptr_t int_31;
+extern uintptr_t int_32;
+extern uintptr_t int_33;
+extern uintptr_t int_34;
+extern uintptr_t int_35;
+extern uintptr_t int_36;
+extern uintptr_t int_37;
+extern uintptr_t int_38;
+extern uintptr_t int_39;
+extern uintptr_t int_40;
+extern uintptr_t int_41;
+extern uintptr_t int_42;
+extern uintptr_t int_43;
+extern uintptr_t int_44;
+extern uintptr_t int_45;
+extern uintptr_t int_46;
+extern uintptr_t int_47;
+extern uintptr_t int_48;
+extern uintptr_t int_49;
+extern uintptr_t int_50;
+extern uintptr_t int_51;
+extern uintptr_t int_52;
+extern uintptr_t int_53;
+extern uintptr_t int_54;
+extern uintptr_t int_55;
+extern uintptr_t int_56;
+extern uintptr_t int_57;
+extern uintptr_t int_58;
+extern uintptr_t int_59;
+extern uintptr_t int_60;
+extern uintptr_t int_61;
+extern uintptr_t int_62;
+extern uintptr_t int_63;
+
 #endif
 
Index: kernel/arch/ia32/include/atomic.h
===================================================================
--- kernel/arch/ia32/include/atomic.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/ia32/include/atomic.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -39,6 +39,7 @@
 #include <arch/barrier.h>
 #include <preemption.h>
+#include <trace.h>
 
-static inline void atomic_inc(atomic_t *val)
+NO_TRACE static inline void atomic_inc(atomic_t *val)
 {
 #ifdef CONFIG_SMP
@@ -55,5 +56,5 @@
 }
 
-static inline void atomic_dec(atomic_t *val)
+NO_TRACE static inline void atomic_dec(atomic_t *val)
 {
 #ifdef CONFIG_SMP
@@ -70,5 +71,5 @@
 }
 
-static inline atomic_count_t atomic_postinc(atomic_t *val)
+NO_TRACE static inline atomic_count_t atomic_postinc(atomic_t *val)
 {
 	atomic_count_t r = 1;
@@ -83,5 +84,5 @@
 }
 
-static inline atomic_count_t atomic_postdec(atomic_t *val)
+NO_TRACE static inline atomic_count_t atomic_postdec(atomic_t *val)
 {
 	atomic_count_t r = -1;
@@ -99,5 +100,5 @@
 #define atomic_predec(val)  (atomic_postdec(val) - 1)
 
-static inline atomic_count_t test_and_set(atomic_t *val)
+NO_TRACE static inline atomic_count_t test_and_set(atomic_t *val)
 {
 	atomic_count_t v = 1;
@@ -113,5 +114,5 @@
 
 /** ia32 specific fast spinlock */
-static inline void atomic_lock_arch(atomic_t *val)
+NO_TRACE static inline void atomic_lock_arch(atomic_t *val)
 {
 	atomic_count_t tmp;
Index: kernel/arch/ia32/include/barrier.h
===================================================================
--- kernel/arch/ia32/include/barrier.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/ia32/include/barrier.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -36,4 +36,6 @@
 #define KERN_ia32_BARRIER_H_
 
+#include <trace.h>
+
 /*
  * NOTE:
@@ -50,5 +52,5 @@
 #define CS_LEAVE_BARRIER()  asm volatile ("" ::: "memory")
 
-static inline void cpuid_serialization(void)
+NO_TRACE static inline void cpuid_serialization(void)
 {
 	asm volatile (
Index: kernel/arch/ia32/include/bios/bios.h
===================================================================
--- kernel/arch/ia32/include/bios/bios.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/ia32/include/bios/bios.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -27,5 +27,5 @@
  */
 
-/** @addtogroup ia32	
+/** @addtogroup ia32
  * @{
  */
@@ -38,6 +38,4 @@
 #include <typedefs.h>
 
-#define BIOS_EBDA_PTR	0x40e
-
 extern uintptr_t ebda;
 
Index: kernel/arch/ia32/include/cpu.h
===================================================================
--- kernel/arch/ia32/include/cpu.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/ia32/include/cpu.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -37,4 +37,6 @@
 
 #define EFLAGS_IF       (1 << 9)
+#define EFLAGS_DF       (1 << 10)
+#define EFLAGS_NT       (1 << 14)
 #define EFLAGS_RF       (1 << 16)
 
Index: kernel/arch/ia32/include/cycle.h
===================================================================
--- kernel/arch/ia32/include/cycle.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/ia32/include/cycle.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -27,5 +27,5 @@
  */
 
-/** @addtogroup ia32	
+/** @addtogroup ia32
  * @{
  */
@@ -36,5 +36,7 @@
 #define KERN_ia32_CYCLE_H_
 
-static inline uint64_t get_cycle(void)
+#include <trace.h>
+
+NO_TRACE static inline uint64_t get_cycle(void)
 {
 	uint64_t v;
Index: kernel/arch/ia32/include/ddi/ddi.h
===================================================================
--- kernel/arch/ia32/include/ddi/ddi.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/ia32/include/ddi/ddi.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -32,5 +32,5 @@
 /**
  * @file
- * @brief	ia32 specific DDI declarations and macros.
+ * @brief ia32 specific DDI declarations and macros.
  */
 
Index: rnel/arch/ia32/include/debug.h
===================================================================
--- kernel/arch/ia32/include/debug.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ 	(revision )
@@ -1,45 +1,0 @@
-/*
- * Copyright (c) 2005 Martin Decky
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/** @addtogroup amd64debug
- * @{
- */
-/** @file
- */
-
-#ifndef KERN_ia32_DEBUG_H_
-#define KERN_ia32_DEBUG_H_
-
-#include <arch/asm.h>
-
-#define HERE get_ip()
-
-#endif
-
-/** @}
- */
Index: kernel/arch/ia32/include/drivers/i8259.h
===================================================================
--- kernel/arch/ia32/include/drivers/i8259.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/ia32/include/drivers/i8259.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -48,6 +48,6 @@
 
 extern void i8259_init(void);
-extern void pic_enable_irqs(uint16_t irqmask);
-extern void pic_disable_irqs(uint16_t irqmask);
+extern void pic_enable_irqs(uint16_t);
+extern void pic_disable_irqs(uint16_t);
 extern void pic_eoi(void);
 
Index: kernel/arch/ia32/include/fpu_context.h
===================================================================
--- kernel/arch/ia32/include/fpu_context.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/ia32/include/fpu_context.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -27,5 +27,5 @@
  */
 
-/** @addtogroup ia32	
+/** @addtogroup ia32
  * @{
  */
@@ -38,13 +38,12 @@
 #include <typedefs.h>
 
-#define FPU_CONTEXT_ALIGN 16
-
-void fpu_fxsr(void);
-void fpu_fsr(void);
-
+#define FPU_CONTEXT_ALIGN  16
 
 typedef struct {
-	uint8_t fpu[512]; 		/* FXSAVE & FXRSTOR storage area */
+	uint8_t fpu[512];  /* FXSAVE & FXRSTOR storage area */
 } fpu_context_t;
+
+extern void fpu_fxsr(void);
+extern void fpu_fsr(void);
 
 #endif
Index: kernel/arch/ia32/include/interrupt.h
===================================================================
--- kernel/arch/ia32/include/interrupt.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/ia32/include/interrupt.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -38,24 +38,25 @@
 #include <typedefs.h>
 #include <arch/pm.h>
+#include <trace.h>
 
-#define IVT_ITEMS	IDT_ITEMS
-#define IVT_FIRST	0
+#define IVT_ITEMS  IDT_ITEMS
+#define IVT_FIRST  0
 
-#define EXC_COUNT	32
-#define IRQ_COUNT	16
+#define EXC_COUNT  32
+#define IRQ_COUNT  16
 
-#define IVT_EXCBASE	0
-#define IVT_IRQBASE	(IVT_EXCBASE + EXC_COUNT)
-#define IVT_FREEBASE	(IVT_IRQBASE + IRQ_COUNT)
+#define IVT_EXCBASE   0
+#define IVT_IRQBASE   (IVT_EXCBASE + EXC_COUNT)
+#define IVT_FREEBASE  (IVT_IRQBASE + IRQ_COUNT)
 
-#define IRQ_CLK		0
-#define IRQ_KBD		1
-#define IRQ_PIC1	2
-#define IRQ_PIC_SPUR	7
-#define IRQ_MOUSE	12
-#define IRQ_DP8390	9
+#define IRQ_CLK       0
+#define IRQ_KBD       1
+#define IRQ_PIC1      2
+#define IRQ_PIC_SPUR  7
+#define IRQ_MOUSE     12
+#define IRQ_DP8390    9
 
-/* this one must have four least significant bits set to ones */
-#define VECTOR_APIC_SPUR	(IVT_ITEMS - 1)
+/* This one must have four least significant bits set to ones */
+#define VECTOR_APIC_SPUR  (IVT_ITEMS - 1)
 
 #if (((VECTOR_APIC_SPUR + 1) % 16) || VECTOR_APIC_SPUR >= IVT_ITEMS)
@@ -63,58 +64,70 @@
 #endif
 
-#define VECTOR_DEBUG			1
-#define VECTOR_CLK			(IVT_IRQBASE + IRQ_CLK)
-#define VECTOR_PIC_SPUR			(IVT_IRQBASE + IRQ_PIC_SPUR)
-#define VECTOR_SYSCALL			IVT_FREEBASE
-#define VECTOR_TLB_SHOOTDOWN_IPI	(IVT_FREEBASE + 1)
-#define VECTOR_DEBUG_IPI		(IVT_FREEBASE + 2)
+#define VECTOR_DEBUG              1
+#define VECTOR_CLK                (IVT_IRQBASE + IRQ_CLK)
+#define VECTOR_PIC_SPUR           (IVT_IRQBASE + IRQ_PIC_SPUR)
+#define VECTOR_SYSCALL            IVT_FREEBASE
+#define VECTOR_TLB_SHOOTDOWN_IPI  (IVT_FREEBASE + 1)
+#define VECTOR_DEBUG_IPI          (IVT_FREEBASE + 2)
 
 typedef struct istate {
+	/*
+	 * The strange order of the GPRs is given by the requirement to use the
+	 * istate structure for both regular interrupts and exceptions as well
+	 * as for syscall handlers which use this order as an optimization.
+	 */
+	uint32_t edx;
+	uint32_t ecx;
+	uint32_t ebx;
+	uint32_t esi;
+	uint32_t edi;
+	uint32_t ebp;
 	uint32_t eax;
-	uint32_t ecx;
-	uint32_t edx;
-	uint32_t ebp;
-
+	
+	uint32_t ebp_frame;  /* imitation of frame pointer linkage */
+	uint32_t eip_frame;  /* imitation of return address linkage */
+	
 	uint32_t gs;
 	uint32_t fs;
 	uint32_t es;
 	uint32_t ds;
-
-	uint32_t error_word;
+	
+	uint32_t error_word;  /* real or fake error word */
 	uint32_t eip;
 	uint32_t cs;
 	uint32_t eflags;
-	uint32_t stack[];
+	uint32_t esp;         /* only if istate_t is from uspace */
+	uint32_t ss;          /* only if istate_t is from uspace */
 } istate_t;
 
 /** Return true if exception happened while in userspace */
-static inline int istate_from_uspace(istate_t *istate)
+NO_TRACE static inline int istate_from_uspace(istate_t *istate)
 {
 	return !(istate->eip & 0x80000000);
 }
 
-static inline void istate_set_retaddr(istate_t *istate, uintptr_t retaddr)
+NO_TRACE static inline void istate_set_retaddr(istate_t *istate,
+    uintptr_t retaddr)
 {
 	istate->eip = retaddr;
 }
 
-static inline unative_t istate_get_pc(istate_t *istate)
+NO_TRACE static inline unative_t istate_get_pc(istate_t *istate)
 {
 	return istate->eip;
 }
 
-static inline unative_t istate_get_fp(istate_t *istate)
+NO_TRACE static inline unative_t istate_get_fp(istate_t *istate)
 {
 	return istate->ebp;
 }
 
-extern void (* disable_irqs_function)(uint16_t irqmask);
-extern void (* enable_irqs_function)(uint16_t irqmask);
+extern void (* disable_irqs_function)(uint16_t);
+extern void (* enable_irqs_function)(uint16_t);
 extern void (* eoi_function)(void);
 
-extern void decode_istate(istate_t *istate);
 extern void interrupt_init(void);
-extern void trap_virtual_enable_irqs(uint16_t irqmask);
-extern void trap_virtual_disable_irqs(uint16_t irqmask);
+extern void trap_virtual_enable_irqs(uint16_t);
+extern void trap_virtual_disable_irqs(uint16_t);
 
 #endif
Index: kernel/arch/ia32/include/mm/as.h
===================================================================
--- kernel/arch/ia32/include/mm/as.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/ia32/include/mm/as.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -27,5 +27,5 @@
  */
 
-/** @addtogroup ia32mm	
+/** @addtogroup ia32mm
  * @{
  */
Index: kernel/arch/ia32/include/mm/asid.h
===================================================================
--- kernel/arch/ia32/include/mm/asid.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/ia32/include/mm/asid.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -27,5 +27,5 @@
  */
 
-/** @addtogroup ia32mm	
+/** @addtogroup ia32mm
  * @{
  */
@@ -47,7 +47,7 @@
 typedef int32_t asid_t;
 
-#define ASID_MAX_ARCH		3
+#define ASID_MAX_ARCH  3
 
-#define asid_get()		(ASID_START + 1)
+#define asid_get()  (ASID_START + 1)
 #define asid_put(asid)
 
Index: kernel/arch/ia32/include/mm/page.h
===================================================================
--- kernel/arch/ia32/include/mm/page.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/ia32/include/mm/page.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -27,5 +27,5 @@
  */
 
-/** @addtogroup ia32mm	
+/** @addtogroup ia32mm
  * @{
  */
@@ -37,4 +37,5 @@
 
 #include <arch/mm/frame.h>
+#include <trace.h>
 
 #define PAGE_WIDTH	FRAME_WIDTH
@@ -105,5 +106,5 @@
 
 /* Set PTE flags accessors for each level. */
-#define SET_PTL1_FLAGS_ARCH(ptl0, i, x)	\
+#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)
@@ -161,5 +162,5 @@
 } __attribute__ ((packed)) pte_t;
 
-static inline unsigned int get_pt_flags(pte_t *pt, size_t i)
+NO_TRACE static inline unsigned int get_pt_flags(pte_t *pt, size_t i)
 {
 	pte_t *p = &pt[i];
@@ -174,5 +175,5 @@
 }
 
-static inline void set_pt_flags(pte_t *pt, size_t i, int flags)
+NO_TRACE static inline void set_pt_flags(pte_t *pt, size_t i, int flags)
 {
 	pte_t *p = &pt[i];
@@ -192,5 +193,5 @@
 
 extern void page_arch_init(void);
-extern void page_fault(int n, istate_t *istate);
+extern void page_fault(unsigned int, istate_t *);
 
 #endif /* __ASM__ */
Index: kernel/arch/ia32/include/pm.h
===================================================================
--- kernel/arch/ia32/include/pm.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/ia32/include/pm.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -58,5 +58,5 @@
 #endif /* CONFIG_FB */
 
-#define gdtselector(des)  ((des) << 3)
+#define GDT_SELECTOR(des)  ((des) << 3)
 
 #define PL_KERNEL  0
@@ -67,6 +67,7 @@
 #define AR_CODE       (3 << 3)
 #define AR_WRITABLE   (1 << 1)
-#define AR_INTERRUPT  (0x0e)
-#define AR_TSS        (0x09)
+#define AR_INTERRUPT  (0xe)
+#define AR_TRAP       (0xf)
+#define AR_TSS        (0x9)
 
 #define DPL_KERNEL  (PL_KERNEL << 5)
@@ -152,5 +153,4 @@
 
 extern ptr_16_32_t gdtr;
-extern ptr_16_32_t bootstrap_gdtr;
 extern ptr_16_32_t protected_ap_gdtr;
 extern tss_t *tss_p;
Index: kernel/arch/ia32/include/smp/apic.h
===================================================================
--- kernel/arch/ia32/include/smp/apic.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/ia32/include/smp/apic.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -27,5 +27,5 @@
  */
 
-/** @addtogroup ia32	
+/** @addtogroup ia32
  * @{
  */
@@ -39,87 +39,88 @@
 #include <cpu.h>
 
-#define FIXED		(0<<0)
-#define LOPRI		(1<<0)
-
-#define APIC_ID_COUNT	16
+#define FIXED  (0 << 0)
+#define LOPRI  (1 << 0)
+
+#define APIC_ID_COUNT  16
 
 /* local APIC macros */
-#define IPI_INIT 	0
-#define IPI_STARTUP	0
+#define IPI_INIT     0
+#define IPI_STARTUP  0
 
 /** Delivery modes. */
-#define DELMOD_FIXED	0x0
-#define DELMOD_LOWPRI	0x1
-#define DELMOD_SMI	0x2
+#define DELMOD_FIXED    0x0
+#define DELMOD_LOWPRI   0x1
+#define DELMOD_SMI      0x2
 /* 0x3 reserved */
-#define DELMOD_NMI	0x4
-#define DELMOD_INIT	0x5
-#define DELMOD_STARTUP	0x6
-#define DELMOD_EXTINT	0x7
+#define DELMOD_NMI      0x4
+#define DELMOD_INIT     0x5
+#define DELMOD_STARTUP  0x6
+#define DELMOD_EXTINT   0x7
 
 /** Destination modes. */
-#define DESTMOD_PHYS	0x0
-#define DESTMOD_LOGIC	0x1
+#define DESTMOD_PHYS   0x0
+#define DESTMOD_LOGIC  0x1
 
 /** Trigger Modes. */
-#define TRIGMOD_EDGE	0x0
-#define TRIGMOD_LEVEL	0x1
+#define TRIGMOD_EDGE   0x0
+#define TRIGMOD_LEVEL  0x1
 
 /** Levels. */
-#define LEVEL_DEASSERT	0x0
-#define LEVEL_ASSERT	0x1
+#define LEVEL_DEASSERT  0x0
+#define LEVEL_ASSERT    0x1
 
 /** Destination Shorthands. */
-#define SHORTHAND_NONE		0x0
-#define SHORTHAND_SELF		0x1
-#define SHORTHAND_ALL_INCL	0x2
-#define SHORTHAND_ALL_EXCL	0x3
+#define SHORTHAND_NONE      0x0
+#define SHORTHAND_SELF      0x1
+#define SHORTHAND_ALL_INCL  0x2
+#define SHORTHAND_ALL_EXCL  0x3
 
 /** Interrupt Input Pin Polarities. */
-#define POLARITY_HIGH	0x0
-#define POLARITY_LOW	0x1
+#define POLARITY_HIGH  0x0
+#define POLARITY_LOW   0x1
 
 /** Divide Values. (Bit 2 is always 0) */
-#define DIVIDE_2	0x0
-#define DIVIDE_4	0x1
-#define DIVIDE_8	0x2
-#define DIVIDE_16	0x3
-#define DIVIDE_32	0x8
-#define DIVIDE_64	0x9
-#define DIVIDE_128	0xa
-#define DIVIDE_1	0xb
+#define DIVIDE_2    0x0
+#define DIVIDE_4    0x1
+#define DIVIDE_8    0x2
+#define DIVIDE_16   0x3
+#define DIVIDE_32   0x8
+#define DIVIDE_64   0x9
+#define DIVIDE_128  0xa
+#define DIVIDE_1    0xb
 
 /** Timer Modes. */
-#define TIMER_ONESHOT	0x0
-#define TIMER_PERIODIC	0x1
+#define TIMER_ONESHOT   0x0
+#define TIMER_PERIODIC  0x1
 
 /** Delivery status. */
-#define DELIVS_IDLE	0x0
-#define DELIVS_PENDING	0x1
+#define DELIVS_IDLE     0x0
+#define DELIVS_PENDING  0x1
 
 /** Destination masks. */
-#define DEST_ALL	0xff
+#define DEST_ALL  0xff
 
 /** Dest format models. */
-#define MODEL_FLAT	0xf
-#define MODEL_CLUSTER	0x0
+#define MODEL_FLAT     0xf
+#define MODEL_CLUSTER  0x0
 
 /** Interrupt Command Register. */
-#define ICRlo		(0x300 / sizeof(uint32_t))
-#define ICRhi		(0x310 / sizeof(uint32_t))
+#define ICRlo  (0x300 / sizeof(uint32_t))
+#define ICRhi  (0x310 / sizeof(uint32_t))
+
 typedef struct {
 	union {
 		uint32_t lo;
 		struct {
-			uint8_t vector;			/**< Interrupt Vector. */
-			unsigned delmod : 3;		/**< Delivery Mode. */
-			unsigned destmod : 1;		/**< Destination Mode. */
-			unsigned delivs : 1;		/**< Delivery status (RO). */
-			unsigned : 1;			/**< Reserved. */
-			unsigned level : 1;		/**< Level. */
-			unsigned trigger_mode : 1;	/**< Trigger Mode. */
-			unsigned : 2;			/**< Reserved. */
-			unsigned shorthand : 2;		/**< Destination Shorthand. */
-			unsigned : 12;			/**< Reserved. */
+			uint8_t vector;                 /**< Interrupt Vector. */
+			unsigned int delmod : 3;        /**< Delivery Mode. */
+			unsigned int destmod : 1;       /**< Destination Mode. */
+			unsigned int delivs : 1;        /**< Delivery status (RO). */
+			unsigned int : 1;               /**< Reserved. */
+			unsigned int level : 1;         /**< Level. */
+			unsigned int trigger_mode : 1;  /**< Trigger Mode. */
+			unsigned int : 2;               /**< Reserved. */
+			unsigned int shorthand : 2;     /**< Destination Shorthand. */
+			unsigned int : 12;              /**< Reserved. */
 		} __attribute__ ((packed));
 	};
@@ -127,6 +128,6 @@
 		uint32_t hi;
 		struct {
-			unsigned : 24;			/**< Reserved. */
-			uint8_t dest;			/**< Destination field. */
+			unsigned int : 24;  /**< Reserved. */
+			uint8_t dest;       /**< Destination field. */
 		} __attribute__ ((packed));
 	};
@@ -134,154 +135,165 @@
 
 /* End Of Interrupt. */
-#define EOI		(0x0b0 / sizeof(uint32_t))
+#define EOI  (0x0b0 / sizeof(uint32_t))
 
 /** Error Status Register. */
-#define ESR		(0x280 / sizeof(uint32_t))
+#define ESR  (0x280 / sizeof(uint32_t))
+
 typedef union {
 	uint32_t value;
 	uint8_t err_bitmap;
 	struct {
-		unsigned send_checksum_error : 1;
-		unsigned receive_checksum_error : 1;
-		unsigned send_accept_error : 1;
-		unsigned receive_accept_error : 1;
-		unsigned : 1;
-		unsigned send_illegal_vector : 1;
-		unsigned received_illegal_vector : 1;
-		unsigned illegal_register_address : 1;
-		unsigned : 24;
+		unsigned int send_checksum_error : 1;
+		unsigned int receive_checksum_error : 1;
+		unsigned int send_accept_error : 1;
+		unsigned int receive_accept_error : 1;
+		unsigned int : 1;
+		unsigned int send_illegal_vector : 1;
+		unsigned int received_illegal_vector : 1;
+		unsigned int illegal_register_address : 1;
+		unsigned int : 24;
 	} __attribute__ ((packed));
 } esr_t;
 
 /* Task Priority Register */
-#define TPR		(0x080 / sizeof(uint32_t))
-typedef union {
-	uint32_t value;
-	struct {
-		unsigned pri_sc : 4;		/**< Task Priority Sub-Class. */
-		unsigned pri : 4;		/**< Task Priority. */
+#define TPR  (0x080 / sizeof(uint32_t))
+
+typedef union {
+	uint32_t value;
+	struct {
+		unsigned int pri_sc : 4;  /**< Task Priority Sub-Class. */
+		unsigned int pri : 4;     /**< Task Priority. */
 	} __attribute__ ((packed));
 } tpr_t;
 
 /** Spurious-Interrupt Vector Register. */
-#define SVR		(0x0f0 / sizeof(uint32_t))
-typedef union {
-	uint32_t value;
-	struct {
-		uint8_t vector;			/**< Spurious Vector. */
-		unsigned lapic_enabled : 1;	/**< APIC Software Enable/Disable. */
-		unsigned focus_checking : 1;	/**< Focus Processor Checking. */
-		unsigned : 22;			/**< Reserved. */
+#define SVR  (0x0f0 / sizeof(uint32_t))
+
+typedef union {
+	uint32_t value;
+	struct {
+		uint8_t vector;                   /**< Spurious Vector. */
+		unsigned int lapic_enabled : 1;   /**< APIC Software Enable/Disable. */
+		unsigned int focus_checking : 1;  /**< Focus Processor Checking. */
+		unsigned int : 22;                /**< Reserved. */
 	} __attribute__ ((packed));
 } svr_t;
 
 /** Time Divide Configuration Register. */
-#define TDCR		(0x3e0 / sizeof(uint32_t))
-typedef union {
-	uint32_t value;
-	struct {
-		unsigned div_value : 4;		/**< Divide Value, bit 2 is always 0. */
-		unsigned : 28;			/**< Reserved. */
+#define TDCR  (0x3e0 / sizeof(uint32_t))
+
+typedef union {
+	uint32_t value;
+	struct {
+		unsigned int div_value : 4;  /**< Divide Value, bit 2 is always 0. */
+		unsigned int : 28;           /**< Reserved. */
 	} __attribute__ ((packed));
 } tdcr_t;
 
 /* Initial Count Register for Timer */
-#define ICRT		(0x380 / sizeof(uint32_t))
+#define ICRT  (0x380 / sizeof(uint32_t))
 
 /* Current Count Register for Timer */
-#define CCRT		(0x390 / sizeof(uint32_t))
+#define CCRT  (0x390 / sizeof(uint32_t))
 
 /** LVT Timer register. */
-#define LVT_Tm		(0x320 / sizeof(uint32_t))
-typedef union {
-	uint32_t value;
-	struct {
-		uint8_t vector;		/**< Local Timer Interrupt vector. */
-		unsigned : 4;		/**< Reserved. */
-		unsigned delivs : 1;	/**< Delivery status (RO). */
-		unsigned : 3;		/**< Reserved. */
-		unsigned masked : 1;	/**< Interrupt Mask. */
-		unsigned mode : 1;	/**< Timer Mode. */
-		unsigned : 14;		/**< Reserved. */
+#define LVT_Tm  (0x320 / sizeof(uint32_t))
+
+typedef union {
+	uint32_t value;
+	struct {
+		uint8_t vector;           /**< Local Timer Interrupt vector. */
+		unsigned int : 4;         /**< Reserved. */
+		unsigned int delivs : 1;  /**< Delivery status (RO). */
+		unsigned int : 3;         /**< Reserved. */
+		unsigned int masked : 1;  /**< Interrupt Mask. */
+		unsigned int mode : 1;    /**< Timer Mode. */
+		unsigned int : 14;        /**< Reserved. */
 	} __attribute__ ((packed));
 } lvt_tm_t;
 
 /** LVT LINT registers. */
-#define LVT_LINT0	(0x350 / sizeof(uint32_t))
-#define LVT_LINT1	(0x360 / sizeof(uint32_t))
-typedef union {
-	uint32_t value;
-	struct {
-		uint8_t vector;			/**< LINT Interrupt vector. */
-		unsigned delmod : 3;		/**< Delivery Mode. */
-		unsigned : 1;			/**< Reserved. */
-		unsigned delivs : 1;		/**< Delivery status (RO). */
-		unsigned intpol : 1;		/**< Interrupt Input Pin Polarity. */
-		unsigned irr : 1;		/**< Remote IRR (RO). */
-		unsigned trigger_mode : 1;	/**< Trigger Mode. */
-		unsigned masked : 1;		/**< Interrupt Mask. */
-		unsigned : 15;			/**< Reserved. */
+#define LVT_LINT0  (0x350 / sizeof(uint32_t))
+#define LVT_LINT1  (0x360 / sizeof(uint32_t))
+
+typedef union {
+	uint32_t value;
+	struct {
+		uint8_t vector;                 /**< LINT Interrupt vector. */
+		unsigned int delmod : 3;        /**< Delivery Mode. */
+		unsigned int : 1;               /**< Reserved. */
+		unsigned int delivs : 1;        /**< Delivery status (RO). */
+		unsigned int intpol : 1;        /**< Interrupt Input Pin Polarity. */
+		unsigned int irr : 1;           /**< Remote IRR (RO). */
+		unsigned int trigger_mode : 1;  /**< Trigger Mode. */
+		unsigned int masked : 1;        /**< Interrupt Mask. */
+		unsigned int : 15;              /**< Reserved. */
 	} __attribute__ ((packed));
 } lvt_lint_t;
 
 /** LVT Error register. */
-#define LVT_Err		(0x370 / sizeof(uint32_t))
-typedef union {
-	uint32_t value;
-	struct {
-		uint8_t vector;		/**< Local Timer Interrupt vector. */
-		unsigned : 4;		/**< Reserved. */
-		unsigned delivs : 1;	/**< Delivery status (RO). */
-		unsigned : 3;		/**< Reserved. */
-		unsigned masked : 1;	/**< Interrupt Mask. */
-		unsigned : 15;		/**< Reserved. */
+#define LVT_Err  (0x370 / sizeof(uint32_t))
+
+typedef union {
+	uint32_t value;
+	struct {
+		uint8_t vector;           /**< Local Timer Interrupt vector. */
+		unsigned int : 4;         /**< Reserved. */
+		unsigned int delivs : 1;  /**< Delivery status (RO). */
+		unsigned int : 3;         /**< Reserved. */
+		unsigned int masked : 1;  /**< Interrupt Mask. */
+		unsigned int : 15;        /**< Reserved. */
 	} __attribute__ ((packed));
 } lvt_error_t;
 
 /** Local APIC ID Register. */
-#define L_APIC_ID	(0x020 / sizeof(uint32_t))
-typedef union {
-	uint32_t value;
-	struct {
-		unsigned : 24;		/**< Reserved. */
-		uint8_t apic_id;		/**< Local APIC ID. */
+#define L_APIC_ID  (0x020 / sizeof(uint32_t))
+
+typedef union {
+	uint32_t value;
+	struct {
+		unsigned int : 24;  /**< Reserved. */
+		uint8_t apic_id;    /**< Local APIC ID. */
 	} __attribute__ ((packed));
 } l_apic_id_t;
 
 /** Local APIC Version Register */
-#define LAVR		(0x030 / sizeof(uint32_t))
-#define LAVR_Mask	0xff
-#define is_local_apic(x)	(((x) & LAVR_Mask & 0xf0) == 0x1)
-#define is_82489DX_apic(x)	((((x) & LAVR_Mask & 0xf0) == 0x0))
-#define is_local_xapic(x)	(((x) & LAVR_Mask) == 0x14)
+#define LAVR       (0x030 / sizeof(uint32_t))
+#define LAVR_Mask  0xff
+
+#define is_local_apic(x)    (((x) & LAVR_Mask & 0xf0) == 0x1)
+#define is_82489DX_apic(x)  ((((x) & LAVR_Mask & 0xf0) == 0x0))
+#define is_local_xapic(x)   (((x) & LAVR_Mask) == 0x14)
 
 /** Logical Destination Register. */
-#define  LDR		(0x0d0 / sizeof(uint32_t))
-typedef union {
-	uint32_t value;
-	struct {
-		unsigned : 24;		/**< Reserved. */
-		uint8_t id;		/**< Logical APIC ID. */
+#define  LDR  (0x0d0 / sizeof(uint32_t))
+
+typedef union {
+	uint32_t value;
+	struct {
+		unsigned int : 24;  /**< Reserved. */
+		uint8_t id;         /**< Logical APIC ID. */
 	} __attribute__ ((packed));
 } ldr_t;
 
 /** Destination Format Register. */
-#define DFR		(0x0e0 / sizeof(uint32_t))
-typedef union {
-	uint32_t value;
-	struct {
-		unsigned : 28;		/**< Reserved, all ones. */
-		unsigned model : 4;	/**< Model. */
+#define DFR  (0x0e0 / sizeof(uint32_t))
+
+typedef union {
+	uint32_t value;
+	struct {
+		unsigned int : 28;       /**< Reserved, all ones. */
+		unsigned int model : 4;  /**< Model. */
 	} __attribute__ ((packed));
 } dfr_t;
 
 /* IO APIC */
-#define IOREGSEL	(0x00 / sizeof(uint32_t))
-#define IOWIN		(0x10 / sizeof(uint32_t))
-
-#define IOAPICID	0x00
-#define IOAPICVER	0x01
-#define IOAPICARB	0x02
-#define IOREDTBL	0x10
+#define IOREGSEL  (0x00 / sizeof(uint32_t))
+#define IOWIN     (0x10 / sizeof(uint32_t))
+
+#define IOAPICID   0x00
+#define IOAPICVER  0x01
+#define IOAPICARB  0x02
+#define IOREDTBL   0x10
 
 /** I/O Register Select Register. */
@@ -289,6 +301,6 @@
 	uint32_t value;
 	struct {
-		uint8_t reg_addr;		/**< APIC Register Address. */
-		unsigned : 24;		/**< Reserved. */
+		uint8_t reg_addr;   /**< APIC Register Address. */
+		unsigned int : 24;  /**< Reserved. */
 	} __attribute__ ((packed));
 } io_regsel_t;
@@ -299,13 +311,13 @@
 		uint32_t lo;
 		struct {
-			uint8_t intvec;			/**< Interrupt Vector. */
-			unsigned delmod : 3;		/**< Delivery Mode. */
-			unsigned destmod : 1; 		/**< Destination mode. */
-			unsigned delivs : 1;		/**< Delivery status (RO). */
-			unsigned intpol : 1;		/**< Interrupt Input Pin Polarity. */
-			unsigned irr : 1;		/**< Remote IRR (RO). */
-			unsigned trigger_mode : 1;	/**< Trigger Mode. */
-			unsigned masked : 1;		/**< Interrupt Mask. */
-			unsigned : 15;			/**< Reserved. */
+			uint8_t intvec;                 /**< Interrupt Vector. */
+			unsigned int delmod : 3;        /**< Delivery Mode. */
+			unsigned int destmod : 1;       /**< Destination mode. */
+			unsigned int delivs : 1;        /**< Delivery status (RO). */
+			unsigned int intpol : 1;        /**< Interrupt Input Pin Polarity. */
+			unsigned int irr : 1;           /**< Remote IRR (RO). */
+			unsigned int trigger_mode : 1;  /**< Trigger Mode. */
+			unsigned int masked : 1;        /**< Interrupt Mask. */
+			unsigned int : 15;              /**< Reserved. */
 		} __attribute__ ((packed));
 	};
@@ -313,6 +325,6 @@
 		uint32_t hi;
 		struct {
-			unsigned : 24;			/**< Reserved. */
-			uint8_t dest : 8;			/**< Destination Field. */
+			unsigned int : 24;  /**< Reserved. */
+			uint8_t dest : 8;   /**< Destination Field. */
 		} __attribute__ ((packed));
 	};
@@ -325,7 +337,7 @@
 	uint32_t value;
 	struct {
-		unsigned : 24;		/**< Reserved. */
-		unsigned apic_id : 4;	/**< IO APIC ID. */
-		unsigned : 4;		/**< Reserved. */
+		unsigned int : 24;         /**< Reserved. */
+		unsigned int apic_id : 4;  /**< IO APIC ID. */
+		unsigned int : 4;          /**< Reserved. */
 	} __attribute__ ((packed));
 } io_apic_id_t;
@@ -335,4 +347,5 @@
 
 extern uint32_t apic_id_mask;
+extern uint8_t bsp_l_apic;
 
 extern void apic_init(void);
@@ -340,14 +353,13 @@
 extern void l_apic_init(void);
 extern void l_apic_eoi(void);
-extern int l_apic_broadcast_custom_ipi(uint8_t vector);
-extern int l_apic_send_init_ipi(uint8_t apicid);
+extern int l_apic_broadcast_custom_ipi(uint8_t);
+extern int l_apic_send_init_ipi(uint8_t);
 extern void l_apic_debug(void);
-extern uint8_t l_apic_id(void);
-
-extern uint32_t io_apic_read(uint8_t address);
-extern void io_apic_write(uint8_t address , uint32_t x);
-extern void io_apic_change_ioredtbl(uint8_t pin, uint8_t dest, uint8_t v, int flags);
-extern void io_apic_disable_irqs(uint16_t irqmask);
-extern void io_apic_enable_irqs(uint16_t irqmask);
+
+extern uint32_t io_apic_read(uint8_t);
+extern void io_apic_write(uint8_t, uint32_t);
+extern void io_apic_change_ioredtbl(uint8_t pin, uint8_t dest, uint8_t v, unsigned int);
+extern void io_apic_disable_irqs(uint16_t);
+extern void io_apic_enable_irqs(uint16_t);
 
 #endif
Index: kernel/arch/ia32/include/smp/mps.h
===================================================================
--- kernel/arch/ia32/include/smp/mps.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/ia32/include/smp/mps.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -27,5 +27,5 @@
  */
 
-/** @addtogroup ia32	
+/** @addtogroup ia32
  * @{
  */
@@ -41,6 +41,6 @@
 #include <arch/smp/smp.h>
 
-#define CT_EXT_ENTRY_TYPE		0
-#define CT_EXT_ENTRY_LEN		1
+#define CT_EXT_ENTRY_TYPE  0
+#define CT_EXT_ENTRY_LEN   1
 
 struct mps_fs {
@@ -70,5 +70,5 @@
 	uint16_t ext_table_length;
 	uint8_t ext_table_checksum;
-	uint8_t xxx;
+	uint8_t reserved;
 	uint8_t base_table[0];
 } __attribute__ ((packed));
@@ -81,5 +81,5 @@
 	uint8_t cpu_signature[4];
 	uint32_t feature_flags;
-	uint32_t xxx[2];
+	uint32_t reserved[2];
 } __attribute__ ((packed));
 
@@ -102,5 +102,5 @@
 	uint8_t intr_type;
 	uint8_t poel;
-	uint8_t xxx;
+	uint8_t reserved;
 	uint8_t src_bus_id;
 	uint8_t src_bus_irq;
@@ -113,5 +113,5 @@
 	uint8_t intr_type;
 	uint8_t poel;
-	uint8_t xxx;
+	uint8_t reserved;
 	uint8_t src_bus_id;
 	uint8_t src_bus_irq;
Index: kernel/arch/ia32/include/smp/smp.h
===================================================================
--- kernel/arch/ia32/include/smp/smp.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/ia32/include/smp/smp.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -27,5 +27,5 @@
  */
 
-/** @addtogroup ia32	
+/** @addtogroup ia32
  * @{
  */
@@ -40,12 +40,18 @@
 /** SMP config opertaions interface. */
 struct smp_config_operations {
-	size_t (* cpu_count)(void);		/**< Return number of detected processors. */
-	bool (* cpu_enabled)(size_t i);	/**< Check whether the processor of index i is enabled. */
-	bool (*cpu_bootstrap)(size_t i);	/**< Check whether the processor of index i is BSP. */
-	uint8_t (*cpu_apic_id)(size_t i);		/**< Return APIC ID of the processor of index i. */
-	int (*irq_to_pin)(unsigned int irq);		/**< Return mapping between irq and APIC pin. */
+	/** Check whether a processor is enabled. */
+	bool (* cpu_enabled)(size_t);
+	
+	/** Check whether a processor is BSP. */
+	bool (*cpu_bootstrap)(size_t);
+	
+	/** Return APIC ID of a processor. */
+	uint8_t (*cpu_apic_id)(size_t);
+	
+	/** Return mapping between IRQ and APIC pin. */
+	int (*irq_to_pin)(unsigned int);
 };
 
-extern int smp_irq_to_pin(unsigned int irq);
+extern int smp_irq_to_pin(unsigned int);
 
 #endif
Index: kernel/arch/ia32/src/asm.S
===================================================================
--- kernel/arch/ia32/src/asm.S	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/ia32/src/asm.S	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -1,41 +1,41 @@
-#
-# 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.
-#
-
-## very low and hardware-level functions
-
-# Mask for interrupts 0 - 31 (bits 0 - 31) where 0 means that int has no error
-# word and 1 means interrupt with error word
-#define ERROR_WORD_INTERRUPT_LIST 0x00027d00
+/*
+ * Copyright (c) 2010 Jakub Jermar
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** Very low and hardware-level functions
+ *
+ */
+
+#include <arch/pm.h>
+#include <arch/cpu.h>
+#include <arch/mm/page.h>
 
 .text
-
 .global paging_on
 .global enable_l_apic_in_msr
-.global interrupt_handlers
 .global memsetb
 .global memsetw
@@ -45,18 +45,17 @@
 .global memcpy_to_uspace
 .global memcpy_to_uspace_failover_address
-
-
-# Wrapper for generic memsetb
+.global early_putchar
+
+/* Wrapper for generic memsetb */
 memsetb:
 	jmp _memsetb
 
-# Wrapper for generic memsetw
+/* Wrapper for generic memsetw */
 memsetw:
 	jmp _memsetw
 
-
-#define MEMCPY_DST	4
-#define MEMCPY_SRC	8
-#define MEMCPY_SIZE	12
+#define MEMCPY_DST   4
+#define MEMCPY_SRC   8
+#define MEMCPY_SIZE  12
 
 /** Copy memory to/from userspace.
@@ -68,36 +67,42 @@
  * or copy_to_uspace().
  *
- * @param MEMCPY_DST(%esp)	Destination address.
- * @param MEMCPY_SRC(%esp)	Source address.
- * @param MEMCPY_SIZE(%esp)	Size.
+ * @param MEMCPY_DST(%esp)  Destination address.
+ * @param MEMCPY_SRC(%esp)  Source address.
+ * @param MEMCPY_SIZE(%esp) Size.
  *
  * @return MEMCPY_DST(%esp) on success and 0 on failure.
+ *
  */
 memcpy:
 memcpy_from_uspace:
 memcpy_to_uspace:
-	movl %edi, %edx			/* save %edi */
-	movl %esi, %eax			/* save %esi */
+	movl %edi, %edx  /* save %edi */
+	movl %esi, %eax  /* save %esi */
 	
 	movl MEMCPY_SIZE(%esp), %ecx
-	shrl $2, %ecx			/* size / 4 */
+	shrl $2, %ecx  /* size / 4 */
 	
 	movl MEMCPY_DST(%esp), %edi
 	movl MEMCPY_SRC(%esp), %esi
 	
-	rep movsl			/* copy whole words */
-
+	/* Copy whole words */
+	rep movsl
+	
 	movl MEMCPY_SIZE(%esp), %ecx
-	andl $3, %ecx			/* size % 4 */
+	andl $3, %ecx  /* size % 4 */
 	jz 0f
 	
-	rep movsb			/* copy the rest byte by byte */
-
-0:
-	movl %edx, %edi
-	movl %eax, %esi
-	movl MEMCPY_DST(%esp), %eax	/* MEMCPY_DST(%esp), success */
-	ret
-	
+	/* Copy the rest byte by byte */
+	rep movsb
+	
+	0:
+	
+		movl %edx, %edi
+		movl %eax, %esi
+		
+		/* MEMCPY_DST(%esp), success */
+		movl MEMCPY_DST(%esp), %eax
+		ret
+
 /*
  * We got here from as_page_fault() after the memory operations
@@ -108,26 +113,31 @@
 	movl %edx, %edi
 	movl %eax, %esi
-	xorl %eax, %eax			/* return 0, failure */
+	
+	/* Return 0, failure */
+	xorl %eax, %eax
 	ret
 
-## Turn paging on
-#
-# Enable paging and write-back caching in CR0.
-#
+/** Turn paging on
+ *
+ * Enable paging and write-back caching in CR0.
+ *
+ */
 paging_on:
 	movl %cr0, %edx
-	orl $(1 << 31), %edx		# paging on
-	# clear Cache Disable and not Write Though
+	orl $(1 << 31), %edx  /* paging on */
+	
+	/* Clear Cache Disable and not Write Though */
 	andl $~((1 << 30) | (1 << 29)), %edx
-	movl %edx,%cr0
+	movl %edx, %cr0
 	jmp 0f
-0:
-	ret
-
-
-## Enable local APIC
-#
-# Enable local APIC in MSR.
-#
+	
+	0:
+		ret
+
+/** Enable local APIC
+ *
+ * Enable local APIC in MSR.
+ *
+ */
 enable_l_apic_in_msr:
 	movl $0x1b, %ecx
@@ -138,13 +148,29 @@
 	ret
 
-# Clear nested flag
-# overwrites %ecx
-.macro CLEAR_NT_FLAG
-	pushfl
-	pop %ecx
-	and $0xffffbfff, %ecx
-	push %ecx
-	popfl
-.endm	
+#define ISTATE_OFFSET_EDX         0
+#define ISTATE_OFFSET_ECX         4
+#define ISTATE_OFFSET_EBX         8
+#define ISTATE_OFFSET_ESI         12
+#define ISTATE_OFFSET_EDI         16 
+#define ISTATE_OFFSET_EBP         20
+#define ISTATE_OFFSET_EAX         24
+#define ISTATE_OFFSET_EBP_FRAME   28
+#define ISTATE_OFFSET_EIP_FRAME   32
+#define ISTATE_OFFSET_GS          36
+#define ISTATE_OFFSET_FS          40
+#define ISTATE_OFFSET_ES          44
+#define ISTATE_OFFSET_DS          48
+#define ISTATE_OFFSET_ERROR_WORD  52
+#define ISTATE_OFFSET_EIP         56
+#define ISTATE_OFFSET_CS          60
+#define ISTATE_OFFSET_EFLAGS      64
+#define ISTATE_OFFSET_ESP         68
+#define ISTATE_OFFSET_SS          72
+
+/*
+ * Size of the istate structure without the hardware-saved part
+ * and without the error word.
+ */
+#define ISTATE_SOFT_SIZE  52
 
 /*
@@ -159,164 +185,437 @@
 .global sysenter_handler
 sysenter_handler:
-	sti
-	pushl %ebp	# remember user stack
-	pushl %edi	# remember return user address
-
-	pushl %gs	# remember TLS
-
-	pushl %eax	# syscall number
-	subl $8, %esp	# unused sixth and fifth argument
-	pushl %esi	# fourth argument
-	pushl %ebx	# third argument
-	pushl %ecx	# second argument
-	pushl %edx	# first argument
-
-	movw $16, %ax
+
+	/*
+	 * Note that the space needed for the istate structure has been
+	 * preallocated on the stack by before_thread_runs_arch().
+	 */
+
+	/*
+	 * Save the return address and the userspace stack in the istate
+	 * structure on locations that would normally be taken by them.
+	 */
+	movl %ebp, ISTATE_OFFSET_ESP(%esp)
+	movl %edi, ISTATE_OFFSET_EIP(%esp)
+
+	/*
+	 * Push syscall arguments onto the stack
+	 */
+	movl %eax, ISTATE_OFFSET_EAX(%esp)
+	movl %ebx, ISTATE_OFFSET_EBX(%esp)
+	movl %ecx, ISTATE_OFFSET_ECX(%esp)
+	movl %edx, ISTATE_OFFSET_EDX(%esp)
+	movl %esi, ISTATE_OFFSET_ESI(%esp)
+	movl %edi, ISTATE_OFFSET_EDI(%esp)	/* observability; not needed */
+	movl %ebp, ISTATE_OFFSET_EBP(%esp)	/* observability; not needed */
+	
+	/*
+	 * Fake up the stack trace linkage.
+	 */
+	movl %edi, ISTATE_OFFSET_EIP_FRAME(%esp)
+	movl $0, ISTATE_OFFSET_EBP_FRAME(%esp)
+	leal ISTATE_OFFSET_EBP_FRAME(%esp), %ebp
+
+	/*
+	 * Save TLS.
+	 */
+	movl %gs, %edx
+	movl %edx, ISTATE_OFFSET_GS(%esp)
+
+	/*
+	 * Switch to kernel selectors.
+	 */
+	movw $(GDT_SELECTOR(KDATA_DES)), %ax
 	movw %ax, %ds
 	movw %ax, %es
-
+	
+	/*
+	 * Sanitize EFLAGS.
+	 *
+	 * SYSENTER does not clear the NT flag, which could thus proliferate
+	 * from here to the IRET instruction via a context switch and result
+	 * in crash.
+	 *
+	 * SYSENTER does not clear DF, which the ABI assumes to be cleared.
+	 *
+	 * SYSENTER clears IF, which we would like to be set for syscalls.
+	 *
+	 */
+	pushl $(EFLAGS_IF)  /* specify EFLAGS bits that we want to set */
+	popfl	            /* set bits from the mask, clear or ignore others */
+
+	call syscall_handler
+	
+	/*
+	 * Restore TLS.
+	 */
+	movl ISTATE_OFFSET_GS(%esp), %edx
+	movl %edx, %gs
+	
+	/*
+	 * Prepare return address and userspace stack for SYSEXIT.
+	 */
+	movl ISTATE_OFFSET_EIP(%esp), %edx
+	movl ISTATE_OFFSET_ESP(%esp), %ecx
+
+	sysexit   /* return to userspace */
+
+/*
+ * This is the legacy syscall handler using the interrupt mechanism.
+ */
+.global int_syscall
+int_syscall:
+	subl $(ISTATE_SOFT_SIZE + 4), %esp
+
+	/*
+	 * Push syscall arguments onto the stack
+	 *
+	 * NOTE: The idea behind the order of arguments passed
+	 *       in registers is to use all scratch registers
+	 *       first and preserved registers next. An optimized
+	 *       libc syscall wrapper can make use of this setup.
+	 *       The istate structure is arranged in the way to support
+	 *       this idea.
+	 *
+	 */
+	movl %eax, ISTATE_OFFSET_EAX(%esp)
+	movl %ebx, ISTATE_OFFSET_EBX(%esp)
+	movl %ecx, ISTATE_OFFSET_ECX(%esp)
+	movl %edx, ISTATE_OFFSET_EDX(%esp)
+	movl %edi, ISTATE_OFFSET_EDI(%esp)
+	movl %esi, ISTATE_OFFSET_ESI(%esp)
+	movl %ebp, ISTATE_OFFSET_EBP(%esp)
+
+	/*
+	 * Save the selector registers.
+	 */
+	movl %gs, %ecx
+	movl %fs, %edx
+
+	movl %ecx, ISTATE_OFFSET_GS(%esp)
+	movl %edx, ISTATE_OFFSET_FS(%esp)
+
+	movl %es, %ecx
+	movl %ds, %edx
+		
+	movl %ecx, ISTATE_OFFSET_ES(%esp)
+	movl %edx, ISTATE_OFFSET_DS(%esp)
+
+	/*
+	 * Switch to kernel selectors.
+	 */
+	movl $(GDT_SELECTOR(KDATA_DES)), %eax
+	movl %eax, %ds
+	movl %eax, %es
+		
+	movl $0, ISTATE_OFFSET_EBP_FRAME(%esp)
+	movl ISTATE_OFFSET_EIP(%esp), %eax
+	movl %eax, ISTATE_OFFSET_EIP_FRAME(%esp)
+	leal ISTATE_OFFSET_EBP_FRAME(%esp), %ebp
+		
 	cld
+		
+	/* Call syscall_handler(edx, ecx, ebx, esi, edi, ebp, eax) */
 	call syscall_handler
-	addl $28, %esp	# remove arguments from stack
-
-	pop %gs		# restore TLS
-
-	pop %edx	# prepare return EIP for SYSEXIT
-	pop %ecx	# prepare userspace ESP for SYSEXIT
-
-	sysexit		# return to userspace
-
-
-## Declare interrupt handlers
-#
-# Declare interrupt handlers for n interrupt
-# vectors starting at vector i.
-#
-# The handlers setup data segment registers
-# and call exc_dispatch().
-#
-#define INTERRUPT_ALIGN 64
-.macro handler i n
-
-.ifeq \i - 0x30     # Syscall handler
-	pushl %ds
-	pushl %es
-	pushl %fs
-	pushl %gs
-
-	#
-	# Push syscall arguments onto the stack
-	#
-	# NOTE: The idea behind the order of arguments passed in registers is to
-	#	use all scratch registers first and preserved registers next.
-	#	An optimized libc syscall wrapper can make use of this setup.
-	#
-	pushl %eax
-	pushl %ebp
-	pushl %edi
-	pushl %esi
-	pushl %ebx
-	pushl %ecx
-	pushl %edx
-	
-	# we must fill the data segment registers
-	movw $16, %ax
-	movw %ax, %ds
-	movw %ax, %es
-	
-	cld
-	sti
-	# syscall_handler(edx, ecx, ebx, esi, edi, ebp, eax)
-	call syscall_handler   
-	cli
-	addl $28, %esp         # clean-up of parameters
-	
-	popl %gs
-	popl %fs
-	popl %es
-	popl %ds
-	
-	CLEAR_NT_FLAG
+			
+	/*
+	 * Restore the selector registers.
+	 */
+	movl ISTATE_OFFSET_GS(%esp), %ecx
+	movl ISTATE_OFFSET_FS(%esp), %edx
+
+	movl %ecx, %gs
+	movl %edx, %fs
+
+	movl ISTATE_OFFSET_ES(%esp), %ecx
+	movl ISTATE_OFFSET_DS(%esp), %edx
+			
+	movl %ecx, %es
+	movl %edx, %ds
+			
+	/*
+	 * Restore the preserved registers the handler cloberred itself
+	 * (i.e. EBP).
+	 */
+	movl ISTATE_OFFSET_EBP(%esp), %ebp
+			
+	addl $(ISTATE_SOFT_SIZE + 4), %esp
 	iret
-.else	
-	/*
-	 * This macro distinguishes between two versions of ia32 exceptions.
-	 * One version has error word and the other does not have it.
-	 * The latter version fakes the error word on the stack so that the
-	 * handlers and istate_t can be the same for both types.
+		
+/**
+ * Mask for interrupts 0 - 31 (bits 0 - 31) where 0 means that int
+ * has no error word  and 1 means interrupt with error word
+ *
+ */
+#define ERROR_WORD_INTERRUPT_LIST  0x00027d00
+
+.macro handler i
+.global int_\i
+int_\i:
+	/*
+	 * This macro distinguishes between two versions of ia32
+	 * exceptions. One version has error word and the other
+	 * does not have it. The latter version fakes the error
+	 * word on the stack so that the handlers and istate_t
+	 * can be the same for both types.
 	 */
 	.iflt \i - 32
 		.if (1 << \i) & ERROR_WORD_INTERRUPT_LIST
-			/* 
-			 * With error word, do nothing
+			/*
+			 * Exception with error word.
 			 */
-                .else
-                        /*
-                         * Version without error word,
-                         */
-			subl $4, %esp
-                .endif
-        .else
-                /*
-                 * Version without error word,
-                 */
-		subl $4, %esp
+			subl $ISTATE_SOFT_SIZE, %esp
+		.else
+			/*
+			 * Exception without error word: fake up one
+			 */
+			subl $(ISTATE_SOFT_SIZE + 4), %esp
+		.endif
+	.else
+		/*
+		 * Interrupt: fake up an error word 
+		 */
+		subl $(ISTATE_SOFT_SIZE + 4), %esp
 	.endif
 	
-	pushl %ds
-	pushl %es
-	pushl %fs
-	pushl %gs
-
+	/*
+	 * Save the general purpose registers.
+	 */
+	movl %eax, ISTATE_OFFSET_EAX(%esp)
+	movl %ebx, ISTATE_OFFSET_EBX(%esp)
+	movl %ecx, ISTATE_OFFSET_ECX(%esp)
+	movl %edx, ISTATE_OFFSET_EDX(%esp)
+	movl %edi, ISTATE_OFFSET_EDI(%esp)
+	movl %esi, ISTATE_OFFSET_ESI(%esp)
+	movl %ebp, ISTATE_OFFSET_EBP(%esp)
+	
+	/*
+	 * Save the selector registers.
+	 */
+	movl %gs, %ecx
+	movl %fs, %edx
+
+	movl %ecx, ISTATE_OFFSET_GS(%esp)
+	movl %edx, ISTATE_OFFSET_FS(%esp)
+
+	movl %es, %ecx
+	movl %ds, %edx
+	
+	movl %ecx, ISTATE_OFFSET_ES(%esp)
+	movl %edx, ISTATE_OFFSET_DS(%esp)
+	
+	/*
+	 * Switch to kernel selectors.
+	 */
+	movl $(GDT_SELECTOR(KDATA_DES)), %eax
+	movl %eax, %ds
+	movl %eax, %es
+	
+	/*
+	 * Imitate a regular stack frame linkage.
+	 * Stop stack traces here if we came from userspace.
+	 */
+	xorl %eax, %eax
+	cmpl $(GDT_SELECTOR(KTEXT_DES)), ISTATE_OFFSET_CS(%esp)
+	cmovnzl %eax, %ebp
+
+	movl %ebp, ISTATE_OFFSET_EBP_FRAME(%esp)
+	movl ISTATE_OFFSET_EIP(%esp), %eax
+	movl %eax, ISTATE_OFFSET_EIP_FRAME(%esp)
+	leal ISTATE_OFFSET_EBP_FRAME(%esp), %ebp
+		
+	cld
+		
+	pushl %esp   /* pass istate address */
+	pushl $(\i)  /* pass intnum */
+		
+	/* Call exc_dispatch(intnum, istate) */
+	call exc_dispatch
+		
+	addl $8, %esp  /* clear arguments from the stack */
+		
+	/*
+	 * Restore the selector registers.
+	 */
+	movl ISTATE_OFFSET_GS(%esp), %ecx
+	movl ISTATE_OFFSET_FS(%esp), %edx
+
+	movl %ecx, %gs
+	movl %edx, %fs
+
+	movl ISTATE_OFFSET_ES(%esp), %ecx
+	movl ISTATE_OFFSET_DS(%esp), %edx
+		
+	movl %ecx, %es
+	movl %edx, %ds
+		
+	/*
+	 * Restore the scratch registers and the preserved
+	 * registers the handler cloberred itself
+	 * (i.e. EBP).
+	 */
+	movl ISTATE_OFFSET_EAX(%esp), %eax
+	movl ISTATE_OFFSET_ECX(%esp), %ecx
+	movl ISTATE_OFFSET_EDX(%esp), %edx
+	movl ISTATE_OFFSET_EBP(%esp), %ebp
+		
+	addl $(ISTATE_SOFT_SIZE + 4), %esp
+	iret
+.endm
+
+#define LIST_0_63 \
+	0, 1, 2, 3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,\
+	28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,\
+	53,54,55,56,57,58,59,60,61,62,63
+
+interrupt_handlers:
+.irp cnt, LIST_0_63 
+	handler \cnt
+.endr
+
+/** Print Unicode character to EGA display.
+ *
+ * If CONFIG_EGA is undefined or CONFIG_FB is defined
+ * then this function does nothing.
+ *
+ * Since the EGA can only display Extended ASCII (usually
+ * ISO Latin 1) characters, some of the Unicode characters
+ * can be displayed in a wrong way. Only newline and backspace
+ * are interpreted, all other characters (even unprintable) are
+ * printed verbatim.
+ *
+ * @param %ebp+0x08 Unicode character to be printed.
+ *
+ */
+early_putchar:
+	
+#if ((defined(CONFIG_EGA)) && (!defined(CONFIG_FB)))
+	
+	/* Prologue, save preserved registers */
 	pushl %ebp
-	pushl %edx
-	pushl %ecx
-	pushl %eax
-	
-	# we must fill the data segment registers
-	movw $16, %ax
-	movw %ax, %ds
-	movw %ax, %es
-
-	# stop stack traces here
-	xorl %ebp, %ebp
-
-	pushl %esp          # *istate
-	pushl $(\i)         # intnum
-	call exc_dispatch   # excdispatch(intnum, *istate)
-	addl $8, %esp       # Clear arguments from stack
-
-	CLEAR_NT_FLAG # Modifies %ecx
-	
-	popl %eax
-	popl %ecx
-	popl %edx
-	popl %ebp
-	
-	popl %gs
-	popl %fs
-	popl %es
-	popl %ds
-
-	addl $4, %esp	# Skip error word, no matter whether real or fake.
-	iret
-.endif
-
-	.align INTERRUPT_ALIGN
-	.if (\n- \i) - 1
-	handler "(\i + 1)", \n
-	.endif
-.endm
-
-# keep in sync with pm.h !!!
-IDT_ITEMS = 64
-.align INTERRUPT_ALIGN
-interrupt_handlers:
-h_start:
-	handler 0 IDT_ITEMS
-h_end:
-
-.data
-.global interrupt_handler_size
-
-interrupt_handler_size: .long (h_end - h_start) / IDT_ITEMS
+	movl %esp, %ebp
+	pushl %ebx
+	pushl %esi
+	pushl %edi
+	
+	movl $(PA2KA(0xb8000)), %edi  /* base of EGA text mode memory */
+	xorl %eax, %eax
+	
+	/* Read bits 8 - 15 of the cursor address */
+	movw $0x3d4, %dx
+	movb $0xe, %al
+	outb %al, %dx
+	
+	movw $0x3d5, %dx
+	inb %dx, %al
+	shl $8, %ax
+	
+	/* Read bits 0 - 7 of the cursor address */
+	movw $0x3d4, %dx
+	movb $0xf, %al
+	outb %al, %dx
+	
+	movw $0x3d5, %dx
+	inb %dx, %al
+	
+	/* Sanity check for the cursor on screen */
+	cmp $2000, %ax
+	jb early_putchar_cursor_ok
+	
+		movw $1998, %ax
+	
+	early_putchar_cursor_ok:
+	
+	movw %ax, %bx
+	shl $1, %eax
+	addl %eax, %edi
+	
+	movl 0x08(%ebp), %eax
+	
+	cmp $0x0a, %al
+	jne early_putchar_backspace
+	
+		/* Interpret newline */
+		
+		movw %bx, %ax  /* %bx -> %dx:%ax */
+		xorw %dx, %dx
+		
+		movw $80, %cx
+		idivw %cx, %ax  /* %dx = %bx % 80 */
+		
+		/* %bx <- %bx + 80 - (%bx % 80) */
+		addw %cx, %bx
+		subw %dx, %bx
+		
+		jmp early_putchar_skip
+	
+	early_putchar_backspace:
+	
+		cmp $0x08, %al
+		jne early_putchar_print
+		
+		/* Interpret backspace */
+		
+		cmp $0x0000, %bx
+		je early_putchar_skip
+		
+		dec %bx
+		jmp early_putchar_skip
+	
+	early_putchar_print:
+	
+		/* Print character */
+		
+		movb $0x0e, %ah  /* black background, yellow foreground */
+		stosw
+		inc %bx
+	
+	early_putchar_skip:
+	
+	/* Sanity check for the cursor on the last line */
+	cmp $2000, %bx
+	jb early_putchar_no_scroll
+	
+		/* Scroll the screen (24 rows) */
+		movl $(PA2KA(0xb80a0)), %esi
+		movl $(PA2KA(0xb8000)), %edi
+		movl $960, %ecx
+		rep movsl
+		
+		/* Clear the 24th row */
+		xorl %eax, %eax
+		movl $40, %ecx
+		rep stosl
+		
+		/* Go to row 24 */
+		movw $1920, %bx
+	
+	early_putchar_no_scroll:
+	
+	/* Write bits 8 - 15 of the cursor address */
+	movw $0x3d4, %dx
+	movb $0xe, %al
+	outb %al, %dx
+	
+	movw $0x3d5, %dx
+	movb %bh, %al
+	outb %al, %dx
+	
+	/* Write bits 0 - 7 of the cursor address */
+	movw $0x3d4, %dx
+	movb $0xf, %al
+	outb %al, %dx
+	
+	movw $0x3d5, %dx
+	movb %bl, %al
+	outb %al, %dx
+	
+	/* Epilogue, restore preserved registers */
+	popl %edi
+	popl %esi
+	popl %ebx
+	leave
+	
+#endif
+	
+	ret
+
Index: kernel/arch/ia32/src/bios/bios.c
===================================================================
--- kernel/arch/ia32/src/bios/bios.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/ia32/src/bios/bios.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -27,5 +27,5 @@
  */
 
-/** @addtogroup ia32	
+/** @addtogroup ia32
  * @{
  */
@@ -35,4 +35,6 @@
 #include <arch/bios/bios.h>
 #include <typedefs.h>
+
+#define BIOS_EBDA_PTR  0x40e
 
 uintptr_t ebda = 0;
Index: kernel/arch/ia32/src/boot/boot.S
===================================================================
--- kernel/arch/ia32/src/boot/boot.S	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/ia32/src/boot/boot.S	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -1,30 +1,30 @@
-#
-# Copyright (c) 2001-2004 Jakub Jermar
-# Copyright (c) 2005-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.
-#
+/*
+ * Copyright (c) 2001 Jakub Jermar
+ * Copyright (c) 2005 Martin Decky
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
 
 #include <arch/boot/boot.h>
@@ -34,9 +34,29 @@
 #include <arch/cpuid.h>
 
-#define START_STACK (BOOT_OFFSET - BOOT_STACK_SIZE)
+#define START_STACK  (BOOT_OFFSET - BOOT_STACK_SIZE)
 
 .section K_TEXT_START, "ax"
 
 .code32
+
+.macro pm_error msg
+	movl \msg, %esi
+	jmp pm_error_halt
+.endm
+
+.macro pm_status msg
+#ifdef CONFIG_EGA
+	pushl %esi
+	movl \msg, %esi
+	call pm_early_puts
+	popl %esi
+#endif
+.endm
+
+.macro pm2_status msg
+	pushl \msg
+	call early_puts
+.endm
+
 .align 4
 .global multiboot_image_start
@@ -44,5 +64,5 @@
 	.long MULTIBOOT_HEADER_MAGIC
 	.long MULTIBOOT_HEADER_FLAGS
-	.long -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS)  # checksum
+	.long -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS)  /* checksum */
 	.long multiboot_header
 	.long unmapped_ktext_start
@@ -53,23 +73,31 @@
 multiboot_image_start:
 	cld
-	movl $START_STACK, %esp     # initialize stack pointer
-	lgdt KA2PA(bootstrap_gdtr)  # initialize Global Descriptor Table register
-	
-	movw $gdtselector(KDATA_DES), %cx
+	
+	/* Initialize stack pointer */
+	movl $START_STACK, %esp
+	
+	/* Initialize Global Descriptor Table register */
+	lgdtl bootstrap_gdtr
+	
+	/* Kernel data + stack */
+	movw $GDT_SELECTOR(KDATA_DES), %cx
 	movw %cx, %es
 	movw %cx, %fs
 	movw %cx, %gs
-	movw %cx, %ds               # kernel data + stack
+	movw %cx, %ds
 	movw %cx, %ss
 	
-	jmpl $gdtselector(KTEXT_DES), $multiboot_meeting_point
+	jmpl $GDT_SELECTOR(KTEXT_DES), $multiboot_meeting_point
 	multiboot_meeting_point:
 	
-	movl %eax, grub_eax         # save parameters from GRUB
+	/* Save GRUB arguments */
+	movl %eax, grub_eax
 	movl %ebx, grub_ebx
+	
+	pm_status $status_prot
 	
 	movl $(INTEL_CPUID_LEVEL), %eax
 	cpuid
-	cmp $0x0, %eax              # any function > 0?
+	cmp $0x0, %eax  /* any function > 0? */
 	jbe pse_unsupported
 	
@@ -80,26 +108,31 @@
 	
 	pse_unsupported:
-		movl $pse_msg, %esi
-		jmp error_halt
+		
+		pm_error $err_pse
 	
 	pse_supported:
 	
 #include "vesa_prot.inc"
-
-	# map kernel and turn paging on
+	
+	/* Map kernel and turn paging on */
 	call map_kernel
 	
-	# call arch_pre_main(grub_eax, grub_ebx)
+	/* Create the first stack frame */
+	pushl $0
+	movl %esp, %ebp
+	
+	pm2_status $status_prot2
+	
+	/* Call arch_pre_main(grub_eax, grub_ebx) */
 	pushl grub_ebx
 	pushl grub_eax
 	call arch_pre_main
-
-	# Create the first stack frame
-	pushl $0
-	movl %esp, %ebp
-	
+	
+	pm2_status $status_main
+	
+	/* Call main_bsp() */
 	call main_bsp
 	
-	# not reached
+	/* Not reached */
 	cli
 	hlt0:
@@ -107,13 +140,15 @@
 		jmp hlt0
 
+/** Setup mapping for the kernel.
+ *
+ * Setup mapping for both the unmapped and mapped sections
+ * of the kernel. For simplicity, we map the entire 4G space.
+ *
+ */
 .global map_kernel
 map_kernel:
-	#
-	# Here we setup mapping for both the unmapped and mapped sections of the kernel.
-	# For simplicity, we map the entire 4G space.
-	#
 	movl %cr4, %ecx
-	orl $(1 << 4), %ecx                 # turn PSE on
-	andl $(~(1 << 5)), %ecx             # turn PAE off
+	orl $(1 << 4), %ecx      /* PSE on */
+	andl $(~(1 << 5)), %ecx  /* PAE off */
 	movl %ecx, %cr4
 	
@@ -126,6 +161,8 @@
 		movl $((1 << 7) | (1 << 1) | (1 << 0)), %eax
 		orl %ebx, %eax
-		movl %eax, (%esi, %ecx, 4)      # mapping 0x00000000 + %ecx * 4M => 0x00000000 + %ecx * 4M
-		movl %eax, (%edi, %ecx, 4)      # mapping 0x80000000 + %ecx * 4M => 0x00000000 + %ecx * 4M
+		/* Mapping 0x00000000 + %ecx * 4M => 0x00000000 + %ecx * 4M */
+		movl %eax, (%esi, %ecx, 4)
+		/* Mapping 0x80000000 + %ecx * 4M => 0x00000000 + %ecx * 4M */
+		movl %eax, (%edi, %ecx, 4)
 		addl $(4 * 1024 * 1024), %ebx
 		
@@ -137,14 +174,25 @@
 	
 	movl %cr0, %ebx
-	orl $(1 << 31), %ebx                # turn paging on
+	orl $(1 << 31), %ebx  /* paging on */
 	movl %ebx, %cr0
 	ret
 
-# Print string from %esi to EGA display (in red) and halt
-error_halt:
-	movl $0xb8000, %edi         # base of EGA text mode memory
+/** Print string to EGA display (in light red) and halt.
+ *
+ * Should be executed from 32 bit protected mode with paging
+ * turned off. Stack is not required. This routine is used even
+ * if CONFIG_EGA is not enabled. Since we are going to halt the
+ * CPU anyway, it is always better to at least try to print
+ * some hints.
+ *
+ * @param %esi NULL-terminated string to print.
+ *
+ */
+pm_error_halt:
+	movl $0xb8000, %edi  /* base of EGA text mode memory */
 	xorl %eax, %eax
 	
-	movw $0x3d4, %dx            # read bits 8 - 15 of the cursor address
+	/* Read bits 8 - 15 of the cursor address */
+	movw $0x3d4, %dx
 	movb $0xe, %al
 	outb %al, %dx
@@ -154,5 +202,6 @@
 	shl $8, %ax
 	
-	movw $0x3d4, %dx            # read bits 0 - 7 of the cursor address
+	/* Read bits 0 - 7 of the cursor address */
+	movw $0x3d4, %dx
 	movb $0xf, %al
 	outb %al, %dx
@@ -161,10 +210,11 @@
 	inb %dx, %al
 	
-	cmp $1920, %ax
-	jbe cursor_ok
-	
-		movw $1920, %ax         # sanity check for the cursor on the last line
-	
-	cursor_ok:
+	/* Sanity check for the cursor on screen */
+	cmp $2000, %ax
+	jb err_cursor_ok
+	
+		movw $1998, %ax
+	
+	err_cursor_ok:
 	
 	movw %ax, %bx
@@ -172,16 +222,40 @@
 	addl %eax, %edi
 	
-	movw $0x0c00, %ax           # black background, light red foreground
-	
-	ploop:
+	err_ploop:
 		lodsb
+		
 		cmp $0, %al
-		je ploop_end
+		je err_ploop_end
+		
+		movb $0x0c, %ah  /* black background, light red foreground */
 		stosw
+		
+		/* Sanity check for the cursor on the last line */
 		inc %bx
-		jmp ploop
-	ploop_end:
-	
-	movw $0x3d4, %dx            # write bits 8 - 15 of the cursor address
+		cmp $2000, %bx
+		jb err_ploop
+		
+		/* Scroll the screen (24 rows) */
+		movl %esi, %edx
+		movl $0xb80a0, %esi
+		movl $0xb8000, %edi
+		movl $960, %ecx
+		rep movsl
+		
+		/* Clear the 24th row */
+		xorl %eax, %eax
+		movl $40, %ecx
+		rep stosl
+		
+		/* Go to row 24 */
+		movl %edx, %esi
+		movl $0xb8f00, %edi
+		movw $1920, %bx
+		
+		jmp err_ploop
+	err_ploop_end:
+	
+	/* Write bits 8 - 15 of the cursor address */
+	movw $0x3d4, %dx
 	movb $0xe, %al
 	outb %al, %dx
@@ -191,5 +265,6 @@
 	outb %al, %dx
 	
-	movw $0x3d4, %dx            # write bits 0 - 7 of the cursor address
+	/* Write bits 0 - 7 of the cursor address */
+	movw $0x3d4, %dx
 	movb $0xf, %al
 	outb %al, %dx
@@ -204,4 +279,232 @@
 		jmp hlt1
 
+/** Print string to EGA display (in light green).
+ *
+ * Should be called from 32 bit protected mode with paging
+ * turned off. A stack space of at least 24 bytes is required,
+ * but the function does not establish a stack frame.
+ *
+ * Macros such as pm_status take care that this function
+ * is used only when CONFIG_EGA is enabled.
+ *
+ * @param %esi NULL-terminated string to print.
+ *
+ */
+pm_early_puts:
+	pushl %eax
+	pushl %ebx
+	pushl %ecx
+	pushl %edx
+	pushl %edi
+	
+	movl $0xb8000, %edi  /* base of EGA text mode memory */
+	xorl %eax, %eax
+	
+	/* Read bits 8 - 15 of the cursor address */
+	movw $0x3d4, %dx
+	movb $0xe, %al
+	outb %al, %dx
+	
+	movw $0x3d5, %dx
+	inb %dx, %al
+	shl $8, %ax
+	
+	/* Read bits 0 - 7 of the cursor address */
+	movw $0x3d4, %dx
+	movb $0xf, %al
+	outb %al, %dx
+	
+	movw $0x3d5, %dx
+	inb %dx, %al
+	
+	/* Sanity check for the cursor on screen */
+	cmp $2000, %ax
+	jb pm_puts_cursor_ok
+	
+		movw $1998, %ax
+	
+	pm_puts_cursor_ok:
+	
+	movw %ax, %bx
+	shl $1, %eax
+	addl %eax, %edi
+	
+	pm_puts_ploop:
+		lodsb
+		
+		cmp $0, %al
+		je pm_puts_ploop_end
+		
+		movb $0x0a, %ah  /* black background, light green foreground */
+		stosw
+		
+		/* Sanity check for the cursor on the last line */
+		inc %bx
+		cmp $2000, %bx
+		jb pm_puts_ploop
+		
+		/* Scroll the screen (24 rows) */
+		movl %esi, %edx
+		movl $0xb80a0, %esi
+		movl $0xb8000, %edi
+		movl $960, %ecx
+		rep movsl
+		
+		/* Clear the 24th row */
+		xorl %eax, %eax
+		movl $40, %ecx
+		rep stosl
+		
+		/* Go to row 24 */
+		movl %edx, %esi
+		movl $0xb8f00, %edi
+		movw $1920, %bx
+		
+		jmp pm_puts_ploop
+	pm_puts_ploop_end:
+	
+	/* Write bits 8 - 15 of the cursor address */
+	movw $0x3d4, %dx
+	movb $0xe, %al
+	outb %al, %dx
+	
+	movw $0x3d5, %dx
+	movb %bh, %al
+	outb %al, %dx
+	
+	/* Write bits 0 - 7 of the cursor address */
+	movw $0x3d4, %dx
+	movb $0xf, %al
+	outb %al, %dx
+	
+	movw $0x3d5, %dx
+	movb %bl, %al
+	outb %al, %dx
+	
+	popl %edi
+	popl %edx
+	popl %ecx
+	popl %ebx
+	popl %eax
+	
+	ret
+
+/** Print string to EGA display.
+ *
+ * Should be called from 32 bit protected mode (with paging
+ * enabled and stack established). This function is ABI compliant.
+ *
+ * If CONFIG_EGA is undefined or CONFIG_FB is defined
+ * then this function does nothing.
+ *
+ * @param %ebp+0x08 NULL-terminated string to print.
+ *
+ */
+early_puts:
+	
+#if ((defined(CONFIG_EGA)) && (!defined(CONFIG_FB)))
+	
+	/* Prologue, save preserved registers */
+	pushl %ebp
+	movl %esp, %ebp
+	pushl %ebx
+	pushl %esi
+	pushl %edi
+	
+	movl 0x08(%ebp), %esi
+	movl $(PA2KA(0xb8000)), %edi  /* base of EGA text mode memory */
+	xorl %eax, %eax
+	
+	/* Read bits 8 - 15 of the cursor address */
+	movw $0x3d4, %dx
+	movb $0xe, %al
+	outb %al, %dx
+	
+	movw $0x3d5, %dx
+	inb %dx, %al
+	shl $8, %ax
+	
+	/* Read bits 0 - 7 of the cursor address */
+	movw $0x3d4, %dx
+	movb $0xf, %al
+	outb %al, %dx
+	
+	movw $0x3d5, %dx
+	inb %dx, %al
+	
+	/* Sanity check for the cursor on screen */
+	cmp $2000, %ax
+	jb early_puts_cursor_ok
+	
+		movw $1998, %ax
+	
+	early_puts_cursor_ok:
+	
+	movw %ax, %bx
+	shl $1, %eax
+	addl %eax, %edi
+	
+	early_puts_ploop:
+		lodsb
+		
+		cmp $0, %al
+		je early_puts_ploop_end
+		
+		movb $0x0e, %ah  /* black background, yellow foreground */
+		stosw
+		
+		/* Sanity check for the cursor on the last line */
+		inc %bx
+		cmp $2000, %bx
+		jb early_puts_ploop
+		
+		/* Scroll the screen (24 rows) */
+		movl %esi, %edx
+		movl $(PA2KA(0xb80a0)), %esi
+		movl $(PA2KA(0xb8000)), %edi
+		movl $960, %ecx
+		rep movsl
+		
+		/* Clear the 24th row */
+		xorl %eax, %eax
+		movl $40, %ecx
+		rep stosl
+		
+		/* Go to row 24 */
+		movl %edx, %esi
+		movl $(PA2KA(0xb8f00)), %edi
+		movw $1920, %bx
+		
+		jmp early_puts_ploop
+	early_puts_ploop_end:
+	
+	/* Write bits 8 - 15 of the cursor address */
+	movw $0x3d4, %dx
+	movb $0xe, %al
+	outb %al, %dx
+	
+	movw $0x3d5, %dx
+	movb %bh, %al
+	outb %al, %dx
+	
+	/* Write bits 0 - 7 of the cursor address */
+	movw $0x3d4, %dx
+	movb $0xf, %al
+	outb %al, %dx
+	
+	movw $0x3d5, %dx
+	movb %bl, %al
+	outb %al, %dx
+	
+	/* Epilogue, restore preserved registers */
+	popl %edi
+	popl %esi
+	popl %ebx
+	leave
+	
+#endif
+	
+	ret
+
 #include "vesa_real.inc"
 
@@ -212,4 +515,8 @@
 	.space 4096, 0
 
+bootstrap_gdtr:
+	.word GDT_SELECTOR(GDT_ITEMS)
+	.long KA2PA(gdt)
+
 grub_eax:
 	.long 0
@@ -218,5 +525,17 @@
 	.long 0
 
-pse_msg:
+err_pse:
 	.asciz "Page Size Extension not supported. System halted."
 
+status_prot:
+	.asciz "[prot] "
+status_vesa_copy:
+	.asciz "[vesa_copy] "
+status_grub_cmdline:
+	.asciz "[grub_cmdline] "
+status_vesa_real:
+	.asciz "[vesa_real] "
+status_prot2:
+	.asciz "[prot2] "
+status_main:
+	.asciz "[main] "
Index: kernel/arch/ia32/src/boot/vesa_prot.inc
===================================================================
--- kernel/arch/ia32/src/boot/vesa_prot.inc	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/ia32/src/boot/vesa_prot.inc	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -5,5 +5,7 @@
 #define MBINFO_OFFSET_CMDLINE   16
 
-	# copy real mode VESA initialization code
+	/* Copy real mode VESA initialization code */
+	
+	pm_status $status_vesa_copy
 	
 	mov $vesa_init, %esi
@@ -12,5 +14,7 @@
 	rep movsb
 	
-	# check for GRUB command line
+	/* Check for GRUB command line */
+	
+	pm_status $status_grub_cmdline
 	
 	mov grub_eax, %eax
@@ -23,5 +27,5 @@
 	jnc no_cmdline
 	
-	# skip the kernel path in command line
+	/* Skip the kernel path in command line */
 	
 	mov MBINFO_OFFSET_CMDLINE(%ebx), %esi
@@ -52,5 +56,5 @@
 	space_loop_done:
 	
-	# copy at most 23 characters from command line
+	/* Copy at most 23 characters from command line */
 	
 	mov $VESA_INIT_SEGMENT << 4, %edi
@@ -68,5 +72,5 @@
 	cmd_loop_done:
 	
-	# zero termination
+	/* Zero termination */
 	
 	xor %eax, %eax
@@ -75,5 +79,7 @@
 	no_cmdline:
 	
-	# jump to the real mode
+	/* Jump to the real mode */
+	
+	pm_status $status_vesa_real
 	
 	mov $VESA_INIT_SEGMENT << 4, %edi
@@ -81,5 +87,5 @@
 	
 	vesa_meeting_point:
-		# returned back to protected mode
+		/* Returned back to protected mode */
 		
 		mov %ax, KA2PA(vesa_scanline)
Index: kernel/arch/ia32/src/boot/vesa_real.inc
===================================================================
--- kernel/arch/ia32/src/boot/vesa_real.inc	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/ia32/src/boot/vesa_real.inc	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -30,6 +30,6 @@
 .code32
 vesa_init:
-	jmp $gdtselector(VESA_INIT_DES), $vesa_init_real - vesa_init
-	
+	jmp $GDT_SELECTOR(VESA_INIT_DES), $vesa_init_real - vesa_init
+
 .code16
 vesa_init_real:
@@ -55,5 +55,5 @@
 	pushl %eax
 	
-	# parse default mode string
+	/* Parse default mode string */
 	
 	mov $default_mode - vesa_init, %di
@@ -65,5 +65,5 @@
 		mov (%di), %al
 		
-		# check for digit
+		/* Check for digit */
 		
 		cmp $'0', %al
@@ -75,5 +75,5 @@
 		sub $'0', %al
 		
-		# multiply default_width by 10 and add digit
+		/* Multiply default_width by 10 and add digit */
 		
 		mov default_width - vesa_init, %bx
@@ -96,5 +96,5 @@
 		mov (%di), %al
 		
-		# check for digit
+		/* Check for digit */
 		
 		cmp $'0', %al
@@ -106,5 +106,5 @@
 		sub $'0', %al
 		
-		# multiply default_height by 10 and add digit
+		/* Multiply default_height by 10 and add digit */
 		
 		mov default_height - vesa_init, %bx
@@ -127,5 +127,5 @@
 		mov (%di), %al
 		
-		# check for digit
+		/* Check for digit */
 		
 		cmp $'0', %al
@@ -137,5 +137,5 @@
 		sub $'0', %al
 		
-		# multiply default_bpp by 10 and add digit
+		/* Multiply default_bpp by 10 and add digit */
 		
 		mov default_bpp - vesa_init, %bx
@@ -167,5 +167,6 @@
 	
 	next_mode:
-		# try next mode
+		/* Try next mode */
+		
 		mov %gs:(%si), %cx
 		cmp $VESA_END_OF_MODES, %cx
@@ -186,5 +187,8 @@
 		jne no_mode
 		
-		# check for proper attributes (supported, color, graphics, linear framebuffer)
+		/*
+		 * Check for proper attributes (supported,
+		 * color, graphics, linear framebuffer).
+		 */
 		
 		mov VESA_MODE_ATTRIBUTES_OFFSET(%di), %ax
@@ -193,5 +197,5 @@
 		jne next_mode
 		
-		# check for proper resolution
+		/* Check for proper resolution */
 		
 		mov default_width - vesa_init, %ax
@@ -203,5 +207,5 @@
 		jne next_mode
 		
-		# check for proper bpp
+		/* Check for proper bpp */
 		
 		mov default_bpp - vesa_init, %al
@@ -213,5 +217,5 @@
 		jne next_mode
 		
-		# for 24 bpp modes accept also 32 bit bpp
+		/* For 24 bpp modes accept also 32 bit bpp */
 		
 		mov $32, %al
@@ -230,5 +234,5 @@
 		jnz no_mode
 		
-		# set 3:2:3 VGA palette
+		/* Set 3:2:3 VGA palette */
 		
 		mov VESA_MODE_BPP_OFFSET(%di), %al
@@ -241,8 +245,10 @@
 		mov $0x100, %ecx
 		
-		bt $5, %ax              # test if VGA compatible registers are present
+		/* Test if VGA compatible registers are present */
+		bt $5, %ax
 		jnc vga_compat
 		
-			# try VESA routine to set palette
+			/* Use VESA routine to set the palette */
+			
 			mov $VESA_SET_PALETTE, %ax
 			xor %bl, %bl
@@ -254,14 +260,16 @@
 		
 		vga_compat:
-			# try VGA registers to set palette
-			movw $0x3c6, %dx    # set palette mask
+			
+			/* Use VGA registers to set the palette */
+			
+			movw $0x3c6, %dx  /* set palette mask */
 			movb $0xff, %al
 			outb %al, %dx
 			
-			movw $0x3c8, %dx    # first index to set
+			movw $0x3c8, %dx  /* first index to set */
 			xor %al, %al
 			outb %al, %dx
 			
-			movw $0x3c9, %dx    # data port
+			movw $0x3c9, %dx  /* data port */
 			
 			vga_loop:
@@ -284,10 +292,12 @@
 		vga_not_set:
 		
-		# store mode parameters
-		#  eax = bpp[8] scanline[16]
-		#  ebx = width[16]  height[16]
-		#  edx = red_mask[8] red_pos[8] green_mask[8] green_pos[8]
-		#  esi = blue_mask[8] blue_pos[8]
-		#  edi = linear frame buffer
+		/*
+		 * Store mode parameters:
+		 *  eax = bpp[8] scanline[16]
+		 *  ebx = width[16]  height[16]
+		 *  edx = red_mask[8] red_pos[8] green_mask[8] green_pos[8]
+		 *  esi = blue_mask[8] blue_pos[8]
+		 *  edi = linear frame buffer
+		 */
 		
 		mov VESA_MODE_BPP_OFFSET(%di), %al
@@ -325,8 +335,10 @@
 		vesa_leave_real2:
 		
-			ljmpl $gdtselector(KTEXT32_DES), $(vesa_init_protected - vesa_init + VESA_INIT_SEGMENT << 4)
+			ljmpl $GDT_SELECTOR(KTEXT32_DES), $(vesa_init_protected - vesa_init + VESA_INIT_SEGMENT << 4)
 	
 	no_mode:
-		# no prefered mode found
+		
+		/* No prefered mode found */
+		
 		mov $0x111, %cx
 		push %di
@@ -339,13 +351,15 @@
 		cmp $VESA_OK, %al
 		jnz text_mode
-		jz set_mode             # force relative jump
+		jz set_mode  /* force relative jump */
 	
 	text_mode:
-		# reset to EGA text mode (because of problems with VESA)
+		
+		/* Reset to EGA text mode (because of problems with VESA) */
+		
 		mov $0x0003, %ax
 		int $0x10
 		mov $0xffffffff, %edi
 		xor %ax, %ax
-		jz vesa_leave_real      # force relative jump
+		jz vesa_leave_real  /* force relative jump */
 
 vga323:
Index: kernel/arch/ia32/src/boot/vesa_ret.inc
===================================================================
--- kernel/arch/ia32/src/boot/vesa_ret.inc	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/ia32/src/boot/vesa_ret.inc	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -1,12 +1,16 @@
 .code32
 vesa_init_protected:
-	movw $gdtselector(KDATA_DES), %cx
+	cld
+	
+	/* Initialize stack pointer */
+	movl $START_STACK, %esp
+	
+	/* Kernel data + stack */
+	movw $GDT_SELECTOR(KDATA_DES), %cx
 	movw %cx, %es
 	movw %cx, %fs
 	movw %cx, %gs
-	movw %cx, %ds               # kernel data + stack
+	movw %cx, %ds
 	movw %cx, %ss
 	
-	movl $START_STACK, %esp     # initialize stack pointer
-	
-	jmpl $gdtselector(KTEXT_DES), $vesa_meeting_point
+	jmpl $GDT_SELECTOR(KTEXT_DES), $vesa_meeting_point
Index: kernel/arch/ia32/src/ddi/ddi.c
===================================================================
--- kernel/arch/ia32/src/ddi/ddi.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/ia32/src/ddi/ddi.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -50,34 +50,31 @@
  * Interrupts are disabled and task is locked.
  *
- * @param task Task.
+ * @param task   Task.
  * @param ioaddr Startign I/O space address.
- * @param size Size of the enabled I/O range.
+ * @param size   Size of the enabled I/O range.
  *
  * @return 0 on success or an error code from errno.h.
+ *
  */
 int ddi_iospace_enable_arch(task_t *task, uintptr_t ioaddr, size_t size)
 {
-	size_t bits;
-
-	bits = ioaddr + size;
+	size_t bits = ioaddr + size;
 	if (bits > IO_PORTS)
 		return ENOENT;
-
+	
 	if (task->arch.iomap.bits < bits) {
-		bitmap_t oldiomap;
-		uint8_t *newmap;
-	
 		/*
 		 * The I/O permission bitmap is too small and needs to be grown.
 		 */
 		
-		newmap = (uint8_t *) malloc(BITS2BYTES(bits), FRAME_ATOMIC);
+		uint8_t *newmap = (uint8_t *) malloc(BITS2BYTES(bits), FRAME_ATOMIC);
 		if (!newmap)
 			return ENOMEM;
 		
+		bitmap_t oldiomap;
 		bitmap_initialize(&oldiomap, task->arch.iomap.map,
 		    task->arch.iomap.bits);
 		bitmap_initialize(&task->arch.iomap, newmap, bits);
-
+		
 		/*
 		 * Mark the new range inaccessible.
@@ -85,9 +82,9 @@
 		bitmap_set_range(&task->arch.iomap, oldiomap.bits,
 		    bits - oldiomap.bits);
-
+		
 		/*
 		 * In case there really existed smaller iomap,
 		 * copy its contents and deallocate it.
-		 */		
+		 */
 		if (oldiomap.bits) {
 			bitmap_copy(&task->arch.iomap, &oldiomap,
@@ -96,15 +93,15 @@
 		}
 	}
-
+	
 	/*
 	 * Enable the range and we are done.
 	 */
 	bitmap_clear_range(&task->arch.iomap, (size_t) ioaddr, (size_t) size);
-
+	
 	/*
 	 * Increment I/O Permission bitmap generation counter.
 	 */
 	task->arch.iomapver++;
-
+	
 	return 0;
 }
@@ -116,23 +113,20 @@
  *
  * Interrupts must be disabled prior this call.
+ *
  */
 void io_perm_bitmap_install(void)
 {
-	size_t bits;
-	ptr_16_32_t cpugdtr;
-	descriptor_t *gdt_p;
-	size_t ver;
-
 	/* First, copy the I/O Permission Bitmap. */
-	spinlock_lock(&TASK->lock);
-	ver = TASK->arch.iomapver;
-	if ((bits = TASK->arch.iomap.bits)) {
+	irq_spinlock_lock(&TASK->lock, false);
+	size_t ver = TASK->arch.iomapver;
+	size_t bits = TASK->arch.iomap.bits;
+	if (bits) {
+		ASSERT(TASK->arch.iomap.map);
+		
 		bitmap_t iomap;
-		task_t *task = TASK;
-	
-		ASSERT(TASK->arch.iomap.map);
 		bitmap_initialize(&iomap, CPU->arch.tss->iomap,
 		    TSS_IOMAP_SIZE * 8);
-		bitmap_copy(&iomap, &task->arch.iomap, task->arch.iomap.bits);
+		bitmap_copy(&iomap, &TASK->arch.iomap, TASK->arch.iomap.bits);
+		
 		/*
 		 * It is safe to set the trailing eight bits because of the
@@ -141,15 +135,17 @@
 		bitmap_set_range(&iomap, ALIGN_UP(TASK->arch.iomap.bits, 8), 8);
 	}
-	spinlock_unlock(&TASK->lock);
-
+	irq_spinlock_unlock(&TASK->lock, false);
+	
 	/*
 	 * Second, adjust TSS segment limit.
 	 * Take the extra ending byte with all bits set into account.
 	 */
+	ptr_16_32_t cpugdtr;
 	gdtr_store(&cpugdtr);
-	gdt_p = (descriptor_t *) cpugdtr.base;
+	
+	descriptor_t *gdt_p = (descriptor_t *) cpugdtr.base;
 	gdt_setlimit(&gdt_p[TSS_DES], TSS_BASIC_SIZE + BITS2BYTES(bits));
 	gdtr_load(&cpugdtr);
-
+	
 	/*
 	 * Before we load new TSS limit, the current TSS descriptor
@@ -157,5 +153,5 @@
 	 */
 	gdt_p[TSS_DES].access = AR_PRESENT | AR_TSS | DPL_KERNEL;
-	tr_load(gdtselector(TSS_DES));
+	tr_load(GDT_SELECTOR(TSS_DES));
 	
 	/*
Index: rnel/arch/ia32/src/debug/panic.s
===================================================================
--- kernel/arch/ia32/src/debug/panic.s	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ 	(revision )
@@ -1,34 +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.
-#
-
-.text
-.global panic_printf
-
-panic_printf:
-	movl $halt, (%esp)	# fake stack to make printf return to halt
-	jmp printf
Index: kernel/arch/ia32/src/debug/stacktrace.c
===================================================================
--- kernel/arch/ia32/src/debug/stacktrace.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/ia32/src/debug/stacktrace.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -40,38 +40,38 @@
 #define FRAME_OFFSET_RA		1
 
-bool kernel_frame_pointer_validate(uintptr_t fp)
+bool kernel_stack_trace_context_validate(stack_trace_context_t *ctx)
 {
-	return fp != 0;
+	return ctx->fp != 0;
 }
 
-bool kernel_frame_pointer_prev(uintptr_t fp, uintptr_t *prev)
+bool kernel_frame_pointer_prev(stack_trace_context_t *ctx, uintptr_t *prev)
 {
-	uint32_t *stack = (void *) fp;
+	uint32_t *stack = (void *) ctx->fp;
 	*prev = stack[FRAME_OFFSET_FP_PREV];
 	return true;
 }
 
-bool kernel_return_address_get(uintptr_t fp, uintptr_t *ra)
+bool kernel_return_address_get(stack_trace_context_t *ctx, uintptr_t *ra)
 {
-	uint32_t *stack = (void *) fp;
+	uint32_t *stack = (void *) ctx->fp;
 	*ra = stack[FRAME_OFFSET_RA];
 	return true;
 }
 
-bool uspace_frame_pointer_validate(uintptr_t fp)
+bool uspace_stack_trace_context_validate(stack_trace_context_t *ctx)
 {
-	return fp != 0;
+	return ctx->fp != 0;
 }
 
-bool uspace_frame_pointer_prev(uintptr_t fp, uintptr_t *prev)
+bool uspace_frame_pointer_prev(stack_trace_context_t *ctx, uintptr_t *prev)
 {
 	return !copy_from_uspace((void *) prev,
-	    (uint32_t *) fp + FRAME_OFFSET_FP_PREV, sizeof(*prev));
+	    (uint32_t *) ctx->fp + FRAME_OFFSET_FP_PREV, sizeof(*prev));
 }
 
-bool uspace_return_address_get(uintptr_t fp, uintptr_t *ra)
+bool uspace_return_address_get(stack_trace_context_t *ctx, uintptr_t *ra)
 {
-	return !copy_from_uspace((void *) ra, (uint32_t *) fp + FRAME_OFFSET_RA,
-	    sizeof(*ra));
+	return !copy_from_uspace((void *) ra,
+	    (uint32_t *) ctx->fp + FRAME_OFFSET_RA, sizeof(*ra));
 }
 
Index: kernel/arch/ia32/src/drivers/i8254.c
===================================================================
--- kernel/arch/ia32/src/drivers/i8254.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/ia32/src/drivers/i8254.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -54,9 +54,12 @@
 #include <ddi/device.h>
 
-#define CLK_PORT1	((ioport8_t *)0x40)
-#define CLK_PORT4	((ioport8_t *)0x43)
+#define CLK_PORT1  ((ioport8_t *) 0x40)
+#define CLK_PORT4  ((ioport8_t *) 0x43)
 
-#define CLK_CONST	1193180
-#define MAGIC_NUMBER	1194
+#define CLK_CONST     1193180
+#define MAGIC_NUMBER  1194
+
+#define LOOPS  150000
+#define SHIFT  11
 
 static irq_t i8254_irq;
@@ -75,7 +78,7 @@
 	 * lock. We just release it, call clock() and then reacquire it again.
 	 */
-	spinlock_unlock(&irq->lock);
+	irq_spinlock_unlock(&irq->lock, false);
 	clock();
-	spinlock_lock(&irq->lock);
+	irq_spinlock_lock(&irq->lock, false);
 }
 
@@ -102,13 +105,6 @@
 }
 
-#define LOOPS 150000
-#define SHIFT 11
 void i8254_calibrate_delay_loop(void)
 {
-	uint64_t clk1, clk2;
-	uint32_t t1, t2, o1, o2;
-	uint8_t not_ok;
-
-
 	/*
 	 * One-shot timer. Count-down from 0xffff at 1193180Hz
@@ -118,5 +114,9 @@
 	pio_write_8(CLK_PORT1, 0xff);
 	pio_write_8(CLK_PORT1, 0xff);
-
+	
+	uint8_t not_ok;
+	uint32_t t1;
+	uint32_t t2;
+	
 	do {
 		/* will read both status and count */
@@ -126,34 +126,34 @@
 		t1 |= pio_read_8(CLK_PORT1) << 8;
 	} while (not_ok);
-
+	
 	asm_delay_loop(LOOPS);
-
+	
 	pio_write_8(CLK_PORT4, 0xd2);
 	t2 = pio_read_8(CLK_PORT1);
 	t2 |= pio_read_8(CLK_PORT1) << 8;
-
+	
 	/*
 	 * We want to determine the overhead of the calibrating mechanism.
 	 */
 	pio_write_8(CLK_PORT4, 0xd2);
-	o1 = pio_read_8(CLK_PORT1);
+	uint32_t o1 = pio_read_8(CLK_PORT1);
 	o1 |= pio_read_8(CLK_PORT1) << 8;
-
+	
 	asm_fake_loop(LOOPS);
-
+	
 	pio_write_8(CLK_PORT4, 0xd2);
-	o2 = pio_read_8(CLK_PORT1);
+	uint32_t o2 = pio_read_8(CLK_PORT1);
 	o2 |= pio_read_8(CLK_PORT1) << 8;
-
+	
 	CPU->delay_loop_const =
 	    ((MAGIC_NUMBER * LOOPS) / 1000) / ((t1 - t2) - (o1 - o2)) +
 	    (((MAGIC_NUMBER * LOOPS) / 1000) % ((t1 - t2) - (o1 - o2)) ? 1 : 0);
-
-	clk1 = get_cycle();
+	
+	uint64_t clk1 = get_cycle();
 	delay(1 << SHIFT);
-	clk2 = get_cycle();
+	uint64_t clk2 = get_cycle();
 	
 	CPU->frequency_mhz = (clk2 - clk1) >> SHIFT;
-
+	
 	return;
 }
Index: kernel/arch/ia32/src/drivers/i8259.c
===================================================================
--- kernel/arch/ia32/src/drivers/i8259.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/ia32/src/drivers/i8259.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -27,5 +27,5 @@
  */
 
-/** @addtogroup ia32	
+/** @addtogroup ia32
  * @{
  */
@@ -45,5 +45,5 @@
 #include <interrupt.h>
 
-static void pic_spurious(int n, istate_t *istate);
+static void pic_spurious(unsigned int n, istate_t *istate);
 
 void i8259_init(void)
@@ -76,5 +76,6 @@
 	 * Register interrupt handler for the PIC spurious interrupt.
 	 */
-	exc_register(VECTOR_PIC_SPUR, "pic_spurious", (iroutine) pic_spurious);	
+	exc_register(VECTOR_PIC_SPUR, "pic_spurious", false,
+	    (iroutine_t) pic_spurious);
 
 	/*
@@ -124,5 +125,5 @@
 }
 
-void pic_spurious(int n __attribute__((unused)), istate_t *istate __attribute__((unused)))
+void pic_spurious(unsigned int n __attribute__((unused)), istate_t *istate __attribute__((unused)))
 {
 #ifdef CONFIG_DEBUG
Index: kernel/arch/ia32/src/ia32.c
===================================================================
--- kernel/arch/ia32/src/ia32.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/ia32/src/ia32.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -139,5 +139,5 @@
 {
 #ifdef CONFIG_SMP
-        if (config.cpu_active > 1) {
+	if (config.cpu_active > 1) {
 		l_apic_init();
 		l_apic_debug();
Index: kernel/arch/ia32/src/interrupt.c
===================================================================
--- kernel/arch/ia32/src/interrupt.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/ia32/src/interrupt.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -63,21 +63,19 @@
 void (* eoi_function)(void) = NULL;
 
-void decode_istate(istate_t *istate)
-{
-	const char *symbol = symtab_fmt_name_lookup(istate->eip);
-	
-	if (CPU)
-		printf("----------------EXCEPTION OCCURED (cpu%u)----------------\n", CPU->id);
-	else
-		printf("----------------EXCEPTION OCCURED----------------\n");
-	
-	printf("%%eip: %#lx (%s)\n", istate->eip, symbol);
-	printf("ERROR_WORD=%#lx\n", istate->error_word);
-	printf("%%cs=%#lx,flags=%#lx\n", istate->cs, istate->eflags);
-	printf("%%eax=%#lx, %%ecx=%#lx, %%edx=%#lx, %%esp=%p\n", istate->eax, istate->ecx, istate->edx, &istate->stack[0]);
-	printf("stack: %#lx, %#lx, %#lx, %#lx\n", istate->stack[0], istate->stack[1], istate->stack[2], istate->stack[3]);
-	printf("       %#lx, %#lx, %#lx, %#lx\n", istate->stack[4], istate->stack[5], istate->stack[6], istate->stack[7]);
-	
-	stack_trace_istate(istate);
+void istate_decode(istate_t *istate)
+{
+	printf("cs =%p\teip=%p\tefl=%p\terr=%p\n",
+	    istate->cs, istate->eip, istate->eflags, istate->error_word);
+
+	printf("ds =%p\tes =%p\tfs =%p\tgs =%p\n",
+	    istate->ds, istate->es, istate->fs, istate->gs);
+	if (istate_from_uspace(istate))
+		printf("ss =%p\n", istate->ss);
+
+	printf("eax=%p\tebx=%p\tecx=%p\tedx=%p\n",
+	    istate->eax, istate->ebx, istate->ecx, istate->edx);
+	printf("esi=%p\tedi=%p\tebp=%p\tesp=%p\n",
+	    istate->esi, istate->edi, istate->ebp,
+	    istate_from_uspace(istate) ? istate->esp : (uintptr_t)&istate->esp);
 }
 
@@ -91,30 +89,24 @@
 }
 
-static void null_interrupt(int n, istate_t *istate)
-{
-	fault_if_from_uspace(istate, "Unserviced interrupt: %d.", n);
-
-	decode_istate(istate);
-	panic("Unserviced interrupt: %d.", n);
-}
-
-static void de_fault(int n, istate_t *istate)
+static void null_interrupt(unsigned int n, istate_t *istate)
+{
+	fault_if_from_uspace(istate, "Unserviced interrupt: %u.", n);
+	panic_badtrap(istate, n, "Unserviced interrupt: %u.", n);
+}
+
+static void de_fault(unsigned int n, istate_t *istate)
 {
 	fault_if_from_uspace(istate, "Divide error.");
-
-	decode_istate(istate);
-	panic("Divide error.");
+	panic_badtrap(istate, n, "Divide error.");
 }
 
 /** General Protection Fault. */
-static void gp_fault(int n __attribute__((unused)), istate_t *istate)
+static void gp_fault(unsigned int n __attribute__((unused)), istate_t *istate)
 {
 	if (TASK) {
-		size_t ver;
+		irq_spinlock_lock(&TASK->lock, false);
+		size_t ver = TASK->arch.iomapver;
+		irq_spinlock_unlock(&TASK->lock, false);
 		
-		spinlock_lock(&TASK->lock);
-		ver = TASK->arch.iomapver;
-		spinlock_unlock(&TASK->lock);
-	
 		if (CPU->arch.iomapver_copy != ver) {
 			/*
@@ -130,44 +122,40 @@
 		fault_if_from_uspace(istate, "General protection fault.");
 	}
-
-	decode_istate(istate);
-	panic("General protection fault.");
-}
-
-static void ss_fault(int n __attribute__((unused)), istate_t *istate)
+	panic_badtrap(istate, n, "General protection fault.");
+}
+
+static void ss_fault(unsigned int n __attribute__((unused)), istate_t *istate)
 {
 	fault_if_from_uspace(istate, "Stack fault.");
-
-	decode_istate(istate);
-	panic("Stack fault.");
-}
-
-static void simd_fp_exception(int n __attribute__((unused)), istate_t *istate)
+	panic_badtrap(istate, n, "Stack fault.");
+}
+
+static void simd_fp_exception(unsigned int n __attribute__((unused)), istate_t *istate)
 {
 	uint32_t mxcsr;
-	asm (
+	asm volatile (
 		"stmxcsr %[mxcsr]\n"
 		: [mxcsr] "=m" (mxcsr)
 	);
-	fault_if_from_uspace(istate, "SIMD FP exception(19), MXCSR: %#zx.",
+	
+	fault_if_from_uspace(istate, "SIMD FP exception(19), MXCSR=%#0.8x.",
 	    (unative_t) mxcsr);
-	
-	decode_istate(istate);
-	printf("MXCSR: %#lx\n", mxcsr);
-	panic("SIMD FP exception(19).");
-}
-
-static void nm_fault(int n __attribute__((unused)), istate_t *istate __attribute__((unused)))
-{
-#ifdef CONFIG_FPU_LAZY     
+	panic_badtrap(istate, n, "SIMD FP exception, MXCSR=%#0.8x");
+}
+
+static void nm_fault(unsigned int n __attribute__((unused)),
+    istate_t *istate __attribute__((unused)))
+{
+#ifdef CONFIG_FPU_LAZY
 	scheduler_fpu_lazy_request();
 #else
 	fault_if_from_uspace(istate, "FPU fault.");
-	panic("FPU fault.");
+	panic_badtrap(istate, n, "FPU fault.");
 #endif
 }
 
 #ifdef CONFIG_SMP
-static void tlb_shootdown_ipi(int n __attribute__((unused)), istate_t *istate __attribute__((unused)))
+static void tlb_shootdown_ipi(unsigned int n __attribute__((unused)),
+    istate_t *istate __attribute__((unused)))
 {
 	trap_virtual_eoi();
@@ -177,9 +165,9 @@
 
 /** Handler of IRQ exceptions */
-static void irq_interrupt(int n, istate_t *istate __attribute__((unused)))
+static void irq_interrupt(unsigned int n, istate_t *istate __attribute__((unused)))
 {
 	ASSERT(n >= IVT_IRQBASE);
 	
-	int inum = n - IVT_IRQBASE;
+	unsigned int inum = n - IVT_IRQBASE;
 	bool ack = false;
 	ASSERT(inum < IRQ_COUNT);
@@ -191,5 +179,5 @@
 		 * The IRQ handler was found.
 		 */
-		 
+		
 		if (irq->preack) {
 			/* Send EOI before processing the interrupt */
@@ -198,5 +186,5 @@
 		}
 		irq->handler(irq);
-		spinlock_unlock(&irq->lock);
+		irq_spinlock_unlock(&irq->lock, false);
 	} else {
 		/*
@@ -204,5 +192,5 @@
 		 */
 #ifdef CONFIG_DEBUG
-		printf("cpu%u: spurious interrupt (inum=%d)\n", CPU->id, inum);
+		printf("cpu%u: spurious interrupt (inum=%u)\n", CPU->id, inum);
 #endif
 	}
@@ -214,22 +202,24 @@
 void interrupt_init(void)
 {
-	int i;
+	unsigned int i;
 	
 	for (i = 0; i < IVT_ITEMS; i++)
-		exc_register(i, "null", (iroutine) null_interrupt);
+		exc_register(i, "null", false, (iroutine_t) null_interrupt);
 	
 	for (i = 0; i < IRQ_COUNT; i++) {
 		if ((i != IRQ_PIC_SPUR) && (i != IRQ_PIC1))
-			exc_register(IVT_IRQBASE + i, "irq", (iroutine) irq_interrupt);
+			exc_register(IVT_IRQBASE + i, "irq", true,
+			    (iroutine_t) irq_interrupt);
 	}
 	
-	exc_register(0, "de_fault", (iroutine) de_fault);
-	exc_register(7, "nm_fault", (iroutine) nm_fault);
-	exc_register(12, "ss_fault", (iroutine) ss_fault);
-	exc_register(13, "gp_fault", (iroutine) gp_fault);
-	exc_register(19, "simd_fp", (iroutine) simd_fp_exception);
+	exc_register(0, "de_fault", true, (iroutine_t) de_fault);
+	exc_register(7, "nm_fault", true, (iroutine_t) nm_fault);
+	exc_register(12, "ss_fault", true, (iroutine_t) ss_fault);
+	exc_register(13, "gp_fault", true, (iroutine_t) gp_fault);
+	exc_register(19, "simd_fp", true, (iroutine_t) simd_fp_exception);
 	
 #ifdef CONFIG_SMP
-	exc_register(VECTOR_TLB_SHOOTDOWN_IPI, "tlb_shootdown", (iroutine) tlb_shootdown_ipi);
+	exc_register(VECTOR_TLB_SHOOTDOWN_IPI, "tlb_shootdown", true,
+	    (iroutine_t) tlb_shootdown_ipi);
 #endif
 }
Index: kernel/arch/ia32/src/mm/as.c
===================================================================
--- kernel/arch/ia32/src/mm/as.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/ia32/src/mm/as.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -27,5 +27,5 @@
  */
 
-/** @addtogroup ia32mm	
+/** @addtogroup ia32mm
  * @{
  */
Index: kernel/arch/ia32/src/mm/frame.c
===================================================================
--- kernel/arch/ia32/src/mm/frame.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/ia32/src/mm/frame.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -47,4 +47,7 @@
 #include <print.h>
 
+#define PHYSMEM_LIMIT32  0x07c000000ull
+#define PHYSMEM_LIMIT64  0x200000000ull
+
 size_t hardcoded_unmapped_ktext_size = 0;
 size_t hardcoded_unmapped_kdata_size = 0;
@@ -55,5 +58,5 @@
 {
 	unsigned int i;
-
+	
 	for (i = 0; i < e820counter; i++) {
 		uint64_t base = e820table[i].base_address;
@@ -61,20 +64,59 @@
 		
 #ifdef __32_BITS__
-		/* Ignore physical memory above 4 GB */
-		if ((base >> 32) != 0)
+		/*
+		 * XXX FIXME:
+		 *
+		 * Ignore zones which start above PHYSMEM_LIMIT32
+		 * or clip zones which go beyond PHYSMEM_LIMIT32.
+		 *
+		 * The PHYSMEM_LIMIT32 (2 GB - 64 MB) is a rather
+		 * arbitrary constant which allows to have at
+		 * least 64 MB in the kernel address space to
+		 * map hardware resources.
+		 *
+		 * The kernel uses fixed 1:1 identity mapping
+		 * of the physical memory with 2:2 GB split.
+		 * This is a severe limitation of the current
+		 * kernel memory management.
+		 *
+		 */
+		
+		if (base > PHYSMEM_LIMIT32)
 			continue;
 		
-		/* Clip regions above 4 GB */
-		if (((base + size) >> 32) != 0)
-			size = 0xffffffff - base;
-#endif
-
-		pfn_t pfn;
-		size_t count;
+		if (base + size > PHYSMEM_LIMIT32)
+			size = PHYSMEM_LIMIT32 - base;
+#endif
+		
+#ifdef __64_BITS__
+		/*
+		 * XXX FIXME:
+		 *
+		 * Ignore zones which start above PHYSMEM_LIMIT64
+		 * or clip zones which go beyond PHYSMEM_LIMIT64.
+		 *
+		 * The PHYSMEM_LIMIT64 (8 GB) is the size of the
+		 * fixed 1:1 identically mapped physical memory
+		 * accessible during the bootstrap process.
+		 * This is a severe limitation of the current
+		 * kernel memory management.
+		 *
+		 */
+		
+		if (base > PHYSMEM_LIMIT64)
+			continue;
+		
+		if (base + size > PHYSMEM_LIMIT64)
+			size = PHYSMEM_LIMIT64 - base;
+#endif
 		
 		if (e820table[i].type == MEMMAP_MEMORY_AVAILABLE) {
-			/* To be safe, make available zone possibly smaller */
-			pfn = ADDR2PFN(ALIGN_UP(base, FRAME_SIZE));
-			count = SIZE2FRAMES(ALIGN_DOWN(size, FRAME_SIZE));
+			/* To be safe, make the available zone possibly smaller */
+			uint64_t new_base = ALIGN_UP(base, FRAME_SIZE);
+			uint64_t new_size = ALIGN_DOWN(size - (new_base - base),
+			    FRAME_SIZE);
+			
+			pfn_t pfn = ADDR2PFN(new_base);
+			size_t count = SIZE2FRAMES(new_size);
 			
 			pfn_t conf;
@@ -87,22 +129,23 @@
 			
 			// XXX this has to be removed
-			if (last_frame < ALIGN_UP(base + size, FRAME_SIZE))
-				last_frame = ALIGN_UP(base + size, FRAME_SIZE);
-		}
-		
-		if (e820table[i].type == MEMMAP_MEMORY_RESERVED) {
-			/* To be safe, make reserved zone possibly larger */
-			pfn = ADDR2PFN(ALIGN_DOWN(base, FRAME_SIZE));
-			count = SIZE2FRAMES(ALIGN_UP(size, FRAME_SIZE));
-			
-			zone_create(pfn, count, 0, ZONE_RESERVED);
-		}
-		
-		if (e820table[i].type == MEMMAP_MEMORY_ACPI) {
-			/* To be safe, make firmware zone possibly larger */
-			pfn = ADDR2PFN(ALIGN_DOWN(base, (uintptr_t) FRAME_SIZE));
-			count = SIZE2FRAMES(ALIGN_UP(size, (uintptr_t) FRAME_SIZE));
-			
-			zone_create(pfn, count, 0, ZONE_FIRMWARE);
+			if (last_frame < ALIGN_UP(new_base + new_size, FRAME_SIZE))
+				last_frame = ALIGN_UP(new_base + new_size, FRAME_SIZE);
+		} else if ((e820table[i].type == MEMMAP_MEMORY_ACPI) ||
+		    (e820table[i].type == MEMMAP_MEMORY_NVS)) {
+			/* To be safe, make the firmware zone possibly larger */
+			uint64_t new_base = ALIGN_DOWN(base, FRAME_SIZE);
+			uint64_t new_size = ALIGN_UP(size + (base - new_base),
+			    FRAME_SIZE);
+			
+			zone_create(ADDR2PFN(new_base), SIZE2FRAMES(new_size), 0,
+			    ZONE_FIRMWARE);
+		} else {
+			/* To be safe, make the reserved zone possibly larger */
+			uint64_t new_base = ALIGN_DOWN(base, FRAME_SIZE);
+			uint64_t new_size = ALIGN_UP(size + (base - new_base),
+			    FRAME_SIZE);
+			
+			zone_create(ADDR2PFN(new_base), SIZE2FRAMES(new_size), 0,
+			    ZONE_RESERVED);
 		}
 	}
@@ -121,10 +164,9 @@
 {
 	unsigned int i;
-	const char *name;
+	printf("[base            ] [size            ] [name   ]\n");
 	
-	printf("Base               Size               Name\n");
-	printf("------------------ ------------------ ---------\n");
-		
 	for (i = 0; i < e820counter; i++) {
+		const char *name;
+		
 		if (e820table[i].type <= MEMMAP_MEMORY_UNUSABLE)
 			name = e820names[e820table[i].type];
@@ -132,5 +174,5 @@
 			name = "invalid";
 		
-		printf("%#18llx %#18llx %s\n", e820table[i].base_address,
+		printf("%#018" PRIx64 " %#018" PRIx64" %s\n", e820table[i].base_address,
 		    e820table[i].size, name);
 	}
@@ -150,5 +192,5 @@
 		    hardcoded_unmapped_kdata_size));
 #endif
-
+		
 		init_e820_memory(minconf);
 		
@@ -158,5 +200,5 @@
 #ifdef CONFIG_SMP
 		/* Reserve AP real mode bootstrap memory */
-		frame_mark_unavailable(AP_BOOT_OFFSET >> FRAME_WIDTH, 
+		frame_mark_unavailable(AP_BOOT_OFFSET >> FRAME_WIDTH,
 		    (hardcoded_unmapped_ktext_size +
 		    hardcoded_unmapped_kdata_size) >> FRAME_WIDTH);
Index: kernel/arch/ia32/src/mm/page.c
===================================================================
--- kernel/arch/ia32/src/mm/page.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/ia32/src/mm/page.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -61,4 +61,5 @@
 		 * PA2KA(identity) mapping for all frames until last_frame.
 		 */
+		page_table_lock(AS_KERNEL, true);
 		for (cur = 0; cur < last_frame; cur += FRAME_SIZE) {
 			flags = PAGE_CACHEABLE | PAGE_WRITE;
@@ -67,6 +68,7 @@
 			page_mapping_insert(AS_KERNEL, PA2KA(cur), cur, flags);
 		}
+		page_table_unlock(AS_KERNEL, true);
 		
-		exc_register(14, "page_fault", (iroutine) page_fault);
+		exc_register(14, "page_fault", true, (iroutine_t) page_fault);
 		write_cr3((uintptr_t) AS_KERNEL->genarch.page_table);
 	} else
@@ -84,8 +86,10 @@
 	uintptr_t virtaddr = PA2KA(last_frame);
 	pfn_t i;
+	page_table_lock(AS_KERNEL, true);
 	for (i = 0; i < ADDR2PFN(ALIGN_UP(size, PAGE_SIZE)); i++) {
 		uintptr_t addr = PFN2ADDR(i);
 		page_mapping_insert(AS_KERNEL, virtaddr + addr, physaddr + addr, PAGE_NOT_CACHEABLE | PAGE_WRITE);
 	}
+	page_table_unlock(AS_KERNEL, true);
 	
 	last_frame = ALIGN_UP(last_frame + size, FRAME_SIZE);
@@ -94,5 +98,5 @@
 }
 
-void page_fault(int n __attribute__((unused)), istate_t *istate)
+void page_fault(unsigned int n __attribute__((unused)), istate_t *istate)
 {
 	uintptr_t page;
@@ -111,8 +115,5 @@
 	if (as_page_fault(page, access, istate) == AS_PF_FAULT) {
 		fault_if_from_uspace(istate, "Page fault: %#x.", page);
-		
-		decode_istate(istate);
-		printf("page fault address: %#lx\n", page);
-		panic("Page fault.");
+		panic_memtrap(istate, access, page, NULL);
 	}
 }
Index: kernel/arch/ia32/src/mm/tlb.c
===================================================================
--- kernel/arch/ia32/src/mm/tlb.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/ia32/src/mm/tlb.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -27,5 +27,5 @@
  */
 
-/** @addtogroup ia32mm	
+/** @addtogroup ia32mm
  * @{
  */
Index: kernel/arch/ia32/src/pm.c
===================================================================
--- kernel/arch/ia32/src/pm.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/ia32/src/pm.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -75,6 +75,6 @@
 	/* VESA Init descriptor */
 #ifdef CONFIG_FB
-	{ 0xffff, 0, VESA_INIT_SEGMENT>>12, AR_PRESENT | AR_CODE | DPL_KERNEL, 0xf, 0, 0, 0, 0, 0 }
-#endif	
+	{ 0xffff, 0, VESA_INIT_SEGMENT >> 12, AR_PRESENT | AR_CODE | DPL_KERNEL, 0xf, 0, 0, 0, 0, 0 }
+#endif
 };
 
@@ -86,6 +86,8 @@
 
 /* gdtr is changed by kmp before next CPU is initialized */
-ptr_16_32_t bootstrap_gdtr = { .limit = sizeof(gdt), .base = KA2PA((uintptr_t) gdt) };
-ptr_16_32_t gdtr = { .limit = sizeof(gdt), .base = (uintptr_t) gdt };
+ptr_16_32_t gdtr = {
+	.limit = sizeof(gdt),
+	.base = (uintptr_t) gdt
+};
 
 void gdt_setbase(descriptor_t *d, uintptr_t base)
@@ -128,21 +130,89 @@
 
 		d->unused = 0;
-		d->selector = gdtselector(KTEXT_DES);
-
-		d->access = AR_PRESENT | AR_INTERRUPT;	/* masking interrupt */
+		d->selector = GDT_SELECTOR(KTEXT_DES);
 
 		if (i == VECTOR_SYSCALL) {
 			/*
-			 * The syscall interrupt gate must be calleable from
-			 * userland.
+			 * The syscall trap gate must be callable from
+			 * userland. Interrupts will remain enabled.
 			 */
-			d->access |= DPL_USER;
+			d->access = AR_PRESENT | AR_TRAP | DPL_USER;
+		} else {
+			/*
+			 * Other interrupts use interrupt gates which
+			 * disable interrupts.
+			 */
+			d->access = AR_PRESENT | AR_INTERRUPT;
 		}
-		
-		idt_setoffset(d, ((uintptr_t) interrupt_handlers) +
-		    i * interrupt_handler_size);
 	}
-}
-
+
+	d = &idt[0];
+	idt_setoffset(d++, (uintptr_t) &int_0);
+	idt_setoffset(d++, (uintptr_t) &int_1);
+	idt_setoffset(d++, (uintptr_t) &int_2);
+	idt_setoffset(d++, (uintptr_t) &int_3);
+	idt_setoffset(d++, (uintptr_t) &int_4);
+	idt_setoffset(d++, (uintptr_t) &int_5);
+	idt_setoffset(d++, (uintptr_t) &int_6);
+	idt_setoffset(d++, (uintptr_t) &int_7);
+	idt_setoffset(d++, (uintptr_t) &int_8);
+	idt_setoffset(d++, (uintptr_t) &int_9);
+	idt_setoffset(d++, (uintptr_t) &int_10);
+	idt_setoffset(d++, (uintptr_t) &int_11);
+	idt_setoffset(d++, (uintptr_t) &int_12);
+	idt_setoffset(d++, (uintptr_t) &int_13);
+	idt_setoffset(d++, (uintptr_t) &int_14);
+	idt_setoffset(d++, (uintptr_t) &int_15);
+	idt_setoffset(d++, (uintptr_t) &int_16);
+	idt_setoffset(d++, (uintptr_t) &int_17);
+	idt_setoffset(d++, (uintptr_t) &int_18);
+	idt_setoffset(d++, (uintptr_t) &int_19);
+	idt_setoffset(d++, (uintptr_t) &int_20);
+	idt_setoffset(d++, (uintptr_t) &int_21);
+	idt_setoffset(d++, (uintptr_t) &int_22);
+	idt_setoffset(d++, (uintptr_t) &int_23);
+	idt_setoffset(d++, (uintptr_t) &int_24);
+	idt_setoffset(d++, (uintptr_t) &int_25);
+	idt_setoffset(d++, (uintptr_t) &int_26);
+	idt_setoffset(d++, (uintptr_t) &int_27);
+	idt_setoffset(d++, (uintptr_t) &int_28);
+	idt_setoffset(d++, (uintptr_t) &int_29);
+	idt_setoffset(d++, (uintptr_t) &int_30);
+	idt_setoffset(d++, (uintptr_t) &int_31);
+	idt_setoffset(d++, (uintptr_t) &int_32);
+	idt_setoffset(d++, (uintptr_t) &int_33);
+	idt_setoffset(d++, (uintptr_t) &int_34);
+	idt_setoffset(d++, (uintptr_t) &int_35);
+	idt_setoffset(d++, (uintptr_t) &int_36);
+	idt_setoffset(d++, (uintptr_t) &int_37);
+	idt_setoffset(d++, (uintptr_t) &int_38);
+	idt_setoffset(d++, (uintptr_t) &int_39);
+	idt_setoffset(d++, (uintptr_t) &int_40);
+	idt_setoffset(d++, (uintptr_t) &int_41);
+	idt_setoffset(d++, (uintptr_t) &int_42);
+	idt_setoffset(d++, (uintptr_t) &int_43);
+	idt_setoffset(d++, (uintptr_t) &int_44);
+	idt_setoffset(d++, (uintptr_t) &int_45);
+	idt_setoffset(d++, (uintptr_t) &int_46);
+	idt_setoffset(d++, (uintptr_t) &int_47);
+	idt_setoffset(d++, (uintptr_t) &int_48);
+	idt_setoffset(d++, (uintptr_t) &int_49);
+	idt_setoffset(d++, (uintptr_t) &int_50);
+	idt_setoffset(d++, (uintptr_t) &int_51);
+	idt_setoffset(d++, (uintptr_t) &int_52);
+	idt_setoffset(d++, (uintptr_t) &int_53);
+	idt_setoffset(d++, (uintptr_t) &int_54);
+	idt_setoffset(d++, (uintptr_t) &int_55);
+	idt_setoffset(d++, (uintptr_t) &int_56);
+	idt_setoffset(d++, (uintptr_t) &int_57);
+	idt_setoffset(d++, (uintptr_t) &int_58);
+	idt_setoffset(d++, (uintptr_t) &int_59);
+	idt_setoffset(d++, (uintptr_t) &int_60);
+	idt_setoffset(d++, (uintptr_t) &int_61);
+	idt_setoffset(d++, (uintptr_t) &int_62);
+	idt_setoffset(d++, (uintptr_t) &int_63);
+
+	idt_setoffset(&idt[VECTOR_SYSCALL], (uintptr_t) &int_syscall);
+}
 
 /* Clean IOPL(12,13) and NT(14) flags in EFLAGS register */
@@ -215,5 +285,5 @@
 	 * to its own TSS. We just need to load the TR register.
 	 */
-	tr_load(gdtselector(TSS_DES));
+	tr_load(GDT_SELECTOR(TSS_DES));
 	
 	clean_IOPL_NT_flags();    /* Disable I/O on nonprivileged levels and clear NT flag. */
Index: kernel/arch/ia32/src/proc/scheduler.c
===================================================================
--- kernel/arch/ia32/src/proc/scheduler.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/ia32/src/proc/scheduler.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -38,5 +38,5 @@
 #include <proc/thread.h>
 #include <arch.h>
-#include <arch/context.h>	/* SP_DELTA */
+#include <arch/interrupt.h>
 #include <arch/pm.h>
 #include <arch/asm.h>
@@ -58,15 +58,14 @@
 void before_thread_runs_arch(void)
 {
-	uintptr_t kstk = (uintptr_t) &THREAD->kstack[THREAD_STACK_SIZE -
-	    SP_DELTA];
+	uintptr_t kstk = (uintptr_t) &THREAD->kstack[THREAD_STACK_SIZE];
 	
 	if (CPU->arch.fi.bits.sep) {
 		/* Set kernel stack for CP3 -> CPL0 switch via SYSENTER */
-		write_msr(IA32_MSR_SYSENTER_ESP, kstk);
+		write_msr(IA32_MSR_SYSENTER_ESP, kstk - sizeof(istate_t));
 	}
 	
 	/* Set kernel stack for CPL3 -> CPL0 switch via interrupt */
 	CPU->arch.tss->esp0 = kstk;
-	CPU->arch.tss->ss0 = gdtselector(KDATA_DES);
+	CPU->arch.tss->ss0 = GDT_SELECTOR(KDATA_DES);
 	
 	/* Set up TLS in GS register */
Index: kernel/arch/ia32/src/smp/apic.c
===================================================================
--- kernel/arch/ia32/src/smp/apic.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/ia32/src/smp/apic.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -53,11 +53,12 @@
  * Advanced Programmable Interrupt Controller for SMP systems.
  * Tested on:
- *	Bochs 2.0.2 - Bochs 2.2.6 with 2-8 CPUs
- *	Simics 2.0.28 - Simics 2.2.19 2-15 CPUs
- *	VMware Workstation 5.5 with 2 CPUs
- *	QEMU 0.8.0 with 2-15 CPUs
- *	ASUS P/I-P65UP5 + ASUS C-P55T2D REV. 1.41 with 2x 200Mhz Pentium CPUs
- *	ASUS PCH-DL with 2x 3000Mhz Pentium 4 Xeon (HT) CPUs
- *	MSI K7D Master-L with 2x 2100MHz Athlon MP CPUs
+ *    Bochs 2.0.2 - Bochs 2.2.6 with 2-8 CPUs
+ *    Simics 2.0.28 - Simics 2.2.19 2-15 CPUs
+ *    VMware Workstation 5.5 with 2 CPUs
+ *    QEMU 0.8.0 with 2-15 CPUs
+ *    ASUS P/I-P65UP5 + ASUS C-P55T2D REV. 1.41 with 2x 200Mhz Pentium CPUs
+ *    ASUS PCH-DL with 2x 3000Mhz Pentium 4 Xeon (HT) CPUs
+ *    MSI K7D Master-L with 2x 2100MHz Athlon MP CPUs
+ *
  */
 
@@ -69,4 +70,5 @@
  * optimize the code too much and accesses to l_apic and io_apic, that must
  * always be 32-bit, would use byte oriented instructions.
+ *
  */
 volatile uint32_t *l_apic = (uint32_t *) 0xfee00000;
@@ -74,4 +76,6 @@
 
 uint32_t apic_id_mask = 0;
+uint8_t bsp_l_apic = 0;
+
 static irq_t l_apic_timer_irq;
 
@@ -79,5 +83,5 @@
 
 #ifdef LAPIC_VERBOSE
-static char *delmod_str[] = {
+static const char *delmod_str[] = {
 	"Fixed",
 	"Lowest Priority",
@@ -90,30 +94,30 @@
 };
 
-static char *destmod_str[] = {
+static const char *destmod_str[] = {
 	"Physical",
 	"Logical"
 };
 
-static char *trigmod_str[] = {
+static const char *trigmod_str[] = {
 	"Edge",
 	"Level"
 };
 
-static char *mask_str[] = {
+static const char *mask_str[] = {
 	"Unmasked",
 	"Masked"
 };
 
-static char *delivs_str[] = {
+static const char *delivs_str[] = {
 	"Idle",
 	"Send Pending"
 };
 
-static char *tm_mode_str[] = {
+static const char *tm_mode_str[] = {
 	"One-shot",
 	"Periodic"
 };
 
-static char *intpol_str[] = {
+static const char *intpol_str[] = {
 	"Polarity High",
 	"Polarity Low"
@@ -123,8 +127,10 @@
 /** APIC spurious interrupt handler.
  *
- * @param n Interrupt vector.
+ * @param n      Interrupt vector.
  * @param istate Interrupted state.
- */
-static void apic_spurious(int n __attribute__((unused)), istate_t *istate __attribute__((unused)))
+ *
+ */
+static void apic_spurious(unsigned int n __attribute__((unused)),
+    istate_t *istate __attribute__((unused)))
 {
 #ifdef CONFIG_DEBUG
@@ -145,7 +151,20 @@
 	 * irq->lock so we just unlock it and then lock it again.
 	 */
-	spinlock_unlock(&irq->lock);
+	irq_spinlock_unlock(&irq->lock, false);
 	clock();
-	spinlock_lock(&irq->lock);
+	irq_spinlock_lock(&irq->lock, false);
+}
+
+/** Get Local APIC ID.
+ *
+ * @return Local APIC ID.
+ *
+ */
+static uint8_t l_apic_id(void)
+{
+	l_apic_id_t idreg;
+	
+	idreg.value = l_apic[L_APIC_ID];
+	return idreg.apic_id;
 }
 
@@ -153,8 +172,7 @@
 void apic_init(void)
 {
-	io_apic_id_t idreg;
-	
-	exc_register(VECTOR_APIC_SPUR, "apic_spurious", (iroutine) apic_spurious);
-
+	exc_register(VECTOR_APIC_SPUR, "apic_spurious", false,
+	    (iroutine_t) apic_spurious);
+	
 	enable_irqs_function = io_apic_enable_irqs;
 	disable_irqs_function = io_apic_disable_irqs;
@@ -179,5 +197,5 @@
 	for (i = 0; i < IRQ_COUNT; i++) {
 		int pin;
-	
+		
 		if ((pin = smp_irq_to_pin(i)) != -1)
 			io_apic_change_ioredtbl((uint8_t) pin, DEST_ALL, (uint8_t) (IVT_IRQBASE + i), LOPRI);
@@ -187,6 +205,8 @@
 	 * Ensure that io_apic has unique ID.
 	 */
+	io_apic_id_t idreg;
+	
 	idreg.value = io_apic_read(IOAPICID);
-	if ((1 << idreg.apic_id) & apic_id_mask) {	/* see if IO APIC ID is used already */
+	if ((1 << idreg.apic_id) & apic_id_mask) {  /* See if IO APIC ID is used already */
 		for (i = 0; i < APIC_ID_COUNT; i++) {
 			if (!((1 << i) & apic_id_mask)) {
@@ -197,11 +217,12 @@
 		}
 	}
-
+	
 	/*
 	 * Configure the BSP's lapic.
 	 */
 	l_apic_init();
-
-	l_apic_debug();	
+	l_apic_debug();
+	
+	bsp_l_apic = l_apic_id();
 }
 
@@ -211,4 +232,5 @@
  *
  * @return 0 on error, 1 on success.
+ *
  */
 int apic_poll_errors(void)
@@ -232,5 +254,5 @@
 	if (esr.illegal_register_address)
 		printf("Illegal Register Address\n");
-
+	
 	return !esr.err_bitmap;
 }
@@ -241,9 +263,10 @@
  *
  * @return 0 on failure, 1 on success.
+ *
  */
 int l_apic_broadcast_custom_ipi(uint8_t vector)
 {
 	icr_t icr;
-
+	
 	icr.lo = l_apic[ICRlo];
 	icr.delmod = DELMOD_FIXED;
@@ -253,7 +276,7 @@
 	icr.trigger_mode = TRIGMOD_LEVEL;
 	icr.vector = vector;
-
+	
 	l_apic[ICRlo] = icr.lo;
-
+	
 	icr.lo = l_apic[ICRlo];
 	if (icr.delivs == DELIVS_PENDING) {
@@ -262,5 +285,5 @@
 #endif
 	}
-
+	
 	return apic_poll_errors();
 }
@@ -271,13 +294,13 @@
  *
  * @return 0 on failure, 1 on success.
+ *
  */
 int l_apic_send_init_ipi(uint8_t apicid)
 {
+	/*
+	 * Read the ICR register in and zero all non-reserved fields.
+	 */
 	icr_t icr;
-	int i;
-
-	/*
-	 * Read the ICR register in and zero all non-reserved fields.
-	 */
+	
 	icr.lo = l_apic[ICRlo];
 	icr.hi = l_apic[ICRhi];
@@ -293,5 +316,5 @@
 	l_apic[ICRhi] = icr.hi;
 	l_apic[ICRlo] = icr.lo;
-
+	
 	/*
 	 * According to MP Specification, 20us should be enough to
@@ -299,8 +322,8 @@
 	 */
 	delay(20);
-
+	
 	if (!apic_poll_errors())
 		return 0;
-
+	
 	icr.lo = l_apic[ICRlo];
 	if (icr.delivs == DELIVS_PENDING) {
@@ -309,5 +332,5 @@
 #endif
 	}
-
+	
 	icr.delmod = DELMOD_INIT;
 	icr.destmod = DESTMOD_PHYS;
@@ -317,15 +340,16 @@
 	icr.vector = 0;
 	l_apic[ICRlo] = icr.lo;
-
+	
 	/*
 	 * Wait 10ms as MP Specification specifies.
 	 */
 	delay(10000);
-
+	
 	if (!is_82489DX_apic(l_apic[LAVR])) {
 		/*
 		 * If this is not 82489DX-based l_apic we must send two STARTUP IPI's.
 		 */
-		for (i = 0; i<2; i++) {
+		unsigned int i;
+		for (i = 0; i < 2; i++) {
 			icr.lo = l_apic[ICRlo];
 			icr.vector = (uint8_t) (((uintptr_t) ap_boot) >> 12); /* calculate the reset vector */
@@ -346,31 +370,26 @@
 void l_apic_init(void)
 {
+	/* Initialize LVT Error register. */
 	lvt_error_t error;
-	lvt_lint_t lint;
-	tpr_t tpr;
-	svr_t svr;
-	icr_t icr;
-	tdcr_t tdcr;
-	lvt_tm_t tm;
-	ldr_t ldr;
-	dfr_t dfr;
-	uint32_t t1, t2;
-
-	/* Initialize LVT Error register. */
+	
 	error.value = l_apic[LVT_Err];
 	error.masked = true;
 	l_apic[LVT_Err] = error.value;
-
+	
 	/* Initialize LVT LINT0 register. */
+	lvt_lint_t lint;
+	
 	lint.value = l_apic[LVT_LINT0];
 	lint.masked = true;
 	l_apic[LVT_LINT0] = lint.value;
-
+	
 	/* Initialize LVT LINT1 register. */
 	lint.value = l_apic[LVT_LINT1];
 	lint.masked = true;
 	l_apic[LVT_LINT1] = lint.value;
-
+	
 	/* Task Priority Register initialization. */
+	tpr_t tpr;
+	
 	tpr.value = l_apic[TPR];
 	tpr.pri_sc = 0;
@@ -379,4 +398,6 @@
 	
 	/* Spurious-Interrupt Vector Register initialization. */
+	svr_t svr;
+	
 	svr.value = l_apic[SVR];
 	svr.vector = VECTOR_APIC_SPUR;
@@ -384,9 +405,11 @@
 	svr.focus_checking = true;
 	l_apic[SVR] = svr.value;
-
+	
 	if (CPU->arch.family >= 6)
 		enable_l_apic_in_msr();
 	
 	/* Interrupt Command Register initialization. */
+	icr_t icr;
+	
 	icr.lo = l_apic[ICRlo];
 	icr.delmod = DELMOD_INIT;
@@ -398,9 +421,13 @@
 	
 	/* Timer Divide Configuration Register initialization. */
+	tdcr_t tdcr;
+	
 	tdcr.value = l_apic[TDCR];
 	tdcr.div_value = DIVIDE_1;
 	l_apic[TDCR] = tdcr.value;
-
+	
 	/* Program local timer. */
+	lvt_tm_t tm;
+	
 	tm.value = l_apic[LVT_Tm];
 	tm.vector = VECTOR_CLK;
@@ -408,23 +435,24 @@
 	tm.masked = false;
 	l_apic[LVT_Tm] = tm.value;
-
+	
 	/*
 	 * Measure and configure the timer to generate timer
 	 * interrupt with period 1s/HZ seconds.
 	 */
+	uint32_t t1 = l_apic[CCRT];
+	l_apic[ICRT] = 0xffffffff;
+	
+	while (l_apic[CCRT] == t1);
+	
 	t1 = l_apic[CCRT];
-	l_apic[ICRT] = 0xffffffff;
-
-	while (l_apic[CCRT] == t1)
-		;
-		
-	t1 = l_apic[CCRT];
-	delay(1000000/HZ);
-	t2 = l_apic[CCRT];
-	
-	l_apic[ICRT] = t1-t2;
+	delay(1000000 / HZ);
+	uint32_t t2 = l_apic[CCRT];
+	
+	l_apic[ICRT] = t1 - t2;
 	
 	/* Program Logical Destination Register. */
-	ASSERT(CPU->id < 8)
+	ASSERT(CPU->id < 8);
+	ldr_t ldr;
+	
 	ldr.value = l_apic[LDR];
 	ldr.id = (uint8_t) (1 << CPU->id);
@@ -432,4 +460,6 @@
 	
 	/* Program Destination Format Register for Flat mode. */
+	dfr_t dfr;
+	
 	dfr.value = l_apic[DFR];
 	dfr.model = MODEL_FLAT;
@@ -447,33 +477,33 @@
 {
 #ifdef LAPIC_VERBOSE
+	printf("LVT on cpu%" PRIs ", LAPIC ID: %" PRIu8 "\n",
+	    CPU->id, l_apic_id());
+	
 	lvt_tm_t tm;
+	tm.value = l_apic[LVT_Tm];
+	printf("LVT Tm: vector=%" PRIu8 ", %s, %s, %s\n",
+	    tm.vector, delivs_str[tm.delivs], mask_str[tm.masked],
+	    tm_mode_str[tm.mode]);
+	
 	lvt_lint_t lint;
-	lvt_error_t error;	
-	
-	printf("LVT on cpu%d, LAPIC ID: %d\n", CPU->id, l_apic_id());
-
-	tm.value = l_apic[LVT_Tm];
-	printf("LVT Tm: vector=%hhd, %s, %s, %s\n", tm.vector, delivs_str[tm.delivs], mask_str[tm.masked], tm_mode_str[tm.mode]);
 	lint.value = l_apic[LVT_LINT0];
-	printf("LVT LINT0: vector=%hhd, %s, %s, %s, irr=%d, %s, %s\n", tm.vector, delmod_str[lint.delmod], delivs_str[lint.delivs], intpol_str[lint.intpol], lint.irr, trigmod_str[lint.trigger_mode], mask_str[lint.masked]);
-	lint.value = l_apic[LVT_LINT1];	
-	printf("LVT LINT1: vector=%hhd, %s, %s, %s, irr=%d, %s, %s\n", tm.vector, delmod_str[lint.delmod], delivs_str[lint.delivs], intpol_str[lint.intpol], lint.irr, trigmod_str[lint.trigger_mode], mask_str[lint.masked]);	
+	printf("LVT LINT0: vector=%" PRIu8 ", %s, %s, %s, irr=%u, %s, %s\n",
+	    tm.vector, delmod_str[lint.delmod], delivs_str[lint.delivs],
+	    intpol_str[lint.intpol], lint.irr, trigmod_str[lint.trigger_mode],
+	    mask_str[lint.masked]);
+	
+	lint.value = l_apic[LVT_LINT1];
+	printf("LVT LINT1: vector=%" PRIu8 ", %s, %s, %s, irr=%u, %s, %s\n",
+	    tm.vector, delmod_str[lint.delmod], delivs_str[lint.delivs],
+	    intpol_str[lint.intpol], lint.irr, trigmod_str[lint.trigger_mode],
+	    mask_str[lint.masked]);
+	
+	lvt_error_t error;
 	error.value = l_apic[LVT_Err];
-	printf("LVT Err: vector=%hhd, %s, %s\n", error.vector, delivs_str[error.delivs], mask_str[error.masked]);
+	printf("LVT Err: vector=%" PRIu8 ", %s, %s\n", error.vector,
+	    delivs_str[error.delivs], mask_str[error.masked]);
 #endif
 }
 
-/** Get Local APIC ID.
- *
- * @return Local APIC ID.
- */
-uint8_t l_apic_id(void)
-{
-	l_apic_id_t idreg;
-	
-	idreg.value = l_apic[L_APIC_ID];
-	return idreg.apic_id;
-}
-
 /** Read from IO APIC register.
  *
@@ -481,4 +511,5 @@
  *
  * @return Content of the addressed IO APIC register.
+ *
  */
 uint32_t io_apic_read(uint8_t address)
@@ -495,7 +526,8 @@
  *
  * @param address IO APIC register address.
- * @param x Content to be written to the addressed IO APIC register.
- */
-void io_apic_write(uint8_t address, uint32_t x)
+ * @param val     Content to be written to the addressed IO APIC register.
+ *
+ */
+void io_apic_write(uint8_t address, uint32_t val)
 {
 	io_regsel_t regsel;
@@ -504,22 +536,26 @@
 	regsel.reg_addr = address;
 	io_apic[IOREGSEL] = regsel.value;
-	io_apic[IOWIN] = x;
+	io_apic[IOWIN] = val;
 }
 
 /** Change some attributes of one item in I/O Redirection Table.
  *
- * @param pin IO APIC pin number.
- * @param dest Interrupt destination address.
- * @param v Interrupt vector to trigger.
+ * @param pin   IO APIC pin number.
+ * @param dest  Interrupt destination address.
+ * @param vec   Interrupt vector to trigger.
  * @param flags Flags.
- */
-void io_apic_change_ioredtbl(uint8_t pin, uint8_t dest, uint8_t v, int flags)
-{
-	io_redirection_reg_t reg;
-	int dlvr = DELMOD_FIXED;
+ *
+ */
+void io_apic_change_ioredtbl(uint8_t pin, uint8_t dest, uint8_t vec,
+    unsigned int flags)
+{
+	unsigned int dlvr;
 	
 	if (flags & LOPRI)
 		dlvr = DELMOD_LOWPRI;
-
+	else
+		dlvr = DELMOD_FIXED;
+	
+	io_redirection_reg_t reg;
 	reg.lo = io_apic_read((uint8_t) (IOREDTBL + pin * 2));
 	reg.hi = io_apic_read((uint8_t) (IOREDTBL + pin * 2 + 1));
@@ -530,6 +566,6 @@
 	reg.intpol = POLARITY_HIGH;
 	reg.delmod = dlvr;
-	reg.intvec = v;
-
+	reg.intvec = vec;
+	
 	io_apic_write((uint8_t) (IOREDTBL + pin * 2), reg.lo);
 	io_apic_write((uint8_t) (IOREDTBL + pin * 2 + 1), reg.hi);
@@ -539,11 +575,9 @@
  *
  * @param irqmask Bitmask of IRQs to be masked (0 = do not mask, 1 = mask).
+ *
  */
 void io_apic_disable_irqs(uint16_t irqmask)
 {
-	io_redirection_reg_t reg;
 	unsigned int i;
-	int pin;
-	
 	for (i = 0; i < 16; i++) {
 		if (irqmask & (1 << i)) {
@@ -552,6 +586,8 @@
 			 * mapping for the respective IRQ number.
 			 */
-			pin = smp_irq_to_pin(i);
+			int pin = smp_irq_to_pin(i);
 			if (pin != -1) {
+				io_redirection_reg_t reg;
+				
 				reg.lo = io_apic_read((uint8_t) (IOREDTBL + pin * 2));
 				reg.masked = true;
@@ -566,11 +602,9 @@
  *
  * @param irqmask Bitmask of IRQs to be unmasked (0 = do not unmask, 1 = unmask).
+ *
  */
 void io_apic_enable_irqs(uint16_t irqmask)
 {
 	unsigned int i;
-	int pin;
-	io_redirection_reg_t reg;	
-	
 	for (i = 0; i < 16; i++) {
 		if (irqmask & (1 << i)) {
@@ -579,6 +613,8 @@
 			 * mapping for the respective IRQ number.
 			 */
-			pin = smp_irq_to_pin(i);
+			int pin = smp_irq_to_pin(i);
 			if (pin != -1) {
+				io_redirection_reg_t reg;
+				
 				reg.lo = io_apic_read((uint8_t) (IOREDTBL + pin * 2));
 				reg.masked = false;
Index: kernel/arch/ia32/src/smp/mps.c
===================================================================
--- kernel/arch/ia32/src/smp/mps.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/ia32/src/smp/mps.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -27,5 +27,5 @@
  */
 
-/** @addtogroup ia32	
+/** @addtogroup ia32
  * @{
  */
@@ -52,81 +52,80 @@
  */
 
-#define	FS_SIGNATURE	0x5f504d5f
-#define CT_SIGNATURE 	0x504d4350
-
-static int mps_fs_check(uint8_t *base);
-static int mps_ct_check(void);
-
-static int configure_via_ct(void);
-static int configure_via_default(uint8_t n);
-
-static int ct_processor_entry(struct __processor_entry *pr);
-static void ct_bus_entry(struct __bus_entry *bus);
-static void ct_io_apic_entry(struct __io_apic_entry *ioa);
-static void ct_io_intr_entry(struct __io_intr_entry *iointr);
-static void ct_l_intr_entry(struct __l_intr_entry *lintr);
-
-static void ct_extended_entries(void);
+#define FS_SIGNATURE  0x5f504d5f
+#define CT_SIGNATURE  0x504d4350
 
 static struct mps_fs *fs;
 static struct mps_ct *ct;
 
-struct __processor_entry *processor_entries = NULL;
-struct __bus_entry *bus_entries = NULL;
-struct __io_apic_entry *io_apic_entries = NULL;
-struct __io_intr_entry *io_intr_entries = NULL;
-struct __l_intr_entry *l_intr_entries = NULL;
-
-unsigned int processor_entry_cnt = 0;
-unsigned int bus_entry_cnt = 0;
-unsigned int io_apic_entry_cnt = 0;
-unsigned int io_intr_entry_cnt = 0;
-unsigned int l_intr_entry_cnt = 0;
-
-/*
- * Implementation of IA-32 SMP configuration interface.
- */
-static size_t get_cpu_count(void);
-static bool is_cpu_enabled(size_t i);
-static bool is_bsp(size_t i);
-static uint8_t get_cpu_apic_id(size_t i);
-static int mps_irq_to_pin(unsigned int irq);
-
+static struct __processor_entry *processor_entries = NULL;
+static struct __bus_entry *bus_entries = NULL;
+static struct __io_apic_entry *io_apic_entries = NULL;
+static struct __io_intr_entry *io_intr_entries = NULL;
+static struct __l_intr_entry *l_intr_entries = NULL;
+
+static size_t io_apic_cnt = 0;
+
+static size_t processor_entry_cnt = 0;
+static size_t bus_entry_cnt = 0;
+static size_t io_apic_entry_cnt = 0;
+static size_t io_intr_entry_cnt = 0;
+static size_t l_intr_entry_cnt = 0;
+
+static uint8_t mps_cpu_apic_id(size_t i)
+{
+	ASSERT(i < processor_entry_cnt);
+	
+	return processor_entries[i].l_apic_id;
+}
+
+static bool mps_cpu_enabled(size_t i)
+{
+	ASSERT(i < processor_entry_cnt);
+	
+	/*
+	 * FIXME: The current local APIC driver limits usable
+	 * CPU IDs to 8.
+	 *
+	 */
+	if (i > 7)
+		return false;
+	
+	return (bool) ((processor_entries[i].cpu_flags & 0x01) == 0x01);
+}
+
+static bool mps_cpu_bootstrap(size_t i)
+{
+	ASSERT(i < processor_entry_cnt);
+	
+	return (bool) ((processor_entries[i].cpu_flags & 0x02) == 0x02);
+}
+
+static int mps_irq_to_pin(unsigned int irq)
+{
+	size_t i;
+	
+	for (i = 0; i < io_intr_entry_cnt; i++) {
+		if (io_intr_entries[i].src_bus_irq == irq &&
+		    io_intr_entries[i].intr_type == 0)
+			return io_intr_entries[i].dst_io_apic_pin;
+	}
+	
+	return -1;
+}
+
+/** Implementation of IA-32 SMP configuration interface.
+ *
+ */
 struct smp_config_operations mps_config_operations = {
-	.cpu_count = get_cpu_count,
-	.cpu_enabled = is_cpu_enabled,
-	.cpu_bootstrap = is_bsp,
-	.cpu_apic_id = get_cpu_apic_id,
+	.cpu_enabled = mps_cpu_enabled,
+	.cpu_bootstrap = mps_cpu_bootstrap,
+	.cpu_apic_id = mps_cpu_apic_id,
 	.irq_to_pin = mps_irq_to_pin
 };
 
-size_t get_cpu_count(void)
-{
-	return processor_entry_cnt;
-}
-
-bool is_cpu_enabled(size_t i)
-{
-	ASSERT(i < processor_entry_cnt);
-	return (bool) ((processor_entries[i].cpu_flags & 0x01) == 0x01);
-}
-
-bool is_bsp(size_t i)
-{
-	ASSERT(i < processor_entry_cnt);
-	return (bool) ((processor_entries[i].cpu_flags & 0x02) == 0x02);
-}
-
-uint8_t get_cpu_apic_id(size_t i)
-{
-	ASSERT(i < processor_entry_cnt);
-	return processor_entries[i].l_apic_id;
-}
-
-
-/*
- * Used to check the integrity of the MP Floating Structure.
- */
-int mps_fs_check(uint8_t *base)
+/** Check the integrity of the MP Floating Structure.
+ *
+ */
+static bool mps_fs_check(uint8_t *base)
 {
 	unsigned int i;
@@ -136,112 +135,240 @@
 		sum = (uint8_t) (sum + base[i]);
 	
-	return !sum;
-}
-
-/*
- * Used to check the integrity of the MP Configuration Table.
- */
-int mps_ct_check(void)
+	return (sum == 0);
+}
+
+/** Check the integrity of the MP Configuration Table.
+ *
+ */
+static bool mps_ct_check(void)
 {
 	uint8_t *base = (uint8_t *) ct;
 	uint8_t *ext = base + ct->base_table_length;
 	uint8_t sum;
-	int i;	
-	
-	/* count the checksum for the base table */
-	for (i = 0,sum = 0; i < ct->base_table_length; i++)
+	uint16_t i;
+	
+	/* Compute the checksum for the base table */
+	for (i = 0, sum = 0; i < ct->base_table_length; i++)
 		sum = (uint8_t) (sum + base[i]);
-		
+	
 	if (sum)
-		return 0;
-		
-	/* count the checksum for the extended table */
+		return false;
+	
+	/* Compute the checksum for the extended table */
 	for (i = 0, sum = 0; i < ct->ext_table_length; i++)
 		sum = (uint8_t) (sum + ext[i]);
-		
-	return sum == ct->ext_table_checksum;
-}
-
-void mps_init(void)
-{
-	uint8_t *addr[2] = { NULL, (uint8_t *) PA2KA(0xf0000) };
-	unsigned int i, j, length[2] = { 1024, 64 * 1024 };
-	
-
+	
+	return (sum == ct->ext_table_checksum);
+}
+
+static void ct_processor_entry(struct __processor_entry *pr)
+{
 	/*
-	 * Find MP Floating Pointer Structure
-	 * 1a. search first 1K of EBDA
-	 * 1b. if EBDA is undefined, search last 1K of base memory
-	 *  2. search 64K starting at 0xf0000
+	 * Ignore processors which are not marked enabled.
 	 */
-
-	addr[0] = (uint8_t *) PA2KA(ebda ? ebda : 639 * 1024);
-	for (i = 0; i < 2; i++) {
-		for (j = 0; j < length[i]; j += 16) {
-			if (*((uint32_t *) &addr[i][j]) ==
-			    FS_SIGNATURE && mps_fs_check(&addr[i][j])) {
-				fs = (struct mps_fs *) &addr[i][j];
-				goto fs_found;
-			}
+	if ((pr->cpu_flags & (1 << 0)) == 0)
+		return;
+	
+	apic_id_mask |= (1 << pr->l_apic_id);
+}
+
+static void ct_bus_entry(struct __bus_entry *bus __attribute__((unused)))
+{
+#ifdef MPSCT_VERBOSE
+	char buf[7];
+	
+	memcpy((void *) buf, (void *) bus->bus_type, 6);
+	buf[6] = 0;
+	
+	printf("MPS: bus=%" PRIu8 " (%s)\n", bus->bus_id, buf);
+#endif
+}
+
+static void ct_io_apic_entry(struct __io_apic_entry *ioa)
+{
+	/* This I/O APIC is marked unusable */
+	if ((ioa->io_apic_flags & 1) == 0)
+		return;
+	
+	if (io_apic_cnt++ > 0) {
+		/*
+		 * Multiple I/O APICs are currently not supported.
+		 */
+		return;
+	}
+	
+	io_apic = (uint32_t *) (uintptr_t) ioa->io_apic;
+}
+
+static void ct_io_intr_entry(struct __io_intr_entry *iointr
+    __attribute__((unused)))
+{
+#ifdef MPSCT_VERBOSE
+	printf("MPS: ");
+	
+	switch (iointr->intr_type) {
+	case 0:
+		printf("INT");
+		break;
+	case 1:
+		printf("NMI");
+		break;
+	case 2:
+		printf("SMI");
+		break;
+	case 3:
+		printf("ExtINT");
+		break;
+	}
+	
+	printf(", ");
+	
+	switch (iointr->poel & 3) {
+	case 0:
+		printf("bus-like");
+		break;
+	case 1:
+		printf("active high");
+		break;
+	case 2:
+		printf("reserved");
+		break;
+	case 3:
+		printf("active low");
+		break;
+	}
+	
+	printf(", ");
+	
+	switch ((iointr->poel >> 2) & 3) {
+	case 0:
+		printf("bus-like");
+		break;
+	case 1:
+		printf("edge-triggered");
+		break;
+	case 2:
+		printf("reserved");
+		break;
+	case 3:
+		printf("level-triggered");
+		break;
+	}
+	
+	printf(", bus=%" PRIu8 " irq=%" PRIu8 " io_apic=%" PRIu8" pin=%"
+	    PRIu8 "\n", iointr->src_bus_id, iointr->src_bus_irq,
+	    iointr->dst_io_apic_id, iointr->dst_io_apic_pin);
+#endif
+}
+
+static void ct_l_intr_entry(struct __l_intr_entry *lintr
+    __attribute__((unused)))
+{
+#ifdef MPSCT_VERBOSE
+	printf("MPS: ");
+	
+	switch (lintr->intr_type) {
+	case 0:
+		printf("INT");
+		break;
+	case 1:
+		printf("NMI");
+		break;
+	case 2:
+		printf("SMI");
+		break;
+	case 3:
+		printf("ExtINT");
+		break;
+	}
+	
+	printf(", ");
+	
+	switch (lintr->poel & 3) {
+	case 0:
+		printf("bus-like");
+		break;
+	case 1:
+		printf("active high");
+		break;
+	case 2:
+		printf("reserved");
+		break;
+	case 3:
+		printf("active low");
+		break;
+	}
+	
+	printf(", ");
+	
+	switch ((lintr->poel >> 2) & 3) {
+	case 0:
+		printf("bus-like");
+		break;
+	case 1:
+		printf("edge-triggered");
+		break;
+	case 2:
+		printf("reserved");
+		break;
+	case 3:
+		printf("level-triggered");
+		break;
+	}
+	
+	printf(", bus=%" PRIu8 " irq=%" PRIu8 " l_apic=%" PRIu8" pin=%"
+	    PRIu8 "\n", lintr->src_bus_id, lintr->src_bus_irq,
+	    lintr->dst_l_apic_id, lintr->dst_l_apic_pin);
+#endif
+}
+
+static void ct_extended_entries(void)
+{
+	uint8_t *ext = (uint8_t *) ct + ct->base_table_length;
+	uint8_t *cur;
+	
+	for (cur = ext; cur < ext + ct->ext_table_length;
+	    cur += cur[CT_EXT_ENTRY_LEN]) {
+		switch (cur[CT_EXT_ENTRY_TYPE]) {
+		default:
+			printf("MPS: Skipping MP Configuration Table extended "
+			    "entry type %" PRIu8 "\n", cur[CT_EXT_ENTRY_TYPE]);
 		}
 	}
-
-	return;
-	
-fs_found:
-	printf("%p: MPS Floating Pointer Structure\n", fs);
-
-	if (fs->config_type == 0 && fs->configuration_table) {
-		if (fs->mpfib2 >> 7) {
-			printf("%s: PIC mode not supported\n", __func__);
-			return;
-		}
-
-		ct = (struct mps_ct *)PA2KA((uintptr_t)fs->configuration_table);
-		config.cpu_count = configure_via_ct();
-	} 
-	else
-		config.cpu_count = configure_via_default(fs->config_type);
-
-	return;
-}
-
-int configure_via_ct(void)
-{
-	uint8_t *cur;
-	unsigned int i, cnt;
-		
+}
+
+static void configure_via_ct(void)
+{
 	if (ct->signature != CT_SIGNATURE) {
-		printf("%s: bad ct->signature\n", __func__);
-		return 1;
-	}
+		printf("MPS: Wrong ct->signature\n");
+		return;
+	}
+	
 	if (!mps_ct_check()) {
-		printf("%s: bad ct checksum\n", __func__);
-		return 1;
-	}
+		printf("MPS: Wrong ct checksum\n");
+		return;
+	}
+	
 	if (ct->oem_table) {
-		printf("%s: ct->oem_table not supported\n", __func__);
-		return 1;
-	}
-	
-	l_apic = (uint32_t *)(uintptr_t)ct->l_apic;
-
-	cnt = 0;
-	cur = &ct->base_table[0];
+		printf("MPS: ct->oem_table not supported\n");
+		return;
+	}
+	
+	l_apic = (uint32_t *) (uintptr_t) ct->l_apic;
+	
+	uint8_t *cur = &ct->base_table[0];
+	uint16_t i;
+	
 	for (i = 0; i < ct->entry_count; i++) {
 		switch (*cur) {
-		/* Processor entry */
-		case 0:	
+		case 0:  /* Processor entry */
 			processor_entries = processor_entries ?
 			    processor_entries :
 			    (struct __processor_entry *) cur;
 			processor_entry_cnt++;
-			cnt += ct_processor_entry((struct __processor_entry *)
-			    cur);
+			ct_processor_entry((struct __processor_entry *) cur);
 			cur += 20;
 			break;
-
-		/* Bus entry */
-		case 1:
+		case 1:  /* Bus entry */
 			bus_entries = bus_entries ?
 			    bus_entries : (struct __bus_entry *) cur;
@@ -250,16 +377,12 @@
 			cur += 8;
 			break;
-				
-		/* I/O Apic */
-		case 2:
+		case 2:  /* I/O APIC */
 			io_apic_entries = io_apic_entries ?
 			    io_apic_entries : (struct __io_apic_entry *) cur;
-				io_apic_entry_cnt++;
+			io_apic_entry_cnt++;
 			ct_io_apic_entry((struct __io_apic_entry *) cur);
 			cur += 8;
 			break;
-				
-		/* I/O Interrupt Assignment */
-		case 3:
+		case 3:  /* I/O Interrupt Assignment */
 			io_intr_entries = io_intr_entries ?
 			    io_intr_entries : (struct __io_intr_entry *) cur;
@@ -268,7 +391,5 @@
 			cur += 8;
 			break;
-
-		/* Local Interrupt Assignment */
-		case 4:
+		case 4:  /* Local Interrupt Assignment */
 			l_intr_entries = l_intr_entries ?
 			    l_intr_entries : (struct __l_intr_entry *) cur;
@@ -277,12 +398,10 @@
 			cur += 8;
 			break;
-
 		default:
 			/*
 			 * Something is wrong. Fallback to UP mode.
 			 */
-
-			printf("%s: ct badness\n", __func__);
-			return 1;
+			printf("MPS: ct badness %" PRIu8 "\n", *cur);
+			return;
 		}
 	}
@@ -292,196 +411,57 @@
 	 */
 	ct_extended_entries();
-	return cnt;
-}
-
-int configure_via_default(uint8_t n __attribute__((unused)))
+}
+
+static void configure_via_default(uint8_t n __attribute__((unused)))
 {
 	/*
 	 * Not yet implemented.
 	 */
-	printf("%s: not supported\n", __func__);
-	return 1;
-}
-
-
-int ct_processor_entry(struct __processor_entry *pr __attribute__((unused)))
-{
+	printf("MPS: Default configuration not supported\n");
+}
+
+void mps_init(void)
+{
+	uint8_t *addr[2] = { NULL, (uint8_t *) PA2KA(0xf0000) };
+	unsigned int i;
+	unsigned int j;
+	unsigned int length[2] = { 1024, 64 * 1024 };
+	
 	/*
-	 * Ignore processors which are not marked enabled.
+	 * Find MP Floating Pointer Structure
+	 *  1a. search first 1K of EBDA
+	 *  1b. if EBDA is undefined, search last 1K of base memory
+	 *  2.  search 64K starting at 0xf0000
 	 */
-	if ((pr->cpu_flags & (1 << 0)) == 0)
-		return 0;
-	
-	apic_id_mask |= (1 << pr->l_apic_id); 
-	return 1;
-}
-
-void ct_bus_entry(struct __bus_entry *bus __attribute__((unused)))
-{
-#ifdef MPSCT_VERBOSE
-	char buf[7];
-	memcpy((void *) buf, (void *) bus->bus_type, 6);
-	buf[6] = 0;
-	printf("bus%d: %s\n", bus->bus_id, buf);
-#endif
-}
-
-void ct_io_apic_entry(struct __io_apic_entry *ioa)
-{
-	static unsigned int io_apic_count = 0;
-
-	/* this ioapic is marked unusable */
-	if ((ioa->io_apic_flags & 1) == 0)
-		return;
-	
-	if (io_apic_count++ > 0) {
-		/*
-		 * Multiple IO APIC's are currently not supported.
-		 */
-		return;
-	}
-	
-	io_apic = (uint32_t *)(uintptr_t)ioa->io_apic;
-}
-
-//#define MPSCT_VERBOSE
-void ct_io_intr_entry(struct __io_intr_entry *iointr __attribute__((unused)))
-{
-#ifdef MPSCT_VERBOSE
-	switch (iointr->intr_type) {
-	case 0:
-		printf("INT");
-		break;
-	case 1:
-		printf("NMI");
-		break;
-	case 2:
-		printf("SMI");
-		break;
-	case 3:
-		printf("ExtINT");
-		break;
-	}
-	putchar(',');
-	switch (iointr->poel & 3) {
-	case 0:
-		printf("bus-like");
-		break;
-	case 1:
-		printf("active high");
-		break;
-	case 2:
-		printf("reserved");
-		break;
-	case 3:
-		printf("active low");
-		break;
-	}
-	putchar(',');
-	switch ((iointr->poel >> 2) & 3) {
-	case 0:
-		printf("bus-like");
-		break;
-	case 1:
-		printf("edge-triggered");
-		break;
-	case 2:
-		printf("reserved");
-		break;
-	case 3:
-		printf("level-triggered");
-		break;
-	}
-	putchar(',');
-	printf("bus%d,irq%d", iointr->src_bus_id, iointr->src_bus_irq);
-	putchar(',');
-	printf("io_apic%d,pin%d", iointr->dst_io_apic_id,
-	    iointr->dst_io_apic_pin);
-	putchar('\n');	
-#endif
-}
-
-void ct_l_intr_entry(struct __l_intr_entry *lintr __attribute__((unused)))
-{
-#ifdef MPSCT_VERBOSE
-	switch (lintr->intr_type) {
-	case 0:
-	    printf("INT");
-	    break;
-	case 1:
-	    printf("NMI");
-	    break;
-	case 2:
-	    printf("SMI");
-	    break;
-	case 3:
-	    printf("ExtINT");
-	    break;
-	}
-	putchar(',');
-	switch (lintr->poel & 3) {
-	case 0:
-	    printf("bus-like");
-	    break;
-	case 1:
-	    printf("active high");
-	    break;
-	case 2:
-	    printf("reserved");
-	    break;
-	case 3:
-	    printf("active low");
-	    break;
-	}
-	putchar(',');
-	switch ((lintr->poel >> 2) & 3) {
-	case 0:
-	    printf("bus-like");
-	    break;
-	case 1:
-	    printf("edge-triggered");
-	    break;
-	case 2:
-	    printf("reserved");
-	    break;
-	case 3:
-	    printf("level-triggered");
-	    break;
-	}
-	putchar(',');
-	printf("bus%d,irq%d", lintr->src_bus_id, lintr->src_bus_irq);
-	putchar(',');
-	printf("l_apic%d,pin%d", lintr->dst_l_apic_id, lintr->dst_l_apic_pin);
-	putchar('\n');
-#endif
-}
-
-void ct_extended_entries(void)
-{
-	uint8_t *ext = (uint8_t *) ct + ct->base_table_length;
-	uint8_t *cur;
-
-	for (cur = ext; cur < ext + ct->ext_table_length;
-	    cur += cur[CT_EXT_ENTRY_LEN]) {
-		switch (cur[CT_EXT_ENTRY_TYPE]) {
-		default:
-			printf("%p: skipping MP Configuration Table extended "
-			    "entry type %d\n", cur, cur[CT_EXT_ENTRY_TYPE]);
-			break;
+	
+	addr[0] = (uint8_t *) PA2KA(ebda ? ebda : 639 * 1024);
+	for (i = 0; i < 2; i++) {
+		for (j = 0; j < length[i]; j += 16) {
+			if ((*((uint32_t *) &addr[i][j]) ==
+			    FS_SIGNATURE) && (mps_fs_check(&addr[i][j]))) {
+				fs = (struct mps_fs *) &addr[i][j];
+				goto fs_found;
+			}
 		}
 	}
-}
-
-int mps_irq_to_pin(unsigned int irq)
-{
-	unsigned int i;
-	
-	for (i = 0; i < io_intr_entry_cnt; i++) {
-		if (io_intr_entries[i].src_bus_irq == irq &&
-		    io_intr_entries[i].intr_type == 0)
-			return io_intr_entries[i].dst_io_apic_pin;
-	}
-	
-	return -1;
+	
+	return;
+	
+fs_found:
+	printf("%p: MPS Floating Pointer Structure\n", fs);
+	
+	if ((fs->config_type == 0) && (fs->configuration_table)) {
+		if (fs->mpfib2 >> 7) {
+			printf("MPS: PIC mode not supported\n");
+			return;
+		}
+		
+		ct = (struct mps_ct *) PA2KA((uintptr_t) fs->configuration_table);
+		configure_via_ct();
+	} else
+		configure_via_default(fs->config_type);
+	
+	if (processor_entry_cnt > 0)
+		config.cpu_count = processor_entry_cnt;
 }
 
Index: kernel/arch/ia32/src/smp/smp.c
===================================================================
--- kernel/arch/ia32/src/smp/smp.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/ia32/src/smp/smp.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -62,33 +62,17 @@
 void smp_init(void)
 {
-	uintptr_t l_apic_address, io_apic_address;
-
 	if (acpi_madt) {
 		acpi_madt_parse();
 		ops = &madt_config_operations;
 	}
+	
 	if (config.cpu_count == 1) {
 		mps_init();
 		ops = &mps_config_operations;
 	}
-
-	l_apic_address = (uintptr_t) frame_alloc(ONE_FRAME,
-	    FRAME_ATOMIC | FRAME_KA);
-	if (!l_apic_address)
-		panic("Cannot allocate address for l_apic.");
-
-	io_apic_address = (uintptr_t) frame_alloc(ONE_FRAME,
-	    FRAME_ATOMIC | FRAME_KA);
-	if (!io_apic_address)
-		panic("Cannot allocate address for io_apic.");
-
-	if (config.cpu_count > 1) {		
-		page_mapping_insert(AS_KERNEL, l_apic_address,
-		    (uintptr_t) l_apic, PAGE_NOT_CACHEABLE | PAGE_WRITE);
-		page_mapping_insert(AS_KERNEL, io_apic_address,
-		    (uintptr_t) io_apic, PAGE_NOT_CACHEABLE | PAGE_WRITE);
-				  
-		l_apic = (uint32_t *) l_apic_address;
-		io_apic = (uint32_t *) io_apic_address;
+	
+	if (config.cpu_count > 1) {
+		l_apic = (uint32_t *) hw_map((uintptr_t) l_apic, PAGE_SIZE);
+		io_apic = (uint32_t *) hw_map((uintptr_t) io_apic, PAGE_SIZE);
 	}
 }
@@ -106,16 +90,16 @@
 	
 	ASSERT(ops != NULL);
-
+	
 	/*
 	 * We need to access data in frame 0.
 	 * We boldly make use of kernel address space mapping.
 	 */
-
+	
 	/*
 	 * Set the warm-reset vector to the real-mode address of 4K-aligned ap_boot()
 	 */
 	*((uint16_t *) (PA2KA(0x467 + 0))) =
-	    (uint16_t) (((uintptr_t) ap_boot) >> 4);	/* segment */
-	*((uint16_t *) (PA2KA(0x467 + 2))) = 0;		/* offset */
+	    (uint16_t) (((uintptr_t) ap_boot) >> 4);  /* segment */
+	*((uint16_t *) (PA2KA(0x467 + 2))) = 0;       /* offset */
 	
 	/*
@@ -123,15 +107,11 @@
 	 * BIOS will not do the POST after the INIT signal.
 	 */
-	pio_write_8((ioport8_t *)0x70, 0xf);
-	pio_write_8((ioport8_t *)0x71, 0xa);
-
+	pio_write_8((ioport8_t *) 0x70, 0xf);
+	pio_write_8((ioport8_t *) 0x71, 0xa);
+	
 	pic_disable_irqs(0xffff);
 	apic_init();
 	
-	uint8_t apic = l_apic_id();
-
-	for (i = 0; i < ops->cpu_count(); i++) {
-		descriptor_t *gdt_new;
-		
+	for (i = 0; i < config.cpu_count; i++) {
 		/*
 		 * Skip processors marked unusable.
@@ -139,5 +119,5 @@
 		if (!ops->cpu_enabled(i))
 			continue;
-
+		
 		/*
 		 * The bootstrap processor is already up.
@@ -145,8 +125,8 @@
 		if (ops->cpu_bootstrap(i))
 			continue;
-
-		if (ops->cpu_apic_id(i) == apic) {
-			printf("%s: bad processor entry #%u, will not send IPI "
-			    "to myself\n", __FUNCTION__, i);
+		
+		if (ops->cpu_apic_id(i) == bsp_l_apic) {
+			printf("kmp: bad processor entry #%u, will not send IPI "
+			    "to myself\n", i);
 			continue;
 		}
@@ -160,9 +140,10 @@
 		 * the memory subsystem
 		 */
-		gdt_new = (descriptor_t *) malloc(GDT_ITEMS *
-		    sizeof(descriptor_t), FRAME_ATOMIC);
+		descriptor_t *gdt_new =
+		    (descriptor_t *) malloc(GDT_ITEMS * sizeof(descriptor_t),
+		    FRAME_ATOMIC);
 		if (!gdt_new)
 			panic("Cannot allocate memory for GDT.");
-
+		
 		memcpy(gdt_new, gdt, GDT_ITEMS * sizeof(descriptor_t));
 		memsetb(&gdt_new[TSS_DES], sizeof(descriptor_t), 0);
@@ -170,5 +151,5 @@
 		protected_ap_gdtr.base = KA2PA((uintptr_t) gdt_new);
 		gdtr.base = (uintptr_t) gdt_new;
-
+		
 		if (l_apic_send_init_ipi(ops->cpu_apic_id(i))) {
 			/*
@@ -179,8 +160,6 @@
 			if (waitq_sleep_timeout(&ap_completion_wq, 1000000,
 			    SYNCH_FLAGS_NONE) == ESYNCH_TIMEOUT) {
-				unsigned int cpu = (config.cpu_active > i) ?
-				    config.cpu_active : i;
 				printf("%s: waiting for cpu%u (APIC ID = %d) "
-				    "timed out\n", __FUNCTION__, cpu,
+				    "timed out\n", __FUNCTION__, i,
 				    ops->cpu_apic_id(i));
 			}
Index: kernel/arch/ia32/src/syscall.c
===================================================================
--- kernel/arch/ia32/src/syscall.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/ia32/src/syscall.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -45,5 +45,5 @@
 
 	/* set kernel mode CS selector */
-	write_msr(IA32_MSR_SYSENTER_CS, gdtselector(KTEXT_DES));
+	write_msr(IA32_MSR_SYSENTER_CS, GDT_SELECTOR(KTEXT_DES));
 	/* set kernel mode entry point */
 	write_msr(IA32_MSR_SYSENTER_EIP, (uint32_t) sysenter_handler);
Index: kernel/arch/ia32/src/userspace.c
===================================================================
--- kernel/arch/ia32/src/userspace.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/ia32/src/userspace.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -75,11 +75,11 @@
 		"iret\n"
 		:
-		: [udata_des] "i" (gdtselector(UDATA_DES) | PL_USER),
+		: [udata_des] "i" (GDT_SELECTOR(UDATA_DES) | PL_USER),
 		  [stack_size] "r" ((uint8_t *) kernel_uarg->uspace_stack + THREAD_STACK_SIZE),
 		  [ipl] "r" (ipl),
-		  [utext_des] "i" (gdtselector(UTEXT_DES) | PL_USER),
+		  [utext_des] "i" (GDT_SELECTOR(UTEXT_DES) | PL_USER),
 		  [entry] "r" (kernel_uarg->uspace_entry),
 		  [uarg] "r" (kernel_uarg->uspace_uarg),
-		  [tls_des] "r" (gdtselector(TLS_DES))
+		  [tls_des] "r" (GDT_SELECTOR(TLS_DES))
 		: "eax");
 	
Index: kernel/arch/ia64/Makefile.inc
===================================================================
--- kernel/arch/ia64/Makefile.inc	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/ia64/Makefile.inc	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -34,6 +34,6 @@
 ICC_CFLAGS += $(CMN1)
 
-LFLAGS = -EL
-AFLAGS = -mconstant-gp
+AFLAGS += -mconstant-gp
+LFLAGS += -EL
 
 BITS = 64
Index: kernel/arch/ia64/_link.ld.in
===================================================================
--- kernel/arch/ia64/_link.ld.in	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/ia64/_link.ld.in	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -7,6 +7,6 @@
  */
 
-#define LOAD_ADDRESS_V	0xe000000004404000
-#define LOAD_ADDRESS_P	0x0000000004404000
+#define LOAD_ADDRESS_V	0xe000000004800000
+#define LOAD_ADDRESS_P	0x0000000004800000
 
 ENTRY(kernel_image_start)
Index: kernel/arch/ia64/include/asm.h
===================================================================
--- kernel/arch/ia64/include/asm.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/ia64/include/asm.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -40,8 +40,9 @@
 #include <typedefs.h>
 #include <arch/register.h>
+#include <trace.h>
 
 #define IA64_IOSPACE_ADDRESS  0xE001000000000000ULL
 
-static inline void pio_write_8(ioport8_t *port, uint8_t v)
+NO_TRACE static inline void pio_write_8(ioport8_t *port, uint8_t v)
 {
 	uintptr_t prt = (uintptr_t) port;
@@ -56,5 +57,5 @@
 }
 
-static inline void pio_write_16(ioport16_t *port, uint16_t v)
+NO_TRACE static inline void pio_write_16(ioport16_t *port, uint16_t v)
 {
 	uintptr_t prt = (uintptr_t) port;
@@ -69,5 +70,5 @@
 }
 
-static inline void pio_write_32(ioport32_t *port, uint32_t v)
+NO_TRACE static inline void pio_write_32(ioport32_t *port, uint32_t v)
 {
 	uintptr_t prt = (uintptr_t) port;
@@ -82,5 +83,5 @@
 }
 
-static inline uint8_t pio_read_8(ioport8_t *port)
+NO_TRACE static inline uint8_t pio_read_8(ioport8_t *port)
 {
 	uintptr_t prt = (uintptr_t) port;
@@ -95,5 +96,5 @@
 }
 
-static inline uint16_t pio_read_16(ioport16_t *port)
+NO_TRACE static inline uint16_t pio_read_16(ioport16_t *port)
 {
 	uintptr_t prt = (uintptr_t) port;
@@ -108,5 +109,5 @@
 }
 
-static inline uint32_t pio_read_32(ioport32_t *port)
+NO_TRACE static inline uint32_t pio_read_32(ioport32_t *port)
 {
 	uintptr_t prt = (uintptr_t) port;
@@ -126,21 +127,26 @@
  * The stack is assumed to be STACK_SIZE long.
  * The stack must start on page boundary.
- */
-static inline uintptr_t get_stack_base(void)
-{
-	uint64_t v;
-	
-	/* I'm not sure why but this code bad inlines in scheduler,
-	   so THE shifts about 16B and causes kernel panic
-	   
-	   asm volatile (
-	       "and %[value] = %[mask], r12"
-	       : [value] "=r" (v)
-	       : [mask] "r" (~(STACK_SIZE - 1))
-	   );
-	   return v;
-	   
-	   This code have the same meaning but inlines well.
-	*/
+ *
+ */
+NO_TRACE static inline uintptr_t get_stack_base(void)
+{
+	uint64_t v;
+	
+	/*
+	 * I'm not sure why but this code inlines badly
+	 * in scheduler, resulting in THE shifting about
+	 * 16B and causing kernel panic.
+	 *
+	 * asm volatile (
+	 *     "and %[value] = %[mask], r12"
+	 *     : [value] "=r" (v)
+	 *     : [mask] "r" (~(STACK_SIZE - 1))
+	 * );
+	 * return v;
+	 *
+	 * The following code has the same semantics but
+	 * inlines correctly.
+	 *
+	 */
 	
 	asm volatile (
@@ -155,6 +161,7 @@
  *
  * @return PSR.
- */
-static inline uint64_t psr_read(void)
+ *
+ */
+NO_TRACE static inline uint64_t psr_read(void)
 {
 	uint64_t v;
@@ -171,6 +178,7 @@
  *
  * @return Return location of interruption vector table.
- */
-static inline uint64_t iva_read(void)
+ *
+ */
+NO_TRACE static inline uint64_t iva_read(void)
 {
 	uint64_t v;
@@ -187,6 +195,7 @@
  *
  * @param v New location of interruption vector table.
- */
-static inline void iva_write(uint64_t v)
+ *
+ */
+NO_TRACE static inline void iva_write(uint64_t v)
 {
 	asm volatile (
@@ -196,10 +205,11 @@
 }
 
-
 /** Read IVR (External Interrupt Vector Register).
  *
- * @return Highest priority, pending, unmasked external interrupt vector.
- */
-static inline uint64_t ivr_read(void)
+ * @return Highest priority, pending, unmasked external
+ *         interrupt vector.
+ *
+ */
+NO_TRACE static inline uint64_t ivr_read(void)
 {
 	uint64_t v;
@@ -213,5 +223,5 @@
 }
 
-static inline uint64_t cr64_read(void)
+NO_TRACE static inline uint64_t cr64_read(void)
 {
 	uint64_t v;
@@ -225,10 +235,10 @@
 }
 
-
 /** Write ITC (Interval Timer Counter) register.
  *
  * @param v New counter value.
- */
-static inline void itc_write(uint64_t v)
+ *
+ */
+NO_TRACE static inline void itc_write(uint64_t v)
 {
 	asm volatile (
@@ -241,6 +251,7 @@
  *
  * @return Current counter value.
- */
-static inline uint64_t itc_read(void)
+ *
+ */
+NO_TRACE static inline uint64_t itc_read(void)
 {
 	uint64_t v;
@@ -257,6 +268,7 @@
  *
  * @param v New match value.
- */
-static inline void itm_write(uint64_t v)
+ *
+ */
+NO_TRACE static inline void itm_write(uint64_t v)
 {
 	asm volatile (
@@ -269,6 +281,7 @@
  *
  * @return Match value.
- */
-static inline uint64_t itm_read(void)
+ *
+ */
+NO_TRACE static inline uint64_t itm_read(void)
 {
 	uint64_t v;
@@ -285,6 +298,7 @@
  *
  * @return Current vector and mask bit.
- */
-static inline uint64_t itv_read(void)
+ *
+ */
+NO_TRACE static inline uint64_t itv_read(void)
 {
 	uint64_t v;
@@ -301,6 +315,7 @@
  *
  * @param v New vector and mask bit.
- */
-static inline void itv_write(uint64_t v)
+ *
+ */
+NO_TRACE static inline void itv_write(uint64_t v)
 {
 	asm volatile (
@@ -313,6 +328,7 @@
  *
  * @param v This value is ignored.
- */
-static inline void eoi_write(uint64_t v)
+ *
+ */
+NO_TRACE static inline void eoi_write(uint64_t v)
 {
 	asm volatile (
@@ -325,6 +341,7 @@
  *
  * @return Current value of TPR.
- */
-static inline uint64_t tpr_read(void)
+ *
+ */
+NO_TRACE static inline uint64_t tpr_read(void)
 {
 	uint64_t v;
@@ -341,6 +358,7 @@
  *
  * @param v New value of TPR.
- */
-static inline void tpr_write(uint64_t v)
+ *
+ */
+NO_TRACE static inline void tpr_write(uint64_t v)
 {
 	asm volatile (
@@ -356,6 +374,7 @@
  *
  * @return Old interrupt priority level.
- */
-static ipl_t interrupts_disable(void)
+ *
+ */
+NO_TRACE static ipl_t interrupts_disable(void)
 {
 	uint64_t v;
@@ -377,6 +396,7 @@
  *
  * @return Old interrupt priority level.
- */
-static ipl_t interrupts_enable(void)
+ *
+ */
+NO_TRACE static ipl_t interrupts_enable(void)
 {
 	uint64_t v;
@@ -399,6 +419,7 @@
  *
  * @param ipl Saved interrupt priority level.
- */
-static inline void interrupts_restore(ipl_t ipl)
+ *
+ */
+NO_TRACE static inline void interrupts_restore(ipl_t ipl)
 {
 	if (ipl & PSR_I_MASK)
@@ -411,12 +432,23 @@
  *
  * @return PSR.
- */
-static inline ipl_t interrupts_read(void)
+ *
+ */
+NO_TRACE static inline ipl_t interrupts_read(void)
 {
 	return (ipl_t) psr_read();
 }
 
+/** Check interrupts state.
+ *
+ * @return True if interrupts are disabled.
+ *
+ */
+NO_TRACE static inline bool interrupts_disabled(void)
+{
+	return !(psr_read() & PSR_I_MASK);
+}
+
 /** Disable protection key checking. */
-static inline void pk_disable(void)
+NO_TRACE static inline void pk_disable(void)
 {
 	asm volatile (
Index: kernel/arch/ia64/include/atomic.h
===================================================================
--- kernel/arch/ia64/include/atomic.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/ia64/include/atomic.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -36,5 +36,7 @@
 #define KERN_ia64_ATOMIC_H_
 
-static inline atomic_count_t test_and_set(atomic_t *val)
+#include <trace.h>
+
+NO_TRACE static inline atomic_count_t test_and_set(atomic_t *val)
 {
 	atomic_count_t v;
@@ -50,5 +52,5 @@
 }
 
-static inline void atomic_lock_arch(atomic_t *val)
+NO_TRACE static inline void atomic_lock_arch(atomic_t *val)
 {
 	do {
@@ -57,5 +59,5 @@
 }
 
-static inline void atomic_inc(atomic_t *val)
+NO_TRACE static inline void atomic_inc(atomic_t *val)
 {
 	atomic_count_t v;
@@ -68,5 +70,5 @@
 }
 
-static inline void atomic_dec(atomic_t *val)
+NO_TRACE static inline void atomic_dec(atomic_t *val)
 {
 	atomic_count_t v;
@@ -79,5 +81,5 @@
 }
 
-static inline atomic_count_t atomic_preinc(atomic_t *val)
+NO_TRACE static inline atomic_count_t atomic_preinc(atomic_t *val)
 {
 	atomic_count_t v;
@@ -92,5 +94,5 @@
 }
 
-static inline atomic_count_t atomic_predec(atomic_t *val)
+NO_TRACE static inline atomic_count_t atomic_predec(atomic_t *val)
 {
 	atomic_count_t v;
@@ -105,5 +107,5 @@
 }
 
-static inline atomic_count_t atomic_postinc(atomic_t *val)
+NO_TRACE static inline atomic_count_t atomic_postinc(atomic_t *val)
 {
 	atomic_count_t v;
@@ -118,5 +120,5 @@
 }
 
-static inline atomic_count_t atomic_postdec(atomic_t *val)
+NO_TRACE static inline atomic_count_t atomic_postdec(atomic_t *val)
 {
 	atomic_count_t v;
Index: kernel/arch/ia64/include/bootinfo.h
===================================================================
--- kernel/arch/ia64/include/bootinfo.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/ia64/include/bootinfo.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -30,6 +30,4 @@
 #define KERN_ia64_BOOTINFO_H_
 
-#define BOOTINFO_ADDRESS 0x4401000
-
 #define TASKMAP_MAX_RECORDS  32
 
@@ -37,6 +35,4 @@
 
 #define EFI_MEMMAP_FREE_MEM 0
-#define EFI_MEMMAP_IO 1
-#define EFI_MEMMAP_IO_PORTS 2
 
 /** Size of buffer for storing task name in binit_task_t. */
@@ -75,6 +71,3 @@
 extern bootinfo_t *bootinfo;
 
-extern void start(void);
-extern void bootstrap(void);
-
 #endif
Index: kernel/arch/ia64/include/cpu.h
===================================================================
--- kernel/arch/ia64/include/cpu.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/ia64/include/cpu.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -40,7 +40,13 @@
 #include <arch/asm.h>
 #include <arch/bootinfo.h>
+#include <trace.h>
 
-#define FAMILY_ITANIUM	0x7
-#define FAMILY_ITANIUM2	0x1f
+#define FAMILY_ITANIUM   0x7
+#define FAMILY_ITANIUM2  0x1f
+
+#define CR64_ID_SHIFT   24
+#define CR64_ID_MASK    0xff000000
+#define CR64_EID_SHIFT  16
+#define CR64_EID_MASK   0xff0000
 
 typedef struct {
@@ -55,38 +61,35 @@
  *
  * @return Value of CPUID[n] register.
+ *
  */
-static inline uint64_t cpuid_read(int n)
+NO_TRACE static inline uint64_t cpuid_read(int n)
 {
 	uint64_t v;
 	
-	asm volatile ("mov %0 = cpuid[%1]\n" : "=r" (v) : "r" (n));
+	asm volatile (
+		"mov %[v] = cpuid[%[r]]\n"
+		: [v] "=r" (v)
+		: [r] "r" (n)
+	);
 	
 	return v;
 }
 
-
-#define CR64_ID_SHIFT 24
-#define CR64_ID_MASK 0xff000000
-#define CR64_EID_SHIFT 16
-#define CR64_EID_MASK 0xff0000
-
-static inline int ia64_get_cpu_id(void)
+NO_TRACE static inline int ia64_get_cpu_id(void)
 {
-	uint64_t cr64=cr64_read();
-	return ((CR64_ID_MASK)&cr64)>>CR64_ID_SHIFT;
+	uint64_t cr64 = cr64_read();
+	return ((CR64_ID_MASK) &cr64) >> CR64_ID_SHIFT;
 }
 
-static inline int ia64_get_cpu_eid(void)
+NO_TRACE static inline int ia64_get_cpu_eid(void)
 {
-	uint64_t cr64=cr64_read();
-	return ((CR64_EID_MASK)&cr64)>>CR64_EID_SHIFT;
+	uint64_t cr64 = cr64_read();
+	return ((CR64_EID_MASK) &cr64) >> CR64_EID_SHIFT;
 }
 
-
-static inline void ipi_send_ipi(int id, int eid, int intno)
+NO_TRACE static inline void ipi_send_ipi(int id, int eid, int intno)
 {
 	(bootinfo->sapic)[2 * (id * 256 + eid)] = intno;
 	srlz_d();
-
 }
 
Index: kernel/arch/ia64/include/cycle.h
===================================================================
--- kernel/arch/ia64/include/cycle.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/ia64/include/cycle.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -36,5 +36,7 @@
 #define KERN_ia64_CYCLE_H_
 
-static inline uint64_t get_cycle(void)
+#include <trace.h>
+
+NO_TRACE static inline uint64_t get_cycle(void)
 {
 	return 0;
Index: rnel/arch/ia64/include/debug.h
===================================================================
--- kernel/arch/ia64/include/debug.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ 	(revision )
@@ -1,42 +1,0 @@
-/*
- * Copyright (c) 2005 Ondrej Palkovsky
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/** @addtogroup ia64debug ia64
- * @ingroup debug
- * @{
- */
-/** @file
- */
-
-#ifndef KERN_ia64_DEBUG_H_
-#define KERN_ia64_DEBUG_H_
-
-#endif
-
-/** @}
- */
Index: kernel/arch/ia64/include/interrupt.h
===================================================================
--- kernel/arch/ia64/include/interrupt.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/ia64/include/interrupt.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -38,4 +38,5 @@
 #include <typedefs.h>
 #include <arch/register.h>
+#include <trace.h>
 
 /** ia64 has 256 INRs. */
@@ -133,5 +134,8 @@
 } istate_t;
 
-static inline void istate_set_retaddr(istate_t *istate, uintptr_t retaddr)
+extern void *ivt;
+
+NO_TRACE static inline void istate_set_retaddr(istate_t *istate,
+    uintptr_t retaddr)
 {
 	istate->cr_iip = retaddr;
@@ -139,29 +143,29 @@
 }
 
-static inline unative_t istate_get_pc(istate_t *istate)
+NO_TRACE static inline unative_t istate_get_pc(istate_t *istate)
 {
 	return istate->cr_iip;
 }
 
-static inline unative_t istate_get_fp(istate_t *istate)
+NO_TRACE static inline unative_t istate_get_fp(istate_t *istate)
 {
-	return 0;	/* FIXME */
+	/* FIXME */
+	
+	return 0;
 }
 
-static inline int istate_from_uspace(istate_t *istate)
+NO_TRACE static inline int istate_from_uspace(istate_t *istate)
 {
 	return (istate->cr_iip) < 0xe000000000000000ULL;
 }
 
-extern void *ivt;
+extern void general_exception(uint64_t, istate_t *);
+extern int break_instruction(uint64_t, istate_t *);
+extern void universal_handler(uint64_t, istate_t *);
+extern void nop_handler(uint64_t, istate_t *);
+extern void external_interrupt(uint64_t, istate_t *);
+extern void disabled_fp_register(uint64_t, istate_t *);
 
-extern void general_exception(uint64_t vector, istate_t *istate);
-extern int break_instruction(uint64_t vector, istate_t *istate);
-extern void universal_handler(uint64_t vector, istate_t *istate);
-extern void nop_handler(uint64_t vector, istate_t *istate);
-extern void external_interrupt(uint64_t vector, istate_t *istate);
-extern void disabled_fp_register(uint64_t vector, istate_t *istate);
-
-extern void trap_virtual_enable_irqs(uint16_t irqmask);
+extern void trap_virtual_enable_irqs(uint16_t);
 
 #endif
Index: kernel/arch/ia64/include/mm/page.h
===================================================================
--- kernel/arch/ia64/include/mm/page.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/ia64/include/mm/page.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -208,5 +208,5 @@
  * @return Address of the head of VHPT collision chain.
  */
-static inline uint64_t thash(uint64_t va)
+NO_TRACE static inline uint64_t thash(uint64_t va)
 {
 	uint64_t ret;
@@ -230,5 +230,5 @@
  * @return The unique tag for VPN and RID in the collision chain returned by thash().
  */
-static inline uint64_t ttag(uint64_t va)
+NO_TRACE static inline uint64_t ttag(uint64_t va)
 {
 	uint64_t ret;
@@ -249,5 +249,5 @@
  * @return Current contents of rr[i].
  */
-static inline uint64_t rr_read(size_t i)
+NO_TRACE static inline uint64_t rr_read(size_t i)
 {
 	uint64_t ret;
@@ -269,5 +269,5 @@
  * @param v Value to be written to rr[i].
  */
-static inline void rr_write(size_t i, uint64_t v)
+NO_TRACE static inline void rr_write(size_t i, uint64_t v)
 {
 	ASSERT(i < REGION_REGISTERS);
@@ -284,5 +284,5 @@
  * @return Current value stored in PTA.
  */
-static inline uint64_t pta_read(void)
+NO_TRACE static inline uint64_t pta_read(void)
 {
 	uint64_t ret;
@@ -300,5 +300,5 @@
  * @param v New value to be stored in PTA.
  */
-static inline void pta_write(uint64_t v)
+NO_TRACE static inline void pta_write(uint64_t v)
 {
 	asm volatile (
Index: kernel/arch/ia64/src/asm.S
===================================================================
--- kernel/arch/ia64/src/asm.S	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/ia64/src/asm.S	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -1,43 +1,33 @@
-#
-# Copyright (c) 2005 Jakub Jermar
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions
-# are met:
-#
-# - Redistributions of source code must retain the above copyright
-#   notice, this list of conditions and the following disclaimer.
-# - Redistributions in binary form must reproduce the above copyright
-#   notice, this list of conditions and the following disclaimer in the
-#   documentation and/or other materials provided with the distribution.
-# - The name of the author may not be used to endorse or promote products
-#   derived from this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
-# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
-# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
-# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
-# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
-# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-#
+/*
+ * Copyright (c) 2005 Jakub Jermar
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
 
 #include <arch/register.h>
 
 .text
-
-/** Copy memory from/to userspace.
- *
- * This memcpy() has been taken from the assembler output of
- * the generic _memcpy() and modified to have the failover part.
- *
- * @param in0 Destination address.
- * @param in1 Source address.
- * @param in2 Number of byte to copy.
- */
 .global memcpy
 .global memcpy_from_uspace
@@ -45,9 +35,20 @@
 .global memcpy_from_uspace_failover_address
 .global memcpy_to_uspace_failover_address
+
+/** Copy memory from/to userspace.
+ *
+ * This memcpy() has been taken from the assembler output of
+ * the generic _memcpy() and modified to have the failover part.
+ *
+ * @param in0 Destination address.
+ * @param in1 Source address.
+ * @param in2 Number of byte to copy.
+ *
+ */
 memcpy:
 memcpy_from_uspace:
 memcpy_to_uspace:
 	alloc loc0 = ar.pfs, 3, 1, 0, 0
-
+	
 	adds r14 = 7, in1
 	mov r2 = ar.lc
@@ -55,71 +56,86 @@
 	and r14 = -8, r14 ;;
 	cmp.ne p6, p7 = r14, in1
-(p7)	br.cond.dpnt 3f	;;
-0:
-	cmp.ne p6, p7 = 0, in2
-(p7)	br.cond.dpnt 2f	;;
-(p6)	adds r14 = -1, in2
-(p6)	mov r16 = r0
-(p6)	mov r17 = r0 ;;
-(p6)	mov ar.lc = r14
-1:
-	add r14 = r16, in1 
-	add r15 = r16, in0
-	adds r17 = 1, r17 ;;
-	ld1 r14 = [r14]
-	mov r16 = r17 ;;
-	st1 [r15] = r14
-	br.cloop.sptk.few 1b ;;
-2:
-	mov ar.lc = r2
-	mov ar.pfs = loc0
-	br.ret.sptk.many rp
-3:
-	adds r14 = 7, in0 ;;
-	and r14 = -8, r14 ;;
-	cmp.eq p6, p7 = r14, in0
-(p7)	br.cond.dptk 0b
-	shr.u r18 = in2, 3 ;;
-	cmp.ne p6, p7 = 0, r18
-(p7)	br.cond.dpnt 5f	;;
-(p6)	adds r14 = -1, r18
-(p6)	mov r16 = r0
-(p6)	mov r17 = r0 ;;
-(p6)	mov ar.lc = r14
-4:
-	shladd r14 = r16, 3, r0
-	adds r16 = 1, r17 ;;
-	add r15 = in1, r14
-	add r14 = in0, r14
-	mov r17 = r16 ;;
-	ld8 r15 = [r15] ;;
-	st8 [r14] = r15
-	br.cloop.sptk.few 4b
-5:
-	and r15 = 7, in2
-	shladd r14 = r18, 3, r0
-	mov r16 = r0
-	mov r18 = r0 ;;
-	cmp.eq p6, p7 = 0, r15
-	add in0 = r14, in0
-	adds r15 = -1, r15
-	add r17 = r14, in1 
-(p6)	br.cond.dpnt 2b	;;
-	mov ar.lc = r15
-6:
-	add r14 = r16, r17
-	add r15 = r16, in0
-	adds r16 = 1, r18 ;;
-	ld1 r14 = [r14]
-	mov r18 = r16 ;;
-	st1 [r15] = r14
-	br.cloop.sptk.few 6b ;;
-	mov ar.lc = r2
-	mov ar.pfs = loc0
-	br.ret.sptk.many rp
-	
+	(p7) br.cond.dpnt 3f ;;
+	
+	0:
+	
+		cmp.ne p6, p7 = 0, in2
+		(p7) br.cond.dpnt 2f ;;
+		(p6) adds r14 = -1, in2
+		(p6) mov r16 = r0
+		(p6) mov r17 = r0 ;;
+		(p6) mov ar.lc = r14
+	
+	1:
+	
+		add r14 = r16, in1 
+		add r15 = r16, in0
+		adds r17 = 1, r17 ;;
+		ld1 r14 = [r14]
+		mov r16 = r17 ;;
+		st1 [r15] = r14
+		br.cloop.sptk.few 1b ;;
+	
+	2:
+	
+		mov ar.lc = r2
+		mov ar.pfs = loc0
+		br.ret.sptk.many rp
+	
+	3:
+	
+		adds r14 = 7, in0 ;;
+		and r14 = -8, r14 ;;
+		cmp.eq p6, p7 = r14, in0
+		(p7) br.cond.dptk 0b
+		shr.u r18 = in2, 3 ;;
+		cmp.ne p6, p7 = 0, r18
+		(p7) br.cond.dpnt 5f ;;
+		(p6) adds r14 = -1, r18
+		(p6) mov r16 = r0
+		(p6) mov r17 = r0 ;;
+		(p6) mov ar.lc = r14
+	
+	4:
+	
+		shladd r14 = r16, 3, r0
+		adds r16 = 1, r17 ;;
+		add r15 = in1, r14
+		add r14 = in0, r14
+		mov r17 = r16 ;;
+		ld8 r15 = [r15] ;;
+		st8 [r14] = r15
+		br.cloop.sptk.few 4b
+	
+	5:
+	
+		and r15 = 7, in2
+		shladd r14 = r18, 3, r0
+		mov r16 = r0
+		mov r18 = r0 ;;
+		cmp.eq p6, p7 = 0, r15
+		add in0 = r14, in0
+		adds r15 = -1, r15
+		add r17 = r14, in1 
+		(p6) br.cond.dpnt 2b ;;
+		mov ar.lc = r15
+	
+	6:
+	
+		add r14 = r16, r17
+		add r15 = r16, in0
+		adds r16 = 1, r18 ;;
+		ld1 r14 = [r14]
+		mov r18 = r16 ;;
+		st1 [r15] = r14
+		br.cloop.sptk.few 6b ;;
+		mov ar.lc = r2
+		mov ar.pfs = loc0
+		br.ret.sptk.many rp
+
 memcpy_from_uspace_failover_address:
 memcpy_to_uspace_failover_address:
-	mov r8 = r0			/* return 0 on failure */
+	/* Return 0 on failure */
+	mov r8 = r0
 	mov ar.pfs = loc0
 	br.ret.sptk.many rp
@@ -136,11 +152,4 @@
 cpu_halt:
 	br cpu_halt
-
-.global panic_printf
-panic_printf:
-	{
-		br.call.sptk.many b0=printf
-	}
-	br halt
 
 /** Switch to userspace - low level code.
@@ -152,9 +161,12 @@
  * @param in4 Value to be stored in IPSR.
  * @param in5 Value to be stored in RSC.
+ *
  */
 .global switch_to_userspace
 switch_to_userspace:
 	alloc loc0 = ar.pfs, 6, 3, 0, 0
-	rsm (PSR_IC_MASK | PSR_I_MASK)		/* disable interruption collection and interrupts */
+	
+	/* Disable interruption collection and interrupts */
+	rsm (PSR_IC_MASK | PSR_I_MASK)
 	srlz.d ;;
 	srlz.i ;;
@@ -163,5 +175,5 @@
 	mov cr.iip = in0
 	mov r12 = in1
-
+	
 	xor r1 = r1, r1
 	
@@ -172,12 +184,12 @@
 	movl loc2 = PFM_MASK ;;
 	and loc1 = loc2, loc1 ;;
-	mov cr.ifs = loc1 ;;			/* prevent decrementing BSP by rfi */
-
+	mov cr.ifs = loc1 ;;  /* prevent decrementing BSP by rfi */
+	
 	invala
 	
 	mov loc1 = ar.rsc ;;
-	and loc1 = ~3, loc1 ;;			
-	mov ar.rsc = loc1 ;;			/* put RSE into enforced lazy mode */
-
+	and loc1 = ~3, loc1 ;;
+	mov ar.rsc = loc1 ;;  /* put RSE into enforced lazy mode */
+	
 	flushrs ;;
 	
@@ -188,2 +200,6 @@
 	
 	rfi ;;
+
+.global early_putchar
+early_putchar:
+	br.ret.sptk.many b0
Index: kernel/arch/ia64/src/debug/stacktrace.c
===================================================================
--- kernel/arch/ia64/src/debug/stacktrace.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/ia64/src/debug/stacktrace.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -37,30 +37,30 @@
 #include <typedefs.h>
 
-bool kernel_frame_pointer_validate(uintptr_t fp)
+bool kernel_stack_trace_context_validate(stack_trace_context_t *ctx)
 {
 	return false;
 }
 
-bool kernel_frame_pointer_prev(uintptr_t fp, uintptr_t *prev)
+bool kernel_frame_pointer_prev(stack_trace_context_t *ctx, uintptr_t *prev)
 {
 	return false;
 }
 
-bool kernel_return_address_get(uintptr_t fp, uintptr_t *ra)
+bool kernel_return_address_get(stack_trace_context_t *ctx, uintptr_t *ra)
 {
 	return false;
 }
 
-bool uspace_frame_pointer_validate(uintptr_t fp)
+bool uspace_stack_trace_context_validate(stack_trace_context_t *ctx)
 {
 	return false;
 }
 
-bool uspace_frame_pointer_prev(uintptr_t fp, uintptr_t *prev)
+bool uspace_frame_pointer_prev(stack_trace_context_t *ctx, uintptr_t *prev)
 {
 	return false;
 }
 
-bool uspace_return_address_get(uintptr_t fp, uintptr_t *ra)
+bool uspace_return_address_get(stack_trace_context_t *ctx, uintptr_t *ra)
 {
 	return false;
Index: kernel/arch/ia64/src/drivers/it.c
===================================================================
--- kernel/arch/ia64/src/drivers/it.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/ia64/src/drivers/it.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -34,5 +34,5 @@
 
 /** Interval Timer driver. */
- 
+
 #include <arch/drivers/it.h>
 #include <arch/interrupt.h>
@@ -45,11 +45,11 @@
 #include <arch.h>
 
-#define IT_SERVICE_CLOCKS	64
+#define IT_SERVICE_CLOCKS  64
 
-#define FREQ_NUMERATOR_SHIFT	32
-#define FREQ_NUMERATOR_MASK	0xffffffff00000000ULL
+#define FREQ_NUMERATOR_SHIFT  32
+#define FREQ_NUMERATOR_MASK   0xffffffff00000000ULL
 
-#define FREQ_DENOMINATOR_SHIFT	0
-#define FREQ_DENOMINATOR_MASK	0xffffffffULL
+#define FREQ_DENOMINATOR_SHIFT  0
+#define FREQ_DENOMINATOR_MASK   0xffffffffULL
 
 uint64_t it_delta;
@@ -63,6 +63,4 @@
 void it_init(void)
 {
-	cr_itv_t itv;
-	
 	if (config.cpu_active == 1) {
 		irq_initialize(&it_irq);
@@ -83,17 +81,19 @@
 	}
 	
-	/* initialize Interval Timer external interrupt vector */
+	/* Initialize Interval Timer external interrupt vector */
+	cr_itv_t itv;
+	
 	itv.value = itv_read();
 	itv.vector = INTERRUPT_TIMER;
 	itv.m = 0;
 	itv_write(itv.value);
-
-	/* set Interval Timer Counter to zero */
+	
+	/* Set Interval Timer Counter to zero */
 	itc_write(0);
 	
-	/* generate first Interval Timer interrupt in IT_DELTA ticks */
+	/* Generate first Interval Timer interrupt in IT_DELTA ticks */
 	itm_write(IT_DELTA);
-
-	/* propagate changes */
+	
+	/* Propagate changes */
 	srlz_d();
 }
@@ -104,4 +104,5 @@
  *
  * @return Always IRQ_ACCEPT.
+ *
  */
 irq_ownership_t it_claim(irq_t *irq)
@@ -113,17 +114,14 @@
 void it_interrupt(irq_t *irq)
 {
-	int64_t c;
-	int64_t m;
-	
 	eoi_write(EOI);
 	
-	m = itm_read();
+	int64_t itm = itm_read();
 	
-	while (1) {
-		c = itc_read();
-		c += IT_SERVICE_CLOCKS;
-
-		m += IT_DELTA;
-		if (m - c < 0)
+	while (true) {
+		int64_t itc = itc_read();
+		itc += IT_SERVICE_CLOCKS;
+		
+		itm += IT_DELTA;
+		if (itm - itc < 0)
 			CPU->missed_clock_ticks++;
 		else
@@ -131,14 +129,14 @@
 	}
 	
-	itm_write(m);
-	srlz_d();				/* propagate changes */
-
+	itm_write(itm);
+	srlz_d();  /* Propagate changes */
+	
 	/*
 	 * We are holding a lock which prevents preemption.
 	 * Release the lock, call clock() and reacquire the lock again.
 	 */
-	spinlock_unlock(&irq->lock);	
+	irq_spinlock_unlock(&irq->lock, false);
 	clock();
-	spinlock_lock(&irq->lock);
+	irq_spinlock_lock(&irq->lock, false);
 }
 
Index: kernel/arch/ia64/src/drivers/ski.c
===================================================================
--- kernel/arch/ia64/src/drivers/ski.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/ia64/src/drivers/ski.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -216,5 +216,5 @@
 		 * self-sufficient.
 		 */
-		sysinfo_set_item_val("fb", NULL, false);
+		sysinfo_set_item_val("fb.kind", NULL, 6);
 		
 		fb_exported = true;
Index: kernel/arch/ia64/src/interrupt.c
===================================================================
--- kernel/arch/ia64/src/interrupt.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/ia64/src/interrupt.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -57,10 +57,11 @@
 #include <putchar.h>
 
-#define VECTORS_64_BUNDLE	20
-#define VECTORS_16_BUNDLE	48
-#define VECTORS_16_BUNDLE_START	0x5000
-#define VECTOR_MAX		0x7f00
-
-#define BUNDLE_SIZE		16
+#define VECTORS_64_BUNDLE        20
+#define VECTORS_16_BUNDLE        48
+#define VECTORS_16_BUNDLE_START  0x5000
+
+#define VECTOR_MAX  0x7f00
+
+#define BUNDLE_SIZE  16
 
 static const char *vector_names_64_bundle[VECTORS_64_BUNDLE] = {
@@ -132,12 +133,6 @@
 }
 
-static void dump_interrupted_context(istate_t *istate)
-{
-	const char *ifa = symtab_fmt_name_lookup(istate->cr_ifa);
-	const char *iipa = symtab_fmt_name_lookup(istate->cr_iipa);
-	const char *iip = symtab_fmt_name_lookup(istate->cr_iip);
-	
-	putchar('\n');
-	printf("Interrupted context dump:\n");
+void istate_decode(istate_t *istate)
+{
 	printf("ar.bsp=%p\tar.bspstore=%p\n", istate->ar_bsp,
 	    istate->ar_bspstore);
@@ -149,8 +144,10 @@
 	    istate->cr_ipsr);
 	
-	printf("cr.iip=%#018llx, #%d\t(%s)\n", istate->cr_iip,
-	    istate->cr_isr.ei, iip);
-	printf("cr.iipa=%#018llx\t(%s)\n", istate->cr_iipa, iipa);
-	printf("cr.ifa=%#018llx\t(%s)\n", istate->cr_ifa, ifa);
+	printf("cr.iip=%#018llx, #%d\t(%s)\n", istate->cr_iip, istate->cr_isr.ei,
+	    symtab_fmt_name_lookup(istate->cr_iip));
+	printf("cr.iipa=%#018llx\t(%s)\n", istate->cr_iipa,
+	    symtab_fmt_name_lookup(istate->cr_iipa));
+	printf("cr.ifa=%#018llx\t(%s)\n", istate->cr_ifa,
+	    symtab_fmt_name_lookup(istate->cr_ifa));
 }
 
@@ -184,7 +181,5 @@
 	
 	fault_if_from_uspace(istate, "General Exception (%s).", desc);
-	
-	dump_interrupted_context(istate);
-	panic("General Exception (%s).", desc);
+	panic_badtrap(istate, vector, "General Exception (%s).", desc);
 }
 
@@ -196,7 +191,6 @@
 	fault_if_from_uspace(istate, "Interruption: %#hx (%s).",
 	    (uint16_t) vector, vector_to_string(vector));
-	dump_interrupted_context(istate);
-	panic("Interruption: %#hx (%s).", (uint16_t) vector,
-	    vector_to_string(vector));
+	panic_badtrap(istate, vector, "Interruption: %#hx (%s).",
+	    (uint16_t) vector, vector_to_string(vector));
 #endif
 }
@@ -218,5 +212,5 @@
 		istate->cr_ipsr.ri++;
 	}
-
+	
 	return syscall_handler(istate->in0, istate->in1, istate->in2,
 	    istate->in3, istate->in4, istate->in5, istate->in6);
@@ -227,23 +221,24 @@
 	fault_if_from_uspace(istate, "Interruption: %#hx (%s).",
 	    (uint16_t) vector, vector_to_string(vector));
-	dump_interrupted_context(istate);
-	panic("Interruption: %#hx (%s).", (uint16_t) vector,
-	    vector_to_string(vector));
+	panic_badtrap(istate, vector, "Interruption: %#hx (%s).",
+	    (uint16_t) vector, vector_to_string(vector));
 }
 
 static void end_of_local_irq(void)
 {
-	asm volatile ("mov cr.eoi=r0;;");
-}
-
+	asm volatile (
+		"mov cr.eoi=r0;;"
+	);
+}
 
 void external_interrupt(uint64_t vector, istate_t *istate)
 {
 	cr_ivr_t ivr;
-	irq_t *irq;
 	
 	ivr.value = ivr_read();
 	srlz_d();
-
+	
+	irq_t *irq;
+	
 	switch (ivr.vector) {
 	case INTERRUPT_SPURIOUS:
@@ -252,5 +247,5 @@
 #endif
 		break;
-
+	
 #ifdef CONFIG_SMP
 	case VECTOR_TLB_SHOOTDOWN_IPI:
@@ -259,10 +254,10 @@
 		break;
 #endif
-
+	
 	case INTERRUPT_TIMER:
 		irq = irq_dispatch_and_lock(ivr.vector);
 		if (irq) {
 			irq->handler(irq);
-			spinlock_unlock(&irq->lock);
+			irq_spinlock_unlock(&irq->lock, false);
 		} else {
 			panic("Unhandled Internal Timer Interrupt (%d).",
@@ -283,5 +278,5 @@
 			if (!irq->preack)
 				end_of_local_irq();
-			spinlock_unlock(&irq->lock);
+			irq_spinlock_unlock(&irq->lock, false);
 		} else {
 			/*
Index: kernel/arch/ia64/src/mm/tlb.c
===================================================================
--- kernel/arch/ia64/src/mm/tlb.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/ia64/src/mm/tlb.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -500,6 +500,5 @@
 		if (as_page_fault(va, PF_ACCESS_EXEC, istate) == AS_PF_FAULT) {
 			fault_if_from_uspace(istate, "Page fault at %p.", va);
-			panic("%s: va=%p, rid=%d, iip=%p.", __func__, va, rid,
-			    istate->cr_iip);
+			panic_memtrap(istate, PF_ACCESS_EXEC, va, NULL);
 		}
 	}
@@ -622,6 +621,5 @@
 		if (as_page_fault(va, PF_ACCESS_READ, istate) == AS_PF_FAULT) {
 			fault_if_from_uspace(istate, "Page fault at %p.", va);
-			panic("%s: va=%p, rid=%d, iip=%p.", __func__, va, rid,
-			    istate->cr_iip);
+			panic_memtrap(istate, PF_ACCESS_UNKNOWN, va, NULL);
 		}
 	}
@@ -671,6 +669,5 @@
 		if (as_page_fault(va, PF_ACCESS_WRITE, istate) == AS_PF_FAULT) {
 			fault_if_from_uspace(istate, "Page fault at %p.", va);
-			panic("%s: va=%p, rid=%d, iip=%p.", __func__, va, rid,
-			    istate->cr_iip);
+			panic_memtrap(istate, PF_ACCESS_WRITE, va, NULL);
 		}
 	}
@@ -708,6 +705,5 @@
 		if (as_page_fault(va, PF_ACCESS_EXEC, istate) == AS_PF_FAULT) {
 			fault_if_from_uspace(istate, "Page fault at %p.", va);
-			panic("%s: va=%p, rid=%d, iip=%p.", __func__, va, rid,
-			    istate->cr_iip);
+			panic_memtrap(istate, PF_ACCESS_EXEC, va, NULL);
 		}
 	}
@@ -745,6 +741,5 @@
 		if (as_page_fault(va, PF_ACCESS_READ, istate) == AS_PF_FAULT) {
 			fault_if_from_uspace(istate, "Page fault at %p.", va);
-			panic("%s: va=%p, rid=%d, iip=%p.", __func__, va, rid,
-			    istate->cr_iip);
+			panic_memtrap(istate, PF_ACCESS_UNKNOWN, va, NULL);
 		}
 	}
@@ -778,6 +773,5 @@
 	if (as_page_fault(va, PF_ACCESS_WRITE, istate) == AS_PF_FAULT) {
 		fault_if_from_uspace(istate, "Page fault at %p.", va);
-		panic("%s: va=%p, rid=%d, iip=%p.", __func__, va, rid,
-		    istate->cr_iip);
+		panic_memtrap(istate, PF_ACCESS_WRITE, va, NULL);
 	}
 	page_table_unlock(AS, true);
@@ -819,5 +813,5 @@
 		if (as_page_fault(va, PF_ACCESS_READ, istate) == AS_PF_FAULT) {
 			fault_if_from_uspace(istate, "Page fault at %p.", va);
-			panic("%s: va=%p, rid=%d.", __func__, va, rid);
+			panic_memtrap(istate, PF_ACCESS_UNKNOWN, va, NULL);
 		}
 	}
Index: kernel/arch/ia64/src/smp/smp.c
===================================================================
--- kernel/arch/ia64/src/smp/smp.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/ia64/src/smp/smp.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -33,130 +33,19 @@
  */
 
-#include <arch.h>
-#include <arch/drivers/ski.h>
-#include <arch/drivers/it.h>
-#include <arch/interrupt.h>
-#include <arch/barrier.h>
-#include <arch/asm.h>
-#include <arch/register.h>
-#include <typedefs.h>
-#include <arch/context.h>
-#include <arch/stack.h>
-#include <arch/mm/page.h>
-#include <mm/as.h>
-#include <config.h>
-#include <userspace.h>
-#include <console/console.h>
-#include <proc/uarg.h>
-#include <syscall/syscall.h>
-#include <ddi/irq.h>
-#include <ddi/device.h>
-#include <arch/bootinfo.h>
 #include <smp/smp.h>
 #include <smp/ipi.h>
-#include <arch/atomic.h>
-#include <panic.h>
-#include <print.h>
 
 #ifdef CONFIG_SMP
 
-extern char cpu_by_id_eid_list[256][256];
-
-static void sapic_init(void)
+void ipi_broadcast_arch(int ipi)
 {
-	bootinfo->sapic = (unative_t *)(PA2KA((unative_t)(bootinfo->sapic)) |
-	    FW_OFFSET);
-}
-
-static void ipi_broadcast_arch_all(int ipi)
-{
-	int id, eid;
-	int myid, myeid;
-	
-	myid = ia64_get_cpu_id();
-	myeid = ia64_get_cpu_eid();
-	
-	for (id = 0; id < 256; id++)
-		for (eid = 0; eid < 256; eid++)
-			if ((id != myid) || (eid != myeid))
-				ipi_send_ipi(id, eid, ipi);
-}
-
-void ipi_broadcast_arch(int ipi )
-{
-	int id, eid;
-	int myid, myeid;
-	
-	myid = ia64_get_cpu_id();
-	myeid = ia64_get_cpu_eid();
-
-	for (id = 0; id < 256; id++)
-		for (eid = 0; eid < 256; eid++)
-			if ((id != myid) || (eid != myeid))
-				if (cpu_by_id_eid_list[id][eid])
-					ipi_send_ipi(id, eid, ipi);
 }
 
 void smp_init(void)
 {
-	if (!bootinfo->hello_configured)
-		return; 
-	
-	/*
-	 * If we have not got system prepared by hello, we are not able to start
-	 * AP's. This means we are running on a simulator.
-	 */
-	
-	sapic_init();
-	ipi_broadcast_arch_all(bootinfo->wakeup_intno);	
-	volatile long long brk;
-        for (brk = 0; brk < 100LL * 1024LL * 1024LL; brk++)
-		;	/* wait a while before CPUs starts */
-
-	config.cpu_count = 0;
-	int id, eid;
-	
-	for (id = 0; id < 256; id++)
-		for (eid = 0; eid < 256; eid++)
-		        if (cpu_by_id_eid_list[id][eid] == 1) {
-		    		config.cpu_count++;
-		    		cpu_by_id_eid_list[id][eid] = 2;
-			}
 }
 
 void kmp(void *arg __attribute__((unused)))
 {
-	int id, eid;
-	int myid, myeid;
-	
-	myid = ia64_get_cpu_id();
-	myeid = ia64_get_cpu_eid();
-
-	for (id = 0; id < 256; id++)
-		for (eid = 0; eid < 256; eid++)
-		        if ((id != myid) || (eid != myeid))
-		        	if (cpu_by_id_eid_list[id][eid] != 0) {
-		    			if (cpu_by_id_eid_list[id][eid] == 1) {
-				    		printf("Found Late CPU ID:%d "
-						    "EDI:%d Not added to "
-						    "system!!!\n", id, eid);
-				    		continue;
-					}
-					cpu_by_id_eid_list[id][eid] = 3;
-					/*
-					 * There may be just one AP being
-					 * initialized at the time. After
-					 * it comes completely up, it is
-					 * supposed to wake us up.
-					 */
-					if (waitq_sleep_timeout(
-					    &ap_completion_wq, 1000000,
-					    SYNCH_FLAGS_NONE) ==
-					    ESYNCH_TIMEOUT) {
-						printf("%s: waiting for cpu "
-						    "ID:%d EID:%d timed out\n",
-						    __FUNCTION__, id, eid);
-					    }
-				}
 }
 
Index: kernel/arch/ia64/src/start.S
===================================================================
--- kernel/arch/ia64/src/start.S	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/ia64/src/start.S	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -47,19 +47,15 @@
 
 stack0:
+
+#
+# Kernel entry point.
+#
+# This is where we are passed control from the boot code.
+# Register contents:
+#
+#	r2	Address of the boot code's bootinfo structure.
+#
 kernel_image_start:
 	.auto
-	
-#ifdef CONFIG_SMP
-	# Identify self(CPU) in OS structures by ID / EID
-	
-	mov r9 = cr64
-	mov r10 = 1
-	movl r12 = 0xffffffff
-	movl r8 = cpu_by_id_eid_list
-	and r8 = r8, r12
-	shr r9 = r9, 16
-	add r8 = r8, r9
-	st1 [r8] = r10
-#endif
 	
 	mov psr.l = r0
@@ -164,13 +160,4 @@
 	bsw.1
 	
-#ifdef CONFIG_SMP
-	# Am I BSP or AP?
-	movl r20 = bsp_started ;;
-	ld8 r20 = [r20] ;;
-	cmp.eq p3, p2 = r20, r0 ;;
-#else
-	cmp.eq p3, p2 = r0, r0 ;;  /* you are BSP */
-#endif  /* CONFIG_SMP */
-	
 	# Initialize register stack
 	mov ar.rsc = r0
@@ -179,18 +166,21 @@
 	loadrs
 	
-	# Initialize memory stack to some sane value
-	movl r12 = stack0 ;;
-	add r12 = -16, r12  /* allocate a scratch area on the stack */
+	#
+	# Initialize memory stack to some sane value and allocate a scratch are
+	# on it.
+	#
+	movl sp = stack0 ;;
+	add sp = -16, sp
 	
 	# Initialize gp (Global Pointer) register
+	movl gp = kernel_image_start
+	
+	#	
+	# Initialize bootinfo on BSP.
+	#
 	movl r20 = (VRN_KERNEL << VRN_SHIFT) ;;
-	or r20 = r20, r1 ;;
-	movl r1 = kernel_image_start
-	
-	/*
-	 * Initialize bootinfo on BSP.
-	 */
-(p3)	addl r21 = @gprel(bootinfo), gp ;;
-(p3)	st8 [r21] = r20
+	or r20 = r20, r2 ;;
+	addl r21 = @gprel(bootinfo), gp ;;
+	st8 [r21] = r20
 	
 	ssm (1 << 19) ;; /* Disable f32 - f127 */
@@ -198,68 +188,7 @@
 	srlz.d ;;
 	
-#ifdef CONFIG_SMP
-(p2)	movl r18 = main_ap ;;
-(p2)	mov b1 = r18 ;;
-(p2)	br.call.sptk.many b0 = b1
-	
-	# Mark that BSP is on
-	
-	mov r20 = 1 ;;
-	movl r21 = bsp_started ;;
-	st8 [r21] = r20 ;;
-#endif
-	
 	br.call.sptk.many b0 = arch_pre_main
-	
-	movl r18 = main_bsp ;;
-	mov b1 = r18 ;;
-	br.call.sptk.many b0 = b1
-
+0:
+	br.call.sptk.many b0 = main_bsp
 0:
 	br 0b
-
-#ifdef CONFIG_SMP
-
-.align 4096
-kernel_image_ap_start:
-	.auto
-	
-	# Identify self(CPU) in OS structures by ID / EID
-	
-	mov r9 = cr64
-	mov r10 = 1
-	movl r12 = 0xffffffff
-	movl r8 = cpu_by_id_eid_list
-	and r8 = r8, r12
-	shr r9 = r9, 16
-	add r8 = r8, r9
-	st1 [r8] = r10
-	
-	# Wait for wakeup synchro signal (#3 in cpu_by_id_eid_list)
-
-kernel_image_ap_start_loop:
-	movl r11 = kernel_image_ap_start_loop
-	and r11 = r11, r12
-	mov b1 = r11
-	
-	ld1 r20 = [r8]
-	movl r21 = 3
-	cmp.eq p2, p3 = r20, r21
-(p3)	br.call.sptk.many b0 = b1
-	
-	movl r11 = kernel_image_start
-	and r11 = r11, r12
-	mov b1 = r11
-	br.call.sptk.many b0 = b1
-
-.align 16
-.global bsp_started
-bsp_started:
-	.space 8
-
-.align 4096
-.global cpu_by_id_eid_list
-cpu_by_id_eid_list:
-	.space 65536
-
-#endif  /* CONFIG_SMP */
Index: kernel/arch/mips32/Makefile.inc
===================================================================
--- kernel/arch/mips32/Makefile.inc	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/mips32/Makefile.inc	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -54,5 +54,4 @@
 	arch/$(KARCH)/src/start.S \
 	arch/$(KARCH)/src/context.S \
-	arch/$(KARCH)/src/panic.S \
 	arch/$(KARCH)/src/mips32.c \
 	arch/$(KARCH)/src/asm.S \
Index: kernel/arch/mips32/include/asm.h
===================================================================
--- kernel/arch/mips32/include/asm.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/mips32/include/asm.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -27,5 +27,5 @@
  */
 
-/** @addtogroup mips32	
+/** @addtogroup mips32
  * @{
  */
@@ -38,71 +38,77 @@
 #include <typedefs.h>
 #include <config.h>
+#include <trace.h>
 
-
-static inline void cpu_sleep(void)
+NO_TRACE static inline void cpu_sleep(void)
 {
-	/* Most of the simulators do not support */
-/*	asm volatile ("wait"); */
+	/*
+	 * Unfortunatelly most of the simulators do not support
+	 *
+	 * asm volatile (
+	 *     "wait"
+	 * );
+	 *
+	 */
 }
 
 /** Return base address of current stack
- * 
+ *
  * Return the base address of the current stack.
  * The stack is assumed to be STACK_SIZE bytes long.
  * The stack must start on page boundary.
+ *
  */
-static inline uintptr_t get_stack_base(void)
+NO_TRACE static inline uintptr_t get_stack_base(void)
 {
-	uintptr_t v;
+	uintptr_t base;
 	
 	asm volatile (
-		"and %0, $29, %1\n"
-		: "=r" (v)
-		: "r" (~(STACK_SIZE-1))
+		"and %[base], $29, %[mask]\n"
+		: [base] "=r" (base)
+		: [mask] "r" (~(STACK_SIZE - 1))
 	);
 	
-	return v;
+	return base;
 }
 
-extern void cpu_halt(void) __attribute__((noreturn));
-extern void asm_delay_loop(uint32_t t);
-extern void userspace_asm(uintptr_t ustack, uintptr_t uspace_uarg,
-    uintptr_t entry);
-
-extern ipl_t interrupts_disable(void);
-extern ipl_t interrupts_enable(void);
-extern void interrupts_restore(ipl_t ipl);
-extern ipl_t interrupts_read(void);
-extern void asm_delay_loop(uint32_t t);
-
-static inline void pio_write_8(ioport8_t *port, uint8_t v)
+NO_TRACE static inline void pio_write_8(ioport8_t *port, uint8_t v)
 {
-	*port = v;	
+	*port = v;
 }
 
-static inline void pio_write_16(ioport16_t *port, uint16_t v)
+NO_TRACE static inline void pio_write_16(ioport16_t *port, uint16_t v)
 {
-	*port = v;	
+	*port = v;
 }
 
-static inline void pio_write_32(ioport32_t *port, uint32_t v)
+NO_TRACE static inline void pio_write_32(ioport32_t *port, uint32_t v)
 {
-	*port = v;	
+	*port = v;
 }
 
-static inline uint8_t pio_read_8(ioport8_t *port)
+NO_TRACE static inline uint8_t pio_read_8(ioport8_t *port)
 {
 	return *port;
 }
 
-static inline uint16_t pio_read_16(ioport16_t *port)
+NO_TRACE static inline uint16_t pio_read_16(ioport16_t *port)
 {
 	return *port;
 }
 
-static inline uint32_t pio_read_32(ioport32_t *port)
+NO_TRACE static inline uint32_t pio_read_32(ioport32_t *port)
 {
 	return *port;
 }
+
+extern void cpu_halt(void) __attribute__((noreturn));
+extern void asm_delay_loop(uint32_t);
+extern void userspace_asm(uintptr_t, uintptr_t, uintptr_t);
+
+extern ipl_t interrupts_disable(void);
+extern ipl_t interrupts_enable(void);
+extern void interrupts_restore(ipl_t);
+extern ipl_t interrupts_read(void);
+extern bool interrupts_disabled(void);
 
 #endif
Index: kernel/arch/mips32/include/atomic.h
===================================================================
--- kernel/arch/mips32/include/atomic.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/mips32/include/atomic.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -36,4 +36,6 @@
 #define KERN_mips32_ATOMIC_H_
 
+#include <trace.h>
+
 #define atomic_inc(x)  ((void) atomic_add(x, 1))
 #define atomic_dec(x)  ((void) atomic_add(x, -1))
@@ -53,5 +55,6 @@
  *
  */
-static inline atomic_count_t atomic_add(atomic_t *val, atomic_count_t i)
+NO_TRACE static inline atomic_count_t atomic_add(atomic_t *val,
+    atomic_count_t i)
 {
 	atomic_count_t tmp;
@@ -76,5 +79,5 @@
 }
 
-static inline atomic_count_t test_and_set(atomic_t *val)
+NO_TRACE static inline atomic_count_t test_and_set(atomic_t *val)
 {
 	atomic_count_t tmp;
@@ -98,5 +101,5 @@
 }
 
-static inline void atomic_lock_arch(atomic_t *val)
+NO_TRACE static inline void atomic_lock_arch(atomic_t *val)
 {
 	do {
Index: kernel/arch/mips32/include/barrier.h
===================================================================
--- kernel/arch/mips32/include/barrier.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/mips32/include/barrier.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -27,5 +27,5 @@
  */
 
-/** @addtogroup mips32	
+/** @addtogroup mips32
  * @{
  */
@@ -39,10 +39,10 @@
  * TODO: implement true MIPS memory barriers for macros below.
  */
-#define CS_ENTER_BARRIER()	asm volatile ("" ::: "memory")
-#define CS_LEAVE_BARRIER()	asm volatile ("" ::: "memory")
+#define CS_ENTER_BARRIER()  asm volatile ("" ::: "memory")
+#define CS_LEAVE_BARRIER()  asm volatile ("" ::: "memory")
 
-#define memory_barrier()        asm volatile ("" ::: "memory")
-#define read_barrier()          asm volatile ("" ::: "memory")
-#define write_barrier()         asm volatile ("" ::: "memory")
+#define memory_barrier() asm volatile ("" ::: "memory")
+#define read_barrier()   asm volatile ("" ::: "memory")
+#define write_barrier()  asm volatile ("" ::: "memory")
 
 #define smc_coherence(a)
Index: kernel/arch/mips32/include/context_offset.h
===================================================================
--- kernel/arch/mips32/include/context_offset.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/mips32/include/context_offset.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -60,32 +60,4 @@
 # define OFFSET_F30     0x5c
 #endif /* KERNEL */
-
-/* istate_t */
-#define EOFFSET_AT     0x0
-#define EOFFSET_V0     0x4
-#define EOFFSET_V1     0x8
-#define EOFFSET_A0     0xc
-#define EOFFSET_A1     0x10
-#define EOFFSET_A2     0x14
-#define EOFFSET_A3     0x18
-#define EOFFSET_T0     0x1c
-#define EOFFSET_T1     0x20
-#define EOFFSET_T2     0x24
-#define EOFFSET_T3     0x28
-#define EOFFSET_T4     0x2c
-#define EOFFSET_T5     0x30
-#define EOFFSET_T6     0x34
-#define EOFFSET_T7     0x38
-#define EOFFSET_T8     0x3c
-#define EOFFSET_T9     0x40
-#define EOFFSET_GP     0x44
-#define EOFFSET_SP     0x48
-#define EOFFSET_RA     0x4c
-#define EOFFSET_LO     0x50
-#define EOFFSET_HI     0x54
-#define EOFFSET_STATUS 0x58
-#define EOFFSET_EPC    0x5c
-#define EOFFSET_K1     0x60
-#define REGISTER_SPACE 104	/* respect stack alignment */
 
 #ifdef __ASM__
Index: kernel/arch/mips32/include/cp0.h
===================================================================
--- kernel/arch/mips32/include/cp0.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/mips32/include/cp0.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -38,10 +38,10 @@
 #include <typedefs.h>
 
-#define cp0_status_ie_enabled_bit	(1 << 0)
-#define cp0_status_exl_exception_bit	(1 << 1)
-#define cp0_status_erl_error_bit	(1 << 2)
-#define cp0_status_um_bit	        (1 << 4)
-#define cp0_status_bev_bootstrap_bit	(1 << 22)
-#define cp0_status_fpu_bit              (1 << 29)
+#define cp0_status_ie_enabled_bit     (1 << 0)
+#define cp0_status_exl_exception_bit  (1 << 1)
+#define cp0_status_erl_error_bit      (1 << 2)
+#define cp0_status_um_bit             (1 << 4)
+#define cp0_status_bev_bootstrap_bit  (1 << 22)
+#define cp0_status_fpu_bit            (1 << 29)
 
 #define cp0_status_im_shift		8
Index: kernel/arch/mips32/include/cycle.h
===================================================================
--- kernel/arch/mips32/include/cycle.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/mips32/include/cycle.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -38,6 +38,7 @@
 #include <arch/cp0.h>
 #include <arch/interrupt.h>
+#include <trace.h>
 
-static inline uint64_t get_cycle(void)
+NO_TRACE static inline uint64_t get_cycle(void)
 {
 	return ((uint64_t) count_hi << 32) + ((uint64_t) cp0_count_read());
Index: kernel/arch/mips32/include/debug.h
===================================================================
--- kernel/arch/mips32/include/debug.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/mips32/include/debug.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -36,14 +36,18 @@
 #define KERN_mips23_DEBUG_H_
 
-/**	simulator enters the trace mode */
-#define ___traceon()	asm volatile ( "\t.word\t0x39\n");
-/** 	simulator leaves the trace mode */
-#define ___traceoff()	asm volatile ( "\t.word\t0x3d\n");
-/** 	register dump */
-#define ___regview()	asm volatile ( "\t.word\t0x37\n");
-/** 	halt the simulator */
-#define ___halt()	asm volatile ( "\t.word\t0x28\n");
-/**     simulator enters interactive mode */
-#define ___intmode()	asm volatile ( "\t.word\t0x29\n");
+/** Enter the simulator trace mode */
+#define ___traceon()  asm volatile ( "\t.word\t0x39\n");
+
+/** Leave the simulator trace mode */
+#define ___traceoff()  asm volatile ( "\t.word\t0x3d\n");
+
+/** Ask the simulator to dump registers */
+#define ___regview()  asm volatile ( "\t.word\t0x37\n");
+
+/** Halt the simulator */
+#define ___halt()  asm volatile ( "\t.word\t0x28\n");
+
+/** Enter the simulator interactive mode */
+#define ___intmode()  asm volatile ( "\t.word\t0x29\n");
 
 #endif
Index: kernel/arch/mips32/include/debugger.h
===================================================================
--- kernel/arch/mips32/include/debugger.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/mips32/include/debugger.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -41,25 +41,35 @@
 #define BKPOINTS_MAX 10
 
-#define BKPOINT_INPROG   (1 << 0)   /**< Breakpoint was shot */
-#define BKPOINT_ONESHOT  (1 << 1)   /**< One-time breakpoint,mandatory for j/b
-				         instructions */
-#define BKPOINT_REINST   (1 << 2)   /**< Breakpoint is set on the next 
-				         instruction, so that it could be
-					 reinstalled on the previous one */
-#define BKPOINT_FUNCCALL (1 << 3)   /**< Call a predefined function */
+/** Breakpoint was shot */
+#define BKPOINT_INPROG  (1 << 0)
+
+/** One-time breakpoint, mandatory for j/b instructions */
+#define BKPOINT_ONESHOT  (1 << 1)
+
+/**
+ * Breakpoint is set on the next instruction, so that it
+ * could be reinstalled on the previous one
+ */
+#define BKPOINT_REINST  (1 << 2)
+
+/** Call a predefined function */
+#define BKPOINT_FUNCCALL  (1 << 3)
+
 
 typedef struct  {
-	uintptr_t address;      /**< Breakpoint address */
-	unative_t instruction; /**< Original instruction */
+	uintptr_t address;          /**< Breakpoint address */
+	unative_t instruction;      /**< Original instruction */
 	unative_t nextinstruction;  /**< Original instruction following break */
-	int flags;        /**< Flags regarding breakpoint */
+	unsigned int flags;         /**< Flags regarding breakpoint */
 	size_t counter;
-	void (*bkfunc)(void *b, istate_t *istate);
+	void (*bkfunc)(void *, istate_t *);
 } bpinfo_t;
 
+extern bpinfo_t breakpoints[BKPOINTS_MAX];
+
+extern bool is_jump(unative_t);
+
 extern void debugger_init(void);
-void debugger_bpoint(istate_t *istate);
-
-extern bpinfo_t breakpoints[BKPOINTS_MAX];
+extern void debugger_bpoint(istate_t *);
 
 #endif
Index: kernel/arch/mips32/include/exception.h
===================================================================
--- kernel/arch/mips32/include/exception.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/mips32/include/exception.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -27,5 +27,5 @@
  */
 
-/** @addtogroup mips32	
+/** @addtogroup mips32
  * @{
  */
@@ -38,34 +38,39 @@
 #include <typedefs.h>
 #include <arch/cp0.h>
+#include <trace.h>
 
-#define EXC_Int		0
-#define EXC_Mod		1
-#define EXC_TLBL	2
-#define EXC_TLBS	3
-#define EXC_AdEL	4
-#define EXC_AdES	5
-#define EXC_IBE		6
-#define EXC_DBE		7
-#define EXC_Sys		8
-#define EXC_Bp		9
-#define EXC_RI		10
-#define EXC_CpU		11
-#define EXC_Ov		12
-#define EXC_Tr		13
-#define EXC_VCEI	14
-#define EXC_FPE		15
-#define EXC_WATCH	23
-#define EXC_VCED	31
+#define EXC_Int    0
+#define EXC_Mod    1
+#define EXC_TLBL   2
+#define EXC_TLBS   3
+#define EXC_AdEL   4
+#define EXC_AdES   5
+#define EXC_IBE    6
+#define EXC_DBE    7
+#define EXC_Sys    8
+#define EXC_Bp     9
+#define EXC_RI     10
+#define EXC_CpU    11
+#define EXC_Ov     12
+#define EXC_Tr     13
+#define EXC_VCEI   14
+#define EXC_FPE    15
+#define EXC_WATCH  23
+#define EXC_VCED   31
 
 typedef struct istate {
+	/*
+	 * The first seven registers are arranged so that the istate structure
+	 * can be used both for exception handlers and for the syscall handler.
+	 */
+	uint32_t a0;	/* arg1 */
+	uint32_t a1;	/* arg2 */
+	uint32_t a2;	/* arg3 */
+	uint32_t a3;	/* arg4 */
+	uint32_t t0;	/* arg5 */
+	uint32_t t1;	/* arg6 */
+	uint32_t v0;	/* arg7 */
+	uint32_t v1;
 	uint32_t at;
-	uint32_t v0;
-	uint32_t v1;
-	uint32_t a0;
-	uint32_t a1;
-	uint32_t a2;
-	uint32_t a3;
-	uint32_t t0;
-	uint32_t t1;
 	uint32_t t2;
 	uint32_t t3;
@@ -74,19 +79,32 @@
 	uint32_t t6;
 	uint32_t t7;
+	uint32_t s0;
+	uint32_t s1;
+	uint32_t s2;
+	uint32_t s3;
+	uint32_t s4;
+	uint32_t s5;
+	uint32_t s6;
+	uint32_t s7;
 	uint32_t t8;
 	uint32_t t9;
+	uint32_t kt0;
+	uint32_t kt1;	/* We use it as thread-local pointer */
 	uint32_t gp;
 	uint32_t sp;
+	uint32_t s8;
 	uint32_t ra;
 	
 	uint32_t lo;
 	uint32_t hi;
+	
+	uint32_t status;	/* cp0_status */
+	uint32_t epc;		/* cp0_epc */
 
-	uint32_t status; /* cp0_status */
-	uint32_t epc; /* cp0_epc */
-	uint32_t k1; /* We use it as thread-local pointer */
+	uint32_t alignment;	/* to make sizeof(istate_t) a multiple of 8 */
 } istate_t;
 
-static inline void istate_set_retaddr(istate_t *istate, uintptr_t retaddr)
+NO_TRACE static inline void istate_set_retaddr(istate_t *istate,
+    uintptr_t retaddr)
 {
 	istate->epc = retaddr;
@@ -94,15 +112,17 @@
 
 /** Return true if exception happened while in userspace */
-static inline int istate_from_uspace(istate_t *istate)
+NO_TRACE static inline int istate_from_uspace(istate_t *istate)
 {
 	return istate->status & cp0_status_um_bit;
 }
-static inline unative_t istate_get_pc(istate_t *istate)
+
+NO_TRACE static inline unative_t istate_get_pc(istate_t *istate)
 {
 	return istate->epc;
 }
-static inline unative_t istate_get_fp(istate_t *istate)
+
+NO_TRACE static inline unative_t istate_get_fp(istate_t *istate)
 {
-	return 0;	/* FIXME */
+	return istate->sp;
 }
 
Index: kernel/arch/mips32/include/faddr.h
===================================================================
--- kernel/arch/mips32/include/faddr.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/mips32/include/faddr.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -27,5 +27,5 @@
  */
 
-/** @addtogroup mips32	
+/** @addtogroup mips32
  * @{
  */
@@ -38,5 +38,5 @@
 #include <typedefs.h>
 
-#define FADDR(fptr)		((uintptr_t) (fptr))
+#define FADDR(fptr)  ((uintptr_t) (fptr))
 
 #endif
Index: kernel/arch/mips32/include/mm/as.h
===================================================================
--- kernel/arch/mips32/include/mm/as.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/mips32/include/mm/as.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -27,5 +27,5 @@
  */
 
-/** @addtogroup mips32mm	
+/** @addtogroup mips32mm
  * @{
  */
@@ -36,5 +36,5 @@
 #define KERN_mips32_AS_H_
 
-#define KERNEL_ADDRESS_SPACE_SHADOWED_ARCH	0
+#define KERNEL_ADDRESS_SPACE_SHADOWED_ARCH  0
 
 #define KERNEL_ADDRESS_SPACE_START_ARCH		(unsigned long) 0x80000000
Index: kernel/arch/mips32/include/mm/page.h
===================================================================
--- kernel/arch/mips32/include/mm/page.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/mips32/include/mm/page.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -37,4 +37,5 @@
 
 #include <arch/mm/frame.h>
+#include <trace.h>
 
 #define PAGE_WIDTH	FRAME_WIDTH
@@ -155,5 +156,5 @@
 
 
-static inline unsigned int get_pt_flags(pte_t *pt, size_t i)
+NO_TRACE static inline unsigned int get_pt_flags(pte_t *pt, size_t i)
 {
 	pte_t *p = &pt[i];
@@ -168,5 +169,5 @@
 }
 
-static inline void set_pt_flags(pte_t *pt, size_t i, int flags)
+NO_TRACE static inline void set_pt_flags(pte_t *pt, size_t i, int flags)
 {
 	pte_t *p = &pt[i];
Index: kernel/arch/mips32/include/mm/tlb.h
===================================================================
--- kernel/arch/mips32/include/mm/tlb.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/mips32/include/mm/tlb.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -39,4 +39,5 @@
 #include <arch/mm/asid.h>
 #include <arch/exception.h>
+#include <trace.h>
 
 #define TLB_ENTRY_COUNT  48
@@ -126,5 +127,5 @@
  * Probe TLB for Matching Entry.
  */
-static inline void tlbp(void)
+NO_TRACE static inline void tlbp(void)
 {
 	asm volatile ("tlbp\n\t");
@@ -136,5 +137,5 @@
  * Read Indexed TLB Entry.
  */
-static inline void tlbr(void)
+NO_TRACE static inline void tlbr(void)
 {
 	asm volatile ("tlbr\n\t");
@@ -145,5 +146,5 @@
  * Write Indexed TLB Entry.
  */
-static inline void tlbwi(void)
+NO_TRACE static inline void tlbwi(void)
 {
 	asm volatile ("tlbwi\n\t");
@@ -154,5 +155,5 @@
  * Write Random TLB Entry.
  */
-static inline void tlbwr(void)
+NO_TRACE static inline void tlbwr(void)
 {
 	asm volatile ("tlbwr\n\t");
Index: kernel/arch/mips32/include/smp/dorder.h
===================================================================
--- kernel/arch/mips32/include/smp/dorder.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
+++ kernel/arch/mips32/include/smp/dorder.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2007 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 mips32
+ * @{
+ */
+/** @file
+ */
+
+#ifndef KERN_mips32_DORDER_H_
+#define KERN_mips32_DORDER_H_
+
+#include <typedefs.h>
+
+extern uint32_t dorder_cpuid(void);
+extern void dorder_ipi_ack(uint32_t);
+
+#endif
+
+/** @}
+ */
Index: kernel/arch/mips32/src/asm.S
===================================================================
--- kernel/arch/mips32/src/asm.S	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/mips32/src/asm.S	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -1,29 +1,29 @@
-#
-# 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.
-#
+/*
+ * Copyright (c) 2003 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 <arch/asm/regname.h>
@@ -57,5 +57,4 @@
 	nop
 
-
 .global memsetb
 memsetb:
@@ -63,10 +62,8 @@
 	nop
 
-
 .global memsetw
 memsetw:
 	j _memsetw
 	nop
-
 
 .global memcpy
@@ -78,8 +75,8 @@
 memcpy_from_uspace:
 memcpy_to_uspace:
-	move $t2, $a0      # save dst
+	move $t2, $a0  /* save dst */
 	
 	addiu $v0, $a1, 3
-	li $v1, -4         # 0xfffffffffffffffc
+	li $v1, -4  /* 0xfffffffffffffffc */
 	and $v0, $v0, $v1
 	beq $a1, $v0, 3f
@@ -149,6 +146,4 @@
 	move $v0, $zero
 
-
-
 .macro fpu_gp_save reg ctx
 	mfc1 $t0, $\reg
@@ -164,5 +159,5 @@
 	cfc1 $t0, $1
 	sw $t0, (\reg + 32) * 4(\ctx)
-.endm	
+.endm
 
 .macro fpu_ct_restore reg ctx
@@ -170,5 +165,4 @@
 	ctc1 $t0, $\reg
 .endm
-
 
 .global fpu_context_save
@@ -313,2 +307,7 @@
 	j $ra
 	nop
+
+.global early_putchar
+early_putchar:
+	j $ra
+	nop
Index: kernel/arch/mips32/src/context.S
===================================================================
--- kernel/arch/mips32/src/context.S	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/mips32/src/context.S	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -28,6 +28,6 @@
 
 #include <arch/context_offset.h>
-	
-.text   
+
+.text
 
 .set noat
@@ -38,16 +38,15 @@
 .global context_restore_arch
 
-	
 context_save_arch:
 	CONTEXT_SAVE_ARCH_CORE $a0
-
+	
 	# context_save returns 1
 	j $31
-	li $2, 1	
-	
+	li $2, 1
+
 context_restore_arch:
 	CONTEXT_RESTORE_ARCH_CORE $a0
-
+	
 	# context_restore returns 0
 	j $31
-	xor $2, $2	
+	xor $2, $2
Index: kernel/arch/mips32/src/debug/stacktrace.c
===================================================================
--- kernel/arch/mips32/src/debug/stacktrace.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/mips32/src/debug/stacktrace.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -33,38 +33,242 @@
  */
 
+/*
+ * This stack tracing code is based on the suggested algorithm described on page
+ * 3-27 and 3-28 of:
+ * 
+ * SYSTEM V
+ * APPLICATION BINARY INTERFACE
+ *
+ * MIPS RISC Processor
+ * Supplement
+ * 3rd Edition
+ *
+ * Unfortunately, GCC generates code which is not entirely compliant with this
+ * method. For example, it places the "jr ra" instruction quite arbitrarily in
+ * the middle of the function which makes the original algorithm unapplicable.
+ *
+ * We deal with this problem by simply not using those parts of the algorithm
+ * that rely on the "jr ra" instruction occurring in the last basic block of a
+ * function, which gives us still usable, but less reliable stack tracer. The
+ * unreliability stems from the fact that under some circumstances it can become
+ * confused and produce incorrect or incomplete stack trace. We apply extra
+ * sanity checks so that the algorithm is still safe and should not crash the
+ * system.
+ *
+ * Even though not perfect, our solution is pretty lightweight, especially when
+ * compared with a prospective alternative solution based on additional
+ * debugging information stored directly in the kernel image.
+ */
+
 #include <stacktrace.h>
 #include <syscall/copy.h>
 #include <typedefs.h>
-
-bool kernel_frame_pointer_validate(uintptr_t fp)
+#include <arch/debugger.h>
+#include <print.h>
+
+#define R0	0U
+#define SP	29U
+#define RA	31U
+
+#define OP_SHIFT	26
+#define RS_SHIFT	21
+#define RT_SHIFT	16
+#define RD_SHIFT	11
+
+#define HINT_SHIFT	6
+#define BASE_SHIFT	RS_SHIFT
+#define IMM_SHIFT	0
+#define OFFSET_SHIFT	IMM_SHIFT
+
+#define RS_MASK		(0x1f << RS_SHIFT)
+#define RT_MASK		(0x1f << RT_SHIFT)
+#define RD_MASK		(0x1f << RD_SHIFT)
+#define HINT_MASK	(0x1f << HINT_SHIFT)
+#define BASE_MASK	RS_MASK
+#define IMM_MASK	(0xffff << IMM_SHIFT)
+#define OFFSET_MASK	IMM_MASK	
+
+#define RS_GET(inst)		(((inst) & RS_MASK) >> RS_SHIFT)
+#define RD_GET(inst)		(((inst) & RD_MASK) >> RD_SHIFT)
+#define IMM_GET(inst)		(int16_t)(((inst) & IMM_MASK) >> IMM_SHIFT)
+#define BASE_GET(inst)		RS_GET(inst)
+#define OFFSET_GET(inst)	IMM_GET(inst)	
+
+#define ADDU_R_SP_R0_TEMPL \
+	((0x0 << OP_SHIFT) | (SP << RS_SHIFT) | (R0 << RT_SHIFT) | 0x21)
+#define ADDU_SP_R_R0_TEMPL \
+	((0x0 << OP_SHIFT) | (SP << RD_SHIFT) | (R0 << RT_SHIFT) | 0x21)
+#define ADDI_SP_SP_IMM_TEMPL \
+	((0x8 << OP_SHIFT) | (SP << RS_SHIFT) | (SP << RT_SHIFT))
+#define ADDIU_SP_SP_IMM_TEMPL \
+	((0x9 << OP_SHIFT) | (SP << RS_SHIFT) | (SP << RT_SHIFT))
+#define JR_RA_TEMPL \
+	((0x0 << OP_SHIFT) | (RA << RS_SHIFT) | (0x0 << HINT_SHIFT) | 0x8)
+#define SW_RA_TEMPL \
+	((0x2b << OP_SHIFT) | (RA << RT_SHIFT))
+
+#define IS_ADDU_R_SP_R0(inst) \
+	(((inst) & ~RD_MASK) == ADDU_R_SP_R0_TEMPL)
+#define IS_ADDU_SP_R_R0(inst) \
+	(((inst) & ~RS_MASK) == ADDU_SP_R_R0_TEMPL)
+#define IS_ADDI_SP_SP_IMM(inst) \
+	(((inst) & ~IMM_MASK) == ADDI_SP_SP_IMM_TEMPL)
+#define IS_ADDIU_SP_SP_IMM(inst) \
+	(((inst) & ~IMM_MASK) == ADDIU_SP_SP_IMM_TEMPL)
+#define IS_JR_RA(inst) \
+	(((inst) & ~HINT_MASK) == JR_RA_TEMPL)
+#define IS_SW_RA(inst) \
+	(((inst) & ~(BASE_MASK | OFFSET_MASK)) == SW_RA_TEMPL)
+
+extern char ktext_start;
+extern char ktext_end;
+
+static bool bounds_check(uintptr_t pc)
+{
+	return (pc >= (uintptr_t) &ktext_start) &&
+	    (pc < (uintptr_t) &ktext_end);
+}
+
+static bool
+scan(stack_trace_context_t *ctx, uintptr_t *prev_fp, uintptr_t *prev_ra)
+{
+	uint32_t *inst = (void *) ctx->pc;
+	bool has_fp = false;
+	size_t frame_size;
+	unsigned int fp = SP;
+
+	do {
+		inst--;
+		if (!bounds_check((uintptr_t) inst))
+			return false;
+#if 0
+		/*
+		 * This is one of the situations in which the theory (ABI) does
+		 * not meet the practice (GCC). GCC simply does not place the
+		 * JR $ra instruction as dictated by the ABI, rendering the
+		 * official stack tracing algorithm somewhat unapplicable.
+		 */
+
+		if (IS_ADDU_R_SP_R0(*inst)) {
+			uint32_t *cur;
+			fp = RD_GET(*inst);
+			/*
+			 * We have a candidate for frame pointer.
+			 */
+			
+			/* Seek to the end of this function. */
+			for (cur = inst + 1; !IS_JR_RA(*cur); cur++)
+				;
+			/* Scan the last basic block */
+			for (cur--; !is_jump(*(cur - 1)); cur--) {
+				if (IS_ADDU_SP_R_R0(*cur) &&
+				    (fp == RS_GET(*cur))) {
+					has_fp = true;
+				}
+			}
+			continue;
+		}
+		
+		if (IS_JR_RA(*inst)) {
+			if (!ctx->istate)
+				return false;
+			/*
+			 * No stack frame has been allocated yet.
+			 * Use the values stored in istate.
+			 */
+			if (prev_fp)
+				*prev_fp = ctx->istate->sp;
+			if (prev_ra)
+				*prev_ra = ctx->istate->ra - 8;
+			ctx->istate = NULL;
+			return true;
+		}
+#endif
+
+	} while ((!IS_ADDIU_SP_SP_IMM(*inst) && !IS_ADDI_SP_SP_IMM(*inst)) ||
+	    (IMM_GET(*inst) >= 0));
+	
+	/*
+	 * We are at the instruction which allocates the space for the current
+	 * stack frame.
+	 */
+	frame_size = -IMM_GET(*inst);
+	if (prev_fp)
+		*prev_fp = ctx->fp + frame_size;
+
+	/*
+	 * Scan the first basic block for the occurrence of
+	 * SW $ra, OFFSET($base).
+	 */
+	for (inst++; !is_jump(*(inst - 1)) && (uintptr_t) inst < ctx->pc;
+	    inst++) {
+		if (IS_SW_RA(*inst)) {
+			unsigned int base = BASE_GET(*inst);
+			int16_t offset = OFFSET_GET(*inst);
+
+			if (base == SP || (has_fp && base == fp)) {
+				uint32_t *addr = (void *) (ctx->fp + offset);
+				
+				if (offset % 4 != 0)
+					return false;
+				/* cannot store below current stack pointer */
+				if (offset < 0)
+					return false;
+				/* too big offsets are suspicious */
+				if ((size_t) offset > sizeof(istate_t))
+					return false;
+
+				if (prev_ra)
+					*prev_ra = *addr;
+				return true;
+			}
+		}
+	}
+
+	/*
+	 * The first basic block does not save the return address or saves it
+	 * after ctx->pc, which means that the correct value is in istate.
+	 */
+	if (prev_ra) {
+		if (!ctx->istate)
+			return false;
+		*prev_ra = ctx->istate->ra - 8;
+		ctx->istate = NULL;
+	}
+	return true;
+}
+
+
+bool kernel_stack_trace_context_validate(stack_trace_context_t *ctx)
+{
+	return !((ctx->fp == 0) || ((ctx->fp % 8) != 0) ||
+	    (ctx->pc % 4 != 0) || !bounds_check(ctx->pc));
+}
+
+bool kernel_frame_pointer_prev(stack_trace_context_t *ctx, uintptr_t *prev)
+{
+	return scan(ctx, prev, NULL);
+}
+
+bool kernel_return_address_get(stack_trace_context_t *ctx, uintptr_t *ra)
+{
+	return scan(ctx, NULL, ra);
+}
+
+bool uspace_stack_trace_context_validate(stack_trace_context_t *ctx)
 {
 	return false;
 }
 
-bool kernel_frame_pointer_prev(uintptr_t fp, uintptr_t *prev)
+bool uspace_frame_pointer_prev(stack_trace_context_t *ctx, uintptr_t *prev)
 {
 	return false;
 }
 
-bool kernel_return_address_get(uintptr_t fp, uintptr_t *ra)
+bool uspace_return_address_get(stack_trace_context_t *ctx, uintptr_t *ra)
 {
 	return false;
 }
 
-bool uspace_frame_pointer_validate(uintptr_t fp)
-{
-	return false;
-}
-
-bool uspace_frame_pointer_prev(uintptr_t fp, uintptr_t *prev)
-{
-	return false;
-}
-
-bool uspace_return_address_get(uintptr_t fp, uintptr_t *ra)
-{
-	return false;
-}
-
 /** @}
  */
Index: kernel/arch/mips32/src/debug/stacktrace_asm.S
===================================================================
--- kernel/arch/mips32/src/debug/stacktrace_asm.S	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/mips32/src/debug/stacktrace_asm.S	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -37,7 +37,7 @@
 frame_pointer_get:
 	j $ra
-	xor $v0, $v0
+	move $v0, $sp
 
 program_counter_get:
 	j $ra
-	xor $v0, $v0
+	move $v0, $ra
Index: kernel/arch/mips32/src/debugger.c
===================================================================
--- kernel/arch/mips32/src/debugger.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/mips32/src/debugger.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -46,9 +46,12 @@
 
 bpinfo_t breakpoints[BKPOINTS_MAX];
-SPINLOCK_INITIALIZE(bkpoint_lock);
+IRQ_SPINLOCK_STATIC_INITIALIZE(bkpoint_lock);
 
 #ifdef CONFIG_KCONSOLE
 
-static int cmd_print_breakpoints(cmd_arg_t *argv);
+static int cmd_print_breakpoints(cmd_arg_t *);
+static int cmd_del_breakpoint(cmd_arg_t *);
+static int cmd_add_breakpoint(cmd_arg_t *);
+
 static cmd_info_t bkpts_info = {
 	.name = "bkpts",
@@ -58,11 +61,11 @@
 };
 
-static int cmd_del_breakpoint(cmd_arg_t *argv);
 static cmd_arg_t del_argv = {
 	.type = ARG_TYPE_INT
 };
+
 static cmd_info_t delbkpt_info = {
 	.name = "delbkpt",
-	.description = "delbkpt <number> - Delete breakpoint.",
+	.description = "Delete breakpoint.",
 	.func = cmd_del_breakpoint,
 	.argc = 1,
@@ -70,12 +73,11 @@
 };
 
-static int cmd_add_breakpoint(cmd_arg_t *argv);
 static cmd_arg_t add_argv = {
 	.type = ARG_TYPE_INT
 };
+
 static cmd_info_t addbkpt_info = {
 	.name = "addbkpt",
-	.description = "addbkpt <&symbol> - new bkpoint. Break on J/Branch "
-	    "insts unsupported.",
+	.description = "Add bkpoint (break on J/Branch insts unsupported).",
 	.func = cmd_add_breakpoint,
 	.argc = 1,
@@ -89,6 +91,5 @@
 static cmd_info_t addbkpte_info = {
 	.name = "addbkpte",
-	.description = "addebkpte <&symbol> <&func> - new bkpoint. Call "
-	    "func(or Nothing if 0).",
+	.description = "Add bkpoint with a trigger function.",
 	.func = cmd_add_breakpoint,
 	.argc = 2,
@@ -100,162 +101,164 @@
 	uint32_t value;
 } jmpinstr[] = {
-	{0xf3ff0000, 0x41000000}, /* BCzF */
-	{0xf3ff0000, 0x41020000}, /* BCzFL */
-	{0xf3ff0000, 0x41010000}, /* BCzT */
-	{0xf3ff0000, 0x41030000}, /* BCzTL */
-	{0xfc000000, 0x10000000}, /* BEQ */
-	{0xfc000000, 0x50000000}, /* BEQL */
-	{0xfc1f0000, 0x04010000}, /* BEQL */
-	{0xfc1f0000, 0x04110000}, /* BGEZAL */
-	{0xfc1f0000, 0x04130000}, /* BGEZALL */
-	{0xfc1f0000, 0x04030000}, /* BGEZL */
-	{0xfc1f0000, 0x1c000000}, /* BGTZ */
-	{0xfc1f0000, 0x5c000000}, /* BGTZL */
-	{0xfc1f0000, 0x18000000}, /* BLEZ */
-	{0xfc1f0000, 0x58000000}, /* BLEZL */
-	{0xfc1f0000, 0x04000000}, /* BLTZ */
-	{0xfc1f0000, 0x04100000}, /* BLTZAL */
-	{0xfc1f0000, 0x04120000}, /* BLTZALL */
-	{0xfc1f0000, 0x04020000}, /* BLTZL */
-	{0xfc000000, 0x14000000}, /* BNE */
-	{0xfc000000, 0x54000000}, /* BNEL */
-	{0xfc000000, 0x08000000}, /* J */
-	{0xfc000000, 0x0c000000}, /* JAL */
-	{0xfc1f07ff, 0x00000009}, /* JALR */
-	{0, 0} /* EndOfTable */
-};
-
+	{0xf3ff0000, 0x41000000},  /* BCzF */
+	{0xf3ff0000, 0x41020000},  /* BCzFL */
+	{0xf3ff0000, 0x41010000},  /* BCzT */
+	{0xf3ff0000, 0x41030000},  /* BCzTL */
+	{0xfc000000, 0x10000000},  /* BEQ */
+	{0xfc000000, 0x50000000},  /* BEQL */
+	{0xfc1f0000, 0x04010000},  /* BEQL */
+	{0xfc1f0000, 0x04110000},  /* BGEZAL */
+	{0xfc1f0000, 0x04130000},  /* BGEZALL */
+	{0xfc1f0000, 0x04030000},  /* BGEZL */
+	{0xfc1f0000, 0x1c000000},  /* BGTZ */
+	{0xfc1f0000, 0x5c000000},  /* BGTZL */
+	{0xfc1f0000, 0x18000000},  /* BLEZ */
+	{0xfc1f0000, 0x58000000},  /* BLEZL */
+	{0xfc1f0000, 0x04000000},  /* BLTZ */
+	{0xfc1f0000, 0x04100000},  /* BLTZAL */
+	{0xfc1f0000, 0x04120000},  /* BLTZALL */
+	{0xfc1f0000, 0x04020000},  /* BLTZL */
+	{0xfc000000, 0x14000000},  /* BNE */
+	{0xfc000000, 0x54000000},  /* BNEL */
+	{0xfc000000, 0x08000000},  /* J */
+	{0xfc000000, 0x0c000000},  /* JAL */
+	{0xfc1f07ff, 0x00000009},  /* JALR */
+	{0, 0}                     /* end of table */
+};
 
 /** Test, if the given instruction is a jump or branch instruction
  *
  * @param instr Instruction code
- * @return true - it is jump instruction, false otherwise
- *
- */
-static bool is_jump(unative_t instr)
-{
-	int i;
-
+ *
+ * @return true if it is jump instruction, false otherwise
+ *
+ */
+bool is_jump(unative_t instr)
+{
+	unsigned int i;
+	
 	for (i = 0; jmpinstr[i].andmask; i++) {
 		if ((instr & jmpinstr[i].andmask) == jmpinstr[i].value)
 			return true;
 	}
-
+	
 	return false;
 }
 
-/** Add new breakpoint to table */
+/** Add new breakpoint to table
+ *
+ */
 int cmd_add_breakpoint(cmd_arg_t *argv)
 {
-	bpinfo_t *cur = NULL;
-	ipl_t ipl;
-	int i;
-
 	if (argv->intval & 0x3) {
 		printf("Not aligned instruction, forgot to use &symbol?\n");
 		return 1;
 	}
-	ipl = interrupts_disable();
-	spinlock_lock(&bkpoint_lock);
-
+	
+	irq_spinlock_lock(&bkpoint_lock, true);
+	
 	/* Check, that the breakpoints do not conflict */
+	unsigned int i;
 	for (i = 0; i < BKPOINTS_MAX; i++) {
-		if (breakpoints[i].address == (uintptr_t)argv->intval) {
+		if (breakpoints[i].address == (uintptr_t) argv->intval) {
 			printf("Duplicate breakpoint %d.\n", i);
-			spinlock_unlock(&bkpoint_lock);
-			interrupts_restore(ipl);
+			irq_spinlock_unlock(&bkpoint_lock, true);
 			return 0;
-		} else if (breakpoints[i].address == (uintptr_t)argv->intval +
-		    sizeof(unative_t) || breakpoints[i].address ==
-		    (uintptr_t)argv->intval - sizeof(unative_t)) {
+		} else if ((breakpoints[i].address == (uintptr_t) argv->intval +
+		    sizeof(unative_t)) || (breakpoints[i].address ==
+		    (uintptr_t) argv->intval - sizeof(unative_t))) {
 			printf("Adjacent breakpoints not supported, conflict "
 			    "with %d.\n", i);
-			spinlock_unlock(&bkpoint_lock);
-			interrupts_restore(ipl);
+			irq_spinlock_unlock(&bkpoint_lock, true);
 			return 0;
 		}
 		
 	}
-
-	for (i = 0; i < BKPOINTS_MAX; i++)
+	
+	bpinfo_t *cur = NULL;
+	
+	for (i = 0; i < BKPOINTS_MAX; i++) {
 		if (!breakpoints[i].address) {
 			cur = &breakpoints[i];
 			break;
 		}
+	}
+	
 	if (!cur) {
 		printf("Too many breakpoints.\n");
-		spinlock_unlock(&bkpoint_lock);
-		interrupts_restore(ipl);
+		irq_spinlock_unlock(&bkpoint_lock, true);
 		return 0;
 	}
+	
+	printf("Adding breakpoint on address %p\n", argv->intval);
+	
 	cur->address = (uintptr_t) argv->intval;
-	printf("Adding breakpoint on address: %p\n", argv->intval);
-	cur->instruction = ((unative_t *)cur->address)[0];
-	cur->nextinstruction = ((unative_t *)cur->address)[1];
+	cur->instruction = ((unative_t *) cur->address)[0];
+	cur->nextinstruction = ((unative_t *) cur->address)[1];
 	if (argv == &add_argv) {
 		cur->flags = 0;
-	} else { /* We are add extended */
+	} else {  /* We are add extended */
 		cur->flags = BKPOINT_FUNCCALL;
 		cur->bkfunc = (void (*)(void *, istate_t *)) argv[1].intval;
 	}
+	
 	if (is_jump(cur->instruction))
 		cur->flags |= BKPOINT_ONESHOT;
+	
 	cur->counter = 0;
-
+	
 	/* Set breakpoint */
-	*((unative_t *)cur->address) = 0x0d;
+	*((unative_t *) cur->address) = 0x0d;
 	smc_coherence(cur->address);
-
-	spinlock_unlock(&bkpoint_lock);
-	interrupts_restore(ipl);
-
+	
+	irq_spinlock_unlock(&bkpoint_lock, true);
+	
 	return 1;
 }
 
-/** Remove breakpoint from table */
+/** Remove breakpoint from table
+ *
+ */
 int cmd_del_breakpoint(cmd_arg_t *argv)
 {
-	bpinfo_t *cur;
-	ipl_t ipl;
-
 	if (argv->intval > BKPOINTS_MAX) {
 		printf("Invalid breakpoint number.\n");
 		return 0;
 	}
-	ipl = interrupts_disable();
-	spinlock_lock(&bkpoint_lock);
-
-	cur = &breakpoints[argv->intval];
+	
+	irq_spinlock_lock(&bkpoint_lock, true);
+	
+	bpinfo_t *cur = &breakpoints[argv->intval];
 	if (!cur->address) {
 		printf("Breakpoint does not exist.\n");
-		spinlock_unlock(&bkpoint_lock);
-		interrupts_restore(ipl);
+		irq_spinlock_unlock(&bkpoint_lock, true);
 		return 0;
 	}
+	
 	if ((cur->flags & BKPOINT_INPROG) && (cur->flags & BKPOINT_ONESHOT)) {
 		printf("Cannot remove one-shot breakpoint in-progress\n");
-		spinlock_unlock(&bkpoint_lock);
-		interrupts_restore(ipl);
+		irq_spinlock_unlock(&bkpoint_lock, true);
 		return 0;
 	}
-	((uint32_t *)cur->address)[0] = cur->instruction;
-	smc_coherence(((uint32_t *)cur->address)[0]);
-	((uint32_t *)cur->address)[1] = cur->nextinstruction;
-	smc_coherence(((uint32_t *)cur->address)[1]);
-
+	
+	((uint32_t *) cur->address)[0] = cur->instruction;
+	smc_coherence(((uint32_t *) cur->address)[0]);
+	((uint32_t *) cur->address)[1] = cur->nextinstruction;
+	smc_coherence(((uint32_t *) cur->address)[1]);
+	
 	cur->address = NULL;
-
-	spinlock_unlock(&bkpoint_lock);
-	interrupts_restore(ipl);
+	
+	irq_spinlock_unlock(&bkpoint_lock, true);
 	return 1;
 }
 
-/** Print table of active breakpoints */
+/** Print table of active breakpoints
+ *
+ */
 int cmd_print_breakpoints(cmd_arg_t *argv)
 {
 	unsigned int i;
 	
-	printf("#  Count Address    INPROG ONESHOT FUNCCALL In symbol\n");
-	printf("-- ----- ---------- ------ ------- -------- ---------\n");
+	printf("[nr] [count] [address ] [inprog] [oneshot] [funccall] [in symbol\n");
 	
 	for (i = 0; i < BKPOINTS_MAX; i++) {
@@ -264,5 +267,5 @@
 			    breakpoints[i].address);
 			
-			printf("%-2u %-5d %#10zx %-6s %-7s %-8s %s\n", i,
+			printf("%-4u %7" PRIs " %p %-8s %-9s %-10s %s\n", i,
 			    breakpoints[i].counter, breakpoints[i].address,
 			    ((breakpoints[i].flags & BKPOINT_INPROG) ? "true" :
@@ -276,59 +279,64 @@
 }
 
-#endif
-
-/** Initialize debugger */
+#endif /* CONFIG_KCONSOLE */
+
+/** Initialize debugger
+ *
+ */
 void debugger_init()
 {
-	int i;
-
+	unsigned int i;
+	
 	for (i = 0; i < BKPOINTS_MAX; i++)
 		breakpoints[i].address = NULL;
-
+	
 #ifdef CONFIG_KCONSOLE
 	cmd_initialize(&bkpts_info);
 	if (!cmd_register(&bkpts_info))
 		printf("Cannot register command %s\n", bkpts_info.name);
-
+	
 	cmd_initialize(&delbkpt_info);
 	if (!cmd_register(&delbkpt_info))
 		printf("Cannot register command %s\n", delbkpt_info.name);
-
+	
 	cmd_initialize(&addbkpt_info);
 	if (!cmd_register(&addbkpt_info))
 		printf("Cannot register command %s\n", addbkpt_info.name);
-
+	
 	cmd_initialize(&addbkpte_info);
 	if (!cmd_register(&addbkpte_info))
 		printf("Cannot register command %s\n", addbkpte_info.name);
-#endif
+#endif /* CONFIG_KCONSOLE */
 }
 
 /** Handle breakpoint
  *
- * Find breakpoint in breakpoint table. 
+ * Find breakpoint in breakpoint table.
  * If found, call kconsole, set break on next instruction and reexecute.
  * If we are on "next instruction", set it back on the first and reexecute.
  * If breakpoint not found in breakpoint table, call kconsole and start
  * next instruction.
+ *
  */
 void debugger_bpoint(istate_t *istate)
 {
-	bpinfo_t *cur = NULL;
-	uintptr_t fireaddr = istate->epc;
-	int i;
-
 	/* test branch delay slot */
 	if (cp0_cause_read() & 0x80000000)
 		panic("Breakpoint in branch delay slot not supported.");
-
-	spinlock_lock(&bkpoint_lock);
+	
+	irq_spinlock_lock(&bkpoint_lock, false);
+	
+	bpinfo_t *cur = NULL;
+	uintptr_t fireaddr = istate->epc;
+	unsigned int i;
+	
 	for (i = 0; i < BKPOINTS_MAX; i++) {
 		/* Normal breakpoint */
-		if (fireaddr == breakpoints[i].address &&
-		    !(breakpoints[i].flags & BKPOINT_REINST)) {
+		if ((fireaddr == breakpoints[i].address) &&
+		    (!(breakpoints[i].flags & BKPOINT_REINST))) {
 			cur = &breakpoints[i];
 			break;
 		}
+		
 		/* Reinst only breakpoint */
 		if ((breakpoints[i].flags & BKPOINT_REINST) &&
@@ -338,24 +346,28 @@
 		}
 	}
+	
 	if (cur) {
 		if (cur->flags & BKPOINT_REINST) {
 			/* Set breakpoint on first instruction */
-			((uint32_t *)cur->address)[0] = 0x0d;
+			((uint32_t *) cur->address)[0] = 0x0d;
 			smc_coherence(((uint32_t *)cur->address)[0]);
+			
 			/* Return back the second */
-			((uint32_t *)cur->address)[1] = cur->nextinstruction;
-			smc_coherence(((uint32_t *)cur->address)[1]);
+			((uint32_t *) cur->address)[1] = cur->nextinstruction;
+			smc_coherence(((uint32_t *) cur->address)[1]);
+			
 			cur->flags &= ~BKPOINT_REINST;
-			spinlock_unlock(&bkpoint_lock);
+			irq_spinlock_unlock(&bkpoint_lock, false);
 			return;
-		} 
+		}
+		
 		if (cur->flags & BKPOINT_INPROG)
 			printf("Warning: breakpoint recursion\n");
 		
 		if (!(cur->flags & BKPOINT_FUNCCALL)) {
-			printf("***Breakpoint %d: %p in %s.\n", i, fireaddr,
-			    symtab_fmt_name_lookup(istate->epc));
-		}
-
+			printf("***Breakpoint %u: %p in %s.\n", i, fireaddr,
+			    symtab_fmt_name_lookup(fireaddr));
+		}
+		
 		/* Return first instruction back */
 		((uint32_t *)cur->address)[0] = cur->instruction;
@@ -371,10 +383,12 @@
 		printf("***Breakpoint %d: %p in %s.\n", i, fireaddr,
 		    symtab_fmt_name_lookup(fireaddr));
-
+		
 		/* Move on to next instruction */
 		istate->epc += 4;
 	}
+	
 	if (cur)
 		cur->counter++;
+	
 	if (cur && (cur->flags & BKPOINT_FUNCCALL)) {
 		/* Allow zero bkfunc, just for counting */
@@ -383,26 +397,31 @@
 	} else {
 #ifdef CONFIG_KCONSOLE
-		/* This disables all other processors - we are not SMP,
+		/*
+		 * This disables all other processors - we are not SMP,
 		 * actually this gets us to cpu_halt, if scheduler() is run
 		 * - we generally do not want scheduler to be run from debug,
 		 *   so this is a good idea
-		 */	
+		 */
 		atomic_set(&haltstate, 1);
-		spinlock_unlock(&bkpoint_lock);
+		irq_spinlock_unlock(&bkpoint_lock, false);
 		
 		kconsole("debug", "Debug console ready.\n", false);
 		
-		spinlock_lock(&bkpoint_lock);
+		irq_spinlock_lock(&bkpoint_lock, false);
 		atomic_set(&haltstate, 0);
 #endif
 	}
-	if (cur && cur->address == fireaddr && (cur->flags & BKPOINT_INPROG)) {
+	
+	if ((cur) && (cur->address == fireaddr)
+	    && ((cur->flags & BKPOINT_INPROG))) {
 		/* Remove one-shot breakpoint */
 		if ((cur->flags & BKPOINT_ONESHOT))
 			cur->address = NULL;
+		
 		/* Remove in-progress flag */
 		cur->flags &= ~BKPOINT_INPROG;
-	} 
-	spinlock_unlock(&bkpoint_lock);
+	}
+	
+	irq_spinlock_unlock(&bkpoint_lock, false);
 }
 
Index: kernel/arch/mips32/src/exception.c
===================================================================
--- kernel/arch/mips32/src/exception.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/mips32/src/exception.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -27,5 +27,5 @@
  */
 
-/** @addtogroup mips32	
+/** @addtogroup mips32
  * @{
  */
@@ -67,37 +67,48 @@
 	"Floating Point",
 	NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-	"WatchHi/WatchLo", /* 23 */
+	"WatchHi/WatchLo",  /* 23 */
 	NULL, NULL, NULL, NULL, NULL, NULL, NULL,
 	"Virtual Coherency - data",
 };
 
-static void print_regdump(istate_t *istate)
-{
-	const char *pcsymbol = symtab_fmt_name_lookup(istate->epc);
-	const char *rasymbol = symtab_fmt_name_lookup(istate->ra);
-	
-	printf("PC: %#x(%s) RA: %#x(%s), SP(%p)\n", istate->epc, pcsymbol,
-	    istate->ra, rasymbol, istate->sp);
-}
-
-static void unhandled_exception(int n, istate_t *istate)
+void istate_decode(istate_t *istate)
+{
+	printf("epc=%p\tsta=%p\tlo =%p\thi =%p\n",
+	    istate->epc, istate->status, istate->lo, istate->hi);
+	printf("a0 =%p\ta1 =%p\ta2 =%p\ta3 =%p\n",
+	    istate->a0, istate->a1, istate->a2, istate->a3);
+	printf("t0 =%p\tt1 =%p\tt2 =%p\tt3 =%p\n",
+	    istate->t0, istate->t1, istate->t2, istate->t3);
+	printf("t4 =%p\tt5 =%p\tt6 =%p\tt7 =%p\n",
+	    istate->t4, istate->t5, istate->t6, istate->t7);
+	printf("t8 =%p\tt9 =%p\tv0 =%p\tv1 =%p\n",
+	    istate->t8, istate->t9, istate->v0, istate->v1);
+	printf("s0 =%p\ts1 =%p\ts2 =%p\ts3 =%p\n",
+	    istate->s0, istate->s1, istate->s2, istate->s3);
+	printf("s4 =%p\ts5 =%p\ts6 =%p\ts7 =%p\n",
+	    istate->s4, istate->s5, istate->s6, istate->s7);
+	printf("s8 =%p\tat =%p\tkt0=%p\tkt1=%p\n",
+	    istate->s8, istate->at, istate->kt0, istate->kt1);
+	printf("sp =%p\tra =%p\tgp =%p\n",
+	    istate->sp, istate->ra, istate->gp);
+}
+
+static void unhandled_exception(unsigned int n, istate_t *istate)
 {
 	fault_if_from_uspace(istate, "Unhandled exception %s.", exctable[n]);
-	
-	print_regdump(istate);
-	panic("Unhandled exception %s.", exctable[n]);
-}
-
-static void reserved_instr_exception(int n, istate_t *istate)
+	panic_badtrap(istate, n, "Unhandled exception %s.", exctable[n]);
+}
+
+static void reserved_instr_exception(unsigned int n, istate_t *istate)
 {
 	if (*((uint32_t *) istate->epc) == 0x7c03e83b) {
 		ASSERT(THREAD);
 		istate->epc += 4;
-		istate->v1 = istate->k1;
+		istate->v1 = istate->kt1;
 	} else
 		unhandled_exception(n, istate);
 }
 
-static void breakpoint_exception(int n, istate_t *istate)
+static void breakpoint_exception(unsigned int n, istate_t *istate)
 {
 #ifdef CONFIG_DEBUG
@@ -111,10 +122,10 @@
 }
 
-static void tlbmod_exception(int n, istate_t *istate)
+static void tlbmod_exception(unsigned int n, istate_t *istate)
 {
 	tlb_modified(istate);
 }
 
-static void tlbinv_exception(int n, istate_t *istate)
+static void tlbinv_exception(unsigned int n, istate_t *istate)
 {
 	tlb_invalid(istate);
@@ -122,23 +133,23 @@
 
 #ifdef CONFIG_FPU_LAZY
-static void cpuns_exception(int n, istate_t *istate)
+static void cpuns_exception(unsigned int n, istate_t *istate)
 {
 	if (cp0_cause_coperr(cp0_cause_read()) == fpu_cop_id)
 		scheduler_fpu_lazy_request();
 	else {
-		fault_if_from_uspace(istate, "Unhandled Coprocessor Unusable Exception.");
-		panic("Unhandled Coprocessor Unusable Exception.");
+		fault_if_from_uspace(istate,
+		    "Unhandled Coprocessor Unusable Exception.");
+		panic_badtrap(istate, n,
+		    "Unhandled Coprocessor Unusable Exception.");
 	}
 }
 #endif
 
-static void interrupt_exception(int n, istate_t *istate)
-{
-	uint32_t cause;
-	int i;
-	
-	/* decode interrupt number and process the interrupt */
-	cause = (cp0_cause_read() >> 8) & 0xff;
-	
+static void interrupt_exception(unsigned int n, istate_t *istate)
+{
+	/* Decode interrupt number and process the interrupt */
+	uint32_t cause = (cp0_cause_read() >> 8) & 0xff;
+	
+	unsigned int i;
 	for (i = 0; i < 8; i++) {
 		if (cause & (1 << i)) {
@@ -149,5 +160,5 @@
 				 */
 				irq->handler(irq);
-				spinlock_unlock(&irq->lock);
+				irq_spinlock_unlock(&irq->lock, false);
 			} else {
 				/*
@@ -155,5 +166,5 @@
 				 */
 #ifdef CONFIG_DEBUG
-				printf("cpu%u: spurious interrupt (inum=%d)\n",
+				printf("cpu%u: spurious interrupt (inum=%u)\n",
 				    CPU->id, i);
 #endif
@@ -164,27 +175,38 @@
 
 /** Handle syscall userspace call */
-static void syscall_exception(int n, istate_t *istate)
-{
-	panic("Syscall is handled through shortcut.");
+static void syscall_exception(unsigned int n, istate_t *istate)
+{
+	fault_if_from_uspace(istate, "Syscall is handled through shortcut.");
 }
 
 void exception_init(void)
 {
-	int i;
-
+	unsigned int i;
+	
 	/* Clear exception table */
 	for (i = 0; i < IVT_ITEMS; i++)
-		exc_register(i, "undef", (iroutine) unhandled_exception);
-	
-	exc_register(EXC_Bp, "bkpoint", (iroutine) breakpoint_exception);
-	exc_register(EXC_RI, "resinstr", (iroutine) reserved_instr_exception);
-	exc_register(EXC_Mod, "tlb_mod", (iroutine) tlbmod_exception);
-	exc_register(EXC_TLBL, "tlbinvl", (iroutine) tlbinv_exception);
-	exc_register(EXC_TLBS, "tlbinvl", (iroutine) tlbinv_exception);
-	exc_register(EXC_Int, "interrupt", (iroutine) interrupt_exception);
+		exc_register(i, "undef", false,
+		    (iroutine_t) unhandled_exception);
+	
+	exc_register(EXC_Bp, "bkpoint", true,
+	    (iroutine_t) breakpoint_exception);
+	exc_register(EXC_RI, "resinstr", true,
+	    (iroutine_t) reserved_instr_exception);
+	exc_register(EXC_Mod, "tlb_mod", true,
+	    (iroutine_t) tlbmod_exception);
+	exc_register(EXC_TLBL, "tlbinvl", true,
+	    (iroutine_t) tlbinv_exception);
+	exc_register(EXC_TLBS, "tlbinvl", true,
+	    (iroutine_t) tlbinv_exception);
+	exc_register(EXC_Int, "interrupt", true,
+	    (iroutine_t) interrupt_exception);
+	
 #ifdef CONFIG_FPU_LAZY
-	exc_register(EXC_CpU, "cpunus", (iroutine) cpuns_exception);
-#endif
-	exc_register(EXC_Sys, "syscall", (iroutine) syscall_exception);
+	exc_register(EXC_CpU, "cpunus", true,
+	    (iroutine_t) cpuns_exception);
+#endif
+	
+	exc_register(EXC_Sys, "syscall", true,
+	    (iroutine_t) syscall_exception);
 }
 
Index: kernel/arch/mips32/src/interrupt.c
===================================================================
--- kernel/arch/mips32/src/interrupt.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/mips32/src/interrupt.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -38,4 +38,5 @@
 #include <arch.h>
 #include <arch/cp0.h>
+#include <arch/smp/dorder.h>
 #include <time/clock.h>
 #include <ipc/sysipc.h>
@@ -48,4 +49,11 @@
 function virtual_timer_fnc = NULL;
 static irq_t timer_irq;
+static irq_t dorder_irq;
+
+// TODO: This is SMP unsafe!!!
+
+uint32_t count_hi = 0;
+static unsigned long nextcount;
+static unsigned long lastcount;
 
 /** Disable interrupts.
@@ -89,10 +97,17 @@
 }
 
-/* TODO: This is SMP unsafe!!! */
-uint32_t count_hi = 0;
-static unsigned long nextcount;
-static unsigned long lastcount;
+/** Check interrupts state.
+ *
+ * @return True if interrupts are disabled.
+ *
+ */
+bool interrupts_disabled(void)
+{
+	return !(cp0_status_read() & cp0_status_ie_enabled_bit);
+}
 
-/** Start hardware clock */
+/** Start hardware clock
+ *
+ */
 static void timer_start(void)
 {
@@ -109,16 +124,16 @@
 static void timer_irq_handler(irq_t *irq)
 {
-	unsigned long drift;
-	
 	if (cp0_count_read() < lastcount)
 		/* Count overflow detected */
 		count_hi++;
+	
 	lastcount = cp0_count_read();
 	
-	drift = cp0_count_read() - nextcount;
+	unsigned long drift = cp0_count_read() - nextcount;
 	while (drift > cp0_compare_value) {
 		drift -= cp0_compare_value;
 		CPU->missed_clock_ticks++;
 	}
+	
 	nextcount = cp0_count_read() + cp0_compare_value - drift;
 	cp0_compare_write(nextcount);
@@ -128,10 +143,20 @@
 	 * Release the lock, call clock() and reacquire the lock again.
 	 */
-	spinlock_unlock(&irq->lock);
+	irq_spinlock_unlock(&irq->lock, false);
 	clock();
-	spinlock_lock(&irq->lock);
+	irq_spinlock_lock(&irq->lock, false);
 	
 	if (virtual_timer_fnc != NULL)
 		virtual_timer_fnc();
+}
+
+static irq_ownership_t dorder_claim(irq_t *irq)
+{
+	return IRQ_ACCEPT;
+}
+
+static void dorder_irq_handler(irq_t *irq)
+{
+	dorder_ipi_ack(1 << dorder_cpuid());
 }
 
@@ -150,4 +175,13 @@
 	timer_start();
 	cp0_unmask_int(TIMER_IRQ);
+	
+	irq_initialize(&dorder_irq);
+	dorder_irq.devno = device_assign_devno();
+	dorder_irq.inr = DORDER_IRQ;
+	dorder_irq.claim = dorder_claim;
+	dorder_irq.handler = dorder_irq_handler;
+	irq_register(&dorder_irq);
+	
+	cp0_unmask_int(DORDER_IRQ);
 }
 
Index: kernel/arch/mips32/src/mips32.c
===================================================================
--- kernel/arch/mips32/src/mips32.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/mips32/src/mips32.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -36,4 +36,5 @@
 #include <arch/cp0.h>
 #include <arch/exception.h>
+#include <arch/debug.h>
 #include <mm/as.h>
 #include <userspace.h>
Index: kernel/arch/mips32/src/mm/frame.c
===================================================================
--- kernel/arch/mips32/src/mm/frame.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/mips32/src/mm/frame.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -249,6 +249,5 @@
 void physmem_print(void)
 {
-	printf("Base       Size\n");
-	printf("---------- ----------\n");
+	printf("[base    ] [size    ]\n");
 	
 	size_t i;
Index: kernel/arch/mips32/src/mm/tlb.c
===================================================================
--- kernel/arch/mips32/src/mm/tlb.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/mips32/src/mm/tlb.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -321,11 +321,8 @@
 void tlb_refill_fail(istate_t *istate)
 {
-	const char *symbol = symtab_fmt_name_lookup(istate->epc);
-	const char *sym2 = symtab_fmt_name_lookup(istate->ra);
-	
-	fault_if_from_uspace(istate, "TLB Refill Exception on %p.",
-	    cp0_badvaddr_read());
-	panic("%x: TLB Refill Exception at %x (%s<-%s).", cp0_badvaddr_read(),
-	    istate->epc, symbol, sym2);
+	uintptr_t va = cp0_badvaddr_read();
+	
+	fault_if_from_uspace(istate, "TLB Refill Exception on %p.", va);
+	panic_memtrap(istate, PF_ACCESS_UNKNOWN, va, "TLB Refill Exception.");
 }
 
@@ -333,25 +330,19 @@
 void tlb_invalid_fail(istate_t *istate)
 {
-	const char *symbol = symtab_fmt_name_lookup(istate->epc);
-	
-	fault_if_from_uspace(istate, "TLB Invalid Exception on %p.",
-	    cp0_badvaddr_read());
-	panic("%x: TLB Invalid Exception at %x (%s).", cp0_badvaddr_read(),
-	    istate->epc, symbol);
+	uintptr_t va = cp0_badvaddr_read();
+	
+	fault_if_from_uspace(istate, "TLB Invalid Exception on %p.", va);
+	panic_memtrap(istate, PF_ACCESS_UNKNOWN, va, "TLB Invalid Exception.");
 }
 
 void tlb_modified_fail(istate_t *istate)
 {
-	const char *symbol = symtab_fmt_name_lookup(istate->epc);
-	
-	fault_if_from_uspace(istate, "TLB Modified Exception on %p.",
-	    cp0_badvaddr_read());
-	panic("%x: TLB Modified Exception at %x (%s).", cp0_badvaddr_read(),
-	    istate->epc, symbol);
+	uintptr_t va = cp0_badvaddr_read();
+	
+	fault_if_from_uspace(istate, "TLB Modified Exception on %p.", va);
+	panic_memtrap(istate, PF_ACCESS_WRITE, va, "TLB Modified Exception.");
 }
 
 /** Try to find PTE for faulting address.
- *
- * The AS->lock must be held on entry to this function.
  *
  * @param badvaddr	Faulting virtual address.
@@ -369,4 +360,6 @@
 	entry_hi_t hi;
 	pte_t *pte;
+
+	ASSERT(mutex_locked(&AS->lock));
 
 	hi.value = cp0_entry_hi_read();
@@ -455,6 +448,5 @@
 	hi_save.value = cp0_entry_hi_read();
 	
-	printf("#  ASID VPN2   MASK G V D C PFN\n");
-	printf("-- ---- ------ ---- - - - - ------\n");
+	printf("[nr] [asid] [vpn2] [mask] [gvdc] [pfn ]\n");
 	
 	for (i = 0; i < TLB_ENTRY_COUNT; i++) {
@@ -467,8 +459,8 @@
 		lo1.value = cp0_entry_lo1_read();
 		
-		printf("%-2u %-4u %#6x %#4x %1u %1u %1u %1u %#6x\n",
+		printf("%-4u %-6u %#6x %#6x  %1u%1u%1u%1u  %#6x\n",
 		    i, hi.asid, hi.vpn2, mask.mask,
 		    lo0.g, lo0.v, lo0.d, lo0.c, lo0.pfn);
-		printf("                    %1u %1u %1u %1u %#6x\n",
+		printf("                           %1u%1u%1u%1u  %#6x\n",
 		    lo1.g, lo1.v, lo1.d, lo1.c, lo1.pfn);
 	}
Index: rnel/arch/mips32/src/panic.S
===================================================================
--- kernel/arch/mips32/src/panic.S	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ 	(revision )
@@ -1,48 +1,0 @@
-#
-# 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.
-#
-
-.text   
-
-.set noat
-.set noreorder
-.set nomacro
-
-#include <arch/asm/regname.h>
-	
-.global panic_printf
-
-/* From printf return directly to halt() */	
-panic_printf:
-	jal printf
-	nop
-	j halt
-	nop
-/* This code does not work, god knows why */		
-/*	lui $ra, %hi(halt)
-	j printf
-	ori $ra, %lo(halt) */
Index: kernel/arch/mips32/src/smp/dorder.c
===================================================================
--- kernel/arch/mips32/src/smp/dorder.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/mips32/src/smp/dorder.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -33,17 +33,29 @@
  */
 
+#include <typedefs.h>
 #include <smp/ipi.h>
+#include <arch/smp/dorder.h>
+
+#define MSIM_DORDER_ADDRESS  0xB0000004
 
 #ifdef CONFIG_SMP
 
-#define MSIM_DORDER_ADDRESS  0xB0000004
-
 void ipi_broadcast_arch(int ipi)
 {
-	*((volatile unsigned int *) MSIM_DORDER_ADDRESS) = 0x7FFFFFFF;
+	*((volatile uint32_t *) MSIM_DORDER_ADDRESS) = 0x7fffffff;
 }
 
 #endif
 
+uint32_t dorder_cpuid(void)
+{
+	return *((volatile uint32_t *) MSIM_DORDER_ADDRESS);
+}
+
+void dorder_ipi_ack(uint32_t mask)
+{
+	*((volatile uint32_t *) (MSIM_DORDER_ADDRESS + 4)) = mask;
+}
+
 /** @}
  */
Index: kernel/arch/mips32/src/start.S
===================================================================
--- kernel/arch/mips32/src/start.S	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/mips32/src/start.S	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -45,127 +45,200 @@
 .global userspace_asm
 
-# Which status bits should are thread-local
-#define REG_SAVE_MASK 0x1f # KSU(UM), EXL, ERL, IE
-	
-# Save registers to space defined by \r
-# We will change status: Disable ERL,EXL,UM,IE
-# These changes will be automatically reversed in REGISTER_LOAD
-# SP is NOT saved as part of these registers
+/*
+ * Which status bits are thread-local:
+ * KSU(UM), EXL, ERL, IE
+ */
+#define REG_SAVE_MASK 0x1f
+
+#define ISTATE_OFFSET_A0	0
+#define ISTATE_OFFSET_A1	4
+#define ISTATE_OFFSET_A2	8
+#define ISTATE_OFFSET_A3	12
+#define ISTATE_OFFSET_T0	16
+#define ISTATE_OFFSET_T1	20
+#define ISTATE_OFFSET_V0	24
+#define ISTATE_OFFSET_V1	28
+#define ISTATE_OFFSET_AT	32
+#define ISTATE_OFFSET_T2	36
+#define ISTATE_OFFSET_T3	40
+#define ISTATE_OFFSET_T4	44
+#define ISTATE_OFFSET_T5	48
+#define ISTATE_OFFSET_T6	52
+#define ISTATE_OFFSET_T7	56
+#define ISTATE_OFFSET_S0	60
+#define ISTATE_OFFSET_S1	64
+#define ISTATE_OFFSET_S2	68
+#define ISTATE_OFFSET_S3	72
+#define ISTATE_OFFSET_S4	76
+#define ISTATE_OFFSET_S5	80
+#define ISTATE_OFFSET_S6	84
+#define ISTATE_OFFSET_S7	88
+#define ISTATE_OFFSET_T8	92
+#define ISTATE_OFFSET_T9	96
+#define ISTATE_OFFSET_KT0	100
+#define ISTATE_OFFSET_KT1	104
+#define ISTATE_OFFSET_GP	108
+#define ISTATE_OFFSET_SP	112
+#define ISTATE_OFFSET_S8	116
+#define ISTATE_OFFSET_RA	120
+#define ISTATE_OFFSET_LO	124
+#define ISTATE_OFFSET_HI	128
+#define ISTATE_OFFSET_STATUS	132
+#define ISTATE_OFFSET_EPC	136
+#define ISTATE_OFFSET_ALIGNMENT	140
+
+#define ISTATE_SOFT_SIZE	144
+
+/*
+ * The fake ABI prologue is never executed and may not be part of the
+ * procedure's body. Instead, it should be immediately preceding the procedure's
+ * body. Its only purpose is to trick the stack trace walker into thinking that
+ * the exception is more or less just a normal function call.
+ */
+.macro FAKE_ABI_PROLOGUE
+	sub $sp, ISTATE_SOFT_SIZE
+	sw $ra, ISTATE_OFFSET_EPC($sp)
+.endm
+
+/*
+ * Save registers to space defined by \r
+ * We will change status: Disable ERL, EXL, UM, IE
+ * These changes will be automatically reversed in REGISTER_LOAD
+ * %sp is NOT saved as part of these registers
+ */
 .macro REGISTERS_STORE_AND_EXC_RESET r
-	sw $at, EOFFSET_AT(\r)
-	sw $v0, EOFFSET_V0(\r)
-	sw $v1, EOFFSET_V1(\r)
-	sw $a0, EOFFSET_A0(\r)
-	sw $a1, EOFFSET_A1(\r)
-	sw $a2, EOFFSET_A2(\r)
-	sw $a3, EOFFSET_A3(\r)
-	sw $t0, EOFFSET_T0(\r)
-	sw $t1, EOFFSET_T1(\r)
-	sw $t2, EOFFSET_T2(\r)
-	sw $t3, EOFFSET_T3(\r)
-	sw $t4, EOFFSET_T4(\r)
-	sw $t5, EOFFSET_T5(\r)
-	sw $t6, EOFFSET_T6(\r)
-	sw $t7, EOFFSET_T7(\r)
-	sw $t8, EOFFSET_T8(\r)
-	sw $t9, EOFFSET_T9(\r)
-
+	sw $at, ISTATE_OFFSET_AT(\r)
+	sw $v0, ISTATE_OFFSET_V0(\r)
+	sw $v1, ISTATE_OFFSET_V1(\r)
+	sw $a0, ISTATE_OFFSET_A0(\r)
+	sw $a1, ISTATE_OFFSET_A1(\r)
+	sw $a2, ISTATE_OFFSET_A2(\r)
+	sw $a3, ISTATE_OFFSET_A3(\r)
+	sw $t0, ISTATE_OFFSET_T0(\r)
+	sw $t1, ISTATE_OFFSET_T1(\r)
+	sw $t2, ISTATE_OFFSET_T2(\r)
+	sw $t3, ISTATE_OFFSET_T3(\r)
+	sw $t4, ISTATE_OFFSET_T4(\r)
+	sw $t5, ISTATE_OFFSET_T5(\r)
+	sw $t6, ISTATE_OFFSET_T6(\r)
+	sw $t7, ISTATE_OFFSET_T7(\r)
+	sw $t8, ISTATE_OFFSET_T8(\r)
+	sw $t9, ISTATE_OFFSET_T9(\r)
+	sw $s0, ISTATE_OFFSET_S0(\r)
+	sw $s1, ISTATE_OFFSET_S1(\r)
+	sw $s2, ISTATE_OFFSET_S2(\r)
+	sw $s3, ISTATE_OFFSET_S3(\r)
+	sw $s4, ISTATE_OFFSET_S4(\r)
+	sw $s5, ISTATE_OFFSET_S5(\r)
+	sw $s6, ISTATE_OFFSET_S6(\r)
+	sw $s7, ISTATE_OFFSET_S7(\r)
+	sw $s8, ISTATE_OFFSET_S8(\r)
+	
 	mflo $at
-	sw $at, EOFFSET_LO(\r)
+	sw $at, ISTATE_OFFSET_LO(\r)
 	mfhi $at
-	sw $at, EOFFSET_HI(\r)
-	
-	sw $gp, EOFFSET_GP(\r)
-	sw $ra, EOFFSET_RA(\r)
-	sw $k1, EOFFSET_K1(\r)
-
+	sw $at, ISTATE_OFFSET_HI(\r)
+	
+	sw $gp, ISTATE_OFFSET_GP(\r)
+	sw $ra, ISTATE_OFFSET_RA(\r)
+	sw $k0, ISTATE_OFFSET_KT0(\r)
+	sw $k1, ISTATE_OFFSET_KT1(\r)
+	
 	mfc0 $t0, $status
 	mfc0 $t1, $epc
 	
-	and $t2, $t0, REG_SAVE_MASK	# Save only KSU,EXL,ERL,IE
-	li $t3, ~(0x1f)
-	and $t0, $t0, $t3		# Clear KSU,EXL,ERL,IE
-	
-	sw $t2,EOFFSET_STATUS(\r)
-	sw $t1,EOFFSET_EPC(\r)
+	/* save only KSU, EXL, ERL, IE */
+	and $t2, $t0, REG_SAVE_MASK
+	
+	/* clear KSU, EXL, ERL, IE */
+	li $t3, ~(REG_SAVE_MASK)
+	and $t0, $t0, $t3
+	
+	sw $t2, ISTATE_OFFSET_STATUS(\r)
+	sw $t1, ISTATE_OFFSET_EPC(\r)
 	mtc0 $t0, $status
 .endm
 
 .macro REGISTERS_LOAD r
-	# Update only UM,EXR,IE from status, the rest
-	# is controlled by OS and not bound to task
+	/*
+	 * Update only UM, EXR, IE from status, the rest
+	 * is controlled by OS and not bound to task.
+	 */
 	mfc0 $t0, $status
-	lw $t1,EOFFSET_STATUS(\r)
-
-	li $t2, ~REG_SAVE_MASK		# Mask UM,EXL,ERL,IE
+	lw $t1, ISTATE_OFFSET_STATUS(\r)
+	
+	/* mask UM, EXL, ERL, IE */
+	li $t2, ~REG_SAVE_MASK
 	and $t0, $t0, $t2
 	
-	or $t0, $t0, $t1		# Copy UM,EXL, ERL, IE from saved status
+	/* copy UM, EXL, ERL, IE from saved status */
+	or $t0, $t0, $t1
 	mtc0 $t0, $status
 	
-	lw $v0, EOFFSET_V0(\r)
-	lw $v1, EOFFSET_V1(\r)
-	lw $a0, EOFFSET_A0(\r)
-	lw $a1, EOFFSET_A1(\r)
-	lw $a2, EOFFSET_A2(\r)
-	lw $a3, EOFFSET_A3(\r)
-	lw $t0, EOFFSET_T0(\r)
-	lw $t1, EOFFSET_T1(\r)
-	lw $t2, EOFFSET_T2(\r)
-	lw $t3, EOFFSET_T3(\r)
-	lw $t4, EOFFSET_T4(\r)
-	lw $t5, EOFFSET_T5(\r)
-	lw $t6, EOFFSET_T6(\r)
-	lw $t7, EOFFSET_T7(\r)
-	lw $t8, EOFFSET_T8(\r)
-	lw $t9, EOFFSET_T9(\r)
-	
-	lw $gp, EOFFSET_GP(\r)
-	lw $ra, EOFFSET_RA(\r)
-	lw $k1, EOFFSET_K1(\r)
-	
-	lw $at, EOFFSET_LO(\r)
+	lw $v0, ISTATE_OFFSET_V0(\r)
+	lw $v1, ISTATE_OFFSET_V1(\r)
+	lw $a0, ISTATE_OFFSET_A0(\r)
+	lw $a1, ISTATE_OFFSET_A1(\r)
+	lw $a2, ISTATE_OFFSET_A2(\r)
+	lw $a3, ISTATE_OFFSET_A3(\r)
+	lw $t0, ISTATE_OFFSET_T0(\r)
+	lw $t1, ISTATE_OFFSET_T1(\r)
+	lw $t2, ISTATE_OFFSET_T2(\r)
+	lw $t3, ISTATE_OFFSET_T3(\r)
+	lw $t4, ISTATE_OFFSET_T4(\r)
+	lw $t5, ISTATE_OFFSET_T5(\r)
+	lw $t6, ISTATE_OFFSET_T6(\r)
+	lw $t7, ISTATE_OFFSET_T7(\r)
+	lw $t8, ISTATE_OFFSET_T8(\r)
+	lw $t9, ISTATE_OFFSET_T9(\r)
+	
+	lw $gp, ISTATE_OFFSET_GP(\r)
+	lw $ra, ISTATE_OFFSET_RA(\r)
+	lw $k1, ISTATE_OFFSET_KT1(\r)
+	
+	lw $at, ISTATE_OFFSET_LO(\r)
 	mtlo $at
-	lw $at, EOFFSET_HI(\r)
+	lw $at, ISTATE_OFFSET_HI(\r)
 	mthi $at
-
-	lw $at, EOFFSET_EPC(\r)
+	
+	lw $at, ISTATE_OFFSET_EPC(\r)
 	mtc0 $at, $epc
 	
-	lw $at, EOFFSET_AT(\r)
-	lw $sp, EOFFSET_SP(\r)
+	lw $at, ISTATE_OFFSET_AT(\r)
+	lw $sp, ISTATE_OFFSET_SP(\r)
 .endm
 
-# Move kernel stack pointer address to register K0
-# - if we are in user mode, load the appropriate stack
-# address
+/*
+ * Move kernel stack pointer address to register $k0.
+ * If we are in user mode, load the appropriate stack address.
+ */
 .macro KERNEL_STACK_TO_K0
-	# If we are in user mode
+	/* if we are in user mode */
 	mfc0 $k0, $status
 	andi $k0, 0x10
 	
 	beq $k0, $0, 1f
-	add $k0, $sp, 0
-	
-	# Move $k0 pointer to kernel stack
+	move $k0, $sp
+	
+	/* move $k0 pointer to kernel stack */
 	lui $k0, %hi(supervisor_sp)
 	ori $k0, $k0, %lo(supervisor_sp)
-	# Move $k0 (superveisor_sp)
-	lw $k0, 0($k0)
-1:
+	
+	/* move $k0 (supervisor_sp) */
+	lw $k0, ($k0)
+	
+	1:
 .endm
 
 .org 0x0
 kernel_image_start:
-	/* Load temporary stack */
+	/* load temporary stack */
 	lui $sp, %hi(end_stack)
 	ori $sp, $sp, %lo(end_stack)
 	
-	/* Not sure about this, but might
-	   be needed for PIC code */
+	/* not sure about this, but might be needed for PIC code */
 	lui $gp, 0x8000
 	
 	/* $a1 contains physical address of bootinfo_t */
-	
 	jal arch_pre_main
 	nop
@@ -174,5 +247,5 @@
 	nop
 
-	.space TEMP_STACK_SIZE
+.space TEMP_STACK_SIZE
 end_stack:
 
@@ -189,125 +262,125 @@
 	nop
 
+	FAKE_ABI_PROLOGUE
 exception_handler:
 	KERNEL_STACK_TO_K0
-	sub $k0, REGISTER_SPACE
-	sw $sp, EOFFSET_SP($k0)
+	
+	sub $k0, ISTATE_SOFT_SIZE
+	sw $sp, ISTATE_OFFSET_SP($k0)
 	move $sp, $k0
 	
 	mfc0 $k0, $cause
 	
-	sra $k0, $k0, 0x2    # cp0_exc_cause() part 1
-	andi $k0, $k0, 0x1f  # cp0_exc_cause() part 2
-	sub $k0, 8           # 8 = SYSCALL
+	sra $k0, $k0, 0x2    /* cp0_exc_cause() part 1 */
+	andi $k0, $k0, 0x1f  /* cp0_exc_cause() part 2 */
+	sub $k0, 8           /* 8 = SYSCALL */
 	
 	beqz $k0, syscall_shortcut
-	add $k0, 8           # Revert $k0 back to correct exc number
+	add $k0, 8           /* revert $k0 back to correct exc number */
 	
 	REGISTERS_STORE_AND_EXC_RESET $sp
 	
 	move $a1, $sp
-	jal exc_dispatch     # exc_dispatch(excno, register_space)
+	jal exc_dispatch     /* exc_dispatch(excno, register_space) */
 	move $a0, $k0
-
+	
 	REGISTERS_LOAD $sp
-	# The $sp is automatically restored to former value
-	eret
-
-## Syscall entry
-#
-# Registers:
-#
-# @param v0		Syscall number.
-# @param a0		1st argument.
-# @param a1		2nd argument.
-# @param a2		3rd argument.
-# @param a3		4th argument.
-# @param t0		5th argument.
-# @param t1		6th argument.
-#
-# @return		The return value will be stored in v0.
-#
-#define SS_SP		EOFFSET_SP
-#define SS_STATUS	EOFFSET_STATUS
-#define SS_EPC		EOFFSET_EPC
-#define SS_K1		EOFFSET_K1
+	/* the $sp is automatically restored to former value */
+	eret
+
+/** Syscall entry
+ *
+ * Registers:
+ *
+ * @param $v0 Syscall number.
+ * @param $a0 1st argument.
+ * @param $a1 2nd argument.
+ * @param $a2 3rd argument.
+ * @param $a3 4th argument.
+ * @param $t0 5th argument.
+ * @param $t1 6th argument.
+ *
+ * @return The return value will be stored in $v0.
+ *
+ */
 syscall_shortcut:
-	# We have a lot of space on the stack, with free use
 	mfc0 $t3, $epc
 	mfc0 $t2, $status
-	sw $t3, SS_EPC($sp)		# Save EPC
-	sw $k1, SS_K1($sp)   		# Save k1 not saved on context switch
-	
-	and $t4, $t2, REG_SAVE_MASK	# Save only KSU, EXL, ERL, IE
+	sw $t3, ISTATE_OFFSET_EPC($sp)  /* save EPC */
+	sw $k1, ISTATE_OFFSET_KT1($sp)  /* save $k1 not saved on context switch */
+	
+	and $t4, $t2, REG_SAVE_MASK  /* save only KSU, EXL, ERL, IE */
 	li $t5, ~(0x1f)
-	and $t2, $t2, $t5		# Clear KSU, EXL, ERL
-	ori $t2, $t2, 0x1		# Set IE
-
-	sw $t4, SS_STATUS($sp)
+	and $t2, $t2, $t5  /* clear KSU, EXL, ERL */
+	ori $t2, $t2, 0x1  /* set IE */
+	
+	sw $t4, ISTATE_OFFSET_STATUS($sp)
 	mtc0 $t2, $status
-
-	#
-	# Call the higher level system call handler
-	# We are going to reuse part of the unused exception stack frame
-	#
-	sw $t0, STACK_ARG4($sp)		# save the 5th argument on the stack
-	sw $t1, STACK_ARG5($sp)		# save the 6th argument on the stack
+	
+	/*
+	 * Call the higher level system call handler.
+	 *
+	 */
+	sw $t0, ISTATE_OFFSET_T0($sp)  /* save the 5th argument on the stack */
+	sw $t1, ISTATE_OFFSET_T1($sp)  /* save the 6th argument on the stack */
 	jal syscall_handler
-	sw $v0, STACK_ARG6($sp)		# save the syscall number on the stack
-
-	# restore status
+	sw $v0, ISTATE_OFFSET_V0($sp)  /* save the syscall number on the stack */
+	
+	/* restore status */
 	mfc0 $t2, $status
-	lw $t3, SS_STATUS($sp)
-
-	# Change back to EXL = 1 (from last exception), otherwise
-	# an interrupt could rewrite the CP0 - EPC
-	li $t4, ~REG_SAVE_MASK		# Mask UM, EXL, ERL, IE
+	lw $t3, ISTATE_OFFSET_STATUS($sp)
+	
+	/*
+	 * Change back to EXL = 1 (from last exception), otherwise
+	 * an interrupt could rewrite the CP0 - EPC.
+	 *
+	 */
+	li $t4, ~REG_SAVE_MASK  /* mask UM, EXL, ERL, IE */
 	and $t2, $t2, $t4
-	or $t2, $t2, $t3		# Copy saved UM, EXL, ERL, IE
+	or $t2, $t2, $t3  /* copy saved UM, EXL, ERL, IE */
 	mtc0 $t2, $status
-			
-	# restore epc + 4
-	lw $t2, SS_EPC($sp)
-	lw $k1, SS_K1($sp)
+	
+	/* restore epc + 4 */
+	lw $t2, ISTATE_OFFSET_EPC($sp)
+	lw $k1, ISTATE_OFFSET_KT1($sp)
 	addi $t2, $t2, 4
 	mtc0 $t2, $epc
 	
-	lw $sp, SS_SP($sp)		# restore sp
-	
-	eret
-		
+	lw $sp, ISTATE_OFFSET_SP($sp)  /* restore $sp */
+	eret
+
+	FAKE_ABI_PROLOGUE
 tlb_refill_handler:
 	KERNEL_STACK_TO_K0
-	sub $k0, REGISTER_SPACE
+	sub $k0, ISTATE_SOFT_SIZE
 	REGISTERS_STORE_AND_EXC_RESET $k0
-	sw $sp,EOFFSET_SP($k0)
-	add $sp, $k0, 0
-
+	sw $sp, ISTATE_OFFSET_SP($k0)
+	move $sp, $k0
+	
 	jal tlb_refill
-	add $a0, $sp, 0 
-
+	move $a0, $sp 
+	
 	REGISTERS_LOAD $sp
-
-	eret
-
+	eret
+
+	FAKE_ABI_PROLOGUE
 cache_error_handler:
 	KERNEL_STACK_TO_K0
-	sub $k0, REGISTER_SPACE
+	sub $k0, ISTATE_SOFT_SIZE 
 	REGISTERS_STORE_AND_EXC_RESET $k0
-	sw $sp,EOFFSET_SP($k0)
-	add $sp, $k0, 0
-
+	sw $sp, ISTATE_OFFSET_SP($k0)
+	move $sp, $k0
+	
 	jal cache_error
-	add $a0, $sp, 0 
-
+	move $a0, $sp
+	
 	REGISTERS_LOAD $sp
-
 	eret
 
 userspace_asm:
-	add $sp, $a0, 0
-	add $v0, $a1, 0 
-	add $t9, $a2, 0			# Set up correct entry into PIC code
-	xor $a0, $a0, $a0		# $a0 is defined to hold pcb_ptr
-					# set it to 0
-	eret
+	move $sp, $a0
+	move $v0, $a1
+	move $t9, $a2      /* set up correct entry into PIC code */
+	xor $a0, $a0, $a0  /* $a0 is defined to hold pcb_ptr */
+	                   /* set it to 0 */
+	eret
Index: kernel/arch/ppc32/Makefile.inc
===================================================================
--- kernel/arch/ppc32/Makefile.inc	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/ppc32/Makefile.inc	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -32,6 +32,6 @@
 
 GCC_CFLAGS += -mcpu=powerpc -msoft-float -m32
-AFLAGS = -a32
-LFLAGS = -no-check-sections -N
+AFLAGS += -a32
+LFLAGS += -no-check-sections
 
 BITS = 32
@@ -40,5 +40,4 @@
 ARCH_SOURCES = \
 	arch/$(KARCH)/src/context.S \
-	arch/$(KARCH)/src/debug/panic.s \
 	arch/$(KARCH)/src/debug/stacktrace.c \
 	arch/$(KARCH)/src/debug/stacktrace_asm.S \
Index: kernel/arch/ppc32/include/asm.h
===================================================================
--- kernel/arch/ppc32/include/asm.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/ppc32/include/asm.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -38,4 +38,61 @@
 #include <typedefs.h>
 #include <config.h>
+#include <arch/cpu.h>
+#include <arch/mm/asid.h>
+#include <trace.h>
+
+NO_TRACE static inline uint32_t msr_read(void)
+{
+	uint32_t msr;
+	
+	asm volatile (
+		"mfmsr %[msr]\n"
+		: [msr] "=r" (msr)
+	);
+	
+	return msr;
+}
+
+NO_TRACE static inline void msr_write(uint32_t msr)
+{
+	asm volatile (
+		"mtmsr %[msr]\n"
+		:: [msr] "r" (msr)
+	);
+}
+
+NO_TRACE static inline void sr_set(uint32_t flags, asid_t asid, uint32_t sr)
+{
+	asm volatile (
+		"mtsrin %[value], %[sr]\n"
+		:: [value] "r" ((flags << 16) + (asid << 4) + sr),
+		   [sr] "r" (sr << 28)
+	);
+}
+
+NO_TRACE static inline uint32_t sr_get(uint32_t vaddr)
+{
+	uint32_t vsid;
+	
+	asm volatile (
+		"mfsrin %[vsid], %[vaddr]\n"
+		: [vsid] "=r" (vsid)
+		: [vaddr] "r" (vaddr)
+	);
+	
+	return vsid;
+}
+
+NO_TRACE static inline uint32_t sdr1_get(void)
+{
+	uint32_t sdr1;
+	
+	asm volatile (
+		"mfsdr1 %[sdr1]\n"
+		: [sdr1] "=r" (sdr1)
+	);
+	
+	return sdr1;
+}
 
 /** Enable interrupts.
@@ -45,18 +102,11 @@
  *
  * @return Old interrupt priority level.
- */
-static inline ipl_t interrupts_enable(void)
-{
-	ipl_t v;
-	ipl_t tmp;
-	
-	asm volatile (
-		"mfmsr %0\n"
-		"mfmsr %1\n"
-		"ori %1, %1, 1 << 15\n"
-		"mtmsr %1\n"
-		: "=r" (v), "=r" (tmp)
-	);
-	return v;
+ *
+ */
+NO_TRACE static inline ipl_t interrupts_enable(void)
+{
+	ipl_t ipl = msr_read();
+	msr_write(ipl | MSR_EE);
+	return ipl;
 }
 
@@ -67,18 +117,11 @@
  *
  * @return Old interrupt priority level.
- */
-static inline ipl_t interrupts_disable(void)
-{
-	ipl_t v;
-	ipl_t tmp;
-	
-	asm volatile (
-		"mfmsr %0\n"
-		"mfmsr %1\n"
-		"rlwinm %1, %1, 0, 17, 15\n"
-		"mtmsr %1\n"
-		: "=r" (v), "=r" (tmp)
-	);
-	return v;
+ *
+ */
+NO_TRACE static inline ipl_t interrupts_disable(void)
+{
+	ipl_t ipl = msr_read();
+	msr_write(ipl & (~MSR_EE));
+	return ipl;
 }
 
@@ -88,20 +131,9 @@
  *
  * @param ipl Saved interrupt priority level.
- */
-static inline void interrupts_restore(ipl_t ipl)
-{
-	ipl_t tmp;
-	
-	asm volatile (
-		"mfmsr %1\n"
-		"rlwimi  %0, %1, 0, 17, 15\n"
-		"cmpw 0, %0, %1\n"
-		"beq 0f\n"
-		"mtmsr %0\n"
-		"0:\n"
-		: "=r" (ipl), "=r" (tmp)
-		: "0" (ipl)
-		: "cr0"
-	);
+ *
+ */
+NO_TRACE static inline void interrupts_restore(ipl_t ipl)
+{
+	msr_write((msr_read() & (~MSR_EE)) | (ipl & MSR_EE));
 }
 
@@ -111,14 +143,19 @@
  *
  * @return Current interrupt priority level.
- */
-static inline ipl_t interrupts_read(void)
-{
-	ipl_t v;
-	
-	asm volatile (
-		"mfmsr %0\n"
-		: "=r" (v)
-	);
-	return v;
+ *
+ */
+NO_TRACE static inline ipl_t interrupts_read(void)
+{
+	return msr_read();
+}
+
+/** Check whether interrupts are disabled.
+ *
+ * @return True if interrupts are disabled.
+ *
+ */
+NO_TRACE static inline bool interrupts_disabled(void)
+{
+	return ((msr_read() & MSR_EE) == 0);
 }
 
@@ -128,19 +165,51 @@
  * The stack is assumed to be STACK_SIZE bytes long.
  * The stack must start on page boundary.
- */
-static inline uintptr_t get_stack_base(void)
-{
-	uintptr_t v;
-	
-	asm volatile (
-		"and %0, %%sp, %1\n"
-		: "=r" (v)
-		: "r" (~(STACK_SIZE - 1))
-	);
-	return v;
-}
-
-static inline void cpu_sleep(void)
-{
+ *
+ */
+NO_TRACE static inline uintptr_t get_stack_base(void)
+{
+	uintptr_t base;
+	
+	asm volatile (
+		"and %[base], %%sp, %[mask]\n"
+		: [base] "=r" (base)
+		: [mask] "r" (~(STACK_SIZE - 1))
+	);
+	
+	return base;
+}
+
+NO_TRACE static inline void cpu_sleep(void)
+{
+}
+
+NO_TRACE static inline void pio_write_8(ioport8_t *port, uint8_t v)
+{
+	*port = v;
+}
+
+NO_TRACE static inline void pio_write_16(ioport16_t *port, uint16_t v)
+{
+	*port = v;
+}
+
+NO_TRACE static inline void pio_write_32(ioport32_t *port, uint32_t v)
+{
+	*port = v;
+}
+
+NO_TRACE static inline uint8_t pio_read_8(ioport8_t *port)
+{
+	return *port;
+}
+
+NO_TRACE static inline uint16_t pio_read_16(ioport16_t *port)
+{
+	return *port;
+}
+
+NO_TRACE static inline uint32_t pio_read_32(ioport32_t *port)
+{
+	return *port;
 }
 
@@ -149,34 +218,4 @@
 extern void userspace_asm(uintptr_t uspace_uarg, uintptr_t stack, uintptr_t entry);
 
-static inline void pio_write_8(ioport8_t *port, uint8_t v)
-{
-	*port = v;
-}
-
-static inline void pio_write_16(ioport16_t *port, uint16_t v)
-{
-	*port = v;
-}
-
-static inline void pio_write_32(ioport32_t *port, uint32_t v)
-{
-	*port = v;
-}
-
-static inline uint8_t pio_read_8(ioport8_t *port)
-{
-	return *port;
-}
-
-static inline uint16_t pio_read_16(ioport16_t *port)
-{
-	return *port;
-}
-
-static inline uint32_t pio_read_32(ioport32_t *port)
-{
-	return *port;
-}
-
 #endif
 
Index: kernel/arch/ppc32/include/asm/regname.h
===================================================================
--- kernel/arch/ppc32/include/asm/regname.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/ppc32/include/asm/regname.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -217,17 +217,4 @@
 #define hid0     1008
 
-/* MSR bits */
-#define msr_dr  (1 << 4)
-#define msr_ir  (1 << 5)
-#define msr_pr  (1 << 14)
-#define msr_ee  (1 << 15)
-
-/* HID0 bits */
-#define hid0_sten  (1 << 24)
-#define hid0_ice   (1 << 15)
-#define hid0_dce   (1 << 14)
-#define hid0_icfi  (1 << 11)
-#define hid0_dci   (1 << 10)
-
 #endif
 
Index: kernel/arch/ppc32/include/atomic.h
===================================================================
--- kernel/arch/ppc32/include/atomic.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/ppc32/include/atomic.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -36,5 +36,7 @@
 #define KERN_ppc32_ATOMIC_H_
 
-static inline void atomic_inc(atomic_t *val)
+#include <trace.h>
+
+NO_TRACE static inline void atomic_inc(atomic_t *val)
 {
 	atomic_count_t tmp;
@@ -42,11 +44,11 @@
 	asm volatile (
 		"1:\n"
-		"lwarx %0, 0, %2\n"
-		"addic %0, %0, 1\n"
-		"stwcx. %0, 0, %2\n"
-		"bne- 1b"
-		: "=&r" (tmp),
+		"	lwarx %[tmp], 0, %[count_ptr]\n"
+		"	addic %[tmp], %[tmp], 1\n"
+		"	stwcx. %[tmp], 0, %[count_ptr]\n"
+		"	bne- 1b"
+		: [tmp] "=&r" (tmp),
 		  "=m" (val->count)
-		: "r" (&val->count),
+		: [count_ptr] "r" (&val->count),
 		  "m" (val->count)
 		: "cc"
@@ -54,5 +56,5 @@
 }
 
-static inline void atomic_dec(atomic_t *val)
+NO_TRACE static inline void atomic_dec(atomic_t *val)
 {
 	atomic_count_t tmp;
@@ -60,11 +62,11 @@
 	asm volatile (
 		"1:\n"
-		"lwarx %0, 0, %2\n"
-		"addic %0, %0, -1\n"
-		"stwcx. %0, 0, %2\n"
-		"bne- 1b"
-		: "=&r" (tmp),
+		"	lwarx %[tmp], 0, %[count_ptr]\n"
+		"	addic %[tmp], %[tmp], -1\n"
+		"	stwcx. %[tmp], 0, %[count_ptr]\n"
+		"	bne- 1b"
+		: [tmp] "=&r" (tmp),
 		  "=m" (val->count)
-		: "r" (&val->count),
+		: [count_ptr] "r" (&val->count),
 		  "m" (val->count)
 		: "cc"
@@ -72,5 +74,5 @@
 }
 
-static inline atomic_count_t atomic_postinc(atomic_t *val)
+NO_TRACE static inline atomic_count_t atomic_postinc(atomic_t *val)
 {
 	atomic_inc(val);
@@ -78,5 +80,5 @@
 }
 
-static inline atomic_count_t atomic_postdec(atomic_t *val)
+NO_TRACE static inline atomic_count_t atomic_postdec(atomic_t *val)
 {
 	atomic_dec(val);
@@ -84,5 +86,5 @@
 }
 
-static inline atomic_count_t atomic_preinc(atomic_t *val)
+NO_TRACE static inline atomic_count_t atomic_preinc(atomic_t *val)
 {
 	atomic_inc(val);
@@ -90,5 +92,5 @@
 }
 
-static inline atomic_count_t atomic_predec(atomic_t *val)
+NO_TRACE static inline atomic_count_t atomic_predec(atomic_t *val)
 {
 	atomic_dec(val);
Index: kernel/arch/ppc32/include/barrier.h
===================================================================
--- kernel/arch/ppc32/include/barrier.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/ppc32/include/barrier.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -27,5 +27,5 @@
  */
 
-/** @addtogroup ppc32	
+/** @addtogroup ppc32
  * @{
  */
@@ -36,10 +36,20 @@
 #define KERN_ppc32_BARRIER_H_
 
-#define CS_ENTER_BARRIER()	asm volatile ("" ::: "memory")
-#define CS_LEAVE_BARRIER()	asm volatile ("" ::: "memory")
+#include <trace.h>
 
-#define memory_barrier() asm volatile ("sync" ::: "memory")
-#define read_barrier() asm volatile ("sync" ::: "memory")
-#define write_barrier() asm volatile ("eieio" ::: "memory")
+#define CS_ENTER_BARRIER()  asm volatile ("" ::: "memory")
+#define CS_LEAVE_BARRIER()  asm volatile ("" ::: "memory")
+
+#define memory_barrier()  asm volatile ("sync" ::: "memory")
+#define read_barrier()    asm volatile ("sync" ::: "memory")
+#define write_barrier()   asm volatile ("eieio" ::: "memory")
+
+#define instruction_barrier() \
+	asm volatile ( \
+		"sync\n" \
+		"isync\n" \
+	)
+
+#define COHERENCE_INVAL_MIN  4
 
 /*
@@ -50,36 +60,35 @@
  */
 
-static inline void smc_coherence(void *addr)
+NO_TRACE static inline void smc_coherence(void *addr)
 {
 	asm volatile (
-		"dcbst 0, %0\n"
+		"dcbst 0, %[addr]\n"
 		"sync\n"
-		"icbi 0, %0\n"
+		"icbi 0, %[addr]\n"
 		"sync\n"
 		"isync\n"
-		:: "r" (addr)
+		:: [addr] "r" (addr)
 	);
 }
 
-#define COHERENCE_INVAL_MIN	4
-
-static inline void smc_coherence_block(void *addr, unsigned long len)
+NO_TRACE static inline void smc_coherence_block(void *addr, unsigned int len)
 {
-	unsigned long i;
-
-	for (i = 0; i < len; i += COHERENCE_INVAL_MIN) {
-		asm volatile ("dcbst 0, %0\n" :: "r" (addr + i));
-	}
-
-	asm volatile ("sync");
-
-	for (i = 0; i < len; i += COHERENCE_INVAL_MIN) {
-		asm volatile ("icbi 0, %0\n" :: "r" (addr + i));
-	}
-
-	asm volatile (
-		"sync\n"
-		"isync\n"
-	);
+	unsigned int i;
+	
+	for (i = 0; i < len; i += COHERENCE_INVAL_MIN)
+		asm volatile (
+			"dcbst 0, %[addr]\n"
+			:: [addr] "r" (addr + i)
+		);
+	
+	memory_barrier();
+	
+	for (i = 0; i < len; i += COHERENCE_INVAL_MIN)
+		asm volatile (
+			"icbi 0, %[addr]\n"
+			:: [addr] "r" (addr + i)
+		);
+	
+	instruction_barrier();
 }
 
Index: kernel/arch/ppc32/include/cpu.h
===================================================================
--- kernel/arch/ppc32/include/cpu.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/ppc32/include/cpu.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -36,11 +36,37 @@
 #define KERN_ppc32_CPU_H_
 
-#include <arch/asm.h>
+/* MSR bits */
+#define MSR_DR  (1 << 4)
+#define MSR_IR  (1 << 5)
+#define MSR_PR  (1 << 14)
+#define MSR_EE  (1 << 15)
+
+/* HID0 bits */
+#define HID0_STEN  (1 << 24)
+#define HID0_ICE   (1 << 15)
+#define HID0_DCE   (1 << 14)
+#define HID0_ICFI  (1 << 11)
+#define HID0_DCI   (1 << 10)
+
+#ifndef __ASM__
+
+#include <typedefs.h>
+#include <trace.h>
 
 typedef struct {
-	int version;
-	int revision;
-} cpu_arch_t;
-	
+	uint16_t version;
+	uint16_t revision;
+} __attribute__ ((packed)) cpu_arch_t;
+
+NO_TRACE static inline void cpu_version(cpu_arch_t *info)
+{
+	asm volatile (
+		"mfpvr %[cpu_info]\n"
+		: [cpu_info] "=r" (*info)
+	);
+}
+
+#endif /* __ASM__ */
+
 #endif
 
Index: rnel/arch/ppc32/include/cpuid.h
===================================================================
--- kernel/arch/ppc32/include/cpuid.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ 	(revision )
@@ -1,56 +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.
- */
-
-/** @addtogroup ppc32
- * @{
- */
-/** @file
- */
-
-#ifndef KERN_ppc32_CPUID_H_
-#define KERN_ppc32_CPUID_H_
-
-#include <typedefs.h>
-
-typedef struct {
-	uint16_t version;
-	uint16_t revision;
-} __attribute__ ((packed)) cpu_info_t;
-
-static inline void cpu_version(cpu_info_t *info)
-{
-	asm volatile (
-		"mfpvr %0\n"
-		: "=r" (*info)
-	);
-}
-
-#endif
-
-/** @}
- */
Index: kernel/arch/ppc32/include/cycle.h
===================================================================
--- kernel/arch/ppc32/include/cycle.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/ppc32/include/cycle.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -36,21 +36,22 @@
 #define KERN_ppc32_CYCLE_H_
 
-static inline uint64_t get_cycle(void)
+#include <trace.h>
+
+NO_TRACE static inline uint64_t get_cycle(void)
 {
 	uint32_t lower;
 	uint32_t upper;
-	uint32_t upper2;
+	uint32_t tmp;
 	
-	asm volatile (
-		"1: mftbu %0\n"
-		"mftb %1\n"
-		"mftbu %2\n"
-		"cmpw %0, %2\n"
-		"bne- 1b\n"
-		: "=r" (upper),
-		  "=r" (lower),
-		  "=r" (upper2)
-		:: "cr0"
-	);
+	do {
+		asm volatile (
+			"mftbu %[upper]\n"
+			"mftb %[lower]\n"
+			"mftbu %[tmp]\n"
+			: [upper] "=r" (upper),
+			  [lower] "=r" (lower),
+			  [tmp] "=r" (tmp)
+		);
+	} while (upper != tmp);
 	
 	return ((uint64_t) upper << 32) + (uint64_t) lower;
Index: rnel/arch/ppc32/include/debug.h
===================================================================
--- kernel/arch/ppc32/include/debug.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ 	(revision )
@@ -1,41 +1,0 @@
-/*
- * Copyright (c) 2005 
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (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 ppc32debug
- * @{
- */
-/** @file
- */
-
-#ifndef KERN_ppc32_DEBUG_H_
-#define KERN_ppc32_DEBUG_H_
-
-#endif
-
-/** @}
- */
Index: kernel/arch/ppc32/include/drivers/pic.h
===================================================================
--- kernel/arch/ppc32/include/drivers/pic.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/ppc32/include/drivers/pic.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -39,16 +39,16 @@
 #include <ddi/irq.h>
 
-#define PIC_PENDING_LOW    8
-#define PIC_PENDING_HIGH   4
-#define PIC_MASK_LOW       9
-#define PIC_MASK_HIGH      5
-#define PIC_ACK_LOW        10
-#define PIC_ACK_HIGH       6
+#define PIC_PENDING_LOW   8
+#define PIC_PENDING_HIGH  4
+#define PIC_MASK_LOW      9
+#define PIC_MASK_HIGH     5
+#define PIC_ACK_LOW       10
+#define PIC_ACK_HIGH      6
 
-extern void pic_init(uintptr_t base, size_t size, cir_t *cir, void **cir_arg);
-extern void pic_enable_interrupt(inr_t intnum);
-extern void pic_disable_interrupt(inr_t intnum);
-extern void pic_ack_interrupt(void *arg, inr_t intnum);
-extern int pic_get_pending(void);
+extern void pic_init(uintptr_t, size_t, cir_t *, void **);
+extern void pic_enable_interrupt(inr_t);
+extern void pic_disable_interrupt(inr_t);
+extern void pic_ack_interrupt(void *, inr_t);
+extern uint8_t pic_get_pending(void);
 
 #endif
Index: kernel/arch/ppc32/include/elf.h
===================================================================
--- kernel/arch/ppc32/include/elf.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/ppc32/include/elf.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -27,5 +27,5 @@
  */
 
-/** @addtogroup ppc32	
+/** @addtogroup ppc32
  * @{
  */
@@ -36,7 +36,7 @@
 #define KERN_ppc32_ELF_H_
 
-#define	ELF_MACHINE		EM_PPC
-#define ELF_DATA_ENCODING	ELFDATA2MSB
-#define ELF_CLASS		ELFCLASS32
+#define ELF_MACHINE        EM_PPC
+#define ELF_DATA_ENCODING  ELFDATA2MSB
+#define ELF_CLASS          ELFCLASS32
 
 #endif
Index: kernel/arch/ppc32/include/exception.h
===================================================================
--- kernel/arch/ppc32/include/exception.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/ppc32/include/exception.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -27,5 +27,5 @@
  */
 
-/** @addtogroup ppc32	
+/** @addtogroup ppc32
  * @{
  */
@@ -37,5 +37,6 @@
 
 #include <typedefs.h>
-#include <arch/regutils.h>
+#include <arch/cpu.h>
+#include <trace.h>
 
 typedef struct istate {
@@ -81,22 +82,26 @@
 } istate_t;
 
-static inline void istate_set_retaddr(istate_t *istate, uintptr_t retaddr)
+NO_TRACE static inline void istate_set_retaddr(istate_t *istate,
+    uintptr_t retaddr)
 {
 	istate->pc = retaddr;
 }
 
-/** Return true if exception happened while in userspace */
-static inline int istate_from_uspace(istate_t *istate)
+/** Return true if exception happened while in userspace
+ *
+ * The contexts of MSR register was stored in SRR1.
+ *
+ */
+NO_TRACE static inline int istate_from_uspace(istate_t *istate)
 {
-	/* true if privilege level PR (copied from MSR) == 1 */
 	return (istate->srr1 & MSR_PR) != 0;
 }
 
-static inline unative_t istate_get_pc(istate_t *istate)
+NO_TRACE static inline unative_t istate_get_pc(istate_t *istate)
 {
 	return istate->pc;
 }
 
-static inline unative_t istate_get_fp(istate_t *istate)
+NO_TRACE static inline unative_t istate_get_fp(istate_t *istate)
 {
 	return istate->sp;
Index: kernel/arch/ppc32/include/faddr.h
===================================================================
--- kernel/arch/ppc32/include/faddr.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/ppc32/include/faddr.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -27,5 +27,5 @@
  */
 
-/** @addtogroup ppc32	
+/** @addtogroup ppc32
  * @{
  */
@@ -38,5 +38,5 @@
 #include <typedefs.h>
 
-#define FADDR(fptr)		((uintptr_t) (fptr))
+#define FADDR(fptr)  ((uintptr_t) (fptr))
 
 #endif
Index: kernel/arch/ppc32/include/fpu_context.h
===================================================================
--- kernel/arch/ppc32/include/fpu_context.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/ppc32/include/fpu_context.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -27,5 +27,5 @@
  */
 
-/** @addtogroup ppc32	
+/** @addtogroup ppc32
  * @{
  */
@@ -36,7 +36,5 @@
 #define KERN_ppc32_FPU_CONTEXT_H_
 
-#ifndef KERN_ppc32_TYPES_H_
-	#include <typedefs.h>
-#endif
+#include <typedefs.h>
 
 typedef struct {
Index: kernel/arch/ppc32/include/interrupt.h
===================================================================
--- kernel/arch/ppc32/include/interrupt.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/ppc32/include/interrupt.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -38,15 +38,15 @@
 #include <arch/exception.h>
 
-#define IVT_ITEMS 16
-#define IVT_FIRST 0
+#define IVT_ITEMS  16
+#define IVT_FIRST  0
 
-#define VECTOR_DATA_STORAGE 2
-#define VECTOR_INSTRUCTION_STORAGE 3
-#define VECTOR_EXTERNAL 4
-#define VECTOR_DECREMENTER 8
+#define VECTOR_DATA_STORAGE         2
+#define VECTOR_INSTRUCTION_STORAGE  3
+#define VECTOR_EXTERNAL             4
+#define VECTOR_DECREMENTER          8
 
 extern void start_decrementer(void);
 extern void interrupt_init(void);
-extern void extint_handler(int n, istate_t *istate);
+extern void extint_handler(unsigned int, istate_t *);
 
 #endif
Index: kernel/arch/ppc32/include/mm/as.h
===================================================================
--- kernel/arch/ppc32/include/mm/as.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/ppc32/include/mm/as.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -27,5 +27,5 @@
  */
 
-/** @addtogroup ppc32mm	
+/** @addtogroup ppc32mm
  * @{
  */
@@ -36,12 +36,12 @@
 #define KERN_ppc32_AS_H_
 
-#define KERNEL_ADDRESS_SPACE_SHADOWED_ARCH	0
+#define KERNEL_ADDRESS_SPACE_SHADOWED_ARCH  0
 
-#define KERNEL_ADDRESS_SPACE_START_ARCH		((unsigned long) 0x80000000)
-#define KERNEL_ADDRESS_SPACE_END_ARCH		((unsigned long) 0xffffffff)
-#define USER_ADDRESS_SPACE_START_ARCH		((unsigned long) 0x00000000)
-#define USER_ADDRESS_SPACE_END_ARCH		((unsigned long) 0x7fffffff)
+#define KERNEL_ADDRESS_SPACE_START_ARCH  ((unsigned long) 0x80000000)
+#define KERNEL_ADDRESS_SPACE_END_ARCH    ((unsigned long) 0xffffffff)
+#define USER_ADDRESS_SPACE_START_ARCH    ((unsigned long) 0x00000000)
+#define USER_ADDRESS_SPACE_END_ARCH      ((unsigned long) 0x7fffffff)
 
-#define USTACK_ADDRESS_ARCH	(0x7fffffff - (PAGE_SIZE - 1))
+#define USTACK_ADDRESS_ARCH  (0x7fffffff - (PAGE_SIZE - 1))
 
 typedef struct {
@@ -50,7 +50,7 @@
 #include <genarch/mm/as_pt.h>
 
-#define as_constructor_arch(as, flags)		(as != as)
-#define as_destructor_arch(as)			(as != as)
-#define as_create_arch(as, flags)		(as != as)
+#define as_constructor_arch(as, flags)  (as != as)
+#define as_destructor_arch(as)          (as != as)
+#define as_create_arch(as, flags)       (as != as)
 #define as_deinstall_arch(as)
 #define as_invalidate_translation_cache(as, page, cnt)
Index: kernel/arch/ppc32/include/mm/asid.h
===================================================================
--- kernel/arch/ppc32/include/mm/asid.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/ppc32/include/mm/asid.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -27,5 +27,5 @@
  */
 
-/** @addtogroup ppc32mm	
+/** @addtogroup ppc32mm
  * @{
  */
@@ -38,5 +38,5 @@
 #include <typedefs.h>
 
-#define ASID_MAX_ARCH		4096
+#define ASID_MAX_ARCH  4096
 
 typedef uint32_t asid_t;
Index: kernel/arch/ppc32/include/mm/frame.h
===================================================================
--- kernel/arch/ppc32/include/mm/frame.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/ppc32/include/mm/frame.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -43,6 +43,19 @@
 
 #include <typedefs.h>
+#include <trace.h>
 
 extern uintptr_t last_frame;
+
+NO_TRACE static inline uint32_t physmem_top(void)
+{
+	uint32_t physmem;
+	
+	asm volatile (
+		"mfsprg3 %[physmem]\n"
+		: [physmem] "=r" (physmem)
+	);
+	
+	return physmem;
+}
 
 extern void frame_arch_init(void);
Index: kernel/arch/ppc32/include/mm/page.h
===================================================================
--- kernel/arch/ppc32/include/mm/page.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/ppc32/include/mm/page.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -27,5 +27,5 @@
  */
 
-/** @addtogroup ppc32mm	
+/** @addtogroup ppc32mm
  * @{
  */
@@ -37,16 +37,17 @@
 
 #include <arch/mm/frame.h>
+#include <trace.h>
 
-#define PAGE_WIDTH	FRAME_WIDTH
-#define PAGE_SIZE	FRAME_SIZE
+#define PAGE_WIDTH  FRAME_WIDTH
+#define PAGE_SIZE   FRAME_SIZE
 
 #ifdef KERNEL
 
 #ifndef __ASM__
-#	define KA2PA(x)	(((uintptr_t) (x)) - 0x80000000)
-#	define PA2KA(x)	(((uintptr_t) (x)) + 0x80000000)
+	#define KA2PA(x)  (((uintptr_t) (x)) - 0x80000000)
+	#define PA2KA(x)  (((uintptr_t) (x)) + 0x80000000)
 #else
-#	define KA2PA(x)	((x) - 0x80000000)
-#	define PA2KA(x)	((x) + 0x80000000)
+	#define KA2PA(x)  ((x) - 0x80000000)
+	#define PA2KA(x)  ((x) + 0x80000000)
 #endif
 
@@ -65,37 +66,43 @@
 
 /* Number of entries in each level. */
-#define PTL0_ENTRIES_ARCH	1024
-#define PTL1_ENTRIES_ARCH	0
-#define PTL2_ENTRIES_ARCH	0
-#define PTL3_ENTRIES_ARCH	1024
+#define PTL0_ENTRIES_ARCH  1024
+#define PTL1_ENTRIES_ARCH  0
+#define PTL2_ENTRIES_ARCH  0
+#define PTL3_ENTRIES_ARCH  1024
 
 /* Page table sizes for each level. */
-#define PTL0_SIZE_ARCH		ONE_FRAME
-#define PTL1_SIZE_ARCH		0
-#define PTL2_SIZE_ARCH		0
-#define PTL3_SIZE_ARCH		ONE_FRAME
+#define PTL0_SIZE_ARCH  ONE_FRAME
+#define PTL1_SIZE_ARCH  0
+#define PTL2_SIZE_ARCH  0
+#define PTL3_SIZE_ARCH  ONE_FRAME
 
 /* Macros calculating indices into page tables on each level. */
-#define PTL0_INDEX_ARCH(vaddr)	(((vaddr) >> 22) & 0x3ff)
-#define PTL1_INDEX_ARCH(vaddr)	0
-#define PTL2_INDEX_ARCH(vaddr)	0
-#define PTL3_INDEX_ARCH(vaddr)	(((vaddr) >> 12) & 0x3ff)
+#define PTL0_INDEX_ARCH(vaddr)  (((vaddr) >> 22) & 0x3ff)
+#define PTL1_INDEX_ARCH(vaddr)  0
+#define PTL2_INDEX_ARCH(vaddr)  0
+#define PTL3_INDEX_ARCH(vaddr)  (((vaddr) >> 12) & 0x3ff)
 
 /* Get PTE address accessors for each level. */
 #define GET_PTL1_ADDRESS_ARCH(ptl0, i) \
 	(((pte_t *) (ptl0))[(i)].pfn << 12)
+
 #define GET_PTL2_ADDRESS_ARCH(ptl1, i) \
 	(ptl1)
+
 #define GET_PTL3_ADDRESS_ARCH(ptl2, i) \
 	(ptl2)
-#define GET_FRAME_ADDRESS_ARCH(ptl3, i)	\
+
+#define GET_FRAME_ADDRESS_ARCH(ptl3, i) \
 	(((pte_t *) (ptl3))[(i)].pfn << 12)
 
 /* Set PTE address accessors for each level. */
 #define SET_PTL0_ADDRESS_ARCH(ptl0)
+
 #define SET_PTL1_ADDRESS_ARCH(ptl0, i, a) \
 	(((pte_t *) (ptl0))[(i)].pfn = (a) >> 12)
+
 #define SET_PTL2_ADDRESS_ARCH(ptl1, i, a)
 #define SET_PTL3_ADDRESS_ARCH(ptl2, i, a)
+
 #define SET_FRAME_ADDRESS_ARCH(ptl3, i, a) \
 	(((pte_t *) (ptl3))[(i)].pfn = (a) >> 12)
@@ -104,25 +111,30 @@
 #define GET_PTL1_FLAGS_ARCH(ptl0, i) \
 	get_pt_flags((pte_t *) (ptl0), (size_t) (i))
+
 #define GET_PTL2_FLAGS_ARCH(ptl1, i) \
 	PAGE_PRESENT
+
 #define GET_PTL3_FLAGS_ARCH(ptl2, i) \
 	PAGE_PRESENT
+
 #define GET_FRAME_FLAGS_ARCH(ptl3, i) \
 	get_pt_flags((pte_t *) (ptl3), (size_t) (i))
 
 /* Set PTE flags accessors for each level. */
-#define SET_PTL1_FLAGS_ARCH(ptl0, i, x)	\
+#define SET_PTL1_FLAGS_ARCH(ptl0, i, x) \
 	set_pt_flags((pte_t *) (ptl0), (size_t) (i), (x))
+
 #define SET_PTL2_FLAGS_ARCH(ptl1, i, x)
 #define SET_PTL3_FLAGS_ARCH(ptl2, i, x)
+
 #define SET_FRAME_FLAGS_ARCH(ptl3, i, x) \
 	set_pt_flags((pte_t *) (ptl3), (size_t) (i), (x))
 
 /* Macros for querying the last-level PTEs. */
-#define PTE_VALID_ARCH(pte)			(*((uint32_t *) (pte)) != 0)
-#define PTE_PRESENT_ARCH(pte)			((pte)->present != 0)
-#define PTE_GET_FRAME_ARCH(pte)			((pte)->pfn << 12)
-#define PTE_WRITABLE_ARCH(pte)			1
-#define PTE_EXECUTABLE_ARCH(pte)		1
+#define PTE_VALID_ARCH(pte)       (*((uint32_t *) (pte)) != 0)
+#define PTE_PRESENT_ARCH(pte)     ((pte)->present != 0)
+#define PTE_GET_FRAME_ARCH(pte)   ((pte)->pfn << 12)
+#define PTE_WRITABLE_ARCH(pte)    1
+#define PTE_EXECUTABLE_ARCH(pte)  1
 
 #ifndef __ASM__
@@ -133,34 +145,34 @@
 /** Page Table Entry. */
 typedef struct {
-	unsigned present : 1;             /**< Present bit. */
-	unsigned page_write_through : 1;  /**< Write thought caching. */
-	unsigned page_cache_disable : 1;  /**< No caching. */
-	unsigned accessed : 1;            /**< Accessed bit. */
-	unsigned global : 1;              /**< Global bit. */
-	unsigned valid : 1;               /**< Valid content even if not present. */
-	unsigned pfn : 20;                /**< Physical frame number. */
+	unsigned int present : 1;             /**< Present bit. */
+	unsigned int page_write_through : 1;  /**< Write thought caching. */
+	unsigned int page_cache_disable : 1;  /**< No caching. */
+	unsigned int accessed : 1;            /**< Accessed bit. */
+	unsigned int global : 1;              /**< Global bit. */
+	unsigned int valid : 1;               /**< Valid content even if not present. */
+	unsigned int pfn : 20;                /**< Physical frame number. */
 } pte_t;
 
-static inline unsigned int get_pt_flags(pte_t *pt, size_t i)
+NO_TRACE static inline unsigned int get_pt_flags(pte_t *pt, size_t i)
 {
-	pte_t *p = &pt[i];
+	pte_t *entry = &pt[i];
 	
-	return (((!p->page_cache_disable) << PAGE_CACHEABLE_SHIFT) |
-	    ((!p->present) << PAGE_PRESENT_SHIFT) |
+	return (((!entry->page_cache_disable) << PAGE_CACHEABLE_SHIFT) |
+	    ((!entry->present) << PAGE_PRESENT_SHIFT) |
 	    (1 << PAGE_USER_SHIFT) |
 	    (1 << PAGE_READ_SHIFT) |
 	    (1 << PAGE_WRITE_SHIFT) |
 	    (1 << PAGE_EXEC_SHIFT) |
-	    (p->global << PAGE_GLOBAL_SHIFT));
+	    (entry->global << PAGE_GLOBAL_SHIFT));
 }
 
-static inline void set_pt_flags(pte_t *pt, size_t i, int flags)
+NO_TRACE static inline void set_pt_flags(pte_t *pt, size_t i, int flags)
 {
-	pte_t *p = &pt[i];
+	pte_t *entry = &pt[i];
 	
-	p->page_cache_disable = !(flags & PAGE_CACHEABLE);
-	p->present = !(flags & PAGE_NOT_PRESENT);
-	p->global = (flags & PAGE_GLOBAL) != 0;
-	p->valid = 1;
+	entry->page_cache_disable = !(flags & PAGE_CACHEABLE);
+	entry->present = !(flags & PAGE_NOT_PRESENT);
+	entry->global = (flags & PAGE_GLOBAL) != 0;
+	entry->valid = 1;
 }
 
Index: kernel/arch/ppc32/include/mm/tlb.h
===================================================================
--- kernel/arch/ppc32/include/mm/tlb.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/ppc32/include/mm/tlb.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -27,5 +27,5 @@
  */
 
-/** @addtogroup ppc32mm	
+/** @addtogroup ppc32mm
  * @{
  */
@@ -45,38 +45,41 @@
 
 typedef struct {
-	unsigned v : 1;          /**< Valid */
-	unsigned vsid : 24;      /**< Virtual Segment ID */
-	unsigned h : 1;          /**< Primary/secondary hash */
-	unsigned api : 6;        /**< Abbreviated Page Index */
-	unsigned rpn : 20;       /**< Real Page Number */
-	unsigned reserved0 : 3;
-	unsigned r : 1;          /**< Reference */
-	unsigned c : 1;          /**< Change */
-	unsigned wimg : 4;       /**< Access control */
-	unsigned reserved1 : 1;
-	unsigned pp : 2;         /**< Page protection */
+	unsigned int v : 1;          /**< Valid */
+	unsigned int vsid : 24;      /**< Virtual Segment ID */
+	unsigned int h : 1;          /**< Primary/secondary hash */
+	unsigned int api : 6;        /**< Abbreviated Page Index */
+	unsigned int rpn : 20;       /**< Real Page Number */
+	unsigned int reserved0 : 3;
+	unsigned int r : 1;          /**< Reference */
+	unsigned int c : 1;          /**< Change */
+	unsigned int wimg : 4;       /**< Access control */
+	unsigned int reserved1 : 1;
+	unsigned int pp : 2;         /**< Page protection */
 } phte_t;
 
 typedef struct {
-	unsigned v : 1;
-	unsigned vsid : 24;
-	unsigned reserved0 : 1;
-	unsigned api : 6;
+	unsigned int v : 1;
+	unsigned int vsid : 24;
+	unsigned int reserved0 : 1;
+	unsigned int api : 6;
 } ptehi_t;
 
 typedef struct {
-	unsigned rpn : 20;
-	unsigned xpn : 3;
-	unsigned reserved0 : 1;
-	unsigned c : 1;
-	unsigned wimg : 4;
-	unsigned x : 1;
-	unsigned pp : 2;
+	unsigned int rpn : 20;
+	unsigned int xpn : 3;
+	unsigned int reserved0 : 1;
+	unsigned int c : 1;
+	unsigned int wimg : 4;
+	unsigned int x : 1;
+	unsigned int pp : 2;
 } ptelo_t;
 
 extern void pht_init(void);
-extern void pht_refill(int n, istate_t *istate);
-extern bool pht_refill_real(int n, istate_t *istate) __attribute__ ((section("K_UNMAPPED_TEXT_START")));
-extern void tlb_refill_real(int n, uint32_t tlbmiss, ptehi_t ptehi, ptelo_t ptelo, istate_t *istate) __attribute__ ((section("K_UNMAPPED_TEXT_START")));
+extern void pht_refill(unsigned int, istate_t *);
+
+extern bool pht_refill_real(unsigned int, istate_t *)
+    __attribute__ ((section("K_UNMAPPED_TEXT_START")));
+extern void tlb_refill_real(unsigned int, uint32_t, ptehi_t, ptelo_t,
+    istate_t *) __attribute__ ((section("K_UNMAPPED_TEXT_START")));
 
 #endif
Index: rnel/arch/ppc32/include/regutils.h
===================================================================
--- kernel/arch/ppc32/include/regutils.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ 	(revision )
@@ -1,45 +1,0 @@
-/*
- * 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 ppc32
- * @{
- */
-/** 
- * @file
- * @brief Utilities for convenient manipulation with ppc32 registers.
- */
-
-#ifndef KERN_ppc32_REGUTILS_H_
-#define KERN_ppc32_REGUTILS_H_
-
-#define MSR_PR (1 << 14)
-
-#endif
-
-/** @}
- */
Index: kernel/arch/ppc32/include/types.h
===================================================================
--- kernel/arch/ppc32/include/types.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/ppc32/include/types.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -50,9 +50,9 @@
 } fncptr_t;
 
-/**< Formats for uintptr_t, size_t */
+/** Formats for uintptr_t, size_t */
 #define PRIp  "x"
 #define PRIs  "u"
 
-/**< Formats for (u)int8_t, (u)int16_t, (u)int32_t, (u)int64_t and (u)native_t */
+/** Formats for (u)int8_t, (u)int16_t, (u)int32_t, (u)int64_t and (u)native_t */
 #define PRId8   "d"
 #define PRId16  "d"
Index: kernel/arch/ppc32/src/asm.S
===================================================================
--- kernel/arch/ppc32/src/asm.S	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/ppc32/src/asm.S	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -1,31 +1,32 @@
-#
-# 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.
-#
+/*
+ * Copyright (c) 2005 Martin Decky
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
 
 #include <arch/asm/regname.h>
+#include <arch/cpu.h>
 
 .text
@@ -41,36 +42,39 @@
 .global memcpy_from_uspace_failover_address
 .global memcpy_to_uspace_failover_address
+.global early_putchar
 
 userspace_asm:
-
-	# r3 = uspace_uarg
-	# r4 = stack
-	# r5 = entry
-	
-	# disable interrupts
-
+	
+	/*
+	 * r3 = uspace_uarg
+	 * r4 = stack
+	 * r5 = entry
+	 */
+	
+	/* Disable interrupts */
+	
 	mfmsr r31
 	rlwinm r31, r31, 0, 17, 15
 	mtmsr r31
 	
-	# set entry point
+	/* Set entry point */
 	
 	mtsrr0 r5
 	
-	# set problem state, enable interrupts
-	
-	ori r31, r31, msr_pr
-	ori r31, r31, msr_ee
+	/* Set problem state, enable interrupts */
+	
+	ori r31, r31, MSR_PR
+	ori r31, r31, MSR_EE
 	mtsrr1 r31
 	
-	# set stack
+	/* Set stack */
 	
 	mr sp, r4
-
-	# %r6 is defined to hold pcb_ptr - set it to 0
-
+	
+	/* %r6 is defined to hold pcb_ptr - set it to 0 */
+	
 	xor r6, r6, r6
 	
-	# jump to userspace
+	/* Jump to userspace */
 	
 	rfi
@@ -78,5 +82,5 @@
 iret:
 	
-	# disable interrupts
+	/* Disable interrupts */
 	
 	mfmsr r31
@@ -140,10 +144,10 @@
 iret_syscall:
 	
-	# reset decrementer
-
+	/* Reset decrementer */
+	
 	li r31, 1000
 	mtdec r31
 	
-	# disable interrupts
+	/* Disable interrupts */
 	
 	mfmsr r31
@@ -201,5 +205,5 @@
 	lwz r12, 156(sp)
 	lwz sp, 160(sp)
-
+	
 	rfi
 
@@ -213,9 +217,9 @@
 memcpy_from_uspace:
 memcpy_to_uspace:
-
+	
 	srwi. r7, r5, 3
 	addi r6, r3, -4
 	addi r4, r4, -4
-	beq	2f
+	beq 2f
 	
 	andi. r0, r6, 3
@@ -225,57 +229,60 @@
 	1:
 	
-	lwz r7, 4(r4)
-	lwzu r8, 8(r4)
-	stw r7, 4(r6)
-	stwu r8, 8(r6)
-	bdnz 1b
-	
-	andi. r5, r5, 7
+		lwz r7, 4(r4)
+		lwzu r8, 8(r4)
+		stw r7, 4(r6)
+		stwu r8, 8(r6)
+		bdnz 1b
+		
+		andi. r5, r5, 7
 	
 	2:
 	
-	cmplwi 0, r5, 4
-	blt 3f
-	
-	lwzu r0, 4(r4)
-	addi r5, r5, -4
-	stwu r0, 4(r6)
+		cmplwi 0, r5, 4
+		blt 3f
+		
+		lwzu r0, 4(r4)
+		addi r5, r5, -4
+		stwu r0, 4(r6)
 	
 	3:
 	
-	cmpwi 0, r5, 0
-	beqlr
-	mtctr r5
-	addi r4, r4, 3
-	addi r6, r6, 3
+		cmpwi 0, r5, 0
+		beqlr
+		mtctr r5
+		addi r4, r4, 3
+		addi r6, r6, 3
 	
 	4:
 	
-	lbzu r0, 1(r4)
-	stbu r0, 1(r6)
-	bdnz 4b
-	blr
+		lbzu r0, 1(r4)
+		stbu r0, 1(r6)
+		bdnz 4b
+		blr
 	
 	5:
 	
-	subfic r0, r0, 4
-	mtctr r0
+		subfic r0, r0, 4
+		mtctr r0
 	
 	6:
 	
-	lbz r7, 4(r4)
-	addi r4, r4, 1
-	stb r7, 4(r6)
-	addi r6, r6, 1
-	bdnz 6b
-	subf r5, r0, r5
-	rlwinm. r7, r5, 32-3, 3, 31
-	beq 2b
-	mtctr r7
-	b 1b
+		lbz r7, 4(r4)
+		addi r4, r4, 1
+		stb r7, 4(r6)
+		addi r6, r6, 1
+		bdnz 6b
+		subf r5, r0, r5
+		rlwinm. r7, r5, 32-3, 3, 31
+		beq 2b
+		mtctr r7
+		b 1b
 
 memcpy_from_uspace_failover_address:
 memcpy_to_uspace_failover_address:
-	# return zero, failure
+	/* Return zero, failure */
 	xor r3, r3, r3
 	blr
+
+early_putchar:
+	blr
Index: kernel/arch/ppc32/src/context.S
===================================================================
--- kernel/arch/ppc32/src/context.S	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/ppc32/src/context.S	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -29,5 +29,5 @@
 #include <arch/context_offset.h>
 
-.text   
+.text
 
 .global context_save_arch
@@ -46,5 +46,5 @@
 	li r3, 1
 	blr
-	
+
 context_restore_arch:
 	CONTEXT_RESTORE_ARCH_CORE r3
Index: kernel/arch/ppc32/src/cpu/cpu.c
===================================================================
--- kernel/arch/ppc32/src/cpu/cpu.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/ppc32/src/cpu/cpu.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -34,5 +34,4 @@
 
 #include <arch/cpu.h>
-#include <arch/cpuid.h>
 #include <cpu.h>
 #include <arch.h>
@@ -45,33 +44,30 @@
 void cpu_identify(void)
 {
-	cpu_info_t info;
-	
-	cpu_version(&info);
-	CPU->arch.version = info.version;
-	CPU->arch.revision = info.revision;
+	cpu_version(&CPU->arch);
 }
 
-void cpu_print_report(cpu_t *m)
+void cpu_print_report(cpu_t *cpu)
 {
 	const char *name;
 	
-	switch (m->arch.version) {
+	switch (cpu->arch.version) {
 		case 8:
-			name = " (PowerPC 750)";
+			name = "PowerPC 750";
 			break;
 		case 9:
-			name = " (PowerPC 604e)";
+			name = "PowerPC 604e";
 			break;
 		case 0x81:
-			name = " (PowerPC 8260)";
+			name = "PowerPC 8260";
 			break;
 		case 0x8081:
-			name = " (PowerPC 826xA)";
+			name = "PowerPC 826xA";
 			break;
 		default:
-			name = "";
+			name = "unknown";
 	}
 	
-	printf("cpu%d: version=%d%s, revision=%d\n", m->id, m->arch.version, name, m->arch.revision);
+	printf("cpu%" PRIs ": version=%" PRIu16" (%s), revision=%" PRIu16 "\n", cpu->id,
+	    cpu->arch.version, name, cpu->arch.revision);
 }
 
Index: kernel/arch/ppc32/src/ddi/ddi.c
===================================================================
--- kernel/arch/ppc32/src/ddi/ddi.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/ppc32/src/ddi/ddi.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -46,4 +46,5 @@
  *
  * @return 0 on success or an error code from errno.h.
+ *
  */
 int ddi_iospace_enable_arch(task_t *task, uintptr_t ioaddr, size_t size)
Index: rnel/arch/ppc32/src/debug/panic.s
===================================================================
--- kernel/arch/ppc32/src/debug/panic.s	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ 	(revision )
@@ -1,38 +1,0 @@
-#
-# Copyright (c) 2005 Martin Decky
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions
-# are met:
-#
-# - Redistributions of source code must retain the above copyright
-#   notice, this list of conditions and the following disclaimer.
-# - Redistributions in binary form must reproduce the above copyright
-#   notice, this list of conditions and the following disclaimer in the
-#   documentation and/or other materials provided with the distribution.
-# - The name of the author may not be used to endorse or promote products
-#   derived from this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
-# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
-# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
-# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
-# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
-# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-#
-
-#include <arch/asm/macro.h>
-
-.text
-.global panic_printf
-
-panic_printf:
-	lis %r14, halt@ha
-	addi %r14, %r14, halt@l
-	mtlr %r14	# fake stack to make printf return to halt
-	b printf
Index: kernel/arch/ppc32/src/debug/stacktrace.c
===================================================================
--- kernel/arch/ppc32/src/debug/stacktrace.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/ppc32/src/debug/stacktrace.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -37,32 +37,41 @@
 #include <typedefs.h>
 
-bool kernel_frame_pointer_validate(uintptr_t fp)
+#define FRAME_OFFSET_FP_PREV  0
+#define FRAME_OFFSET_RA       1
+
+bool kernel_stack_trace_context_validate(stack_trace_context_t *ctx)
 {
-	return false;
+	return ctx->fp != 0;
 }
 
-bool kernel_frame_pointer_prev(uintptr_t fp, uintptr_t *prev)
+bool kernel_frame_pointer_prev(stack_trace_context_t *ctx, uintptr_t *prev)
 {
-	return false;
+	uint32_t *stack = (void *) ctx->fp;
+	*prev = stack[FRAME_OFFSET_FP_PREV];
+	return true;
 }
 
-bool kernel_return_address_get(uintptr_t fp, uintptr_t *ra)
+bool kernel_return_address_get(stack_trace_context_t *ctx, uintptr_t *ra)
 {
-	return false;
+	uint32_t *stack = (void *) ctx->fp;
+	*ra = stack[FRAME_OFFSET_RA];
+	return true;
 }
 
-bool uspace_frame_pointer_validate(uintptr_t fp)
+bool uspace_stack_trace_context_validate(stack_trace_context_t *ctx)
 {
-	return false;
+	return ctx->fp != 0;
 }
 
-bool uspace_frame_pointer_prev(uintptr_t fp, uintptr_t *prev)
+bool uspace_frame_pointer_prev(stack_trace_context_t *ctx, uintptr_t *prev)
 {
-	return false;
+	return !copy_from_uspace((void *) prev,
+	    (uint32_t *) ctx->fp + FRAME_OFFSET_FP_PREV, sizeof(*prev));
 }
 
-bool uspace_return_address_get(uintptr_t fp, uintptr_t *ra)
+bool uspace_return_address_get(stack_trace_context_t *ctx, uintptr_t *ra)
 {
-	return false;
+	return !copy_from_uspace((void *) ra,
+	    (uint32_t *) ctx->fp + FRAME_OFFSET_RA, sizeof(*ra));
 }
 
Index: kernel/arch/ppc32/src/debug/stacktrace_asm.S
===================================================================
--- kernel/arch/ppc32/src/debug/stacktrace_asm.S	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/ppc32/src/debug/stacktrace_asm.S	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -27,4 +27,6 @@
 #
 
+#include <arch/asm/regname.h>
+
 .text
 
@@ -33,6 +35,8 @@
 
 frame_pointer_get:
+	mr r3, sp
 	blr
 
 program_counter_get:
+	mflr r3
 	blr
Index: kernel/arch/ppc32/src/drivers/pic.c
===================================================================
--- kernel/arch/ppc32/src/drivers/pic.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/ppc32/src/drivers/pic.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -32,5 +32,4 @@
 /** @file
  */
-
 
 #include <arch/drivers/pic.h>
@@ -79,20 +78,22 @@
 }
 
-/** Return number of pending interrupt */
-int pic_get_pending(void)
+/** Return number of pending interrupts
+ *
+ */
+uint8_t pic_get_pending(void)
 {
 	if (pic) {
-		int pending;
+		uint32_t pending;
 		
 		pending = pic[PIC_PENDING_LOW];
-		if (pending)
+		if (pending != 0)
 			return fnzb32(pending);
 		
 		pending = pic[PIC_PENDING_HIGH];
-		if (pending)
+		if (pending != 0)
 			return fnzb32(pending) + 32;
 	}
 	
-	return -1;
+	return 255;
 }
 
Index: kernel/arch/ppc32/src/exception.S
===================================================================
--- kernel/arch/ppc32/src/exception.S	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/ppc32/src/exception.S	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -28,4 +28,5 @@
 
 #include <arch/asm/regname.h>
+#include <arch/cpu.h>
 #include <arch/mm/page.h>
 
@@ -34,7 +35,7 @@
 .macro CONTEXT_STORE
 	
-	# save R12 in SPRG1, backup CR in R12
+	# save r12 in SPRG1, backup CR in r12
 	# save SP in SPRG2
-
+	
 	mtsprg1 r12
 	mfcr r12
@@ -288,5 +289,5 @@
 	
 	mfmsr r12
-	ori r12, r12, (msr_ir | msr_dr)@l
+	ori r12, r12, (MSR_IR | MSR_DR)@l
 	mtsrr1 r12
 	
@@ -307,5 +308,5 @@
 	
 	mfmsr r12
-	ori r12, r12, (msr_ir | msr_dr)@l
+	ori r12, r12, (MSR_IR | MSR_DR)@l
 	mtsrr1 r12
 	
Index: kernel/arch/ppc32/src/fpu_context.S
===================================================================
--- kernel/arch/ppc32/src/fpu_context.S	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/ppc32/src/fpu_context.S	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -30,5 +30,5 @@
 #include <arch/context_offset.h>
 
-.text   
+.text
 
 .global fpu_context_save
@@ -87,5 +87,5 @@
 	
 	blr
-	
+
 fpu_context_restore:
 //	FPU_CONTEXT_LOAD r3
Index: kernel/arch/ppc32/src/interrupt.c
===================================================================
--- kernel/arch/ppc32/src/interrupt.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/ppc32/src/interrupt.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -44,21 +44,46 @@
 #include <print.h>
 
-
 void start_decrementer(void)
 {
 	asm volatile (
-		"mtdec %0\n"
-		:
-		: "r" (1000)
+		"mtdec %[dec]\n"
+		:: [dec] "r" (1000)
 	);
 }
 
+void istate_decode(istate_t *istate)
+{
+	printf("r0 =%p\tr1 =%p\tr2 =%p\n", istate->r0, istate->sp, istate->r2);
+	printf("r3 =%p\tr4 =%p\tr5 =%p\n", istate->r3, istate->r4, istate->r5);
+	printf("r6 =%p\tr7 =%p\tr8 =%p\n", istate->r6, istate->r7, istate->r8);
+	printf("r9 =%p\tr10=%p\tr11=%p\n",
+	    istate->r9, istate->r10, istate->r11);
+	printf("r12=%p\tr13=%p\tr14=%p\n",
+	    istate->r12, istate->r13, istate->r14);
+	printf("r15=%p\tr16=%p\tr17=%p\n",
+	    istate->r15, istate->r16, istate->r17);
+	printf("r18=%p\tr19=%p\tr20=%p\n",
+	    istate->r18, istate->r19, istate->r20);
+	printf("r21=%p\tr22=%p\tr23=%p\n",
+	    istate->r21, istate->r22, istate->r23);
+	printf("r24=%p\tr25=%p\tr26=%p\n",
+	    istate->r24, istate->r25, istate->r26);
+	printf("r27=%p\tr28=%p\tr29=%p\n",
+	    istate->r27, istate->r28, istate->r29);
+	printf("r30=%p\tr31=%p\n", istate->r30, istate->r31);
+	printf("cr =%p\tpc =%p\tlr =%p\n", istate->cr, istate->pc, istate->lr);
+	printf("ctr=%p\txer=%p\tdar=%p\n",
+	    istate->ctr, istate->xer, istate->dar);
+	printf("srr1=%p\n", istate->srr1);
+}
 
-/** Handler of external interrupts */
-static void exception_external(int n, istate_t *istate)
+/** External interrupts handler
+ *
+ */
+static void exception_external(unsigned int n, istate_t *istate)
 {
-	int inum;
+	uint8_t inum;
 	
-	while ((inum = pic_get_pending()) != -1) {
+	while ((inum = pic_get_pending()) != 255) {
 		irq_t *irq = irq_dispatch_and_lock(inum);
 		if (irq) {
@@ -80,5 +105,5 @@
 			}
 			
-			spinlock_unlock(&irq->lock);
+			irq_spinlock_unlock(&irq->lock, false);
 		} else {
 			/*
@@ -86,5 +111,6 @@
 			 */
 #ifdef CONFIG_DEBUG
-			printf("cpu%u: spurious interrupt (inum=%d)\n", CPU->id, inum);
+			printf("cpu%" PRIs ": spurious interrupt (inum=%" PRIu8 ")\n",
+			    CPU->id, inum);
 #endif
 		}
@@ -92,6 +118,5 @@
 }
 
-
-static void exception_decrementer(int n, istate_t *istate)
+static void exception_decrementer(unsigned int n, istate_t *istate)
 {
 	start_decrementer();
@@ -99,12 +124,15 @@
 }
 
-
 /* Initialize basic tables for exception dispatching */
 void interrupt_init(void)
 {
-	exc_register(VECTOR_DATA_STORAGE, "data_storage", pht_refill);
-	exc_register(VECTOR_INSTRUCTION_STORAGE, "instruction_storage", pht_refill);
-	exc_register(VECTOR_EXTERNAL, "external", exception_external);
-	exc_register(VECTOR_DECREMENTER, "timer", exception_decrementer);
+	exc_register(VECTOR_DATA_STORAGE, "data_storage", true,
+	    pht_refill);
+	exc_register(VECTOR_INSTRUCTION_STORAGE, "instruction_storage", true,
+	    pht_refill);
+	exc_register(VECTOR_EXTERNAL, "external", true,
+	    exception_external);
+	exc_register(VECTOR_DECREMENTER, "timer", true,
+	    exception_decrementer);
 }
 
Index: kernel/arch/ppc32/src/mm/as.c
===================================================================
--- kernel/arch/ppc32/src/mm/as.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/ppc32/src/mm/as.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -55,26 +55,13 @@
 void as_install_arch(as_t *as)
 {
-	asid_t asid;
 	uint32_t sr;
-
-	asid = as->asid;
 	
 	/* Lower 2 GB, user and supervisor access */
-	for (sr = 0; sr < 8; sr++) {
-		asm volatile (
-			"mtsrin %0, %1\n"
-			:
-			: "r" ((0x6000 << 16) + (asid << 4) + sr), "r" (sr << 28)
-		);
-	}
+	for (sr = 0; sr < 8; sr++)
+		sr_set(0x6000, as->asid, sr);
 	
 	/* Upper 2 GB, only supervisor access */
-	for (sr = 8; sr < 16; sr++) {
-		asm volatile (
-			"mtsrin %0, %1\n"
-			:
-			: "r" ((0x4000 << 16) + (asid << 4) + sr), "r" (sr << 28)
-		);
-	}
+	for (sr = 8; sr < 16; sr++)
+		sr_set(0x4000, as->asid, sr);
 }
 
Index: kernel/arch/ppc32/src/mm/frame.c
===================================================================
--- kernel/arch/ppc32/src/mm/frame.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/ppc32/src/mm/frame.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -45,12 +45,10 @@
 void physmem_print(void)
 {
-	unsigned int i;
+	printf("[base    ] [size    ]\n");
 	
-	printf("Base       Size\n");
-	printf("---------- ----------\n");
-		
+	size_t i;
 	for (i = 0; i < memmap.cnt; i++) {
 		printf("%#10x %#10x\n", memmap.zones[i].start,
-			memmap.zones[i].size);
+		    memmap.zones[i].size);
 	}
 }
@@ -60,19 +58,25 @@
 	pfn_t minconf = 2;
 	size_t i;
-	pfn_t start, conf;
-	size_t size;
 	
 	for (i = 0; i < memmap.cnt; i++) {
-		start = ADDR2PFN(ALIGN_UP((uintptr_t) memmap.zones[i].start, FRAME_SIZE));
-		size = SIZE2FRAMES(ALIGN_DOWN(memmap.zones[i].size, FRAME_SIZE));
+		/* To be safe, make the available zone possibly smaller */
+		uintptr_t new_start = ALIGN_UP((uintptr_t) memmap.zones[i].start,
+		    FRAME_SIZE);
+		size_t new_size = ALIGN_DOWN(memmap.zones[i].size -
+		    (new_start - ((uintptr_t) memmap.zones[i].start)), FRAME_SIZE);
 		
-		if ((minconf < start) || (minconf >= start + size))
-			conf = start;
+		pfn_t pfn = ADDR2PFN(new_start);
+		size_t count = SIZE2FRAMES(new_size);
+		
+		pfn_t conf;
+		if ((minconf < pfn) || (minconf >= pfn + count))
+			conf = pfn;
 		else
 			conf = minconf;
 		
-		zone_create(start, size, conf, 0);
-		if (last_frame < ALIGN_UP((uintptr_t) memmap.zones[i].start + memmap.zones[i].size, FRAME_SIZE))
-			last_frame = ALIGN_UP((uintptr_t) memmap.zones[i].start + memmap.zones[i].size, FRAME_SIZE);
+		zone_create(pfn, count, conf, 0);
+		
+		if (last_frame < ALIGN_UP(new_start + new_size, FRAME_SIZE))
+			last_frame = ALIGN_UP(new_start + new_size, FRAME_SIZE);
 	}
 	
@@ -82,10 +86,8 @@
 	
 	/* Mark the Page Hash Table frames as unavailable */
-	uint32_t sdr1;
-	asm volatile (
-		"mfsdr1 %0\n"
-		: "=r" (sdr1)
-	);
-	frame_mark_unavailable(ADDR2PFN(sdr1 & 0xffff000), 16); // FIXME
+	uint32_t sdr1 = sdr1_get();
+	
+	// FIXME: compute size of PHT exactly
+	frame_mark_unavailable(ADDR2PFN(sdr1 & 0xffff000), 16);
 }
 
Index: kernel/arch/ppc32/src/mm/page.c
===================================================================
--- kernel/arch/ppc32/src/mm/page.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/ppc32/src/mm/page.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -54,7 +54,9 @@
 	uintptr_t virtaddr = PA2KA(last_frame);
 	pfn_t i;
+	page_table_lock(AS_KERNEL, true);
 	for (i = 0; i < ADDR2PFN(ALIGN_UP(size, PAGE_SIZE)); i++)
 		page_mapping_insert(AS_KERNEL, virtaddr + PFN2ADDR(i),
 		    physaddr + PFN2ADDR(i), PAGE_NOT_CACHEABLE | PAGE_WRITE);
+	page_table_unlock(AS_KERNEL, true);
 	
 	last_frame = ALIGN_UP(last_frame + size, FRAME_SIZE);
Index: kernel/arch/ppc32/src/mm/tlb.c
===================================================================
--- kernel/arch/ppc32/src/mm/tlb.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/ppc32/src/mm/tlb.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -45,30 +45,28 @@
 
 static unsigned int seed = 10;
-static unsigned int seed_real __attribute__ ((section("K_UNMAPPED_DATA_START"))) = 42;
-
+static unsigned int seed_real
+    __attribute__ ((section("K_UNMAPPED_DATA_START"))) = 42;
 
 /** Try to find PTE for faulting address
  *
- * Try to find PTE for faulting address.
- * The as->lock must be held on entry to this function
- * if lock is true.
- *
- * @param as		Address space.
- * @param lock		Lock/unlock the address space.
- * @param badvaddr	Faulting virtual address.
- * @param access	Access mode that caused the fault.
- * @param istate	Pointer to interrupted state.
- * @param pfrc		Pointer to variable where as_page_fault() return code
- * 			will be stored.
- * @return		PTE on success, NULL otherwise.
- *
- */
-static pte_t *
-find_mapping_and_check(as_t *as, bool lock, uintptr_t badvaddr, int access,
+ * @param as       Address space.
+ * @param lock     Lock/unlock the address space.
+ * @param badvaddr Faulting virtual address.
+ * @param access   Access mode that caused the fault.
+ * @param istate   Pointer to interrupted state.
+ * @param pfrc     Pointer to variable where as_page_fault() return code
+ *                 will be stored.
+ *
+ * @return PTE on success, NULL otherwise.
+ *
+ */
+static pte_t *find_mapping_and_check(as_t *as, uintptr_t badvaddr, int access,
     istate_t *istate, int *pfrc)
 {
+	ASSERT(mutex_locked(&as->lock));
+
 	/*
 	 * Check if the mapping exists in page tables.
-	 */	
+	 */
 	pte_t *pte = page_mapping_find(as, badvaddr);
 	if ((pte) && (pte->present)) {
@@ -79,12 +77,12 @@
 		return pte;
 	} else {
-		int rc;
-	
 		/*
 		 * Mapping not found in page tables.
 		 * Resort to higher-level page fault handler.
 		 */
-		page_table_unlock(as, lock);
-		switch (rc = as_page_fault(badvaddr, access, istate)) {
+		page_table_unlock(as, true);
+		
+		int rc = as_page_fault(badvaddr, access, istate);
+		switch (rc) {
 		case AS_PF_OK:
 			/*
@@ -92,5 +90,5 @@
 			 * The mapping ought to be in place.
 			 */
-			page_table_lock(as, lock);
+			page_table_lock(as, true);
 			pte = page_mapping_find(as, badvaddr);
 			ASSERT((pte) && (pte->present));
@@ -98,29 +96,23 @@
 			return pte;
 		case AS_PF_DEFER:
-			page_table_lock(as, lock);
+			page_table_lock(as, true);
 			*pfrc = rc;
 			return NULL;
 		case AS_PF_FAULT:
-			page_table_lock(as, lock);
+			page_table_lock(as, true);
 			*pfrc = rc;
 			return NULL;
 		default:
 			panic("Unexpected rc (%d).", rc);
-		}	
-	}
-}
-
+		}
+	}
+}
 
 static void pht_refill_fail(uintptr_t badvaddr, istate_t *istate)
 {
-	const char *symbol = symtab_fmt_name_lookup(istate->pc);
-	const char *sym2 = symtab_fmt_name_lookup(istate->lr);
-	
-	fault_if_from_uspace(istate,
-	    "PHT Refill Exception on %p.", badvaddr);
-	panic("%p: PHT Refill Exception at %p (%s<-%s).", badvaddr,
-	    istate->pc, symbol, sym2);
-}
-
+	fault_if_from_uspace(istate, "PHT Refill Exception on %p.", badvaddr);
+	panic_memtrap(istate, PF_ACCESS_UNKNOWN, badvaddr,
+	    "PHT Refill Exception.");
+}
 
 static void pht_insert(const uintptr_t vaddr, const pte_t *pte)
@@ -129,16 +121,8 @@
 	uint32_t api = (vaddr >> 22) & 0x3f;
 	
-	uint32_t vsid;
-	asm volatile (
-		"mfsrin %0, %1\n"
-		: "=r" (vsid)
-		: "r" (vaddr)
-	);
-	
-	uint32_t sdr1;
-	asm volatile (
-		"mfsdr1 %0\n"
-		: "=r" (sdr1)
-	);
+	uint32_t vsid = sr_get(vaddr);
+	uint32_t sdr1 = sdr1_get();
+	
+	// FIXME: compute size of PHT exactly
 	phte_t *phte = (phte_t *) PA2KA(sdr1 & 0xffff0000);
 	
@@ -215,5 +199,4 @@
 }
 
-
 /** Process Instruction/Data Storage Exception
  *
@@ -222,19 +205,8 @@
  *
  */
-void pht_refill(int n, istate_t *istate)
-{
+void pht_refill(unsigned int n, istate_t *istate)
+{
+	as_t *as = (AS == NULL) ? AS_KERNEL : AS;
 	uintptr_t badvaddr;
-	pte_t *pte;
-	int pfrc;
-	as_t *as;
-	bool lock;
-	
-	if (AS == NULL) {
-		as = AS_KERNEL;
-		lock = false;
-	} else {
-		as = AS;
-		lock = true;
-	}
 	
 	if (n == VECTOR_DATA_STORAGE)
@@ -242,9 +214,11 @@
 	else
 		badvaddr = istate->pc;
-		
-	page_table_lock(as, lock);
-	
-	pte = find_mapping_and_check(as, lock, badvaddr,
+	
+	page_table_lock(as, true);
+	
+	int pfrc;
+	pte_t *pte = find_mapping_and_check(as, badvaddr,
 	    PF_ACCESS_READ /* FIXME */, istate, &pfrc);
+	
 	if (!pte) {
 		switch (pfrc) {
@@ -257,5 +231,5 @@
 			 * or copy_to_uspace().
 			 */
-			page_table_unlock(as, lock);
+			page_table_unlock(as, true);
 			return;
 		default:
@@ -264,15 +238,15 @@
 	}
 	
-	pte->accessed = 1; /* Record access to PTE */
+	/* Record access to PTE */
+	pte->accessed = 1;
 	pht_insert(badvaddr, pte);
 	
-	page_table_unlock(as, lock);
+	page_table_unlock(as, true);
 	return;
 	
 fail:
-	page_table_unlock(as, lock);
+	page_table_unlock(as, true);
 	pht_refill_fail(badvaddr, istate);
 }
-
 
 /** Process Instruction/Data Storage Exception in Real Mode
@@ -282,5 +256,5 @@
  *
  */
-bool pht_refill_real(int n, istate_t *istate)
+bool pht_refill_real(unsigned int n, istate_t *istate)
 {
 	uintptr_t badvaddr;
@@ -291,9 +265,5 @@
 		badvaddr = istate->pc;
 	
-	uint32_t physmem;
-	asm volatile (
-		"mfsprg3 %0\n"
-		: "=r" (physmem)
-	);
+	uint32_t physmem = physmem_top();
 	
 	if ((badvaddr < PA2KA(0)) || (badvaddr >= PA2KA(physmem)))
@@ -303,16 +273,8 @@
 	uint32_t api = (badvaddr >> 22) & 0x3f;
 	
-	uint32_t vsid;
-	asm volatile (
-		"mfsrin %0, %1\n"
-		: "=r" (vsid)
-		: "r" (badvaddr)
-	);
-	
-	uint32_t sdr1;
-	asm volatile (
-		"mfsdr1 %0\n"
-		: "=r" (sdr1)
-	);
+	uint32_t vsid = sr_get(badvaddr);
+	uint32_t sdr1 = sdr1_get();
+	
+	// FIXME: compute size of PHT exactly
 	phte_t *phte_real = (phte_t *) (sdr1 & 0xffff0000);
 	
@@ -396,18 +358,13 @@
 }
 
-
 /** Process ITLB/DTLB Miss Exception in Real Mode
  *
  *
  */
-void tlb_refill_real(int n, uint32_t tlbmiss, ptehi_t ptehi, ptelo_t ptelo, istate_t *istate)
+void tlb_refill_real(unsigned int n, uint32_t tlbmiss, ptehi_t ptehi,
+    ptelo_t ptelo, istate_t *istate)
 {
 	uint32_t badvaddr = tlbmiss & 0xfffffffc;
-	
-	uint32_t physmem;
-	asm volatile (
-		"mfsprg3 %0\n"
-		: "=r" (physmem)
-	);
+	uint32_t physmem = physmem_top();
 	
 	if ((badvaddr < PA2KA(0)) || (badvaddr >= PA2KA(physmem)))
@@ -420,15 +377,14 @@
 	uint32_t index = 0;
 	asm volatile (
-		"mtspr 981, %0\n"
-		"mtspr 982, %1\n"
-		"tlbld %2\n"
-		"tlbli %2\n"
-		: "=r" (index)
-		: "r" (ptehi),
-		  "r" (ptelo)
+		"mtspr 981, %[ptehi]\n"
+		"mtspr 982, %[ptelo]\n"
+		"tlbld %[index]\n"
+		"tlbli %[index]\n"
+		: [index] "=r" (index)
+		: [ptehi] "r" (ptehi),
+		  [ptelo] "r" (ptelo)
 	);
 }
 
-
 void tlb_arch_init(void)
 {
@@ -436,15 +392,15 @@
 }
 
-
 void tlb_invalidate_all(void)
 {
 	uint32_t index;
+	
 	asm volatile (
-		"li %0, 0\n"
+		"li %[index], 0\n"
 		"sync\n"
 		
 		".rept 64\n"
-		"tlbie %0\n"
-		"addi %0, %0, 0x1000\n"
+		"	tlbie %[index]\n"
+		"	addi %[index], %[index], 0x1000\n"
 		".endr\n"
 		
@@ -452,19 +408,16 @@
 		"tlbsync\n"
 		"sync\n"
-		: "=r" (index)
+		: [index] "=r" (index)
 	);
 }
 
-
 void tlb_invalidate_asid(asid_t asid)
 {
-	uint32_t sdr1;
-	asm volatile (
-		"mfsdr1 %0\n"
-		: "=r" (sdr1)
-	);
+	uint32_t sdr1 = sdr1_get();
+	
+	// FIXME: compute size of PHT exactly
 	phte_t *phte = (phte_t *) PA2KA(sdr1 & 0xffff0000);
 	
-	uint32_t i;
+	size_t i;
 	for (i = 0; i < 8192; i++) {
 		if ((phte[i].v) && (phte[i].vsid >= (asid << 4)) &&
@@ -472,7 +425,7 @@
 			phte[i].v = 0;
 	}
+	
 	tlb_invalidate_all();
 }
-
 
 void tlb_invalidate_pages(asid_t asid, uintptr_t page, size_t cnt)
@@ -482,15 +435,17 @@
 }
 
-
 #define PRINT_BAT(name, ureg, lreg) \
 	asm volatile ( \
-		"mfspr %0," #ureg "\n" \
-		"mfspr %1," #lreg "\n" \
-		: "=r" (upper), "=r" (lower) \
+		"mfspr %[upper], " #ureg "\n" \
+		"mfspr %[lower], " #lreg "\n" \
+		: [upper] "=r" (upper), \
+		  [lower] "=r" (lower) \
 	); \
+	\
 	mask = (upper & 0x1ffc) >> 2; \
 	if (upper & 3) { \
 		uint32_t tmp = mask; \
 		length = 128; \
+		\
 		while (tmp) { \
 			if ((tmp & 1) == 0) { \
@@ -503,4 +458,5 @@
 	} else \
 		length = 0; \
+	\
 	printf(name ": page=%.*p frame=%.*p length=%d KB (mask=%#x)%s%s\n", \
 	    sizeof(upper) * 2, upper & 0xffff0000, sizeof(lower) * 2, \
@@ -515,10 +471,6 @@
 	
 	for (sr = 0; sr < 16; sr++) {
-		uint32_t vsid;
-		asm volatile (
-			"mfsrin %0, %1\n"
-			: "=r" (vsid)
-			: "r" (sr << 28)
-		);
+		uint32_t vsid = sr_get(sr << 28);
+		
 		printf("sr[%02u]: vsid=%.*p (asid=%u)%s%s\n", sr,
 		    sizeof(vsid) * 2, vsid & 0xffffff, (vsid & 0xffffff) >> 4,
Index: kernel/arch/ppc32/src/ppc32.c
===================================================================
--- kernel/arch/ppc32/src/ppc32.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/ppc32/src/ppc32.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -201,5 +201,5 @@
 		pic_init(assigned_address[0].addr, PAGE_SIZE, &pic_cir,
 		    &pic_cir_arg);
-
+		
 #ifdef CONFIG_MAC_KBD
 		uintptr_t pa = assigned_address[0].addr + 0x16000;
@@ -223,5 +223,5 @@
 			}
 		}
-
+		
 		/*
 		 * This is the necessary evil until the userspace driver is entirely
@@ -284,5 +284,5 @@
 {
 	// TODO
-	while (1);
+	while (true);
 }
 
Index: kernel/arch/ppc32/src/proc/scheduler.c
===================================================================
--- kernel/arch/ppc32/src/proc/scheduler.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/ppc32/src/proc/scheduler.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -39,17 +39,21 @@
 #include <arch.h>
 
-/** Perform ppc32 specific tasks needed before the new task is run. */
+/** Perform ppc32 specific tasks needed before the new task is run.
+ *
+ */
 void before_task_runs_arch(void)
 {
 }
 
-/** Perform ppc32 specific tasks needed before the new thread is scheduled. */
+/** Perform ppc32 specific tasks needed before the new thread is scheduled.
+ *
+ */
 void before_thread_runs_arch(void)
 {
 	tlb_invalidate_all();
+	
 	asm volatile (
-		"mtsprg0 %0\n"
-		:
-		: "r" (KA2PA(&THREAD->kstack[THREAD_STACK_SIZE - SP_DELTA]))
+		"mtsprg0 %[ksp]\n"
+		:: [ksp] "r" (KA2PA(&THREAD->kstack[THREAD_STACK_SIZE - SP_DELTA]))
 	);
 }
Index: kernel/arch/sparc64/Makefile.inc
===================================================================
--- kernel/arch/sparc64/Makefile.inc	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/sparc64/Makefile.inc	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -31,8 +31,8 @@
 BFD = binary
 
-GCC_CFLAGS += -m64 -mcpu=ultrasparc 
+GCC_CFLAGS += -m64 -mcpu=ultrasparc -mcmodel=medlow
 SUNCC_CFLAGS += -m64 -xarch=sparc -xregs=appl,no%float
 
-LFLAGS = -no-check-sections -N
+LFLAGS += -no-check-sections
 
 BITS = 64
@@ -64,5 +64,4 @@
 	arch/$(KARCH)/src/asm.S \
 	arch/$(KARCH)/src/$(USARCH)/asm.S \
-	arch/$(KARCH)/src/panic.S \
 	arch/$(KARCH)/src/console.c \
 	arch/$(KARCH)/src/context.S \
Index: kernel/arch/sparc64/include/asm.h
===================================================================
--- kernel/arch/sparc64/include/asm.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/sparc64/include/asm.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -27,5 +27,5 @@
  */
 
-/** @addtogroup sparc64	
+/** @addtogroup sparc64
  * @{
  */
@@ -43,6 +43,7 @@
 #include <arch/stack.h>
 #include <arch/barrier.h>
-
-static inline void pio_write_8(ioport8_t *port, uint8_t v)
+#include <trace.h>
+
+NO_TRACE static inline void pio_write_8(ioport8_t *port, uint8_t v)
 {
 	*port = v;
@@ -50,5 +51,5 @@
 }
 
-static inline void pio_write_16(ioport16_t *port, uint16_t v)
+NO_TRACE static inline void pio_write_16(ioport16_t *port, uint16_t v)
 {
 	*port = v;
@@ -56,5 +57,5 @@
 }
 
-static inline void pio_write_32(ioport32_t *port, uint32_t v)
+NO_TRACE static inline void pio_write_32(ioport32_t *port, uint32_t v)
 {
 	*port = v;
@@ -62,31 +63,22 @@
 }
 
-static inline uint8_t pio_read_8(ioport8_t *port)
-{
-	uint8_t rv;
-
-	rv = *port;
+NO_TRACE static inline uint8_t pio_read_8(ioport8_t *port)
+{
+	uint8_t rv = *port;
 	memory_barrier();
-
 	return rv;
 }
 
-static inline uint16_t pio_read_16(ioport16_t *port)
-{
-	uint16_t rv;
-
-	rv = *port;
+NO_TRACE static inline uint16_t pio_read_16(ioport16_t *port)
+{
+	uint16_t rv = *port;
 	memory_barrier();
-
 	return rv;
 }
 
-static inline uint32_t pio_read_32(ioport32_t *port)
-{
-	uint32_t rv;
-
-	rv = *port;
+NO_TRACE static inline uint32_t pio_read_32(ioport32_t *port)
+{
+	uint32_t rv = *port;
 	memory_barrier();
-
 	return rv;
 }
@@ -95,10 +87,14 @@
  *
  * @return Value of PSTATE register.
- */
-static inline uint64_t pstate_read(void)
-{
-	uint64_t v;
-	
-	asm volatile ("rdpr %%pstate, %0\n" : "=r" (v));
+ *
+ */
+NO_TRACE static inline uint64_t pstate_read(void)
+{
+	uint64_t v;
+	
+	asm volatile (
+		"rdpr %%pstate, %[v]\n"
+		: [v] "=r" (v)
+	);
 	
 	return v;
@@ -108,8 +104,13 @@
  *
  * @param v New value of PSTATE register.
- */
-static inline void pstate_write(uint64_t v)
-{
-	asm volatile ("wrpr %0, %1, %%pstate\n" : : "r" (v), "i" (0));
+ *
+ */
+NO_TRACE static inline void pstate_write(uint64_t v)
+{
+	asm volatile (
+		"wrpr %[v], %[zero], %%pstate\n"
+		:: [v] "r" (v),
+		   [zero] "i" (0)
+	);
 }
 
@@ -117,10 +118,14 @@
  *
  * @return Value of TICK_comapre register.
- */
-static inline uint64_t tick_compare_read(void)
-{
-	uint64_t v;
-	
-	asm volatile ("rd %%tick_cmpr, %0\n" : "=r" (v));
+ *
+ */
+NO_TRACE static inline uint64_t tick_compare_read(void)
+{
+	uint64_t v;
+	
+	asm volatile (
+		"rd %%tick_cmpr, %[v]\n"
+		: [v] "=r" (v)
+	);
 	
 	return v;
@@ -130,8 +135,13 @@
  *
  * @param v New value of TICK_comapre register.
- */
-static inline void tick_compare_write(uint64_t v)
-{
-	asm volatile ("wr %0, %1, %%tick_cmpr\n" : : "r" (v), "i" (0));
+ *
+ */
+NO_TRACE static inline void tick_compare_write(uint64_t v)
+{
+	asm volatile (
+		"wr %[v], %[zero], %%tick_cmpr\n"
+		:: [v] "r" (v),
+		   [zero] "i" (0)
+	);
 }
 
@@ -139,10 +149,14 @@
  *
  * @return Value of STICK_compare register.
- */
-static inline uint64_t stick_compare_read(void)
-{
-	uint64_t v;
-	
-	asm volatile ("rd %%asr25, %0\n" : "=r" (v));
+ *
+ */
+NO_TRACE static inline uint64_t stick_compare_read(void)
+{
+	uint64_t v;
+	
+	asm volatile (
+		"rd %%asr25, %[v]\n"
+		: [v] "=r" (v)
+	);
 	
 	return v;
@@ -152,8 +166,13 @@
  *
  * @param v New value of STICK_comapre register.
- */
-static inline void stick_compare_write(uint64_t v)
-{
-	asm volatile ("wr %0, %1, %%asr25\n" : : "r" (v), "i" (0));
+ *
+ */
+NO_TRACE static inline void stick_compare_write(uint64_t v)
+{
+	asm volatile (
+		"wr %[v], %[zero], %%asr25\n"
+		:: [v] "r" (v),
+		   [zero] "i" (0)
+	);
 }
 
@@ -161,10 +180,14 @@
  *
  * @return Value of TICK register.
- */
-static inline uint64_t tick_read(void)
-{
-	uint64_t v;
-	
-	asm volatile ("rdpr %%tick, %0\n" : "=r" (v));
+ *
+ */
+NO_TRACE static inline uint64_t tick_read(void)
+{
+	uint64_t v;
+	
+	asm volatile (
+		"rdpr %%tick, %[v]\n"
+		: [v] "=r" (v)
+	);
 	
 	return v;
@@ -174,8 +197,13 @@
  *
  * @param v New value of TICK register.
- */
-static inline void tick_write(uint64_t v)
-{
-	asm volatile ("wrpr %0, %1, %%tick\n" : : "r" (v), "i" (0));
+ *
+ */
+NO_TRACE static inline void tick_write(uint64_t v)
+{
+	asm volatile (
+		"wrpr %[v], %[zero], %%tick\n"
+		:: [v] "r" (v),
+		   [zero] "i" (0)
+	);
 }
 
@@ -183,10 +211,14 @@
  *
  * @return Value of FPRS register.
- */
-static inline uint64_t fprs_read(void)
-{
-	uint64_t v;
-	
-	asm volatile ("rd %%fprs, %0\n" : "=r" (v));
+ *
+ */
+NO_TRACE static inline uint64_t fprs_read(void)
+{
+	uint64_t v;
+	
+	asm volatile (
+		"rd %%fprs, %[v]\n"
+		: [v] "=r" (v)
+	);
 	
 	return v;
@@ -196,8 +228,13 @@
  *
  * @param v New value of FPRS register.
- */
-static inline void fprs_write(uint64_t v)
-{
-	asm volatile ("wr %0, %1, %%fprs\n" : : "r" (v), "i" (0));
+ *
+ */
+NO_TRACE static inline void fprs_write(uint64_t v)
+{
+	asm volatile (
+		"wr %[v], %[zero], %%fprs\n"
+		:: [v] "r" (v),
+		   [zero] "i" (0)
+	);
 }
 
@@ -205,11 +242,15 @@
  *
  * @return Value of SOFTINT register.
- */
-static inline uint64_t softint_read(void)
-{
-	uint64_t v;
-
-	asm volatile ("rd %%softint, %0\n" : "=r" (v));
-
+ *
+ */
+NO_TRACE static inline uint64_t softint_read(void)
+{
+	uint64_t v;
+	
+	asm volatile (
+		"rd %%softint, %[v]\n"
+		: [v] "=r" (v)
+	);
+	
 	return v;
 }
@@ -218,8 +259,13 @@
  *
  * @param v New value of SOFTINT register.
- */
-static inline void softint_write(uint64_t v)
-{
-	asm volatile ("wr %0, %1, %%softint\n" : : "r" (v), "i" (0));
+ *
+ */
+NO_TRACE static inline void softint_write(uint64_t v)
+{
+	asm volatile (
+		"wr %[v], %[zero], %%softint\n"
+		:: [v] "r" (v),
+		   [zero] "i" (0)
+	);
 }
 
@@ -229,8 +275,13 @@
  *
  * @param v New value of CLEAR_SOFTINT register.
- */
-static inline void clear_softint_write(uint64_t v)
-{
-	asm volatile ("wr %0, %1, %%clear_softint\n" : : "r" (v), "i" (0));
+ *
+ */
+NO_TRACE static inline void clear_softint_write(uint64_t v)
+{
+	asm volatile (
+		"wr %[v], %[zero], %%clear_softint\n"
+		:: [v] "r" (v),
+		   [zero] "i" (0)
+	);
 }
 
@@ -240,8 +291,13 @@
  *
  * @param v New value of SET_SOFTINT register.
- */
-static inline void set_softint_write(uint64_t v)
-{
-	asm volatile ("wr %0, %1, %%set_softint\n" : : "r" (v), "i" (0));
+ *
+ */
+NO_TRACE static inline void set_softint_write(uint64_t v)
+{
+	asm volatile (
+		"wr %[v], %[zero], %%set_softint\n"
+		:: [v] "r" (v),
+		   [zero] "i" (0)
+	);
 }
 
@@ -252,10 +308,10 @@
  *
  * @return Old interrupt priority level.
- */
-static inline ipl_t interrupts_enable(void) {
+ *
+ */
+NO_TRACE static inline ipl_t interrupts_enable(void) {
 	pstate_reg_t pstate;
-	uint64_t value;
-	
-	value = pstate_read();
+	uint64_t value = pstate_read();
+	
 	pstate.value = value;
 	pstate.ie = true;
@@ -271,10 +327,10 @@
  *
  * @return Old interrupt priority level.
- */
-static inline ipl_t interrupts_disable(void) {
+ *
+ */
+NO_TRACE static inline ipl_t interrupts_disable(void) {
 	pstate_reg_t pstate;
-	uint64_t value;
-	
-	value = pstate_read();
+	uint64_t value = pstate_read();
+	
 	pstate.value = value;
 	pstate.ie = false;
@@ -289,6 +345,7 @@
  *
  * @param ipl Saved interrupt priority level.
- */
-static inline void interrupts_restore(ipl_t ipl) {
+ *
+ */
+NO_TRACE static inline void interrupts_restore(ipl_t ipl) {
 	pstate_reg_t pstate;
 	
@@ -303,7 +360,21 @@
  *
  * @return Current interrupt priority level.
- */
-static inline ipl_t interrupts_read(void) {
+ *
+ */
+NO_TRACE static inline ipl_t interrupts_read(void) {
 	return (ipl_t) pstate_read();
+}
+
+/** Check interrupts state.
+ *
+ * @return True if interrupts are disabled.
+ *
+ */
+NO_TRACE static inline bool interrupts_disabled(void)
+{
+	pstate_reg_t pstate;
+	
+	pstate.value = pstate_read();
+	return !pstate.ie;
 }
 
@@ -313,10 +384,15 @@
  * The stack is assumed to be STACK_SIZE bytes long.
  * The stack must start on page boundary.
- */
-static inline uintptr_t get_stack_base(void)
+ *
+ */
+NO_TRACE static inline uintptr_t get_stack_base(void)
 {
 	uintptr_t unbiased_sp;
 	
-	asm volatile ("add %%sp, %1, %0\n" : "=r" (unbiased_sp) : "i" (STACK_BIAS));
+	asm volatile (
+		"add %%sp, %[stack_bias], %[unbiased_sp]\n"
+		: [unbiased_sp] "=r" (unbiased_sp)
+		: [stack_bias] "i" (STACK_BIAS)
+	);
 	
 	return ALIGN_DOWN(unbiased_sp, STACK_SIZE);
@@ -326,10 +402,14 @@
  *
  * @return Value of VER register.
- */
-static inline uint64_t ver_read(void)
-{
-	uint64_t v;
-	
-	asm volatile ("rdpr %%ver, %0\n" : "=r" (v));
+ *
+ */
+NO_TRACE static inline uint64_t ver_read(void)
+{
+	uint64_t v;
+	
+	asm volatile (
+		"rdpr %%ver, %[v]\n"
+		: [v] "=r" (v)
+	);
 	
 	return v;
@@ -339,10 +419,14 @@
  *
  * @return Current value in TPC.
- */
-static inline uint64_t tpc_read(void)
-{
-	uint64_t v;
-	
-	asm volatile ("rdpr %%tpc, %0\n" : "=r" (v));
+ *
+ */
+NO_TRACE static inline uint64_t tpc_read(void)
+{
+	uint64_t v;
+	
+	asm volatile (
+		"rdpr %%tpc, %[v]\n"
+		: [v] "=r" (v)
+	);
 	
 	return v;
@@ -352,10 +436,14 @@
  *
  * @return Current value in TL.
- */
-static inline uint64_t tl_read(void)
-{
-	uint64_t v;
-	
-	asm volatile ("rdpr %%tl, %0\n" : "=r" (v));
+ *
+ */
+NO_TRACE static inline uint64_t tl_read(void)
+{
+	uint64_t v;
+	
+	asm volatile (
+		"rdpr %%tl, %[v]\n"
+		: [v] "=r" (v)
+	);
 	
 	return v;
@@ -365,10 +453,14 @@
  *
  * @return Current value in TBA.
- */
-static inline uint64_t tba_read(void)
-{
-	uint64_t v;
-	
-	asm volatile ("rdpr %%tba, %0\n" : "=r" (v));
+ *
+ */
+NO_TRACE static inline uint64_t tba_read(void)
+{
+	uint64_t v;
+	
+	asm volatile (
+		"rdpr %%tba, %[v]\n"
+		: [v] "=r" (v)
+	);
 	
 	return v;
@@ -378,8 +470,13 @@
  *
  * @param v New value of TBA.
- */
-static inline void tba_write(uint64_t v)
-{
-	asm volatile ("wrpr %0, %1, %%tba\n" : : "r" (v), "i" (0));
+ *
+ */
+NO_TRACE static inline void tba_write(uint64_t v)
+{
+	asm volatile (
+		"wrpr %[v], %[zero], %%tba\n"
+		:: [v] "r" (v),
+		   [zero] "i" (0)
+	);
 }
 
@@ -387,13 +484,20 @@
  *
  * @param asi ASI determining the alternate space.
- * @param va Virtual address within the ASI.
- *
- * @return Value read from the virtual address in the specified address space.
- */
-static inline uint64_t asi_u64_read(asi_t asi, uintptr_t va)
-{
-	uint64_t v;
-	
-	asm volatile ("ldxa [%1] %2, %0\n" : "=r" (v) : "r" (va), "i" ((unsigned) asi));
+ * @param va  Virtual address within the ASI.
+ *
+ * @return Value read from the virtual address in
+ *         the specified address space.
+ *
+ */
+NO_TRACE static inline uint64_t asi_u64_read(asi_t asi, uintptr_t va)
+{
+	uint64_t v;
+	
+	asm volatile (
+		"ldxa [%[va]] %[asi], %[v]\n"
+		: [v] "=r" (v)
+		: [va] "r" (va),
+		  [asi] "i" ((unsigned int) asi)
+	);
 	
 	return v;
@@ -403,14 +507,21 @@
  *
  * @param asi ASI determining the alternate space.
- * @param va Virtual address within the ASI.
- * @param v Value to be written.
- */
-static inline void asi_u64_write(asi_t asi, uintptr_t va, uint64_t v)
-{
-	asm volatile ("stxa %0, [%1] %2\n" : :  "r" (v), "r" (va), "i" ((unsigned) asi) : "memory");
+ * @param va  Virtual address within the ASI.
+ * @param v   Value to be written.
+ *
+ */
+NO_TRACE static inline void asi_u64_write(asi_t asi, uintptr_t va, uint64_t v)
+{
+	asm volatile (
+		"stxa %[v], [%[va]] %[asi]\n"
+		:: [v] "r" (v),
+		   [va] "r" (va),
+		   [asi] "i" ((unsigned int) asi)
+		: "memory"
+	);
 }
 
 /** Flush all valid register windows to memory. */
-static inline void flushw(void)
+NO_TRACE static inline void flushw(void)
 {
 	asm volatile ("flushw\n");
@@ -418,5 +529,5 @@
 
 /** Switch to nucleus by setting TL to 1. */
-static inline void nucleus_enter(void)
+NO_TRACE static inline void nucleus_enter(void)
 {
 	asm volatile ("wrpr %g0, 1, %tl\n");
@@ -424,5 +535,5 @@
 
 /** Switch from nucleus by setting TL to 0. */
-static inline void nucleus_leave(void)
+NO_TRACE static inline void nucleus_leave(void)
 {
 	asm volatile ("wrpr %g0, %g0, %tl\n");
@@ -433,4 +544,5 @@
 extern void asm_delay_loop(const uint32_t usec);
 
+extern uint64_t read_from_ag_g6(void);
 extern uint64_t read_from_ag_g7(void);
 extern void write_to_ag_g6(uint64_t val);
Index: kernel/arch/sparc64/include/atomic.h
===================================================================
--- kernel/arch/sparc64/include/atomic.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/sparc64/include/atomic.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -39,4 +39,5 @@
 #include <typedefs.h>
 #include <preemption.h>
+#include <trace.h>
 
 /** Atomic add operation.
@@ -50,5 +51,6 @@
  *
  */
-static inline atomic_count_t atomic_add(atomic_t *val, atomic_count_t i)
+NO_TRACE static inline atomic_count_t atomic_add(atomic_t *val,
+    atomic_count_t i)
 {
 	atomic_count_t a;
@@ -72,35 +74,35 @@
 }
 
-static inline atomic_count_t atomic_preinc(atomic_t *val)
+NO_TRACE static inline atomic_count_t atomic_preinc(atomic_t *val)
 {
 	return atomic_add(val, 1) + 1;
 }
 
-static inline atomic_count_t atomic_postinc(atomic_t *val)
+NO_TRACE static inline atomic_count_t atomic_postinc(atomic_t *val)
 {
 	return atomic_add(val, 1);
 }
 
-static inline atomic_count_t atomic_predec(atomic_t *val)
+NO_TRACE static inline atomic_count_t atomic_predec(atomic_t *val)
 {
 	return atomic_add(val, -1) - 1;
 }
 
-static inline atomic_count_t atomic_postdec(atomic_t *val)
+NO_TRACE static inline atomic_count_t atomic_postdec(atomic_t *val)
 {
 	return atomic_add(val, -1);
 }
 
-static inline void atomic_inc(atomic_t *val)
+NO_TRACE static inline void atomic_inc(atomic_t *val)
 {
 	(void) atomic_add(val, 1);
 }
 
-static inline void atomic_dec(atomic_t *val)
+NO_TRACE static inline void atomic_dec(atomic_t *val)
 {
 	(void) atomic_add(val, -1);
 }
 
-static inline atomic_count_t test_and_set(atomic_t *val)
+NO_TRACE static inline atomic_count_t test_and_set(atomic_t *val)
 {
 	atomic_count_t v = 1;
@@ -117,5 +119,5 @@
 }
 
-static inline void atomic_lock_arch(atomic_t *val)
+NO_TRACE static inline void atomic_lock_arch(atomic_t *val)
 {
 	atomic_count_t tmp1 = 1;
@@ -135,6 +137,5 @@
 			"brz %2, 0b\n"
 			"nop\n"
-			"ba %%xcc, 1b\n"
-			"nop\n"
+			"ba,a %%xcc, 1b\n"
 		"2:\n"
 		: "+m" (*((atomic_count_t *) ptr)),
Index: kernel/arch/sparc64/include/barrier.h
===================================================================
--- kernel/arch/sparc64/include/barrier.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/sparc64/include/barrier.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -27,5 +27,5 @@
  */
 
-/** @addtogroup sparc64	
+/** @addtogroup sparc64
  * @{
  */
@@ -36,32 +36,62 @@
 #define KERN_sparc64_BARRIER_H_
 
+#include <trace.h>
+
+#ifdef KERNEL
+
+#include <typedefs.h>
+
+#else
+
+#include <stdint.h>
+
+#endif
+
 /*
  * Our critical section barriers are prepared for the weakest RMO memory model.
  */
-#define CS_ENTER_BARRIER() 				\
-	asm volatile (					\
-		"membar #LoadLoad | #LoadStore\n"	\
-		::: "memory"				\
-	)
-#define CS_LEAVE_BARRIER()				\
-	asm volatile ( 					\
-		"membar #StoreStore\n"			\
-		"membar #LoadStore\n"			\
-		::: "memory"				\
+#define CS_ENTER_BARRIER() \
+	asm volatile ( \
+		"membar #LoadLoad | #LoadStore\n" \
+		::: "memory" \
 	)
 
-#define memory_barrier()	\
-	asm volatile ("membar #LoadLoad | #StoreStore\n" ::: "memory")
-#define read_barrier()		\
-	asm volatile ("membar #LoadLoad\n" ::: "memory")
-#define write_barrier()		\
-	asm volatile ("membar #StoreStore\n" ::: "memory")
+#define CS_LEAVE_BARRIER() \
+	asm volatile ( \
+		"membar #StoreStore\n" \
+		"membar #LoadStore\n" \
+		::: "memory" \
+	)
 
-#define flush(a)		\
-	asm volatile ("flush %0\n" :: "r" ((a)) : "memory")
+#define memory_barrier() \
+	asm volatile ( \
+		"membar #LoadLoad | #StoreStore\n" \
+		::: "memory" \
+	)
+
+#define read_barrier() \
+	asm volatile ( \
+		"membar #LoadLoad\n" \
+		::: "memory" \
+	)
+
+#define write_barrier() \
+	asm volatile ( \
+		"membar #StoreStore\n" \
+		::: "memory" \
+	)
+
+#define flush(a) \
+	asm volatile ( \
+		"flush %[reg]\n" \
+		:: [reg] "r" ((a)) \
+		: "memory" \
+	)
 
 /** Flush Instruction pipeline. */
-static inline void flush_pipeline(void)
+NO_TRACE static inline void flush_pipeline(void)
 {
+	uint64_t pc;
+	
 	/*
 	 * The FLUSH instruction takes address parameter.
@@ -70,49 +100,58 @@
 	 * The entire kernel text is mapped by a locked ITLB and
 	 * DTLB entries. Therefore, when this function is called,
-	 * the %o7 register will always be in the range mapped by
+	 * the %pc register will always be in the range mapped by
 	 * DTLB.
+	 *
 	 */
-	 
-        asm volatile ("flush %o7\n");
+	
+	asm volatile (
+		"rd %%pc, %[pc]\n"
+		"flush %[pc]\n"
+		: [pc] "=&r" (pc)
+	);
 }
 
 /** Memory Barrier instruction. */
-static inline void membar(void)
+NO_TRACE static inline void membar(void)
 {
-	asm volatile ("membar #Sync\n");
+	asm volatile (
+		"membar #Sync\n"
+	);
 }
 
 #if defined (US)
 
-#define smc_coherence(a)	\
-{				\
-	write_barrier();	\
-	flush((a));		\
-}
+#define FLUSH_INVAL_MIN  4
 
-#define FLUSH_INVAL_MIN		4
-#define smc_coherence_block(a, l)			\
-{							\
-	unsigned long i;				\
-	write_barrier();				\
-	for (i = 0; i < (l); i += FLUSH_INVAL_MIN)	\
-		flush((void *)(a) + i);			\
-}
+#define smc_coherence(a) \
+	do { \
+		write_barrier(); \
+		flush((a)); \
+	} while (0)
+
+#define smc_coherence_block(a, l) \
+	do { \
+		unsigned long i; \
+		write_barrier(); \
+		\
+		for (i = 0; i < (l); i += FLUSH_INVAL_MIN) \
+			flush((void *)(a) + i); \
+	} while (0)
 
 #elif defined (US3)
 
-#define smc_coherence(a)	\
-{				\
-	write_barrier();	\
-	flush_pipeline();	\
-}
+#define smc_coherence(a) \
+	do { \
+		write_barrier(); \
+		flush_pipeline(); \
+	} while (0)
 
-#define smc_coherence_block(a, l)	\
-{					\
-	write_barrier();		\
-	flush_pipeline();		\
-}
+#define smc_coherence_block(a, l) \
+	do { \
+		write_barrier(); \
+		flush_pipeline(); \
+	} while (0)
 
-#endif	/* defined(US3) */
+#endif  /* defined(US3) */
 
 #endif
Index: kernel/arch/sparc64/include/cycle.h
===================================================================
--- kernel/arch/sparc64/include/cycle.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/sparc64/include/cycle.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -36,7 +36,8 @@
 #define KERN_sparc64_CYCLE_H_
 
-#include <arch/asm.h> 
+#include <arch/asm.h>
+#include <trace.h>
 
-static inline uint64_t get_cycle(void)
+NO_TRACE static inline uint64_t get_cycle(void)
 {
 	return tick_read();
Index: rnel/arch/sparc64/include/debug.h
===================================================================
--- kernel/arch/sparc64/include/debug.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ 	(revision )
@@ -1,41 +1,0 @@
-/*
- * Copyright (c) 2005 Jakub Jermar 
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/** @addtogroup sparc64debug
- * @{
- */
-/** @file
- */
-
-#ifndef KERN_sparc64_DEBUG_H_
-#define KERN_sparc64_DEBUG_H_
-
-#endif
-
-/** @}
- */
Index: kernel/arch/sparc64/include/drivers/scr.h
===================================================================
--- kernel/arch/sparc64/include/drivers/scr.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/sparc64/include/drivers/scr.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -44,5 +44,6 @@
 	SCR_FFB,
 	SCR_CGSIX,
-	SCR_XVR
+	SCR_XVR,
+	SCR_QEMU_VGA
 } scr_type_t;
 
Index: kernel/arch/sparc64/include/drivers/tick.h
===================================================================
--- kernel/arch/sparc64/include/drivers/tick.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/sparc64/include/drivers/tick.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -27,5 +27,5 @@
  */
 
-/** @addtogroup sparc64	
+/** @addtogroup sparc64
  * @{
  */
@@ -40,8 +40,8 @@
 
 /* mask of the "counter" field of the Tick register */
-#define TICK_COUNTER_MASK	(~(1l << 63))
+#define TICK_COUNTER_MASK  (~(1l << 63))
 
 extern void tick_init(void);
-extern void tick_interrupt(int n, istate_t *istate);
+extern void tick_interrupt(unsigned int, istate_t *);
 
 /**
Index: kernel/arch/sparc64/include/faddr.h
===================================================================
--- kernel/arch/sparc64/include/faddr.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/sparc64/include/faddr.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -27,5 +27,5 @@
  */
 
-/** @addtogroup sparc64	
+/** @addtogroup sparc64
  * @{
  */
@@ -38,5 +38,5 @@
 #include <typedefs.h>
 
-#define FADDR(fptr)		((uintptr_t) (fptr))
+#define FADDR(fptr)  ((uintptr_t) (fptr))
 
 #endif
Index: kernel/arch/sparc64/include/interrupt.h
===================================================================
--- kernel/arch/sparc64/include/interrupt.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/sparc64/include/interrupt.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -39,39 +39,43 @@
 #include <typedefs.h>
 #include <arch/regdef.h>
+#include <trace.h>
 
-#define IVT_ITEMS 	15
-#define IVT_FIRST	1
+#define IVT_ITEMS  15
+#define IVT_FIRST  1
 
 /* This needs to be defined for inter-architecture API portability. */
-#define VECTOR_TLB_SHOOTDOWN_IPI	0
+#define VECTOR_TLB_SHOOTDOWN_IPI  0
 
 enum {
 	IPI_TLB_SHOOTDOWN = VECTOR_TLB_SHOOTDOWN_IPI
-};		
+};
 
 typedef struct istate {
-	uint64_t	tnpc;
-	uint64_t	tpc;
-	uint64_t	tstate;
+	uint64_t tnpc;
+	uint64_t tpc;
+	uint64_t tstate;
 } istate_t;
 
-static inline void istate_set_retaddr(istate_t *istate, uintptr_t retaddr)
+NO_TRACE static inline void istate_set_retaddr(istate_t *istate,
+    uintptr_t retaddr)
 {
 	istate->tpc = retaddr;
 }
 
-static inline int istate_from_uspace(istate_t *istate)
+NO_TRACE static inline int istate_from_uspace(istate_t *istate)
 {
 	return !(istate->tstate & TSTATE_PRIV_BIT);
 }
 
-static inline unative_t istate_get_pc(istate_t *istate)
+NO_TRACE static inline unative_t istate_get_pc(istate_t *istate)
 {
 	return istate->tpc;
 }
 
-static inline unative_t istate_get_fp(istate_t *istate)
+NO_TRACE static inline unative_t istate_get_fp(istate_t *istate)
 {
-	return 0;	/* TODO */
+	/* TODO */
+	
+	return 0;
 }
 
Index: kernel/arch/sparc64/include/mm/as.h
===================================================================
--- kernel/arch/sparc64/include/mm/as.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/sparc64/include/mm/as.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -27,5 +27,5 @@
  */
 
-/** @addtogroup sparc64mm	
+/** @addtogroup sparc64mm
  * @{
  */
@@ -37,7 +37,11 @@
 
 #if defined (SUN4U)
+
 #include <arch/mm/sun4u/as.h>
+
 #elif defined (SUN4V)
+
 #include <arch/mm/sun4v/as.h>
+
 #endif
 
Index: kernel/arch/sparc64/include/mm/frame.h
===================================================================
--- kernel/arch/sparc64/include/mm/frame.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/sparc64/include/mm/frame.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -27,5 +27,5 @@
  */
 
-/** @addtogroup sparc64mm	
+/** @addtogroup sparc64mm
  * @{
  */
@@ -37,7 +37,11 @@
 
 #if defined (SUN4U)
+
 #include <arch/mm/sun4u/frame.h>
+
 #elif defined (SUN4V)
+
 #include <arch/mm/sun4v/frame.h>
+
 #endif
 
Index: kernel/arch/sparc64/include/mm/sun4u/tlb.h
===================================================================
--- kernel/arch/sparc64/include/mm/sun4u/tlb.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/sparc64/include/mm/sun4u/tlb.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -100,4 +100,5 @@
 #include <arch/barrier.h>
 #include <typedefs.h>
+#include <trace.h>
 #include <arch/register.h>
 #include <arch/cpu.h>
@@ -242,5 +243,5 @@
  * Determine the number of entries in the DMMU's small TLB. 
  */
-static inline uint16_t tlb_dsmall_size(void)
+NO_TRACE static inline uint16_t tlb_dsmall_size(void)
 {
 	return 16;
@@ -250,5 +251,5 @@
  * Determine the number of entries in each DMMU's big TLB. 
  */
-static inline uint16_t tlb_dbig_size(void)
+NO_TRACE static inline uint16_t tlb_dbig_size(void)
 {
 	return 512;
@@ -258,5 +259,5 @@
  * Determine the number of entries in the IMMU's small TLB. 
  */
-static inline uint16_t tlb_ismall_size(void)
+NO_TRACE static inline uint16_t tlb_ismall_size(void)
 {
 	return 16;
@@ -266,5 +267,5 @@
  * Determine the number of entries in the IMMU's big TLB. 
  */
-static inline uint16_t tlb_ibig_size(void)
+NO_TRACE static inline uint16_t tlb_ibig_size(void)
 {
 	if (((ver_reg_t) ver_read()).impl == IMPL_ULTRASPARCIV_PLUS)
@@ -280,5 +281,5 @@
  * @return		Current value of Primary Context Register.
  */
-static inline uint64_t mmu_primary_context_read(void)
+NO_TRACE static inline uint64_t mmu_primary_context_read(void)
 {
 	return asi_u64_read(ASI_DMMU, VA_PRIMARY_CONTEXT_REG);
@@ -289,5 +290,5 @@
  * @param v		New value of Primary Context Register.
  */
-static inline void mmu_primary_context_write(uint64_t v)
+NO_TRACE static inline void mmu_primary_context_write(uint64_t v)
 {
 	asi_u64_write(ASI_DMMU, VA_PRIMARY_CONTEXT_REG, v);
@@ -299,5 +300,5 @@
  * @return		Current value of Secondary Context Register.
  */
-static inline uint64_t mmu_secondary_context_read(void)
+NO_TRACE static inline uint64_t mmu_secondary_context_read(void)
 {
 	return asi_u64_read(ASI_DMMU, VA_SECONDARY_CONTEXT_REG);
@@ -308,5 +309,5 @@
  * @param v		New value of Primary Context Register.
  */
-static inline void mmu_secondary_context_write(uint64_t v)
+NO_TRACE static inline void mmu_secondary_context_write(uint64_t v)
 {
 	asi_u64_write(ASI_DMMU, VA_SECONDARY_CONTEXT_REG, v);
@@ -323,5 +324,5 @@
  * 			Register.
  */
-static inline uint64_t itlb_data_access_read(size_t entry)
+NO_TRACE static inline uint64_t itlb_data_access_read(size_t entry)
 {
 	itlb_data_access_addr_t reg;
@@ -337,5 +338,5 @@
  * @param value		Value to be written.
  */
-static inline void itlb_data_access_write(size_t entry, uint64_t value)
+NO_TRACE static inline void itlb_data_access_write(size_t entry, uint64_t value)
 {
 	itlb_data_access_addr_t reg;
@@ -354,5 +355,5 @@
  * 			Register.
  */
-static inline uint64_t dtlb_data_access_read(size_t entry)
+NO_TRACE static inline uint64_t dtlb_data_access_read(size_t entry)
 {
 	dtlb_data_access_addr_t reg;
@@ -368,5 +369,5 @@
  * @param value		Value to be written.
  */
-static inline void dtlb_data_access_write(size_t entry, uint64_t value)
+NO_TRACE static inline void dtlb_data_access_write(size_t entry, uint64_t value)
 {
 	dtlb_data_access_addr_t reg;
@@ -384,5 +385,5 @@
  * @return		Current value of specified IMMU TLB Tag Read Register.
  */
-static inline uint64_t itlb_tag_read_read(size_t entry)
+NO_TRACE static inline uint64_t itlb_tag_read_read(size_t entry)
 {
 	itlb_tag_read_addr_t tag;
@@ -399,5 +400,5 @@
  * @return		Current value of specified DMMU TLB Tag Read Register.
  */
-static inline uint64_t dtlb_tag_read_read(size_t entry)
+NO_TRACE static inline uint64_t dtlb_tag_read_read(size_t entry)
 {
 	dtlb_tag_read_addr_t tag;
@@ -419,5 +420,5 @@
  * 			Register.
  */
-static inline uint64_t itlb_data_access_read(int tlb, size_t entry)
+NO_TRACE static inline uint64_t itlb_data_access_read(int tlb, size_t entry)
 {
 	itlb_data_access_addr_t reg;
@@ -434,5 +435,5 @@
  * @param value		Value to be written.
  */
-static inline void itlb_data_access_write(int tlb, size_t entry,
+NO_TRACE static inline void itlb_data_access_write(int tlb, size_t entry,
 	uint64_t value)
 {
@@ -454,5 +455,5 @@
  * 			Register.
  */
-static inline uint64_t dtlb_data_access_read(int tlb, size_t entry)
+NO_TRACE static inline uint64_t dtlb_data_access_read(int tlb, size_t entry)
 {
 	dtlb_data_access_addr_t reg;
@@ -470,5 +471,5 @@
  * @param value		Value to be written.
  */
-static inline void dtlb_data_access_write(int tlb, size_t entry,
+NO_TRACE static inline void dtlb_data_access_write(int tlb, size_t entry,
 	uint64_t value)
 {
@@ -489,5 +490,5 @@
  * @return		Current value of specified IMMU TLB Tag Read Register.
  */
-static inline uint64_t itlb_tag_read_read(int tlb, size_t entry)
+NO_TRACE static inline uint64_t itlb_tag_read_read(int tlb, size_t entry)
 {
 	itlb_tag_read_addr_t tag;
@@ -506,5 +507,5 @@
  * @return		Current value of specified DMMU TLB Tag Read Register.
  */
-static inline uint64_t dtlb_tag_read_read(int tlb, size_t entry)
+NO_TRACE static inline uint64_t dtlb_tag_read_read(int tlb, size_t entry)
 {
 	dtlb_tag_read_addr_t tag;
@@ -523,5 +524,5 @@
  * @param v		Value to be written.
  */
-static inline void itlb_tag_access_write(uint64_t v)
+NO_TRACE static inline void itlb_tag_access_write(uint64_t v)
 {
 	asi_u64_write(ASI_IMMU, VA_IMMU_TAG_ACCESS, v);
@@ -533,5 +534,5 @@
  * @return		Current value of IMMU TLB Tag Access Register.
  */
-static inline uint64_t itlb_tag_access_read(void)
+NO_TRACE static inline uint64_t itlb_tag_access_read(void)
 {
 	return asi_u64_read(ASI_IMMU, VA_IMMU_TAG_ACCESS);
@@ -542,5 +543,5 @@
  * @param v		Value to be written.
  */
-static inline void dtlb_tag_access_write(uint64_t v)
+NO_TRACE static inline void dtlb_tag_access_write(uint64_t v)
 {
 	asi_u64_write(ASI_DMMU, VA_DMMU_TAG_ACCESS, v);
@@ -552,5 +553,5 @@
  * @return 		Current value of DMMU TLB Tag Access Register.
  */
-static inline uint64_t dtlb_tag_access_read(void)
+NO_TRACE static inline uint64_t dtlb_tag_access_read(void)
 {
 	return asi_u64_read(ASI_DMMU, VA_DMMU_TAG_ACCESS);
@@ -562,5 +563,5 @@
  * @param v		Value to be written.
  */
-static inline void itlb_data_in_write(uint64_t v)
+NO_TRACE static inline void itlb_data_in_write(uint64_t v)
 {
 	asi_u64_write(ASI_ITLB_DATA_IN_REG, 0, v);
@@ -572,5 +573,5 @@
  * @param v		Value to be written.
  */
-static inline void dtlb_data_in_write(uint64_t v)
+NO_TRACE static inline void dtlb_data_in_write(uint64_t v)
 {
 	asi_u64_write(ASI_DTLB_DATA_IN_REG, 0, v);
@@ -582,5 +583,5 @@
  * @return		Current content of I-SFSR register.
  */
-static inline uint64_t itlb_sfsr_read(void)
+NO_TRACE static inline uint64_t itlb_sfsr_read(void)
 {
 	return asi_u64_read(ASI_IMMU, VA_IMMU_SFSR);
@@ -591,5 +592,5 @@
  * @param v		New value of I-SFSR register.
  */
-static inline void itlb_sfsr_write(uint64_t v)
+NO_TRACE static inline void itlb_sfsr_write(uint64_t v)
 {
 	asi_u64_write(ASI_IMMU, VA_IMMU_SFSR, v);
@@ -601,5 +602,5 @@
  * @return		Current content of D-SFSR register.
  */
-static inline uint64_t dtlb_sfsr_read(void)
+NO_TRACE static inline uint64_t dtlb_sfsr_read(void)
 {
 	return asi_u64_read(ASI_DMMU, VA_DMMU_SFSR);
@@ -610,5 +611,5 @@
  * @param v		New value of D-SFSR register.
  */
-static inline void dtlb_sfsr_write(uint64_t v)
+NO_TRACE static inline void dtlb_sfsr_write(uint64_t v)
 {
 	asi_u64_write(ASI_DMMU, VA_DMMU_SFSR, v);
@@ -620,5 +621,5 @@
  * @return		Current content of D-SFAR register.
  */
-static inline uint64_t dtlb_sfar_read(void)
+NO_TRACE static inline uint64_t dtlb_sfar_read(void)
 {
 	return asi_u64_read(ASI_DMMU, VA_DMMU_SFAR);
@@ -633,5 +634,5 @@
  * @param page		Address which is on the page to be demapped.
  */
-static inline void itlb_demap(int type, int context_encoding, uintptr_t page)
+NO_TRACE static inline void itlb_demap(int type, int context_encoding, uintptr_t page)
 {
 	tlb_demap_addr_t da;
@@ -659,5 +660,5 @@
  * @param page		Address which is on the page to be demapped.
  */
-static inline void dtlb_demap(int type, int context_encoding, uintptr_t page)
+NO_TRACE static inline void dtlb_demap(int type, int context_encoding, uintptr_t page)
 {
 	tlb_demap_addr_t da;
Index: kernel/arch/sparc64/include/mm/sun4v/tlb.h
===================================================================
--- kernel/arch/sparc64/include/mm/sun4v/tlb.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/sparc64/include/mm/sun4v/tlb.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -43,5 +43,5 @@
 
 #include <arch/mm/tte.h>
-#include <print.h>
+#include <trace.h>
 #include <arch/mm/mmu.h>
 #include <arch/mm/page.h>
@@ -88,32 +88,32 @@
  * @return	Current value of Primary Context Register.
  */
-static inline uint64_t mmu_primary_context_read(void)
+NO_TRACE static inline uint64_t mmu_primary_context_read(void)
 {
 	return asi_u64_read(ASI_PRIMARY_CONTEXT_REG, VA_PRIMARY_CONTEXT_REG);
 }
- 
+
 /** Write MMU Primary Context Register.
  *
  * @param v	New value of Primary Context Register.
  */
-static inline void mmu_primary_context_write(uint64_t v)
+NO_TRACE static inline void mmu_primary_context_write(uint64_t v)
 {
 	asi_u64_write(ASI_PRIMARY_CONTEXT_REG, VA_PRIMARY_CONTEXT_REG, v);
 }
- 
+
 /** Read MMU Secondary Context Register.
  *
  * @return	Current value of Secondary Context Register.
  */
-static inline uint64_t mmu_secondary_context_read(void)
+NO_TRACE static inline uint64_t mmu_secondary_context_read(void)
 {
 	return asi_u64_read(ASI_SECONDARY_CONTEXT_REG, VA_SECONDARY_CONTEXT_REG);
 }
- 
+
 /** Write MMU Secondary Context Register.
  *
  * @param v	New value of Secondary Context Register.
  */
-static inline void mmu_secondary_context_write(uint64_t v)
+NO_TRACE static inline void mmu_secondary_context_write(uint64_t v)
 {
 	asi_u64_write(ASI_SECONDARY_CONTEXT_REG, VA_SECONDARY_CONTEXT_REG, v);
@@ -126,5 +126,5 @@
  * @param mmu_flag	MMU_FLAG_DTLB, MMU_FLAG_ITLB or a combination of both
  */
-static inline void mmu_demap_ctx(int context, int mmu_flag) {
+NO_TRACE static inline void mmu_demap_ctx(int context, int mmu_flag) {
 	__hypercall_fast4(MMU_DEMAP_CTX, 0, 0, context, mmu_flag);
 }
@@ -137,5 +137,5 @@
  * @param mmu_flag	MMU_FLAG_DTLB, MMU_FLAG_ITLB or a combination of both
  */
-static inline void mmu_demap_page(uintptr_t vaddr, int context, int mmu_flag) {
+NO_TRACE static inline void mmu_demap_page(uintptr_t vaddr, int context, int mmu_flag) {
 	__hypercall_fast5(MMU_DEMAP_PAGE, 0, 0, vaddr, context, mmu_flag);
 }
Index: kernel/arch/sparc64/include/mm/tlb.h
===================================================================
--- kernel/arch/sparc64/include/mm/tlb.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/sparc64/include/mm/tlb.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -27,5 +27,5 @@
  */
 
-/** @addtogroup sparc64mm	
+/** @addtogroup sparc64mm
  * @{
  */
@@ -36,9 +36,12 @@
 #define KERN_sparc64_TLB_H_
 
+#if defined (SUN4U)
 
-#if defined (SUN4U)
 #include <arch/mm/sun4u/tlb.h>
+
 #elif defined (SUN4V)
+
 #include <arch/mm/sun4v/tlb.h>
+
 #endif
 
Index: kernel/arch/sparc64/include/sparc64.h
===================================================================
--- kernel/arch/sparc64/include/sparc64.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/sparc64/include/sparc64.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -38,5 +38,5 @@
 #include <interrupt.h>
 
-extern void interrupt_register(int n, const char *name, iroutine f);
+extern void interrupt_register(unsigned int, const char *, iroutine_t);
 
 #endif
Index: kernel/arch/sparc64/include/sun4u/asm.h
===================================================================
--- kernel/arch/sparc64/include/sun4u/asm.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/sparc64/include/sun4u/asm.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -27,5 +27,5 @@
  */
 
-/** @addtogroup sparc64	
+/** @addtogroup sparc64
  * @{
  */
@@ -36,22 +36,27 @@
 #define KERN_sparc64_sun4u_ASM_H_
 
-extern uint64_t read_from_ag_g7(void);
-extern void write_to_ag_g6(uint64_t val);
-extern void write_to_ag_g7(uint64_t val);
-extern void write_to_ig_g6(uint64_t val);
-
+#include <trace.h>
 
 /** Read Version Register.
  *
  * @return Value of VER register.
+ *
  */
-static inline uint64_t ver_read(void)
+NO_TRACE static inline uint64_t ver_read(void)
 {
 	uint64_t v;
 	
-	asm volatile ("rdpr %%ver, %0\n" : "=r" (v));
+	asm volatile (
+		"rdpr %%ver, %[v]\n"
+		: [v] "=r" (v)
+	);
 	
 	return v;
 }
+
+extern uint64_t read_from_ag_g7(void);
+extern void write_to_ag_g6(uint64_t);
+extern void write_to_ag_g7(uint64_t);
+extern void write_to_ig_g6(uint64_t);
 
 #endif
Index: kernel/arch/sparc64/include/sun4u/cpu.h
===================================================================
--- kernel/arch/sparc64/include/sun4u/cpu.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/sparc64/include/sun4u/cpu.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -36,19 +36,19 @@
 #define KERN_sparc64_sun4u_CPU_H_
 
-#define MANUF_FUJITSU		0x04
-#define MANUF_ULTRASPARC	0x17	/**< UltraSPARC I, UltraSPARC II */
-#define MANUF_SUN		0x3e
+#define MANUF_FUJITSU     0x04
+#define MANUF_ULTRASPARC  0x17  /**< UltraSPARC I, UltraSPARC II */
+#define MANUF_SUN         0x3e
 
-#define IMPL_ULTRASPARCI	0x10
-#define IMPL_ULTRASPARCII	0x11
-#define IMPL_ULTRASPARCII_I	0x12
-#define IMPL_ULTRASPARCII_E	0x13
-#define IMPL_ULTRASPARCIII	0x14
-#define IMPL_ULTRASPARCIII_PLUS	0x15
-#define IMPL_ULTRASPARCIII_I	0x16
-#define IMPL_ULTRASPARCIV	0x18
-#define IMPL_ULTRASPARCIV_PLUS	0x19
+#define IMPL_ULTRASPARCI         0x10
+#define IMPL_ULTRASPARCII        0x11
+#define IMPL_ULTRASPARCII_I      0x12
+#define IMPL_ULTRASPARCII_E      0x13
+#define IMPL_ULTRASPARCIII       0x14
+#define IMPL_ULTRASPARCIII_PLUS  0x15
+#define IMPL_ULTRASPARCIII_I     0x16
+#define IMPL_ULTRASPARCIV        0x18
+#define IMPL_ULTRASPARCIV_PLUS   0x19
 
-#define IMPL_SPARC64V		0x5
+#define IMPL_SPARC64V  0x5
 
 #ifndef __ASM__
@@ -58,4 +58,5 @@
 #include <arch/regdef.h>
 #include <arch/asm.h>
+#include <trace.h>
 
 #ifdef CONFIG_SMP
@@ -64,21 +65,21 @@
 
 typedef struct {
-	uint32_t mid;			/**< Processor ID as read from
-					     UPA_CONFIG/FIREPLANE_CONFIG. */
+	uint32_t mid;              /**< Processor ID as read from
+	                                UPA_CONFIG/FIREPLANE_CONFIG. */
 	ver_reg_t ver;
-	uint32_t clock_frequency;	/**< Processor frequency in Hz. */
-	uint64_t next_tick_cmpr;	/**< Next clock interrupt should be
-					     generated when the TICK register
-					     matches this value. */
+	uint32_t clock_frequency;  /**< Processor frequency in Hz. */
+	uint64_t next_tick_cmpr;   /**< Next clock interrupt should be
+	                                generated when the TICK register
+	                                matches this value. */
 } cpu_arch_t;
 
-
-/**
- * Reads the module ID (agent ID/CPUID) of the current CPU.
+/** Read the module ID (agent ID/CPUID) of the current CPU.
+ *
  */
-static inline uint32_t read_mid(void)
+NO_TRACE static inline uint32_t read_mid(void)
 {
 	uint64_t icbus_config = asi_u64_read(ASI_ICBUS_CONFIG, 0);
 	icbus_config = icbus_config >> ICBUS_CONFIG_MID_SHIFT;
+	
 #if defined (US)
 	return icbus_config & 0x1f;
@@ -91,5 +92,5 @@
 }
 
-#endif	
+#endif
 
 #endif
Index: kernel/arch/sparc64/include/sun4v/asm.h
===================================================================
--- kernel/arch/sparc64/include/sun4v/asm.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/sparc64/include/sun4v/asm.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -27,5 +27,5 @@
  */
 
-/** @addtogroup sparc64	
+/** @addtogroup sparc64
  * @{
  */
Index: kernel/arch/sparc64/include/sun4v/cpu.h
===================================================================
--- kernel/arch/sparc64/include/sun4v/cpu.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/sparc64/include/sun4v/cpu.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -37,8 +37,8 @@
 
 /** Maximum number of virtual processors. */
-#define MAX_NUM_STRANDS		64
+#define MAX_NUM_STRANDS  64
 
 /** Maximum number of logical processors in a processor core */
-#define MAX_CORE_STRANDS	8
+#define MAX_CORE_STRANDS  8
 
 #ifndef __ASM__
@@ -59,17 +59,13 @@
 
 typedef struct cpu_arch {
-	uint64_t id;			/**< virtual processor ID */
-	uint32_t clock_frequency;	/**< Processor frequency in Hz. */
-	uint64_t next_tick_cmpr;	/**< Next clock interrupt should be
-					     generated when the TICK register
-					     matches this value. */
-	exec_unit_t *exec_unit;		/**< Physical core. */
-	unsigned long proposed_nrdy;	/**< Proposed No. of ready threads
-					     so that cores are equally balanced. */
+	uint64_t id;                  /**< virtual processor ID */
+	uint32_t clock_frequency;     /**< Processor frequency in Hz. */
+	uint64_t next_tick_cmpr;      /**< Next clock interrupt should be
+	                                   generated when the TICK register
+	                                   matches this value. */
+	exec_unit_t *exec_unit;       /**< Physical core. */
+	unsigned long proposed_nrdy;  /**< Proposed No. of ready threads
+	                                   so that cores are equally balanced. */
 } cpu_arch_t;
-
-#endif	
-
-#ifdef __ASM__
 
 #endif
Index: kernel/arch/sparc64/include/trap/sun4v/mmu.h
===================================================================
--- kernel/arch/sparc64/include/trap/sun4v/mmu.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/sparc64/include/trap/sun4v/mmu.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -96,5 +96,5 @@
 
 	/* service by higher-level routine when context != 0 */
-	brnz %g3, 0f 
+	brnz %g3, 0f
 	nop
 	/* exclude page number 0 from installing the identity mapping */
@@ -107,8 +107,7 @@
 	 * returns.
 	 */
-	ba install_identity_mapping
-	nop	
+	ba,a %xcc, install_identity_mapping
 
-	0:
+0:
 
 	/*
Index: kernel/arch/sparc64/include/trap/trap_table.h
===================================================================
--- kernel/arch/sparc64/include/trap/trap_table.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/sparc64/include/trap/trap_table.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -42,4 +42,26 @@
 #define TRAP_TABLE_SIZE		(TRAP_TABLE_ENTRY_COUNT * TRAP_TABLE_ENTRY_SIZE)
 
+/*
+ * The following needs to be in sync with the definition of the istate
+ * structure. The one STACK_ITEM_SIZE is counted for space holding the 7th
+ * argument to syscall_handler (i.e. syscall number) and the other
+ * STACK_ITEM_SIZE is counted because of the required alignment.
+ */
+#define PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE \
+    (STACK_WINDOW_SAVE_AREA_SIZE + STACK_ARG_SAVE_AREA_SIZE + \
+    (2 * STACK_ITEM_SIZE) + (12 * 8))
+#define SAVED_TSTATE	-(1 * 8)
+#define SAVED_TPC	-(2 * 8)
+#define SAVED_TNPC	-(3 * 8)	/* <-- istate_t begins here */
+#define SAVED_Y		-(4 * 8)
+#define SAVED_I0	-(5 * 8)
+#define SAVED_I1	-(6 * 8)
+#define SAVED_I2	-(7 * 8)
+#define SAVED_I3	-(8 * 8)
+#define SAVED_I4	-(9 * 8)
+#define SAVED_I5	-(10 * 8)
+#define SAVED_I6	-(11 * 8)
+#define SAVED_I7	-(12 * 8)
+
 #ifndef __ASM__
 
@@ -77,29 +99,7 @@
 .endm
 
-/*
- * The following needs to be in sync with the definition of the istate
- * structure. The one STACK_ITEM_SIZE is counted for space holding the 7th
- * argument to syscall_handler (i.e. syscall number) and the other
- * STACK_ITEM_SIZE is counted because of the required alignment.
- */
-#define PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE	\
-    (STACK_WINDOW_SAVE_AREA_SIZE + STACK_ARG_SAVE_AREA_SIZE + \
-    (2 * STACK_ITEM_SIZE) + (12 * 8))
-#define SAVED_TSTATE	-(1 * 8)
-#define SAVED_TPC	-(2 * 8)
-#define SAVED_TNPC	-(3 * 8)	/* <-- istate_t begins here */
-#define SAVED_Y		-(4 * 8)
-#define SAVED_I0	-(5 * 8)
-#define SAVED_I1	-(6 * 8)
-#define SAVED_I2	-(7 * 8)
-#define SAVED_I3	-(8 * 8)
-#define SAVED_I4	-(9 * 8)
-#define SAVED_I5	-(10 * 8)
-#define SAVED_I6	-(11 * 8)
-#define SAVED_I7	-(12 * 8)
-
 .macro PREEMPTIBLE_HANDLER f
 	sethi %hi(\f), %g1
-	b preemptible_handler
+	ba %xcc, preemptible_handler
 	or %g1, %lo(\f), %g1
 .endm
Index: kernel/arch/sparc64/include/types.h
===================================================================
--- kernel/arch/sparc64/include/types.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/sparc64/include/types.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -52,9 +52,9 @@
 typedef uint8_t asi_t;
 
-/**< Formats for uintptr_t, size_t */
+/** Formats for uintptr_t, size_t */
 #define PRIp  "llx"
 #define PRIs  "llu"
 
-/**< Formats for (u)int8_t, (u)int16_t, (u)int32_t, (u)int64_t and (u)native_t */
+/** Formats for (u)int8_t, (u)int16_t, (u)int32_t, (u)int64_t and (u)native_t */
 #define PRId8   "d"
 #define PRId16  "d"
Index: kernel/arch/sparc64/src/asm.S
===================================================================
--- kernel/arch/sparc64/src/asm.S	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/sparc64/src/asm.S	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -1,29 +1,29 @@
-#
-# Copyright (c) 2005 Jakub Jermar
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions
-# are met:
-#
-# - Redistributions of source code must retain the above copyright
-#   notice, this list of conditions and the following disclaimer.
-# - Redistributions in binary form must reproduce the above copyright
-#   notice, this list of conditions and the following disclaimer in the
-#   documentation and/or other materials provided with the distribution.
-# - The name of the author may not be used to endorse or promote products
-#   derived from this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
-# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
-# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
-# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
-# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
-# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-#
+/*
+ * Copyright (c) 2005 Jakub Jermar
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
 
 #include <arch/arch.h>
@@ -32,6 +32,6 @@
 .text
 
-.register       %g2, #scratch
-.register       %g3, #scratch
+.register %g2, #scratch
+.register %g3, #scratch
 
 /*
@@ -40,58 +40,72 @@
 .global memcpy
 memcpy:
-	mov	%o0, %o3		! save dst
-	add	%o1, 7, %g1
-	and	%g1, -8, %g1
-	cmp	%o1, %g1
-	be,pn	%xcc, 3f
-	add	%o0, 7, %g1
-	mov	0, %g3
-0:
-	brz,pn	%o2, 2f
-	mov	0, %g2
-1:
-	ldub	[%g3 + %o1], %g1
-	add	%g2, 1, %g2
-	cmp	%o2, %g2
-	stb	%g1, [%g3 + %o0]
-	bne,pt	%xcc, 1b
-	mov	%g2, %g3
-2:
-	jmp	%o7 + 8			! exit point
-	mov	%o3, %o0
-3:
-	and	%g1, -8, %g1
-	cmp	%o0, %g1
-	bne,pt	%xcc, 0b
-	mov	0, %g3
-	srlx	%o2, 3, %g4
-	brz,pn	%g4, 5f
-	mov	0, %g5
-4:
-	sllx	%g3, 3, %g2
-	add	%g5, 1, %g3
-	ldx	[%o1 + %g2], %g1
-	mov	%g3, %g5
-	cmp	%g4, %g3
-	bne,pt	%xcc, 4b
-	stx	%g1, [%o0 + %g2]
-5:
-	and	%o2, 7, %o2
-	brz,pn	%o2, 2b
-	sllx	%g4, 3, %g1
-	mov	0, %g2
-	add	%g1, %o0, %o0
-	add	%g1, %o1, %g4
-	mov	0, %g3
-6:
-	ldub	[%g2 + %g4], %g1
-	stb	%g1, [%g2 + %o0]
-	add	%g3, 1, %g2
-	cmp	%o2, %g2
-	bne,pt	%xcc, 6b
-	mov	%g2, %g3
-
-	jmp	%o7 + 8			! exit point
-	mov	%o3, %o0
+	mov %o0, %o3  /* save dst */
+	add %o1, 7, %g1
+	and %g1, -8, %g1
+	cmp %o1, %g1
+	be,pn %xcc, 3f
+	add %o0, 7, %g1
+	mov 0, %g3
+	
+	0:
+	
+		brz,pn %o2, 2f
+		mov 0, %g2
+	
+	1:
+	
+		ldub [%g3 + %o1], %g1
+		add %g2, 1, %g2
+		cmp %o2, %g2
+		stb %g1, [%g3 + %o0]
+		bne,pt %xcc, 1b
+		mov %g2, %g3
+	
+	2:
+	
+		jmp %o7 + 8  /* exit point */
+		mov %o3, %o0
+	
+	3:
+	
+		and %g1, -8, %g1
+		cmp %o0, %g1
+		bne,pt %xcc, 0b
+		mov 0, %g3
+		srlx %o2, 3, %g4
+		brz,pn %g4, 5f
+		mov 0, %g5
+	
+	4:
+	
+		sllx %g3, 3, %g2
+		add %g5, 1, %g3
+		ldx [%o1 + %g2], %g1
+		mov %g3, %g5
+		cmp %g4, %g3
+		bne,pt %xcc, 4b
+		stx %g1, [%o0 + %g2]
+	
+	5:
+	
+		and %o2, 7, %o2
+		brz,pn %o2, 2b
+		sllx %g4, 3, %g1
+		mov 0, %g2
+		add %g1, %o0, %o0
+		add %g1, %o1, %g4
+		mov 0, %g3
+	
+	6:
+	
+		ldub [%g2 + %g4], %g1
+		stb %g1, [%g2 + %o0]
+		add %g3, 1, %g2
+		cmp %o2, %g2
+		bne,pt %xcc, 6b
+		mov %g2, %g3
+		
+		jmp %o7 + 8  /* exit point */
+		mov %o3, %o0
 
 /*
@@ -100,58 +114,72 @@
 .global memcpy_from_uspace
 memcpy_from_uspace:
-	mov	%o0, %o3		! save dst
-	add	%o1, 7, %g1
-	and	%g1, -8, %g1
-	cmp	%o1, %g1
-	be,pn	%xcc, 3f
-	add	%o0, 7, %g1
-	mov	0, %g3
-0:
-	brz,pn	%o2, 2f
-	mov	0, %g2
-1:
-	lduba	[%g3 + %o1] ASI_AIUS, %g1
-	add	%g2, 1, %g2
-	cmp	%o2, %g2
-	stb	%g1, [%g3 + %o0]
-	bne,pt	%xcc, 1b
-	mov	%g2, %g3
-2:
-	jmp	%o7 + 8			! exit point
-	mov	%o3, %o0
-3:
-	and	%g1, -8, %g1
-	cmp	%o0, %g1
-	bne,pt	%xcc, 0b
-	mov	0, %g3
-	srlx	%o2, 3, %g4
-	brz,pn	%g4, 5f
-	mov	0, %g5
-4:
-	sllx	%g3, 3, %g2
-	add	%g5, 1, %g3
-	ldxa	[%o1 + %g2] ASI_AIUS, %g1
-	mov	%g3, %g5
-	cmp	%g4, %g3
-	bne,pt	%xcc, 4b
-	stx	%g1, [%o0 + %g2]
-5:
-	and	%o2, 7, %o2
-	brz,pn	%o2, 2b
-	sllx	%g4, 3, %g1
-	mov	0, %g2
-	add	%g1, %o0, %o0
-	add	%g1, %o1, %g4
-	mov	0, %g3
-6:
-	lduba	[%g2 + %g4] ASI_AIUS, %g1
-	stb	%g1, [%g2 + %o0]
-	add	%g3, 1, %g2
-	cmp	%o2, %g2
-	bne,pt	%xcc, 6b
-	mov	%g2, %g3
-
-	jmp	%o7 + 8			! exit point
-	mov	%o3, %o0
+	mov %o0, %o3  /* save dst */
+	add %o1, 7, %g1
+	and %g1, -8, %g1
+	cmp %o1, %g1
+	be,pn %xcc, 3f
+	add %o0, 7, %g1
+	mov 0, %g3
+	
+	0:
+	
+		brz,pn %o2, 2f
+		mov 0, %g2
+	
+	1:
+	
+		lduba [%g3 + %o1] ASI_AIUS, %g1
+		add %g2, 1, %g2
+		cmp %o2, %g2
+		stb %g1, [%g3 + %o0]
+		bne,pt %xcc, 1b
+		mov %g2, %g3
+	
+	2:
+	
+		jmp %o7 + 8  /* exit point */
+		mov %o3, %o0
+	
+	3:
+	
+		and %g1, -8, %g1
+		cmp %o0, %g1
+		bne,pt %xcc, 0b
+		mov 0, %g3
+		srlx %o2, 3, %g4
+		brz,pn %g4, 5f
+		mov 0, %g5
+	
+	4:
+	
+		sllx %g3, 3, %g2
+		add %g5, 1, %g3
+		ldxa [%o1 + %g2] ASI_AIUS, %g1
+		mov %g3, %g5
+		cmp %g4, %g3
+		bne,pt %xcc, 4b
+		stx %g1, [%o0 + %g2]
+	
+	5:
+	
+		and %o2, 7, %o2
+		brz,pn %o2, 2b
+		sllx %g4, 3, %g1
+		mov 0, %g2
+		add %g1, %o0, %o0
+		add %g1, %o1, %g4
+		mov 0, %g3
+	
+	6:
+	
+		lduba [%g2 + %g4] ASI_AIUS, %g1
+		stb %g1, [%g2 + %o0]
+		add %g3, 1, %g2
+		cmp %o2, %g2
+		bne,pt %xcc, 6b
+		mov %g2, %g3
+		
+		jmp %o7 + 8  /* exit point */
+		mov %o3, %o0
 
 /*
@@ -160,58 +188,72 @@
 .global memcpy_to_uspace
 memcpy_to_uspace:
-	mov	%o0, %o3		! save dst
-	add	%o1, 7, %g1
-	and	%g1, -8, %g1
-	cmp	%o1, %g1
-	be,pn	%xcc, 3f
-	add	%o0, 7, %g1
-	mov	0, %g3
-0:
-	brz,pn	%o2, 2f
-	mov	0, %g2
-1:
-	ldub	[%g3 + %o1], %g1
-	add	%g2, 1, %g2
-	cmp	%o2, %g2
-	stba	%g1, [%g3 + %o0] ASI_AIUS
-	bne,pt	%xcc, 1b
-	mov	%g2, %g3
-2:
-	jmp	%o7 + 8			! exit point
-	mov	%o3, %o0
-3:
-	and	%g1, -8, %g1
-	cmp	%o0, %g1
-	bne,pt	%xcc, 0b
-	mov	0, %g3
-	srlx	%o2, 3, %g4
-	brz,pn	%g4, 5f
-	mov	0, %g5
-4:
-	sllx	%g3, 3, %g2
-	add	%g5, 1, %g3
-	ldx	[%o1 + %g2], %g1
-	mov	%g3, %g5
-	cmp	%g4, %g3
-	bne,pt	%xcc, 4b
-	stxa	%g1, [%o0 + %g2] ASI_AIUS
-5:
-	and	%o2, 7, %o2
-	brz,pn	%o2, 2b
-	sllx	%g4, 3, %g1
-	mov	0, %g2
-	add	%g1, %o0, %o0
-	add	%g1, %o1, %g4
-	mov	0, %g3
-6:
-	ldub	[%g2 + %g4], %g1
-	stba	%g1, [%g2 + %o0] ASI_AIUS
-	add	%g3, 1, %g2
-	cmp	%o2, %g2
-	bne,pt	%xcc, 6b
-	mov	%g2, %g3
-
-	jmp	%o7 + 8			! exit point
-	mov	%o3, %o0
+	mov %o0, %o3  /* save dst */
+	add %o1, 7, %g1
+	and %g1, -8, %g1
+	cmp %o1, %g1
+	be,pn %xcc, 3f
+	add %o0, 7, %g1
+	mov 0, %g3
+	
+	0:
+	
+		brz,pn %o2, 2f
+		mov 0, %g2
+	
+	1:
+	
+		ldub [%g3 + %o1], %g1
+		add %g2, 1, %g2
+		cmp %o2, %g2
+		stba %g1, [%g3 + %o0] ASI_AIUS
+		bne,pt %xcc, 1b
+		mov %g2, %g3
+	
+	2:
+	
+		jmp %o7 + 8  /* exit point */
+		mov %o3, %o0
+	
+	3:
+	
+		and %g1, -8, %g1
+		cmp %o0, %g1
+		bne,pt %xcc, 0b
+		mov 0, %g3
+		srlx %o2, 3, %g4
+		brz,pn %g4, 5f
+		mov 0, %g5
+	
+	4:
+	
+		sllx %g3, 3, %g2
+		add %g5, 1, %g3
+		ldx [%o1 + %g2], %g1
+		mov %g3, %g5
+		cmp %g4, %g3
+		bne,pt %xcc, 4b
+		stxa %g1, [%o0 + %g2] ASI_AIUS
+	
+	5:
+	
+		and %o2, 7, %o2
+		brz,pn %o2, 2b
+		sllx %g4, 3, %g1
+		mov 0, %g2
+		add %g1, %o0, %o0
+		add %g1, %o1, %g4
+		mov 0, %g3
+	
+	6:
+	
+		ldub [%g2 + %g4], %g1
+		stba %g1, [%g2 + %o0] ASI_AIUS
+		add %g3, 1, %g2
+		cmp %o2, %g2
+		bne,pt %xcc, 6b
+		mov %g2, %g3
+		
+		jmp	%o7 + 8  /* exit point */
+		mov	%o3, %o0
 
 .global memcpy_from_uspace_failover_address
@@ -219,6 +261,6 @@
 memcpy_from_uspace_failover_address:
 memcpy_to_uspace_failover_address:
-	jmp	%o7 + 8			! exit point
-	mov	%g0, %o0		! return 0 on failure
+	jmp %o7 + 8   /* exit point */
+	mov %g0, %o0  /* return 0 on failure */
 
 .global memsetb
@@ -232,2 +274,6 @@
 	nop
 
+.global early_putchar
+early_putchar:
+	retl
+	nop
Index: kernel/arch/sparc64/src/debug/stacktrace.c
===================================================================
--- kernel/arch/sparc64/src/debug/stacktrace.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/sparc64/src/debug/stacktrace.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -37,30 +37,62 @@
 #include <typedefs.h>
 
-bool kernel_frame_pointer_validate(uintptr_t fp)
+#include <arch.h>
+#include <arch/stack.h>
+#include <arch/trap/trap_table.h>
+
+#if defined(SUN4V)
+#include <arch/sun4v/arch.h>
+#endif
+
+#define FRAME_OFFSET_FP_PREV	14
+#define FRAME_OFFSET_RA		15
+
+extern void alloc_window_and_flush(void);
+
+bool kernel_stack_trace_context_validate(stack_trace_context_t *ctx)
+{
+	uintptr_t kstack;
+	
+#if defined(SUN4U)
+	kstack = read_from_ag_g6();
+#elif defined(SUN4V)
+	kstack = asi_u64_read(ASI_SCRATCHPAD, SCRATCHPAD_KSTACK);
+#endif
+
+	kstack += STACK_BIAS;
+	kstack -= PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE;
+
+	if (THREAD && (ctx->fp == kstack))
+		return false;
+	return ctx->fp != 0;
+}
+
+bool kernel_frame_pointer_prev(stack_trace_context_t *ctx, uintptr_t *prev)
+{
+	uint64_t *stack = (void *) ctx->fp;
+	alloc_window_and_flush();
+	*prev = stack[FRAME_OFFSET_FP_PREV] + STACK_BIAS;
+	return true;
+}
+
+bool kernel_return_address_get(stack_trace_context_t *ctx, uintptr_t *ra)
+{
+	uint64_t *stack = (void *) ctx->fp;
+	alloc_window_and_flush();
+	*ra = stack[FRAME_OFFSET_RA];
+	return true;
+}
+
+bool uspace_stack_trace_context_validate(stack_trace_context_t *ctx)
 {
 	return false;
 }
 
-bool kernel_frame_pointer_prev(uintptr_t fp, uintptr_t *prev)
+bool uspace_frame_pointer_prev(stack_trace_context_t *ctx, uintptr_t *prev)
 {
 	return false;
 }
 
-bool kernel_return_address_get(uintptr_t fp, uintptr_t *ra)
-{
-	return false;
-}
-
-bool uspace_frame_pointer_validate(uintptr_t fp)
-{
-	return false;
-}
-
-bool uspace_frame_pointer_prev(uintptr_t fp, uintptr_t *prev)
-{
-	return false;
-}
-
-bool uspace_return_address_get(uintptr_t fp, uintptr_t *ra)
+bool uspace_return_address_get(stack_trace_context_t *ctx , uintptr_t *ra)
 {
 	return false;
Index: kernel/arch/sparc64/src/debug/stacktrace_asm.S
===================================================================
--- kernel/arch/sparc64/src/debug/stacktrace_asm.S	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/sparc64/src/debug/stacktrace_asm.S	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -27,15 +27,26 @@
 #
 
+#include <arch/stack.h>
+
 .text
 
 .global frame_pointer_get
 .global program_counter_get
+.global alloc_window_and_flush
 
 frame_pointer_get:
+	# Add the stack bias to %sp to get the actual address.
 	retl
-	nop
+	add %sp, STACK_BIAS, %o0
 
 program_counter_get:
 	retl
-	nop
+	mov %o7, %o0
 
+alloc_window_and_flush:
+	save %sp, -(STACK_WINDOW_SAVE_AREA_SIZE+STACK_ARG_SAVE_AREA_SIZE), %sp
+	# Flush all other windows to memory so that we can read their contents.
+	flushw
+	ret
+	restore
+
Index: kernel/arch/sparc64/src/drivers/scr.c
===================================================================
--- kernel/arch/sparc64/src/drivers/scr.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/sparc64/src/drivers/scr.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -77,4 +77,6 @@
 	else if (str_cmp(name, "cgsix") == 0)
 		scr_type = SCR_CGSIX;
+	else if (str_cmp(name, "QEMU,VGA") == 0)
+		scr_type = SCR_QEMU_VGA;
 	
 	if (scr_type == SCR_UNKNOWN) {
@@ -228,4 +230,47 @@
 	
 		break;
+
+	case SCR_QEMU_VGA:
+		if (prop->size / sizeof(ofw_pci_reg_t) < 2) {
+			printf("Too few screen registers.\n");
+			return;
+		}
+
+		pci_reg = &((ofw_pci_reg_t *) prop->value)[1];
+
+		if (!ofw_pci_reg_absolutize(node, pci_reg, &pci_abs_reg)) {
+			printf("Failed to absolutize fb register.\n");
+			return;
+		}
+
+		if (!ofw_pci_apply_ranges(node->parent, &pci_abs_reg,
+		    &fb_addr)) {
+			printf("Failed to determine screen address.\n");
+			return;
+		}
+
+		switch (fb_depth) {
+		case 8:
+			fb_scanline = fb_linebytes * (fb_depth >> 3);
+			visual = VISUAL_INDIRECT_8;
+			break;
+		case 16:
+			fb_scanline = fb_linebytes * (fb_depth >> 3);
+			visual = VISUAL_RGB_5_6_5_BE;
+			break;
+		case 24:
+			fb_scanline = fb_linebytes * 4;
+			visual = VISUAL_BGR_8_8_8_0;
+			break;
+		case 32:
+			fb_scanline = fb_linebytes * (fb_depth >> 3);
+			visual = VISUAL_RGB_0_8_8_8;
+			break;
+		default:
+			printf("Unsupported bits per pixel.\n");
+			return;
+		}
+		break;
+
 	default:
 		panic("Unexpected type.");
Index: kernel/arch/sparc64/src/drivers/sgcn.c
===================================================================
--- kernel/arch/sparc64/src/drivers/sgcn.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/sparc64/src/drivers/sgcn.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -132,5 +132,5 @@
 static void init_sram_begin(void)
 {
-	ASSERT(instance)
+	ASSERT(instance);
 	
 	ofw_tree_node_t *chosen = ofw_tree_lookup("/chosen");
Index: kernel/arch/sparc64/src/drivers/tick.c
===================================================================
--- kernel/arch/sparc64/src/drivers/tick.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/sparc64/src/drivers/tick.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -27,5 +27,5 @@
  */
 
-/** @addtogroup sparc64	
+/** @addtogroup sparc64
  * @{
  */
@@ -77,8 +77,9 @@
 /** Process tick interrupt.
  *
- * @param n Interrupt Level, 14,  (can be ignored)
+ * @param n      Interrupt Level (14, can be ignored)
  * @param istate Interrupted state.
+ *
  */
-void tick_interrupt(int n, istate_t *istate)
+void tick_interrupt(unsigned int n, istate_t *istate)
 {
 	softint_reg_t softint, clear;
Index: kernel/arch/sparc64/src/mm/sun4u/as.c
===================================================================
--- kernel/arch/sparc64/src/mm/sun4u/as.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/sparc64/src/mm/sun4u/as.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -41,4 +41,5 @@
 
 #ifdef CONFIG_TSB
+
 #include <arch/mm/tsb.h>
 #include <arch/memstr.h>
@@ -47,4 +48,5 @@
 #include <bitops.h>
 #include <macros.h>
+
 #endif /* CONFIG_TSB */
 
@@ -58,5 +60,5 @@
 }
 
-int as_constructor_arch(as_t *as, int flags)
+int as_constructor_arch(as_t *as, unsigned int flags)
 {
 #ifdef CONFIG_TSB
@@ -64,20 +66,22 @@
 	 * The order must be calculated with respect to the emulated
 	 * 16K page size.
-	 */
-	int order = fnzb32(((ITSB_ENTRY_COUNT + DTSB_ENTRY_COUNT) *
+	 *
+	 */
+	uint8_t order = fnzb32(((ITSB_ENTRY_COUNT + DTSB_ENTRY_COUNT) *
 	    sizeof(tsb_entry_t)) >> FRAME_WIDTH);
-
+	
 	uintptr_t tsb = (uintptr_t) frame_alloc(order, flags | FRAME_KA);
-
+	
 	if (!tsb)
 		return -1;
-
+	
 	as->arch.itsb = (tsb_entry_t *) tsb;
 	as->arch.dtsb = (tsb_entry_t *) (tsb + ITSB_ENTRY_COUNT *
 	    sizeof(tsb_entry_t));
-
+	
 	memsetb(as->arch.itsb,
 	    (ITSB_ENTRY_COUNT + DTSB_ENTRY_COUNT) * sizeof(tsb_entry_t), 0);
 #endif
+	
 	return 0;
 }
@@ -93,4 +97,5 @@
 	    sizeof(tsb_entry_t)) >> FRAME_WIDTH;
 	frame_free(KA2PA((uintptr_t) as->arch.itsb));
+	
 	return cnt;
 #else
@@ -99,9 +104,10 @@
 }
 
-int as_create_arch(as_t *as, int flags)
+int as_create_arch(as_t *as, unsigned int flags)
 {
 #ifdef CONFIG_TSB
 	tsb_invalidate(as, 0, (size_t) -1);
 #endif
+	
 	return 0;
 }
@@ -123,4 +129,5 @@
 	 *
 	 * Moreover, the as->asid is protected by asidlock, which is being held.
+	 *
 	 */
 	
@@ -130,16 +137,17 @@
 	 * secondary context register from the TL=1 code just before switch to
 	 * userspace.
+	 *
 	 */
 	ctx.v = 0;
 	ctx.context = as->asid;
 	mmu_secondary_context_write(ctx.v);
-
-#ifdef CONFIG_TSB	
+	
+#ifdef CONFIG_TSB
 	uintptr_t base = ALIGN_DOWN(config.base, 1 << KERNEL_PAGE_WIDTH);
-
+	
 	ASSERT(as->arch.itsb && as->arch.dtsb);
-
+	
 	uintptr_t tsb = (uintptr_t) as->arch.itsb;
-		
+	
 	if (!overlaps(tsb, 8 * MMU_PAGE_SIZE, base, 1 << KERNEL_PAGE_WIDTH)) {
 		/*
@@ -147,18 +155,20 @@
 		 * by the locked 4M kernel DTLB entry. We need
 		 * to map both TSBs explicitly.
+		 *
 		 */
 		dtlb_demap(TLB_DEMAP_PAGE, TLB_DEMAP_NUCLEUS, tsb);
 		dtlb_insert_mapping(tsb, KA2PA(tsb), PAGESIZE_64K, true, true);
 	}
-		
+	
 	/*
 	 * Setup TSB Base registers.
+	 *
 	 */
 	tsb_base_reg_t tsb_base;
-		
+	
 	tsb_base.value = 0;
 	tsb_base.size = TSB_SIZE;
 	tsb_base.split = 0;
-
+	
 	tsb_base.base = ((uintptr_t) as->arch.itsb) >> MMU_PAGE_WIDTH;
 	itsb_base_write(tsb_base.value);
@@ -175,5 +185,6 @@
 	 * Clearing the extension registers will ensure that the value of the
 	 * TSB Base register will be used as an address of TSB, making the code
-	 * compatible with the US port. 
+	 * compatible with the US port.
+	 *
 	 */
 	itsb_primary_extension_write(0);
@@ -195,5 +206,4 @@
 void as_deinstall_arch(as_t *as)
 {
-
 	/*
 	 * Note that we don't and may not lock the address space. That's ok
@@ -201,13 +211,14 @@
 	 *
 	 * Moreover, the as->asid is protected by asidlock, which is being held.
-	 */
-
+	 *
+	 */
+	
 #ifdef CONFIG_TSB
 	uintptr_t base = ALIGN_DOWN(config.base, 1 << KERNEL_PAGE_WIDTH);
-
+	
 	ASSERT(as->arch.itsb && as->arch.dtsb);
-
+	
 	uintptr_t tsb = (uintptr_t) as->arch.itsb;
-		
+	
 	if (!overlaps(tsb, 8 * MMU_PAGE_SIZE, base, 1 << KERNEL_PAGE_WIDTH)) {
 		/*
Index: kernel/arch/sparc64/src/mm/sun4u/frame.c
===================================================================
--- kernel/arch/sparc64/src/mm/sun4u/frame.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/sparc64/src/mm/sun4u/frame.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -49,27 +49,30 @@
 void frame_arch_init(void)
 {
-	unsigned int i;
-	pfn_t confdata;
-
 	if (config.cpu_active == 1) {
+		unsigned int i;
+		
 		for (i = 0; i < memmap.cnt; i++) {
-			uintptr_t start = (uintptr_t) memmap.zones[i].start;
-			size_t size = memmap.zones[i].size;
-
+			/* To be safe, make the available zone possibly smaller */
+			uintptr_t new_start = ALIGN_UP((uintptr_t) memmap.zones[i].start,
+			    FRAME_SIZE);
+			size_t new_size = ALIGN_DOWN(memmap.zones[i].size -
+			    (new_start - ((uintptr_t) memmap.zones[i].start)), FRAME_SIZE);
+			
 			/*
 			 * The memmap is created by HelenOS boot loader.
 			 * It already contains no holes.
 			 */
-
-			confdata = ADDR2PFN(start);
+			
+			pfn_t confdata = ADDR2PFN(new_start);
+			
 			if (confdata == ADDR2PFN(KA2PA(PFN2ADDR(0))))
 				confdata = ADDR2PFN(KA2PA(PFN2ADDR(2)));
-			zone_create(ADDR2PFN(start),
-			    SIZE2FRAMES(ALIGN_DOWN(size, FRAME_SIZE)),
+			
+			zone_create(ADDR2PFN(new_start), SIZE2FRAMES(new_size),
 			    confdata, 0);
-			last_frame = max(last_frame, start + ALIGN_UP(size,
-			    FRAME_SIZE));
+			
+			last_frame = max(last_frame, new_start + new_size);
 		}
-
+		
 		/*
 		 * On sparc64, physical memory can start on a non-zero address.
@@ -80,5 +83,5 @@
 		frame_mark_unavailable(ADDR2PFN(KA2PA(PFN2ADDR(0))), 1);
 	}
-
+	
 	end_of_identity = PA2KA(last_frame);
 }
Index: kernel/arch/sparc64/src/mm/sun4u/tlb.c
===================================================================
--- kernel/arch/sparc64/src/mm/sun4u/tlb.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/sparc64/src/mm/sun4u/tlb.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -27,5 +27,5 @@
  */
 
-/** @addtogroup sparc64mm	
+/** @addtogroup sparc64mm
  * @{
  */
@@ -58,5 +58,6 @@
 static void dtlb_pte_copy(pte_t *, size_t, bool);
 static void itlb_pte_copy(pte_t *, size_t);
-static void do_fast_instruction_access_mmu_miss_fault(istate_t *, const char *);
+static void do_fast_instruction_access_mmu_miss_fault(istate_t *, uintptr_t,
+    const char *);
 static void do_fast_data_access_mmu_miss_fault(istate_t *, tlb_tag_access_reg_t,
     const char *);
@@ -222,10 +223,10 @@
 		 * Forward the page fault to the address space page fault
 		 * handler.
-		 */		
+		 */
 		page_table_unlock(AS, true);
 		if (as_page_fault(page_16k, PF_ACCESS_EXEC, istate) ==
 		    AS_PF_FAULT) {
 			do_fast_instruction_access_mmu_miss_fault(istate,
-			    __func__);
+			    istate->tpc, __func__);
 		}
 	}
@@ -258,5 +259,5 @@
 			/* NULL access in kernel */
 			do_fast_data_access_mmu_miss_fault(istate, tag,
-			    __func__);
+			    "Dereferencing NULL pointer.");
 		} else if (page_8k >= end_of_identity) {
 			/*
@@ -438,9 +439,8 @@
 
 void do_fast_instruction_access_mmu_miss_fault(istate_t *istate,
-    const char *str)
-{
-	fault_if_from_uspace(istate, "%s.", str);
-	dump_istate(istate);
-	panic("%s.", str);
+    uintptr_t va, const char *str)
+{
+	fault_if_from_uspace(istate, "%s, Address=%p.", str, va);
+	panic_memtrap(istate, PF_ACCESS_EXEC, va, str);
 }
 
@@ -451,11 +451,7 @@
 
 	va = tag.vpn << MMU_PAGE_WIDTH;
-	if (tag.context) {
-		fault_if_from_uspace(istate, "%s, Page=%p (ASID=%d).", str, va,
-		    tag.context);
-	}
-	dump_istate(istate);
-	printf("Faulting page: %p, ASID=%d.\n", va, tag.context);
-	panic("%s.", str);
+	fault_if_from_uspace(istate, "%s, Page=%p (ASID=%d).", str, va,
+	    tag.context);
+	panic_memtrap(istate, PF_ACCESS_UNKNOWN, va, str);
 }
 
@@ -466,12 +462,7 @@
 
 	va = tag.vpn << MMU_PAGE_WIDTH;
-
-	if (tag.context) {
-		fault_if_from_uspace(istate, "%s, Page=%p (ASID=%d).", str, va,
-		    tag.context);
-	}
-	printf("Faulting page: %p, ASID=%d\n", va, tag.context);
-	dump_istate(istate);
-	panic("%s.", str);
+	fault_if_from_uspace(istate, "%s, Page=%p (ASID=%d).", str, va,
+	    tag.context);
+	panic_memtrap(istate, PF_ACCESS_WRITE, va, str);
 }
 
Index: kernel/arch/sparc64/src/mm/sun4v/as.c
===================================================================
--- kernel/arch/sparc64/src/mm/sun4v/as.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/sparc64/src/mm/sun4v/as.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -44,4 +44,5 @@
 
 #ifdef CONFIG_TSB
+
 #include <arch/mm/tsb.h>
 #include <arch/memstr.h>
@@ -50,4 +51,5 @@
 #include <bitops.h>
 #include <macros.h>
+
 #endif /* CONFIG_TSB */
 
@@ -61,15 +63,15 @@
 }
 
-int as_constructor_arch(as_t *as, int flags)
+int as_constructor_arch(as_t *as, unsigned int flags)
 {
 #ifdef CONFIG_TSB
-	int order = fnzb32(
+	uint8_t order = fnzb32(
 		(TSB_ENTRY_COUNT * sizeof(tsb_entry_t)) >> FRAME_WIDTH);
-
+	
 	uintptr_t tsb = (uintptr_t) frame_alloc(order, flags);
-
+	
 	if (!tsb)
 		return -1;
-
+	
 	as->arch.tsb_description.page_size = PAGESIZE_8K;
 	as->arch.tsb_description.associativity = 1;
@@ -79,8 +81,9 @@
 	as->arch.tsb_description.reserved = 0;
 	as->arch.tsb_description.context = 0;
-
+	
 	memsetb((void *) PA2KA(as->arch.tsb_description.tsb_base),
 		TSB_ENTRY_COUNT * sizeof(tsb_entry_t), 0);
 #endif
+	
 	return 0;
 }
@@ -91,4 +94,5 @@
 	size_t cnt = (TSB_ENTRY_COUNT * sizeof(tsb_entry_t)) >> FRAME_WIDTH;
 	frame_free((uintptr_t) as->arch.tsb_description.tsb_base);
+	
 	return cnt;
 #else
@@ -97,9 +101,10 @@
 }
 
-int as_create_arch(as_t *as, int flags)
+int as_create_arch(as_t *as, unsigned int flags)
 {
 #ifdef CONFIG_TSB
 	tsb_invalidate(as, 0, (size_t) -1);
 #endif
+	
 	return 0;
 }
@@ -111,14 +116,16 @@
  *
  * @param as Address space.
+ *
  */
 void as_install_arch(as_t *as)
 {
 	mmu_secondary_context_write(as->asid);
-#ifdef CONFIG_TSB	
+	
+#ifdef CONFIG_TSB
 	uintptr_t base = ALIGN_DOWN(config.base, 1 << KERNEL_PAGE_WIDTH);
-
+	
 	ASSERT(as->arch.tsb_description.tsb_base);
 	uintptr_t tsb = PA2KA(as->arch.tsb_description.tsb_base);
-		
+	
 	if (!overlaps(tsb, 8 * MMU_PAGE_SIZE, base, 1 << KERNEL_PAGE_WIDTH)) {
 		/*
@@ -126,11 +133,11 @@
 		 * by the locked 4M kernel DTLB entry. We need
 		 * to map both TSBs explicitly.
+		 *
 		 */
 		mmu_demap_page(tsb, 0, MMU_FLAG_DTLB);
 		dtlb_insert_mapping(tsb, KA2PA(tsb), PAGESIZE_64K, true, true);
 	}
-
+	
 	__hypercall_fast2(MMU_TSB_CTXNON0, 1, KA2PA(&(as->arch.tsb_description)));
-	
 #endif
 }
@@ -142,8 +149,8 @@
  *
  * @param as Address space.
+ *
  */
 void as_deinstall_arch(as_t *as)
 {
-
 	/*
 	 * Note that we don't and may not lock the address space. That's ok
@@ -151,13 +158,14 @@
 	 *
 	 * Moreover, the as->asid is protected by asidlock, which is being held.
+	 *
 	 */
-
+	
 #ifdef CONFIG_TSB
 	uintptr_t base = ALIGN_DOWN(config.base, 1 << KERNEL_PAGE_WIDTH);
-
+	
 	ASSERT(as->arch.tsb_description.tsb_base);
-
+	
 	uintptr_t tsb = PA2KA(as->arch.tsb_description.tsb_base);
-		
+	
 	if (!overlaps(tsb, 8 * MMU_PAGE_SIZE, base, 1 << KERNEL_PAGE_WIDTH)) {
 		/*
@@ -165,4 +173,5 @@
 		 * by the locked 4M kernel DTLB entry. We need
 		 * to demap the entry installed by as_install_arch().
+		 *
 		 */
 		__hypercall_fast3(MMU_UNMAP_PERM_ADDR, tsb, 0, MMU_FLAG_DTLB);
Index: kernel/arch/sparc64/src/mm/sun4v/frame.c
===================================================================
--- kernel/arch/sparc64/src/mm/sun4v/frame.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/sparc64/src/mm/sun4v/frame.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -47,25 +47,28 @@
 void frame_arch_init(void)
 {
-	unsigned int i;
-	pfn_t confdata;
-
 	if (config.cpu_active == 1) {
+		unsigned int i;
+		
 		for (i = 0; i < memmap.cnt; i++) {
-			uintptr_t start = (uintptr_t) memmap.zones[i].start;
-			size_t size = memmap.zones[i].size;
-
+			/* To be safe, make the available zone possibly smaller */
+			uintptr_t new_start = ALIGN_UP((uintptr_t) memmap.zones[i].start,
+			    FRAME_SIZE);
+			size_t new_size = ALIGN_DOWN(memmap.zones[i].size -
+			    (new_start - ((uintptr_t) memmap.zones[i].start)), FRAME_SIZE);
+			
 			/*
 			 * The memmap is created by HelenOS boot loader.
 			 * It already contains no holes.
 			 */
-
-			confdata = ADDR2PFN(start);
+			
+			pfn_t confdata = ADDR2PFN(new_start);
+			
 			if (confdata == ADDR2PFN(KA2PA(PFN2ADDR(0))))
 				confdata = ADDR2PFN(KA2PA(PFN2ADDR(2)));
-			zone_create(ADDR2PFN(start),
-			    SIZE2FRAMES(ALIGN_DOWN(size, FRAME_SIZE)),
+			
+			zone_create(ADDR2PFN(new_start), SIZE2FRAMES(new_size),
 			    confdata, 0);
 		}
-
+		
 		/*
 		 * On sparc64, physical memory can start on a non-zero address.
Index: kernel/arch/sparc64/src/mm/sun4v/tlb.c
===================================================================
--- kernel/arch/sparc64/src/mm/sun4v/tlb.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/sparc64/src/mm/sun4v/tlb.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -28,5 +28,5 @@
  */
 
-/** @addtogroup sparc64mm	
+/** @addtogroup sparc64mm
  * @{
  */
@@ -62,5 +62,6 @@
 static void itlb_pte_copy(pte_t *);
 static void dtlb_pte_copy(pte_t *, bool);
-static void do_fast_instruction_access_mmu_miss_fault(istate_t *, const char *);
+static void do_fast_instruction_access_mmu_miss_fault(istate_t *, uintptr_t,
+    const char *);
 static void do_fast_data_access_mmu_miss_fault(istate_t *, uint64_t,
     const char *);
@@ -235,9 +236,9 @@
 		 * Forward the page fault to the address space page fault
 		 * handler.
-		 */		
+		 */
 		page_table_unlock(AS, true);
 		if (as_page_fault(va, PF_ACCESS_EXEC, istate) == AS_PF_FAULT) {
 			do_fast_instruction_access_mmu_miss_fault(istate,
-			    __func__);
+			    istate->tpc, __func__);
 		}
 	}
@@ -354,10 +355,9 @@
 }
 
-void do_fast_instruction_access_mmu_miss_fault(istate_t *istate,
+void do_fast_instruction_access_mmu_miss_fault(istate_t *istate, uintptr_t va,
     const char *str)
 {
-	fault_if_from_uspace(istate, "%s.", str);
-	dump_istate(istate);
-	panic("%s.", str);
+	fault_if_from_uspace(istate, "%s, Address=%p.", str, va);
+	panic_memtrap(istate, PF_ACCESS_EXEC, va, str);
 }
 
@@ -365,11 +365,8 @@
     uint64_t page_and_ctx, const char *str)
 {
-	if (DMISS_CONTEXT(page_and_ctx)) {
-		fault_if_from_uspace(istate, "%s, Page=%p (ASID=%d)\n", str, DMISS_ADDRESS(page_and_ctx),
-		    DMISS_CONTEXT(page_and_ctx));
-	}
-	dump_istate(istate);
-	printf("Faulting page: %p, ASID=%d\n", DMISS_ADDRESS(page_and_ctx), DMISS_CONTEXT(page_and_ctx));
-	panic("%s\n", str);
+	fault_if_from_uspace(istate, "%s, Page=%p (ASID=%d).", str,
+	    DMISS_ADDRESS(page_and_ctx), DMISS_CONTEXT(page_and_ctx));
+	panic_memtrap(istate, PF_ACCESS_UNKNOWN, DMISS_ADDRESS(page_and_ctx),
+	    str);
 }
 
@@ -377,11 +374,8 @@
     uint64_t page_and_ctx, const char *str)
 {
-	if (DMISS_CONTEXT(page_and_ctx)) {
-		fault_if_from_uspace(istate, "%s, Page=%p (ASID=%d)\n", str, DMISS_ADDRESS(page_and_ctx),
-		    DMISS_CONTEXT(page_and_ctx));
-	}
-	printf("Faulting page: %p, ASID=%d\n", DMISS_ADDRESS(page_and_ctx), DMISS_CONTEXT(page_and_ctx));
-	dump_istate(istate);
-	panic("%s\n", str);
+	fault_if_from_uspace(istate, "%s, Page=%p (ASID=%d).", str,
+	    DMISS_ADDRESS(page_and_ctx), DMISS_CONTEXT(page_and_ctx));
+	panic_memtrap(istate, PF_ACCESS_WRITE, DMISS_ADDRESS(page_and_ctx),
+	    str);
 }
 
Index: rnel/arch/sparc64/src/panic.S
===================================================================
--- kernel/arch/sparc64/src/panic.S	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ 	(revision )
@@ -1,40 +1,0 @@
-#
-# Copyright (c) 2005 Jakub Jermar
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions
-# are met:
-#
-# - Redistributions of source code must retain the above copyright
-#   notice, this list of conditions and the following disclaimer.
-# - Redistributions in binary form must reproduce the above copyright
-#   notice, this list of conditions and the following disclaimer in the
-#   documentation and/or other materials provided with the distribution.
-# - The name of the author may not be used to endorse or promote products
-#   derived from this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
-# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
-# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
-# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
-# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
-# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-#
-
-.text
-
-#include <arch/stack.h>
-
-.global panic_printf
-panic_printf:
-	call printf
-	nop
-	call halt
-	nop
-	/* Not reached. */
-
Index: kernel/arch/sparc64/src/smp/sun4v/smp.c
===================================================================
--- kernel/arch/sparc64/src/smp/sun4v/smp.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/sparc64/src/smp/sun4v/smp.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -28,5 +28,5 @@
  */
 
-/** @addtogroup sparc64	
+/** @addtogroup sparc64
  * @{
  */
@@ -292,5 +292,5 @@
 				exec_units[i].strand_count = 0;
 				atomic_set(&(exec_units[i].nrdy), 0);
-				spinlock_initialize(&(exec_units[i].proposed_nrdy_lock), "proposed nrdy lock");
+				spinlock_initialize(&(exec_units[i].proposed_nrdy_lock), "exec_units[].proposed_nrdy_lock");
 				exec_unit_count++;
 			}
@@ -330,5 +330,5 @@
 		exec_units[0].strand_count = cpu_count;
 		exec_units[0].exec_unit_id = 1;
-		spinlock_initialize(&(exec_units[0].proposed_nrdy_lock), "proposed nrdy lock");
+		spinlock_initialize(&(exec_units[0].proposed_nrdy_lock), "exec_units[0].proposed_nrdy_lock");
 		atomic_set(&(exec_units[0].nrdy), 0);
 		max_core_strands = cpu_count;
Index: kernel/arch/sparc64/src/sun4u/asm.S
===================================================================
--- kernel/arch/sparc64/src/sun4u/asm.S	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/sparc64/src/sun4u/asm.S	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -67,4 +67,8 @@
 	WRITE_ALTERNATE_REGISTER %g6, PSTATE_IG_BIT
 
+.global read_from_ag_g6
+read_from_ag_g6:
+	READ_ALTERNATE_REGISTER %g6, PSTATE_AG_BIT
+
 .global read_from_ag_g7
 read_from_ag_g7:
Index: kernel/arch/sparc64/src/sun4u/start.S
===================================================================
--- kernel/arch/sparc64/src/sun4u/start.S	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/sparc64/src/sun4u/start.S	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -293,8 +293,14 @@
 	 * Call arch_pre_main(bootinfo)
 	 */
+	call arch_pre_main
 	mov %o1, %o0
-	call arch_pre_main
-	nop
-	
+	
+	/*
+	 * Create the first stack frame.
+	 */
+	save %sp, -(STACK_WINDOW_SAVE_AREA_SIZE + STACK_ARG_SAVE_AREA_SIZE), %sp
+	flushw
+	add %g0, -STACK_BIAS, %fp
+
 	call main_bsp
 	nop
@@ -303,6 +309,5 @@
 
 0:
-	ba %xcc, 0b
-	nop
+	ba,a %xcc, 0b
 
 
@@ -354,4 +359,11 @@
 	ldx [%g1], %o6
 
+	/*
+	 * Create the first stack frame.
+	 */
+	save %sp, -(STACK_WINDOW_SAVE_AREA_SIZE + STACK_ARG_SAVE_AREA_SIZE), %sp
+	flushw
+	add %g0, -STACK_BIAS, %fp
+
 	call main_ap
 	nop
@@ -361,6 +373,5 @@
 	
 0:
-	ba %xcc, 0b
-	nop
+	ba,a %xcc, 0b
 
 
Index: kernel/arch/sparc64/src/sun4v/start.S
===================================================================
--- kernel/arch/sparc64/src/sun4v/start.S	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/sparc64/src/sun4v/start.S	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -155,5 +155,4 @@
    	mov 0, %o5
    	ta 0xff
-   	nop
 
 	/*
@@ -219,5 +218,5 @@
 	! on APs skip executing the following code
 	cmp %l7, 0
-	be 1f
+	be %xcc, 1f
 	nop
 
@@ -250,8 +249,14 @@
 	 * Call arch_pre_main(bootinfo)
 	 */
+	call arch_pre_main
 	or %l1, %g0, %o0
-	call arch_pre_main
-	nop
 	
+	/*
+	 * Create the first stack frame.
+	 */
+	save %sp, -(STACK_WINDOW_SAVE_AREA_SIZE + STACK_ARG_SAVE_AREA_SIZE), %sp
+	flushw
+	add %g0, -STACK_BIAS, %fp
+
 	call main_bsp
 	nop
@@ -260,6 +265,5 @@
 
 0:
-	ba 0b
-	nop
+	ba,a %xcc, 0b
 
 1:
@@ -273,8 +277,8 @@
 	 */
 
-	mov	1, %o0			! MMU enable flag
-	set	mmu_enabled, %o1
-	mov	MMU_ENABLE, %o5	! MMU enable HV call
-	ta	0x80		! call HV
+	mov 1, %o0		! MMU enable flag
+	set mmu_enabled, %o1
+	mov MMU_ENABLE, %o5	! MMU enable HV call
+	ta 0x80			! call HV
 
 	mmu_enabled:
@@ -289,4 +293,11 @@
 	ldx [%g1], %o6
 
+	/*
+	 * Create the first stack frame.
+	 */
+	save %sp, -(STACK_WINDWO_SAVE_AREA_SIZE + STACK_ARG_SAVE_AREA_SIZE), %sp
+	flushw
+	add %g0, -STACK_BIAS, %fp
+
 	call main_ap
 	nop
@@ -295,6 +306,5 @@
 	/* Not reached. */
 0:
-	ba 0b
-	nop
+	ba,a %xcc, 0b
 
 .align 8
@@ -314,6 +324,5 @@
 before_ap_boots:
 	setx 0x80400000, %g0, %o0
-	ba kernel_image_start
-	nop
+	ba,a %xcc, kernel_image_start
 
 .section K_DATA_START, "aw", @progbits
Index: kernel/arch/sparc64/src/trap/exception.c
===================================================================
--- kernel/arch/sparc64/src/trap/exception.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/sparc64/src/trap/exception.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -44,5 +44,5 @@
 #include <symtab.h>
 
-void dump_istate(istate_t *istate)
+void istate_decode(istate_t *istate)
 {
 	const char *tpcs = symtab_fmt_name_lookup(istate->tpc);
@@ -58,6 +58,5 @@
 {
 	fault_if_from_uspace(istate, "%s.", __func__);
-	dump_istate(istate);
-	panic("%s.", __func__);
+	panic_badtrap(istate, n, "%s.", __func__);
 }
 
@@ -66,6 +65,5 @@
 {
 	fault_if_from_uspace(istate, "%s.", __func__);
-	dump_istate(istate);
-	panic("%s.", __func__);
+	panic_badtrap(istate, n, "%s.", __func__);
 }
 
@@ -74,6 +72,5 @@
 {
 	fault_if_from_uspace(istate, "%s.", __func__);
-	dump_istate(istate);
-	panic("%s.", __func__);
+	panic_badtrap(istate, n, "%s.", __func__);
 }
 
@@ -82,6 +79,5 @@
 {
 	fault_if_from_uspace(istate, "%s.", __func__);
-	dump_istate(istate);
-	panic("%s.", __func__);
+	panic_badtrap(istate, n, "%s.", __func__);
 }
 
@@ -90,6 +86,5 @@
 {
 	fault_if_from_uspace(istate, "%s.", __func__);
-	dump_istate(istate);
-	panic("%s.", __func__);
+	panic_badtrap(istate, n, "%s.", __func__);
 }
 
@@ -98,6 +93,5 @@
 {
 	fault_if_from_uspace(istate, "%s.", __func__);
-	dump_istate(istate);
-	panic("%s.", __func__);
+	panic_badtrap(istate, n, "%s.", __func__);
 }
 
@@ -118,6 +112,5 @@
 #else
 	fault_if_from_uspace(istate, "%s.", __func__);
-	dump_istate(istate);
-	panic("%s.", __func__);
+	panic_badtrap(istate, n, "%s.", __func__);
 #endif
 }
@@ -127,6 +120,5 @@
 {
 	fault_if_from_uspace(istate, "%s.", __func__);
-	dump_istate(istate);
-	panic("%s.", __func__);
+	panic_badtrap(istate, n, "%s.", __func__);
 }
 
@@ -135,6 +127,5 @@
 {
 	fault_if_from_uspace(istate, "%s.", __func__);
-	dump_istate(istate);
-	panic("%s.", __func__);
+	panic_badtrap(istate, n, "%s.", __func__);
 }
 
@@ -143,6 +134,5 @@
 {
 	fault_if_from_uspace(istate, "%s.", __func__);
-	dump_istate(istate);
-	panic("%s.", __func__);
+	panic_badtrap(istate, n, "%s.", __func__);
 }
 
@@ -151,6 +141,5 @@
 {
 	fault_if_from_uspace(istate, "%s.", __func__);
-	dump_istate(istate);
-	panic("%s.", __func__);
+	panic_badtrap(istate, n, "%s.", __func__);
 }
 
@@ -159,7 +148,5 @@
 {
 	fault_if_from_uspace(istate, "%s.", __func__);
-	dump_istate(istate);
-	describe_dmmu_fault();
-	panic("%s.", __func__);
+	panic_badtrap(istate, n, "%s.", __func__);
 }
 
@@ -168,6 +155,5 @@
 {
 	fault_if_from_uspace(istate, "%s.", __func__);
-	dump_istate(istate);
-	panic("%s.", __func__);
+	panic_badtrap(istate, n, "%s.", __func__);
 }
 
@@ -176,6 +162,5 @@
 {
 	fault_if_from_uspace(istate, "%s.", __func__);
-	dump_istate(istate);
-	panic("%s.", __func__);
+	panic_badtrap(istate, n, "%s.", __func__);
 }
 
@@ -184,6 +169,5 @@
 {
 	fault_if_from_uspace(istate, "%s.", __func__);
-	dump_istate(istate);
-	panic("%s.", __func__);
+	panic_badtrap(istate, n, "%s.", __func__);
 }
 
@@ -192,6 +176,5 @@
 {
 	fault_if_from_uspace(istate, "%s.", __func__);
-	dump_istate(istate);
-	panic("%s.", __func__);
+	panic_badtrap(istate, n, "%s.", __func__);
 }
 
@@ -200,6 +183,5 @@
 {
 	fault_if_from_uspace(istate, "%s.", __func__);
-	dump_istate(istate);
-	panic("%s.", __func__);
+	panic_badtrap(istate, n, "%s.", __func__);
 }
 
@@ -208,6 +190,5 @@
 {
 	fault_if_from_uspace(istate, "%s.", __func__);
-	dump_istate(istate);
-	panic("%s.", __func__);
+	panic_badtrap(istate, n, "%s.", __func__);
 }
 
@@ -216,6 +197,5 @@
 {
 	fault_if_from_uspace(istate, "%s.", __func__);
-	dump_istate(istate);
-	panic("%s.", __func__);
+	panic_badtrap(istate, n, "%s.", __func__);
 }
 
Index: kernel/arch/sparc64/src/trap/interrupt.c
===================================================================
--- kernel/arch/sparc64/src/trap/interrupt.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/sparc64/src/trap/interrupt.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -51,14 +51,17 @@
 /** Register Interrupt Level Handler.
  *
- * @param n Interrupt Level (1 - 15).
- * @param name Short descriptive string.
- * @param f Handler.
+ * @param n       Interrupt Level (1 - 15).
+ * @param name    Short descriptive string.
+ * @param handler Handler.
+ *
  */
-void interrupt_register(int n, const char *name, iroutine f)
+void interrupt_register(unsigned int n, const char *name, iroutine_t handler)
 {
-	ASSERT(n >= IVT_FIRST && n <= IVT_ITEMS);
+	ASSERT(n >= IVT_FIRST);
+	ASSERT(n <= IVT_ITEMS);
 	
-	exc_register(n - 1, name, f);
+	exc_register(n - IVT_FIRST, name, true, handler);
 }
+
 /** @}
  */
Index: kernel/arch/sparc64/src/trap/sun4u/interrupt.c
===================================================================
--- kernel/arch/sparc64/src/trap/sun4u/interrupt.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/sparc64/src/trap/sun4u/interrupt.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -55,18 +55,15 @@
 void interrupt(int n, istate_t *istate)
 {
-	uint64_t status;
-	uint64_t intrcv;
-	uint64_t data0;
-	status = asi_u64_read(ASI_INTR_DISPATCH_STATUS, 0);
+	uint64_t status = asi_u64_read(ASI_INTR_DISPATCH_STATUS, 0);
 	if (status & (!INTR_DISPATCH_STATUS_BUSY))
 		panic("Interrupt Dispatch Status busy bit not set\n");
-
-	intrcv = asi_u64_read(ASI_INTR_RECEIVE, 0);
+	
+	uint64_t intrcv = asi_u64_read(ASI_INTR_RECEIVE, 0);
 #if defined (US)
-	data0 = asi_u64_read(ASI_INTR_R, ASI_UDB_INTR_R_DATA_0);
+	uint64_t data0 = asi_u64_read(ASI_INTR_R, ASI_UDB_INTR_R_DATA_0);
 #elif defined (US3)
-	data0 = asi_u64_read(ASI_INTR_R, VA_INTR_R_DATA_0);
+	uint64_t data0 = asi_u64_read(ASI_INTR_R, VA_INTR_R_DATA_0);
 #endif
-
+	
 	irq_t *irq = irq_dispatch_and_lock(data0);
 	if (irq) {
@@ -75,11 +72,12 @@
 		 */
 		irq->handler(irq);
+		
 		/*
 		 * See if there is a clear-interrupt-routine and call it.
 		 */
-		if (irq->cir) {
+		if (irq->cir)
 			irq->cir(irq->cir_arg, irq->inr);
-		}
-		spinlock_unlock(&irq->lock);
+		
+		irq_spinlock_unlock(&irq->lock, false);
 	} else if (data0 > config.base) {
 		/*
@@ -90,7 +88,6 @@
 		 */
 #ifdef CONFIG_SMP
-		if (data0 == (uintptr_t) tlb_shootdown_ipi_recv) {
+		if (data0 == (uintptr_t) tlb_shootdown_ipi_recv)
 			tlb_shootdown_ipi_recv();
-		}
 #endif
 	} else {
@@ -101,7 +98,9 @@
 		printf("cpu%u: spurious interrupt (intrcv=%#" PRIx64
 		    ", data0=%#" PRIx64 ")\n", CPU->id, intrcv, data0);
+#else
+		(void) intrcv;
 #endif
 	}
-
+	
 	membar();
 	asi_u64_write(ASI_INTR_RECEIVE, 0, 0);
Index: kernel/arch/sparc64/src/trap/sun4u/trap_table.S
===================================================================
--- kernel/arch/sparc64/src/trap/sun4u/trap_table.S	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/sparc64/src/trap/sun4u/trap_table.S	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -481,6 +481,6 @@
 	be %xcc, 1f
 	nop
-0:	ba %xcc, 0b				! this is for debugging, if we ever get here
-	nop					! it will be easy to find
+	! this is for debugging, if we ever get here it will be easy to find
+0:	ba,a %xcc, 0b
 
 1:
@@ -546,6 +546,5 @@
 
 .if NOT(\is_syscall)
-	ba %xcc, 1f
-	nop
+	ba,a %xcc, 1f
 0:
 	save %sp, -PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE, %sp
Index: kernel/arch/sparc64/src/trap/sun4v/interrupt.c
===================================================================
--- kernel/arch/sparc64/src/trap/sun4v/interrupt.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/sparc64/src/trap/sun4v/interrupt.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -111,5 +111,5 @@
 			((void (*)(void)) data1)();
 		} else {
-			printf("Spurious interrupt on %d, data = %lx.\n",
+			printf("Spurious interrupt on %d, data = %" PRIx64 ".\n",
 			    CPU->arch.id, data1);
 		}
Index: kernel/arch/sparc64/src/trap/sun4v/trap_table.S
===================================================================
--- kernel/arch/sparc64/src/trap/sun4v/trap_table.S	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/arch/sparc64/src/trap/sun4v/trap_table.S	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -71,6 +71,5 @@
 .org trap_table + TT_INSTRUCTION_ACCESS_MMU_MISS*ENTRY_SIZE
 .global instruction_access_mmu_miss_handler_tl0
-	ba fast_instruction_access_mmu_miss_handler_tl0
-	nop
+	ba,a %xcc, fast_instruction_access_mmu_miss_handler_tl0
 
 /* TT = 0x0a, TL = 0, instruction_access_error */
@@ -187,6 +186,5 @@
 .global data_access_mmu_miss_tl0
 data_access_mmu_miss_tl0:
-	ba fast_data_access_mmu_miss_handler_tl0
-	nop
+	ba,a %xcc, fast_data_access_mmu_miss_handler_tl0
 
 /* TT = 0x32, TL = 0, data_access_error */
@@ -394,5 +392,5 @@
 .global trap_instruction_\cur\()_tl0
 trap_instruction_\cur\()_tl0:
-	ba trap_instruction_handler
+	ba %xcc, trap_instruction_handler
 	mov \cur, %g2
 .endr
@@ -414,6 +412,5 @@
 .global instruction_access_mmu_miss_handler_tl1
 	wrpr %g0, 1, %tl
-	ba fast_instruction_access_mmu_miss_handler_tl0
-	nop
+	ba,a %xcc, fast_instruction_access_mmu_miss_handler_tl0
 
 /* TT = 0x0a, TL > 0, instruction_access_error */
@@ -498,7 +495,5 @@
 .global data_access_mmu_miss_tl1
 data_access_mmu_miss_tl1:
-	ba fast_data_access_mmu_miss_handler_tl1
-	nop
-
+	ba,a %xcc, fast_data_access_mmu_miss_handler_tl1
 
 /* TT = 0x32, TL > 0, data_access_error */
@@ -742,5 +737,5 @@
 	rdpr %cwp, %l1
 	cmp %l0, %l1
-	bz 4f				! CWP is ok
+	bz %xcc, 4f			! CWP is ok
 	nop
 
@@ -785,8 +780,9 @@
 	rdpr %tl, %g3
 	cmp %g3, 1
-	be 1f
+	be %xcc, 1f
 	nop
-0:	ba 0b					! this is for debugging, if we ever get here
-	nop					! it will be easy to find
+
+	! this is for debugging, if we ever get here it will be easy to find
+0:	ba,a %xcc, 0b
 
 1:
@@ -957,5 +953,5 @@
 	clr %g4
 5:	andcc %g7, UWB_ALIGNMENT - 1, %g0	! alignment check
-	bz 6f					! %g7 is UWB_ALIGNMENT-aligned, no more windows to refill
+	bz %xcc, 6f				! %g7 is UWB_ALIGNMENT-aligned, no more windows to refill
 	nop
 
@@ -982,5 +978,5 @@
 	wrpr %g3, 0, %cwp			! switch to the preceeding window
 
-	ba 5b
+	ba %xcc, 5b
 	inc %g4
 
@@ -996,5 +992,5 @@
 	add %g4, %g2, %g2
 	cmp %g2, NWINDOWS - 2
-	bg 8f					! fix the CANRESTORE=NWINDOWS-1 anomaly
+	bg %xcc, 8f				! fix the CANRESTORE=NWINDOWS-1 anomaly
 	mov NWINDOWS - 2, %g1			! use dealy slot for both cases
 	sub %g1, %g2, %g1
@@ -1066,6 +1062,5 @@
 
 	PREEMPTIBLE_HANDLER_KERNEL
-	ba 101f
-	nop
+	ba,a %xcc, 101f
 
 	100:
Index: rnel/doc/AUTHORS
===================================================================
--- kernel/doc/AUTHORS	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ 	(revision )
@@ -1,12 +1,0 @@
-Jakub Jermar
-Martin Decky
-Ondrej Palkovsky
-Jiri Svoboda
-Jakub Vana
-Josef Cejka
-Michal Kebrt
-Sergey Bondari
-Pavel Jancik
-Petr Stepan
-Michal Konopa
-Vojtech Mencl
Index: rnel/doc/arch/amd64
===================================================================
--- kernel/doc/arch/amd64	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ 	(revision )
@@ -1,35 +1,0 @@
-amd64 port
-==========
-
-The fifth port, amd64 port, was originally written by Ondrej Palkovsky.
-The goal is to support AMD64 and Intel Extended Memory 64 Technology PC's.
-The port makes use of portable parts of ia32.
-Both uniprocessors and multiprocessors are supported.
-The kernel runs on real hardware and in simulators too.
-
-HARDWARE REQUIREMENTS
-        o AMD64 architecture processor
-	o Intel Extended Memory 64 Technology processor
-
-CPU
-	o Intel Xeon with Intel Extended Memory 64 Technology
-	o AMD Athlon 64
-
-SMP COMPATIBILITY
-        o Bochs 2.2.1 - 2.2.6
-                o 2x-8x AMD64 CPU
-        o Simics 2.2.19
-                o 2x-15x AMD hammer CPU
-	o QEMU 0.8.0 - QEMU 0.8.1
-		o 2x-15x CPU
-	o HP ProLiant ML350 (HyperThreading)
-
-EMULATORS AND VIRTUALIZERS
-        o Bochs 2.2.6
-        o Simics 2.2.19
-	o QEMU 0.8.1
-
-TOOLCHAIN REQUIREMENTS
-	o binutils 2.16, 2.16.1
-	o gcc 4.0.1, 4.1.0, 4.1.1
-	o older versions may do as well, but are now obsoleted
Index: rnel/doc/arch/arm32
===================================================================
--- kernel/doc/arch/arm32	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ 	(revision )
@@ -1,16 +1,0 @@
-arm32 port
-==========
-
-arm32 port is the ninth port of SPARTAN, originally written by Michal Kebrt,
-Petr Stepan, Pavel Jancik. The goal is to support 32-bit ARM architecture.
-So far, it runs only in emulator.
-
-HARDWARE REQUIREMENTS
-        o no real hardware supported
-
-EMULATORS AND VIRTUALIZERS
-        o GXemul
-
-TOOLCHAIN REQUIREMENTS
-	o binutils 2.17
-	o gcc 4.1.1
Index: rnel/doc/arch/ia32
===================================================================
--- kernel/doc/arch/ia32	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ 	(revision )
@@ -1,40 +1,0 @@
-ia32 port
-=========
-
-ia32 port is the oldest and the most advanced one.
-It was originally written by Jakub Jermar.
-It is meant to support ordinary PC's based on IA-32 architecture.
-Both uniprocessor and multiprocessor modes are supported.
-It runs both in emulated environment and on real hardware.
-
-HARDWARE REQUIREMENTS
-        o IA-32 processor (Pentium and successors)
-
-SMP COMPATIBILITY
-        o Bochs 2.0.2 - Bochs 2.2.6
-                o 2x-8x 686 CPU
-        o Simics 2.0.28 - Simics 2.2.19
-                o 2x-15x Pentium 4 CPU
-	o VMware Workstation 5.5
-		o 2x CPU
-	o QEMU 0.8.0 - QEMU 0.8.1
-		o 2x-15x CPU
-        o ASUS P/I-P65UP5 + ASUS C-P55T2D REV. 1.41
-                o 2x 200Mhz Pentium CPU
-        o ASUS PCH-DL
-                o 2x 3000Mhz Pentium 4 Xeon (HT) CPU
-        o MSI K7D Master-L
-	        o 2x 2100MHz Athlon MP CPU
-	o ECS 865PE-A REV : 2.0
-		o 1x 2800MHz Pentium 4 Prescott (HT) CPU
-
-EMULATORS AND VIRTUALIZERS
-        o Bochs 2.0.2 - Bochs 2.2.6
-        o VMware Workstation 4, VMware Workstation 5, VMware Workstation 5.5
-        o Simics 2.2.19
-	o QEMU 0.8.0 - QEMU 0.8.1
-
-TOOLCHAIN REQUIREMENTS
-        o binutils 2.15, 2.16, 2.16.1
-	o gcc 3.3.5, 4.0.1, 4.1.0, 4.1.1
-        o older versions may do as well, but are now obsoleted
Index: rnel/doc/arch/ia64
===================================================================
--- kernel/doc/arch/ia64	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ 	(revision )
@@ -1,16 +1,0 @@
-ia64 port
-=========
-
-ia64 port is the third port of SPARTAN originally written by Jakub Jermar.
-It is still in its early stages. It runs on HP Ski simulator of IA-64 architecture.
-
-HARDWARE REQUIREMENTS
-        o no real hardware supported
-
-EMULATORS AND VIRTUALIZERS
-        o ski
-
-TOOLCHAIN REQUIREMENTS
-        o binutils 2.15, 2.16, 2.16.1
-	o gcc 4.0.0, 4.0.1, 4.1.0, 4.1.1
-        o older versions may do as well, but are now obsoleted
Index: rnel/doc/arch/mips32
===================================================================
--- kernel/doc/arch/mips32	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ 	(revision )
@@ -1,22 +1,0 @@
-mips32 port
-===========
-
-mips32 is the second port of SPARTAN kernel originally written by Jakub Jermar.
-It was first developed to run on MIPS R4000 32-bit simulator.
-It can be compiled and run either as little- or big-endian.
-
-HARDWARE REQUIREMENTS
-        o emulated MIPS 4K CPU
-
-CPU
-	o QED R4600
-
-EMULATORS AND VIRTUALIZERS
-	o msim 1.2.12
-        o gxemul - both big and little endian
-        o simics 2.2.19
-
-TOOLCHAIN REQUIREMENTS
-        o binutils 2.16, 2.16.1
-	o gcc 4.0.1, 4.1.0, 4.1.1
-        o older versions may do as well, but are now obsoleted
Index: rnel/doc/arch/ppc32
===================================================================
--- kernel/doc/arch/ppc32	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ 	(revision )
@@ -1,15 +1,0 @@
-ppc32 port
-==========
-
-ppc32 port is the fourth port of SPARTAN, originally written by Martin Decky.
-The goal is to support 32-bit PowerPC architecture.
-
-HARDWARE REQUIREMENTS
-        o Apple iMac G4
-
-EMULATORS AND VIRTUALIZERS
-        o QEMU
-
-TOOLCHAIN REQUIREMENTS
-        o binutils 2.16
-        o gcc 4.0.1, 4.1.0, 4.1.1
Index: rnel/doc/arch/sparc64
===================================================================
--- kernel/doc/arch/sparc64	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ 	(revision )
@@ -1,25 +1,0 @@
-sparc64 port
-============
-
-Currently, this porting effort is subject to
-Jakub Jermar's work on his master thesis.
-
-The goal is to provide support for UltraSPARC
-implementation of SPARC V9 architecture.
-
-MACHINES
-	o Sun Ultra 5
-	o Sun Ultra 60
-	o Sun Enterprise E6500 (simulated)
-		
-CPU
-	o UltraSPARC II
-	o UltraSPARC IIi
-
-SIMULATORS
-	o simics 2.2.19, simics 3.0.17, simics 3.0.21
-						
-TOOLCHAIN REQUIREMENTS
-	o binutils 2.17
-	o gcc 4.1.1
-	o older versions may do as well, but are now obsoleted
Index: rnel/doc/build
===================================================================
--- kernel/doc/build	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ 	(revision )
@@ -1,14 +1,0 @@
-Following make targets are supported:
-
-make, make all
-	- Check configuration, build
-
-make config
-	- Start kernel configuration program
-
-make clean
-	- Clean build temporary files
-
-make distclean
-	- Clean everything including configuration
-
Index: kernel/doc/synchronization
===================================================================
--- kernel/doc/synchronization	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/doc/synchronization	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -5,4 +5,14 @@
                                  | spinlock_t |
                                  +------------+
+                                       |
+                                       +------------------------------+
+                                                                      |
+                      INTERRUPTS-DISABLED SPINNING LOCKS              |
+       irq_spinlock_lock, irq_spinlock_trylock, irq_spinlock_unlock   |
+                               +----------------+                     |
+                               | irq_spinlock_t |<--------------------+
+                               +----------------+
+
+
 
                                    WAIT QUEUES
@@ -10,6 +20,6 @@
                                    +---------+
                                    | waitq_t |
-			           +---------+
-				  /           \
+                                   +---------+
+                                  /           \
                SEMAPHORES        /             \  CONDITION VARIABLES
  semaphore_down_timeout, semaphore_up    condvar_wait_timeout, condvar_signal
@@ -18,12 +28,12 @@
             +--------------+                         +-----------+
                    |                                       ^
-		   |                                       |
+                   |                                       |
                    |                                +------+
-                   V                               /           
+                   V                               /
                 MUTEXES                           / READERS/WRITERS LOCKS
     mutex_lock_timeout, mutex_unlock   rwlock_reader/writer_lock_timeout, rwlock_unlock
               +---------+                       /        +----------+
-	      | mutex_t |------------------------------->| rwlock_t |
-	      +---------+                     /          +----------+
-	           |                         /
-		   +------------------------+
+              | mutex_t |------------------------------->| rwlock_t |
+              +---------+                     /          +----------+
+                   |                         /
+                   +------------------------+
Index: kernel/genarch/Makefile.inc
===================================================================
--- kernel/genarch/Makefile.inc	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/genarch/Makefile.inc	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -90,4 +90,14 @@
 endif
 
+ifeq ($(CONFIG_S3C24XX_IRQC),y)
+	GENARCH_SOURCES += \
+		genarch/src/drivers/s3c24xx_irqc/s3c24xx_irqc.c
+endif
+
+ifeq ($(CONFIG_S3C24XX_UART),y)
+	GENARCH_SOURCES += \
+		genarch/src/drivers/s3c24xx_uart/s3c24xx_uart.c
+endif
+
 ifeq ($(CONFIG_Z8530),y)
 	GENARCH_SOURCES += \
Index: kernel/genarch/include/acpi/acpi.h
===================================================================
--- kernel/genarch/include/acpi/acpi.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/genarch/include/acpi/acpi.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -27,5 +27,5 @@
  */
 
-/** @addtogroup genarch	
+/** @addtogroup genarch
  * @{
  */
@@ -62,5 +62,5 @@
 	uint32_t creator_id;
 	uint32_t creator_revision;
-} __attribute__ ((packed));;
+} __attribute__ ((packed));
 
 struct acpi_signature_map {
@@ -74,5 +74,5 @@
 	struct acpi_sdt_header header;
 	uint32_t entry[];
-} __attribute__ ((packed));;
+} __attribute__ ((packed));
 
 /* Extended System Description Table */
@@ -80,5 +80,5 @@
 	struct acpi_sdt_header header;
 	uint64_t entry[];
-} __attribute__ ((packed));;
+} __attribute__ ((packed));
 
 extern struct acpi_rsdp *acpi_rsdp;
Index: kernel/genarch/include/acpi/madt.h
===================================================================
--- kernel/genarch/include/acpi/madt.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/genarch/include/acpi/madt.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -27,5 +27,5 @@
  */
 
-/** @addtogroup genarch	
+/** @addtogroup genarch
  * @{
  */
@@ -40,16 +40,16 @@
 #include <arch/smp/smp.h>
 
-#define	MADT_L_APIC			0
-#define MADT_IO_APIC			1
-#define MADT_INTR_SRC_OVRD		2
-#define MADT_NMI_SRC			3
-#define MADT_L_APIC_NMI			4
-#define MADT_L_APIC_ADDR_OVRD		5
-#define MADT_IO_SAPIC			6
-#define MADT_L_SAPIC			7
-#define MADT_PLATFORM_INTR_SRC		8
-#define MADT_RESERVED_SKIP_BEGIN	9
-#define MADT_RESERVED_SKIP_END		127
-#define MADT_RESERVED_OEM_BEGIN		128
+#define MADT_L_APIC               0
+#define MADT_IO_APIC              1
+#define MADT_INTR_SRC_OVRD        2
+#define MADT_NMI_SRC              3
+#define MADT_L_APIC_NMI           4
+#define MADT_L_APIC_ADDR_OVRD     5
+#define MADT_IO_SAPIC             6
+#define MADT_L_SAPIC              7
+#define MADT_PLATFORM_INTR_SRC    8
+#define MADT_RESERVED_SKIP_BEGIN  9
+#define MADT_RESERVED_SKIP_END    127
+#define MADT_RESERVED_OEM_BEGIN   128
 
 struct madt_apic_header {
@@ -57,5 +57,4 @@
 	uint8_t length;
 } __attribute__ ((packed));
-
 
 /* Multiple APIC Description Table */
@@ -71,5 +70,5 @@
 	uint8_t acpi_id;
 	uint8_t apic_id;
-	uint32_t flags;	
+	uint32_t flags;
 } __attribute__ ((packed));
 
@@ -78,5 +77,5 @@
 	uint8_t io_apic_id;
 	uint8_t reserved;
-	uint32_t io_apic_address;	
+	uint32_t io_apic_address;
 	uint32_t global_intr_base;
 } __attribute__ ((packed));
@@ -114,5 +113,5 @@
 	uint8_t reserved;
 	uint32_t global_intr_base;
-	uint64_t io_apic_address;		
+	uint64_t io_apic_address;
 } __attribute__ ((packed));
 
Index: kernel/genarch/include/drivers/pl050/pl050.h
===================================================================
--- kernel/genarch/include/drivers/pl050/pl050.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/genarch/include/drivers/pl050/pl050.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -72,5 +72,5 @@
 #define PL050_STAT_RXFULL	(1 << 4)	/* 1: register Full */
 #define PL050_STAT_RXBUSY	(1 << 3)	/* 1: Busy, recieving Data */
-#define PL050_STAT_RXPARITY	(1 << 2)	/* odd parity of the last bit recieved */
+#define PL050_STAT_RXPARITY	(1 << 2)	/* odd parity of the last bit received */
 #define PL050_STAT_KMIC		(1 << 1)	/* status of KMICLKIN */
 #define PL050_STAT_KMID		1		/* status of KMIDATAIN */
Index: kernel/genarch/include/drivers/s3c24xx_irqc/s3c24xx_irqc.h
===================================================================
--- kernel/genarch/include/drivers/s3c24xx_irqc/s3c24xx_irqc.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
+++ kernel/genarch/include/drivers/s3c24xx_irqc/s3c24xx_irqc.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -0,0 +1,137 @@
+/*
+ * 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
+ * @brief Samsung S3C24xx on-chip interrupt controller driver.
+ */
+
+#ifndef KERN_S3C24XX_IRQC_H_
+#define KERN_S3C24XX_IRQC_H_
+
+#include <typedefs.h>
+
+/** Physical address where S3C24XX Interrupt controller is mapped */
+#define S3C24XX_IRQC_ADDRESS	0x4a000000
+
+/** S3C24xx on-chip interrupt controller registers */
+typedef struct {
+	ioport32_t srcpnd;	/**< Source pending */
+	ioport32_t intmod;	/**< Interrupt mode */
+	ioport32_t intmsk;	/**< Interrupt mask */
+	ioport32_t priority;	/**< Priority */
+	ioport32_t intpnd;	/**< Interrupt pending */
+	ioport32_t intoffset;	/**< Interrupt offset */
+	ioport32_t subsrcpnd;	/**< Sub source pending */
+	ioport32_t intsubmsk;	/** Interrupt sub mask */
+} s3c24xx_irqc_regs_t;
+
+/** S3C24xx Interrupt source numbers.
+ *
+ * These correspond to bit numbers in srcpnd, intmod, intmsk and intpnd
+ * registers as well as to the values read from the intoffset register.
+ */
+enum s3c24xx_int_source {
+	S3C24XX_INT_ADC		= 31,
+	S3C24XX_INT_RTC		= 30,
+	S3C24XX_INT_SPI1	= 29,
+	S3C24XX_INT_UART0	= 28,
+	S3C24XX_INT_IIC		= 27,
+	S3C24XX_INT_USBH	= 26,
+	S3C24XX_INT_USBD	= 25,
+	S3C24XX_INT_NFCON	= 24,
+	S3C24XX_INT_UART1	= 23,
+	S3C24XX_INT_SPI0	= 22,
+	S3C24XX_INT_SDI		= 21,
+	S3C24XX_INT_DMA3	= 20,
+	S3C24XX_INT_DMA2	= 19,
+	S3C24XX_INT_DMA1	= 18,
+	S3C24XX_INT_DMA0	= 17,
+	S3C24XX_INT_LCD		= 16,
+	S3C24XX_INT_UART2	= 15,
+	S3C24XX_INT_TIMER4	= 14,
+	S3C24XX_INT_TIMER3	= 13,
+	S3C24XX_INT_TIMER2	= 12,
+	S3C24XX_INT_TIMER1	= 11,
+	S3C24XX_INT_TIMER0	= 10,
+	S3C24XX_INT_WDT_AC97	= 9,
+	S3C24XX_INT_TICK	= 8,
+	S3C24XX_nBATT_FLT	= 7,
+	S3C24XX_INT_CAM		= 6,
+	S3C24XX_EINT8_23	= 5,
+	S3C24XX_EINT4_7		= 4,
+	S3C24XX_EINT3		= 3,
+	S3C24XX_EINT2		= 2,
+	S3C24XX_EINT1		= 1,
+	S3C24XX_EINT0		= 0
+};
+
+/** S3C24xx Interrupt sub-source numbers.
+ *
+ * These correspond to bit numbers in the intsubmsk register.
+ */
+enum s3c24xx_int_subsource {
+	S3C24XX_SUBINT_AC97	= 14,
+	S3C24XX_SUBINT_WDT	= 13,
+	S3C24XX_SUBINT_CAM_P	= 12,
+	S3C24XX_SUBINT_CAM_C	= 11,
+	S3C24XX_SUBINT_ADC_S	= 10,
+	S3C24XX_SUBINT_TC	= 9,
+	S3C24XX_SUBINT_ERR2	= 8,
+	S3C24XX_SUBINT_TXD2	= 7,
+	S3C24XX_SUBINT_RXD2	= 6,
+	S3C24XX_SUBINT_ERR1	= 5,
+	S3C24XX_SUBINT_TXD1	= 4,
+	S3C24XX_SUBINT_RXD1	= 3,
+	S3C24XX_SUBINT_ERR0	= 2,
+	S3C24XX_SUBINT_TXD0	= 1,
+	S3C24XX_SUBINT_RXD0	= 0
+};
+
+#define S3C24XX_INT_BIT(source) (1 << (source))
+#define S3C24XX_SUBINT_BIT(subsource) (1 << (subsource))
+
+typedef struct {
+	s3c24xx_irqc_regs_t *regs;
+} s3c24xx_irqc_t;
+
+extern void s3c24xx_irqc_init(s3c24xx_irqc_t *, s3c24xx_irqc_regs_t *);
+extern unsigned s3c24xx_irqc_inum_get(s3c24xx_irqc_t *);
+extern void s3c24xx_irqc_clear(s3c24xx_irqc_t *, unsigned);
+extern void s3c24xx_irqc_src_enable(s3c24xx_irqc_t *, unsigned);
+extern void s3c24xx_irqc_src_disable(s3c24xx_irqc_t *, unsigned);
+extern void s3c24xx_irqc_subsrc_enable(s3c24xx_irqc_t *, unsigned);
+extern void s3c24xx_irqc_subsrc_disable(s3c24xx_irqc_t *, unsigned);
+
+#endif
+
+/** @}
+ */
Index: kernel/genarch/include/drivers/s3c24xx_timer/s3c24xx_timer.h
===================================================================
--- kernel/genarch/include/drivers/s3c24xx_timer/s3c24xx_timer.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
+++ kernel/genarch/include/drivers/s3c24xx_timer/s3c24xx_timer.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -0,0 +1,90 @@
+/*
+ * 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
+ * @brief Samsung S3C24xx on-chip PWM timer driver.
+ */
+
+#ifndef KERN_S3C24XX_TIMER_H_
+#define KERN_S3C24XX_TIMER_H_
+
+#include <typedefs.h>
+
+/** Physical address where S3C24XX on-chip PWM timer is mapped */
+#define S3C24XX_TIMER_ADDRESS	0x51000000
+
+/** S3C24xx on-chip PWM timer registers */
+typedef struct {
+	ioport32_t tcfg0;	/**< Timer configuration register 0 */
+	ioport32_t tcfg1;	/**< Timer configuration register 1 */
+	ioport32_t tcon;	/**< Timer control register */
+
+	struct {
+		ioport32_t cntb;	/**< Count buffer register */
+		ioport32_t cmpb;	/**< Compare buffer register */
+		ioport32_t cnto;	/**< Count observation register */
+	} timer[5];
+} s3c24xx_timer_t;
+
+/** Bits in the S3C24xx PWM timer TCON register. */
+enum s3c24xx_tcon_bits {
+	TCON_T0_START		= (1 << 0),	/**< Timer 0 start */
+	TCON_T0_MUPDATE		= (1 << 1),	/**< Timer 0 manual update */
+	TCON_T0_INVERT		= (1 << 2),	/**< Timer 0 inverter on */
+	TCON_T0_AUTO_RLD	= (1 << 3),	/**< Timer 0 auto reload */
+
+	TCON_DEAD_ZONE		= (1 << 4),	/**< Dead zone enable */
+
+	TCON_T1_START		= (1 << 8),	/**< Timer 1 start */
+	TCON_T1_MUPDATE		= (1 << 9),	/**< Timer 1 manual update */
+	TCON_T1_INVERT		= (1 << 10),	/**< Timer 1 inverter on */
+	TCON_T1_AUTO_RLD	= (1 << 11),	/**< Timer 1 auto reload */
+
+	TCON_T2_START		= (1 << 12),	/**< Timer 2 start */
+	TCON_T2_MUPDATE		= (1 << 13),	/**< Timer 2 manual update */
+	TCON_T2_INVERT		= (1 << 14),	/**< Timer 2 inverter on */
+	TCON_T2_AUTO_RLD	= (1 << 15),	/**< Timer 2 auto reload */
+
+	TCON_T3_START		= (1 << 16),	/**< Timer 3 start */
+	TCON_T3_MUPDATE		= (1 << 17),	/**< Timer 3 manual update */
+	TCON_T3_INVERT		= (1 << 18),	/**< Timer 3 inverter on */
+	TCON_T3_AUTO_RLD	= (1 << 19),	/**< Timer 3 auto reload */
+
+	TCON_T4_START		= (1 << 20),	/**< Timer 4 start */
+	TCON_T4_MUPDATE		= (1 << 21),	/**< Timer 4 manual update */
+	TCON_T4_AUTO_RLD	= (1 << 22)	/**< Timer 4 auto reload */
+};
+
+#endif
+
+/** @}
+ */
Index: kernel/genarch/include/drivers/s3c24xx_uart/s3c24xx_uart.h
===================================================================
--- kernel/genarch/include/drivers/s3c24xx_uart/s3c24xx_uart.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
+++ kernel/genarch/include/drivers/s3c24xx_uart/s3c24xx_uart.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -0,0 +1,94 @@
+/*
+ * 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
+ * @brief Samsung S3C24xx on-chip UART driver.
+ */
+
+#ifndef KERN_S3C24XX_UART_H_
+#define KERN_S3C24XX_UART_H_
+
+#include <ddi/irq.h>
+#include <console/chardev.h>
+#include <typedefs.h>
+
+/** S3C24xx UART I/O */
+typedef struct {
+	uint32_t ulcon;
+	uint32_t ucon;
+	uint32_t ufcon;
+	uint32_t umcon;
+
+	uint32_t utrstat;
+	uint32_t uerstat;
+	uint32_t ufstat;
+	uint32_t umstat;
+
+	uint32_t utxh;
+	uint32_t urxh;
+
+	uint32_t ubrdiv;
+} s3c24xx_uart_io_t;
+
+/* Bits in UTRSTAT register */
+#define S3C24XX_UTRSTAT_TX_EMPTY	0x4
+#define S3C24XX_UTRSTAT_RDATA		0x1
+
+/* Bits in UFSTAT register */
+#define S3C24XX_UFSTAT_TX_FULL		0x4000
+#define S3C24XX_UFSTAT_RX_FULL		0x0040
+#define S3C24XX_UFSTAT_RX_COUNT		0x002f
+
+/* Bits in UCON register */
+#define UCON_RX_INT_LEVEL		0x100
+
+/* Bits in UFCON register */
+#define UFCON_TX_FIFO_TLEVEL_EMPTY	0x00
+#define UFCON_RX_FIFO_TLEVEL_1B		0x00
+#define UFCON_FIFO_ENABLE		0x01
+
+
+/** S3C24xx UART instance */
+typedef struct {
+	s3c24xx_uart_io_t *io;
+	indev_t *indev;
+	irq_t irq;
+} s3c24xx_uart_t;
+
+extern outdev_t *s3c24xx_uart_init(s3c24xx_uart_io_t *, inr_t inr);
+extern void s3c24xx_uart_input_wire(s3c24xx_uart_t *,
+    indev_t *);
+
+#endif
+
+/** @}
+ */
Index: kernel/genarch/include/mm/page_ht.h
===================================================================
--- kernel/genarch/include/mm/page_ht.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/genarch/include/mm/page_ht.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -32,5 +32,5 @@
 /**
  * @file
- * @brief	This is the generic page hash table interface.
+ * @brief This is the generic page hash table interface.
  */
 
@@ -46,18 +46,18 @@
 #include <adt/hash_table.h>
 
-#define PAGE_HT_KEYS	2
-#define KEY_AS		0
-#define KEY_PAGE	1
+#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)
+#define PAGE_HT_ENTRIES_BITS  13
+#define PAGE_HT_ENTRIES       (1 << PAGE_HT_ENTRIES_BITS)
 
 /* Macros for querying page hash table PTEs. */
-#define PTE_VALID(pte)		((pte) != NULL)
-#define PTE_PRESENT(pte)	((pte)->p != 0)
-#define PTE_GET_FRAME(pte)	((pte)->frame)
-#define PTE_READABLE(pte)	1
-#define PTE_WRITABLE(pte)	((pte)->w != 0)
-#define PTE_EXECUTABLE(pte)	((pte)->x != 0)
+#define PTE_VALID(pte)       ((pte) != NULL)
+#define PTE_PRESENT(pte)     ((pte)->p != 0)
+#define PTE_GET_FRAME(pte)   ((pte)->frame)
+#define PTE_READABLE(pte)    1
+#define PTE_WRITABLE(pte)    ((pte)->w != 0)
+#define PTE_EXECUTABLE(pte)  ((pte)->x != 0)
 
 extern as_operations_t as_ht_operations;
Index: kernel/genarch/include/mm/page_pt.h
===================================================================
--- kernel/genarch/include/mm/page_pt.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/genarch/include/mm/page_pt.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -37,4 +37,5 @@
  * Architectures that use hierarchical page tables
  * are supposed to implement *_ARCH macros.
+ *
  */
 
@@ -52,76 +53,81 @@
  * Number of entries in each level.
  */
-#define PTL0_ENTRIES			PTL0_ENTRIES_ARCH
-#define PTL1_ENTRIES			PTL1_ENTRIES_ARCH
-#define PTL2_ENTRIES			PTL2_ENTRIES_ARCH
-#define PTL3_ENTRIES			PTL3_ENTRIES_ARCH
+#define PTL0_ENTRIES  PTL0_ENTRIES_ARCH
+#define PTL1_ENTRIES  PTL1_ENTRIES_ARCH
+#define PTL2_ENTRIES  PTL2_ENTRIES_ARCH
+#define PTL3_ENTRIES  PTL3_ENTRIES_ARCH
 
 /* Table sizes in each level */
-#define PTL0_SIZE			PTL0_SIZE_ARCH
-#define PTL1_SIZE			PTL1_SIZE_ARCH
-#define PTL2_SIZE			PTL2_SIZE_ARCH
-#define PTL3_SIZE			PTL3_SIZE_ARCH
+#define PTL0_SIZE  PTL0_SIZE_ARCH
+#define PTL1_SIZE  PTL1_SIZE_ARCH
+#define PTL2_SIZE  PTL2_SIZE_ARCH
+#define PTL3_SIZE  PTL3_SIZE_ARCH
 
 /*
  * These macros process vaddr and extract those portions
  * of it that function as indices to respective page tables.
+ *
  */
-#define PTL0_INDEX(vaddr)		PTL0_INDEX_ARCH(vaddr)
-#define PTL1_INDEX(vaddr)		PTL1_INDEX_ARCH(vaddr)
-#define PTL2_INDEX(vaddr)		PTL2_INDEX_ARCH(vaddr)
-#define PTL3_INDEX(vaddr)		PTL3_INDEX_ARCH(vaddr)
+#define PTL0_INDEX(vaddr)  PTL0_INDEX_ARCH(vaddr)
+#define PTL1_INDEX(vaddr)  PTL1_INDEX_ARCH(vaddr)
+#define PTL2_INDEX(vaddr)  PTL2_INDEX_ARCH(vaddr)
+#define PTL3_INDEX(vaddr)  PTL3_INDEX_ARCH(vaddr)
 
-#define SET_PTL0_ADDRESS(ptl0)		SET_PTL0_ADDRESS_ARCH(ptl0)
+#define SET_PTL0_ADDRESS(ptl0)  SET_PTL0_ADDRESS_ARCH(ptl0)
 
 /*
  * These macros traverse the 4-level tree of page tables,
  * each descending by one level.
+ *
  */
-#define GET_PTL1_ADDRESS(ptl0, i)	GET_PTL1_ADDRESS_ARCH(ptl0, i)
-#define GET_PTL2_ADDRESS(ptl1, i)	GET_PTL2_ADDRESS_ARCH(ptl1, i)
-#define GET_PTL3_ADDRESS(ptl2, i)	GET_PTL3_ADDRESS_ARCH(ptl2, i)
-#define GET_FRAME_ADDRESS(ptl3, i)	GET_FRAME_ADDRESS_ARCH(ptl3, i)
+#define GET_PTL1_ADDRESS(ptl0, i)   GET_PTL1_ADDRESS_ARCH(ptl0, i)
+#define GET_PTL2_ADDRESS(ptl1, i)   GET_PTL2_ADDRESS_ARCH(ptl1, i)
+#define GET_PTL3_ADDRESS(ptl2, i)   GET_PTL3_ADDRESS_ARCH(ptl2, i)
+#define GET_FRAME_ADDRESS(ptl3, i)  GET_FRAME_ADDRESS_ARCH(ptl3, i)
 
 /*
  * These macros are provided to change the shape of the 4-level tree of page
  * tables on respective level.
+ *
  */
-#define SET_PTL1_ADDRESS(ptl0, i, a)	SET_PTL1_ADDRESS_ARCH(ptl0, i, a)
-#define SET_PTL2_ADDRESS(ptl1, i, a)	SET_PTL2_ADDRESS_ARCH(ptl1, i, a)
-#define SET_PTL3_ADDRESS(ptl2, i, a)	SET_PTL3_ADDRESS_ARCH(ptl2, i, a)
-#define SET_FRAME_ADDRESS(ptl3, i, a)	SET_FRAME_ADDRESS_ARCH(ptl3, i, a)
+#define SET_PTL1_ADDRESS(ptl0, i, a)   SET_PTL1_ADDRESS_ARCH(ptl0, i, a)
+#define SET_PTL2_ADDRESS(ptl1, i, a)   SET_PTL2_ADDRESS_ARCH(ptl1, i, a)
+#define SET_PTL3_ADDRESS(ptl2, i, a)   SET_PTL3_ADDRESS_ARCH(ptl2, i, a)
+#define SET_FRAME_ADDRESS(ptl3, i, a)  SET_FRAME_ADDRESS_ARCH(ptl3, i, a)
 
 /*
  * These macros are provided to query various flags within the page tables.
+ *
  */
-#define GET_PTL1_FLAGS(ptl0, i)		GET_PTL1_FLAGS_ARCH(ptl0, i)
-#define GET_PTL2_FLAGS(ptl1, i)		GET_PTL2_FLAGS_ARCH(ptl1, i)
-#define GET_PTL3_FLAGS(ptl2, i)		GET_PTL3_FLAGS_ARCH(ptl2, i)
-#define GET_FRAME_FLAGS(ptl3, i)	GET_FRAME_FLAGS_ARCH(ptl3, i)
+#define GET_PTL1_FLAGS(ptl0, i)   GET_PTL1_FLAGS_ARCH(ptl0, i)
+#define GET_PTL2_FLAGS(ptl1, i)   GET_PTL2_FLAGS_ARCH(ptl1, i)
+#define GET_PTL3_FLAGS(ptl2, i)   GET_PTL3_FLAGS_ARCH(ptl2, i)
+#define GET_FRAME_FLAGS(ptl3, i)  GET_FRAME_FLAGS_ARCH(ptl3, i)
 
 /*
  * These macros are provided to set/clear various flags within the page tables.
+ *
  */
-#define SET_PTL1_FLAGS(ptl0, i, x)	SET_PTL1_FLAGS_ARCH(ptl0, i, x)
-#define SET_PTL2_FLAGS(ptl1, i, x)	SET_PTL2_FLAGS_ARCH(ptl1, i, x)
-#define SET_PTL3_FLAGS(ptl2, i, x)	SET_PTL3_FLAGS_ARCH(ptl2, i, x)
-#define SET_FRAME_FLAGS(ptl3, i, x)	SET_FRAME_FLAGS_ARCH(ptl3, i, x)
+#define SET_PTL1_FLAGS(ptl0, i, x)   SET_PTL1_FLAGS_ARCH(ptl0, i, x)
+#define SET_PTL2_FLAGS(ptl1, i, x)   SET_PTL2_FLAGS_ARCH(ptl1, i, x)
+#define SET_PTL3_FLAGS(ptl2, i, x)   SET_PTL3_FLAGS_ARCH(ptl2, i, x)
+#define SET_FRAME_FLAGS(ptl3, i, x)  SET_FRAME_FLAGS_ARCH(ptl3, i, x)
 
 /*
  * Macros for querying the last-level PTEs.
+ *
  */
-#define PTE_VALID(p)		PTE_VALID_ARCH((p))
-#define PTE_PRESENT(p)		PTE_PRESENT_ARCH((p))
-#define PTE_GET_FRAME(p)	PTE_GET_FRAME_ARCH((p))
-#define PTE_READABLE(p)		1
-#define PTE_WRITABLE(p)		PTE_WRITABLE_ARCH((p))
-#define PTE_EXECUTABLE(p)	PTE_EXECUTABLE_ARCH((p))
+#define PTE_VALID(p)       PTE_VALID_ARCH((p))
+#define PTE_PRESENT(p)     PTE_PRESENT_ARCH((p))
+#define PTE_GET_FRAME(p)   PTE_GET_FRAME_ARCH((p))
+#define PTE_READABLE(p)    1
+#define PTE_WRITABLE(p)    PTE_WRITABLE_ARCH((p))
+#define PTE_EXECUTABLE(p)  PTE_EXECUTABLE_ARCH((p))
 
 extern as_operations_t as_pt_operations;
 extern page_mapping_operations_t pt_mapping_operations;
 
-extern void page_mapping_insert_pt(as_t *as, uintptr_t page, uintptr_t frame,
-    int flags);
-extern pte_t *page_mapping_find_pt(as_t *as, uintptr_t page);
+extern void page_mapping_insert_pt(as_t *, uintptr_t, uintptr_t, unsigned int);
+extern pte_t *page_mapping_find_pt(as_t *, uintptr_t);
 
 #endif
Index: kernel/genarch/src/acpi/acpi.c
===================================================================
--- kernel/genarch/src/acpi/acpi.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/genarch/src/acpi/acpi.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -33,7 +33,7 @@
 /**
  * @file
- * @brief	Advanced Configuration and Power Interface (ACPI) initialization.
- */
- 
+ * @brief Advanced Configuration and Power Interface (ACPI) initialization.
+ */
+
 #include <genarch/acpi/acpi.h>
 #include <genarch/acpi/madt.h>
@@ -43,6 +43,6 @@
 #include <print.h>
 
-#define RSDP_SIGNATURE		"RSD PTR "
-#define RSDP_REVISION_OFFS	15
+#define RSDP_SIGNATURE      "RSD PTR "
+#define RSDP_REVISION_OFFS  15
 
 #define CMP_SIGNATURE(left, right) \
@@ -64,61 +64,68 @@
 };
 
-static int rsdp_check(uint8_t *rsdp) {
-	struct acpi_rsdp *r = (struct acpi_rsdp *) rsdp;
+static int rsdp_check(uint8_t *_rsdp) {
+	struct acpi_rsdp *rsdp = (struct acpi_rsdp *) _rsdp;
+	uint8_t sum = 0;
+	uint32_t i;
+	
+	for (i = 0; i < 20; i++)
+		sum = (uint8_t) (sum + _rsdp[i]);
+	
+	if (sum)
+		return 0; /* bad checksum */
+	
+	if (rsdp->revision == 0)
+		return 1; /* ACPI 1.0 */
+	
+	for (; i < rsdp->length; i++)
+		sum = (uint8_t) (sum + _rsdp[i]);
+	
+	return !sum;
+}
+
+int acpi_sdt_check(uint8_t *sdt)
+{
+	struct acpi_sdt_header *hdr = (struct acpi_sdt_header *) sdt;
 	uint8_t sum = 0;
 	unsigned int i;
 	
-	for (i = 0; i < 20; i++)
-		sum = (uint8_t) (sum + rsdp[i]);
-		
-	if (sum)	
-		return 0; /* bad checksum */
-
-	if (r->revision == 0)
-		return 1; /* ACPI 1.0 */
-		
-	for (; i < r->length; i++)
-		sum = (uint8_t) (sum + rsdp[i]);
-		
+	for (i = 0; i < hdr->length; i++)
+		sum = (uint8_t) (sum + sdt[i]);
+	
 	return !sum;
-	
-}
-
-int acpi_sdt_check(uint8_t *sdt)
-{
-	struct acpi_sdt_header *h = (struct acpi_sdt_header *) sdt;
-	uint8_t sum = 0;
-	unsigned int i;
-
-	for (i = 0; i < h->length; i++)
-		sum = (uint8_t) (sum + sdt[i]);
-		
-	return !sum;
 }
 
 static void map_sdt(struct acpi_sdt_header *sdt)
 {
-	page_mapping_insert(AS_KERNEL, (uintptr_t) sdt, (uintptr_t) sdt, PAGE_NOT_CACHEABLE | PAGE_WRITE);
+	page_table_lock(AS_KERNEL, true);
+	page_mapping_insert(AS_KERNEL, (uintptr_t) sdt, (uintptr_t) sdt,
+	    PAGE_NOT_CACHEABLE | PAGE_WRITE);
 	map_structure((uintptr_t) sdt, sdt->length);
+	page_table_unlock(AS_KERNEL, true);
 }
 
 static void configure_via_rsdt(void)
 {
-	unsigned int i, j, cnt = (acpi_rsdt->header.length - sizeof(struct acpi_sdt_header)) / sizeof(uint32_t);
+	size_t i;
+	size_t j;
+	size_t cnt = (acpi_rsdt->header.length - sizeof(struct acpi_sdt_header))
+	    / sizeof(uint32_t);
 	
 	for (i = 0; i < cnt; i++) {
-		for (j = 0; j < sizeof(signature_map) / sizeof(struct acpi_signature_map); j++) {
-			struct acpi_sdt_header *h = (struct acpi_sdt_header *) (unative_t) acpi_rsdt->entry[i];
-		
-			map_sdt(h);
-			if (CMP_SIGNATURE(h->signature, signature_map[j].signature)) {
-				if (!acpi_sdt_check((uint8_t *) h))
-					goto next;
-				*signature_map[j].sdt_ptr = h;
-				LOG("%p: ACPI %s\n", *signature_map[j].sdt_ptr, signature_map[j].description);
+		for (j = 0; j < sizeof(signature_map)
+		    / sizeof(struct acpi_signature_map); j++) {
+			struct acpi_sdt_header *hdr =
+			    (struct acpi_sdt_header *) (unative_t) acpi_rsdt->entry[i];
+			
+			map_sdt(hdr);
+			if (CMP_SIGNATURE(hdr->signature, signature_map[j].signature)) {
+				if (!acpi_sdt_check((uint8_t *) hdr))
+					break;
+				
+				*signature_map[j].sdt_ptr = hdr;
+				LOG("%p: ACPI %s", *signature_map[j].sdt_ptr,
+				    signature_map[j].description);
 			}
 		}
-next:
-		;
 	}
 }
@@ -126,22 +133,26 @@
 static void configure_via_xsdt(void)
 {
-	unsigned int i, j, cnt = (acpi_xsdt->header.length - sizeof(struct acpi_sdt_header)) / sizeof(uint64_t);
+	size_t i;
+	size_t j;
+	size_t cnt = (acpi_xsdt->header.length - sizeof(struct acpi_sdt_header))
+	    / sizeof(uint64_t);
 	
 	for (i = 0; i < cnt; i++) {
-		for (j = 0; j < sizeof(signature_map) / sizeof(struct acpi_signature_map); j++) {
-			struct acpi_sdt_header *h = (struct acpi_sdt_header *) ((uintptr_t) acpi_rsdt->entry[i]);
-
-			map_sdt(h);
-			if (CMP_SIGNATURE(h->signature, signature_map[j].signature)) {
-				if (!acpi_sdt_check((uint8_t *) h))
-					goto next;
-				*signature_map[j].sdt_ptr = h;
-				LOG("%p: ACPI %s\n", *signature_map[j].sdt_ptr, signature_map[j].description);
+		for (j = 0; j < sizeof(signature_map)
+		    / sizeof(struct acpi_signature_map); j++) {
+			struct acpi_sdt_header *hdr =
+			    (struct acpi_sdt_header *) ((uintptr_t) acpi_xsdt->entry[i]);
+			
+			map_sdt(hdr);
+			if (CMP_SIGNATURE(hdr->signature, signature_map[j].signature)) {
+				if (!acpi_sdt_check((uint8_t *) hdr))
+					break;
+				
+				*signature_map[j].sdt_ptr = hdr;
+				LOG("%p: ACPI %s", *signature_map[j].sdt_ptr,
+				    signature_map[j].description);
 			}
 		}
-next:
-		;
-	}
-
+	}
 }
 
@@ -149,7 +160,9 @@
 {
 	uint8_t *addr[2] = { NULL, (uint8_t *) PA2KA(0xe0000) };
-	int i, j, length[2] = { 1024, 128*1024 };
+	unsigned int i;
+	unsigned int j;
+	unsigned int length[2] = { 1024, 128 * 1024 };
 	uint64_t *sig = (uint64_t *) RSDP_SIGNATURE;
-
+	
 	/*
 	 * Find Root System Description Pointer
@@ -157,9 +170,10 @@
 	 * 2. search 128K starting at 0xe0000
 	 */
-
+	
 	addr[0] = (uint8_t *) PA2KA(ebda);
 	for (i = (ebda ? 0 : 1); i < 2; i++) {
 		for (j = 0; j < length[i]; j += 16) {
-			if (*((uint64_t *) &addr[i][j]) == *sig && rsdp_check(&addr[i][j])) {
+			if ((*((uint64_t *) &addr[i][j]) == *sig)
+			    && (rsdp_check(&addr[i][j]))) {
 				acpi_rsdp = (struct acpi_rsdp *) &addr[i][j];
 				goto rsdp_found;
@@ -167,33 +181,34 @@
 		}
 	}
-
+	
 	return;
-
+	
 rsdp_found:
-	LOG("%p: ACPI Root System Description Pointer\n", acpi_rsdp);
-
-	acpi_rsdt = (struct acpi_rsdt *) (unative_t) acpi_rsdp->rsdt_address;
+	LOG("%p: ACPI Root System Description Pointer", acpi_rsdp);
+	
+	acpi_rsdt = (struct acpi_rsdt *) ((uintptr_t) acpi_rsdp->rsdt_address);
 	if (acpi_rsdp->revision)
 		acpi_xsdt = (struct acpi_xsdt *) ((uintptr_t) acpi_rsdp->xsdt_address);
-
+	
 	if (acpi_rsdt)
 		map_sdt((struct acpi_sdt_header *) acpi_rsdt);
+	
 	if (acpi_xsdt)
 		map_sdt((struct acpi_sdt_header *) acpi_xsdt);
-
-	if (acpi_rsdt && !acpi_sdt_check((uint8_t *) acpi_rsdt)) {
+	
+	if ((acpi_rsdt) && (!acpi_sdt_check((uint8_t *) acpi_rsdt))) {
 		printf("RSDT: bad checksum\n");
 		return;
 	}
-	if (acpi_xsdt && !acpi_sdt_check((uint8_t *) acpi_xsdt)) {
+	
+	if ((acpi_xsdt) && (!acpi_sdt_check((uint8_t *) acpi_xsdt))) {
 		printf("XSDT: bad checksum\n");
 		return;
 	}
-
+	
 	if (acpi_xsdt)
 		configure_via_xsdt();
 	else if (acpi_rsdt)
 		configure_via_rsdt();
-
 }
 
Index: kernel/genarch/src/acpi/madt.c
===================================================================
--- kernel/genarch/src/acpi/madt.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/genarch/src/acpi/madt.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -27,10 +27,10 @@
  */
 
-/** @addtogroup genarch	
+/** @addtogroup genarch
  * @{
  */
 /**
  * @file
- * @brief	Multiple APIC Description Table (MADT) parsing.
+ * @brief Multiple APIC Description Table (MADT) parsing.
  */
 
@@ -52,23 +52,20 @@
 #ifdef CONFIG_SMP
 
-/** Standard ISA IRQ map; can be overriden by Interrupt Source Override entries of MADT. */
-int isa_irq_map[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
-
-static void madt_l_apic_entry(struct madt_l_apic *la, uint32_t index);
-static void madt_io_apic_entry(struct madt_io_apic *ioa, uint32_t index);
-static void madt_intr_src_ovrd_entry(struct madt_intr_src_ovrd *override, uint32_t index);
-static int madt_cmp(void * a, void * b);
+/**
+ * Standard ISA IRQ map; can be overriden by
+ * Interrupt Source Override entries of MADT.
+ */
+static int isa_irq_map[] =
+    { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
 
 struct madt_l_apic *madt_l_apic_entries = NULL;
 struct madt_io_apic *madt_io_apic_entries = NULL;
 
-size_t madt_l_apic_entry_index = 0;
-size_t madt_io_apic_entry_index = 0;
-size_t madt_l_apic_entry_cnt = 0;
-size_t madt_io_apic_entry_cnt = 0;
-size_t cpu_count = 0;
-
-struct madt_apic_header * * madt_entries_index = NULL;
-unsigned int madt_entries_index_cnt = 0;
+static size_t madt_l_apic_entry_index = 0;
+static size_t madt_io_apic_entry_index = 0;
+static size_t madt_l_apic_entry_cnt = 0;
+static size_t madt_io_apic_entry_cnt = 0;
+
+static struct madt_apic_header **madt_entries_index = NULL;
 
 const char *entry[] = {
@@ -84,15 +81,48 @@
 };
 
-/*
- * ACPI MADT Implementation of SMP configuration interface.
- */
-static size_t madt_cpu_count(void);
-static bool madt_cpu_enabled(size_t i);
-static bool madt_cpu_bootstrap(size_t i);
-static uint8_t madt_cpu_apic_id(size_t i);
-static int madt_irq_to_pin(unsigned int irq);
-
+static uint8_t madt_cpu_apic_id(size_t i)
+{
+	ASSERT(i < madt_l_apic_entry_cnt);
+	
+	return ((struct madt_l_apic *)
+	    madt_entries_index[madt_l_apic_entry_index + i])->apic_id;
+}
+
+static bool madt_cpu_enabled(size_t i)
+{
+	ASSERT(i < madt_l_apic_entry_cnt);
+	
+	/*
+	 * FIXME: The current local APIC driver limits usable
+	 * CPU IDs to 8.
+	 *
+	 */
+	if (i > 7)
+		return false;
+	
+	return ((struct madt_l_apic *)
+	    madt_entries_index[madt_l_apic_entry_index + i])->flags & 0x1;
+}
+
+static bool madt_cpu_bootstrap(size_t i)
+{
+	ASSERT(i < madt_l_apic_entry_cnt);
+	
+	return ((struct madt_l_apic *)
+	    madt_entries_index[madt_l_apic_entry_index + i])->apic_id ==
+	    bsp_l_apic;
+}
+
+static int madt_irq_to_pin(unsigned int irq)
+{
+	ASSERT(irq < sizeof(isa_irq_map) / sizeof(int));
+	
+	return isa_irq_map[irq];
+}
+
+/** ACPI MADT Implementation of SMP configuration interface.
+ *
+ */
 struct smp_config_operations madt_config_operations = {
-	.cpu_count = madt_cpu_count,
 	.cpu_enabled = madt_cpu_enabled,
 	.cpu_bootstrap = madt_cpu_bootstrap,
@@ -101,114 +131,25 @@
 };
 
-size_t madt_cpu_count(void)
-{
-	return madt_l_apic_entry_cnt;
-}
-
-bool madt_cpu_enabled(size_t i)
-{
-	ASSERT(i < madt_l_apic_entry_cnt);
-	return ((struct madt_l_apic *) madt_entries_index[madt_l_apic_entry_index + i])->flags & 0x1;
-
-}
-
-bool madt_cpu_bootstrap(size_t i)
-{
-	ASSERT(i < madt_l_apic_entry_cnt);
-	return ((struct madt_l_apic *) madt_entries_index[madt_l_apic_entry_index + i])->apic_id == l_apic_id();
-}
-
-uint8_t madt_cpu_apic_id(size_t i)
-{
-	ASSERT(i < madt_l_apic_entry_cnt);
-	return ((struct madt_l_apic *) madt_entries_index[madt_l_apic_entry_index + i])->apic_id;
-}
-
-int madt_irq_to_pin(unsigned int irq)
-{
-	ASSERT(irq < sizeof(isa_irq_map) / sizeof(int));
-        return isa_irq_map[irq];
-}
-
-int madt_cmp(void * a, void * b) 
-{
-	return 
-		(((struct madt_apic_header *) a)->type > ((struct madt_apic_header *) b)->type) ?
-		1 : 
-		((((struct madt_apic_header *) a)->type < ((struct madt_apic_header *) b)->type) ? -1 : 0);
-}
-	
-void acpi_madt_parse(void)
-{
-	struct madt_apic_header *end = (struct madt_apic_header *) (((uint8_t *) acpi_madt) + acpi_madt->header.length);
-	struct madt_apic_header *h;
-	
-	l_apic = (uint32_t *) (unative_t) acpi_madt->l_apic_address;
-
-	/* calculate madt entries */
-	for (h = &acpi_madt->apic_header[0]; h < end; h = (struct madt_apic_header *) (((uint8_t *) h) + h->length)) {
-		madt_entries_index_cnt++;
-	}
-
-	/* create madt apic entries index array */
-	madt_entries_index = (struct madt_apic_header * *) malloc(madt_entries_index_cnt * sizeof(struct madt_apic_header * *), FRAME_ATOMIC);
-	if (!madt_entries_index)
-		panic("Memory allocation error.");
-
-	uint32_t index = 0;
-
-	for (h = &acpi_madt->apic_header[0]; h < end; h = (struct madt_apic_header *) (((uint8_t *) h) + h->length)) {
-		madt_entries_index[index++] = h;
-	}
-
-	/* Quicksort MADT index structure */
-	qsort(madt_entries_index, madt_entries_index_cnt, sizeof(uintptr_t), &madt_cmp);
-
-	/* Parse MADT entries */
-	if (madt_entries_index_cnt > 0) {	
-		for (index = 0; index < madt_entries_index_cnt - 1; index++) {
-			h = madt_entries_index[index];
-			switch (h->type) {
-				case MADT_L_APIC:
-					madt_l_apic_entry((struct madt_l_apic *) h, index);
-					break;
-				case MADT_IO_APIC:
-					madt_io_apic_entry((struct madt_io_apic *) h, index);
-					break;
-				case MADT_INTR_SRC_OVRD:
-					madt_intr_src_ovrd_entry((struct madt_intr_src_ovrd *) h, index);
-					break;
-				case MADT_NMI_SRC:
-				case MADT_L_APIC_NMI:
-				case MADT_L_APIC_ADDR_OVRD:
-				case MADT_IO_SAPIC:
-				case MADT_L_SAPIC:
-				case MADT_PLATFORM_INTR_SRC:
-					printf("MADT: skipping %s entry (type=%" PRIu8 ")\n", entry[h->type], h->type);
-					break;
-	
-				default:
-					if (h->type >= MADT_RESERVED_SKIP_BEGIN && h->type <= MADT_RESERVED_SKIP_END) {
-						printf("MADT: skipping reserved entry (type=%" PRIu8 ")\n", h->type);
-					}
-					if (h->type >= MADT_RESERVED_OEM_BEGIN) {
-						printf("MADT: skipping OEM entry (type=%" PRIu8 ")\n", h->type);
-					}
-					break;
-			}
-		}
-	}
-
-	if (cpu_count)
-		config.cpu_count = cpu_count;
-}
- 
-
-void madt_l_apic_entry(struct madt_l_apic *la, uint32_t index)
-{
-	if (!madt_l_apic_entry_cnt++) {
-		madt_l_apic_entry_index = index;
-	}
-		
+static int madt_cmp(void *a, void *b, void *arg)
+{
+	uint8_t typea = (*((struct madt_apic_header **) a))->type;
+	uint8_t typeb = (*((struct madt_apic_header **) b))->type;
+	
+	if (typea > typeb)
+		return 1;
+	
+	if (typea < typeb)
+		return -1;
+	
+	return 0;
+}
+
+static void madt_l_apic_entry(struct madt_l_apic *la, size_t i)
+{
+	if (madt_l_apic_entry_cnt == 0)
+		madt_l_apic_entry_index = i;
+	
+	madt_l_apic_entry_cnt++;
+	
 	if (!(la->flags & 0x1)) {
 		/* Processor is unusable, skip it. */
@@ -216,26 +157,104 @@
 	}
 	
-	cpu_count++;	
-	apic_id_mask |= 1<<la->apic_id;
-}
-
-void madt_io_apic_entry(struct madt_io_apic *ioa, uint32_t index)
-{
-	if (!madt_io_apic_entry_cnt++) {
-		/* remember index of the first io apic entry */
-		madt_io_apic_entry_index = index;
+	apic_id_mask |= 1 << la->apic_id;
+}
+
+static void madt_io_apic_entry(struct madt_io_apic *ioa, size_t i)
+{
+	if (madt_io_apic_entry_cnt == 0) {
+		/* Remember index of the first io apic entry */
+		madt_io_apic_entry_index = i;
 		io_apic = (uint32_t *) (unative_t) ioa->io_apic_address;
 	} else {
-		/* currently not supported */
-		return;
-	}
-}
-
-void madt_intr_src_ovrd_entry(struct madt_intr_src_ovrd *override, uint32_t index)
+		/* Currently not supported */
+	}
+	
+	madt_io_apic_entry_cnt++;
+}
+
+static void madt_intr_src_ovrd_entry(struct madt_intr_src_ovrd *override,
+    size_t i)
 {
 	ASSERT(override->source < sizeof(isa_irq_map) / sizeof(int));
-	printf("MADT: ignoring %s entry: bus=%" PRIu8 ", source=%" PRIu8 ", global_int=%" PRIu32 ", flags=%#" PRIx16 "\n",
-		entry[override->header.type], override->bus, override->source,
-		override->global_int, override->flags);
+	
+	printf("MADT: Ignoring %s entry: bus=%" PRIu8 ", source=%" PRIu8
+	    ", global_int=%" PRIu32 ", flags=%#" PRIx16 "\n",
+	    entry[override->header.type], override->bus, override->source,
+	    override->global_int, override->flags);
+}
+
+void acpi_madt_parse(void)
+{
+	struct madt_apic_header *end = (struct madt_apic_header *)
+	    (((uint8_t *) acpi_madt) + acpi_madt->header.length);
+	struct madt_apic_header *hdr;
+	
+	l_apic = (uint32_t *) (unative_t) acpi_madt->l_apic_address;
+	
+	/* Count MADT entries */
+	unsigned int madt_entries_index_cnt = 0;
+	for (hdr = acpi_madt->apic_header; hdr < end;
+	    hdr = (struct madt_apic_header *) (((uint8_t *) hdr) + hdr->length))
+		madt_entries_index_cnt++;
+	
+	/* Create MADT APIC entries index array */
+	madt_entries_index = (struct madt_apic_header **)
+	    malloc(madt_entries_index_cnt * sizeof(struct madt_apic_header *),
+	    FRAME_ATOMIC);
+	if (!madt_entries_index)
+		panic("Memory allocation error.");
+	
+	size_t i = 0;
+	
+	for (hdr = acpi_madt->apic_header; hdr < end;
+	    hdr = (struct madt_apic_header *) (((uint8_t *) hdr) + hdr->length)) {
+		madt_entries_index[i] = hdr;
+		i++;
+	}
+	
+	/* Sort MADT index structure */
+	if (!gsort(madt_entries_index, madt_entries_index_cnt,
+	    sizeof(struct madt_apic_header *), madt_cmp, NULL))
+		panic("Sorting error.");
+	
+	/* Parse MADT entries */
+	for (i = 0; i < madt_entries_index_cnt; i++) {
+		hdr = madt_entries_index[i];
+		
+		switch (hdr->type) {
+		case MADT_L_APIC:
+			madt_l_apic_entry((struct madt_l_apic *) hdr, i);
+			break;
+		case MADT_IO_APIC:
+			madt_io_apic_entry((struct madt_io_apic *) hdr, i);
+		break;
+		case MADT_INTR_SRC_OVRD:
+			madt_intr_src_ovrd_entry((struct madt_intr_src_ovrd *) hdr, i);
+			break;
+		case MADT_NMI_SRC:
+		case MADT_L_APIC_NMI:
+		case MADT_L_APIC_ADDR_OVRD:
+		case MADT_IO_SAPIC:
+		case MADT_L_SAPIC:
+		case MADT_PLATFORM_INTR_SRC:
+			printf("MADT: Skipping %s entry (type=%" PRIu8 ")\n",
+			    entry[hdr->type], hdr->type);
+			break;
+		default:
+			if ((hdr->type >= MADT_RESERVED_SKIP_BEGIN)
+			    && (hdr->type <= MADT_RESERVED_SKIP_END))
+				printf("MADT: Skipping reserved entry (type=%" PRIu8 ")\n",
+				    hdr->type);
+				
+			if (hdr->type >= MADT_RESERVED_OEM_BEGIN)
+				printf("MADT: Skipping OEM entry (type=%" PRIu8 ")\n",
+				    hdr->type);
+			
+			break;
+		}
+	}
+	
+	if (madt_l_apic_entry_cnt > 0)
+		config.cpu_count = madt_l_apic_entry_cnt;
 }
 
Index: kernel/genarch/src/drivers/ega/ega.c
===================================================================
--- kernel/genarch/src/drivers/ega/ega.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/genarch/src/drivers/ega/ega.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -63,5 +63,5 @@
 
 typedef struct {
-	SPINLOCK_DECLARE(lock);
+	IRQ_SPINLOCK_DECLARE(lock);
 	
 	uint32_t cursor;
@@ -71,6 +71,6 @@
 } ega_instance_t;
 
-static void ega_putchar(outdev_t *dev, wchar_t ch, bool silent);
-static void ega_redraw(outdev_t *dev);
+static void ega_putchar(outdev_t *, wchar_t, bool);
+static void ega_redraw(outdev_t *);
 
 static outdev_operations_t egadev_ops = {
@@ -540,6 +540,5 @@
 	ega_instance_t *instance = (ega_instance_t *) dev->data;
 	
-	ipl_t ipl = interrupts_disable();
-	spinlock_lock(&instance->lock);
+	irq_spinlock_lock(&instance->lock, true);
 	
 	switch (ch) {
@@ -564,6 +563,5 @@
 	ega_move_cursor(instance, silent);
 	
-	spinlock_unlock(&instance->lock);
-	interrupts_restore(ipl);
+	irq_spinlock_unlock(&instance->lock, true);
 }
 
@@ -572,6 +570,5 @@
 	ega_instance_t *instance = (ega_instance_t *) dev->data;
 	
-	ipl_t ipl = interrupts_disable();
-	spinlock_lock(&instance->lock);
+	irq_spinlock_lock(&instance->lock, true);
 	
 	memcpy(instance->addr, instance->backbuf, EGA_VRAM_SIZE);
@@ -579,6 +576,5 @@
 	ega_show_cursor(instance, silent);
 	
-	spinlock_unlock(&instance->lock);
-	interrupts_restore(ipl);
+	irq_spinlock_unlock(&instance->lock, true);
 }
 
@@ -598,5 +594,5 @@
 	egadev->data = instance;
 	
-	spinlock_initialize(&instance->lock, "*ega_lock");
+	irq_spinlock_initialize(&instance->lock, "*ega.instance.lock");
 	
 	instance->base = base;
Index: kernel/genarch/src/drivers/s3c24xx_irqc/s3c24xx_irqc.c
===================================================================
--- kernel/genarch/src/drivers/s3c24xx_irqc/s3c24xx_irqc.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
+++ kernel/genarch/src/drivers/s3c24xx_irqc/s3c24xx_irqc.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -0,0 +1,141 @@
+/*
+ * 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
+ * @brief Samsung S3C24xx on-chip interrupt controller.
+ *
+ * This IRQC is present on the Samsung S3C24xx CPU (on the gta02 platform).
+ */
+
+#include <genarch/drivers/s3c24xx_irqc/s3c24xx_irqc.h>
+#include <arch/asm.h>
+
+/** Correspondence between interrupt sources and sub-sources. */
+static unsigned s3c24xx_subsrc_src[][2] = {
+	{ S3C24XX_SUBINT_CAM_P, S3C24XX_INT_CAM },
+	{ S3C24XX_SUBINT_CAM_C, S3C24XX_INT_CAM },
+	{ S3C24XX_SUBINT_ADC_S, S3C24XX_INT_ADC },
+	{ S3C24XX_SUBINT_TC, S3C24XX_INT_ADC },
+	{ S3C24XX_SUBINT_ERR2, S3C24XX_INT_UART2 },
+	{ S3C24XX_SUBINT_TXD2, S3C24XX_INT_UART2 },
+	{ S3C24XX_SUBINT_RXD2, S3C24XX_INT_UART2 },
+	{ S3C24XX_SUBINT_ERR1, S3C24XX_INT_UART1 },
+	{ S3C24XX_SUBINT_TXD1, S3C24XX_INT_UART1 },
+	{ S3C24XX_SUBINT_RXD1, S3C24XX_INT_UART1 },
+	{ S3C24XX_SUBINT_ERR0, S3C24XX_INT_UART0 },
+	{ S3C24XX_SUBINT_TXD0, S3C24XX_INT_UART0 },
+	{ S3C24XX_SUBINT_RXD0, S3C24XX_INT_UART0 }
+};
+
+/** Initialize S3C24xx interrupt controller.
+ *
+ * @param irqc	Instance structure
+ * @param regs	Register I/O structure
+ */
+void s3c24xx_irqc_init(s3c24xx_irqc_t *irqc, s3c24xx_irqc_regs_t *regs)
+{
+	irqc->regs = regs;
+
+	/* Make all interrupt sources use IRQ mode (not FIQ). */
+	pio_write_32(&regs->intmod, 0x00000000);
+
+	/* Disable all interrupt sources. */
+	pio_write_32(&regs->intmsk, 0xffffffff);
+
+	/* Disable interrupts from all sub-sources. */
+	pio_write_32(&regs->intsubmsk, 0xffffffff);
+}
+
+/** Obtain number of pending interrupt. */
+unsigned s3c24xx_irqc_inum_get(s3c24xx_irqc_t *irqc)
+{
+	return pio_read_32(&irqc->regs->intoffset);
+}
+
+/** Clear pending interrupt condition including sub-sources.
+ *
+ * Clear source and interrupt pending condition and also automatically clear
+ * any sub-source pending condition pertaining to the source.
+ */
+void s3c24xx_irqc_clear(s3c24xx_irqc_t *irqc, unsigned inum)
+{
+	unsigned src, subsrc;
+	unsigned entries, i;
+
+	entries = sizeof(s3c24xx_subsrc_src) / sizeof(s3c24xx_subsrc_src[0]);
+
+	for (i = 0; i < entries; i++) {
+		subsrc = s3c24xx_subsrc_src[i][0];
+		src = s3c24xx_subsrc_src[i][1];
+
+		if (src == inum) {
+			pio_write_32(&irqc->regs->subsrcpnd,
+			    S3C24XX_SUBINT_BIT(subsrc));
+		}
+	}
+
+	pio_write_32(&irqc->regs->srcpnd, S3C24XX_INT_BIT(inum));
+	pio_write_32(&irqc->regs->intpnd, S3C24XX_INT_BIT(inum));
+}
+
+/** Enable interrupts from the specified source. */
+void s3c24xx_irqc_src_enable(s3c24xx_irqc_t *irqc, unsigned src)
+{
+	pio_write_32(&irqc->regs->intmsk, pio_read_32(&irqc->regs->intmsk) &
+	    ~S3C24XX_INT_BIT(src));
+}
+
+/** Disable interrupts from the specified source. */
+void s3c24xx_irqc_src_disable(s3c24xx_irqc_t *irqc, unsigned src)
+{
+	pio_write_32(&irqc->regs->intmsk, pio_read_32(&irqc->regs->intmsk) |
+	    S3C24XX_INT_BIT(src));
+}
+
+/** Enable interrupts from the specified sub-source. */
+void s3c24xx_irqc_subsrc_enable(s3c24xx_irqc_t *irqc, unsigned subsrc)
+{
+	pio_write_32(&irqc->regs->intsubmsk,
+	    pio_read_32(&irqc->regs->intsubmsk) &
+	    ~S3C24XX_SUBINT_BIT(subsrc));
+}
+
+/** Disable interrupts from the specified sub-source. */
+void s3c24xx_irqc_subsrc_disable(s3c24xx_irqc_t *irqc, unsigned subsrc)
+{
+	pio_write_32(&irqc->regs->intsubmsk,
+	    pio_read_32(&irqc->regs->intsubmsk) |
+	    S3C24XX_SUBINT_BIT(subsrc));
+}
+
+/** @}
+ */
Index: kernel/genarch/src/drivers/s3c24xx_uart/s3c24xx_uart.c
===================================================================
--- kernel/genarch/src/drivers/s3c24xx_uart/s3c24xx_uart.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
+++ kernel/genarch/src/drivers/s3c24xx_uart/s3c24xx_uart.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -0,0 +1,155 @@
+/*
+ * Copyright (c) 2009 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
+ * @brief Samsung S3C24xx on-chip UART driver.
+ *
+ * This UART is present on the Samsung S3C24xx CPU (on the gta02 platform).
+ */
+
+#include <genarch/drivers/s3c24xx_uart/s3c24xx_uart.h>
+#include <console/chardev.h>
+#include <console/console.h>
+#include <ddi/device.h>
+#include <arch/asm.h>
+#include <mm/slab.h>
+#include <sysinfo/sysinfo.h>
+#include <str.h>
+
+static void s3c24xx_uart_sendb(outdev_t *dev, uint8_t byte)
+{
+	s3c24xx_uart_t *uart =
+	    (s3c24xx_uart_t *) dev->data;
+
+	/* Wait for space becoming available in Tx FIFO. */
+	while ((pio_read_32(&uart->io->ufstat) & S3C24XX_UFSTAT_TX_FULL) != 0)
+		;
+
+	pio_write_32(&uart->io->utxh, byte);
+}
+
+static void s3c24xx_uart_putchar(outdev_t *dev, wchar_t ch, bool silent)
+{
+	if (!silent) {
+		if (!ascii_check(ch)) {
+			s3c24xx_uart_sendb(dev, U_SPECIAL);
+		} else {
+    			if (ch == '\n')
+				s3c24xx_uart_sendb(dev, (uint8_t) '\r');
+			s3c24xx_uart_sendb(dev, (uint8_t) ch);
+		}
+	}
+}
+
+static irq_ownership_t s3c24xx_uart_claim(irq_t *irq)
+{
+	return IRQ_ACCEPT;
+}
+
+static void s3c24xx_uart_irq_handler(irq_t *irq)
+{
+	s3c24xx_uart_t *uart = irq->instance;
+
+	while ((pio_read_32(&uart->io->ufstat) & S3C24XX_UFSTAT_RX_COUNT) != 0) {
+		uint32_t data = pio_read_32(&uart->io->urxh);
+		pio_read_32(&uart->io->uerstat);
+		indev_push_character(uart->indev, data & 0xff);
+	}
+}
+
+static outdev_operations_t s3c24xx_uart_ops = {
+	.write = s3c24xx_uart_putchar,
+	.redraw = NULL
+};
+
+outdev_t *s3c24xx_uart_init(s3c24xx_uart_io_t *io, inr_t inr)
+{
+	outdev_t *uart_dev = malloc(sizeof(outdev_t), FRAME_ATOMIC);
+	if (!uart_dev)
+		return NULL;
+
+	s3c24xx_uart_t *uart =
+	    malloc(sizeof(s3c24xx_uart_t), FRAME_ATOMIC);
+	if (!uart) {
+		free(uart_dev);
+		return NULL;
+	}
+
+	outdev_initialize("s3c24xx_uart_dev", uart_dev, &s3c24xx_uart_ops);
+	uart_dev->data = uart;
+
+	uart->io = io;
+	uart->indev = NULL;
+
+	/* Initialize IRQ structure. */
+	irq_initialize(&uart->irq);
+	uart->irq.devno = device_assign_devno();
+	uart->irq.inr = inr;
+	uart->irq.claim = s3c24xx_uart_claim;
+	uart->irq.handler = s3c24xx_uart_irq_handler;
+	uart->irq.instance = uart;
+
+	/* Enable FIFO, Tx trigger level: empty, Rx trigger level: 1 byte. */
+	pio_write_32(&uart->io->ufcon, UFCON_FIFO_ENABLE |
+	    UFCON_TX_FIFO_TLEVEL_EMPTY | UFCON_RX_FIFO_TLEVEL_1B);
+
+	/* Set RX interrupt to pulse mode */
+	pio_write_32(&uart->io->ucon,
+	    pio_read_32(&uart->io->ucon) & ~UCON_RX_INT_LEVEL);
+
+	if (!fb_exported) {
+		/*
+		 * This is the necessary evil until the userspace driver is entirely
+		 * self-sufficient.
+		 */
+		sysinfo_set_item_val("fb", NULL, true);
+		sysinfo_set_item_val("fb.kind", NULL, 3);
+		sysinfo_set_item_val("fb.address.physical", NULL, KA2PA(io));
+
+		fb_exported = true;
+	}
+
+	return uart_dev;
+}
+
+void s3c24xx_uart_input_wire(s3c24xx_uart_t *uart, indev_t *indev)
+{
+	ASSERT(uart);
+	ASSERT(indev);
+
+	uart->indev = indev;
+	irq_register(&uart->irq);
+}
+
+/** @}
+ */
Index: kernel/genarch/src/drivers/via-cuda/cuda.c
===================================================================
--- kernel/genarch/src/drivers/via-cuda/cuda.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/genarch/src/drivers/via-cuda/cuda.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -99,5 +99,5 @@
 		instance->snd_bytes = 0;
 
-		spinlock_initialize(&instance->dev_lock, "cuda_dev");
+		spinlock_initialize(&instance->dev_lock, "cuda.instance.dev_lock");
 
 		/* Disable all interrupts from CUDA. */
Index: kernel/genarch/src/fb/fb.c
===================================================================
--- kernel/genarch/src/fb/fb.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/genarch/src/fb/fb.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -554,5 +554,5 @@
 	fbdev->data = instance;
 	
-	spinlock_initialize(&instance->lock, "*fb_lock");
+	spinlock_initialize(&instance->lock, "*fb.instance.lock");
 	instance->rgb_conv = rgb_conv;
 	instance->pixelbytes = pixelbytes;
Index: kernel/genarch/src/kbrd/kbrd.c
===================================================================
--- kernel/genarch/src/kbrd/kbrd.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/genarch/src/kbrd/kbrd.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -169,5 +169,5 @@
 		indev_initialize("kbrd", &instance->raw, &kbrd_raw_ops);
 		
-		spinlock_initialize(&instance->keylock, "instance_keylock");
+		spinlock_initialize(&instance->keylock, "kbrd.instance.keylock");
 		instance->keyflags = 0;
 		instance->lockflags = 0;
Index: kernel/genarch/src/kbrd/kbrd_pl050.c
===================================================================
--- kernel/genarch/src/kbrd/kbrd_pl050.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/genarch/src/kbrd/kbrd_pl050.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -181,5 +181,5 @@
 		indev_initialize("kbrd", &instance->raw, &kbrd_raw_ops);
 		
-		spinlock_initialize(&instance->keylock, "instance_keylock");
+		spinlock_initialize(&instance->keylock, "kbrd_pl050.instance.keylock");
 		instance->keyflags = 0;
 		instance->lockflags = 0;
Index: kernel/genarch/src/mm/as_ht.c
===================================================================
--- kernel/genarch/src/mm/as_ht.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/genarch/src/mm/as_ht.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -30,8 +30,8 @@
  * @{
  */
- 
+
 /**
  * @file
- * @brief	Address space functions for global page hash table.
+ * @brief Address space functions for global page hash table.
  */
 
@@ -46,9 +46,10 @@
 #include <synch/mutex.h>
 
-static pte_t *ht_create(int flags);
-static void ht_destroy(pte_t *page_table);
+static pte_t *ht_create(unsigned int);
+static void ht_destroy(pte_t *);
 
-static void ht_lock(as_t *as, bool lock);
-static void ht_unlock(as_t *as, bool unlock);
+static void ht_lock(as_t *, bool);
+static void ht_unlock(as_t *, bool);
+static bool ht_locked(as_t *);
 
 as_operations_t as_ht_operations = {
@@ -57,4 +58,5 @@
 	.page_table_lock = ht_lock,
 	.page_table_unlock = ht_unlock,
+	.page_table_locked = ht_locked,
 };
 
@@ -68,6 +70,7 @@
  *
  * @return Returns NULL.
+ *
  */
-pte_t *ht_create(int flags)
+pte_t *ht_create(unsigned int flags)
 {
 	if (flags & FLAG_AS_KERNEL) {
@@ -75,4 +78,5 @@
 		mutex_initialize(&page_ht_lock, MUTEX_PASSIVE);
 	}
+	
 	return NULL;
 }
@@ -83,4 +87,5 @@
  *
  * @param page_table This parameter is ignored.
+ *
  */
 void ht_destroy(pte_t *page_table)
@@ -94,6 +99,7 @@
  * Interrupts must be disabled.
  *
- * @param as Address space.
+ * @param as   Address space.
  * @param lock If false, do not attempt to lock the address space.
+ *
  */
 void ht_lock(as_t *as, bool lock)
@@ -101,4 +107,5 @@
 	if (lock)
 		mutex_lock(&as->lock);
+	
 	mutex_lock(&page_ht_lock);
 }
@@ -109,14 +116,28 @@
  * Interrupts must be disabled.
  *
- * @param as Address space.
+ * @param as     Address space.
  * @param unlock If false, do not attempt to lock the address space.
+ *
  */
 void ht_unlock(as_t *as, bool unlock)
 {
 	mutex_unlock(&page_ht_lock);
+	
 	if (unlock)
 		mutex_unlock(&as->lock);
 }
 
+/** Test whether page tables are locked.
+ *
+ * @param as		Address space where the page tables belong.
+ *
+ * @return		True if the page tables belonging to the address soace
+ *			are locked, otherwise false.
+ */
+bool ht_locked(as_t *as)
+{
+	return (mutex_locked(&page_ht_lock) && mutex_locked(&as->lock));
+}
+
 /** @}
  */
Index: kernel/genarch/src/mm/as_pt.c
===================================================================
--- kernel/genarch/src/mm/as_pt.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/genarch/src/mm/as_pt.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -33,5 +33,5 @@
 /**
  * @file
- * @brief	Address space functions for 4-level hierarchical pagetables.
+ * @brief Address space functions for 4-level hierarchical pagetables.
  */
 
@@ -47,9 +47,10 @@
 #include <arch.h>
 
-static pte_t *ptl0_create(int flags);
-static void ptl0_destroy(pte_t *page_table);
+static pte_t *ptl0_create(unsigned int);
+static void ptl0_destroy(pte_t *);
 
-static void pt_lock(as_t *as, bool lock);
-static void pt_unlock(as_t *as, bool unlock);
+static void pt_lock(as_t *, bool);
+static void pt_unlock(as_t *, bool);
+static bool pt_locked(as_t *);
 
 as_operations_t as_pt_operations = {
@@ -57,5 +58,6 @@
 	.page_table_destroy = ptl0_destroy,
 	.page_table_lock = pt_lock,
-	.page_table_unlock = pt_unlock
+	.page_table_unlock = pt_unlock,
+	.page_table_locked = pt_locked,
 };
 
@@ -67,36 +69,36 @@
  *
  * @return New PTL0.
+ *
  */
-pte_t *ptl0_create(int flags)
+pte_t *ptl0_create(unsigned int flags)
 {
-	pte_t *src_ptl0, *dst_ptl0;
-	ipl_t ipl;
-	int table_size;
-
-	dst_ptl0 = (pte_t *) frame_alloc(PTL0_SIZE, FRAME_KA);
-	table_size = FRAME_SIZE << PTL0_SIZE;
-
-	if (flags & FLAG_AS_KERNEL) {
+	pte_t *dst_ptl0 = (pte_t *) frame_alloc(PTL0_SIZE, FRAME_KA);
+	size_t table_size = FRAME_SIZE << PTL0_SIZE;
+	
+	if (flags & FLAG_AS_KERNEL)
 		memsetb(dst_ptl0, table_size, 0);
-	} else {
-		uintptr_t src, dst;
-	
+	else {
 		/*
 		 * Copy the kernel address space portion to new PTL0.
+		 *
 		 */
-		 
-		ipl = interrupts_disable();
-		mutex_lock(&AS_KERNEL->lock);		
-		src_ptl0 = (pte_t *) PA2KA((uintptr_t) AS_KERNEL->genarch.page_table);
-
-		src = (uintptr_t) &src_ptl0[PTL0_INDEX(KERNEL_ADDRESS_SPACE_START)];
-		dst = (uintptr_t) &dst_ptl0[PTL0_INDEX(KERNEL_ADDRESS_SPACE_START)];
-
+		
+		mutex_lock(&AS_KERNEL->lock);
+		
+		pte_t *src_ptl0 =
+		    (pte_t *) PA2KA((uintptr_t) AS_KERNEL->genarch.page_table);
+		
+		uintptr_t src =
+		    (uintptr_t) &src_ptl0[PTL0_INDEX(KERNEL_ADDRESS_SPACE_START)];
+		uintptr_t dst =
+		    (uintptr_t) &dst_ptl0[PTL0_INDEX(KERNEL_ADDRESS_SPACE_START)];
+		
 		memsetb(dst_ptl0, table_size, 0);
-		memcpy((void *) dst, (void *) src, table_size - (src - (uintptr_t) src_ptl0));
+		memcpy((void *) dst, (void *) src,
+		    table_size - (src - (uintptr_t) src_ptl0));
+		
 		mutex_unlock(&AS_KERNEL->lock);
-		interrupts_restore(ipl);
 	}
-
+	
 	return (pte_t *) KA2PA((uintptr_t) dst_ptl0);
 }
@@ -107,8 +109,9 @@
  *
  * @param page_table Physical address of PTL0.
+ *
  */
 void ptl0_destroy(pte_t *page_table)
 {
-	frame_free((uintptr_t)page_table);
+	frame_free((uintptr_t) page_table);
 }
 
@@ -118,6 +121,7 @@
  * Interrupts must be disabled.
  *
- * @param as Address space.
+ * @param as   Address space.
  * @param lock If false, do not attempt to lock the address space.
+ *
  */
 void pt_lock(as_t *as, bool lock)
@@ -132,6 +136,7 @@
  * Interrupts must be disabled.
  *
- * @param as Address space.
+ * @param as     Address space.
  * @param unlock If false, do not attempt to unlock the address space.
+ *
  */
 void pt_unlock(as_t *as, bool unlock)
@@ -141,4 +146,16 @@
 }
 
+/** Test whether page tables are locked.
+ *
+ * @param as		Address space where the page tables belong.
+ *
+ * @return		True if the page tables belonging to the address soace
+ *			are locked, otherwise false.
+ */
+bool pt_locked(as_t *as)
+{
+	return mutex_locked(&as->lock);
+}
+
 /** @}
  */
Index: kernel/genarch/src/mm/asid.c
===================================================================
--- kernel/genarch/src/mm/asid.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/genarch/src/mm/asid.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -70,7 +70,4 @@
 /** Allocate free address space identifier.
  *
- * Interrupts must be disabled and inactive_as_with_asid_lock must be held
- * prior to this call
- *
  * @return New ASID.
  */
@@ -80,4 +77,7 @@
 	link_t *tmp;
 	as_t *as;
+
+	ASSERT(interrupts_disabled());
+	ASSERT(spinlock_locked(&asidlock));
 
 	/*
@@ -126,7 +126,7 @@
 		 * Get the system rid of the stolen ASID.
 		 */
-		tlb_shootdown_start(TLB_INVL_ASID, asid, 0, 0);
+		ipl_t ipl = tlb_shootdown_start(TLB_INVL_ASID, asid, 0, 0);
 		tlb_invalidate_asid(asid);
-		tlb_shootdown_finalize();
+		tlb_shootdown_finalize(ipl);
 	} else {
 
@@ -142,7 +142,7 @@
 		 * Purge the allocated ASID from TLBs.
 		 */
-		tlb_shootdown_start(TLB_INVL_ASID, asid, 0, 0);
+		ipl_t ipl = tlb_shootdown_start(TLB_INVL_ASID, asid, 0, 0);
 		tlb_invalidate_asid(asid);
-		tlb_shootdown_finalize();
+		tlb_shootdown_finalize(ipl);
 	}
 	
Index: kernel/genarch/src/mm/page_ht.c
===================================================================
--- kernel/genarch/src/mm/page_ht.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/genarch/src/mm/page_ht.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -33,5 +33,5 @@
 /**
  * @file
- * @brief	Virtual Address Translation (VAT) for global page hash table.
+ * @brief Virtual Address Translation (VAT) for global page hash table.
  */
 
@@ -52,12 +52,11 @@
 #include <align.h>
 
-static size_t hash(unative_t key[]);
-static bool compare(unative_t key[], size_t keys, link_t *item);
-static void remove_callback(link_t *item);
-
-static void ht_mapping_insert(as_t *as, uintptr_t page, uintptr_t frame,
-    int flags);
-static void ht_mapping_remove(as_t *as, uintptr_t page);
-static pte_t *ht_mapping_find(as_t *as, uintptr_t page);
+static size_t hash(unative_t[]);
+static bool compare(unative_t[], size_t, link_t *);
+static void remove_callback(link_t *);
+
+static void ht_mapping_insert(as_t *, uintptr_t, uintptr_t, unsigned int);
+static void ht_mapping_remove(as_t *, uintptr_t);
+static pte_t *ht_mapping_find(as_t *, uintptr_t);
 
 /**
@@ -65,10 +64,12 @@
  * after address space lock and after any address space area
  * locks.
+ *
  */
 mutex_t page_ht_lock;
 
-/**
- * Page hash table.
+/** Page hash table.
+ *
  * The page hash table may be accessed only when page_ht_lock is held.
+ *
  */
 hash_table_t page_ht;
@@ -93,4 +94,5 @@
  *
  * @return Index into page hash table.
+ *
  */
 size_t hash(unative_t key[])
@@ -98,5 +100,4 @@
 	as_t *as = (as_t *) key[KEY_AS];
 	uintptr_t page = (uintptr_t) key[KEY_PAGE];
-	size_t index;
 	
 	/*
@@ -104,6 +105,7 @@
 	 * of occurring. Least significant bits of VPN compose the
 	 * hash index.
-	 */
-	index = ((page >> PAGE_WIDTH) & (PAGE_HT_ENTRIES - 1));
+	 *
+	 */
+	size_t index = ((page >> PAGE_WIDTH) & (PAGE_HT_ENTRIES - 1));
 	
 	/*
@@ -111,4 +113,5 @@
 	 * similar addresses. Least significant bits compose the
 	 * hash index.
+	 *
 	 */
 	index |= ((unative_t) as) & (PAGE_HT_ENTRIES - 1);
@@ -119,28 +122,28 @@
 /** 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 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(unative_t key[], size_t keys, link_t *item)
 {
-	pte_t *t;
-
 	ASSERT(item);
-	ASSERT((keys > 0) && (keys <= PAGE_HT_KEYS));
-
+	ASSERT(keys > 0);
+	ASSERT(keys <= PAGE_HT_KEYS);
+	
 	/*
 	 * Convert item to PTE.
-	 */
-	t = hash_table_get_instance(item, pte_t, link);
-
-	if (keys == PAGE_HT_KEYS) {
-		return (key[KEY_AS] == (uintptr_t) t->as) &&
-		    (key[KEY_PAGE] == t->page);
-	} else {
-		return (key[KEY_AS] == (uintptr_t) t->as);
-	}
+	 *
+	 */
+	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);
 }
 
@@ -148,17 +151,17 @@
  *
  * @param item Page hash table item being removed.
+ *
  */
 void remove_callback(link_t *item)
 {
-	pte_t *t;
-
 	ASSERT(item);
-
+	
 	/*
 	 * Convert item to PTE.
-	 */
-	t = hash_table_get_instance(item, pte_t, link);
-
-	free(t);
+	 *
+	 */
+	pte_t *pte = hash_table_get_instance(item, pte_t, link);
+	
+	free(pte);
 }
 
@@ -166,39 +169,40 @@
  *
  * Map virtual address page to physical address frame
- * using flags. 
- *
- * The page table must be locked and interrupts must be disabled.
- *
- * @param as Address space to which page belongs.
- * @param page Virtual address of the page to be mapped.
+ * using flags.
+ *
+ * @param as    Address space to which page belongs.
+ * @param page  Virtual address of the page to be mapped.
  * @param frame Physical address of memory frame to which the mapping is done.
  * @param flags Flags to be used for mapping.
- */
-void ht_mapping_insert(as_t *as, uintptr_t page, uintptr_t frame, int flags)
-{
-	pte_t *t;
+ *
+ */
+void ht_mapping_insert(as_t *as, uintptr_t page, uintptr_t frame,
+    unsigned int flags)
+{
 	unative_t key[2] = {
 		(uintptr_t) as,
 		page = ALIGN_DOWN(page, PAGE_SIZE)
 	};
+
+	ASSERT(page_table_locked(as));
 	
 	if (!hash_table_find(&page_ht, key)) {
-		t = (pte_t *) malloc(sizeof(pte_t), FRAME_ATOMIC);
-		ASSERT(t != NULL);
-
-		t->g = (flags & PAGE_GLOBAL) != 0;
-		t->x = (flags & PAGE_EXEC) != 0;
-		t->w = (flags & PAGE_WRITE) != 0;
-		t->k = !(flags & PAGE_USER);
-		t->c = (flags & PAGE_CACHEABLE) != 0;
-		t->p = !(flags & PAGE_NOT_PRESENT);
-		t->a = false;
-		t->d = false;
-
-		t->as = as;
-		t->page = ALIGN_DOWN(page, PAGE_SIZE);
-		t->frame = ALIGN_DOWN(frame, FRAME_SIZE);
-
-		hash_table_insert(&page_ht, key, &t->link);
+		pte_t *pte = (pte_t *) malloc(sizeof(pte_t), FRAME_ATOMIC);
+		ASSERT(pte != NULL);
+		
+		pte->g = (flags & PAGE_GLOBAL) != 0;
+		pte->x = (flags & PAGE_EXEC) != 0;
+		pte->w = (flags & PAGE_WRITE) != 0;
+		pte->k = !(flags & PAGE_USER);
+		pte->c = (flags & PAGE_CACHEABLE) != 0;
+		pte->p = !(flags & PAGE_NOT_PRESENT);
+		pte->a = false;
+		pte->d = false;
+		
+		pte->as = as;
+		pte->page = ALIGN_DOWN(page, PAGE_SIZE);
+		pte->frame = ALIGN_DOWN(frame, FRAME_SIZE);
+		
+		hash_table_insert(&page_ht, key, &pte->link);
 	}
 }
@@ -210,8 +214,7 @@
  * this call visible.
  *
- * The page table must be locked and interrupts must be disabled.
- *
- * @param as Address space to wich page belongs.
+ * @param as   Address space to wich page belongs.
  * @param page Virtual address of the page to be demapped.
+ *
  */
 void ht_mapping_remove(as_t *as, uintptr_t page)
@@ -221,4 +224,6 @@
 		page = ALIGN_DOWN(page, PAGE_SIZE)
 	};
+
+	ASSERT(page_table_locked(as));
 	
 	/*
@@ -234,25 +239,24 @@
  * Find mapping for virtual page.
  *
- * The page table must be locked and interrupts must be disabled.
- *
- * @param as Address space to wich page belongs.
+ * @param as   Address space to wich page belongs.
  * @param page Virtual page.
  *
  * @return NULL if there is no such mapping; requested mapping otherwise.
+ *
  */
 pte_t *ht_mapping_find(as_t *as, uintptr_t page)
 {
-	link_t *hlp;
-	pte_t *t = NULL;
 	unative_t key[2] = {
 		(uintptr_t) as,
 		page = ALIGN_DOWN(page, PAGE_SIZE)
 	};
-	
-	hlp = hash_table_find(&page_ht, key);
-	if (hlp)
-		t = hash_table_get_instance(hlp, pte_t, link);
-
-	return t;
+
+	ASSERT(page_table_locked(as));
+	
+	link_t *cur = hash_table_find(&page_ht, key);
+	if (cur)
+		return hash_table_get_instance(cur, pte_t, link);
+	
+	return NULL;
 }
 
Index: kernel/genarch/src/mm/page_pt.c
===================================================================
--- kernel/genarch/src/mm/page_pt.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/genarch/src/mm/page_pt.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -33,5 +33,5 @@
 /**
  * @file
- * @brief	Virtual Address Translation for hierarchical 4-level page tables.
+ * @brief Virtual Address Translation for hierarchical 4-level page tables.
  */
 
@@ -46,7 +46,7 @@
 #include <memstr.h>
 
-static void pt_mapping_insert(as_t *as, uintptr_t page, uintptr_t frame, int flags);
-static void pt_mapping_remove(as_t *as, uintptr_t page);
-static pte_t *pt_mapping_find(as_t *as, uintptr_t page);
+static void pt_mapping_insert(as_t *, uintptr_t, uintptr_t, unsigned int);
+static void pt_mapping_remove(as_t *, uintptr_t);
+static pte_t *pt_mapping_find(as_t *, uintptr_t);
 
 page_mapping_operations_t pt_mapping_operations = {
@@ -61,45 +61,44 @@
  * using flags.
  *
- * The page table must be locked and interrupts must be disabled.
- *
- * @param as Address space to wich page belongs.
- * @param page Virtual address of the page to be mapped.
+ * @param as    Address space to wich page belongs.
+ * @param page  Virtual address of the page to be mapped.
  * @param frame Physical address of memory frame to which the mapping is done.
  * @param flags Flags to be used for mapping.
- */
-void pt_mapping_insert(as_t *as, uintptr_t page, uintptr_t frame, int flags)
+ *
+ */
+void pt_mapping_insert(as_t *as, uintptr_t page, uintptr_t frame,
+    unsigned int flags)
 {
-	pte_t *ptl0, *ptl1, *ptl2, *ptl3;
-	pte_t *newpt;
-
-	ptl0 = (pte_t *) PA2KA((uintptr_t) as->genarch.page_table);
-
+	pte_t *ptl0 = (pte_t *) PA2KA((uintptr_t) as->genarch.page_table);
+
+	ASSERT(page_table_locked(as));
+	
 	if (GET_PTL1_FLAGS(ptl0, PTL0_INDEX(page)) & PAGE_NOT_PRESENT) {
-		newpt = (pte_t *)frame_alloc(PTL1_SIZE, FRAME_KA);
+		pte_t *newpt = (pte_t *) frame_alloc(PTL1_SIZE, FRAME_KA);
 		memsetb(newpt, FRAME_SIZE << PTL1_SIZE, 0);
 		SET_PTL1_ADDRESS(ptl0, PTL0_INDEX(page), KA2PA(newpt));
 		SET_PTL1_FLAGS(ptl0, PTL0_INDEX(page), PAGE_PRESENT | PAGE_USER | PAGE_EXEC | PAGE_CACHEABLE | PAGE_WRITE);
 	}
-
-	ptl1 = (pte_t *) PA2KA(GET_PTL1_ADDRESS(ptl0, PTL0_INDEX(page)));
-
+	
+	pte_t *ptl1 = (pte_t *) PA2KA(GET_PTL1_ADDRESS(ptl0, PTL0_INDEX(page)));
+	
 	if (GET_PTL2_FLAGS(ptl1, PTL1_INDEX(page)) & PAGE_NOT_PRESENT) {
-		newpt = (pte_t *)frame_alloc(PTL2_SIZE, FRAME_KA);
+		pte_t *newpt = (pte_t *) frame_alloc(PTL2_SIZE, FRAME_KA);
 		memsetb(newpt, FRAME_SIZE << PTL2_SIZE, 0);
 		SET_PTL2_ADDRESS(ptl1, PTL1_INDEX(page), KA2PA(newpt));
 		SET_PTL2_FLAGS(ptl1, PTL1_INDEX(page), PAGE_PRESENT | PAGE_USER | PAGE_EXEC | PAGE_CACHEABLE | PAGE_WRITE);
 	}
-
-	ptl2 = (pte_t *) PA2KA(GET_PTL2_ADDRESS(ptl1, PTL1_INDEX(page)));
-
+	
+	pte_t *ptl2 = (pte_t *) PA2KA(GET_PTL2_ADDRESS(ptl1, PTL1_INDEX(page)));
+	
 	if (GET_PTL3_FLAGS(ptl2, PTL2_INDEX(page)) & PAGE_NOT_PRESENT) {
-		newpt = (pte_t *)frame_alloc(PTL3_SIZE, FRAME_KA);
+		pte_t *newpt = (pte_t *) frame_alloc(PTL3_SIZE, FRAME_KA);
 		memsetb(newpt, FRAME_SIZE << PTL3_SIZE, 0);
 		SET_PTL3_ADDRESS(ptl2, PTL2_INDEX(page), KA2PA(newpt));
 		SET_PTL3_FLAGS(ptl2, PTL2_INDEX(page), PAGE_PRESENT | PAGE_USER | PAGE_EXEC | PAGE_CACHEABLE | PAGE_WRITE);
 	}
-
-	ptl3 = (pte_t *) PA2KA(GET_PTL3_ADDRESS(ptl2, PTL2_INDEX(page)));
-
+	
+	pte_t *ptl3 = (pte_t *) PA2KA(GET_PTL3_ADDRESS(ptl2, PTL2_INDEX(page)));
+	
 	SET_FRAME_ADDRESS(ptl3, PTL3_INDEX(page), frame);
 	SET_FRAME_FLAGS(ptl3, PTL3_INDEX(page), flags);
@@ -114,44 +113,43 @@
  * Empty page tables except PTL0 are freed.
  *
- * The page table must be locked and interrupts must be disabled.
- *
- * @param as Address space to wich page belongs.
+ * @param as   Address space to wich page belongs.
  * @param page Virtual address of the page to be demapped.
+ *
  */
 void pt_mapping_remove(as_t *as, uintptr_t page)
 {
-	pte_t *ptl0, *ptl1, *ptl2, *ptl3;
-	bool empty = true;
-	int i;
+	ASSERT(page_table_locked(as));
 
 	/*
 	 * First, remove the mapping, if it exists.
+	 *
 	 */
-
-	ptl0 = (pte_t *) PA2KA((uintptr_t) as->genarch.page_table);
-
+	
+	pte_t *ptl0 = (pte_t *) PA2KA((uintptr_t) as->genarch.page_table);
 	if (GET_PTL1_FLAGS(ptl0, PTL0_INDEX(page)) & PAGE_NOT_PRESENT)
 		return;
-
-	ptl1 = (pte_t *) PA2KA(GET_PTL1_ADDRESS(ptl0, PTL0_INDEX(page)));
-
+	
+	pte_t *ptl1 = (pte_t *) PA2KA(GET_PTL1_ADDRESS(ptl0, PTL0_INDEX(page)));
 	if (GET_PTL2_FLAGS(ptl1, PTL1_INDEX(page)) & PAGE_NOT_PRESENT)
 		return;
-
-	ptl2 = (pte_t *) PA2KA(GET_PTL2_ADDRESS(ptl1, PTL1_INDEX(page)));
-
+	
+	pte_t *ptl2 = (pte_t *) PA2KA(GET_PTL2_ADDRESS(ptl1, PTL1_INDEX(page)));
 	if (GET_PTL3_FLAGS(ptl2, PTL2_INDEX(page)) & PAGE_NOT_PRESENT)
 		return;
-
-	ptl3 = (pte_t *) PA2KA(GET_PTL3_ADDRESS(ptl2, PTL2_INDEX(page)));
-
+	
+	pte_t *ptl3 = (pte_t *) PA2KA(GET_PTL3_ADDRESS(ptl2, PTL2_INDEX(page)));
+	
 	/* Destroy the mapping. Setting to PAGE_NOT_PRESENT is not sufficient. */
 	memsetb(&ptl3[PTL3_INDEX(page)], sizeof(pte_t), 0);
-
+	
 	/*
 	 * Second, free all empty tables along the way from PTL3 down to PTL0.
+	 *
 	 */
 	
-	/* check PTL3 */
+	/* Check PTL3 */
+	bool empty = true;
+	
+	unsigned int i;
 	for (i = 0; i < PTL3_ENTRIES; i++) {
 		if (PTE_VALID(&ptl3[i])) {
@@ -160,16 +158,19 @@
 		}
 	}
+	
 	if (empty) {
 		/*
 		 * PTL3 is empty.
 		 * Release the frame and remove PTL3 pointer from preceding table.
+		 *
 		 */
 		frame_free(KA2PA((uintptr_t) ptl3));
-		if (PTL2_ENTRIES)
-			memsetb(&ptl2[PTL2_INDEX(page)], sizeof(pte_t), 0);
-		else if (PTL1_ENTRIES)
-			memsetb(&ptl1[PTL1_INDEX(page)], sizeof(pte_t), 0);
-		else
-			memsetb(&ptl0[PTL0_INDEX(page)], sizeof(pte_t), 0);
+#if (PTL2_ENTRIES != 0)
+		memsetb(&ptl2[PTL2_INDEX(page)], sizeof(pte_t), 0);
+#elif (PTL1_ENTRIES != 0)
+		memsetb(&ptl1[PTL1_INDEX(page)], sizeof(pte_t), 0);
+#else
+		memsetb(&ptl0[PTL0_INDEX(page)], sizeof(pte_t), 0);
+#endif
 	} else {
 		/*
@@ -177,55 +178,60 @@
 		 * Therefore, there must be a path from PTL0 to PTL3 and
 		 * thus nothing to free in higher levels.
-		 */
-		return;
-	}
-	
-	/* check PTL2, empty is still true */
-	if (PTL2_ENTRIES) {
-		for (i = 0; i < PTL2_ENTRIES; i++) {
-			if (PTE_VALID(&ptl2[i])) {
-				empty = false;
-				break;
-			}
+		 *
+		 */
+		return;
+	}
+	
+	/* Check PTL2, empty is still true */
+#if (PTL2_ENTRIES != 0)
+	for (i = 0; i < PTL2_ENTRIES; i++) {
+		if (PTE_VALID(&ptl2[i])) {
+			empty = false;
+			break;
 		}
-		if (empty) {
-			/*
-			 * PTL2 is empty.
-			 * Release the frame and remove PTL2 pointer from preceding table.
-			 */
-			frame_free(KA2PA((uintptr_t) ptl2));
-			if (PTL1_ENTRIES)
-				memsetb(&ptl1[PTL1_INDEX(page)], sizeof(pte_t), 0);
-			else
-				memsetb(&ptl0[PTL0_INDEX(page)], sizeof(pte_t), 0);
+	}
+	
+	if (empty) {
+		/*
+		 * PTL2 is empty.
+		 * Release the frame and remove PTL2 pointer from preceding table.
+		 *
+		 */
+		frame_free(KA2PA((uintptr_t) ptl2));
+#if (PTL1_ENTRIES != 0)
+		memsetb(&ptl1[PTL1_INDEX(page)], sizeof(pte_t), 0);
+#else
+		memsetb(&ptl0[PTL0_INDEX(page)], sizeof(pte_t), 0);
+#endif
+	} else {
+		/*
+		 * PTL2 is not empty.
+		 * Therefore, there must be a path from PTL0 to PTL2 and
+		 * thus nothing to free in higher levels.
+		 *
+		 */
+		return;
+	}
+#endif /* PTL2_ENTRIES != 0 */
+	
+	/* check PTL1, empty is still true */
+#if (PTL1_ENTRIES != 0)
+	for (i = 0; i < PTL1_ENTRIES; i++) {
+		if (PTE_VALID(&ptl1[i])) {
+			empty = false;
+			break;
 		}
-		else {
-			/*
-			 * PTL2 is not empty.
-			 * Therefore, there must be a path from PTL0 to PTL2 and
-			 * thus nothing to free in higher levels.
-			 */
-			return;
-		}
-	}
-
-	/* check PTL1, empty is still true */
-	if (PTL1_ENTRIES) {
-		for (i = 0; i < PTL1_ENTRIES; i++) {
-			if (PTE_VALID(&ptl1[i])) {
-				empty = false;
-				break;
-			}
-		}
-		if (empty) {
-			/*
-			 * PTL1 is empty.
-			 * Release the frame and remove PTL1 pointer from preceding table.
-			 */
-			frame_free(KA2PA((uintptr_t) ptl1));
-			memsetb(&ptl0[PTL0_INDEX(page)], sizeof(pte_t), 0);
-		}
-	}
-
+	}
+	
+	if (empty) {
+		/*
+		 * PTL1 is empty.
+		 * Release the frame and remove PTL1 pointer from preceding table.
+		 *
+		 */
+		frame_free(KA2PA((uintptr_t) ptl1));
+		memsetb(&ptl0[PTL0_INDEX(page)], sizeof(pte_t), 0);
+	}
+#endif /* PTL1_ENTRIES != 0 */
 }
 
@@ -234,32 +240,29 @@
  * Find mapping for virtual page.
  *
- * The page table must be locked and interrupts must be disabled.
- *
- * @param as Address space to which page belongs.
+ * @param as   Address space to which page belongs.
  * @param page Virtual page.
  *
- * @return NULL if there is no such mapping; entry from PTL3 describing the mapping otherwise.
+ * @return NULL if there is no such mapping; entry from PTL3 describing
+ *         the mapping otherwise.
+ *
  */
 pte_t *pt_mapping_find(as_t *as, uintptr_t page)
 {
-	pte_t *ptl0, *ptl1, *ptl2, *ptl3;
-
-	ptl0 = (pte_t *) PA2KA((uintptr_t) as->genarch.page_table);
-
+	ASSERT(page_table_locked(as));
+
+	pte_t *ptl0 = (pte_t *) PA2KA((uintptr_t) as->genarch.page_table);
 	if (GET_PTL1_FLAGS(ptl0, PTL0_INDEX(page)) & PAGE_NOT_PRESENT)
 		return NULL;
-
-	ptl1 = (pte_t *) PA2KA(GET_PTL1_ADDRESS(ptl0, PTL0_INDEX(page)));
-
+	
+	pte_t *ptl1 = (pte_t *) PA2KA(GET_PTL1_ADDRESS(ptl0, PTL0_INDEX(page)));
 	if (GET_PTL2_FLAGS(ptl1, PTL1_INDEX(page)) & PAGE_NOT_PRESENT)
 		return NULL;
-
-	ptl2 = (pte_t *) PA2KA(GET_PTL2_ADDRESS(ptl1, PTL1_INDEX(page)));
-
+	
+	pte_t *ptl2 = (pte_t *) PA2KA(GET_PTL2_ADDRESS(ptl1, PTL1_INDEX(page)));
 	if (GET_PTL3_FLAGS(ptl2, PTL2_INDEX(page)) & PAGE_NOT_PRESENT)
 		return NULL;
-
-	ptl3 = (pte_t *) PA2KA(GET_PTL3_ADDRESS(ptl2, PTL2_INDEX(page)));
-
+	
+	pte_t *ptl3 = (pte_t *) PA2KA(GET_PTL3_ADDRESS(ptl2, PTL2_INDEX(page)));
+	
 	return &ptl3[PTL3_INDEX(page)];
 }
Index: kernel/generic/include/adt/avl.h
===================================================================
--- kernel/generic/include/adt/avl.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/generic/include/adt/avl.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -34,7 +34,8 @@
 
 #ifndef KERN_AVLTREE_H_
-#define KERN_AVLTREE_H_ 
+#define KERN_AVLTREE_H_
 
 #include <typedefs.h>
+#include <trace.h>
 
 /**
@@ -110,5 +111,5 @@
  * @param t AVL tree.
  */
-static inline void avltree_create(avltree_t *t)
+NO_TRACE static inline void avltree_create(avltree_t *t)
 {
 	t->root = NULL;
@@ -120,5 +121,5 @@
  * @param node Node which is initialized.
  */
-static inline void avltree_node_initialize(avltree_node_t *node)
+NO_TRACE static inline void avltree_node_initialize(avltree_node_t *node)
 {
 	node->key = 0;
Index: kernel/generic/include/adt/list.h
===================================================================
--- kernel/generic/include/adt/list.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/generic/include/adt/list.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -37,4 +37,5 @@
 
 #include <typedefs.h>
+#include <trace.h>
 
 /** Doubly linked list head and link type. */
@@ -57,5 +58,5 @@
  * @param link Pointer to link_t structure to be initialized.
  */
-static inline void link_initialize(link_t *link)
+NO_TRACE static inline void link_initialize(link_t *link)
 {
 	link->prev = NULL;
@@ -69,5 +70,5 @@
  * @param head Pointer to link_t structure representing head of the list.
  */
-static inline void list_initialize(link_t *head)
+NO_TRACE static inline void list_initialize(link_t *head)
 {
 	head->prev = head;
@@ -82,5 +83,5 @@
  * @param head Pointer to link_t structure representing head of the list.
  */
-static inline void list_prepend(link_t *link, link_t *head)
+NO_TRACE static inline void list_prepend(link_t *link, link_t *head)
 {
 	link->next = head->next;
@@ -97,5 +98,5 @@
  * @param head Pointer to link_t structure representing head of the list.
  */
-static inline void list_append(link_t *link, link_t *head)
+NO_TRACE static inline void list_append(link_t *link, link_t *head)
 {
 	link->prev = head->prev;
@@ -112,5 +113,5 @@
  * 		contained in.
  */
-static inline void list_remove(link_t *link)
+NO_TRACE static inline void list_remove(link_t *link)
 {
 	link->next->prev = link->prev;
@@ -125,5 +126,5 @@
  * @param head Pointer to link_t structure representing head of the list.
  */
-static inline bool list_empty(link_t *head)
+NO_TRACE static inline bool list_empty(link_t *head)
 {
 	return head->next == head ? true : false;
@@ -143,5 +144,5 @@
  *		headless) list. 
  */
-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)
 {
 	link_t *hlp;
@@ -164,5 +165,5 @@
  *		headless list. 
  */
-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);
@@ -176,5 +177,5 @@
  * @param part2 Pointer to link_t structure leading the second headless list.
  */
-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);
Index: kernel/generic/include/arch.h
===================================================================
--- kernel/generic/include/arch.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/generic/include/arch.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -65,4 +65,10 @@
 } the_t;
 
+/*
+ * THE is not an abbreviation, but the English definite article written in
+ * capital letters. It means the current pointer to something, e.g. thread,
+ * processor or address space. Kind reader of this comment shall appreciate
+ * the wit of constructs like THE->thread and similar.
+ */
 #define THE  ((the_t * )(get_stack_base()))
 
Index: kernel/generic/include/atomic.h
===================================================================
--- kernel/generic/include/atomic.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/generic/include/atomic.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -38,11 +38,15 @@
 #include <typedefs.h>
 #include <arch/atomic.h>
+#include <verify.h>
 
-static inline void atomic_set(atomic_t *val, atomic_count_t i)
+NO_TRACE ATOMIC static inline void atomic_set(atomic_t *val, atomic_count_t i)
+    WRITES(&val->count)
+    REQUIRES_EXTENT_MUTABLE(val)
 {
 	val->count = i;
 }
 
-static inline atomic_count_t atomic_get(atomic_t *val)
+NO_TRACE ATOMIC static inline atomic_count_t atomic_get(atomic_t *val)
+    REQUIRES_EXTENT_MUTABLE(val)
 {
 	return val->count;
Index: kernel/generic/include/bitops.h
===================================================================
--- kernel/generic/include/bitops.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/generic/include/bitops.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -27,5 +27,5 @@
  */
 
-/** @addtogroup generic	
+/** @addtogroup generic
  * @{
  */
@@ -36,13 +36,23 @@
 #define KERN_BITOPS_H_
 
+#include <trace.h>
 
-/** Return position of first non-zero bit from left (i.e. [log_2(arg)]).
+#ifdef __32_BITS__
+	#define fnzb(arg)  fnzb32(arg)
+#endif
+
+#ifdef __64_BITS__
+	#define fnzb(arg)  fnzb64(arg)
+#endif
+
+/** Return position of first non-zero bit from left (32b variant).
  *
- * If number is zero, it returns 0
+ * @return 0 (if the number is zero) or [log_2(arg)].
+ *
  */
-static inline int fnzb32(uint32_t arg)
+NO_TRACE static inline uint8_t fnzb32(uint32_t arg)
 {
-	int n = 0;
-
+	uint8_t n = 0;
+	
 	if (arg >> 16) {
 		arg >>= 16;
@@ -71,8 +81,13 @@
 }
 
-static inline int fnzb64(uint64_t arg)
+/** Return position of first non-zero bit from left (64b variant).
+ *
+ * @return 0 (if the number is zero) or [log_2(arg)].
+ *
+ */
+NO_TRACE static inline uint8_t fnzb64(uint64_t arg)
 {
-	int n = 0;
-
+	uint8_t n = 0;
+	
 	if (arg >> 32) {
 		arg >>= 32;
@@ -83,6 +98,4 @@
 }
 
-#define fnzb(x) fnzb32(x)
-
 #endif
 
Index: kernel/generic/include/config.h
===================================================================
--- kernel/generic/include/config.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/generic/include/config.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -70,8 +70,8 @@
 	
 	uintptr_t base;
-	size_t kernel_size;           /**< Size of memory in bytes taken by kernel and stack */
+	size_t kernel_size;          /**< Size of memory in bytes taken by kernel and stack */
 	
-	uintptr_t stack_base;         /**< Base adddress of initial stack */
-	size_t stack_size;            /**< Size of initial stack */
+	uintptr_t stack_base;        /**< Base adddress of initial stack */
+	size_t stack_size;           /**< Size of initial stack */
 } config_t;
 
Index: kernel/generic/include/console/chardev.h
===================================================================
--- kernel/generic/include/console/chardev.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/generic/include/console/chardev.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -57,5 +57,5 @@
 	
 	/** Protects everything below. */
-	SPINLOCK_DECLARE(lock);
+	IRQ_SPINLOCK_DECLARE(lock);
 	wchar_t buffer[INDEV_BUFLEN];
 	size_t counter;
@@ -95,13 +95,13 @@
 } outdev_t;
 
-extern void indev_initialize(const char *name, indev_t *indev,
-    indev_operations_t *op);
-extern void indev_push_character(indev_t *indev, wchar_t ch);
-extern wchar_t indev_pop_character(indev_t *indev);
+extern void indev_initialize(const char *, indev_t *,
+    indev_operations_t *);
+extern void indev_push_character(indev_t *, wchar_t);
+extern wchar_t indev_pop_character(indev_t *);
 
-extern void outdev_initialize(const char *name, outdev_t *outdev,
-    outdev_operations_t *op);
+extern void outdev_initialize(const char *, outdev_t *,
+    outdev_operations_t *);
 
-extern bool check_poll(indev_t *indev);
+extern bool check_poll(indev_t *);
 
 #endif /* KERN_CHARDEV_H_ */
Index: kernel/generic/include/console/console.h
===================================================================
--- kernel/generic/include/console/console.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/generic/include/console/console.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -37,8 +37,24 @@
 
 #include <typedefs.h>
+#include <print.h>
 #include <console/chardev.h>
+
+#define PAGING(counter, increment, before, after) \
+	do { \
+		(counter) += (increment); \
+		if ((counter) > 23) { \
+			before; \
+			printf(" -- Press any key to continue -- "); \
+			indev_pop_character(stdin); \
+			after; \
+			printf("\n"); \
+			(counter) = 0; \
+		} \
+	} while (0)
 
 extern indev_t *stdin;
 extern outdev_t *stdout;
+
+extern void early_putchar(wchar_t);
 
 extern indev_t *stdin_wire(void);
Index: kernel/generic/include/console/kconsole.h
===================================================================
--- kernel/generic/include/console/kconsole.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/generic/include/console/kconsole.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -47,4 +47,6 @@
 	ARG_TYPE_INT,
 	ARG_TYPE_STRING,
+	/** Optional string */
+	ARG_TYPE_STRING_OPTIONAL,
 	/** Variable type - either symbol or string. */
 	ARG_TYPE_VAR
Index: kernel/generic/include/context.h
===================================================================
--- kernel/generic/include/context.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/generic/include/context.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -37,4 +37,5 @@
 
 #include <typedefs.h>
+#include <trace.h>
 #include <arch/context.h>
 
@@ -87,6 +88,7 @@
  *
  * @param ctx Context structure.
+ *
  */
-static inline void context_restore(context_t *ctx)
+NO_TRACE static inline void context_restore(context_t *ctx)
 {
 	context_restore_arch(ctx);
Index: kernel/generic/include/cpu.h
===================================================================
--- kernel/generic/include/cpu.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/generic/include/cpu.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -42,5 +42,5 @@
 #include <arch/context.h>
 
-#define CPU_STACK_SIZE	STACK_SIZE
+#define CPU_STACK_SIZE  STACK_SIZE
 
 /** CPU structure.
@@ -49,40 +49,48 @@
  */
 typedef struct cpu {
-	SPINLOCK_DECLARE(lock);
-
+	IRQ_SPINLOCK_DECLARE(lock);
+	
 	tlb_shootdown_msg_t tlb_messages[TLB_MESSAGE_QUEUE_LEN];
 	size_t tlb_messages_count;
 	
 	context_t saved_context;
-
+	
 	atomic_t nrdy;
 	runq_t rq[RQ_COUNT];
 	volatile size_t needs_relink;
-
-	SPINLOCK_DECLARE(timeoutlock);
+	
+	IRQ_SPINLOCK_DECLARE(timeoutlock);
 	link_t timeout_active_head;
-
-	size_t missed_clock_ticks;	/**< When system clock loses a tick, it is recorded here
-					     so that clock() can react. This variable is
-					     CPU-local and can be only accessed when interrupts
-					     are disabled. */
-
+	
+	/**
+	 * When system clock loses a tick, it is
+	 * recorded here so that clock() can react.
+	 * This variable is CPU-local and can be
+	 * only accessed when interrupts are
+	 * disabled.
+	 */
+	size_t missed_clock_ticks;
+	
+	/**
+	 * Processor cycle accounting.
+	 */
 	bool idle;
-	uint64_t idle_ticks;
-	uint64_t busy_ticks;
-
+	uint64_t last_cycle;
+	uint64_t idle_cycles;
+	uint64_t busy_cycles;
+	
 	/**
 	 * Processor ID assigned by kernel.
 	 */
-	unsigned int id;
+	size_t id;
 	
 	bool active;
-	int tlb_active;
-
+	bool tlb_active;
+	
 	uint16_t frequency_mhz;
 	uint32_t delay_loop_const;
-
+	
 	cpu_arch_t arch;
-
+	
 	struct thread *fpu_owner;
 	
@@ -100,5 +108,5 @@
 extern void cpu_arch_init(void);
 extern void cpu_identify(void);
-extern void cpu_print_report(cpu_t *m);
+extern void cpu_print_report(cpu_t *);
 
 #endif
Index: kernel/generic/include/ddi/ddi.h
===================================================================
--- kernel/generic/include/ddi/ddi.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/generic/include/ddi/ddi.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -50,10 +50,8 @@
 
 extern void ddi_init(void);
-extern void ddi_parea_register(parea_t *parea);
+extern void ddi_parea_register(parea_t *);
 
-extern unative_t sys_physmem_map(unative_t phys_base, unative_t virt_base,
-	unative_t pages, unative_t flags);
-extern unative_t sys_iospace_enable(ddi_ioarg_t *uspace_io_arg);
-extern unative_t sys_preempt_control(int enable);
+extern unative_t sys_physmem_map(unative_t, unative_t, unative_t, unative_t);
+extern unative_t sys_iospace_enable(ddi_ioarg_t *);
 extern unative_t sys_interrupt_enable(int irq, int enable);
 
@@ -61,5 +59,5 @@
  * Interface to be implemented by all architectures.
  */
-extern int ddi_iospace_enable_arch(task_t *task, uintptr_t ioaddr, size_t size);
+extern int ddi_iospace_enable_arch(task_t *, uintptr_t, size_t);
 
 
Index: kernel/generic/include/ddi/ddi_arg.h
===================================================================
--- kernel/generic/include/ddi/ddi_arg.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/generic/include/ddi/ddi_arg.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -36,8 +36,14 @@
 #define KERN_DDI_ARG_H_
 
+#ifdef KERNEL
+
+#include <typedefs.h>
+
+#endif /* KERNEL */
+
 /** Structure encapsulating arguments for SYS_PHYSMEM_MAP syscall. */
 typedef struct {
 	/** ID of the destination task. */
-	unsigned long long task_id;
+	uint64_t task_id;
 	/** Physical address of starting frame. */
 	void *phys_base;
@@ -45,14 +51,14 @@
 	void *virt_base;
 	/** Number of pages to map. */
-	unsigned long pages;
+	size_t pages;
 	/** Address space area flags for the mapping. */
-	int flags;
+	unsigned int flags;
 } ddi_memarg_t;
 
 /** Structure encapsulating arguments for SYS_ENABLE_IOSPACE syscall. */
 typedef struct {
-	unsigned long long task_id;	/**< ID of the destination task. */
-	void *ioaddr;			/**< Starting I/O space address. */
-	unsigned long size;		/**< Number of bytes. */
+	uint64_t task_id;  /**< ID of the destination task. */
+	void *ioaddr;      /**< Starting I/O space address. */
+	size_t size;       /**< Number of bytes. */
 } ddi_ioarg_t;
 
Index: kernel/generic/include/ddi/irq.h
===================================================================
--- kernel/generic/include/ddi/irq.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/generic/include/ddi/irq.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -35,4 +35,15 @@
 #ifndef KERN_IRQ_H_
 #define KERN_IRQ_H_
+
+#ifdef KERNEL
+
+#include <typedefs.h>
+#include <adt/list.h>
+#include <adt/hash_table.h>
+#include <synch/spinlock.h>
+#include <proc/task.h>
+#include <ipc/ipc.h>
+
+#endif /* KERNEL */
 
 typedef enum {
@@ -49,4 +60,5 @@
 	/** Write 4 bytes to the I/O space. */
 	CMD_PIO_WRITE_32,
+	
 	/**
 	 * Perform a bit test on the source argument and store the result into
@@ -54,4 +66,5 @@
 	 */
 	CMD_BTEST,
+	
 	/**
 	 * Predicate the execution of the following N commands by the boolean
@@ -59,4 +72,5 @@
 	 */
 	CMD_PREDICATE,
+	
 	/** Accept the interrupt. */
 	CMD_ACCEPT,
@@ -69,11 +83,11 @@
 	irq_cmd_type cmd;
 	void *addr;
-	unsigned long long value;
-	unsigned int srcarg;
-	unsigned int dstarg;
+	uint32_t value;
+	uintptr_t srcarg;
+	uintptr_t dstarg;
 } irq_cmd_t;
 
 typedef struct {
-	unsigned int cmdcount;
+	size_t cmdcount;
 	irq_cmd_t *cmds;
 } irq_code_t;
@@ -81,14 +95,7 @@
 #ifdef KERNEL
 
-#include <typedefs.h>
-#include <adt/list.h>
-#include <adt/hash_table.h>
-#include <synch/spinlock.h>
-#include <proc/task.h>
-#include <ipc/ipc.h>
-
 typedef enum {
-	IRQ_DECLINE,		/**< Decline to service. */
-	IRQ_ACCEPT		/**< Accept to service. */
+	IRQ_DECLINE,  /**< Decline to service. */
+	IRQ_ACCEPT    /**< Accept to service. */
 } irq_ownership_t;
 
@@ -108,4 +115,5 @@
  * Primarily, this structure is encapsulated in the irq_t structure.
  * It is protected by irq_t::lock.
+ *
  */
 typedef struct {
@@ -117,9 +125,10 @@
 	unative_t method;
 	/** Arguments that will be sent if the IRQ is claimed. */
-	unative_t scratch[IPC_CALL_LEN];
+	uint32_t scratch[IPC_CALL_LEN];
 	/** Top-half pseudocode. */
 	irq_code_t *code;
 	/** Counter. */
 	size_t counter;
+	
 	/**
 	 * Link between IRQs that are notifying the same answerbox. The list is
@@ -133,9 +142,10 @@
  * If one device has multiple interrupts, there will be multiple irq_t
  * instantions with the same devno.
+ *
  */
 typedef struct irq {
 	/** Hash table link. */
 	link_t link;
-
+	
 	/** Lock protecting everything in this structure
 	 *  except the link member. When both the IRQ
@@ -143,5 +153,5 @@
 	 *  this lock must not be taken first.
 	 */
-	SPINLOCK_DECLARE(lock);
+	IRQ_SPINLOCK_DECLARE(lock);
 	
 	/** Send EOI before processing the interrupt.
@@ -152,8 +162,8 @@
 	 */
 	bool preack;
-
+	
 	/** Unique device number. -1 if not yet assigned. */
 	devno_t devno;
-
+	
 	/** Actual IRQ number. -1 if not yet assigned. */
 	inr_t inr;
@@ -166,15 +176,15 @@
 	/** Instance argument for the handler and the claim function. */
 	void *instance;
-
+	
 	/** Clear interrupt routine. */
 	cir_t cir;
 	/** First argument to the clear interrupt routine. */
 	void *cir_arg;
-
+	
 	/** Notification configuration structure. */
 	ipc_notif_cfg_t notif_cfg; 
 } irq_t;
 
-SPINLOCK_EXTERN(irq_uspace_hash_table_lock);
+IRQ_SPINLOCK_EXTERN(irq_uspace_hash_table_lock);
 extern hash_table_t irq_uspace_hash_table;
 
@@ -184,8 +194,8 @@
 extern irq_t *irq_dispatch_and_lock(inr_t);
 
+#endif /* KERNEL */
+
 #endif
 
-#endif
-
 /** @}
  */
Index: kernel/generic/include/debug.h
===================================================================
--- kernel/generic/include/debug.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/generic/include/debug.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -37,12 +37,9 @@
 
 #include <panic.h>
-#include <arch/debug.h>
+#include <symtab.h>
 
-#define CALLER ((uintptr_t) __builtin_return_address(0))
+#define CALLER  ((uintptr_t) __builtin_return_address(0))
 
-#ifndef HERE
-/** Current Instruction Pointer address */
-#	define HERE ((uintptr_t *) 0)
-#endif
+#ifdef CONFIG_DEBUG
 
 /** Debugging ASSERT macro
@@ -55,12 +52,35 @@
  *
  */
-#ifdef CONFIG_DEBUG
-#	define ASSERT(expr) \
-		if (!(expr)) { \
-			panic("Assertion failed (%s), caller=%p.", #expr, CALLER); \
-		}
-#else
-#	define ASSERT(expr)
-#endif
+#define ASSERT(expr) \
+	do { \
+		if (!(expr)) \
+			panic_assert("%s", #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, %s", #expr, msg); \
+	} while (0)
+
+#else /* CONFIG_DEBUG */
+
+#define ASSERT(expr)
+#define ASSERT_VERBOSE(expr, msg)
+
+#endif /* CONFIG_DEBUG */
+
+#ifdef CONFIG_LOG
 
 /** Extensive logging output macro
@@ -71,32 +91,23 @@
  *
  */
+#define LOG(format, ...) \
+	do { \
+		printf("%s() from %s at %s:%u: " format "\n", __func__, \
+		    symtab_fmt_name_lookup(CALLER), __FILE__, __LINE__, \
+		    ##__VA_ARGS__); \
+	} while (0)
 
-#ifdef CONFIG_LOG
-#	define LOG(format, ...) \
-		printf("%s() at %s:%u: " format "\n", __func__, __FILE__, \
-		    __LINE__, ##__VA_ARGS__);
-#else
-#	define LOG(format, ...)
-#endif
+#else /* CONFIG_LOG */
 
-/** Extensive logging execute macro
- *
- * If CONFIG_LOG is set, the LOG_EXEC() macro
- * will print an information about calling a given
- * function and call it.
- *
- */
+#define LOG(format, ...)
 
-#ifdef CONFIG_LOG
-#	define LOG_EXEC(fnc) \
-		{ \
-			printf("%s() at %s:%u: " #fnc "\n", __func__, __FILE__, \
-			    __LINE__); \
-			fnc; \
-		}
-#else
-#	define LOG_EXEC(fnc) fnc
-#endif
+#endif /* CONFIG_LOG */
 
+#ifdef CONFIG_TRACE
+
+extern void __cyg_profile_func_enter(void *, void *);
+extern void __cyg_profile_func_exit(void *, void *);
+
+#endif /* CONFIG_TRACE */
 
 #endif
Index: kernel/generic/include/interrupt.h
===================================================================
--- kernel/generic/include/interrupt.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/generic/include/interrupt.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -44,12 +44,25 @@
 #include <stacktrace.h>
 
-typedef void (* iroutine)(int n, istate_t *istate);
+typedef void (* iroutine_t)(unsigned int, istate_t *);
 
-extern void fault_if_from_uspace(istate_t *istate, const char *fmt, ...);
-extern iroutine exc_register(int n, const char *name, iroutine f);
-extern void exc_dispatch(int n, istate_t *t);
-void exc_init(void);
+typedef struct {
+	const char *name;
+	bool hot;
+	iroutine_t handler;
+	uint64_t cycles;
+	uint64_t count;
+} exc_table_t;
 
-extern void irq_initialize_arch(irq_t *irq);
+IRQ_SPINLOCK_EXTERN(exctbl_lock);
+extern exc_table_t exc_table[];
+
+extern void fault_if_from_uspace(istate_t *, const char *, ...);
+extern iroutine_t exc_register(unsigned int, const char *, bool, iroutine_t);
+extern void exc_dispatch(unsigned int, istate_t *);
+extern void exc_init(void);
+
+extern void irq_initialize_arch(irq_t *);
+
+extern void istate_decode(istate_t *);
 
 #endif
Index: kernel/generic/include/ipc/ipc.h
===================================================================
--- kernel/generic/include/ipc/ipc.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/generic/include/ipc/ipc.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -36,13 +36,16 @@
 #define KERN_IPC_H_
 
-/* Length of data being transfered with IPC call */
-/* - the uspace may not be able to utilize full length */
-#define IPC_CALL_LEN		6	
+/** Length of data being transfered with IPC call
+ *
+ * The uspace may not be able to utilize full length
+ *
+ */
+#define IPC_CALL_LEN  6
 
 /** Maximum active async calls per thread */
 #ifdef CONFIG_DEBUG
-#define IPC_MAX_ASYNC_CALLS	4
+	#define IPC_MAX_ASYNC_CALLS  4
 #else
-#define IPC_MAX_ASYNC_CALLS	4000
+	#define IPC_MAX_ASYNC_CALLS  4000
 #endif
 
@@ -50,52 +53,61 @@
 
 /** This is answer to a call */
-#define IPC_CALL_ANSWERED	(1 << 0)
+#define IPC_CALL_ANSWERED  (1 << 0)
+
 /** Answer will not be passed to userspace, will be discarded */
-#define IPC_CALL_DISCARD_ANSWER (1 << 1)
+#define IPC_CALL_DISCARD_ANSWER  (1 << 1)
+
 /** Call was forwarded */
-#define IPC_CALL_FORWARDED	(1 << 2)
+#define IPC_CALL_FORWARDED  (1 << 2)
+
 /** Identify connect_me_to answer */
-#define IPC_CALL_CONN_ME_TO	(1 << 3)
+#define IPC_CALL_CONN_ME_TO  (1 << 3)
+
 /** Interrupt notification */
-#define IPC_CALL_NOTIF		(1 << 4)
-
-/*
- * Bits used in call hashes.
+#define IPC_CALL_NOTIF  (1 << 4)
+
+
+/** Bits used in call hashes.
+ *
  * The addresses are aligned at least to 4 that is why we can use the 2 least
  * significant bits of the call address.
- */
+ *
+ */
+
 /** Type of this call is 'answer' */
-#define IPC_CALLID_ANSWERED	1
+#define IPC_CALLID_ANSWERED  1
+
 /** Type of this call is 'notification' */
-#define IPC_CALLID_NOTIFICATION	2
+#define IPC_CALLID_NOTIFICATION  2
 
 /* Return values from sys_ipc_call_async(). */
-#define IPC_CALLRET_FATAL	-1
-#define IPC_CALLRET_TEMPORARY	-2
+#define IPC_CALLRET_FATAL      -1
+#define IPC_CALLRET_TEMPORARY  -2
 
 
 /* Macros for manipulating calling data */
-#define IPC_SET_RETVAL(data, retval)	((data).args[0] = (retval))
-#define IPC_SET_METHOD(data, val)	((data).args[0] = (val))
-#define IPC_SET_ARG1(data, val)		((data).args[1] = (val))
-#define IPC_SET_ARG2(data, val)		((data).args[2] = (val))
-#define IPC_SET_ARG3(data, val)		((data).args[3] = (val))
-#define IPC_SET_ARG4(data, val)		((data).args[4] = (val))
-#define IPC_SET_ARG5(data, val)		((data).args[5] = (val))
-
-#define IPC_GET_METHOD(data)		((data).args[0])
-#define IPC_GET_RETVAL(data)		((data).args[0])
-
-#define IPC_GET_ARG1(data)		((data).args[1])
-#define IPC_GET_ARG2(data)		((data).args[2])
-#define IPC_GET_ARG3(data)		((data).args[3])
-#define IPC_GET_ARG4(data)		((data).args[4])
-#define IPC_GET_ARG5(data)		((data).args[5])
+#define IPC_SET_RETVAL(data, retval)  ((data).args[0] = (retval))
+#define IPC_SET_METHOD(data, val)     ((data).args[0] = (val))
+#define IPC_SET_ARG1(data, val)       ((data).args[1] = (val))
+#define IPC_SET_ARG2(data, val)       ((data).args[2] = (val))
+#define IPC_SET_ARG3(data, val)       ((data).args[3] = (val))
+#define IPC_SET_ARG4(data, val)       ((data).args[4] = (val))
+#define IPC_SET_ARG5(data, val)       ((data).args[5] = (val))
+
+#define IPC_GET_METHOD(data)  ((data).args[0])
+#define IPC_GET_RETVAL(data)  ((data).args[0])
+
+#define IPC_GET_ARG1(data)  ((data).args[1])
+#define IPC_GET_ARG2(data)  ((data).args[2])
+#define IPC_GET_ARG3(data)  ((data).args[3])
+#define IPC_GET_ARG4(data)  ((data).args[4])
+#define IPC_GET_ARG5(data)  ((data).args[5])
 
 /* Well known phone descriptors */
-#define PHONE_NS	0
+#define PHONE_NS  0
 
 /* Forwarding flags. */
-#define IPC_FF_NONE		0
+#define IPC_FF_NONE  0
+
 /**
  * The call will be routed as though it was initially sent via the phone used to
@@ -104,10 +116,13 @@
  * calls that were initially sent by the forwarder to the same destination. This
  * flag has no imapct on routing replies.
- */
-#define IPC_FF_ROUTE_FROM_ME	(1 << 0)
-
-/* System-specific methods - only through special syscalls
+ *
+ */
+#define IPC_FF_ROUTE_FROM_ME  (1 << 0)
+
+/** System-specific methods - only through special syscalls
  * These methods have special behaviour
- */
+ *
+ */
+
 /** Clone connection.
  *
@@ -115,19 +130,24 @@
  *
  * - ARG1 - The caller sets ARG1 to the phone of the cloned connection.
- *	  - The callee gets the new phone from ARG1.
+ *        - 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
- */
-#define IPC_M_CONNECTION_CLONE	1
+ *
+ */
+#define IPC_M_CONNECTION_CLONE  1
+
 /** Protocol for CONNECT - ME
  *
  * 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 asnwer, the callee acknowledges the new connection by sending EOK back
  *   or the kernel closes it
- */
-#define IPC_M_CONNECT_ME	2
-/** Protocol for CONNECT - TO - ME 
+ *
+ */
+#define IPC_M_CONNECT_ME  2
+
+/** Protocol for CONNECT - TO - ME
  *
  * Calling process asks the callee to create a callback connection,
@@ -144,6 +164,8 @@
  *                     - the allocated phoneid is passed to userspace 
  *                       (on the receiving side) as ARG5 of the call.
- */
-#define IPC_M_CONNECT_TO_ME	3	
+ *
+ */
+#define IPC_M_CONNECT_TO_ME  3
+
 /** Protocol for CONNECT - ME - TO
  *
@@ -163,9 +185,10 @@
  *
  */
-#define IPC_M_CONNECT_ME_TO	4	
-/** This message is sent to answerbox when the phone
- * is hung up
- */
-#define IPC_M_PHONE_HUNGUP	5
+#define IPC_M_CONNECT_ME_TO  4
+
+/** This message is sent to answerbox when the phone is hung up
+ *
+ */
+#define IPC_M_PHONE_HUNGUP  5
 
 /** Send as_area over IPC.
@@ -173,9 +196,10 @@
  * - ARG2 - size of source as_area (filled automatically by kernel)
  * - ARG3 - flags of the as_area being sent
- * 
+ *
  * on answer, the recipient must set:
  * - ARG1 - dst as_area base adress
- */
-#define IPC_M_SHARE_OUT		6	
+ *
+ */
+#define IPC_M_SHARE_OUT  6
 
 /** Receive as_area over IPC.
@@ -183,11 +207,12 @@
  * - ARG2 - destination as_area size
  * - ARG3 - user defined argument
- * 
+ *
  * on answer, the recipient must set:
  *
  * - ARG1 - source as_area base address
  * - ARG2 - flags that will be used for sharing
- */
-#define IPC_M_SHARE_IN		7	
+ *
+ */
+#define IPC_M_SHARE_IN  7
 
 /** Send data to another address space over IPC.
@@ -199,6 +224,7 @@
  * - ARG1 - final destination address space virtual address
  * - ARG2 - final size of data to be copied
- */
-#define IPC_M_DATA_WRITE	8
+ *
+ */
+#define IPC_M_DATA_WRITE  8
 
 /** Receive data from another address space over IPC.
@@ -210,18 +236,21 @@
  * - ARG1 - source virtual address in the destination address space
  * - ARG2 - final size of data to be copied
- */
-#define IPC_M_DATA_READ		9
+ *
+ */
+#define IPC_M_DATA_READ  9
 
 /** Debug the recipient.
  * - ARG1 - specifies the debug method (from udebug_method_t)
  * - other arguments are specific to the debug method
- */
-#define IPC_M_DEBUG_ALL		10
+ *
+ */
+#define IPC_M_DEBUG_ALL  10
 
 /* Well-known methods */
-#define IPC_M_LAST_SYSTEM	511
-#define IPC_M_PING		512
+#define IPC_M_LAST_SYSTEM  511
+#define IPC_M_PING         512
+
 /* User methods */
-#define IPC_FIRST_USER_METHOD	1024
+#define IPC_FIRST_USER_METHOD  1024
 
 #ifdef KERNEL
@@ -259,23 +288,24 @@
 
 typedef struct answerbox {
-	SPINLOCK_DECLARE(lock);
-
+	IRQ_SPINLOCK_DECLARE(lock);
+	
 	struct task *task;
-
+	
 	waitq_t wq;
-
+	
 	/** Linkage for the list of task's synchronous answerboxes. */
 	link_t sync_box_link;
-
+	
 	/** Phones connected to this answerbox. */
 	link_t connected_phones;
 	/** Received calls. */
-	link_t calls;			
-	link_t dispatched_calls;	/* Should be hash table in the future */
-
+	link_t calls;
+	link_t dispatched_calls;  /* Should be hash table in the future */
+	
 	/** Answered calls. */
 	link_t answers;
-
-	SPINLOCK_DECLARE(irq_lock);
+	
+	IRQ_SPINLOCK_DECLARE(irq_lock);
+	
 	/** Notifications from IRQ handlers. */
 	link_t irq_notifs;
@@ -291,43 +321,46 @@
 typedef struct {
 	link_t link;
-
-	int flags;
-
+	
+	unsigned int flags;
+	
 	/** Identification of the caller. */
 	struct task *sender;
-	/** The caller box is different from sender->answerbox for synchronous
-	 *  calls. */
+	
+	/*
+	 * The caller box is different from sender->answerbox
+	 * for synchronous calls.
+	 *
+	 */
 	answerbox_t *callerbox;
-
+	
 	/** Private data to internal IPC. */
 	unative_t priv;
-
+	
 	/** Data passed from/to userspace. */
 	ipc_data_t data;
-
+	
 	/** Buffer for IPC_M_DATA_WRITE and IPC_M_DATA_READ. */
 	uint8_t *buffer;
-
+	
 	/*
 	 * The forward operation can masquerade the caller phone. For those
 	 * cases, we must keep it aside so that the answer is processed
 	 * correctly.
+	 *
 	 */
 	phone_t *caller_phone;
 } call_t;
 
-
 extern answerbox_t *ipc_phone_0;
 
-
 extern void ipc_init(void);
 
-extern call_t * ipc_call_alloc(int);
+extern call_t *ipc_call_alloc(unsigned int);
 extern void ipc_call_free(call_t *);
 
 extern int ipc_call(phone_t *, call_t *);
 extern int ipc_call_sync(phone_t *, call_t *);
-extern call_t * ipc_wait_for_call(answerbox_t *, uint32_t, int);
-extern int ipc_forward(call_t *, phone_t *, answerbox_t *, int);
+extern call_t * ipc_wait_for_call(answerbox_t *, uint32_t, unsigned int);
+extern int ipc_forward(call_t *, phone_t *, answerbox_t *, unsigned int);
 extern void ipc_answer(answerbox_t *, call_t *);
 
@@ -345,8 +378,8 @@
 extern void ipc_print_task(task_id_t);
 
+#endif /* KERNEL */
+
 #endif
 
-#endif
-
 /** @}
  */
Index: kernel/generic/include/ipc/irq.h
===================================================================
--- kernel/generic/include/ipc/irq.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/generic/include/ipc/irq.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -37,5 +37,5 @@
 
 /** Maximum length of IPC IRQ program */
-#define IRQ_MAX_PROG_SIZE	20
+#define IRQ_MAX_PROG_SIZE  20
 
 #include <ipc/ipc.h>
@@ -58,15 +58,20 @@
  */
 #define ipc_irq_send_msg_0(irq) \
-    ipc_irq_send_msg((irq), 0, 0, 0, 0, 0)
+	ipc_irq_send_msg((irq), 0, 0, 0, 0, 0)
+
 #define ipc_irq_send_msg_1(irq, a1) \
-    ipc_irq_send_msg((irq), (a1), 0, 0, 0, 0)
+	ipc_irq_send_msg((irq), (a1), 0, 0, 0, 0)
+
 #define ipc_irq_send_msg_2(irq, a1, a2) \
-    ipc_irq_send_msg((irq), (a1), (a2), 0, 0, 0)
+	ipc_irq_send_msg((irq), (a1), (a2), 0, 0, 0)
+
 #define ipc_irq_send_msg_3(irq, a1, a2, a3) \
-    ipc_irq_send_msg((irq), (a1), (a2), (a3), 0, 0)
+	ipc_irq_send_msg((irq), (a1), (a2), (a3), 0, 0)
+
 #define ipc_irq_send_msg_4(irq, a1, a2, a3, a4) \
-    ipc_irq_send_msg((irq), (a1), (a2), (a3), (a4), 0)
+	ipc_irq_send_msg((irq), (a1), (a2), (a3), (a4), 0)
+
 #define ipc_irq_send_msg_5(irq, a1, a2, a3, a4, a5) \
-    ipc_irq_send_msg((irq), (a1), (a2), (a3), (a4), (a5))
+	ipc_irq_send_msg((irq), (a1), (a2), (a3), (a4), (a5))
 
 extern void ipc_irq_send_msg(irq_t *, unative_t, unative_t, unative_t, unative_t,
Index: kernel/generic/include/ipc/sysipc.h
===================================================================
--- kernel/generic/include/ipc/sysipc.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/generic/include/ipc/sysipc.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -40,26 +40,26 @@
 #include <typedefs.h>
 
-unative_t sys_ipc_call_sync_fast(unative_t phoneid, unative_t method, 
+extern unative_t sys_ipc_call_sync_fast(unative_t phoneid, unative_t method, 
     unative_t arg1, unative_t arg2, unative_t arg3, ipc_data_t *data);
-unative_t sys_ipc_call_sync_slow(unative_t phoneid, ipc_data_t *question,
+extern unative_t sys_ipc_call_sync_slow(unative_t phoneid, ipc_data_t *question,
     ipc_data_t *reply);
-unative_t sys_ipc_call_async_fast(unative_t phoneid, unative_t method, 
+extern unative_t sys_ipc_call_async_fast(unative_t phoneid, unative_t method, 
     unative_t arg1, unative_t arg2, unative_t arg3, unative_t arg4);
-unative_t sys_ipc_call_async_slow(unative_t phoneid, ipc_data_t *data);
-unative_t sys_ipc_answer_fast(unative_t callid, unative_t retval, 
+extern unative_t sys_ipc_call_async_slow(unative_t phoneid, ipc_data_t *data);
+extern unative_t sys_ipc_answer_fast(unative_t callid, unative_t retval, 
     unative_t arg1, unative_t arg2, unative_t arg3, unative_t arg4);
-unative_t sys_ipc_answer_slow(unative_t callid, ipc_data_t *data);
-unative_t sys_ipc_wait_for_call(ipc_data_t *calldata, uint32_t usec,
-    int nonblocking);
-unative_t sys_ipc_poke(void);
-unative_t sys_ipc_forward_fast(unative_t callid, unative_t phoneid,
-    unative_t method, unative_t arg1, unative_t arg2, int mode);
-unative_t sys_ipc_forward_slow(unative_t callid, unative_t phoneid,
-    ipc_data_t *data, int mode);
-unative_t sys_ipc_hangup(unative_t phoneid);
-unative_t sys_ipc_register_irq(inr_t inr, devno_t devno, unative_t method,
+extern unative_t sys_ipc_answer_slow(unative_t callid, ipc_data_t *data);
+extern unative_t sys_ipc_wait_for_call(ipc_data_t *calldata, uint32_t usec,
+    unsigned int nonblocking);
+extern unative_t sys_ipc_poke(void);
+extern unative_t sys_ipc_forward_fast(unative_t callid, unative_t phoneid,
+    unative_t method, unative_t arg1, unative_t arg2, unsigned int mode);
+extern unative_t sys_ipc_forward_slow(unative_t callid, unative_t phoneid,
+    ipc_data_t *data, unsigned int mode);
+extern unative_t sys_ipc_hangup(unative_t phoneid);
+extern unative_t sys_ipc_register_irq(inr_t inr, devno_t devno, unative_t method,
     irq_code_t *ucode);
-unative_t sys_ipc_unregister_irq(inr_t inr, devno_t devno);
-unative_t sys_ipc_connect_kbox(sysarg64_t *task_id);
+extern unative_t sys_ipc_unregister_irq(inr_t inr, devno_t devno);
+extern unative_t sys_ipc_connect_kbox(sysarg64_t *task_id);
 
 #endif
Index: kernel/generic/include/lib/elf.h
===================================================================
--- kernel/generic/include/lib/elf.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/generic/include/lib/elf.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -27,5 +27,5 @@
  */
 
-/** @addtogroup generic	
+/** @addtogroup generic
  * @{
  */
@@ -42,150 +42,150 @@
  * current ELF version
  */
-#define EV_CURRENT	1
+#define EV_CURRENT  1
 
 /**
  * ELF types
  */
-#define ET_NONE		0	/* No type */
-#define ET_REL		1	/* Relocatable file */
-#define ET_EXEC		2	/* Executable */
-#define ET_DYN		3	/* Shared object */
-#define ET_CORE		4	/* Core */
-#define ET_LOPROC	0xff00	/* Processor specific */
-#define ET_HIPROC	0xffff	/* Processor specific */
-
-/** 
+#define ET_NONE    0       /* No type */
+#define ET_REL     1       /* Relocatable file */
+#define ET_EXEC    2       /* Executable */
+#define ET_DYN     3       /* Shared object */
+#define ET_CORE    4       /* Core */
+#define ET_LOPROC  0xff00  /* Processor specific */
+#define ET_HIPROC  0xffff  /* Processor specific */
+
+/**
  * ELF machine types
  */
-#define EM_NO		0	/* No machine */
-#define EM_SPARC	2	/* SPARC */
-#define EM_386		3	/* i386 */
-#define EM_MIPS		8	/* MIPS RS3000 */
-#define EM_MIPS_RS3_LE	10	/* MIPS RS3000 LE */
-#define EM_PPC		20	/* PPC32 */
-#define EM_PPC64	21	/* PPC64 */
-#define EM_ARM		40	/* ARM */
-#define EM_SPARCV9	43	/* SPARC64 */
-#define EM_IA_64	50	/* IA-64 */
-#define EM_X86_64	62	/* AMD64/EMT64 */
+#define EM_NO           0   /* No machine */
+#define EM_SPARC        2   /* SPARC */
+#define EM_386          3   /* i386 */
+#define EM_MIPS         8   /* MIPS RS3000 */
+#define EM_MIPS_RS3_LE  10  /* MIPS RS3000 LE */
+#define EM_PPC          20  /* PPC32 */
+#define EM_PPC64        21  /* PPC64 */
+#define EM_ARM          40  /* ARM */
+#define EM_SPARCV9      43  /* SPARC64 */
+#define EM_IA_64        50  /* IA-64 */
+#define EM_X86_64       62  /* AMD64/EMT64 */
 
 /**
  * ELF identification indexes
  */
-#define EI_MAG0		0
-#define EI_MAG1		1
-#define EI_MAG2		2
-#define EI_MAG3		3
-#define EI_CLASS	4		/* File class */
-#define EI_DATA		5		/* Data encoding */
-#define EI_VERSION	6		/* File version */
-#define EI_OSABI	7
-#define EI_ABIVERSION	8
-#define EI_PAD		9		/* Start of padding bytes */
-#define EI_NIDENT	16		/* ELF identification table size */
+#define EI_MAG0        0
+#define EI_MAG1        1
+#define EI_MAG2        2
+#define EI_MAG3        3
+#define EI_CLASS       4   /* File class */
+#define EI_DATA        5   /* Data encoding */
+#define EI_VERSION     6   /* File version */
+#define EI_OSABI       7
+#define EI_ABIVERSION  8
+#define EI_PAD         9   /* Start of padding bytes */
+#define EI_NIDENT      16  /* ELF identification table size */
 
 /**
  * ELF magic number
  */
-#define ELFMAG0		0x7f
-#define ELFMAG1		'E'
-#define ELFMAG2		'L'
-#define ELFMAG3		'F'
+#define ELFMAG0  0x7f
+#define ELFMAG1  'E'
+#define ELFMAG2  'L'
+#define ELFMAG3  'F'
 
 /**
  * ELF file classes
  */
-#define ELFCLASSNONE	0
-#define ELFCLASS32	1
-#define ELFCLASS64	2
+#define ELFCLASSNONE  0
+#define ELFCLASS32    1
+#define ELFCLASS64    2
 
 /**
  * ELF data encoding types
  */
-#define ELFDATANONE	0
-#define ELFDATA2LSB	1		/* Least significant byte first (little endian) */
-#define ELFDATA2MSB	2		/* Most signigicant byte first (big endian) */
+#define ELFDATANONE  0
+#define ELFDATA2LSB  1  /* Least significant byte first (little endian) */
+#define ELFDATA2MSB  2  /* Most signigicant byte first (big endian) */
 
 /**
  * ELF error return codes
  */
-#define EE_OK			0	/* No error */
-#define EE_INVALID		1	/* Invalid ELF image */
-#define	EE_MEMORY		2	/* Cannot allocate address space */
-#define EE_INCOMPATIBLE		3	/* ELF image is not compatible with current architecture */
-#define EE_UNSUPPORTED		4	/* Non-supported ELF (e.g. dynamic ELFs) */
-#define EE_LOADER		5	/* The image is actually a program loader */
-#define EE_IRRECOVERABLE	6
+#define EE_OK             0  /* No error */
+#define EE_INVALID        1  /* Invalid ELF image */
+#define EE_MEMORY         2  /* Cannot allocate address space */
+#define EE_INCOMPATIBLE   3  /* ELF image is not compatible with current architecture */
+#define EE_UNSUPPORTED    4  /* Non-supported ELF (e.g. dynamic ELFs) */
+#define EE_LOADER         5  /* The image is actually a program loader */
+#define EE_IRRECOVERABLE  6
 
 /**
  * ELF section types
  */
-#define SHT_NULL		0
-#define SHT_PROGBITS		1
-#define SHT_SYMTAB		2
-#define SHT_STRTAB		3
-#define SHT_RELA		4
-#define SHT_HASH		5
-#define SHT_DYNAMIC		6
-#define SHT_NOTE		7
-#define SHT_NOBITS		8
-#define SHT_REL			9
-#define SHT_SHLIB		10
-#define SHT_DYNSYM		11
-#define SHT_LOOS		0x60000000
-#define SHT_HIOS		0x6fffffff
-#define SHT_LOPROC		0x70000000
-#define SHT_HIPROC		0x7fffffff
-#define SHT_LOUSER		0x80000000
-#define SHT_HIUSER		0xffffffff
+#define SHT_NULL      0
+#define SHT_PROGBITS  1
+#define SHT_SYMTAB    2
+#define SHT_STRTAB    3
+#define SHT_RELA      4
+#define SHT_HASH      5
+#define SHT_DYNAMIC   6
+#define SHT_NOTE      7
+#define SHT_NOBITS    8
+#define SHT_REL       9
+#define SHT_SHLIB     10
+#define SHT_DYNSYM    11
+#define SHT_LOOS      0x60000000
+#define SHT_HIOS      0x6fffffff
+#define SHT_LOPROC    0x70000000
+#define SHT_HIPROC    0x7fffffff
+#define SHT_LOUSER    0x80000000
+#define SHT_HIUSER    0xffffffff
 
 /**
  * ELF section flags
  */
-#define SHF_WRITE		0x1 
-#define SHF_ALLOC		0x2
-#define SHF_EXECINSTR		0x4
-#define SHF_TLS			0x400
-#define SHF_MASKPROC		0xf0000000
+#define SHF_WRITE      0x1
+#define SHF_ALLOC      0x2
+#define SHF_EXECINSTR  0x4
+#define SHF_TLS        0x400
+#define SHF_MASKPROC   0xf0000000
 
 /**
  * Symbol binding
  */
-#define STB_LOCAL		0
-#define STB_GLOBAL		1
-#define STB_WEAK		2
-#define STB_LOPROC		13
-#define STB_HIPROC		15
+#define STB_LOCAL   0
+#define STB_GLOBAL  1
+#define STB_WEAK    2
+#define STB_LOPROC  13
+#define STB_HIPROC  15
 
 /**
  * Symbol types
  */
-#define STT_NOTYPE		0
-#define STT_OBJECT		1
-#define STT_FUNC		2
-#define STT_SECTION		3
-#define STT_FILE		4
-#define STT_LOPROC		13
-#define STT_HIPROC		15
+#define STT_NOTYPE   0
+#define STT_OBJECT   1
+#define STT_FUNC     2
+#define STT_SECTION  3
+#define STT_FILE     4
+#define STT_LOPROC   13
+#define STT_HIPROC   15
 
 /**
  * Program segment types
  */
-#define PT_NULL			0
-#define PT_LOAD			1
-#define PT_DYNAMIC		2
-#define PT_INTERP		3
-#define PT_NOTE			4
-#define PT_SHLIB		5
-#define PT_PHDR			6
-#define PT_LOPROC		0x70000000
-#define PT_HIPROC		0x7fffffff
+#define PT_NULL     0
+#define PT_LOAD     1
+#define PT_DYNAMIC  2
+#define PT_INTERP   3
+#define PT_NOTE     4
+#define PT_SHLIB    5
+#define PT_PHDR     6
+#define PT_LOPROC   0x70000000
+#define PT_HIPROC   0x7fffffff
 
 /**
  * Program segment attributes.
  */
-#define PF_X	1
-#define PF_W	2
-#define PF_R	4
+#define PF_X  1
+#define PF_W  2
+#define PF_R  4
 
 /**
@@ -195,4 +195,5 @@
  * ELF object file specifications. They are the only types used
  * in ELF header.
+ *
  */
 typedef uint64_t elf_xword;
@@ -206,4 +207,5 @@
  *
  * These types are specific for 32-bit format.
+ *
  */
 typedef uint32_t elf32_addr;
@@ -214,4 +216,5 @@
  *
  * These types are specific for 64-bit format.
+ *
  */
 typedef uint64_t elf64_addr;
@@ -235,4 +238,5 @@
 	elf_half e_shstrndx;
 };
+
 struct elf64_header {
 	uint8_t e_ident[EI_NIDENT];
@@ -252,5 +256,5 @@
 };
 
-/*
+/**
  * ELF segment header.
  * Segments headers are also known as program headers.
@@ -266,4 +270,5 @@
 	elf_word p_align;
 };
+
 struct elf64_segment_header {
 	elf_word p_type;
@@ -277,5 +282,5 @@
 };
 
-/*
+/**
  * ELF section header
  */
@@ -292,4 +297,5 @@
 	elf_word sh_entsize;
 };
+
 struct elf64_section_header {
 	elf_word sh_name;
@@ -305,5 +311,5 @@
 };
 
-/*
+/**
  * ELF symbol table entry
  */
@@ -316,4 +322,5 @@
 	elf_half st_shndx;
 };
+
 struct elf64_symbol {
 	elf_word st_name;
@@ -325,5 +332,5 @@
 };
 
-#ifdef __32_BITS__ 
+#ifdef __32_BITS__
 typedef struct elf32_header elf_header_t;
 typedef struct elf32_segment_header elf_segment_header_t;
@@ -331,4 +338,5 @@
 typedef struct elf32_symbol elf_symbol_t;
 #endif
+
 #ifdef __64_BITS__
 typedef struct elf64_header elf_header_t;
@@ -340,6 +348,6 @@
 extern const char *elf_error(unsigned int rc);
 
-/* Interpreter string used to recognize the program loader */
-#define ELF_INTERP_ZSTR "kernel"
+/** Interpreter string used to recognize the program loader */
+#define ELF_INTERP_ZSTR  "kernel"
 #define ELF_INTERP_ZLEN  sizeof(ELF_INTERP_ZSTR)
 
Index: kernel/generic/include/macros.h
===================================================================
--- kernel/generic/include/macros.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/generic/include/macros.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -39,4 +39,5 @@
 
 #include <typedefs.h>
+#include <trace.h>
 
 /** Return true if the intervals overlap.
@@ -46,11 +47,30 @@
  * @param s2  Start address of the second interval.
  * @param sz2 Size of the second interval.
+ *
  */
-static inline int overlaps(uintptr_t s1, size_t sz1, uintptr_t s2, size_t sz2)
+NO_TRACE static inline int overlaps(uint64_t s1, uint64_t sz1, uint64_t s2,
+    uint64_t sz2)
 {
-	uintptr_t e1 = s1 + sz1;
-	uintptr_t e2 = s2 + sz2;
+	uint64_t e1 = s1 + sz1;
+	uint64_t e2 = s2 + sz2;
 	
 	return ((s1 < e2) && (s2 < e1));
+}
+
+/** Return true if the second interval is within the first interval.
+ *
+ * @param s1  Start address of the first interval.
+ * @param sz1 Size of the first interval.
+ * @param s2  Start address of the second interval.
+ * @param sz2 Size of the second interval.
+ *
+ */
+NO_TRACE static inline int iswithin(uint64_t s1, uint64_t sz1, uint64_t s2,
+    uint64_t sz2)
+{
+	uint64_t e1 = s1 + sz1;
+	uint64_t e2 = s2 + sz2;
+	
+	return ((s1 <= s2) && (e1 >= e2));
 }
 
@@ -72,5 +92,5 @@
 
 /* Compute overlapping of physical addresses */
-#define PA_overlaps(x, szx, y, szy) \
+#define PA_OVERLAPS(x, szx, y, szy) \
 	overlaps(KA2PA((x)), (szx), KA2PA((y)), (szy))
 
Index: kernel/generic/include/main/main.h
===================================================================
--- kernel/generic/include/main/main.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/generic/include/main/main.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -32,5 +32,5 @@
 /** @file
  */
- 
+
 #ifndef KERN_MAIN_H_
 #define KERN_MAIN_H_
Index: kernel/generic/include/main/version.h
===================================================================
--- kernel/generic/include/main/version.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/generic/include/main/version.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -42,3 +42,2 @@
 /** @}
  */
-
Index: kernel/generic/include/mm/as.h
===================================================================
--- kernel/generic/include/mm/as.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/generic/include/mm/as.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -43,8 +43,8 @@
 
 /** Address space area flags. */
-#define AS_AREA_READ		1
-#define AS_AREA_WRITE		2
-#define AS_AREA_EXEC		4
-#define AS_AREA_CACHEABLE	8
+#define AS_AREA_READ       1
+#define AS_AREA_WRITE      2
+#define AS_AREA_EXEC       4
+#define AS_AREA_CACHEABLE  8
 
 /** Address space area info exported to userspace. */
@@ -52,10 +52,10 @@
 	/** Starting address */
 	uintptr_t start_addr;
-
+	
 	/** Area size */
 	size_t size;
-
+	
 	/** Area flags */
-	int flags;
+	unsigned int flags;
 } as_area_info_t;
 
@@ -75,27 +75,30 @@
  * Defined to be true if user address space and kernel address space shadow each
  * other.
- */
-#define KERNEL_ADDRESS_SPACE_SHADOWED	KERNEL_ADDRESS_SPACE_SHADOWED_ARCH
-
-#define KERNEL_ADDRESS_SPACE_START	KERNEL_ADDRESS_SPACE_START_ARCH
-#define KERNEL_ADDRESS_SPACE_END	KERNEL_ADDRESS_SPACE_END_ARCH
-#define USER_ADDRESS_SPACE_START	USER_ADDRESS_SPACE_START_ARCH
-#define USER_ADDRESS_SPACE_END		USER_ADDRESS_SPACE_END_ARCH
-
-#define USTACK_ADDRESS			USTACK_ADDRESS_ARCH
+ *
+ */
+#define KERNEL_ADDRESS_SPACE_SHADOWED  KERNEL_ADDRESS_SPACE_SHADOWED_ARCH
+
+#define KERNEL_ADDRESS_SPACE_START  KERNEL_ADDRESS_SPACE_START_ARCH
+#define KERNEL_ADDRESS_SPACE_END    KERNEL_ADDRESS_SPACE_END_ARCH
+#define USER_ADDRESS_SPACE_START    USER_ADDRESS_SPACE_START_ARCH
+#define USER_ADDRESS_SPACE_END      USER_ADDRESS_SPACE_END_ARCH
+
+#define USTACK_ADDRESS  USTACK_ADDRESS_ARCH
 
 /** Kernel address space. */
-#define FLAG_AS_KERNEL			(1 << 0)	
+#define FLAG_AS_KERNEL  (1 << 0)
 
 /* Address space area attributes. */
-#define AS_AREA_ATTR_NONE	0
-#define AS_AREA_ATTR_PARTIAL	1	/**< Not fully initialized area. */
+#define AS_AREA_ATTR_NONE     0
+#define AS_AREA_ATTR_PARTIAL  1  /**< Not fully initialized area. */
 
 /** The page fault was not resolved by as_page_fault(). */
-#define AS_PF_FAULT		0
+#define AS_PF_FAULT  0
+
 /** The page fault was resolved by as_page_fault(). */
-#define AS_PF_OK		1
+#define AS_PF_OK  1
+
 /** The page fault was caused by memcpy_from_uspace() or memcpy_to_uspace(). */
-#define AS_PF_DEFER		2
+#define AS_PF_DEFER  2
 
 /** Address space structure.
@@ -105,8 +108,10 @@
  * supposed to figure in the list as they are shared by all tasks and
  * set up during system initialization.
+ *
  */
 typedef struct as {
 	/** Protected by asidlock. */
 	link_t inactive_as_with_asid_link;
+	
 	/**
 	 * Number of processors on wich is this address space active.
@@ -114,4 +119,5 @@
 	 */
 	size_t cpu_refcount;
+	
 	/**
 	 * Address space identifier.
@@ -120,10 +126,10 @@
 	 */
 	asid_t asid;
-
+	
 	/** Number of references (i.e tasks that reference this as). */
 	atomic_t refcount;
-
+	
 	mutex_t lock;
-
+	
 	/** B+tree of address space areas. */
 	btree_t as_area_btree;
@@ -131,5 +137,5 @@
 	/** Non-generic content. */
 	as_genarch_t genarch;
-
+	
 	/** Architecture specific content. */
 	as_arch_t arch;
@@ -137,8 +143,9 @@
 
 typedef struct {
-	pte_t *(* page_table_create)(int flags);
-	void (* page_table_destroy)(pte_t *page_table);
-	void (* page_table_lock)(as_t *as, bool lock);
-	void (* page_table_unlock)(as_t *as, bool unlock);
+	pte_t *(* page_table_create)(unsigned int);
+	void (* page_table_destroy)(pte_t *);
+	void (* page_table_lock)(as_t *, bool);
+	void (* page_table_unlock)(as_t *, bool);
+	bool (* page_table_locked)(as_t *);
 } as_operations_t;
 
@@ -146,10 +153,12 @@
  * This structure contains information associated with the shared address space
  * area.
+ *
  */
 typedef struct {
 	/** This lock must be acquired only when the as_area lock is held. */
-	mutex_t lock;		
+	mutex_t lock;
 	/** This structure can be deallocated if refcount drops to 0. */
 	size_t refcount;
+	
 	/**
 	 * B+tree containing complete map of anonymous pages of the shared area.
@@ -162,5 +171,6 @@
 	PF_ACCESS_READ,
 	PF_ACCESS_WRITE,
-	PF_ACCESS_EXEC
+	PF_ACCESS_EXEC,
+	PF_ACCESS_UNKNOWN
 } pf_access_t;
 
@@ -169,9 +179,12 @@
 /** Backend data stored in address space area. */
 typedef union mem_backend_data {
-	struct {	/**< elf_backend members */
+	/** elf_backend members */
+	struct {
 		elf_header_t *elf;
 		elf_segment_header_t *segment;
 	};
-	struct {	/**< phys_backend members */
+	
+	/** phys_backend members */
+	struct {
 		uintptr_t base;
 		size_t frames;
@@ -182,15 +195,18 @@
  *
  * Each as_area_t structure describes one contiguous area of virtual memory.
+ *
  */
 typedef struct {
 	mutex_t lock;
 	/** Containing address space. */
-	as_t *as;		
+	as_t *as;
+	
 	/**
 	 * Flags related to the memory represented by the address space area.
 	 */
-	int flags;
+	unsigned int flags;
+	
 	/** Attributes related to the address space area itself. */
-	int attributes;
+	unsigned int attributes;
 	/** Size of this area in multiples of PAGE_SIZE. */
 	size_t pages;
@@ -199,5 +215,5 @@
 	/** Map of used space. */
 	btree_t used_space;
-
+	
 	/**
 	 * If the address space area has been shared, this pointer will
@@ -205,8 +221,8 @@
 	 */
 	share_info_t *sh_info;
-
+	
 	/** Memory backend backing this address space area. */
 	struct mem_backend *backend;
-
+	
 	/** Data to be used by the backend. */
 	mem_backend_data_t backend_data;
@@ -215,7 +231,7 @@
 /** Address space area backend structure. */
 typedef struct mem_backend {
-	int (* page_fault)(as_area_t *area, uintptr_t addr, pf_access_t access);
-	void (* frame_free)(as_area_t *area, uintptr_t page, uintptr_t frame);
-	void (* share)(as_area_t *area);
+	int (* page_fault)(as_area_t *, uintptr_t, pf_access_t);
+	void (* frame_free)(as_area_t *, uintptr_t, uintptr_t);
+	void (* share)(as_area_t *);
 } mem_backend_t;
 
@@ -227,5 +243,5 @@
 extern void as_init(void);
 
-extern as_t *as_create(int);
+extern as_t *as_create(unsigned int);
 extern void as_destroy(as_t *);
 extern void as_hold(as_t *);
@@ -234,12 +250,13 @@
 extern int as_page_fault(uintptr_t, pf_access_t, istate_t *);
 
-extern as_area_t *as_area_create(as_t *, int, size_t, uintptr_t, int,
-    mem_backend_t *, mem_backend_data_t *);
+extern as_area_t *as_area_create(as_t *, unsigned int, size_t, uintptr_t,
+    unsigned int, mem_backend_t *, mem_backend_data_t *);
 extern int as_area_destroy(as_t *, uintptr_t);
-extern int as_area_resize(as_t *, uintptr_t, size_t, int);
-extern int as_area_share(as_t *, uintptr_t, size_t, as_t *, uintptr_t, int);
-extern int as_area_change_flags(as_t *, int, uintptr_t);
-
-extern int as_area_get_flags(as_area_t *);
+extern int as_area_resize(as_t *, uintptr_t, size_t, unsigned int);
+extern int as_area_share(as_t *, uintptr_t, size_t, as_t *, uintptr_t,
+    unsigned int);
+extern int as_area_change_flags(as_t *, unsigned int, uintptr_t);
+
+extern unsigned int as_area_get_flags(as_area_t *);
 extern bool as_area_check_access(as_area_t *, pf_access_t);
 extern size_t as_area_get_size(uintptr_t);
@@ -249,16 +266,21 @@
 
 /* Interface to be implemented by architectures. */
+
 #ifndef as_constructor_arch
-extern int as_constructor_arch(as_t *, int);
+extern int as_constructor_arch(as_t *, unsigned int);
 #endif /* !def as_constructor_arch */
+
 #ifndef as_destructor_arch
 extern int as_destructor_arch(as_t *);
 #endif /* !def as_destructor_arch */
+
 #ifndef as_create_arch
-extern int as_create_arch(as_t *, int);
+extern int as_create_arch(as_t *, unsigned int);
 #endif /* !def as_create_arch */
+
 #ifndef as_install_arch
 extern void as_install_arch(as_t *);
 #endif /* !def as_install_arch */
+
 #ifndef as_deinstall_arch
 extern void as_deinstall_arch(as_t *);
@@ -270,17 +292,18 @@
 extern mem_backend_t phys_backend;
 
-/** 
+/**
  * This flags is passed when running the loader, otherwise elf_load()
  * would return with a EE_LOADER error code.
- */
-#define ELD_F_NONE	0
-#define ELD_F_LOADER	1
-
-extern unsigned int elf_load(elf_header_t *, as_t *, int);
+ *
+ */
+#define ELD_F_NONE    0
+#define ELD_F_LOADER  1
+
+extern unsigned int elf_load(elf_header_t *, as_t *, unsigned int);
 
 /* Address space area related syscalls. */
-extern unative_t sys_as_area_create(uintptr_t, size_t, int);
-extern unative_t sys_as_area_resize(uintptr_t, size_t, int);
-extern unative_t sys_as_area_change_flags(uintptr_t, int);
+extern unative_t sys_as_area_create(uintptr_t, size_t, unsigned int);
+extern unative_t sys_as_area_resize(uintptr_t, size_t, unsigned int);
+extern unative_t sys_as_area_change_flags(uintptr_t, unsigned int);
 extern unative_t sys_as_area_destroy(uintptr_t);
 
Index: kernel/generic/include/mm/frame.h
===================================================================
--- kernel/generic/include/mm/frame.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/generic/include/mm/frame.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -38,4 +38,5 @@
 
 #include <typedefs.h>
+#include <trace.h>
 #include <adt/list.h>
 #include <mm/buddy.h>
@@ -81,5 +82,5 @@
 
 typedef struct {
-	size_t refcount;     /**< Tracking of shared frames */
+	size_t refcount;      /**< Tracking of shared frames */
 	uint8_t buddy_order;  /**< Buddy system block order */
 	link_t buddy_link;    /**< Link to the next free block inside
@@ -91,8 +92,8 @@
 	pfn_t base;                    /**< Frame_no of the first frame
                                         in the frames array */
-	size_t count;                 /**< Size of zone */
-	size_t free_count;            /**< Number of free frame_t
+	size_t count;                  /**< Size of zone */
+	size_t free_count;             /**< Number of free frame_t
                                         structures */
-	size_t busy_count;            /**< Number of busy frame_t
+	size_t busy_count;             /**< Number of busy frame_t
                                         structures */
 	zone_flags_t flags;            /**< Type of the zone */
@@ -108,5 +109,5 @@
  */
 typedef struct {
-	SPINLOCK_DECLARE(lock);
+	IRQ_SPINLOCK_DECLARE(lock);
 	size_t count;
 	zone_t info[ZONES_MAX];
@@ -115,15 +116,15 @@
 extern zones_t zones;
 
-static inline uintptr_t PFN2ADDR(pfn_t frame)
+NO_TRACE static inline uintptr_t PFN2ADDR(pfn_t frame)
 {
 	return (uintptr_t) (frame << FRAME_WIDTH);
 }
 
-static inline pfn_t ADDR2PFN(uintptr_t addr)
+NO_TRACE static inline pfn_t ADDR2PFN(uintptr_t addr)
 {
 	return (pfn_t) (addr >> FRAME_WIDTH);
 }
 
-static inline size_t SIZE2FRAMES(size_t size)
+NO_TRACE static inline size_t SIZE2FRAMES(size_t size)
 {
 	if (!size)
@@ -132,10 +133,10 @@
 }
 
-static inline size_t FRAMES2SIZE(size_t frames)
+NO_TRACE static inline size_t FRAMES2SIZE(size_t frames)
 {
 	return (size_t) (frames << FRAME_WIDTH);
 }
 
-static inline bool zone_flags_available(zone_flags_t flags)
+NO_TRACE static inline bool zone_flags_available(zone_flags_t flags)
 {
 	return ((flags & (ZONE_RESERVED | ZONE_FIRMWARE)) == 0);
@@ -166,5 +167,5 @@
 extern void frame_set_parent(pfn_t, void *, size_t);
 extern void frame_mark_unavailable(pfn_t, size_t);
-extern uintptr_t zone_conf_size(size_t);
+extern size_t zone_conf_size(size_t);
 extern bool zone_merge(size_t, size_t);
 extern void zone_merge_all(void);
Index: kernel/generic/include/mm/page.h
===================================================================
--- kernel/generic/include/mm/page.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/generic/include/mm/page.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -42,8 +42,7 @@
 /** Operations to manipulate page mappings. */
 typedef struct {
-	void (* mapping_insert)(as_t *as, uintptr_t page, uintptr_t frame,
-	    int flags);
-	void (* mapping_remove)(as_t *as, uintptr_t page);
-	pte_t *(* mapping_find)(as_t *as, uintptr_t page);
+	void (* mapping_insert)(as_t *, uintptr_t, uintptr_t, unsigned int);
+	void (* mapping_remove)(as_t *, uintptr_t);
+	pte_t *(* mapping_find)(as_t *, uintptr_t);
 } page_mapping_operations_t;
 
@@ -51,15 +50,15 @@
 
 extern void page_init(void);
-extern void page_table_lock(as_t *as, bool lock);
-extern void page_table_unlock(as_t *as, bool unlock);
-extern void page_mapping_insert(as_t *as, uintptr_t page, uintptr_t frame,
-    int flags);
-extern void page_mapping_remove(as_t *as, uintptr_t page);
-extern pte_t *page_mapping_find(as_t *as, uintptr_t page);
-extern pte_t *page_table_create(int flags);
-extern void page_table_destroy(pte_t *page_table);
-extern void map_structure(uintptr_t s, size_t size);
+extern void page_table_lock(as_t *, bool);
+extern void page_table_unlock(as_t *, bool);
+extern bool page_table_locked(as_t *);
+extern void page_mapping_insert(as_t *, uintptr_t, uintptr_t, unsigned int);
+extern void page_mapping_remove(as_t *, uintptr_t);
+extern pte_t *page_mapping_find(as_t *, uintptr_t);
+extern pte_t *page_table_create(unsigned int);
+extern void page_table_destroy(pte_t *);
+extern void map_structure(uintptr_t, size_t);
 
-extern uintptr_t hw_map(uintptr_t physaddr, size_t size);
+extern uintptr_t hw_map(uintptr_t, size_t);
 
 #endif
Index: kernel/generic/include/mm/slab.h
===================================================================
--- kernel/generic/include/mm/slab.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/generic/include/mm/slab.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -84,5 +84,4 @@
 } slab_mag_cache_t;
 
-
 typedef struct {
 	const char *name;
@@ -94,13 +93,13 @@
 	size_t size;
 	
-	int (*constructor)(void *obj, int kmflag);
-	int (*destructor)(void *obj);
+	int (*constructor)(void *obj, unsigned int kmflag);
+	size_t (*destructor)(void *obj);
 	
 	/** Flags changing behaviour of cache */
-	int flags;
+	unsigned int flags;
 	
 	/* Computed values */
-	uint8_t order;         /**< Order of frames to be allocated */
-	unsigned int objects;  /**< Number of objects that fit in */
+	uint8_t order;   /**< Order of frames to be allocated */
+	size_t objects;  /**< Number of objects that fit in */
 	
 	/* Statistics */
@@ -109,5 +108,5 @@
 	atomic_t cached_objs;
 	/** How many magazines in magazines list */
-	atomic_t magazine_counter; 
+	atomic_t magazine_counter;
 	
 	/* Slabs */
@@ -124,10 +123,10 @@
 
 extern slab_cache_t *slab_cache_create(const char *, size_t, size_t,
-    int (*)(void *, int), int (*)(void *), int);
+    int (*)(void *, unsigned int), size_t (*)(void *), unsigned int);
 extern void slab_cache_destroy(slab_cache_t *);
 
-extern void * slab_alloc(slab_cache_t *, int);
+extern void * slab_alloc(slab_cache_t *, unsigned int);
 extern void slab_free(slab_cache_t *, void *);
-extern size_t slab_reclaim(int);
+extern size_t slab_reclaim(unsigned int);
 
 /* slab subsytem initialization */
@@ -139,6 +138,6 @@
 
 /* malloc support */
-extern void *malloc(unsigned int, int);
-extern void *realloc(void *, unsigned int, int);
+extern void *malloc(size_t, unsigned int);
+extern void *realloc(void *, size_t, unsigned int);
 extern void free(void *);
 
Index: kernel/generic/include/mm/tlb.h
===================================================================
--- kernel/generic/include/mm/tlb.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/generic/include/mm/tlb.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -68,11 +68,11 @@
 
 #ifdef CONFIG_SMP
-extern void tlb_shootdown_start(tlb_invalidate_type_t type, asid_t asid,
-    uintptr_t page, size_t count);
-extern void tlb_shootdown_finalize(void);
+extern ipl_t tlb_shootdown_start(tlb_invalidate_type_t, asid_t, uintptr_t,
+    size_t);
+extern void tlb_shootdown_finalize(ipl_t);
 extern void tlb_shootdown_ipi_recv(void);
 #else
-#define tlb_shootdown_start(w, x, y, z)
-#define tlb_shootdown_finalize()
+#define tlb_shootdown_start(w, x, y, z)	(0)
+#define tlb_shootdown_finalize(i)	((i) = (i));
 #define tlb_shootdown_ipi_recv()
 #endif /* CONFIG_SMP */
@@ -84,6 +84,6 @@
 
 extern void tlb_invalidate_all(void);
-extern void tlb_invalidate_asid(asid_t asid);
-extern void tlb_invalidate_pages(asid_t asid, uintptr_t page, size_t cnt);
+extern void tlb_invalidate_asid(asid_t);
+extern void tlb_invalidate_pages(asid_t, uintptr_t, size_t);
 #endif
 
Index: kernel/generic/include/panic.h
===================================================================
--- kernel/generic/include/panic.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/generic/include/panic.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2001-2004 Jakub Jermar
+ * Copyright (c) 2010 Jakub Jermar
  * All rights reserved.
  *
@@ -37,28 +37,30 @@
 
 #include <typedefs.h>
-#include <stacktrace.h>
-#include <print.h>
 
-#ifdef CONFIG_DEBUG
-#	define panic(format, ...) \
-		do { \
-			silent = false; \
-			printf("Kernel panic in %s() at %s:%u.\n", \
-			    __func__, __FILE__, __LINE__); \
-			stack_trace(); \
-			panic_printf("Panic message: " format "\n", \
-			    ##__VA_ARGS__);\
-		} while (0)
-#else
-#	define panic(format, ...) \
-		do { \
-			silent = false; \
-			panic_printf("Kernel panic: " format "\n", ##__VA_ARGS__); \
-		} while (0)
-#endif
+#define panic(fmt, ...) \
+	panic_common(PANIC_OTHER, NULL, 0, 0, fmt, ##__VA_ARGS__)
+
+#define panic_assert(fmt, ...) \
+	panic_common(PANIC_ASSERT, NULL, 0, 0, fmt, ##__VA_ARGS__)
+
+#define panic_badtrap(istate, n, fmt, ...) \
+	panic_common(PANIC_BADTRAP, istate, 0, n, fmt, ##__VA_ARGS__)
+
+#define panic_memtrap(istate, access, addr, fmt, ...) \
+	panic_common(PANIC_MEMTRAP, istate, access, addr, fmt, ##__VA_ARGS__)
+
+typedef enum {
+	PANIC_OTHER,
+	PANIC_ASSERT,
+	PANIC_BADTRAP,
+	PANIC_MEMTRAP
+} panic_category_t;
+
+struct istate;
 
 extern bool silent;
 
-extern void panic_printf(const char *fmt, ...) __attribute__((noreturn));
+extern void panic_common(panic_category_t, struct istate *, int,
+    uintptr_t, const char *, ...) __attribute__ ((noreturn));
 
 #endif
Index: kernel/generic/include/proc/scheduler.h
===================================================================
--- kernel/generic/include/proc/scheduler.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/generic/include/proc/scheduler.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -47,7 +47,7 @@
 /** Scheduler run queue structure. */
 typedef struct {
-	SPINLOCK_DECLARE(lock);
-	link_t rq_head;          /**< List of ready threads. */
-	size_t n;                /**< Number of threads in rq_ready. */
+	IRQ_SPINLOCK_DECLARE(lock);
+	link_t rq_head;              /**< List of ready threads. */
+	size_t n;                    /**< Number of threads in rq_ready. */
 } runq_t;
 
Index: kernel/generic/include/proc/task.h
===================================================================
--- kernel/generic/include/proc/task.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/generic/include/proc/task.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -40,5 +40,4 @@
 #include <synch/spinlock.h>
 #include <synch/mutex.h>
-#include <synch/rwlock.h>
 #include <synch/futex.h>
 #include <adt/avl.h>
@@ -70,6 +69,6 @@
 	 * threads.
 	 */
-	SPINLOCK_DECLARE(lock);
-
+	IRQ_SPINLOCK_DECLARE(lock);
+	
 	char name[TASK_NAME_BUFLEN];
 	/** List of threads contained in this task. */
@@ -81,13 +80,13 @@
 	/** Task security context. */
 	context_id_t context;
-
+	
 	/** Number of references (i.e. threads). */
 	atomic_t refcount;
 	/** Number of threads that haven't exited yet. */
 	atomic_t lifecount;
-
+	
 	/** Task capabilities. */
 	cap_t capabilities;
-
+	
 	/* IPC stuff */
 	answerbox_t answerbox;  /**< Communication endpoint */
@@ -101,13 +100,13 @@
 	/** List of synchronous answerboxes. */
 	link_t sync_box_head;
-
+	
 #ifdef CONFIG_UDEBUG
 	/** Debugging stuff. */
 	udebug_task_t udebug;
-
+	
 	/** Kernel answerbox. */
 	kbox_t kb;
-#endif
-
+#endif /* CONFIG_UDEBUG */
+	
 	/** Architecture specific task data. */
 	task_arch_t arch;
@@ -126,5 +125,5 @@
 } task_t;
 
-SPINLOCK_EXTERN(tasks_lock);
+IRQ_SPINLOCK_EXTERN(tasks_lock);
 extern avltree_t tasks_tree;
 
@@ -138,5 +137,5 @@
 extern int task_kill(task_id_t);
 extern void task_get_accounting(task_t *, uint64_t *, uint64_t *);
-extern void task_print_list(void);
+extern void task_print_list(bool);
 
 extern void cap_set(task_t *, cap_t);
Index: kernel/generic/include/proc/thread.h
===================================================================
--- kernel/generic/include/proc/thread.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/generic/include/proc/thread.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -40,5 +40,4 @@
 #include <time/timeout.h>
 #include <cpu.h>
-#include <synch/rwlock.h>
 #include <synch/spinlock.h>
 #include <adt/avl.h>
@@ -50,6 +49,6 @@
 #include <sysinfo/abi.h>
 
-#define THREAD_STACK_SIZE	STACK_SIZE
-#define THREAD_NAME_BUFLEN	20
+#define THREAD_STACK_SIZE   STACK_SIZE
+#define THREAD_NAME_BUFLEN  20
 
 extern const char *thread_states[];
@@ -61,19 +60,23 @@
  * When using this flag, the caller must set cpu in the thread_t
  * structure manually before calling thread_ready (even on uniprocessor).
- */ 
-#define THREAD_FLAG_WIRED	(1 << 0)
+ *
+ */
+#define THREAD_FLAG_WIRED  (1 << 0)
+
 /** Thread was migrated to another CPU and has not run yet. */
-#define THREAD_FLAG_STOLEN	(1 << 1)
+#define THREAD_FLAG_STOLEN  (1 << 1)
+
 /** Thread executes in userspace. */
-#define THREAD_FLAG_USPACE	(1 << 2)
+#define THREAD_FLAG_USPACE  (1 << 2)
+
 /** Thread will be attached by the caller. */
-#define THREAD_FLAG_NOATTACH	(1 << 3)
+#define THREAD_FLAG_NOATTACH  (1 << 3)
 
 /** Thread structure. There is one per thread. */
 typedef struct thread {
-	link_t rq_link;		/**< Run queue link. */
-	link_t wq_link;		/**< Wait queue link. */
-	link_t th_link;		/**< Links to threads within containing task. */
-
+	link_t rq_link;  /**< Run queue link. */
+	link_t wq_link;  /**< Wait queue link. */
+	link_t th_link;  /**< Links to threads within containing task. */
+	
 	/** Threads linkage to the threads_tree. */
 	avltree_node_t threads_tree_node;
@@ -83,13 +86,13 @@
 	 * Protects the whole thread structure except list links above.
 	 */
-	SPINLOCK_DECLARE(lock);
-
+	IRQ_SPINLOCK_DECLARE(lock);
+	
 	char name[THREAD_NAME_BUFLEN];
-
+	
 	/** Function implementing the thread. */
 	void (* thread_code)(void *);
 	/** Argument passed to thread_code() function. */
 	void *thread_arg;
-
+	
 	/**
 	 * From here, the stored context is restored when the thread is
@@ -107,5 +110,5 @@
 	 */
 	context_t sleep_interruption_context;
-
+	
 	/** If true, the thread can be interrupted from sleep. */
 	bool sleep_interruptible;
@@ -115,6 +118,6 @@
 	timeout_t sleep_timeout;
 	/** Flag signalling sleep timeout in progress. */
-	volatile int timeout_pending;
-
+	volatile bool timeout_pending;
+	
 	/**
 	 * True if this thread is executing copy_from_uspace().
@@ -132,5 +135,5 @@
 	 * thread_exit() before returning to userspace.
 	 */
-	bool interrupted;			
+	bool interrupted;
 	
 	/** If true, thread_join_timeout() cannot be used on this thread. */
@@ -140,8 +143,8 @@
 	/** Link used in the joiner_head list. */
 	link_t joiner_link;
-
+	
 	fpu_context_t *saved_fpu_context;
 	int fpu_context_exists;
-
+	
 	/*
 	 * Defined only if thread doesn't run.
@@ -150,16 +153,9 @@
 	 */
 	int fpu_context_engaged;
-
-	rwlock_type_t rwlock_holder_type;
-
-	/** Callback fired in scheduler before the thread is put asleep. */
-	void (* call_me)(void *);
-	/** Argument passed to call_me(). */
-	void *call_me_with;
-
+	
 	/** Thread's state. */
 	state_t state;
 	/** Thread's flags. */
-	int flags;
+	unsigned int flags;
 	
 	/** Thread's CPU. */
@@ -167,5 +163,5 @@
 	/** Containing task. */
 	task_t *task;
-
+	
 	/** Ticks before preemption. */
 	uint64_t ticks;
@@ -176,7 +172,7 @@
 	/** Last sampled cycle. */
 	uint64_t last_cycle;
-	/** Thread doesn't affect accumulated accounting. */	
+	/** Thread doesn't affect accumulated accounting. */
 	bool uncounted;
-
+	
 	/** Thread's priority. Implemented as index to CPU->rq */
 	int priority;
@@ -186,13 +182,12 @@
 	/** Architecture-specific data. */
 	thread_arch_t arch;
-
+	
 	/** Thread's kernel stack. */
 	uint8_t *kstack;
-
+	
 #ifdef CONFIG_UDEBUG
 	/** Debugging stuff */
 	udebug_thread_t udebug;
-#endif
-
+#endif /* CONFIG_UDEBUG */
 } thread_t;
 
@@ -203,5 +198,5 @@
  *
  */
-SPINLOCK_EXTERN(threads_lock);
+IRQ_SPINLOCK_EXTERN(threads_lock);
 
 /** AVL tree containing all threads. */
@@ -209,6 +204,6 @@
 
 extern void thread_init(void);
-extern thread_t *thread_create(void (*)(void *), void *, task_t *, int,
-    const char *, bool);
+extern thread_t *thread_create(void (*)(void *), void *, task_t *,
+    unsigned int, const char *, bool);
 extern void thread_attach(thread_t *, task_t *);
 extern void thread_ready(thread_t *);
@@ -218,7 +213,9 @@
 extern void thread_create_arch(thread_t *);
 #endif
+
 #ifndef thr_constructor_arch
 extern void thr_constructor_arch(thread_t *);
 #endif
+
 #ifndef thr_destructor_arch
 extern void thr_destructor_arch(thread_t *);
@@ -230,10 +227,10 @@
 #define thread_join(t) \
 	thread_join_timeout((t), SYNCH_NO_TIMEOUT, SYNCH_FLAGS_NONE)
-extern int thread_join_timeout(thread_t *, uint32_t, int);
+
+extern int thread_join_timeout(thread_t *, uint32_t, unsigned int);
 extern void thread_detach(thread_t *);
 
-extern void thread_register_call_me(void (*)(void *), void *);
-extern void thread_print_list(void);
-extern void thread_destroy(thread_t *);
+extern void thread_print_list(bool);
+extern void thread_destroy(thread_t *, bool);
 extern thread_t *thread_find_by_id(thread_id_t);
 extern void thread_update_accounting(bool);
Index: kernel/generic/include/security/cap.h
===================================================================
--- kernel/generic/include/security/cap.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/generic/include/security/cap.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -27,5 +27,5 @@
  */
 
-/** @addtogroup generic 
+/** @addtogroup generic
  * @{
  */
@@ -35,5 +35,5 @@
 /**
  * @file
- * @brief	Capabilities definitions.
+ * @brief Capabilities definitions.
  *
  * Capabilities represent virtual rights that entitle their
@@ -70,12 +70,7 @@
 
 /**
- * CAP_PREEMPT_CONTROL allows its holder to disable/enable preemption.
- */
-#define CAP_PREEMPT_CONTROL	(1<<3)
-
-/**
  * CAP_IRQ_REG entitles its holder to register IRQ handlers.
  */
-#define CAP_IRQ_REG		(1<<4) 
+#define CAP_IRQ_REG		(1<<3) 
 
 typedef uint32_t cap_t;
Index: kernel/generic/include/smp/ipi.h
===================================================================
--- kernel/generic/include/smp/ipi.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/generic/include/smp/ipi.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -43,5 +43,5 @@
 #else
 
-	#define ipi_broadcast(ipi)
+#define ipi_broadcast(ipi)
 
 #endif /* CONFIG_SMP */
Index: kernel/generic/include/smp/smp.h
===================================================================
--- kernel/generic/include/smp/smp.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/generic/include/smp/smp.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -27,5 +27,5 @@
  */
 
-/** @addtogroup generic	
+/** @addtogroup generic
  * @{
  */
@@ -41,8 +41,12 @@
 
 #ifdef CONFIG_SMP
+
 extern void smp_init(void);
 extern void kmp(void *arg);
-#else
+
+#else /* CONFIG_SMP */
+
 #define smp_init()
+
 #endif /* CONFIG_SMP */
 
Index: kernel/generic/include/sort.h
===================================================================
--- kernel/generic/include/sort.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/generic/include/sort.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -38,17 +38,8 @@
 #include <typedefs.h>
 
-/* 
- * sorting routines
- */
-extern void bubblesort(void * data, size_t n, size_t e_size, int (* cmp) (void * a, void * b));
-extern void qsort(void * data, size_t n, size_t e_size, int (* cmp) (void * a, void * b));
+typedef int (* sort_cmp_t)(void *, void *, void *);
 
-/*
- * default sorting comparators
- */
-extern int int_cmp(void * a, void * b);
-extern int uint32_t_cmp(void * a, void * b);
-extern int uint16_t_cmp(void * a, void * b);
-extern int uint8_t_cmp(void * a, void * b);
+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 a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/generic/include/stacktrace.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -38,11 +38,17 @@
 #include <typedefs.h>
 
-/* Forward declarations. */
+/* Forward declaration. */
 struct istate;
 
 typedef struct {
-	bool (* frame_pointer_validate)(uintptr_t);
-	bool (* frame_pointer_prev)(uintptr_t, uintptr_t *);
-	bool (* return_address_get)(uintptr_t, uintptr_t *);
+	uintptr_t fp;
+	uintptr_t pc;
+	struct istate *istate;
+} stack_trace_context_t;
+
+typedef struct {
+	bool (* stack_trace_context_validate)(stack_trace_context_t *);
+	bool (* frame_pointer_prev)(stack_trace_context_t *, uintptr_t *);
+	bool (* return_address_get)(stack_trace_context_t *, uintptr_t *);
 	bool (* symbol_resolve)(uintptr_t, const char **, uintptr_t *);
 } stack_trace_ops_t;
@@ -53,5 +59,5 @@
 extern void stack_trace(void);
 extern void stack_trace_istate(struct istate *);
-extern void stack_trace_fp_pc(stack_trace_ops_t *, uintptr_t, uintptr_t);
+extern void stack_trace_ctx(stack_trace_ops_t *, stack_trace_context_t *);
 
 /*
@@ -61,11 +67,11 @@
 extern uintptr_t program_counter_get(void);
 
-extern bool kernel_frame_pointer_validate(uintptr_t);
-extern bool kernel_frame_pointer_prev(uintptr_t, uintptr_t *);
-extern bool kernel_return_address_get(uintptr_t, uintptr_t *);
+extern bool kernel_stack_trace_context_validate(stack_trace_context_t *);
+extern bool kernel_frame_pointer_prev(stack_trace_context_t *, uintptr_t *);
+extern bool kernel_return_address_get(stack_trace_context_t *, uintptr_t *);
 
-extern bool uspace_frame_pointer_validate(uintptr_t);
-extern bool uspace_frame_pointer_prev(uintptr_t, uintptr_t *);
-extern bool uspace_return_address_get(uintptr_t, uintptr_t *);
+extern bool uspace_stack_trace_context_validate(stack_trace_context_t *);
+extern bool uspace_frame_pointer_prev(stack_trace_context_t *, uintptr_t *);
+extern bool uspace_return_address_get(stack_trace_context_t *, uintptr_t *);
 
 #endif
Index: kernel/generic/include/stdint.h
===================================================================
--- kernel/generic/include/stdint.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
+++ kernel/generic/include/stdint.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -0,0 +1,65 @@
+/*
+ * 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_STDINT_H_
+#define KERN_STDINT_H_
+
+#define INT8_MIN  (0x80)
+#define INT8_MAX  (0x7F)
+
+#define UINT8_MIN  (0u)
+#define UINT8_MAX  (0xFFu)
+
+#define INT16_MIN  (0x8000)
+#define INT16_MAX  (0x7FFF)
+
+#define UINT16_MIN  (0u)
+#define UINT16_MAX  (0xFFFFu)
+
+#define INT32_MIN  (0x80000000l)
+#define INT32_MAX  (0x7FFFFFFFl)
+
+#define UINT32_MIN  (0ul)
+#define UINT32_MAX  (0xFFFFFFFFul)
+
+#define INT64_MIN  (0x8000000000000000ll)
+#define INT64_MAX  (0x7FFFFFFFFFFFFFFFll)
+
+#define UINT64_MIN  (0ull)
+#define UINT64_MAX  (0xFFFFFFFFFFFFFFFFull)
+
+#endif
+
+/** @}
+ */
Index: kernel/generic/include/symtab.h
===================================================================
--- kernel/generic/include/symtab.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/generic/include/symtab.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -38,5 +38,5 @@
 #include <typedefs.h>
 
-#define MAX_SYMBOL_NAME 64
+#define MAX_SYMBOL_NAME  64
 
 struct symtab_entry {
@@ -53,8 +53,10 @@
 #ifdef CONFIG_SYMTAB
 
-/* Symtable linked together by build process */
+/** Symtable linked together by build process
+ *
+ */
 extern struct symtab_entry symbol_table[];
 
-#endif
+#endif /* CONFIG_SYMTAB */
 
 #endif
Index: kernel/generic/include/synch/mutex.h
===================================================================
--- kernel/generic/include/synch/mutex.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/generic/include/synch/mutex.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -50,13 +50,16 @@
 } mutex_t;
 
-#define mutex_lock(mtx)			\
+#define mutex_lock(mtx) \
 	_mutex_lock_timeout((mtx), SYNCH_NO_TIMEOUT, SYNCH_FLAGS_NONE)
-#define mutex_trylock(mtx)		\
+
+#define mutex_trylock(mtx) \
 	_mutex_lock_timeout((mtx), SYNCH_NO_TIMEOUT, SYNCH_FLAGS_NON_BLOCKING)
-#define mutex_lock_timeout(mtx, usec)	\
+
+#define mutex_lock_timeout(mtx, usec) \
 	_mutex_lock_timeout((mtx), (usec), SYNCH_FLAGS_NON_BLOCKING)
 
 extern void mutex_initialize(mutex_t *, mutex_type_t);
-extern int _mutex_lock_timeout(mutex_t *, uint32_t, int);
+extern bool mutex_locked(mutex_t *);
+extern int _mutex_lock_timeout(mutex_t *, uint32_t, unsigned int);
 extern void mutex_unlock(mutex_t *);
 
Index: rnel/generic/include/synch/rwlock.h
===================================================================
--- kernel/generic/include/synch/rwlock.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ 	(revision )
@@ -1,83 +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 sync
- * @{
- */
-/** @file
- */
-
-#ifndef KERN_RWLOCK_H_
-#define KERN_RWLOCK_H_
-
-#include <typedefs.h>
-#include <synch/mutex.h>
-#include <synch/synch.h>
-#include <synch/spinlock.h>
-
-typedef enum {
-	RWLOCK_NONE,
-	RWLOCK_READER,
-	RWLOCK_WRITER
-} rwlock_type_t;
-
-typedef struct {
-	SPINLOCK_DECLARE(lock);
-	/**
-	 * Mutex for writers, readers can bypass it if readers_in is positive.
-	 */
-	mutex_t exclusive;
-	/** Number of readers in critical section. */
-	size_t readers_in;
-} rwlock_t;
-
-#define rwlock_write_lock(rwl) \
-	_rwlock_write_lock_timeout((rwl), SYNCH_NO_TIMEOUT, SYNCH_FLAGS_NONE)
-#define rwlock_read_lock(rwl) \
-	_rwlock_read_lock_timeout((rwl), SYNCH_NO_TIMEOUT, SYNCH_FLAGS_NONE)
-#define rwlock_write_trylock(rwl) \
-	_rwlock_write_lock_timeout((rwl), SYNCH_NO_TIMEOUT, \
-	    SYNCH_FLAGS_NON_BLOCKING)
-#define rwlock_read_trylock(rwl) \
-	_rwlock_read_lock_timeout((rwl), SYNCH_NO_TIMEOUT, \
-	    SYNCH_FLAGS_NON_BLOCKING)
-#define rwlock_write_lock_timeout(rwl, usec) \
-	_rwlock_write_lock_timeout((rwl), (usec), SYNCH_FLAGS_NONE)
-#define rwlock_read_lock_timeout(rwl, usec) \
-	_rwlock_read_lock_timeout((rwl), (usec), SYNCH_FLAGS_NONE)
-
-extern void rwlock_initialize(rwlock_t *rwl);
-extern void rwlock_read_unlock(rwlock_t *rwl);
-extern void rwlock_write_unlock(rwlock_t *rwl);
-extern int _rwlock_read_lock_timeout(rwlock_t *rwl, uint32_t usec, int flags);
-extern int _rwlock_write_lock_timeout(rwlock_t *rwl, uint32_t usec, int flags);
-
-#endif
-
-/** @}
- */
Index: kernel/generic/include/synch/semaphore.h
===================================================================
--- kernel/generic/include/synch/semaphore.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/generic/include/synch/semaphore.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -46,12 +46,15 @@
 #define semaphore_down(s) \
 	_semaphore_down_timeout((s), SYNCH_NO_TIMEOUT, SYNCH_FLAGS_NONE)
+
 #define semaphore_trydown(s) \
 	_semaphore_down_timeout((s), SYNCH_NO_TIMEOUT, SYNCH_FLAGS_NON_BLOCKING)
+
 #define semaphore_down_timeout(s, usec) \
 	_semaphore_down_timeout((s), (usec), SYNCH_FLAGS_NONE)
 
-extern void semaphore_initialize(semaphore_t *s, int val);
-extern int _semaphore_down_timeout(semaphore_t *s, uint32_t usec, int flags);
-extern void semaphore_up(semaphore_t *s);
+extern void semaphore_initialize(semaphore_t *, int);
+extern int _semaphore_down_timeout(semaphore_t *, uint32_t, unsigned int);
+extern void semaphore_up(semaphore_t *);
+extern int semaphore_count_get(semaphore_t *);
 
 #endif
Index: kernel/generic/include/synch/spinlock.h
===================================================================
--- kernel/generic/include/synch/spinlock.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/generic/include/synch/spinlock.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -41,4 +41,5 @@
 #include <atomic.h>
 #include <debug.h>
+#include <arch/asm.h>
 
 #ifdef CONFIG_SMP
@@ -49,5 +50,5 @@
 #ifdef CONFIG_DEBUG_SPINLOCK
 	const char *name;
-#endif
+#endif /* CONFIG_DEBUG_SPINLOCK */
 } spinlock_t;
 
@@ -60,6 +61,7 @@
 
 /*
- * SPINLOCK_INITIALIZE is to be used for statically allocated spinlocks.
- * It declares and initializes the lock.
+ * SPINLOCK_INITIALIZE and SPINLOCK_STATIC_INITIALIZE are to be used
+ * for statically allocated spinlocks. They declare (either as global
+ * or static) symbol and initialize the lock.
  */
 #ifdef CONFIG_DEBUG_SPINLOCK
@@ -77,8 +79,11 @@
 	}
 
-#define spinlock_lock(lock)	spinlock_lock_debug((lock))
-#define spinlock_unlock(lock)	spinlock_unlock_debug((lock))
-
-#else
+#define ASSERT_SPINLOCK(expr, lock) \
+	ASSERT_VERBOSE(expr, (lock)->name)
+
+#define spinlock_lock(lock)    spinlock_lock_debug((lock))
+#define spinlock_unlock(lock)  spinlock_unlock_debug((lock))
+
+#else /* CONFIG_DEBUG_SPINLOCK */
 
 #define SPINLOCK_INITIALIZE_NAME(lock_name, desc_name) \
@@ -92,8 +97,11 @@
 	}
 
-#define spinlock_lock(lock)	atomic_lock_arch(&(lock)->val)
-#define spinlock_unlock(lock)	spinlock_unlock_nondebug((lock))
-
-#endif
+#define ASSERT_SPINLOCK(expr, lock) \
+	ASSERT(expr)
+
+#define spinlock_lock(lock)    atomic_lock_arch(&(lock)->val)
+#define spinlock_unlock(lock)  spinlock_unlock_nondebug((lock))
+
+#endif /* CONFIG_DEBUG_SPINLOCK */
 
 #define SPINLOCK_INITIALIZE(lock_name) \
@@ -103,8 +111,9 @@
 	SPINLOCK_STATIC_INITIALIZE_NAME(lock_name, #lock_name)
 
-extern void spinlock_initialize(spinlock_t *lock, const char *name);
-extern int spinlock_trylock(spinlock_t *lock);
-extern void spinlock_lock_debug(spinlock_t *lock);
-extern void spinlock_unlock_debug(spinlock_t *lock);
+extern void spinlock_initialize(spinlock_t *, const char *);
+extern int spinlock_trylock(spinlock_t *);
+extern void spinlock_lock_debug(spinlock_t *);
+extern void spinlock_unlock_debug(spinlock_t *);
+extern bool spinlock_locked(spinlock_t *);
 
 /** Unlock spinlock
@@ -113,6 +122,7 @@
  *
  * @param sl Pointer to spinlock_t structure.
- */
-static inline void spinlock_unlock_nondebug(spinlock_t *lock)
+ *
+ */
+NO_TRACE static inline void spinlock_unlock_nondebug(spinlock_t *lock)
 {
 	/*
@@ -141,10 +151,10 @@
 	}
 
-#else
+#else /* CONFIG_DEBUG_SPINLOCK */
 
 #define DEADLOCK_PROBE_INIT(pname)
 #define DEADLOCK_PROBE(pname, value)
 
-#endif
+#endif /* CONFIG_DEBUG_SPINLOCK */
 
 #else /* CONFIG_SMP */
@@ -160,4 +170,6 @@
 #define SPINLOCK_INITIALIZE_NAME(name, desc_name)
 #define SPINLOCK_STATIC_INITIALIZE_NAME(name, desc_name)
+
+#define ASSERT_SPINLOCK(expr, lock)  ASSERT(expr)
 
 #define spinlock_initialize(lock, name)
@@ -166,12 +178,116 @@
 #define spinlock_trylock(lock)  (preemption_disable(), 1)
 #define spinlock_unlock(lock)   preemption_enable()
+#define spinlock_locked(lock)	1
+#define spinlock_unlocked(lock)	1
 
 #define DEADLOCK_PROBE_INIT(pname)
 #define DEADLOCK_PROBE(pname, value)
 
+#endif /* CONFIG_SMP */
+
+typedef struct {
+	SPINLOCK_DECLARE(lock);  /**< Spinlock */
+	bool guard;              /**< Flag whether ipl is valid */
+	ipl_t ipl;               /**< Original interrupt level */
+} irq_spinlock_t;
+
+#define IRQ_SPINLOCK_DECLARE(lock_name)  irq_spinlock_t lock_name
+#define IRQ_SPINLOCK_EXTERN(lock_name)   extern irq_spinlock_t lock_name
+
+#ifdef CONFIG_SMP
+
+#define ASSERT_IRQ_SPINLOCK(expr, irq_lock) \
+	ASSERT_SPINLOCK(expr, &((irq_lock)->lock))
+
+/*
+ * IRQ_SPINLOCK_INITIALIZE and IRQ_SPINLOCK_STATIC_INITIALIZE are to be used
+ * for statically allocated interrupts-disabled spinlocks. They declare (either
+ * as global or static symbol) and initialize the lock.
+ */
+#ifdef CONFIG_DEBUG_SPINLOCK
+
+#define IRQ_SPINLOCK_INITIALIZE_NAME(lock_name, desc_name) \
+	irq_spinlock_t lock_name = { \
+		.lock = { \
+			.name = desc_name, \
+			.val = { 0 } \
+		}, \
+		.guard = false, \
+		.ipl = 0 \
+	}
+
+#define IRQ_SPINLOCK_STATIC_INITIALIZE_NAME(lock_name, desc_name) \
+	static irq_spinlock_t lock_name = { \
+		.lock = { \
+			.name = desc_name, \
+			.val = { 0 } \
+		}, \
+		.guard = false, \
+		.ipl = 0 \
+	}
+
+#else /* CONFIG_DEBUG_SPINLOCK */
+
+#define IRQ_SPINLOCK_INITIALIZE_NAME(lock_name, desc_name) \
+	irq_spinlock_t lock_name = { \
+		.lock = { \
+			.val = { 0 } \
+		}, \
+		.guard = false, \
+		.ipl = 0 \
+	}
+
+#define IRQ_SPINLOCK_STATIC_INITIALIZE_NAME(lock_name, desc_name) \
+	static irq_spinlock_t lock_name = { \
+		.lock = { \
+			.val = { 0 } \
+		}, \
+		.guard = false, \
+		.ipl = 0 \
+	}
+
+#endif /* CONFIG_DEBUG_SPINLOCK */
+
+#else /* CONFIG_SMP */
+
+/*
+ * Since the spinlocks are void on UP systems, we also need
+ * to have a special variant of interrupts-disabled spinlock
+ * macros which take this into account.
+ */
+
+#define ASSERT_IRQ_SPINLOCK(expr, irq_lock) \
+	ASSERT_SPINLOCK(expr, NULL)
+
+#define IRQ_SPINLOCK_INITIALIZE_NAME(lock_name, desc_name) \
+	irq_spinlock_t lock_name = { \
+		.guard = false, \
+		.ipl = 0 \
+	}
+
+#define IRQ_SPINLOCK_STATIC_INITIALIZE_NAME(lock_name, desc_name) \
+	static irq_spinlock_t lock_name = { \
+		.guard = false, \
+		.ipl = 0 \
+	}
+
+#endif /* CONFIG_SMP */
+
+#define IRQ_SPINLOCK_INITIALIZE(lock_name) \
+	IRQ_SPINLOCK_INITIALIZE_NAME(lock_name, #lock_name)
+
+#define IRQ_SPINLOCK_STATIC_INITIALIZE(lock_name) \
+	IRQ_SPINLOCK_STATIC_INITIALIZE_NAME(lock_name, #lock_name)
+
+extern void irq_spinlock_initialize(irq_spinlock_t *, const char *);
+extern void irq_spinlock_lock(irq_spinlock_t *, bool);
+extern void irq_spinlock_unlock(irq_spinlock_t *, bool);
+extern int irq_spinlock_trylock(irq_spinlock_t *);
+extern void irq_spinlock_pass(irq_spinlock_t *, irq_spinlock_t *);
+extern void irq_spinlock_exchange(irq_spinlock_t *, irq_spinlock_t *);
+extern bool irq_spinlock_locked(irq_spinlock_t *);
+
 #endif
 
-#endif
-
 /** @}
  */
Index: kernel/generic/include/synch/waitq.h
===================================================================
--- kernel/generic/include/synch/waitq.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/generic/include/synch/waitq.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -46,17 +46,20 @@
 } wakeup_mode_t;
 
-/** Wait queue structure. */
+/** Wait queue structure.
+ *
+ */
 typedef struct {
-
 	/** Lock protecting wait queue structure.
 	 *
 	 * Must be acquired before T.lock for each T of type thread_t.
 	 */
-	SPINLOCK_DECLARE(lock);
-
+	IRQ_SPINLOCK_DECLARE(lock);
+	
 	/**
 	 * Number of waitq_wakeup() calls that didn't find a thread to wake up.
+	 *
 	 */
 	int missed_wakeups;
+	
 	/** List of sleeping threads for wich there was no missed_wakeup. */
 	link_t head;
@@ -69,7 +72,7 @@
 
 extern void waitq_initialize(waitq_t *);
-extern int waitq_sleep_timeout(waitq_t *, uint32_t, int);
+extern int waitq_sleep_timeout(waitq_t *, uint32_t, unsigned int);
 extern ipl_t waitq_sleep_prepare(waitq_t *);
-extern int waitq_sleep_timeout_unsafe(waitq_t *, uint32_t, int);
+extern int waitq_sleep_timeout_unsafe(waitq_t *, uint32_t, unsigned int);
 extern void waitq_sleep_finish(waitq_t *, int, ipl_t);
 extern void waitq_wakeup(waitq_t *, wakeup_mode_t);
@@ -77,4 +80,6 @@
 extern void waitq_interrupt_sleep(struct thread *);
 extern void waitq_unsleep(waitq_t *);
+extern int waitq_count_get(waitq_t *);
+extern void waitq_count_set(waitq_t *, int val);
 
 #endif
Index: kernel/generic/include/syscall/sysarg64.h
===================================================================
--- kernel/generic/include/syscall/sysarg64.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/generic/include/syscall/sysarg64.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -33,5 +33,5 @@
 /**
  * @file
- * @brief	Wrapper for explicit 64-bit arguments passed to syscalls.
+ * @brief Wrapper for explicit 64-bit arguments passed to syscalls.
  */
 
Index: kernel/generic/include/syscall/syscall.h
===================================================================
--- kernel/generic/include/syscall/syscall.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/generic/include/syscall/syscall.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -80,5 +80,4 @@
 	SYS_PHYSMEM_MAP,
 	SYS_IOSPACE_ENABLE,
-	SYS_PREEMPT_CONTROL,
 	SYS_INTERRUPT_ENABLE,
 	
Index: kernel/generic/include/sysinfo/abi.h
===================================================================
--- kernel/generic/include/sysinfo/abi.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/generic/include/sysinfo/abi.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -38,8 +38,9 @@
 
 /** Number of load components */
-#define LOAD_STEPS        3
+#define LOAD_STEPS  3
 
-/** Maximum task name size */
+/** Maximum name sizes */
 #define TASK_NAME_BUFLEN  20
+#define EXC_NAME_BUFLEN   20
 
 /** Thread states */
@@ -65,9 +66,9 @@
  */
 typedef struct {
-	unsigned int id;         /**< CPU ID as stored by kernel */
+	size_t id;               /**< CPU ID as stored by kernel */
 	bool active;             /**< CPU is activate */
 	uint16_t frequency_mhz;  /**< Frequency in MHz */
-	uint64_t idle_ticks;     /**< Number of idle kernel quanta */
-	uint64_t busy_ticks;     /**< Number of busy kernel quanta */
+	uint64_t idle_cycles;    /**< Number of idle cycles */
+	uint64_t busy_cycles;    /**< Number of busy cycles */
 } stats_cpu_t;
 
@@ -89,8 +90,8 @@
 typedef struct {
 	uint64_t call_sent;           /**< IPC calls sent */
-	uint64_t call_recieved;       /**< IPC calls received */
+	uint64_t call_received;       /**< IPC calls received */
 	uint64_t answer_sent;         /**< IPC answers sent */
-	uint64_t answer_recieved;     /**< IPC answers received */
-	uint64_t irq_notif_recieved;  /**< IPC IRQ notifications */
+	uint64_t answer_received;     /**< IPC answers received */
+	uint64_t irq_notif_received;  /**< IPC IRQ notifications */
 	uint64_t forwarded;           /**< IPC messages forwarded */
 } stats_ipc_t;
@@ -123,4 +124,15 @@
 } stats_thread_t;
 
+/** Statistics about a single exception
+ *
+ */
+typedef struct {
+	unsigned int id;             /**< Exception ID */
+	char desc[EXC_NAME_BUFLEN];  /**< Description */
+	bool hot;                    /**< Active or inactive exception */
+	uint64_t cycles;             /**< Number of CPU cycles in the handler */
+	uint64_t count;              /**< Number of handled exceptions */
+} stats_exc_t;
+
 /** Load fixed-point value */
 typedef uint32_t load_t;
Index: kernel/generic/include/time/timeout.h
===================================================================
--- kernel/generic/include/time/timeout.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/generic/include/time/timeout.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -43,9 +43,9 @@
 
 typedef struct {
-	SPINLOCK_DECLARE(lock);
-
+	IRQ_SPINLOCK_DECLARE(lock);
+	
 	/** Link to the list of active timeouts on THE->cpu */
 	link_t link;
-	/** Timeout will be activated in this amount of clock() ticks. */	
+	/** Timeout will be activated in this amount of clock() ticks. */
 	uint64_t ticks;
 	/** Function that will be called on timeout activation. */
@@ -57,12 +57,11 @@
 } timeout_t;
 
-#define us2ticks(us)	((uint64_t) (((uint32_t) (us) / (1000000 / HZ))))
+#define us2ticks(us)  ((uint64_t) (((uint32_t) (us) / (1000000 / HZ))))
 
 extern void timeout_init(void);
-extern void timeout_initialize(timeout_t *t);
-extern void timeout_reinitialize(timeout_t *t);
-extern void timeout_register(timeout_t *t, uint64_t usec, timeout_handler_t f,
-    void *arg);
-extern bool timeout_unregister(timeout_t *t);
+extern void timeout_initialize(timeout_t *);
+extern void timeout_reinitialize(timeout_t *);
+extern void timeout_register(timeout_t *, uint64_t, timeout_handler_t, void *);
+extern bool timeout_unregister(timeout_t *);
 
 #endif
Index: kernel/generic/include/trace.h
===================================================================
--- kernel/generic/include/trace.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
+++ kernel/generic/include/trace.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2010 Martin Decky
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup genericdebug
+ * @{
+ */
+/** @file
+ */
+
+#ifndef KERN_TRACE_H_
+#define KERN_TRACE_H_
+
+#define NO_TRACE  __attribute__((no_instrument_function))
+
+#endif
+
+/** @}
+ */
Index: kernel/generic/include/typedefs.h
===================================================================
--- kernel/generic/include/typedefs.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/generic/include/typedefs.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -36,4 +36,5 @@
 #define KERN_TYPEDEFS_H_
 
+#include <stdint.h>
 #include <arch/common.h>
 #include <arch/types.h>
Index: kernel/generic/include/udebug/udebug_ipc.h
===================================================================
--- kernel/generic/include/udebug/udebug_ipc.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/generic/include/udebug/udebug_ipc.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -27,5 +27,5 @@
  */
 
-/** @addtogroup generic	
+/** @addtogroup generic
  * @{
  */
@@ -41,5 +41,4 @@
 void udebug_call_receive(call_t *call);
 
-
 #endif
 
Index: kernel/generic/include/udebug/udebug_ops.h
===================================================================
--- kernel/generic/include/udebug/udebug_ops.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/generic/include/udebug/udebug_ops.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -27,5 +27,5 @@
  */
 
-/** @addtogroup generic	
+/** @addtogroup generic
  * @{
  */
Index: kernel/generic/include/verify.h
===================================================================
--- kernel/generic/include/verify.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
+++ kernel/generic/include/verify.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2010 Martin Decky
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup genericverify
+ * @{
+ */
+/** @file
+ */
+
+#ifndef KERN_VERIFY_H_
+#define KERN_VERIFY_H_
+
+
+#ifdef CONFIG_VERIFY_VCC
+
+#define ATOMIC         __specification_attr("atomic_inline", "")
+
+#define READS(ptr)     __specification(reads(ptr))
+#define WRITES(ptr)    __specification(writes(ptr))
+#define REQUIRES(...)  __specification(requires __VA_ARGS__)
+
+#define EXTENT(ptr)              \extent(ptr)
+#define ARRAY_RANGE(ptr, nmemb)  \array_range(ptr, nmemb)
+
+#define REQUIRES_EXTENT_MUTABLE(ptr) \
+	REQUIRES(\extent_mutable(ptr))
+
+#define REQUIRES_ARRAY_MUTABLE(ptr, nmemb) \
+	REQUIRES(\mutable_array(ptr, nmemb))
+
+#else /* CONFIG_VERIFY_VCC */
+
+#define ATOMIC
+
+#define READS(ptr)
+#define WRITES(ptr)
+#define REQUIRES(...)
+
+#define EXTENT(ptr)
+#define ARRAY_RANGE(ptr, nmemb)
+
+#define REQUIRES_EXTENT_MUTABLE(ptr)
+#define REQUIRES_ARRAY_MUTABLE(ptr, nmemb)
+
+#endif /* CONFIG_VERIFY_VCC */
+
+
+#endif
+
+/** @}
+ */
Index: kernel/generic/src/adt/btree.c
===================================================================
--- kernel/generic/src/adt/btree.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/generic/src/adt/btree.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -33,5 +33,5 @@
 /**
  * @file
- * @brief	B+tree implementation.
+ * @brief B+tree implementation.
  *
  * This file implements B+tree type and operations.
@@ -53,40 +53,50 @@
 #include <panic.h>
 #include <print.h>
-
-static void btree_destroy_subtree(btree_node_t *root);
-static void _btree_insert(btree_t *t, btree_key_t key, void *value, btree_node_t *rsubtree, btree_node_t *node);
-static void _btree_remove(btree_t *t, btree_key_t key, btree_node_t *node);
-static void node_initialize(btree_node_t *node);
-static void node_insert_key_and_lsubtree(btree_node_t *node, btree_key_t key, void *value, btree_node_t *lsubtree);
-static void node_insert_key_and_rsubtree(btree_node_t *node, btree_key_t key, void *value, btree_node_t *rsubtree);
-static void node_remove_key_and_lsubtree(btree_node_t *node, btree_key_t key);
-static void node_remove_key_and_rsubtree(btree_node_t *node, btree_key_t key);
-static btree_node_t *node_split(btree_node_t *node, btree_key_t key, void *value, btree_node_t *rsubtree, btree_key_t *median);
-static btree_node_t *node_combine(btree_node_t *node);
-static size_t find_key_by_subtree(btree_node_t *node, btree_node_t *subtree, bool right);
-static void rotate_from_right(btree_node_t *lnode, btree_node_t *rnode, size_t idx);
-static void rotate_from_left(btree_node_t *lnode, btree_node_t *rnode, size_t idx);
-static bool try_insert_by_rotation_to_left(btree_node_t *node, btree_key_t key, void *value, btree_node_t *rsubtree);
-static bool try_insert_by_rotation_to_right(btree_node_t *node, btree_key_t key, void *value, btree_node_t *rsubtree);
-static bool try_rotation_from_left(btree_node_t *rnode);
-static bool try_rotation_from_right(btree_node_t *lnode);
-
-#define ROOT_NODE(n)		(!(n)->parent)
-#define INDEX_NODE(n)		((n)->subtree[0] != NULL)
-#define LEAF_NODE(n)		((n)->subtree[0] == NULL)
-
-#define FILL_FACTOR		((BTREE_M-1)/2)
-
-#define MEDIAN_LOW_INDEX(n)	(((n)->keys-1)/2)
-#define MEDIAN_HIGH_INDEX(n)	((n)->keys/2)
-#define MEDIAN_LOW(n)		((n)->key[MEDIAN_LOW_INDEX((n))]);
-#define MEDIAN_HIGH(n)		((n)->key[MEDIAN_HIGH_INDEX((n))]);
+#include <trace.h>
 
 static slab_cache_t *btree_node_slab;
+
+#define ROOT_NODE(n)   (!(n)->parent)
+#define INDEX_NODE(n)  ((n)->subtree[0] != NULL)
+#define LEAF_NODE(n)   ((n)->subtree[0] == NULL)
+
+#define FILL_FACTOR  ((BTREE_M - 1) / 2)
+
+#define MEDIAN_LOW_INDEX(n)   (((n)->keys-1) / 2)
+#define MEDIAN_HIGH_INDEX(n)  ((n)->keys / 2)
+#define MEDIAN_LOW(n)         ((n)->key[MEDIAN_LOW_INDEX((n))]);
+#define MEDIAN_HIGH(n)        ((n)->key[MEDIAN_HIGH_INDEX((n))]);
 
 /** Initialize B-trees. */
 void btree_init(void)
 {
-	btree_node_slab = slab_cache_create("btree_node_slab", sizeof(btree_node_t), 0, NULL, NULL, SLAB_CACHE_MAGDEFERRED);
+	btree_node_slab = slab_cache_create("btree_node_slab",
+	    sizeof(btree_node_t), 0, NULL, NULL, SLAB_CACHE_MAGDEFERRED);
+}
+
+/** Initialize B-tree node.
+ *
+ * @param node B-tree node.
+ *
+ */
+NO_TRACE static void node_initialize(btree_node_t *node)
+{
+	unsigned int i;
+	
+	node->keys = 0;
+	
+	/* Clean also space for the extra key. */
+	for (i = 0; i < BTREE_MAX_KEYS + 1; i++) {
+		node->key[i] = 0;
+		node->value[i] = NULL;
+		node->subtree[i] = NULL;
+	}
+	
+	node->subtree[i] = NULL;
+	node->parent = NULL;
+	
+	link_initialize(&node->leaf_link);
+	link_initialize(&node->bfs_link);
+	node->depth = 0;
 }
 
@@ -94,4 +104,5 @@
  *
  * @param t B-tree.
+ *
  */
 void btree_create(btree_t *t)
@@ -103,41 +114,13 @@
 }
 
-/** Destroy empty B-tree. */
-void btree_destroy(btree_t *t)
-{
-	btree_destroy_subtree(t->root);
-}
-
-/** Insert key-value pair into B-tree.
- *
- * @param t B-tree.
- * @param key Key to be inserted.
- * @param value Value to be inserted.
- * @param leaf_node Leaf node where the insertion should begin.
- */ 
-void btree_insert(btree_t *t, btree_key_t key, void *value, btree_node_t *leaf_node)
-{
-	btree_node_t *lnode;
-	
-	ASSERT(value);
-	
-	lnode = leaf_node;
-	if (!lnode) {
-		if (btree_search(t, key, &lnode)) {
-			panic("B-tree %p already contains key %" PRIu64 ".", t, key);
-		}
-	}
-	
-	_btree_insert(t, key, value, NULL, lnode);
-}
-
 /** Destroy subtree rooted in a node.
  *
  * @param root Root of the subtree.
- */
-void btree_destroy_subtree(btree_node_t *root)
+ *
+ */
+NO_TRACE static void btree_destroy_subtree(btree_node_t *root)
 {
 	size_t i;
-
+	
 	if (root->keys) {
 		for (i = 0; i < root->keys + 1; i++) { 
@@ -146,16 +129,434 @@
 		}
 	}
+	
 	slab_free(btree_node_slab, root);
 }
 
+/** Destroy empty B-tree. */
+void btree_destroy(btree_t *t)
+{
+	btree_destroy_subtree(t->root);
+}
+
+/** Insert key-value-rsubtree triplet into B-tree node.
+ *
+ * It is actually possible to have more keys than BTREE_MAX_KEYS.
+ * This feature is used during splitting the node when the
+ * number of keys is BTREE_MAX_KEYS + 1. Insert by left rotation
+ * also makes use of this feature.
+ *
+ * @param node     B-tree node into wich the new key is to be inserted.
+ * @param key      The key to be inserted.
+ * @param value    Pointer to value to be inserted.
+ * @param rsubtree Pointer to the right subtree.
+ *
+ */
+NO_TRACE static void node_insert_key_and_rsubtree(btree_node_t *node,
+    btree_key_t key, void *value, btree_node_t *rsubtree)
+{
+	size_t i;
+	
+	for (i = 0; i < node->keys; i++) {
+		if (key < node->key[i]) {
+			size_t j;
+			
+			for (j = node->keys; j > i; j--) {
+				node->key[j] = node->key[j - 1];
+				node->value[j] = node->value[j - 1];
+				node->subtree[j + 1] = node->subtree[j];
+			}
+			
+			break;
+		}
+	}
+	
+	node->key[i] = key;
+	node->value[i] = value;
+	node->subtree[i + 1] = rsubtree;
+	node->keys++;
+}
+
+/** Find key by its left or right subtree.
+ *
+ * @param node    B-tree node.
+ * @param subtree Left or right subtree of a key found in node.
+ * @param right   If true, subtree is a right subtree. If false,
+ *                subtree is a left subtree.
+ *
+ * @return Index of the key associated with the subtree.
+ *
+ */
+NO_TRACE static size_t find_key_by_subtree(btree_node_t *node,
+    btree_node_t *subtree, bool right)
+{
+	size_t i;
+	
+	for (i = 0; i < node->keys + 1; i++) {
+		if (subtree == node->subtree[i])
+			return i - (int) (right != false);
+	}
+	
+	panic("Node %p does not contain subtree %p.", node, subtree);
+}
+
+/** Remove key and its left subtree pointer from B-tree node.
+ *
+ * Remove the key and eliminate gaps in node->key array.
+ * Note that the value pointer and the left subtree pointer
+ * is removed from the node as well.
+ *
+ * @param node B-tree node.
+ * @param key  Key to be removed.
+ *
+ */
+NO_TRACE static void node_remove_key_and_lsubtree(btree_node_t *node,
+    btree_key_t key)
+{
+	size_t i;
+	size_t j;
+	
+	for (i = 0; i < node->keys; i++) {
+		if (key == node->key[i]) {
+			for (j = i + 1; j < node->keys; j++) {
+				node->key[j - 1] = node->key[j];
+				node->value[j - 1] = node->value[j];
+				node->subtree[j - 1] = node->subtree[j];
+			}
+			
+			node->subtree[j - 1] = node->subtree[j];
+			node->keys--;
+			
+			return;
+		}
+	}
+	
+	panic("Node %p does not contain key %" PRIu64 ".", node, key);
+}
+
+/** Remove key and its right subtree pointer from B-tree node.
+ *
+ * Remove the key and eliminate gaps in node->key array.
+ * Note that the value pointer and the right subtree pointer
+ * is removed from the node as well.
+ *
+ * @param node B-tree node.
+ * @param key  Key to be removed.
+ *
+ */
+NO_TRACE static void node_remove_key_and_rsubtree(btree_node_t *node,
+    btree_key_t key)
+{
+	size_t i, j;
+	
+	for (i = 0; i < node->keys; i++) {
+		if (key == node->key[i]) {
+			for (j = i + 1; j < node->keys; j++) {
+				node->key[j - 1] = node->key[j];
+				node->value[j - 1] = node->value[j];
+				node->subtree[j] = node->subtree[j + 1];
+			}
+			
+			node->keys--;
+			return;
+		}
+	}
+	
+	panic("Node %p does not contain key %" PRIu64 ".", node, key);
+}
+
+/** Insert key-value-lsubtree triplet into B-tree node.
+ *
+ * It is actually possible to have more keys than BTREE_MAX_KEYS.
+ * This feature is used during insert by right rotation.
+ *
+ * @param node     B-tree node into wich the new key is to be inserted.
+ * @param key      The key to be inserted.
+ * @param value    Pointer to value to be inserted.
+ * @param lsubtree Pointer to the left subtree.
+ *
+ */
+NO_TRACE static void node_insert_key_and_lsubtree(btree_node_t *node,
+    btree_key_t key, void *value, btree_node_t *lsubtree)
+{
+	size_t i;
+	
+	for (i = 0; i < node->keys; i++) {
+		if (key < node->key[i]) {
+			size_t j;
+			
+			for (j = node->keys; j > i; j--) {
+				node->key[j] = node->key[j - 1];
+				node->value[j] = node->value[j - 1];
+				node->subtree[j + 1] = node->subtree[j];
+			}
+			
+			node->subtree[j + 1] = node->subtree[j];
+			break;
+		}
+	}
+	
+	node->key[i] = key;
+	node->value[i] = value;
+	node->subtree[i] = lsubtree;
+	
+	node->keys++;
+}
+
+/** Rotate one key-value-rsubtree triplet from the left sibling to the right sibling.
+ *
+ * The biggest key and its value and right subtree is rotated
+ * from the left node to the right. If the node is an index node,
+ * than the parent node key belonging to the left node takes part
+ * in the rotation.
+ *
+ * @param lnode Left sibling.
+ * @param rnode Right sibling.
+ * @param idx   Index of the parent node key that is taking part
+ *              in the rotation.
+ *
+ */
+NO_TRACE static void rotate_from_left(btree_node_t *lnode, btree_node_t *rnode,
+    size_t idx)
+{
+	btree_key_t key = lnode->key[lnode->keys - 1];
+	
+	if (LEAF_NODE(lnode)) {
+		void *value = lnode->value[lnode->keys - 1];
+		
+		node_remove_key_and_rsubtree(lnode, key);
+		node_insert_key_and_lsubtree(rnode, key, value, NULL);
+		lnode->parent->key[idx] = key;
+	} else {
+		btree_node_t *rsubtree = lnode->subtree[lnode->keys];
+		
+		node_remove_key_and_rsubtree(lnode, key);
+		node_insert_key_and_lsubtree(rnode, lnode->parent->key[idx], NULL, rsubtree);
+		lnode->parent->key[idx] = key;
+		
+		/* Fix parent link of the reconnected right subtree. */
+		rsubtree->parent = rnode;
+	}
+}
+
+/** Rotate one key-value-lsubtree triplet from the right sibling to the left sibling.
+ *
+ * The smallest key and its value and left subtree is rotated
+ * from the right node to the left. If the node is an index node,
+ * than the parent node key belonging to the right node takes part
+ * in the rotation.
+ *
+ * @param lnode Left sibling.
+ * @param rnode Right sibling.
+ * @param idx   Index of the parent node key that is taking part
+ *              in the rotation.
+ *
+ */
+NO_TRACE static void rotate_from_right(btree_node_t *lnode, btree_node_t *rnode,
+    size_t idx)
+{
+	btree_key_t key = rnode->key[0];
+	
+	if (LEAF_NODE(rnode)) {
+		void *value = rnode->value[0];
+		
+		node_remove_key_and_lsubtree(rnode, key);
+		node_insert_key_and_rsubtree(lnode, key, value, NULL);
+		rnode->parent->key[idx] = rnode->key[0];
+	} else {
+		btree_node_t *lsubtree = rnode->subtree[0];
+		
+		node_remove_key_and_lsubtree(rnode, key);
+		node_insert_key_and_rsubtree(lnode, rnode->parent->key[idx], NULL, lsubtree);
+		rnode->parent->key[idx] = key;
+		
+		/* Fix parent link of the reconnected left subtree. */
+		lsubtree->parent = lnode;
+	}
+}
+
+/** Insert key-value-rsubtree triplet and rotate the node to the left, if this operation can be done.
+ *
+ * Left sibling of the node (if it exists) is checked for free space.
+ * If there is free space, the key is inserted and the smallest key of
+ * the node is moved there. The index node which is the parent of both
+ * nodes is fixed.
+ *
+ * @param node     B-tree node.
+ * @param inskey   Key to be inserted.
+ * @param insvalue Value to be inserted.
+ * @param rsubtree Right subtree of inskey.
+ *
+ * @return True if the rotation was performed, false otherwise.
+ *
+ */
+NO_TRACE static bool try_insert_by_rotation_to_left(btree_node_t *node,
+    btree_key_t inskey, void *insvalue, btree_node_t *rsubtree)
+{
+	size_t idx;
+	btree_node_t *lnode;
+	
+	/*
+	 * If this is root node, the rotation can not be done.
+	 */
+	if (ROOT_NODE(node))
+		return false;
+	
+	idx = find_key_by_subtree(node->parent, node, true);
+	if ((int) idx == -1) {
+		/*
+		 * If this node is the leftmost subtree of its parent,
+		 * the rotation can not be done.
+		 */
+		return false;
+	}
+	
+	lnode = node->parent->subtree[idx];
+	if (lnode->keys < BTREE_MAX_KEYS) {
+		/*
+		 * The rotaion can be done. The left sibling has free space.
+		 */
+		node_insert_key_and_rsubtree(node, inskey, insvalue, rsubtree);
+		rotate_from_right(lnode, node, idx);
+		return true;
+	}
+	
+	return false;
+}
+
+/** Insert key-value-rsubtree triplet and rotate the node to the right, if this operation can be done.
+ *
+ * Right sibling of the node (if it exists) is checked for free space.
+ * If there is free space, the key is inserted and the biggest key of
+ * the node is moved there. The index node which is the parent of both
+ * nodes is fixed.
+ *
+ * @param node     B-tree node.
+ * @param inskey   Key to be inserted.
+ * @param insvalue Value to be inserted.
+ * @param rsubtree Right subtree of inskey.
+ *
+ * @return True if the rotation was performed, false otherwise.
+ *
+ */
+NO_TRACE static bool try_insert_by_rotation_to_right(btree_node_t *node,
+    btree_key_t inskey, void *insvalue, btree_node_t *rsubtree)
+{
+	size_t idx;
+	btree_node_t *rnode;
+	
+	/*
+	 * If this is root node, the rotation can not be done.
+	 */
+	if (ROOT_NODE(node))
+		return false;
+	
+	idx = find_key_by_subtree(node->parent, node, false);
+	if (idx == node->parent->keys) {
+		/*
+		 * If this node is the rightmost subtree of its parent,
+		 * the rotation can not be done.
+		 */
+		return false;
+	}
+	
+	rnode = node->parent->subtree[idx + 1];
+	if (rnode->keys < BTREE_MAX_KEYS) {
+		/*
+		 * The rotaion can be done. The right sibling has free space.
+		 */
+		node_insert_key_and_rsubtree(node, inskey, insvalue, rsubtree);
+		rotate_from_left(node, rnode, idx);
+		return true;
+	}
+	
+	return false;
+}
+
+/** Split full B-tree node and insert new key-value-right-subtree triplet.
+ *
+ * This function will split a node and return a pointer to a newly created
+ * node containing keys greater than or equal to the greater of medians
+ * (or median) of the old keys and the newly added key. It will also write
+ * the median key to a memory address supplied by the caller.
+ *
+ * If the node being split is an index node, the median will not be
+ * included in the new node. If the node is a leaf node,
+ * the median will be copied there.
+ *
+ * @param node     B-tree node wich is going to be split.
+ * @param key      The key to be inserted.
+ * @param value    Pointer to the value to be inserted.
+ * @param rsubtree Pointer to the right subtree of the key being added.
+ * @param median   Address in memory, where the median key will be stored.
+ *
+ * @return Newly created right sibling of node.
+ *
+ */
+NO_TRACE static btree_node_t *node_split(btree_node_t *node, btree_key_t key,
+    void *value, btree_node_t *rsubtree, btree_key_t *median)
+{
+	btree_node_t *rnode;
+	size_t i;
+	size_t j;
+	
+	ASSERT(median);
+	ASSERT(node->keys == BTREE_MAX_KEYS);
+	
+	/*
+	 * Use the extra space to store the extra node.
+	 */
+	node_insert_key_and_rsubtree(node, key, value, rsubtree);
+	
+	/*
+	 * Compute median of keys.
+	 */
+	*median = MEDIAN_HIGH(node);
+	
+	/*
+	 * Allocate and initialize new right sibling.
+	 */
+	rnode = (btree_node_t *) slab_alloc(btree_node_slab, 0);
+	node_initialize(rnode);
+	rnode->parent = node->parent;
+	rnode->depth = node->depth;
+	
+	/*
+	 * Copy big keys, values and subtree pointers to the new right sibling.
+	 * If this is an index node, do not copy the median.
+	 */
+	i = (size_t) INDEX_NODE(node);
+	for (i += MEDIAN_HIGH_INDEX(node), j = 0; i < node->keys; i++, j++) {
+		rnode->key[j] = node->key[i];
+		rnode->value[j] = node->value[i];
+		rnode->subtree[j] = node->subtree[i];
+		
+		/*
+		 * Fix parent links in subtrees.
+		 */
+		if (rnode->subtree[j])
+			rnode->subtree[j]->parent = rnode;
+	}
+	
+	rnode->subtree[j] = node->subtree[i];
+	if (rnode->subtree[j])
+		rnode->subtree[j]->parent = rnode;
+	
+	rnode->keys = j;  /* Set number of keys of the new node. */
+	node->keys /= 2;  /* Shrink the old node. */
+	
+	return rnode;
+}
+
 /** Recursively insert into B-tree.
  *
- * @param t B-tree.
- * @param key Key to be inserted.
- * @param value Value to be inserted.
+ * @param t        B-tree.
+ * @param key      Key to be inserted.
+ * @param value    Value to be inserted.
  * @param rsubtree Right subtree of the inserted key.
- * @param node Start inserting into this node.
- */
-void _btree_insert(btree_t *t, btree_key_t key, void *value, btree_node_t *rsubtree, btree_node_t *node)
+ * @param node     Start inserting into this node.
+ *
+ */
+NO_TRACE static void _btree_insert(btree_t *t, btree_key_t key, void *value,
+    btree_node_t *rsubtree, btree_node_t *node)
 {
 	if (node->keys < BTREE_MAX_KEYS) {
@@ -183,7 +584,7 @@
 		 * bigger keys (i.e. the new node) into its parent.
 		 */
-
+		
 		rnode = node_split(node, key, value, rsubtree, &median);
-
+		
 		if (LEAF_NODE(node)) {
 			list_prepend(&rnode->leaf_link, &node->leaf_link);
@@ -202,44 +603,175 @@
 			 * Left-hand side subtree will be the old root (i.e. node).
 			 * Right-hand side subtree will be rnode.
-			 */			
+			 */
 			t->root->subtree[0] = node;
-
+			
 			t->root->depth = node->depth + 1;
 		}
 		_btree_insert(t, median, NULL, rnode, node->parent);
-	}	
-		
-}
-
-/** Remove B-tree node.
- *
- * @param t B-tree.
- * @param key Key to be removed from the B-tree along with its associated value.
- * @param leaf_node If not NULL, pointer to the leaf node where the key is found.
- */
-void btree_remove(btree_t *t, btree_key_t key, btree_node_t *leaf_node)
+	}
+}
+
+/** Insert key-value pair into B-tree.
+ *
+ * @param t         B-tree.
+ * @param key       Key to be inserted.
+ * @param value     Value to be inserted.
+ * @param leaf_node Leaf node where the insertion should begin.
+ *
+ */
+void btree_insert(btree_t *t, btree_key_t key, void *value,
+    btree_node_t *leaf_node)
 {
 	btree_node_t *lnode;
+	
+	ASSERT(value);
 	
 	lnode = leaf_node;
 	if (!lnode) {
-		if (!btree_search(t, key, &lnode)) {
-			panic("B-tree %p does not contain key %" PRIu64 ".", t, key);
-		}
-	}
-	
-	_btree_remove(t, key, lnode);
+		if (btree_search(t, key, &lnode))
+			panic("B-tree %p already contains key %" PRIu64 ".", t, key);
+	}
+	
+	_btree_insert(t, key, value, NULL, lnode);
+}
+
+/** Rotate in a key from the left sibling or from the index node, if this operation can be done.
+ *
+ * @param rnode Node into which to add key from its left sibling
+ *              or from the index node.
+ *
+ * @return True if the rotation was performed, false otherwise.
+ *
+ */
+NO_TRACE static bool try_rotation_from_left(btree_node_t *rnode)
+{
+	size_t idx;
+	btree_node_t *lnode;
+	
+	/*
+	 * If this is root node, the rotation can not be done.
+	 */
+	if (ROOT_NODE(rnode))
+		return false;
+	
+	idx = find_key_by_subtree(rnode->parent, rnode, true);
+	if ((int) idx == -1) {
+		/*
+		 * If this node is the leftmost subtree of its parent,
+		 * the rotation can not be done.
+		 */
+		return false;
+	}
+	
+	lnode = rnode->parent->subtree[idx];
+	if (lnode->keys > FILL_FACTOR) {
+		rotate_from_left(lnode, rnode, idx);
+		return true;
+	}
+	
+	return false;
+}
+
+/** Rotate in a key from the right sibling or from the index node, if this operation can be done.
+ *
+ * @param lnode Node into which to add key from its right sibling
+ *              or from the index node.
+ *
+ * @return True if the rotation was performed, false otherwise.
+ *
+ */
+NO_TRACE static bool try_rotation_from_right(btree_node_t *lnode)
+{
+	size_t idx;
+	btree_node_t *rnode;
+	
+	/*
+	 * If this is root node, the rotation can not be done.
+	 */
+	if (ROOT_NODE(lnode))
+		return false;
+	
+	idx = find_key_by_subtree(lnode->parent, lnode, false);
+	if (idx == lnode->parent->keys) {
+		/*
+		 * If this node is the rightmost subtree of its parent,
+		 * the rotation can not be done.
+		 */
+		return false;
+	}
+	
+	rnode = lnode->parent->subtree[idx + 1];
+	if (rnode->keys > FILL_FACTOR) {
+		rotate_from_right(lnode, rnode, idx);
+		return true;
+	}
+	
+	return false;
+}
+
+/** Combine node with any of its siblings.
+ *
+ * The siblings are required to be below the fill factor.
+ *
+ * @param node Node to combine with one of its siblings.
+ *
+ * @return Pointer to the rightmost of the two nodes.
+ *
+ */
+NO_TRACE static btree_node_t *node_combine(btree_node_t *node)
+{
+	size_t idx;
+	btree_node_t *rnode;
+	size_t i;
+	
+	ASSERT(!ROOT_NODE(node));
+	
+	idx = find_key_by_subtree(node->parent, node, false);
+	if (idx == node->parent->keys) {
+		/*
+		 * Rightmost subtree of its parent, combine with the left sibling.
+		 */
+		idx--;
+		rnode = node;
+		node = node->parent->subtree[idx];
+	} else
+		rnode = node->parent->subtree[idx + 1];
+	
+	/* Index nodes need to insert parent node key in between left and right node. */
+	if (INDEX_NODE(node))
+		node->key[node->keys++] = node->parent->key[idx];
+	
+	/* Copy the key-value-subtree triplets from the right node. */
+	for (i = 0; i < rnode->keys; i++) {
+		node->key[node->keys + i] = rnode->key[i];
+		node->value[node->keys + i] = rnode->value[i];
+		
+		if (INDEX_NODE(node)) {
+			node->subtree[node->keys + i] = rnode->subtree[i];
+			rnode->subtree[i]->parent = node;
+		}
+	}
+	
+	if (INDEX_NODE(node)) {
+		node->subtree[node->keys + i] = rnode->subtree[i];
+		rnode->subtree[i]->parent = node;
+	}
+	
+	node->keys += rnode->keys;
+	return rnode;
 }
 
 /** Recursively remove B-tree node.
  *
- * @param t B-tree.
- * @param key Key to be removed from the B-tree along with its associated value.
+ * @param t    B-tree.
+ * @param key  Key to be removed from the B-tree along with its associated value.
  * @param node Node where the key being removed resides.
- */
-void _btree_remove(btree_t *t, btree_key_t key, btree_node_t *node)
+ *
+ */
+NO_TRACE static void _btree_remove(btree_t *t, btree_key_t key,
+    btree_node_t *node)
 {
 	if (ROOT_NODE(node)) {
-		if (node->keys == 1 && node->subtree[0]) {
+		if ((node->keys == 1) && (node->subtree[0])) {
 			/*
 			 * Free the current root and set new root.
@@ -257,4 +789,5 @@
 			node_remove_key_and_rsubtree(node, key);
 		}
+		
 		return;
 	}
@@ -271,5 +804,5 @@
 	if (node->keys > FILL_FACTOR) {
 		size_t i;
-
+		
 		/*
 		 * The key can be immediatelly removed.
@@ -280,13 +813,14 @@
 		 */
 		node_remove_key_and_rsubtree(node, key);
+		
 		for (i = 0; i < node->parent->keys; i++) {
 			if (node->parent->key[i] == key)
 				node->parent->key[i] = node->key[0];
 		}
-		
 	} else {
 		size_t idx;
-		btree_node_t *rnode, *parent;
-
+		btree_node_t *rnode;
+		btree_node_t *parent;
+		
 		/*
 		 * The node is below the fill factor as well as its left and right sibling.
@@ -298,6 +832,8 @@
 		node_remove_key_and_rsubtree(node, key);
 		rnode = node_combine(node);
+		
 		if (LEAF_NODE(rnode))
 			list_remove(&rnode->leaf_link);
+		
 		idx = find_key_by_subtree(parent, rnode, true);
 		ASSERT((int) idx != -1);
@@ -307,11 +843,34 @@
 }
 
+/** Remove B-tree node.
+ *
+ * @param t         B-tree.
+ * @param key       Key to be removed from the B-tree along
+ *                  with its associated value.
+ * @param leaf_node If not NULL, pointer to the leaf node where
+ *                  the key is found.
+ *
+ */
+void btree_remove(btree_t *t, btree_key_t key, btree_node_t *leaf_node)
+{
+	btree_node_t *lnode;
+	
+	lnode = leaf_node;
+	if (!lnode) {
+		if (!btree_search(t, key, &lnode))
+			panic("B-tree %p does not contain key %" PRIu64 ".", t, key);
+	}
+	
+	_btree_remove(t, key, lnode);
+}
+
 /** Search key in a B-tree.
  *
- * @param t B-tree.
- * @param key Key to be searched.
+ * @param t         B-tree.
+ * @param key       Key to be searched.
  * @param leaf_node Address where to put pointer to visited leaf node.
  *
  * @return Pointer to value or NULL if there is no such key.
+ *
  */
 void *btree_search(btree_t *t, btree_key_t key, btree_node_t **leaf_node)
@@ -323,6 +882,8 @@
 	 */
 	for (cur = t->root; cur; cur = next) {
-
-		/* Last iteration will set this with proper leaf node address. */
+		/*
+		 * Last iteration will set this with proper
+		 * leaf node address.
+		 */
 		*leaf_node = cur;
 		
@@ -337,5 +898,5 @@
 			void *val;
 			size_t i;
-		
+			
 			/*
 			 * Now if the key is smaller than cur->key[i]
@@ -347,26 +908,29 @@
 					next = cur->subtree[i];
 					val = cur->value[i - 1];
-
+					
 					if (LEAF_NODE(cur))
 						return key == cur->key[i - 1] ? val : NULL;
-
+					
 					goto descend;
-				} 
+				}
 			}
 			
 			/*
-			 * Last possibility is that the key is in the rightmost subtree.
+			 * Last possibility is that the key is
+			 * in the rightmost subtree.
 			 */
 			next = cur->subtree[i];
 			val = cur->value[i - 1];
+			
 			if (LEAF_NODE(cur))
 				return key == cur->key[i - 1] ? val : NULL;
 		}
 		descend:
-			;
-	}
-
+		;
+	}
+	
 	/*
-	 * The key was not found in the *leaf_node and is smaller than any of its keys.
+	 * The key was not found in the *leaf_node and
+	 * is smaller than any of its keys.
 	 */
 	return NULL;
@@ -375,12 +939,15 @@
 /** Return pointer to B-tree leaf node's left neighbour.
  *
- * @param t B-tree.
+ * @param t    B-tree.
  * @param node Node whose left neighbour will be returned.
  *
- * @return Left neighbour of the node or NULL if the node does not have the left neighbour.
+ * @return Left neighbour of the node or NULL if the node
+ *         does not have the left neighbour.
+ *
  */
 btree_node_t *btree_leaf_node_left_neighbour(btree_t *t, btree_node_t *node)
 {
 	ASSERT(LEAF_NODE(node));
+	
 	if (node->leaf_link.prev != &t->leaf_head)
 		return list_get_instance(node->leaf_link.prev, btree_node_t, leaf_link);
@@ -391,12 +958,15 @@
 /** Return pointer to B-tree leaf node's right neighbour.
  *
- * @param t B-tree.
+ * @param t    B-tree.
  * @param node Node whose right neighbour will be returned.
  *
- * @return Right neighbour of the node or NULL if the node does not have the right neighbour.
+ * @return Right neighbour of the node or NULL if the node
+ *         does not have the right neighbour.
+ *
  */
 btree_node_t *btree_leaf_node_right_neighbour(btree_t *t, btree_node_t *node)
 {
 	ASSERT(LEAF_NODE(node));
+	
 	if (node->leaf_link.next != &t->leaf_head)
 		return list_get_instance(node->leaf_link.next, btree_node_t, leaf_link);
@@ -405,537 +975,8 @@
 }
 
-/** Initialize B-tree node.
- *
- * @param node B-tree node.
- */
-void node_initialize(btree_node_t *node)
-{
-	int i;
-
-	node->keys = 0;
-	
-	/* Clean also space for the extra key. */
-	for (i = 0; i < BTREE_MAX_KEYS + 1; i++) {
-		node->key[i] = 0;
-		node->value[i] = NULL;
-		node->subtree[i] = NULL;
-	}
-	node->subtree[i] = NULL;
-	
-	node->parent = NULL;
-	
-	link_initialize(&node->leaf_link);
-
-	link_initialize(&node->bfs_link);
-	node->depth = 0;
-}
-
-/** Insert key-value-lsubtree triplet into B-tree node.
- *
- * It is actually possible to have more keys than BTREE_MAX_KEYS.
- * This feature is used during insert by right rotation.
- *
- * @param node B-tree node into wich the new key is to be inserted.
- * @param key The key to be inserted.
- * @param value Pointer to value to be inserted.
- * @param lsubtree Pointer to the left subtree.
- */ 
-void node_insert_key_and_lsubtree(btree_node_t *node, btree_key_t key, void *value, btree_node_t *lsubtree)
-{
-	size_t i;
-
-	for (i = 0; i < node->keys; i++) {
-		if (key < node->key[i]) {
-			size_t j;
-		
-			for (j = node->keys; j > i; j--) {
-				node->key[j] = node->key[j - 1];
-				node->value[j] = node->value[j - 1];
-				node->subtree[j + 1] = node->subtree[j];
-			}
-			node->subtree[j + 1] = node->subtree[j];
-			break;	
-		}
-	}
-	node->key[i] = key;
-	node->value[i] = value;
-	node->subtree[i] = lsubtree;
-			
-	node->keys++;
-}
-
-/** Insert key-value-rsubtree triplet into B-tree node.
- *
- * It is actually possible to have more keys than BTREE_MAX_KEYS.
- * This feature is used during splitting the node when the
- * number of keys is BTREE_MAX_KEYS + 1. Insert by left rotation
- * also makes use of this feature.
- *
- * @param node B-tree node into wich the new key is to be inserted.
- * @param key The key to be inserted.
- * @param value Pointer to value to be inserted.
- * @param rsubtree Pointer to the right subtree.
- */ 
-void node_insert_key_and_rsubtree(btree_node_t *node, btree_key_t key, void *value, btree_node_t *rsubtree)
-{
-	size_t i;
-
-	for (i = 0; i < node->keys; i++) {
-		if (key < node->key[i]) {
-			size_t j;
-		
-			for (j = node->keys; j > i; j--) {
-				node->key[j] = node->key[j - 1];
-				node->value[j] = node->value[j - 1];
-				node->subtree[j + 1] = node->subtree[j];
-			}
-			break;	
-		}
-	}
-	node->key[i] = key;
-	node->value[i] = value;
-	node->subtree[i + 1] = rsubtree;
-			
-	node->keys++;
-}
-
-/** Remove key and its left subtree pointer from B-tree node.
- *
- * Remove the key and eliminate gaps in node->key array.
- * Note that the value pointer and the left subtree pointer
- * is removed from the node as well.
- *
- * @param node B-tree node.
- * @param key Key to be removed.
- */
-void node_remove_key_and_lsubtree(btree_node_t *node, btree_key_t key)
-{
-	size_t i, j;
-	
-	for (i = 0; i < node->keys; i++) {
-		if (key == node->key[i]) {
-			for (j = i + 1; j < node->keys; j++) {
-				node->key[j - 1] = node->key[j];
-				node->value[j - 1] = node->value[j];
-				node->subtree[j - 1] = node->subtree[j];
-			}
-			node->subtree[j - 1] = node->subtree[j];
-			node->keys--;
-			return;
-		}
-	}
-	panic("Node %p does not contain key %" PRIu64 ".", node, key);
-}
-
-/** Remove key and its right subtree pointer from B-tree node.
- *
- * Remove the key and eliminate gaps in node->key array.
- * Note that the value pointer and the right subtree pointer
- * is removed from the node as well.
- *
- * @param node B-tree node.
- * @param key Key to be removed.
- */
-void node_remove_key_and_rsubtree(btree_node_t *node, btree_key_t key)
-{
-	size_t i, j;
-	
-	for (i = 0; i < node->keys; i++) {
-		if (key == node->key[i]) {
-			for (j = i + 1; j < node->keys; j++) {
-				node->key[j - 1] = node->key[j];
-				node->value[j - 1] = node->value[j];
-				node->subtree[j] = node->subtree[j + 1];
-			}
-			node->keys--;
-			return;
-		}
-	}
-	panic("Node %p does not contain key %" PRIu64 ".", node, key);
-}
-
-/** Split full B-tree node and insert new key-value-right-subtree triplet.
- *
- * This function will split a node and return a pointer to a newly created
- * node containing keys greater than or equal to the greater of medians
- * (or median) of the old keys and the newly added key. It will also write
- * the median key to a memory address supplied by the caller.
- *
- * If the node being split is an index node, the median will not be
- * included in the new node. If the node is a leaf node,
- * the median will be copied there.
- *
- * @param node B-tree node wich is going to be split.
- * @param key The key to be inserted.
- * @param value Pointer to the value to be inserted.
- * @param rsubtree Pointer to the right subtree of the key being added.
- * @param median Address in memory, where the median key will be stored.
- *
- * @return Newly created right sibling of node.
- */ 
-btree_node_t *node_split(btree_node_t *node, btree_key_t key, void *value, btree_node_t *rsubtree, btree_key_t *median)
-{
-	btree_node_t *rnode;
-	size_t i, j;
-
-	ASSERT(median);
-	ASSERT(node->keys == BTREE_MAX_KEYS);
-
-	/*
-	 * Use the extra space to store the extra node.
-	 */
-	node_insert_key_and_rsubtree(node, key, value, rsubtree);
-
-	/*
-	 * Compute median of keys.
-	 */
-	*median = MEDIAN_HIGH(node);
-		
-	/*
-	 * Allocate and initialize new right sibling.
-	 */
-	rnode = (btree_node_t *) slab_alloc(btree_node_slab, 0);
-	node_initialize(rnode);
-	rnode->parent = node->parent;
-	rnode->depth = node->depth;
-	
-	/*
-	 * Copy big keys, values and subtree pointers to the new right sibling.
-	 * If this is an index node, do not copy the median.
-	 */
-	i = (size_t) INDEX_NODE(node);
-	for (i += MEDIAN_HIGH_INDEX(node), j = 0; i < node->keys; i++, j++) {
-		rnode->key[j] = node->key[i];
-		rnode->value[j] = node->value[i];
-		rnode->subtree[j] = node->subtree[i];
-		
-		/*
-		 * Fix parent links in subtrees.
-		 */
-		if (rnode->subtree[j])
-			rnode->subtree[j]->parent = rnode;
-			
-	}
-	rnode->subtree[j] = node->subtree[i];
-	if (rnode->subtree[j])
-		rnode->subtree[j]->parent = rnode;
-
-	rnode->keys = j;	/* Set number of keys of the new node. */
-	node->keys /= 2;	/* Shrink the old node. */
-		
-	return rnode;
-}
-
-/** Combine node with any of its siblings.
- *
- * The siblings are required to be below the fill factor.
- *
- * @param node Node to combine with one of its siblings.
- *
- * @return Pointer to the rightmost of the two nodes.
- */
-btree_node_t *node_combine(btree_node_t *node)
-{
-	size_t idx;
-	btree_node_t *rnode;
-	size_t i;
-
-	ASSERT(!ROOT_NODE(node));
-	
-	idx = find_key_by_subtree(node->parent, node, false);
-	if (idx == node->parent->keys) {
-		/*
-		 * Rightmost subtree of its parent, combine with the left sibling.
-		 */
-		idx--;
-		rnode = node;
-		node = node->parent->subtree[idx];
-	} else {
-		rnode = node->parent->subtree[idx + 1];
-	}
-
-	/* Index nodes need to insert parent node key in between left and right node. */
-	if (INDEX_NODE(node))
-		node->key[node->keys++] = node->parent->key[idx];
-	
-	/* Copy the key-value-subtree triplets from the right node. */
-	for (i = 0; i < rnode->keys; i++) {
-		node->key[node->keys + i] = rnode->key[i];
-		node->value[node->keys + i] = rnode->value[i];
-		if (INDEX_NODE(node)) {
-			node->subtree[node->keys + i] = rnode->subtree[i];
-			rnode->subtree[i]->parent = node;
-		}
-	}
-	if (INDEX_NODE(node)) {
-		node->subtree[node->keys + i] = rnode->subtree[i];
-		rnode->subtree[i]->parent = node;
-	}
-
-	node->keys += rnode->keys;
-
-	return rnode;
-}
-
-/** Find key by its left or right subtree.
- *
- * @param node B-tree node.
- * @param subtree Left or right subtree of a key found in node.
- * @param right If true, subtree is a right subtree. If false, subtree is a left subtree.
- *
- * @return Index of the key associated with the subtree.
- */ 
-size_t find_key_by_subtree(btree_node_t *node, btree_node_t *subtree, bool right)
-{
-	size_t i;
-	
-	for (i = 0; i < node->keys + 1; i++) {
-		if (subtree == node->subtree[i])
-			return i - (int) (right != false);
-	}
-	panic("Node %p does not contain subtree %p.", node, subtree);
-}
-
-/** Rotate one key-value-rsubtree triplet from the left sibling to the right sibling.
- *
- * The biggest key and its value and right subtree is rotated from the left node
- * to the right. If the node is an index node, than the parent node key belonging to
- * the left node takes part in the rotation.
- *
- * @param lnode Left sibling.
- * @param rnode Right sibling.
- * @param idx Index of the parent node key that is taking part in the rotation.
- */
-void rotate_from_left(btree_node_t *lnode, btree_node_t *rnode, size_t idx)
-{
-	btree_key_t key;
-
-	key = lnode->key[lnode->keys - 1];
-		
-	if (LEAF_NODE(lnode)) {
-		void *value;
-
-		value = lnode->value[lnode->keys - 1];
-		node_remove_key_and_rsubtree(lnode, key);
-		node_insert_key_and_lsubtree(rnode, key, value, NULL);
-		lnode->parent->key[idx] = key;
-	} else {
-		btree_node_t *rsubtree;
-
-		rsubtree = lnode->subtree[lnode->keys];
-		node_remove_key_and_rsubtree(lnode, key);
-		node_insert_key_and_lsubtree(rnode, lnode->parent->key[idx], NULL, rsubtree);
-		lnode->parent->key[idx] = key;
-
-		/* Fix parent link of the reconnected right subtree. */
-		rsubtree->parent = rnode;
-	}
-
-}
-
-/** Rotate one key-value-lsubtree triplet from the right sibling to the left sibling.
- *
- * The smallest key and its value and left subtree is rotated from the right node
- * to the left. If the node is an index node, than the parent node key belonging to
- * the right node takes part in the rotation.
- *
- * @param lnode Left sibling.
- * @param rnode Right sibling.
- * @param idx Index of the parent node key that is taking part in the rotation.
- */
-void rotate_from_right(btree_node_t *lnode, btree_node_t *rnode, size_t idx)
-{
-	btree_key_t key;
-
-	key = rnode->key[0];
-		
-	if (LEAF_NODE(rnode)) {
-		void *value;
-
-		value = rnode->value[0];
-		node_remove_key_and_lsubtree(rnode, key);
-		node_insert_key_and_rsubtree(lnode, key, value, NULL);
-		rnode->parent->key[idx] = rnode->key[0];
-	} else {
-		btree_node_t *lsubtree;
-
-		lsubtree = rnode->subtree[0];
-		node_remove_key_and_lsubtree(rnode, key);
-		node_insert_key_and_rsubtree(lnode, rnode->parent->key[idx], NULL, lsubtree);
-		rnode->parent->key[idx] = key;
-
-		/* Fix parent link of the reconnected left subtree. */
-		lsubtree->parent = lnode;
-	}
-
-}
-
-/** Insert key-value-rsubtree triplet and rotate the node to the left, if this operation can be done.
- *
- * Left sibling of the node (if it exists) is checked for free space.
- * If there is free space, the key is inserted and the smallest key of
- * the node is moved there. The index node which is the parent of both
- * nodes is fixed.
- *
- * @param node B-tree node.
- * @param inskey Key to be inserted.
- * @param insvalue Value to be inserted.
- * @param rsubtree Right subtree of inskey.
- *
- * @return True if the rotation was performed, false otherwise.
- */
-bool try_insert_by_rotation_to_left(btree_node_t *node, btree_key_t inskey, void *insvalue, btree_node_t *rsubtree)
-{
-	size_t idx;
-	btree_node_t *lnode;
-
-	/*
-	 * If this is root node, the rotation can not be done.
-	 */
-	if (ROOT_NODE(node))
-		return false;
-	
-	idx = find_key_by_subtree(node->parent, node, true);
-	if ((int) idx == -1) {
-		/*
-		 * If this node is the leftmost subtree of its parent,
-		 * the rotation can not be done.
-		 */
-		return false;
-	}
-		
-	lnode = node->parent->subtree[idx];
-	if (lnode->keys < BTREE_MAX_KEYS) {
-		/*
-		 * The rotaion can be done. The left sibling has free space.
-		 */
-		node_insert_key_and_rsubtree(node, inskey, insvalue, rsubtree);
-		rotate_from_right(lnode, node, idx);
-		return true;
-	}
-
-	return false;
-}
-
-/** Insert key-value-rsubtree triplet and rotate the node to the right, if this operation can be done.
- *
- * Right sibling of the node (if it exists) is checked for free space.
- * If there is free space, the key is inserted and the biggest key of
- * the node is moved there. The index node which is the parent of both
- * nodes is fixed.
- *
- * @param node B-tree node.
- * @param inskey Key to be inserted.
- * @param insvalue Value to be inserted.
- * @param rsubtree Right subtree of inskey.
- *
- * @return True if the rotation was performed, false otherwise.
- */
-bool try_insert_by_rotation_to_right(btree_node_t *node, btree_key_t inskey, void *insvalue, btree_node_t *rsubtree)
-{
-	size_t idx;
-	btree_node_t *rnode;
-
-	/*
-	 * If this is root node, the rotation can not be done.
-	 */
-	if (ROOT_NODE(node))
-		return false;
-	
-	idx = find_key_by_subtree(node->parent, node, false);
-	if (idx == node->parent->keys) {
-		/*
-		 * If this node is the rightmost subtree of its parent,
-		 * the rotation can not be done.
-		 */
-		return false;
-	}
-		
-	rnode = node->parent->subtree[idx + 1];
-	if (rnode->keys < BTREE_MAX_KEYS) {
-		/*
-		 * The rotaion can be done. The right sibling has free space.
-		 */
-		node_insert_key_and_rsubtree(node, inskey, insvalue, rsubtree);
-		rotate_from_left(node, rnode, idx);
-		return true;
-	}
-
-	return false;
-}
-
-/** Rotate in a key from the left sibling or from the index node, if this operation can be done.
- *
- * @param rnode Node into which to add key from its left sibling or from the index node.
- *
- * @return True if the rotation was performed, false otherwise.
- */
-bool try_rotation_from_left(btree_node_t *rnode)
-{
-	size_t idx;
-	btree_node_t *lnode;
-
-	/*
-	 * If this is root node, the rotation can not be done.
-	 */
-	if (ROOT_NODE(rnode))
-		return false;
-	
-	idx = find_key_by_subtree(rnode->parent, rnode, true);
-	if ((int) idx == -1) {
-		/*
-		 * If this node is the leftmost subtree of its parent,
-		 * the rotation can not be done.
-		 */
-		return false;
-	}
-		
-	lnode = rnode->parent->subtree[idx];
-	if (lnode->keys > FILL_FACTOR) {
-		rotate_from_left(lnode, rnode, idx);
-		return true;
-	}
-	
-	return false;
-}
-
-/** Rotate in a key from the right sibling or from the index node, if this operation can be done.
- *
- * @param lnode Node into which to add key from its right sibling or from the index node.
- *
- * @return True if the rotation was performed, false otherwise.
- */
-bool try_rotation_from_right(btree_node_t *lnode)
-{
-	size_t idx;
-	btree_node_t *rnode;
-
-	/*
-	 * If this is root node, the rotation can not be done.
-	 */
-	if (ROOT_NODE(lnode))
-		return false;
-	
-	idx = find_key_by_subtree(lnode->parent, lnode, false);
-	if (idx == lnode->parent->keys) {
-		/*
-		 * If this node is the rightmost subtree of its parent,
-		 * the rotation can not be done.
-		 */
-		return false;
-	}
-		
-	rnode = lnode->parent->subtree[idx + 1];
-	if (rnode->keys > FILL_FACTOR) {
-		rotate_from_right(lnode, rnode, idx);
-		return true;
-	}	
-
-	return false;
-}
-
 /** Print B-tree.
  *
  * @param t Print out B-tree.
+ *
  */
 void btree_print(btree_t *t)
@@ -944,13 +985,13 @@
 	int depth = t->root->depth;
 	link_t head, *cur;
-
+	
 	printf("Printing B-tree:\n");
 	list_initialize(&head);
 	list_append(&t->root->bfs_link, &head);
-
+	
 	/*
 	 * Use BFS search to print out the tree.
 	 * Levels are distinguished from one another by node->depth.
-	 */	
+	 */
 	while (!list_empty(&head)) {
 		link_t *hlp;
@@ -968,6 +1009,7 @@
 			depth = node->depth;
 		}
-
+		
 		printf("(");
+		
 		for (i = 0; i < node->keys; i++) {
 			printf("%" PRIu64 "%s", node->key[i], i < node->keys - 1 ? "," : "");
@@ -976,9 +1018,11 @@
 			}
 		}
-		if (node->depth && node->subtree[i]) {
+		
+		if (node->depth && node->subtree[i])
 			list_append(&node->subtree[i]->bfs_link, &head);
-		}
+		
 		printf(")");
 	}
+	
 	printf("\n");
 	
@@ -990,10 +1034,13 @@
 		
 		ASSERT(node);
-
+		
 		printf("(");
+		
 		for (i = 0; i < node->keys; i++)
 			printf("%" PRIu64 "%s", node->key[i], i < node->keys - 1 ? "," : "");
+		
 		printf(")");
 	}
+	
 	printf("\n");
 }
Index: kernel/generic/src/console/chardev.c
===================================================================
--- kernel/generic/src/console/chardev.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/generic/src/console/chardev.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -52,5 +52,5 @@
 	indev->name = name;
 	waitq_initialize(&indev->wq);
-	spinlock_initialize(&indev->lock, "indev");
+	irq_spinlock_initialize(&indev->lock, "chardev.indev.lock");
 	indev->counter = 0;
 	indev->index = 0;
@@ -68,8 +68,8 @@
 	ASSERT(indev);
 	
-	spinlock_lock(&indev->lock);
+	irq_spinlock_lock(&indev->lock, true);
 	if (indev->counter == INDEV_BUFLEN - 1) {
 		/* Buffer full */
-		spinlock_unlock(&indev->lock);
+		irq_spinlock_unlock(&indev->lock, true);
 		return;
 	}
@@ -81,5 +81,5 @@
 	indev->index = indev->index % INDEV_BUFLEN;
 	waitq_wakeup(&indev->wq, WAKEUP_FIRST);
-	spinlock_unlock(&indev->lock);
+	irq_spinlock_unlock(&indev->lock, true);
 }
 
@@ -114,10 +114,8 @@
 	
 	waitq_sleep(&indev->wq);
-	ipl_t ipl = interrupts_disable();
-	spinlock_lock(&indev->lock);
+	irq_spinlock_lock(&indev->lock, true);
 	wchar_t ch = indev->buffer[(indev->index - indev->counter) % INDEV_BUFLEN];
 	indev->counter--;
-	spinlock_unlock(&indev->lock);
-	interrupts_restore(ipl);
+	irq_spinlock_unlock(&indev->lock, true);
 	
 	return ch;
@@ -134,5 +132,5 @@
 {
 	outdev->name = name;
-	spinlock_initialize(&outdev->lock, "outdev");
+	spinlock_initialize(&outdev->lock, "chardev.outdev.lock");
 	link_initialize(&outdev->link);
 	list_initialize(&outdev->list);
Index: kernel/generic/src/console/cmd.c
===================================================================
--- kernel/generic/src/console/cmd.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/generic/src/console/cmd.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -108,17 +108,9 @@
 
 #ifdef CONFIG_TEST
-static int cmd_tests(cmd_arg_t *argv);
-static cmd_info_t tests_info = {
-	.name = "tests",
-	.description = "Print available kernel tests.",
-	.func = cmd_tests,
-	.argc = 0
-};
-
 static char test_buf[MAX_CMDLINE + 1];
 static int cmd_test(cmd_arg_t *argv);
 static cmd_arg_t test_argv[] = {
 	{
-		.type = ARG_TYPE_STRING,
+		.type = ARG_TYPE_STRING_OPTIONAL,
 		.buffer = test_buf,
 		.len = sizeof(test_buf)
@@ -127,5 +119,5 @@
 static cmd_info_t test_info = {
 	.name = "test",
-	.description = "Run kernel test.",
+	.description = "Print list of kernel tests or run a test.",
 	.func = cmd_test,
 	.argc = 1,
@@ -207,5 +199,5 @@
 };
 
-/* Data and methods for 'call0' command. */
+/* Data and methods for 'call0' and 'mcall0' command. */
 static char call0_buf[MAX_CMDLINE + 1];
 static char carg1_buf[MAX_CMDLINE + 1];
@@ -355,18 +347,32 @@
 };
 
+static char flag_buf[MAX_CMDLINE + 1];
+
 static int cmd_threads(cmd_arg_t *argv);
+static cmd_arg_t threads_argv = {
+	.type = ARG_TYPE_STRING_OPTIONAL,
+	.buffer = flag_buf,
+	.len = sizeof(flag_buf)
+};
 static cmd_info_t threads_info = {
 	.name = "threads",
-	.description = "List all threads.",
+	.description = "List all threads (use -a for additional information).",
 	.func = cmd_threads,
-	.argc = 0
+	.argc = 1,
+	.argv = &threads_argv
 };
 
 static int cmd_tasks(cmd_arg_t *argv);
+static cmd_arg_t tasks_argv = {
+	.type = ARG_TYPE_STRING_OPTIONAL,
+	.buffer = flag_buf,
+	.len = sizeof(flag_buf)
+};
 static cmd_info_t tasks_info = {
 	.name = "tasks",
-	.description = "List all tasks.",
+	.description = "List all tasks (use -a for additional information).",
 	.func = cmd_tasks,
-	.argc = 0
+	.argc = 1,
+	.argv = &tasks_argv
 };
 
@@ -495,5 +501,4 @@
 	&zone_info,
 #ifdef CONFIG_TEST
-	&tests_info,
 	&test_info,
 	&bench_info,
@@ -510,5 +515,5 @@
 void cmd_initialize(cmd_info_t *cmd)
 {
-	spinlock_initialize(&cmd->lock, "cmd");
+	spinlock_initialize(&cmd->lock, "cmd.lock");
 	link_initialize(&cmd->link);
 }
@@ -658,8 +663,12 @@
 		printf("Duplicate symbol, be more specific.\n");
 	} else if (rc == EOK) {
+		ipl_t ipl;
+
+		ipl = interrupts_disable();
 		fnc = (unative_t (*)(void)) arch_construct_function(&fptr,
 		    (void *) symaddr, (void *) cmd_call0);
 		printf("Calling %s() (%p)\n", symbol, symaddr);
 		printf("Result: %#" PRIxn "\n", fnc());
+		interrupts_restore(ipl);
 	} else {
 		printf("No symbol information available.\n");
@@ -681,15 +690,18 @@
 			continue;
 		
-		thread_t *t;
-		if ((t = thread_create((void (*)(void *)) cmd_call0, (void *) argv, TASK, THREAD_FLAG_WIRED, "call0", false))) {
-			spinlock_lock(&t->lock);
-			t->cpu = &cpus[i];
-			spinlock_unlock(&t->lock);
-			printf("cpu%u: ", i);
-			thread_ready(t);
-			thread_join(t);
-			thread_detach(t);
+		thread_t *thread;
+		if ((thread = thread_create((void (*)(void *)) cmd_call0,
+		    (void *) argv, TASK, THREAD_FLAG_WIRED, "call0", false))) {
+			irq_spinlock_lock(&thread->lock, true);
+			thread->cpu = &cpus[i];
+			irq_spinlock_unlock(&thread->lock, true);
+			
+			printf("cpu%" PRIs ": ", i);
+			
+			thread_ready(thread);
+			thread_join(thread);
+			thread_detach(thread);
 		} else
-			printf("Unable to create thread for cpu%u\n", i);
+			printf("Unable to create thread for cpu%" PRIs "\n", i);
 	}
 	
@@ -716,7 +728,11 @@
 		printf("Duplicate symbol, be more specific.\n");
 	} else if (rc == EOK) {
+		ipl_t ipl;
+
+		ipl = interrupts_disable();
 		fnc = (unative_t (*)(unative_t, ...)) arch_construct_function(&fptr, (void *) symaddr, (void *) cmd_call1);
 		printf("Calling f(%#" PRIxn "): %p: %s\n", arg1, symaddr, symbol);
 		printf("Result: %#" PRIxn "\n", fnc(arg1));
+		interrupts_restore(ipl);
 	} else {
 		printf("No symbol information available.\n");
@@ -746,8 +762,12 @@
 		printf("Duplicate symbol, be more specific.\n");
 	} else if (rc == EOK) {
+		ipl_t ipl;
+
+		ipl = interrupts_disable();
 		fnc = (unative_t (*)(unative_t, unative_t, ...)) arch_construct_function(&fptr, (void *) symaddr, (void *) cmd_call2);
 		printf("Calling f(%#" PRIxn ", %#" PRIxn "): %p: %s\n", 
 		       arg1, arg2, symaddr, symbol);
 		printf("Result: %#" PRIxn "\n", fnc(arg1, arg2));
+		interrupts_restore(ipl);
 	} else {
 		printf("No symbol information available.\n");
@@ -777,8 +797,12 @@
 		printf("Duplicate symbol, be more specific.\n");
 	} else if (rc == EOK) {
+		ipl_t ipl;
+
+		ipl = interrupts_disable();
 		fnc = (unative_t (*)(unative_t, unative_t, unative_t, ...)) arch_construct_function(&fptr, (void *) symaddr, (void *) cmd_call3);
 		printf("Calling f(%#" PRIxn ",%#" PRIxn ", %#" PRIxn "): %p: %s\n", 
 		       arg1, arg2, arg3, symaddr, symbol);
 		printf("Result: %#" PRIxn "\n", fnc(arg1, arg2, arg3));
+		interrupts_restore(ipl);
 	} else {
 		printf("No symbol information available.\n");
@@ -895,11 +919,17 @@
 /** Command for listings Thread information
  *
- * @param argv Ignores
+ * @param argv Ignored
  *
  * @return Always 1
  */
-int cmd_threads(cmd_arg_t * argv)
-{
-	thread_print_list();
+int cmd_threads(cmd_arg_t *argv)
+{
+	if (str_cmp(flag_buf, "-a") == 0)
+		thread_print_list(true);
+	else if (str_cmp(flag_buf, "") == 0)
+		thread_print_list(false);
+	else
+		printf("Unknown argument \"%s\".\n", flag_buf);
+	
 	return 1;
 }
@@ -907,11 +937,17 @@
 /** Command for listings Task information
  *
- * @param argv Ignores
+ * @param argv Ignored
  *
  * @return Always 1
  */
-int cmd_tasks(cmd_arg_t * argv)
-{
-	task_print_list();
+int cmd_tasks(cmd_arg_t *argv)
+{
+	if (str_cmp(flag_buf, "-a") == 0)
+		task_print_list(true);
+	else if (str_cmp(flag_buf, "") == 0)
+		task_print_list(false);
+	else
+		printf("Unknown argument \"%s\".\n", flag_buf);
+	
 	return 1;
 }
@@ -1021,26 +1057,4 @@
 
 #ifdef CONFIG_TEST
-/** Command for printing kernel tests list.
- *
- * @param argv Ignored.
- *
- * return Always 1.
- */
-int cmd_tests(cmd_arg_t *argv)
-{
-	size_t len = 0;
-	test_t *test;
-	for (test = tests; test->name != NULL; test++) {
-		if (str_length(test->name) > len)
-			len = str_length(test->name);
-	}
-	
-	for (test = tests; test->name != NULL; test++)
-		printf("%-*s %s%s\n", len, test->name, test->desc, (test->safe ? "" : " (unsafe)"));
-	
-	printf("%-*s Run all safe tests\n", len, "*");
-	return 1;
-}
-
 static bool run_test(const test_t *test)
 {
@@ -1049,10 +1063,8 @@
 	/* Update and read thread accounting
 	   for benchmarking */
-	ipl_t ipl = interrupts_disable();
-	spinlock_lock(&TASK->lock);
+	irq_spinlock_lock(&TASK->lock, true);
 	uint64_t ucycles0, kcycles0;
 	task_get_accounting(TASK, &ucycles0, &kcycles0);
-	spinlock_unlock(&TASK->lock);
-	interrupts_restore(ipl);
+	irq_spinlock_unlock(&TASK->lock, true);
 	
 	/* Execute the test */
@@ -1061,10 +1073,8 @@
 	
 	/* Update and read thread accounting */
-	uint64_t ucycles1, kcycles1; 
-	ipl = interrupts_disable();
-	spinlock_lock(&TASK->lock);
+	uint64_t ucycles1, kcycles1;
+	irq_spinlock_lock(&TASK->lock, true);
 	task_get_accounting(TASK, &ucycles1, &kcycles1);
-	spinlock_unlock(&TASK->lock);
-	interrupts_restore(ipl);
+	irq_spinlock_unlock(&TASK->lock, true);
 	
 	uint64_t ucycles, kcycles;
@@ -1072,7 +1082,7 @@
 	order_suffix(ucycles1 - ucycles0, &ucycles, &usuffix);
 	order_suffix(kcycles1 - kcycles0, &kcycles, &ksuffix);
-		
+	
 	printf("Time: %" PRIu64 "%c user cycles, %" PRIu64 "%c kernel cycles\n",
-			ucycles, usuffix, kcycles, ksuffix);
+	    ucycles, usuffix, kcycles, ksuffix);
 	
 	if (ret == NULL) {
@@ -1080,5 +1090,5 @@
 		return true;
 	}
-
+	
 	printf("%s\n", ret);
 	return false;
@@ -1106,10 +1116,8 @@
 		/* Update and read thread accounting
 		   for benchmarking */
-		ipl_t ipl = interrupts_disable();
-		spinlock_lock(&TASK->lock);
+		irq_spinlock_lock(&TASK->lock, true);
 		uint64_t ucycles0, kcycles0;
 		task_get_accounting(TASK, &ucycles0, &kcycles0);
-		spinlock_unlock(&TASK->lock);
-		interrupts_restore(ipl);
+		irq_spinlock_unlock(&TASK->lock, true);
 		
 		/* Execute the test */
@@ -1118,11 +1126,9 @@
 		
 		/* Update and read thread accounting */
-		ipl = interrupts_disable();
-		spinlock_lock(&TASK->lock);
+		irq_spinlock_lock(&TASK->lock, true);
 		uint64_t ucycles1, kcycles1;
 		task_get_accounting(TASK, &ucycles1, &kcycles1);
-		spinlock_unlock(&TASK->lock);
-		interrupts_restore(ipl);
-
+		irq_spinlock_unlock(&TASK->lock, true);
+		
 		if (ret != NULL) {
 			printf("%s\n", ret);
@@ -1135,5 +1141,5 @@
 		order_suffix(kcycles1 - kcycles0, &kcycles, &ksuffix);
 		printf("OK (%" PRIu64 "%c user cycles, %" PRIu64 "%c kernel cycles)\n",
-				ucycles, usuffix, kcycles, ksuffix);
+		    ucycles, usuffix, kcycles, ksuffix);
 	}
 	
@@ -1156,9 +1162,26 @@
 }
 
-/** Command for returning kernel tests
+static void list_tests(void)
+{
+	size_t len = 0;
+	test_t *test;
+	
+	for (test = tests; test->name != NULL; test++) {
+		if (str_length(test->name) > len)
+			len = str_length(test->name);
+	}
+	
+	for (test = tests; test->name != NULL; test++)
+		printf("%-*s %s%s\n", len, test->name, test->desc, (test->safe ? "" : " (unsafe)"));
+	
+	printf("%-*s Run all safe tests\n", len, "*");
+}
+
+/** Command for listing and running kernel tests
  *
  * @param argv Argument vector.
  *
  * return Always 1.
+ *
  */
 int cmd_test(cmd_arg_t *argv)
@@ -1174,5 +1197,5 @@
 			}
 		}
-	} else {
+	} else if (str_cmp((char *) argv->buffer, "") != 0) {
 		bool fnd = false;
 		
@@ -1187,5 +1210,6 @@
 		if (!fnd)
 			printf("Unknown test\n");
-	}
+	} else
+		list_tests();
 	
 	return 1;
Index: kernel/generic/src/console/console.c
===================================================================
--- kernel/generic/src/console/console.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/generic/src/console/console.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -62,10 +62,14 @@
 /** Kernel log initialized */
 static bool klog_inited = false;
+
 /** First kernel log characters */
 static size_t klog_start = 0;
+
 /** Number of valid kernel log characters */
 static size_t klog_len = 0;
+
 /** Number of stored (not printed) kernel log characters */
 static size_t klog_stored = 0;
+
 /** Number of stored kernel log characters for uspace */
 static size_t klog_uspace = 0;
@@ -84,6 +88,6 @@
 };
 
-static void stdout_write(outdev_t *dev, wchar_t ch, bool silent);
-static void stdout_redraw(outdev_t *dev);
+static void stdout_write(outdev_t *, wchar_t, bool);
+static void stdout_redraw(outdev_t *);
 
 static outdev_operations_t stdout_ops = {
@@ -174,7 +178,10 @@
 		stdout->op->redraw(stdout);
 	
-	/* Force the console to print the prompt */
-	if ((stdin) && (prev))
+	if ((stdin) && (prev)) {
+		/*
+		 * Force the console to print the prompt.
+		 */
 		indev_push_character(stdin, '\n');
+	}
 }
 
@@ -287,5 +294,17 @@
 		stdout->op->write(stdout, ch, silent);
 	else {
-		/* The character is just in the kernel log */
+		/*
+		 * No standard output routine defined yet.
+		 * The character is still stored in the kernel log
+		 * for possible future output.
+		 *
+		 * The early_putchar() function is used to output
+		 * the character for low-level debugging purposes.
+		 * Note that the early_putc() function might be
+		 * a no-op on certain hardware configurations.
+		 *
+		 */
+		early_putchar(ch);
+		
 		if (klog_stored < klog_len)
 			klog_stored++;
Index: kernel/generic/src/console/kconsole.c
===================================================================
--- kernel/generic/src/console/kconsole.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/generic/src/console/kconsole.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -160,5 +160,5 @@
 
 /** Print count times a character */
-static void print_cc(wchar_t ch, size_t count)
+NO_TRACE static void print_cc(wchar_t ch, size_t count)
 {
 	size_t i;
@@ -168,5 +168,6 @@
 
 /** Try to find a command beginning with prefix */
-static const char *cmdtab_search_one(const char *name, link_t **startpos)
+NO_TRACE static const char *cmdtab_search_one(const char *name,
+    link_t **startpos)
 {
 	size_t namelen = str_length(name);
@@ -202,5 +203,5 @@
  *
  */
-static int cmdtab_compl(char *input, size_t size)
+NO_TRACE static int cmdtab_compl(char *input, size_t size)
 {
 	const char *name = input;
@@ -209,5 +210,5 @@
 	link_t *pos = NULL;
 	const char *hint;
-	char output[MAX_CMDLINE];
+	char *output = malloc(MAX_CMDLINE, 0);
 	
 	output[0] = 0;
@@ -234,8 +235,9 @@
 		str_cpy(input, size, output);
 	
+	free(output);
 	return found;
 }
 
-static wchar_t *clever_readline(const char *prompt, indev_t *indev)
+NO_TRACE static wchar_t *clever_readline(const char *prompt, indev_t *indev)
 {
 	printf("%s> ", prompt);
@@ -244,4 +246,5 @@
 	wchar_t *current = history[history_pos];
 	current[0] = 0;
+	char *tmp = malloc(STR_BOUNDS(MAX_CMDLINE), 0);
 	
 	while (true) {
@@ -288,5 +291,4 @@
 				beg++;
 			
-			char tmp[STR_BOUNDS(MAX_CMDLINE)];
 			wstr_to_str(tmp, position - beg + 1, current + beg);
 			
@@ -414,4 +416,5 @@
 	}
 	
+	free(tmp);
 	return current;
 }
@@ -422,5 +425,6 @@
 }
 
-static bool parse_int_arg(const char *text, size_t len, unative_t *result)
+NO_TRACE static bool parse_int_arg(const char *text, size_t len,
+    unative_t *result)
 {
 	bool isaddr = false;
@@ -507,5 +511,6 @@
  *
  */
-static bool parse_argument(const char *cmdline, size_t size, size_t *start, size_t *end)
+NO_TRACE static bool parse_argument(const char *cmdline, size_t size,
+    size_t *start, size_t *end)
 {
 	ASSERT(start != NULL);
@@ -543,5 +548,5 @@
  *
  */
-static cmd_info_t *parse_cmdline(const char *cmdline, size_t size)
+NO_TRACE static cmd_info_t *parse_cmdline(const char *cmdline, size_t size)
 {
 	size_t start = 0;
@@ -590,6 +595,14 @@
 	size_t i;
 	for (i = 0; i < cmd->argc; i++) {
+		char *buf;
+		
 		start = end;
 		if (!parse_argument(cmdline, size, &start, &end)) {
+			if (cmd->argv[i].type == ARG_TYPE_STRING_OPTIONAL) {
+				buf = (char *) cmd->argv[i].buffer;
+				str_cpy(buf, cmd->argv[i].len, "");
+				continue;
+			}
+			
 			printf("Too few arguments.\n");
 			spinlock_unlock(&cmd->lock);
@@ -597,7 +610,7 @@
 		}
 		
-		char *buf;
 		switch (cmd->argv[i].type) {
 		case ARG_TYPE_STRING:
+		case ARG_TYPE_STRING_OPTIONAL:
 			buf = (char *) cmd->argv[i].buffer;
 			str_ncpy(buf, cmd->argv[i].len, cmdline + start,
@@ -619,5 +632,5 @@
 					cmd->argv[i].vartype = ARG_TYPE_STRING;
 				} else {
-					printf("Wrong synxtax.\n");
+					printf("Wrong syntax.\n");
 					error = true;
 				}
@@ -677,4 +690,5 @@
 		printf("Type \"exit\" to leave the console.\n");
 	
+	char *cmdline = malloc(STR_BOUNDS(MAX_CMDLINE), 0);
 	while (true) {
 		wchar_t *tmp = clever_readline((char *) prompt, stdin);
@@ -683,5 +697,4 @@
 			continue;
 		
-		char cmdline[STR_BOUNDS(MAX_CMDLINE)];
 		wstr_to_str(cmdline, STR_BOUNDS(MAX_CMDLINE), tmp);
 		
@@ -695,4 +708,5 @@
 		(void) cmd_info->func(cmd_info->argv);
 	}
+	free(cmdline);
 }
 
Index: kernel/generic/src/cpu/cpu.c
===================================================================
--- kernel/generic/src/cpu/cpu.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/generic/src/cpu/cpu.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -33,7 +33,7 @@
 /**
  * @file
- * @brief	CPU subsystem initialization and listing.
+ * @brief CPU subsystem initialization and listing.
  */
- 
+
 #include <cpu.h>
 #include <arch.h>
@@ -49,4 +49,5 @@
 #include <print.h>
 #include <sysinfo/sysinfo.h>
+#include <arch/cycle.h>
 
 cpu_t *cpus;
@@ -58,26 +59,27 @@
  */
 void cpu_init(void) {
-	unsigned int i, j;
-	
 #ifdef CONFIG_SMP
 	if (config.cpu_active == 1) {
 #endif /* CONFIG_SMP */
+		
 		cpus = (cpu_t *) malloc(sizeof(cpu_t) * config.cpu_count,
-					FRAME_ATOMIC);
+		    FRAME_ATOMIC);
 		if (!cpus)
 			panic("Cannot allocate CPU structures.");
-
-		/* initialize everything */
+		
+		/* Initialize everything */
 		memsetb(cpus, sizeof(cpu_t) * config.cpu_count, 0);
-
+		
+		size_t i;
 		for (i = 0; i < config.cpu_count; i++) {
-			cpus[i].stack = (uint8_t *) frame_alloc(STACK_FRAMES, FRAME_KA | FRAME_ATOMIC);
-			
+			cpus[i].stack = (uint8_t *) frame_alloc(STACK_FRAMES,
+			    FRAME_KA | FRAME_ATOMIC);
 			cpus[i].id = i;
 			
-			spinlock_initialize(&cpus[i].lock, "cpu_t.lock");
-
+			irq_spinlock_initialize(&cpus[i].lock, "cpus[].lock");
+			
+			unsigned int j;
 			for (j = 0; j < RQ_COUNT; j++) {
-				spinlock_initialize(&cpus[i].rq[j].lock, "rq_t.lock");
+				irq_spinlock_initialize(&cpus[i].rq[j].lock, "cpus[].rq[].lock");
 				list_initialize(&cpus[i].rq[j].rq_head);
 			}
@@ -87,9 +89,14 @@
 	}
 #endif /* CONFIG_SMP */
-
+	
 	CPU = &cpus[config.cpu_active - 1];
 	
-	CPU->active = 1;
-	CPU->tlb_active = 1;
+	CPU->active = true;
+	CPU->tlb_active = true;
+	
+	CPU->idle = false;
+	CPU->last_cycle = get_cycle();
+	CPU->idle_cycles = 0;
+	CPU->busy_cycles = 0;
 	
 	cpu_identify();
@@ -100,6 +107,6 @@
 void cpu_list(void)
 {
-	unsigned int i;
-
+	size_t i;
+	
 	for (i = 0; i < config.cpu_count; i++) {
 		if (cpus[i].active)
@@ -112,3 +119,2 @@
 /** @}
  */
-
Index: kernel/generic/src/ddi/ddi.c
===================================================================
--- kernel/generic/src/ddi/ddi.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/generic/src/ddi/ddi.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -52,4 +52,5 @@
 #include <align.h>
 #include <errno.h>
+#include <trace.h>
 
 /** This lock protects the parea_btree. */
@@ -59,5 +60,7 @@
 static btree_t parea_btree;
 
-/** Initialize DDI. */
+/** Initialize DDI.
+ *
+ */
 void ddi_init(void)
 {
@@ -97,5 +100,6 @@
  *
  */
-static int ddi_physmem_map(uintptr_t pf, uintptr_t vp, size_t pages, int flags)
+NO_TRACE static int ddi_physmem_map(uintptr_t pf, uintptr_t vp, size_t pages,
+    unsigned int flags)
 {
 	ASSERT(TASK);
@@ -114,8 +118,6 @@
 	backend_data.frames = pages;
 	
-	ipl_t ipl = interrupts_disable();
-	
 	/* Find the zone of the physical memory */
-	spinlock_lock(&zones.lock);
+	irq_spinlock_lock(&zones.lock, true);
 	size_t znum = find_zone(ADDR2PFN(pf), pages, 0);
 	
@@ -124,5 +126,5 @@
 		 * -> assume it is hardware device and allow mapping
 		 */
-		spinlock_unlock(&zones.lock);
+		irq_spinlock_unlock(&zones.lock, true);
 		goto map;
 	}
@@ -130,13 +132,14 @@
 	if (zones.info[znum].flags & ZONE_FIRMWARE) {
 		/* Frames are part of firmware */
-		spinlock_unlock(&zones.lock);
+		irq_spinlock_unlock(&zones.lock, true);
 		goto map;
 	}
 	
 	if (zone_flags_available(zones.info[znum].flags)) {
-		/* Frames are part of physical memory, check if the memory
+		/*
+		 * Frames are part of physical memory, check if the memory
 		 * region is enabled for mapping.
 		 */
-		spinlock_unlock(&zones.lock);
+		irq_spinlock_unlock(&zones.lock, true);
 		
 		mutex_lock(&parea_lock);
@@ -154,12 +157,10 @@
 	}
 	
-	spinlock_unlock(&zones.lock);
+	irq_spinlock_unlock(&zones.lock, true);
+	
 err:
-	interrupts_restore(ipl);
 	return ENOENT;
 	
 map:
-	interrupts_restore(ipl);
-
 	if (!as_area_create(TASK->as, flags, pages * PAGE_SIZE, vp,
 	    AS_AREA_ATTR_NONE, &phys_backend, &backend_data)) {
@@ -187,5 +188,6 @@
  *
  */
-static int ddi_iospace_enable(task_id_t id, uintptr_t ioaddr, size_t size)
+NO_TRACE static int ddi_iospace_enable(task_id_t id, uintptr_t ioaddr,
+    size_t size)
 {
 	/*
@@ -196,6 +198,5 @@
 		return EPERM;
 	
-	ipl_t ipl = interrupts_disable();
-	spinlock_lock(&tasks_lock);
+	irq_spinlock_lock(&tasks_lock, true);
 	
 	task_t *task = task_find_by_id(id);
@@ -207,17 +208,14 @@
 		 * context.
 		 */
-		spinlock_unlock(&tasks_lock);
-		interrupts_restore(ipl);
+		irq_spinlock_unlock(&tasks_lock, true);
 		return ENOENT;
 	}
 	
 	/* Lock the task and release the lock protecting tasks_btree. */
-	spinlock_lock(&task->lock);
-	spinlock_unlock(&tasks_lock);
+	irq_spinlock_exchange(&tasks_lock, &task->lock);
 	
 	int rc = ddi_iospace_enable_arch(task, ioaddr, size);
 	
-	spinlock_unlock(&task->lock);
-	interrupts_restore(ipl);
+	irq_spinlock_unlock(&task->lock, true);
 	
 	return rc;
@@ -258,27 +256,4 @@
 	return (unative_t) ddi_iospace_enable((task_id_t) arg.task_id,
 	    (uintptr_t) arg.ioaddr, (size_t) arg.size);
-}
-
-/** Disable or enable preemption.
- *
- * @param enable If non-zero, the preemption counter will be decremented,
- *               leading to potential enabling of preemption. Otherwise
- *               the preemption counter will be incremented, preventing
- *               preemption from occurring.
- *
- * @return Zero on success or EPERM if callers capabilities are not sufficient.
- *
- */
-unative_t sys_preempt_control(int enable)
-{
-	if (!(cap_get(TASK) & CAP_PREEMPT_CONTROL))
-		return EPERM;
-	
-	if (enable)
-		preemption_enable();
-	else
-		preemption_disable();
-	
-	return 0;
 }
 
@@ -293,5 +268,5 @@
 {	
 	cap_t task_cap = cap_get(TASK);
-	if (!(task_cap & CAP_PREEMPT_CONTROL) || !(task_cap & CAP_IRQ_REG))
+	if (!(task_cap & CAP_IRQ_REG))
 		return EPERM;
 		
Index: kernel/generic/src/ddi/irq.c
===================================================================
--- kernel/generic/src/ddi/irq.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/generic/src/ddi/irq.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -32,5 +32,5 @@
 /**
  * @file
- * @brief	IRQ dispatcher.
+ * @brief IRQ dispatcher.
  *
  * This file provides means of connecting IRQs with particular
@@ -78,20 +78,24 @@
 #include <arch.h>
 
-#define KEY_INR		0
-#define KEY_DEVNO	1
-
-/**
- * Spinlock protecting the kernel IRQ hash table.
+#define KEY_INR    0
+#define KEY_DEVNO  1
+
+/** Spinlock protecting the kernel IRQ hash table.
+ *
  * This lock must be taken only when interrupts are disabled.
- */
-SPINLOCK_INITIALIZE(irq_kernel_hash_table_lock);
+ *
+ */
+IRQ_SPINLOCK_STATIC_INITIALIZE(irq_kernel_hash_table_lock);
+
 /** The kernel IRQ hash table. */
 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.
- */
-SPINLOCK_INITIALIZE(irq_uspace_hash_table_lock);
+ *
+ */
+IRQ_SPINLOCK_INITIALIZE(irq_uspace_hash_table_lock);
+
 /** The uspace IRQ hash table. */
 hash_table_t irq_uspace_hash_table;
@@ -100,4 +104,5 @@
  * Hash table operations for cases when we know that
  * there will be collisions between different keys.
+ *
  */
 static size_t irq_ht_hash(unative_t *key);
@@ -116,4 +121,5 @@
  * However, there might be still collisions among
  * elements with single key (sharing of one IRQ).
+ *
  */
 static size_t irq_lin_hash(unative_t *key);
@@ -132,6 +138,7 @@
 /** Initialize IRQ subsystem.
  *
- * @param inrs Numbers of unique IRQ numbers or INRs.
+ * @param inrs   Numbers of unique IRQ numbers or INRs.
  * @param chains Number of chains in the hash table.
+ *
  */
 void irq_init(size_t inrs, size_t chains)
@@ -166,9 +173,9 @@
 	memsetb(irq, sizeof(irq_t), 0);
 	link_initialize(&irq->link);
-	spinlock_initialize(&irq->lock, "irq.lock");
+	irq_spinlock_initialize(&irq->lock, "irq.lock");
 	link_initialize(&irq->notif_cfg.link);
 	irq->inr = -1;
 	irq->devno = -1;
-
+	
 	irq_initialize_arch(irq);
 }
@@ -180,10 +187,11 @@
  * function pointer and handler() function pointer.
  *
- * @param irq		IRQ structure belonging to a device.
- * @return		True on success, false on failure.
+ * @param irq IRQ structure belonging to a device.
+ *
+ * @return True on success, false on failure.
+ *
  */
 void irq_register(irq_t *irq)
 {
-	ipl_t ipl;
 	unative_t key[] = {
 		(unative_t) irq->inr,
@@ -191,11 +199,9 @@
 	};
 	
-	ipl = interrupts_disable();
-	spinlock_lock(&irq_kernel_hash_table_lock);
-	spinlock_lock(&irq->lock);
+	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);
-	spinlock_unlock(&irq->lock);	
-	spinlock_unlock(&irq_kernel_hash_table_lock);
-	interrupts_restore(ipl);
+	irq_spinlock_unlock(&irq->lock, false);
+	irq_spinlock_unlock(&irq_kernel_hash_table_lock, true);
 }
 
@@ -208,17 +214,15 @@
 	unative_t key[] = {
 		(unative_t) inr,
-		(unative_t) -1    /* search will use claim() instead of devno */
+		(unative_t) -1    /* Search will use claim() instead of devno */
 	};
 	
-	spinlock_lock(&irq_uspace_hash_table_lock);
+	irq_spinlock_lock(&irq_uspace_hash_table_lock, false);
 	lnk = hash_table_find(&irq_uspace_hash_table, key);
 	if (lnk) {
-		irq_t *irq;
-		
-		irq = hash_table_get_instance(lnk, irq_t, link);
-		spinlock_unlock(&irq_uspace_hash_table_lock);
+		irq_t *irq = hash_table_get_instance(lnk, irq_t, link);
+		irq_spinlock_unlock(&irq_uspace_hash_table_lock, false);
 		return irq;
 	}
-	spinlock_unlock(&irq_uspace_hash_table_lock);
+	irq_spinlock_unlock(&irq_uspace_hash_table_lock, false);
 	
 	return NULL;
@@ -233,17 +237,15 @@
 	unative_t key[] = {
 		(unative_t) inr,
-		(unative_t) -1    /* search will use claim() instead of devno */
+		(unative_t) -1    /* Search will use claim() instead of devno */
 	};
 	
-	spinlock_lock(&irq_kernel_hash_table_lock);
+	irq_spinlock_lock(&irq_kernel_hash_table_lock, false);
 	lnk = hash_table_find(&irq_kernel_hash_table, key);
 	if (lnk) {
-		irq_t *irq;
-		
-		irq = hash_table_get_instance(lnk, irq_t, link);
-		spinlock_unlock(&irq_kernel_hash_table_lock);
+		irq_t *irq = hash_table_get_instance(lnk, irq_t, link);
+		irq_spinlock_unlock(&irq_kernel_hash_table_lock, false);
 		return irq;
 	}
-	spinlock_unlock(&irq_kernel_hash_table_lock);
+	irq_spinlock_unlock(&irq_kernel_hash_table_lock, false);
 	
 	return NULL;
@@ -263,9 +265,8 @@
  *
  * @return IRQ structure of the respective device or NULL.
+ *
  */
 irq_t *irq_dispatch_and_lock(inr_t inr)
 {
-	irq_t *irq;
-	
 	/*
 	 * If the kernel console is silenced,
@@ -277,13 +278,15 @@
 	 */
 	if (silent) {
-		irq = irq_dispatch_and_lock_uspace(inr);
+		irq_t *irq = irq_dispatch_and_lock_uspace(inr);
 		if (irq)
 			return irq;
+		
 		return irq_dispatch_and_lock_kernel(inr);
 	}
 	
-	irq = irq_dispatch_and_lock_kernel(inr);
+	irq_t *irq = irq_dispatch_and_lock_kernel(inr);
 	if (irq)
 		return irq;
+	
 	return irq_dispatch_and_lock_uspace(inr);
 }
@@ -301,4 +304,5 @@
  *
  * @return Index into the hash table.
+ *
  */
 size_t irq_ht_hash(unative_t key[])
@@ -322,9 +326,10 @@
  * This function assumes interrupts are already disabled.
  *
- * @param key Keys (i.e. inr and devno).
+ * @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(unative_t key[], size_t keys, link_t *item)
@@ -333,8 +338,8 @@
 	inr_t inr = (inr_t) key[KEY_INR];
 	devno_t devno = (devno_t) key[KEY_DEVNO];
-
+	
 	bool rv;
 	
-	spinlock_lock(&irq->lock);
+	irq_spinlock_lock(&irq->lock, false);
 	if (devno == -1) {
 		/* Invoked by irq_dispatch_and_lock(). */
@@ -348,6 +353,6 @@
 	/* unlock only on non-match */
 	if (!rv)
-		spinlock_unlock(&irq->lock);
-
+		irq_spinlock_unlock(&irq->lock, false);
+	
 	return rv;
 }
@@ -361,5 +366,5 @@
 	irq_t *irq __attribute__((unused))
 	    = hash_table_get_instance(lnk, irq_t, link);
-	spinlock_unlock(&irq->lock);
+	irq_spinlock_unlock(&irq->lock, false);
 }
 
@@ -374,4 +379,5 @@
  *
  * @return Index into the hash table.
+ *
  */
 size_t irq_lin_hash(unative_t key[])
@@ -395,9 +401,10 @@
  * This function assumes interrupts are already disabled.
  *
- * @param key Keys (i.e. inr and devno).
+ * @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(unative_t key[], size_t keys, link_t *item)
@@ -407,5 +414,5 @@
 	bool rv;
 	
-	spinlock_lock(&irq->lock);
+	irq_spinlock_lock(&irq->lock, false);
 	if (devno == -1) {
 		/* Invoked by irq_dispatch_and_lock() */
@@ -418,5 +425,5 @@
 	/* unlock only on non-match */
 	if (!rv)
-		spinlock_unlock(&irq->lock);
+		irq_spinlock_unlock(&irq->lock, false);
 	
 	return rv;
@@ -425,5 +432,6 @@
 /** Unlock IRQ structure after hash_table_remove().
  *
- * @param lnk		Link in the removed and locked IRQ structure.
+ * @param lnk Link in the removed and locked IRQ structure.
+ *
  */
 void irq_lin_remove(link_t *lnk)
@@ -431,5 +439,5 @@
 	irq_t *irq __attribute__((unused))
 	    = hash_table_get_instance(lnk, irq_t, link);
-	spinlock_unlock(&irq->lock);
+	irq_spinlock_unlock(&irq->lock, false);
 }
 
Index: kernel/generic/src/debug/debug.c
===================================================================
--- kernel/generic/src/debug/debug.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
+++ kernel/generic/src/debug/debug.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2010 Martin Decky
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup genericdebug
+ * @{
+ */
+
+/**
+ * @file
+ * @brief Kernel instrumentation functions.
+ */
+
+#ifdef CONFIG_TRACE
+
+#include <debug.h>
+#include <symtab.h>
+#include <errno.h>
+#include <print.h>
+
+void __cyg_profile_func_enter(void *fn, void *call_site)
+{
+	const char *fn_sym = symtab_fmt_name_lookup((uintptr_t) fn);
+	
+	const char *call_site_sym;
+	uintptr_t call_site_off;
+	
+	if (symtab_name_lookup((uintptr_t) call_site, &call_site_sym,
+	    &call_site_off) == EOK)
+		printf("%s+%" PRIp "->%s\n", call_site_sym, call_site_off,
+		    fn_sym);
+	else
+		printf("->%s\n", fn_sym);
+}
+
+void __cyg_profile_func_exit(void *fn, void *call_site)
+{
+	const char *fn_sym = symtab_fmt_name_lookup((uintptr_t) fn);
+	
+	const char *call_site_sym;
+	uintptr_t call_site_off;
+	
+	if (symtab_name_lookup((uintptr_t) call_site, &call_site_sym,
+	    &call_site_off) == EOK)
+		printf("%s+%" PRIp "<-%s\n", call_site_sym, call_site_off,
+		    fn_sym);
+	else
+		printf("<-%s\n", fn_sym);
+}
+
+#endif /* CONFIG_TRACE */
+
+/** @}
+ */
Index: kernel/generic/src/debug/panic.c
===================================================================
--- kernel/generic/src/debug/panic.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
+++ kernel/generic/src/debug/panic.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2010 Jakub Jermar
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup genericdebug
+ * @{
+ */
+/** @file
+ */
+
+#include <panic.h>
+#include <print.h>
+#include <stacktrace.h>
+#include <func.h>
+#include <typedefs.h>
+#include <mm/as.h>
+#include <stdarg.h>
+#include <interrupt.h>
+
+void panic_common(panic_category_t cat, istate_t *istate, int access,
+    uintptr_t address, const char *fmt, ...)
+{
+	va_list args;
+
+	silent = false;
+
+	printf("\nKERNEL PANIC ");
+	if (CPU)
+		printf("ON cpu%d ", CPU->id);
+	printf("DUE TO ");
+
+	va_start(args, fmt);
+	if (cat == PANIC_ASSERT) {
+		printf("A FAILED ASSERTION:\n");
+		vprintf(fmt, args);
+		printf("\n");
+	} else if (cat == PANIC_BADTRAP) {
+		printf("BAD TRAP %ld.\n", address);
+		if (fmt) {
+			vprintf(fmt, args);
+			printf("\n");
+		}
+	} else if (cat == PANIC_MEMTRAP) {
+		printf("A BAD MEMORY ACCESS WHILE ");
+		if (access == PF_ACCESS_READ)
+			printf("LOADING FROM");
+		else if (access == PF_ACCESS_WRITE)
+			printf("STORING TO");
+		else if (access == PF_ACCESS_EXEC)
+			printf("BRANCHING TO");
+		else
+			printf("REFERENCING");
+		printf(" ADDRESS %p.\n", address); 
+		if (fmt) {
+			vprintf(fmt, args);
+			printf("\n");
+		}
+	} else {
+		printf("THE FOLLOWING REASON:\n");
+		vprintf(fmt, args);
+		printf("\n");
+	}
+	va_end(args);
+
+	printf("\n");
+
+	if (istate) {
+		istate_decode(istate);
+		printf("\n");
+	}
+
+	stack_trace();
+	halt();
+}
+
+/** @}
+ */
Index: kernel/generic/src/debug/stacktrace.c
===================================================================
--- kernel/generic/src/debug/stacktrace.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/generic/src/debug/stacktrace.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -27,5 +27,5 @@
  */
 
-/** @addtogroup genericdebug 
+/** @addtogroup genericdebug
  * @{
  */
@@ -37,28 +37,36 @@
 #include <typedefs.h>
 #include <symtab.h>
+#include <print.h>
 
 #define STACK_FRAMES_MAX	20
 
 void
-stack_trace_fp_pc(stack_trace_ops_t *ops, uintptr_t fp, uintptr_t pc)
+stack_trace_ctx(stack_trace_ops_t *ops, stack_trace_context_t *ctx)
 {
 	int cnt = 0;
 	const char *symbol;
 	uintptr_t offset;
+	uintptr_t fp;
+	uintptr_t pc;
 	
-	while (cnt++ < STACK_FRAMES_MAX && ops->frame_pointer_validate(fp)) {
+	while (cnt++ < STACK_FRAMES_MAX &&
+	    ops->stack_trace_context_validate(ctx)) {
 		if (ops->symbol_resolve &&
-		    ops->symbol_resolve(pc, &symbol, &offset)) {
+		    ops->symbol_resolve(ctx->pc, &symbol, &offset)) {
 		    	if (offset)
-				printf("%p: %s+%p()\n", fp, symbol, offset);
+				printf("%p: %s+%" PRIp "()\n",
+				    ctx->fp, symbol, offset);
 			else
-				printf("%p: %s()\n", fp, symbol);
+				printf("%p: %s()\n",
+				    ctx->fp, symbol);
 		} else {
-			printf("%p: %p()\n", fp, pc);
+			printf("%p: %p()\n", ctx->fp, ctx->pc);
 		}
-		if (!ops->return_address_get(fp, &pc))
+		if (!ops->return_address_get(ctx, &pc))
 			break;
-		if (!ops->frame_pointer_prev(fp, &fp))
+		if (!ops->frame_pointer_prev(ctx, &fp))
 			break;
+		ctx->fp = fp;
+		ctx->pc = pc;
 	}
 }
@@ -66,5 +74,11 @@
 void stack_trace(void)
 {
-	stack_trace_fp_pc(&kst_ops, frame_pointer_get(), program_counter_get());
+	stack_trace_context_t ctx = {
+		.fp = frame_pointer_get(),
+		.pc = program_counter_get(),
+		.istate = NULL
+	};
+
+	stack_trace_ctx(&kst_ops, &ctx);
 
 	/*
@@ -77,13 +91,18 @@
 void stack_trace_istate(istate_t *istate)
 {
+	stack_trace_context_t ctx = {
+		.fp = istate_get_fp(istate),
+		.pc = istate_get_pc(istate),
+		.istate = istate
+	};
+	
 	if (istate_from_uspace(istate))
-		stack_trace_fp_pc(&ust_ops, istate_get_fp(istate),
-		    istate_get_pc(istate));
+		stack_trace_ctx(&ust_ops, &ctx);
 	else
-		stack_trace_fp_pc(&kst_ops, istate_get_fp(istate),
-		    istate_get_pc(istate));
+		stack_trace_ctx(&kst_ops, &ctx);
 }
 
-static bool kernel_symbol_resolve(uintptr_t addr, const char **sp, uintptr_t *op)
+static bool
+kernel_symbol_resolve(uintptr_t addr, const char **sp, uintptr_t *op)
 {
 	return (symtab_name_lookup(addr, sp, op) == 0);
@@ -91,5 +110,5 @@
 
 stack_trace_ops_t kst_ops = {
-	.frame_pointer_validate = kernel_frame_pointer_validate,
+	.stack_trace_context_validate = kernel_stack_trace_context_validate,
 	.frame_pointer_prev = kernel_frame_pointer_prev,
 	.return_address_get = kernel_return_address_get,
@@ -98,5 +117,5 @@
 
 stack_trace_ops_t ust_ops = {
-	.frame_pointer_validate = uspace_frame_pointer_validate,
+	.stack_trace_context_validate = uspace_stack_trace_context_validate,
 	.frame_pointer_prev = uspace_frame_pointer_prev,
 	.return_address_get = uspace_return_address_get,
Index: kernel/generic/src/debug/symtab.c
===================================================================
--- kernel/generic/src/debug/symtab.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/generic/src/debug/symtab.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -46,7 +46,7 @@
 /** Get name of a symbol that seems most likely to correspond to address.
  *
- * @param addr		Address.
- * @param name		Place to store pointer to the symbol name.
- * @param offset	Place to store offset from the symbol address.
+ * @param addr   Address.
+ * @param name   Place to store pointer to the symbol name.
+ * @param offset Place to store offset from the symbol address.
  *
  * @return Zero on success or negative error code, ENOENT if not found,
@@ -83,6 +83,7 @@
 /** Lookup symbol by address and format for display.
  *
- * Returns name of closest corresponding symbol, "Not found" if none exists
- * or "N/A" if no symbol information is available.
+ * Returns name of closest corresponding symbol,
+ * "unknown" if none exists and "N/A" if no symbol
+ * information is available.
  *
  * @param addr Address.
@@ -101,5 +102,5 @@
 		return name;
 	case ENOENT:
-		return "Not found";
+		return "unknown";
 	default:
 		return "N/A";
Index: kernel/generic/src/interrupt/interrupt.c
===================================================================
--- kernel/generic/src/interrupt/interrupt.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/generic/src/interrupt/interrupt.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -32,9 +32,10 @@
 /**
  * @file
- * @brief	Interrupt redirector.
+ * @brief Interrupt redirector.
  *
  * This file provides means of registering interrupt handlers
  * by kernel functions and calling the handlers when interrupts
  * occur.
+ *
  */
 
@@ -52,31 +53,39 @@
 #include <symtab.h>
 #include <proc/thread.h>
-
-static struct {
-	const char *name;
-	iroutine f;
-} exc_table[IVT_ITEMS];
-
-SPINLOCK_INITIALIZE(exctbl_lock);
+#include <arch/cycle.h>
+#include <str.h>
+#include <trace.h>
+
+exc_table_t exc_table[IVT_ITEMS];
+IRQ_SPINLOCK_INITIALIZE(exctbl_lock);
 
 /** Register exception handler
- * 
- * @param n Exception number
- * @param name Description 
- * @param f Exception handler
- */
-iroutine exc_register(int n, const char *name, iroutine f)
-{
+ *
+ * @param n       Exception number.
+ * @param name    Description.
+ * @param hot     Whether the exception is actually handled
+ *                in any meaningful way.
+ * @param handler New exception handler.
+ *
+ * @return Previously registered exception handler.
+ *
+ */
+iroutine_t exc_register(unsigned int n, const char *name, bool hot,
+    iroutine_t handler)
+{
+#if (IVT_ITEMS > 0)
 	ASSERT(n < IVT_ITEMS);
-	
-	iroutine old;
-	
-	spinlock_lock(&exctbl_lock);
-	
-	old = exc_table[n].f;
-	exc_table[n].f = f;
+#endif
+	
+	irq_spinlock_lock(&exctbl_lock, true);
+	
+	iroutine_t old = exc_table[n].handler;
+	exc_table[n].handler = handler;
 	exc_table[n].name = name;
-	
-	spinlock_unlock(&exctbl_lock);
+	exc_table[n].hot = hot;
+	exc_table[n].cycles = 0;
+	exc_table[n].count = 0;
+	
+	irq_spinlock_unlock(&exctbl_lock, true);
 	
 	return old;
@@ -87,65 +96,96 @@
  * Called directly from the assembler code.
  * CPU is interrupts_disable()'d.
- */
-void exc_dispatch(int n, istate_t *istate)
-{
+ *
+ */
+NO_TRACE void exc_dispatch(unsigned int n, istate_t *istate)
+{
+#if (IVT_ITEMS > 0)
 	ASSERT(n < IVT_ITEMS);
-
+#endif
+	
 	/* Account user cycles */
 	if (THREAD) {
-		spinlock_lock(&THREAD->lock);
+		irq_spinlock_lock(&THREAD->lock, false);
 		thread_update_accounting(true);
-		spinlock_unlock(&THREAD->lock);
-	}
-
+		irq_spinlock_unlock(&THREAD->lock, false);
+	}
+	
+	/* Account CPU usage if it has waked up from sleep */
+	if (CPU) {
+		irq_spinlock_lock(&CPU->lock, false);
+		if (CPU->idle) {
+			uint64_t now = get_cycle();
+			CPU->idle_cycles += now - CPU->last_cycle;
+			CPU->last_cycle = now;
+			CPU->idle = false;
+		}
+		irq_spinlock_unlock(&CPU->lock, false);
+	}
+	
+	uint64_t begin_cycle = get_cycle();
+	
 #ifdef CONFIG_UDEBUG
-	if (THREAD) THREAD->udebug.uspace_state = istate;
-#endif
-	
-	exc_table[n].f(n + IVT_FIRST, istate);
-
+	if (THREAD)
+		THREAD->udebug.uspace_state = istate;
+#endif
+	
+	exc_table[n].handler(n + IVT_FIRST, istate);
+	
 #ifdef CONFIG_UDEBUG
-	if (THREAD) THREAD->udebug.uspace_state = NULL;
-#endif
-
+	if (THREAD)
+		THREAD->udebug.uspace_state = NULL;
+#endif
+	
 	/* This is a safe place to exit exiting thread */
-	if (THREAD && THREAD->interrupted && istate_from_uspace(istate))
+	if ((THREAD) && (THREAD->interrupted) && (istate_from_uspace(istate)))
 		thread_exit();
-
+	
+	/* Account exception handling */
+	uint64_t end_cycle = get_cycle();
+	
+	irq_spinlock_lock(&exctbl_lock, false);
+	exc_table[n].cycles += end_cycle - begin_cycle;
+	exc_table[n].count++;
+	irq_spinlock_unlock(&exctbl_lock, false);
+	
+	/* Do not charge THREAD for exception cycles */
 	if (THREAD) {
-		spinlock_lock(&THREAD->lock);
-		thread_update_accounting(false);
-		spinlock_unlock(&THREAD->lock);
-	}
-}
-
-/** Default 'null' exception handler */
-static void exc_undef(int n, istate_t *istate)
-{
-	fault_if_from_uspace(istate, "Unhandled exception %d.", n);
-	panic("Unhandled exception %d.", n);
-}
-
-/** Terminate thread and task if exception came from userspace. */
-void fault_if_from_uspace(istate_t *istate, const char *fmt, ...)
-{
-	task_t *task = TASK;
-	va_list args;
-
+		irq_spinlock_lock(&THREAD->lock, false);
+		THREAD->last_cycle = end_cycle;
+		irq_spinlock_unlock(&THREAD->lock, false);
+	}
+}
+
+/** Default 'null' exception handler
+ *
+ */
+NO_TRACE static void exc_undef(unsigned int n, istate_t *istate)
+{
+	fault_if_from_uspace(istate, "Unhandled exception %u.", n);
+	panic_badtrap(istate, n, "Unhandled exception %u.", n);
+}
+
+/** Terminate thread and task if exception came from userspace.
+ *
+ */
+NO_TRACE void fault_if_from_uspace(istate_t *istate, const char *fmt, ...)
+{
 	if (!istate_from_uspace(istate))
 		return;
-
+	
 	printf("Task %s (%" PRIu64 ") killed due to an exception at "
-	    "program counter %p.\n", task->name, task->taskid,
+	    "program counter %p.\n", TASK->name, TASK->taskid,
 	    istate_get_pc(istate));
-
+	
 	stack_trace_istate(istate);
-
+	
 	printf("Kill message: ");
+	
+	va_list args;
 	va_start(args, fmt);
 	vprintf(fmt, args);
 	va_end(args);
 	printf("\n");
-
+	
 	/*
 	 * Userspace can subscribe for FAULT events to take action
@@ -158,5 +198,5 @@
 		event_notify_3(EVENT_FAULT, LOWER32(TASK->taskid),
 		    UPPER32(TASK->taskid), (unative_t) THREAD);
-
+		
 #ifdef CONFIG_UDEBUG
 		/* Wait for a debugging session. */
@@ -164,6 +204,6 @@
 #endif
 	}
-
-	task_kill(task->taskid);
+	
+	task_kill(TASK->taskid);
 	thread_exit();
 }
@@ -171,70 +211,119 @@
 #ifdef CONFIG_KCONSOLE
 
-/** kconsole cmd - print all exceptions */
-static int cmd_exc_print(cmd_arg_t *argv)
-{
+static char flag_buf[MAX_CMDLINE + 1];
+
+/** Print all exceptions
+ *
+ */
+NO_TRACE static int cmd_exc_print(cmd_arg_t *argv)
+{
+	bool excs_all;
+	
+	if (str_cmp(flag_buf, "-a") == 0)
+		excs_all = true;
+	else if (str_cmp(flag_buf, "") == 0)
+		excs_all = false;
+	else {
+		printf("Unknown argument \"%s\".\n", flag_buf);
+		return 1;
+	}
+	
 #if (IVT_ITEMS > 0)
 	unsigned int i;
-
-	spinlock_lock(&exctbl_lock);
-
+	unsigned int rows;
+	
+	irq_spinlock_lock(&exctbl_lock, true);
+	
 #ifdef __32_BITS__
-	printf("Exc Description          Handler    Symbol\n");
-	printf("--- -------------------- ---------- --------\n");
-#endif
-
+	printf("[exc   ] [description       ] [count   ] [cycles  ]"
+	    " [handler ] [symbol\n");
+	rows = 1;
+#endif
+	
 #ifdef __64_BITS__
-	printf("Exc Description          Handler            Symbol\n");
-	printf("--- -------------------- ------------------ --------\n");
+	printf("[exc   ] [description       ] [count   ] [cycles  ]"
+	    " [handler         ]\n");
+	printf("         [symbol\n");
+	rows = 2;
 #endif
 	
 	for (i = 0; i < IVT_ITEMS; i++) {
-		const char *symbol = symtab_fmt_name_lookup((unative_t) exc_table[i].f);
-
+		if ((!excs_all) && (!exc_table[i].hot))
+			continue;
+		
+		uint64_t count;
+		char count_suffix;
+		
+		order_suffix(exc_table[i].count, &count, &count_suffix);
+		
+		uint64_t cycles;
+		char cycles_suffix;
+		
+		order_suffix(exc_table[i].cycles, &cycles, &cycles_suffix);
+		
+		const char *symbol =
+		    symtab_fmt_name_lookup((unative_t) exc_table[i].handler);
+		
 #ifdef __32_BITS__
-		printf("%-3u %-20s %10p %s\n", i + IVT_FIRST, exc_table[i].name,
-			exc_table[i].f, symbol);
-#endif
-
+		printf("%-8u %-20s %9" PRIu64 "%c %9" PRIu64 "%c %10p %s\n",
+		    i + IVT_FIRST, exc_table[i].name, count, count_suffix,
+		    cycles, cycles_suffix, exc_table[i].handler, symbol);
+		
+		PAGING(rows, 1, irq_spinlock_unlock(&exctbl_lock, true),
+		    irq_spinlock_lock(&exctbl_lock, true));
+#endif
+		
 #ifdef __64_BITS__
-		printf("%-3u %-20s %18p %s\n", i + IVT_FIRST, exc_table[i].name,
-			exc_table[i].f, symbol);
-#endif
-		
-		if (((i + 1) % 20) == 0) {
-			printf(" -- Press any key to continue -- ");
-			spinlock_unlock(&exctbl_lock);
-			indev_pop_character(stdin);
-			spinlock_lock(&exctbl_lock);
-			printf("\n");
-		}
-	}
-	
-	spinlock_unlock(&exctbl_lock);
-#endif
+		printf("%-8u %-20s %9" PRIu64 "%c %9" PRIu64 "%c %18p\n",
+		    i + IVT_FIRST, exc_table[i].name, count, count_suffix,
+		    cycles, cycles_suffix, exc_table[i].handler);
+		printf("         %s\n", symbol);
+		
+		PAGING(rows, 2, irq_spinlock_unlock(&exctbl_lock, true),
+		    irq_spinlock_lock(&exctbl_lock, true));
+#endif
+	}
+	
+	irq_spinlock_unlock(&exctbl_lock, true);
+#else /* (IVT_ITEMS > 0) */
+	
+	printf("No exception table%s.\n", excs_all ? " (showing all exceptions)" : "");
+	
+#endif /* (IVT_ITEMS > 0) */
 	
 	return 1;
 }
 
+static cmd_arg_t exc_argv = {
+	.type = ARG_TYPE_STRING_OPTIONAL,
+	.buffer = flag_buf,
+	.len = sizeof(flag_buf)
+};
 
 static cmd_info_t exc_info = {
 	.name = "exc",
-	.description = "Print exception table.",
+	.description = "Print exception table (use -a for all exceptions).",
 	.func = cmd_exc_print,
 	.help = NULL,
-	.argc = 0,
-	.argv = NULL
+	.argc = 1,
+	.argv = &exc_argv
 };
 
-#endif
-
-/** Initialize generic exception handling support */
+#endif /* CONFIG_KCONSOLE */
+
+/** Initialize generic exception handling support
+ *
+ */
 void exc_init(void)
 {
-	int i;
-
+	(void) exc_undef;
+	
+#if (IVT_ITEMS > 0)
+	unsigned int i;
+	
 	for (i = 0; i < IVT_ITEMS; i++)
-		exc_register(i, "undef", (iroutine) exc_undef);
-
+		exc_register(i, "undef", false, (iroutine_t) exc_undef);
+#endif
+	
 #ifdef CONFIG_KCONSOLE
 	cmd_initialize(&exc_info);
Index: kernel/generic/src/ipc/event.c
===================================================================
--- kernel/generic/src/ipc/event.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/generic/src/ipc/event.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -137,9 +137,7 @@
 			IPC_SET_ARG5(call->data, a5);
 			
-			ipl_t ipl = interrupts_disable();
-			spinlock_lock(&events[evno].answerbox->irq_lock);
+			irq_spinlock_lock(&events[evno].answerbox->irq_lock, true);
 			list_append(&call->link, &events[evno].answerbox->irq_notifs);
-			spinlock_unlock(&events[evno].answerbox->irq_lock);
-			interrupts_restore(ipl);
+			irq_spinlock_unlock(&events[evno].answerbox->irq_lock, true);
 			
 			waitq_wakeup(&events[evno].answerbox->wq, WAKEUP_FIRST);
Index: kernel/generic/src/ipc/ipc.c
===================================================================
--- kernel/generic/src/ipc/ipc.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/generic/src/ipc/ipc.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -66,5 +66,6 @@
 /** Initialize a call structure.
  *
- * @param call		Call structure to be initialized.
+ * @param call Call structure to be initialized.
+ *
  */
 static void _ipc_call_init(call_t *call)
@@ -77,21 +78,20 @@
 
 /** Allocate and initialize a call structure.
- * 
+ *
  * The call is initialized, so that the reply will be directed to
  * TASK->answerbox.
  *
- * @param flags		Parameters for slab_alloc (e.g FRAME_ATOMIC).
- *
- * @return		If flags permit it, return NULL, or initialized kernel
- *			call structure.
- */
-call_t *ipc_call_alloc(int flags)
-{
-	call_t *call;
-
-	call = slab_alloc(ipc_call_slab, flags);
+ * @param flags Parameters for slab_alloc (e.g FRAME_ATOMIC).
+ *
+ * @return If flags permit it, return NULL, or initialized kernel
+ *         call structure.
+ *
+ */
+call_t *ipc_call_alloc(unsigned int flags)
+{
+	call_t *call = slab_alloc(ipc_call_slab, flags);
 	if (call)
 		_ipc_call_init(call);
-
+	
 	return call;
 }
@@ -99,5 +99,6 @@
 /** Deallocate a call structure.
  *
- * @param call		Call structure to be freed.
+ * @param call Call structure to be freed.
+ *
  */
 void ipc_call_free(call_t *call)
@@ -111,11 +112,12 @@
 /** Initialize an answerbox structure.
  *
- * @param box		Answerbox structure to be initialized.
- * @param task		Task to which the answerbox belongs.
+ * @param box  Answerbox structure to be initialized.
+ * @param task Task to which the answerbox belongs.
+ *
  */
 void ipc_answerbox_init(answerbox_t *box, task_t *task)
 {
-	spinlock_initialize(&box->lock, "ipc_box_lock");
-	spinlock_initialize(&box->irq_lock, "ipc_box_irqlock");
+	irq_spinlock_initialize(&box->lock, "ipc.box.lock");
+	irq_spinlock_initialize(&box->irq_lock, "ipc.box.irqlock");
 	waitq_initialize(&box->wq);
 	link_initialize(&box->sync_box_link);
@@ -131,18 +133,19 @@
 /** Connect a phone to an answerbox.
  *
- * @param phone		Initialized phone structure.
- * @param box		Initialized answerbox structure.
+ * @param phone Initialized phone structure.
+ * @param box   Initialized answerbox structure.
+ *
  */
 void ipc_phone_connect(phone_t *phone, answerbox_t *box)
 {
 	mutex_lock(&phone->lock);
-
+	
 	phone->state = IPC_PHONE_CONNECTED;
 	phone->callee = box;
-
-	spinlock_lock(&box->lock);
+	
+	irq_spinlock_lock(&box->lock, true);
 	list_append(&phone->link, &box->connected_phones);
-	spinlock_unlock(&box->lock);
-
+	irq_spinlock_unlock(&box->lock, true);
+	
 	mutex_unlock(&phone->lock);
 }
@@ -150,5 +153,6 @@
 /** Initialize a phone structure.
  *
- * @param phone		Phone structure to be initialized.
+ * @param phone Phone structure to be initialized.
+ *
  */
 void ipc_phone_init(phone_t *phone)
@@ -162,47 +166,41 @@
 /** Helper function to facilitate synchronous calls.
  *
- * @param phone		Destination kernel phone structure.
- * @param request	Call structure with request.
- *
- * @return		EOK on success or EINTR if the sleep was interrupted.
+ * @param phone   Destination kernel phone structure.
+ * @param request Call structure with request.
+ *
+ * @return EOK on success or EINTR if the sleep was interrupted.
+ *
  */
 int ipc_call_sync(phone_t *phone, call_t *request)
 {
-	answerbox_t *sync_box; 
-	ipl_t ipl;
-
-	sync_box = slab_alloc(ipc_answerbox_slab, 0);
+	answerbox_t *sync_box = slab_alloc(ipc_answerbox_slab, 0);
 	ipc_answerbox_init(sync_box, TASK);
-
+	
 	/*
 	 * Put the answerbox on the TASK's list of synchronous answerboxes so
 	 * that it can be cleaned up if the call is interrupted.
 	 */
-	ipl = interrupts_disable();
-	spinlock_lock(&TASK->lock);
+	irq_spinlock_lock(&TASK->lock, true);
 	list_append(&sync_box->sync_box_link, &TASK->sync_box_head);
-	spinlock_unlock(&TASK->lock);
-	interrupts_restore(ipl);
-
+	irq_spinlock_unlock(&TASK->lock, true);
+	
 	/* We will receive data in a special box. */
 	request->callerbox = sync_box;
-
+	
 	ipc_call(phone, request);
 	if (!ipc_wait_for_call(sync_box, SYNCH_NO_TIMEOUT,
 	    SYNCH_FLAGS_INTERRUPTIBLE)) {
-	    	/* The answerbox and the call will be freed by ipc_cleanup(). */
+		/* The answerbox and the call will be freed by ipc_cleanup(). */
 		return EINTR;
 	}
-
+	
 	/*
 	 * The answer arrived without interruption so we can remove the
 	 * answerbox from the TASK's list of synchronous answerboxes.
 	 */
-	(void) interrupts_disable();
-	spinlock_lock(&TASK->lock);
+	irq_spinlock_lock(&TASK->lock, true);
 	list_remove(&sync_box->sync_box_link);
-	spinlock_unlock(&TASK->lock);
-	interrupts_restore(ipl);
-
+	irq_spinlock_unlock(&TASK->lock, true);
+	
 	slab_free(ipc_answerbox_slab, sync_box);
 	return EOK;
@@ -211,6 +209,7 @@
 /** Answer a message which was not dispatched and is not listed in any queue.
  *
- * @param call		Call structure to be answered.
- * @param selflocked	If true, then TASK->answebox is locked.
+ * @param call       Call structure to be answered.
+ * @param selflocked If true, then TASK->answebox is locked.
+ *
  */
 static void _ipc_answer_free_call(call_t *call, bool selflocked)
@@ -218,15 +217,12 @@
 	answerbox_t *callerbox = call->callerbox;
 	bool do_lock = ((!selflocked) || callerbox != (&TASK->answerbox));
-	ipl_t ipl;
-
+	
 	/* Count sent answer */
-	ipl = interrupts_disable();
-	spinlock_lock(&TASK->lock);
+	irq_spinlock_lock(&TASK->lock, true);
 	TASK->ipc_info.answer_sent++;
-	spinlock_unlock(&TASK->lock);
-	interrupts_restore(ipl);
-
+	irq_spinlock_unlock(&TASK->lock, true);
+	
 	call->flags |= IPC_CALL_ANSWERED;
-
+	
 	if (call->flags & IPC_CALL_FORWARDED) {
 		if (call->caller_phone) {
@@ -235,10 +231,13 @@
 		}
 	}
-
+	
 	if (do_lock)
-		spinlock_lock(&callerbox->lock);
+		irq_spinlock_lock(&callerbox->lock, true);
+	
 	list_append(&call->link, &callerbox->answers);
+	
 	if (do_lock)
-		spinlock_unlock(&callerbox->lock);
+		irq_spinlock_unlock(&callerbox->lock, true);
+	
 	waitq_wakeup(&callerbox->wq, WAKEUP_FIRST);
 }
@@ -246,13 +245,15 @@
 /** Answer a message which is in a callee queue.
  *
- * @param box		Answerbox that is answering the message.
- * @param call		Modified request that is being sent back.
+ * @param box  Answerbox that is answering the message.
+ * @param call Modified request that is being sent back.
+ *
  */
 void ipc_answer(answerbox_t *box, call_t *call)
 {
 	/* Remove from active box */
-	spinlock_lock(&box->lock);
+	irq_spinlock_lock(&box->lock, true);
 	list_remove(&call->link);
-	spinlock_unlock(&box->lock);
+	irq_spinlock_unlock(&box->lock, true);
+	
 	/* Send back answer */
 	_ipc_answer_free_call(call, false);
@@ -264,7 +265,8 @@
  * message and sending it as a normal answer.
  *
- * @param phone		Phone structure the call should appear to come from.
- * @param call		Call structure to be answered.
- * @param err		Return value to be used for the answer.
+ * @param phone Phone structure the call should appear to come from.
+ * @param call  Call structure to be answered.
+ * @param err   Return value to be used for the answer.
+ *
  */
 void ipc_backsend_err(phone_t *phone, call_t *call, unative_t err)
@@ -278,27 +280,25 @@
 /** Unsafe unchecking version of ipc_call.
  *
- * @param phone		Phone structure the call comes from.
- * @param box		Destination answerbox structure.
- * @param call		Call structure with request.
+ * @param phone Phone structure the call comes from.
+ * @param box   Destination answerbox structure.
+ * @param call  Call structure with request.
+ *
  */
 static void _ipc_call(phone_t *phone, answerbox_t *box, call_t *call)
 {
-	ipl_t ipl;
-
 	/* Count sent ipc call */
-	ipl = interrupts_disable();
-	spinlock_lock(&TASK->lock);
+	irq_spinlock_lock(&TASK->lock, true);
 	TASK->ipc_info.call_sent++;
-	spinlock_unlock(&TASK->lock);
-	interrupts_restore(ipl);
-
+	irq_spinlock_unlock(&TASK->lock, true);
+	
 	if (!(call->flags & IPC_CALL_FORWARDED)) {
 		atomic_inc(&phone->active_calls);
 		call->data.phone = phone;
 	}
-
-	spinlock_lock(&box->lock);
+	
+	irq_spinlock_lock(&box->lock, true);
 	list_append(&call->link, &box->calls);
-	spinlock_unlock(&box->lock);
+	irq_spinlock_unlock(&box->lock, true);
+	
 	waitq_wakeup(&box->wq, WAKEUP_FIRST);
 }
@@ -306,14 +306,13 @@
 /** Send an asynchronous request using a phone to an answerbox.
  *
- * @param phone		Phone structure the call comes from and which is
- *			connected to the destination answerbox.
- * @param call		Call structure with request.
- *
- * @return		Return 0 on success, ENOENT on error.
+ * @param phone Phone structure the call comes from and which is
+ *              connected to the destination answerbox.
+ * @param call  Call structure with request.
+ *
+ * @return Return 0 on success, ENOENT on error.
+ *
  */
 int ipc_call(phone_t *phone, call_t *call)
 {
-	answerbox_t *box;
-
 	mutex_lock(&phone->lock);
 	if (phone->state != IPC_PHONE_CONNECTED) {
@@ -328,7 +327,9 @@
 				ipc_backsend_err(phone, call, ENOENT);
 		}
+		
 		return ENOENT;
 	}
-	box = phone->callee;
+	
+	answerbox_t *box = phone->callee;
 	_ipc_call(phone, box, call);
 	
@@ -342,14 +343,12 @@
  * lazily later.
  *
- * @param phone		Phone structure to be hung up.
- *              
- * @return		Return 0 if the phone is disconnected.
- *			Return -1 if the phone was already disconnected.
+ * @param phone Phone structure to be hung up.
+ *
+ * @return 0 if the phone is disconnected.
+ * @return -1 if the phone was already disconnected.
+ *
  */
 int ipc_phone_hangup(phone_t *phone)
 {
-	answerbox_t *box;
-	call_t *call;
-	
 	mutex_lock(&phone->lock);
 	if (phone->state == IPC_PHONE_FREE ||
@@ -359,20 +358,21 @@
 		return -1;
 	}
-	box = phone->callee;
+	
+	answerbox_t *box = phone->callee;
 	if (phone->state != IPC_PHONE_SLAMMED) {
 		/* Remove myself from answerbox */
-		spinlock_lock(&box->lock);
+		irq_spinlock_lock(&box->lock, true);
 		list_remove(&phone->link);
-		spinlock_unlock(&box->lock);
-
-		call = ipc_call_alloc(0);
+		irq_spinlock_unlock(&box->lock, true);
+		
+		call_t *call = ipc_call_alloc(0);
 		IPC_SET_METHOD(call->data, IPC_M_PHONE_HUNGUP);
 		call->flags |= IPC_CALL_DISCARD_ANSWER;
 		_ipc_call(phone, box, call);
 	}
-
+	
 	phone->state = IPC_PHONE_HUNGUP;
 	mutex_unlock(&phone->lock);
-
+	
 	return 0;
 }
@@ -380,30 +380,26 @@
 /** Forwards call from one answerbox to another one.
  *
- * @param call		Call structure to be redirected.
- * @param newphone	Phone structure to target answerbox.
- * @param oldbox	Old answerbox structure.
- * @param mode		Flags that specify mode of the forward operation.
- *
- * @return		Return 0 if forwarding succeeded or an error code if
- *			there was error.
- * 
+ * @param call     Call structure to be redirected.
+ * @param newphone Phone structure to target answerbox.
+ * @param oldbox   Old answerbox structure.
+ * @param mode     Flags that specify mode of the forward operation.
+ *
+ * @return 0 if forwarding succeeded or an error code if
+ *         there was an error.
+ *
  * The return value serves only as an information for the forwarder,
  * the original caller is notified automatically with EFORWARD.
- */
-int ipc_forward(call_t *call, phone_t *newphone, answerbox_t *oldbox, int mode)
-{
-	ipl_t ipl;
-
+ *
+ */
+int ipc_forward(call_t *call, phone_t *newphone, answerbox_t *oldbox,
+    unsigned int mode)
+{
 	/* Count forwarded calls */
-	ipl = interrupts_disable();
-	spinlock_lock(&TASK->lock);
+	irq_spinlock_lock(&TASK->lock, true);
 	TASK->ipc_info.forwarded++;
-	spinlock_unlock(&TASK->lock);
-	interrupts_restore(ipl);
-
-	spinlock_lock(&oldbox->lock);
+	irq_spinlock_pass(&TASK->lock, &oldbox->lock);
 	list_remove(&call->link);
-	spinlock_unlock(&oldbox->lock);
-
+	irq_spinlock_unlock(&oldbox->lock, true);
+	
 	if (mode & IPC_FF_ROUTE_FROM_ME) {
 		if (!call->caller_phone)
@@ -411,5 +407,5 @@
 		call->data.phone = newphone;
 	}
-
+	
 	return ipc_call(newphone, call);
 }
@@ -418,24 +414,25 @@
 /** Wait for a phone call.
  *
- * @param box		Answerbox expecting the call.
- * @param usec		Timeout in microseconds. See documentation for
- *			waitq_sleep_timeout() for decription of its special
- *			meaning.
- * @param flags		Select mode of sleep operation. See documentation for
- *			waitq_sleep_timeout() for description of its special
- *			meaning.
- * @return 		Recived call structure or NULL.
- * 
+ * @param box   Answerbox expecting the call.
+ * @param usec  Timeout in microseconds. See documentation for
+ *              waitq_sleep_timeout() for decription of its special
+ *              meaning.
+ * @param flags Select mode of sleep operation. See documentation for
+ *              waitq_sleep_timeout() for description of its special
+ *              meaning.
+ *
+ * @return Recived call structure or NULL.
+ *
  * To distinguish between a call and an answer, have a look at call->flags.
- */
-call_t *ipc_wait_for_call(answerbox_t *box, uint32_t usec, int flags)
+ *
+ */
+call_t *ipc_wait_for_call(answerbox_t *box, uint32_t usec, unsigned int flags)
 {
 	call_t *request;
-	ipl_t ipl;
 	uint64_t irq_cnt = 0;
 	uint64_t answer_cnt = 0;
 	uint64_t call_cnt = 0;
 	int rc;
-
+	
 restart:
 	rc = waitq_sleep_timeout(&box->wq, usec, flags);
@@ -443,21 +440,19 @@
 		return NULL;
 	
-	spinlock_lock(&box->lock);
+	irq_spinlock_lock(&box->lock, true);
 	if (!list_empty(&box->irq_notifs)) {
-		/* Count recieved IRQ notification */
-		irq_cnt++;	
-
-		ipl = interrupts_disable();
-		spinlock_lock(&box->irq_lock);
-
+		/* Count received IRQ notification */
+		irq_cnt++;
+		
+		irq_spinlock_lock(&box->irq_lock, false);
+		
 		request = list_get_instance(box->irq_notifs.next, call_t, link);
 		list_remove(&request->link);
-
-		spinlock_unlock(&box->irq_lock);
-		interrupts_restore(ipl);
+		
+		irq_spinlock_unlock(&box->irq_lock, false);
 	} else if (!list_empty(&box->answers)) {
-		/* Count recieved answer */
+		/* Count received answer */
 		answer_cnt++;
-
+		
 		/* Handle asynchronous answers */
 		request = list_get_instance(box->answers.next, call_t, link);
@@ -465,27 +460,27 @@
 		atomic_dec(&request->data.phone->active_calls);
 	} else if (!list_empty(&box->calls)) {
-		/* Count recieved call */
+		/* Count received call */
 		call_cnt++;
-
+		
 		/* Handle requests */
 		request = list_get_instance(box->calls.next, call_t, link);
 		list_remove(&request->link);
+		
 		/* Append request to dispatch queue */
 		list_append(&request->link, &box->dispatched_calls);
 	} else {
 		/* This can happen regularly after ipc_cleanup */
-		spinlock_unlock(&box->lock);
+		irq_spinlock_unlock(&box->lock, true);
 		goto restart;
 	}
-	spinlock_unlock(&box->lock);
-	
-	ipl = interrupts_disable();
-	spinlock_lock(&TASK->lock);
-	TASK->ipc_info.irq_notif_recieved += irq_cnt;
-	TASK->ipc_info.answer_recieved += answer_cnt;
-	TASK->ipc_info.call_recieved += call_cnt;
-	spinlock_unlock(&TASK->lock);
-	interrupts_restore(ipl);
-
+	
+	irq_spinlock_pass(&box->lock, &TASK->lock);
+	
+	TASK->ipc_info.irq_notif_received += irq_cnt;
+	TASK->ipc_info.answer_received += answer_cnt;
+	TASK->ipc_info.call_received += call_cnt;
+	
+	irq_spinlock_unlock(&TASK->lock, true);
+	
 	return request;
 }
@@ -493,16 +488,16 @@
 /** Answer all calls from list with EHANGUP answer.
  *
- * @param lst		Head of the list to be cleaned up.
+ * @param lst Head of the list to be cleaned up.
+ *
  */
 void ipc_cleanup_call_list(link_t *lst)
 {
-	call_t *call;
-
 	while (!list_empty(lst)) {
-		call = list_get_instance(lst->next, call_t, link);
+		call_t *call = list_get_instance(lst->next, call_t, link);
 		if (call->buffer)
 			free(call->buffer);
+		
 		list_remove(&call->link);
-
+		
 		IPC_SET_RETVAL(call->data, EHANGUP);
 		_ipc_answer_free_call(call, true);
@@ -512,7 +507,8 @@
 /** Disconnects all phones connected to an answerbox.
  *
- * @param box		Answerbox to disconnect phones from.
- * @param notify_box	If true, the answerbox will get a hangup message for
- *			each disconnected phone.
+ * @param box        Answerbox to disconnect phones from.
+ * @param notify_box If true, the answerbox will get a hangup message for
+ *                   each disconnected phone.
+ *
  */
 void ipc_answerbox_slam_phones(answerbox_t *box, bool notify_box)
@@ -520,19 +516,15 @@
 	phone_t *phone;
 	DEADLOCK_PROBE_INIT(p_phonelck);
-	ipl_t ipl;
-	call_t *call;
-
-	call = notify_box ? ipc_call_alloc(0) : NULL;
-
+	
+	call_t *call = notify_box ? ipc_call_alloc(0) : NULL;
+	
 	/* Disconnect all phones connected to our answerbox */
 restart_phones:
-	ipl = interrupts_disable();
-	spinlock_lock(&box->lock);
+	irq_spinlock_lock(&box->lock, true);
 	while (!list_empty(&box->connected_phones)) {
 		phone = list_get_instance(box->connected_phones.next,
 		    phone_t, link);
 		if (SYNCH_FAILED(mutex_trylock(&phone->lock))) {
-			spinlock_unlock(&box->lock);
-			interrupts_restore(ipl);
+			irq_spinlock_unlock(&box->lock, true);
 			DEADLOCK_PROBE(p_phonelck, DEADLOCK_THRESHOLD);
 			goto restart_phones;
@@ -541,13 +533,12 @@
 		/* Disconnect phone */
 		ASSERT(phone->state == IPC_PHONE_CONNECTED);
-
+		
 		list_remove(&phone->link);
 		phone->state = IPC_PHONE_SLAMMED;
-
+		
 		if (notify_box) {
 			mutex_unlock(&phone->lock);
-			spinlock_unlock(&box->lock);
-			interrupts_restore(ipl);
-
+			irq_spinlock_unlock(&box->lock, true);
+			
 			/*
 			 * Send one message to the answerbox for each
@@ -559,18 +550,17 @@
 			call->flags |= IPC_CALL_DISCARD_ANSWER;
 			_ipc_call(phone, box, call);
-
+			
 			/* Allocate another call in advance */
 			call = ipc_call_alloc(0);
-
+			
 			/* Must start again */
 			goto restart_phones;
 		}
-
+		
 		mutex_unlock(&phone->lock);
 	}
-
-	spinlock_unlock(&box->lock);
-	interrupts_restore(ipl);
-
+	
+	irq_spinlock_unlock(&box->lock, true);
+	
 	/* Free unused call */
 	if (call)
@@ -578,47 +568,45 @@
 }
 
-/** Cleans up all IPC communication of the current task.
+/** Clean up all IPC communication of the current task.
  *
  * Note: ipc_hangup sets returning answerbox to TASK->answerbox, you
  * have to change it as well if you want to cleanup other tasks than TASK.
+ *
  */
 void ipc_cleanup(void)
 {
-	int i;
-	call_t *call;
-	ipl_t ipl;
-
 	/* Disconnect all our phones ('ipc_phone_hangup') */
+	size_t i;
 	for (i = 0; i < IPC_MAX_PHONES; i++)
 		ipc_phone_hangup(&TASK->phones[i]);
-
+	
 	/* Unsubscribe from any event notifications. */
 	event_cleanup_answerbox(&TASK->answerbox);
-
+	
 	/* Disconnect all connected irqs */
 	ipc_irq_cleanup(&TASK->answerbox);
-
+	
 	/* Disconnect all phones connected to our regular answerbox */
 	ipc_answerbox_slam_phones(&TASK->answerbox, false);
-
+	
 #ifdef CONFIG_UDEBUG
 	/* Clean up kbox thread and communications */
 	ipc_kbox_cleanup();
 #endif
-
+	
 	/* Answer all messages in 'calls' and 'dispatched_calls' queues */
-	spinlock_lock(&TASK->answerbox.lock);
+	irq_spinlock_lock(&TASK->answerbox.lock, true);
 	ipc_cleanup_call_list(&TASK->answerbox.dispatched_calls);
 	ipc_cleanup_call_list(&TASK->answerbox.calls);
-	spinlock_unlock(&TASK->answerbox.lock);
+	irq_spinlock_unlock(&TASK->answerbox.lock, true);
 	
 	/* Wait for all answers to interrupted synchronous calls to arrive */
-	ipl = interrupts_disable();
+	ipl_t ipl = interrupts_disable();
 	while (!list_empty(&TASK->sync_box_head)) {
 		answerbox_t *box = list_get_instance(TASK->sync_box_head.next,
 		    answerbox_t, sync_box_link);
-
+		
 		list_remove(&box->sync_box_link);
-		call = ipc_wait_for_call(box, SYNCH_NO_TIMEOUT,
+		call_t *call = ipc_wait_for_call(box, SYNCH_NO_TIMEOUT,
 		    SYNCH_FLAGS_NONE);
 		ipc_call_free(call);
@@ -626,10 +614,12 @@
 	}
 	interrupts_restore(ipl);
-
+	
 	/* Wait for all answers to asynchronous calls to arrive */
-	while (1) {
-		/* Go through all phones, until all are FREE... */
-		/* Locking not needed, no one else should modify
-		 * it, when we are in cleanup */
+	while (true) {
+		/*
+		 * Go through all phones, until they are all FREE
+		 * Locking is not needed, no one else should modify
+		 * it when we are in cleanup
+		 */
 		for (i = 0; i < IPC_MAX_PHONES; i++) {
 			if (TASK->phones[i].state == IPC_PHONE_HUNGUP &&
@@ -639,20 +629,26 @@
 			}
 			
-			/* Just for sure, we might have had some 
-			 * IPC_PHONE_CONNECTING phones */
+			/*
+			 * Just for sure, we might have had some
+			 * IPC_PHONE_CONNECTING phones
+			 */
 			if (TASK->phones[i].state == IPC_PHONE_CONNECTED)
 				ipc_phone_hangup(&TASK->phones[i]);
-			/* If the hangup succeeded, it has sent a HANGUP 
+			
+			/*
+			 * If the hangup succeeded, it has sent a HANGUP
 			 * message, the IPC is now in HUNGUP state, we
-			 * wait for the reply to come */
+			 * wait for the reply to come
+			 */
 			
 			if (TASK->phones[i].state != IPC_PHONE_FREE)
 				break;
 		}
-		/* Voila, got into cleanup */
+		
+		/* Got into cleanup */
 		if (i == IPC_MAX_PHONES)
 			break;
 		
-		call = ipc_wait_for_call(&TASK->answerbox, SYNCH_NO_TIMEOUT,
+		call_t *call = ipc_wait_for_call(&TASK->answerbox, SYNCH_NO_TIMEOUT,
 		    SYNCH_FLAGS_NONE);
 		ASSERT((call->flags & IPC_CALL_ANSWERED) ||
@@ -666,10 +662,12 @@
 		if (!(call->flags & IPC_CALL_DISCARD_ANSWER))
 			atomic_dec(&TASK->active_calls);
+		
 		ipc_call_free(call);
 	}
 }
 
-
-/** Initilize IPC subsystem */
+/** Initilize IPC subsystem
+ *
+ */
 void ipc_init(void)
 {
@@ -680,30 +678,26 @@
 }
 
-
 /** List answerbox contents.
  *
- * @param taskid	Task ID.
+ * @param taskid Task ID.
+ *
  */
 void ipc_print_task(task_id_t taskid)
 {
-	task_t *task;
-	int i;
-	call_t *call;
-	link_t *tmp;
-	ipl_t ipl;
-	
-	ipl = interrupts_disable();
-	spinlock_lock(&tasks_lock);
-	task = task_find_by_id(taskid);
-	if (task) 
-		spinlock_lock(&task->lock);
-	spinlock_unlock(&tasks_lock);
+	irq_spinlock_lock(&tasks_lock, true);
+	task_t *task = task_find_by_id(taskid);
+	
 	if (!task) {
-		interrupts_restore(ipl);
+		irq_spinlock_unlock(&tasks_lock, true);
 		return;
 	}
-
+	
+	/* Hand-over-hand locking */
+	irq_spinlock_exchange(&tasks_lock, &task->lock);
+	
 	/* Print opened phones & details */
 	printf("PHONE:\n");
+	
+	size_t i;
 	for (i = 0; i < IPC_MAX_PHONES; i++) {
 		if (SYNCH_FAILED(mutex_trylock(&task->phones[i].lock))) {
@@ -711,6 +705,8 @@
 			continue;
 		}
+		
 		if (task->phones[i].state != IPC_PHONE_FREE) {
-			printf("%d: ", i);
+			printf("%" PRIs ": ", i);
+			
 			switch (task->phones[i].state) {
 			case IPC_PHONE_CONNECTING:
@@ -718,31 +714,35 @@
 				break;
 			case IPC_PHONE_CONNECTED:
-				printf("connected to: %p ", 
-				       task->phones[i].callee);
+				printf("connected to: %p ",
+				    task->phones[i].callee);
 				break;
 			case IPC_PHONE_SLAMMED:
 				printf("slammed by: %p ", 
-				       task->phones[i].callee);
+				    task->phones[i].callee);
 				break;
 			case IPC_PHONE_HUNGUP:
 				printf("hung up - was: %p ", 
-				       task->phones[i].callee);
+				    task->phones[i].callee);
 				break;
 			default:
 				break;
 			}
-			printf("active: %ld\n",
+			
+			printf("active: %" PRIun "\n",
 			    atomic_get(&task->phones[i].active_calls));
 		}
+		
 		mutex_unlock(&task->phones[i].lock);
 	}
-
-
+	
+	irq_spinlock_lock(&task->answerbox.lock, false);
+	
+	link_t *cur;
+	
 	/* Print answerbox - calls */
-	spinlock_lock(&task->answerbox.lock);
 	printf("ABOX - CALLS:\n");
-	for (tmp = task->answerbox.calls.next; tmp != &task->answerbox.calls;
-	    tmp = tmp->next) {
-		call = list_get_instance(tmp, call_t, link);
+	for (cur = task->answerbox.calls.next; cur != &task->answerbox.calls;
+	    cur = cur->next) {
+		call_t *call = list_get_instance(cur, call_t, link);
 		printf("Callid: %p Srctask:%" PRIu64 " M:%" PRIun 
 		    " A1:%" PRIun " A2:%" PRIun " A3:%" PRIun
@@ -754,10 +754,11 @@
 		    call->flags);
 	}
-	/* Print answerbox - calls */
+	
+	/* Print answerbox - dispatched calls */
 	printf("ABOX - DISPATCHED CALLS:\n");
-	for (tmp = task->answerbox.dispatched_calls.next;
-	    tmp != &task->answerbox.dispatched_calls; 
-	    tmp = tmp->next) {
-		call = list_get_instance(tmp, call_t, link);
+	for (cur = task->answerbox.dispatched_calls.next;
+	    cur != &task->answerbox.dispatched_calls;
+	    cur = cur->next) {
+		call_t *call = list_get_instance(cur, call_t, link);
 		printf("Callid: %p Srctask:%" PRIu64 " M:%" PRIun
 		    " A1:%" PRIun " A2:%" PRIun " A3:%" PRIun
@@ -769,10 +770,11 @@
 		    call->flags);
 	}
-	/* Print answerbox - calls */
+	
+	/* Print answerbox - answers */
 	printf("ABOX - ANSWERS:\n");
-	for (tmp = task->answerbox.answers.next;
-	    tmp != &task->answerbox.answers;
-	    tmp = tmp->next) {
-		call = list_get_instance(tmp, call_t, link);
+	for (cur = task->answerbox.answers.next;
+	    cur != &task->answerbox.answers;
+	    cur = cur->next) {
+		call_t *call = list_get_instance(cur, call_t, link);
 		printf("Callid:%p M:%" PRIun " A1:%" PRIun " A2:%" PRIun
 		    " A3:%" PRIun " A4:%" PRIun " A5:%" PRIun " Flags:%x\n",
@@ -782,8 +784,7 @@
 		    call->flags);
 	}
-
-	spinlock_unlock(&task->answerbox.lock);
-	spinlock_unlock(&task->lock);
-	interrupts_restore(ipl);
+	
+	irq_spinlock_unlock(&task->answerbox.lock, false);
+	irq_spinlock_unlock(&task->lock, true);
 }
 
Index: kernel/generic/src/ipc/ipcrsc.c
===================================================================
--- kernel/generic/src/ipc/ipcrsc.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/generic/src/ipc/ipcrsc.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -45,5 +45,5 @@
  * - hangup phone (the caller has hung up)
  * - hangup phone (the answerbox is exiting)
- * 
+ *
  * Locking strategy
  *
@@ -85,5 +85,5 @@
  *
  * Phone hangup
- * 
+ *
  * *** The caller hangs up (sys_ipc_hangup) ***
  * - The phone is disconnected (no more messages can be sent over this phone),
@@ -99,5 +99,5 @@
  *
  * 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 
@@ -114,5 +114,5 @@
  *
  * Cleanup strategy
- * 
+ *
  * 1) Disconnect all our phones ('ipc_phone_hangup').
  *
@@ -123,5 +123,5 @@
  *
  * 4) Wait for all async answers to arrive and dispose of them.
- * 
+ *
  */
 
@@ -137,19 +137,20 @@
  * @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.
+ *
  */
 call_t *get_call(unative_t callid)
 {
 	link_t *lst;
-	call_t *call, *result = NULL;
-
-	spinlock_lock(&TASK->answerbox.lock);
+	call_t *result = NULL;
+	
+	irq_spinlock_lock(&TASK->answerbox.lock, true);
 	for (lst = TASK->answerbox.dispatched_calls.next;
 	    lst != &TASK->answerbox.dispatched_calls; lst = lst->next) {
-		call = list_get_instance(lst, call_t, link);
+		call_t *call = list_get_instance(lst, call_t, link);
 		if ((unative_t) call == callid) {
 			result = call;
@@ -157,5 +158,6 @@
 		}
 	}
-	spinlock_unlock(&TASK->answerbox.lock);
+	
+	irq_spinlock_unlock(&TASK->answerbox.lock, true);
 	return result;
 }
@@ -163,29 +165,31 @@
 /** Allocate new phone slot in the specified task.
  *
- * @param t		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 *t)
-{
-	int i;
-
-	spinlock_lock(&t->lock);
+ * @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++) {
-		if (t->phones[i].state == IPC_PHONE_HUNGUP &&
-		    atomic_get(&t->phones[i].active_calls) == 0)
-			t->phones[i].state = IPC_PHONE_FREE;
-
-		if (t->phones[i].state == IPC_PHONE_FREE) {
-			t->phones[i].state = IPC_PHONE_CONNECTING;
+		if ((task->phones[i].state == IPC_PHONE_HUNGUP) &&
+		    (atomic_get(&task->phones[i].active_calls) == 0))
+			task->phones[i].state = IPC_PHONE_FREE;
+		
+		if (task->phones[i].state == IPC_PHONE_FREE) {
+			task->phones[i].state = IPC_PHONE_CONNECTING;
 			break;
 		}
 	}
-	spinlock_unlock(&t->lock);
-
+	
+	irq_spinlock_unlock(&task->lock, true);
+	
 	if (i == IPC_MAX_PHONES)
 		return -1;
-
+	
 	return i;
 }
@@ -193,5 +197,6 @@
 /** Mark a phone structure free.
  *
- * @param phone		Phone structure to be marked free.
+ * @param phone Phone structure to be marked free.
+ *
  */
 static void phone_deallocp(phone_t *phone)
@@ -199,5 +204,5 @@
 	ASSERT(phone->state == IPC_PHONE_CONNECTING);
 	
-	/* atomic operation */
+	/* Atomic operation */
 	phone->state = IPC_PHONE_FREE;
 }
@@ -207,5 +212,6 @@
  * All already sent messages will be correctly processed.
  *
- * @param phoneid	Phone handle of the phone to be freed.
+ * @param phoneid Phone handle of the phone to be freed.
+ *
  */
 void phone_dealloc(int phoneid)
@@ -216,10 +222,11 @@
 /** Connect phone to a given answerbox.
  *
- * @param phoneid 	Phone handle to be connected.
- * @param box		Answerbox to which to connect the phone handle.
+ * @param phoneid Phone handle to be connected.
+ * @param box     Answerbox to which to connect the phone handle.
  *
  * 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.
+ *
  */
 void phone_connect(int phoneid, answerbox_t *box)
Index: kernel/generic/src/ipc/irq.c
===================================================================
--- kernel/generic/src/ipc/irq.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/generic/src/ipc/irq.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -31,4 +31,5 @@
  * @{
  */
+
 /**
  * @file
@@ -67,4 +68,5 @@
  *   structure are finished. Because we hold the hash table lock, we prevent new
  *   IRQs from taking new references to the IRQ structure.
+ *
  */
 
@@ -81,5 +83,6 @@
 /** Free the top-half pseudocode.
  *
- * @param code		Pointer to the top-half pseudocode.
+ * @param code Pointer to the top-half pseudocode.
+ *
  */
 static void code_free(irq_code_t *code)
@@ -93,16 +96,13 @@
 /** 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.
+ * @param ucode Userspace address of the top-half pseudocode.
+ *
+ * @return Kernel address of the copied pseudocode.
+ *
  */
 static irq_code_t *code_from_uspace(irq_code_t *ucode)
 {
-	irq_code_t *code;
-	irq_cmd_t *ucmds;
-	int rc;
-
-	code = malloc(sizeof(*code), 0);
-	rc = copy_from_uspace(code, ucode, sizeof(*code));
+	irq_code_t *code = malloc(sizeof(*code), 0);
+	int rc = copy_from_uspace(code, ucode, sizeof(*code));
 	if (rc != 0) {
 		free(code);
@@ -114,5 +114,6 @@
 		return NULL;
 	}
-	ucmds = code->cmds;
+	
+	irq_cmd_t *ucmds = code->cmds;
 	code->cmds = malloc(sizeof(code->cmds[0]) * code->cmdcount, 0);
 	rc = copy_from_uspace(code->cmds, ucmds,
@@ -123,5 +124,5 @@
 		return NULL;
 	}
-
+	
 	return code;
 }
@@ -141,8 +142,4 @@
     unative_t method, irq_code_t *ucode)
 {
-	ipl_t ipl;
-	irq_code_t *code;
-	irq_t *irq;
-	link_t *hlp;
 	unative_t key[] = {
 		(unative_t) inr,
@@ -150,18 +147,17 @@
 	};
 	
-	printf("kernel ipc_irq_register() ... registering irq = %d\n", inr);
-	
+	irq_code_t *code;
 	if (ucode) {
 		code = code_from_uspace(ucode);
 		if (!code)
 			return EBADMEM;
-	} else {
+	} else
 		code = NULL;
-	}
 	
 	/*
 	 * Allocate and populate the IRQ structure.
 	 */
-	irq = malloc(sizeof(irq_t), 0);
+	irq_t *irq = malloc(sizeof(irq_t), 0);
+	
 	irq_initialize(irq);
 	irq->devno = devno;
@@ -179,32 +175,30 @@
 	 * answerbox's list.
 	 */
-	ipl = interrupts_disable();
-	spinlock_lock(&irq_uspace_hash_table_lock);
-	hlp = hash_table_find(&irq_uspace_hash_table, key);
+	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 __attribute__((unused))
-		    = hash_table_get_instance(hlp, irq_t, link);
+		irq_t *hirq = hash_table_get_instance(hlp, irq_t, link);
 		
 		/* hirq is locked */
-		spinlock_unlock(&hirq->lock);
+		irq_spinlock_unlock(&hirq->lock, false);
 		code_free(code);
-		spinlock_unlock(&irq_uspace_hash_table_lock);
+		irq_spinlock_unlock(&irq_uspace_hash_table_lock, true);
+		
 		free(irq);
-		interrupts_restore(ipl);
 		return EEXISTS;
 	}
 	
-	spinlock_lock(&irq->lock);  /* Not really necessary, but paranoid */
-	spinlock_lock(&box->irq_lock);
+	/* 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_head);
-	spinlock_unlock(&box->irq_lock);
-	spinlock_unlock(&irq->lock);
-	spinlock_unlock(&irq_uspace_hash_table_lock);
-	
-	interrupts_restore(ipl);
-	
-	printf("kernel ipc_irq_register() ... registering irq = %d was successful \n", inr);
-
+	
+	irq_spinlock_unlock(&box->irq_lock, false);
+	irq_spinlock_unlock(&irq->lock, false);
+	irq_spinlock_unlock(&irq_uspace_hash_table_lock, true);
+	
 	return EOK;
 }
@@ -212,29 +206,27 @@
 /** Unregister task from IRQ notification.
  *
- * @param box		Answerbox associated with the notification.
- * @param inr		IRQ number.
- * @param devno		Device number.
+ * @param box   Answerbox associated with the notification.
+ * @param inr   IRQ number.
+ * @param devno Device number.
+ *
  */
 int ipc_irq_unregister(answerbox_t *box, inr_t inr, devno_t devno)
 {
-	ipl_t ipl;
 	unative_t key[] = {
 		(unative_t) inr,
 		(unative_t) devno
 	};
-	link_t *lnk;
-	irq_t *irq;
-
-	ipl = interrupts_disable();
-	spinlock_lock(&irq_uspace_hash_table_lock);
-	lnk = hash_table_find(&irq_uspace_hash_table, key);
+	
+	irq_spinlock_lock(&irq_uspace_hash_table_lock, true);
+	link_t *lnk = hash_table_find(&irq_uspace_hash_table, key);
 	if (!lnk) {
-		spinlock_unlock(&irq_uspace_hash_table_lock);
-		interrupts_restore(ipl);
+		irq_spinlock_unlock(&irq_uspace_hash_table_lock, true);
 		return ENOENT;
 	}
-	irq = hash_table_get_instance(lnk, irq_t, link);
+	
+	irq_t *irq = hash_table_get_instance(lnk, irq_t, link);
+	
 	/* irq is locked */
-	spinlock_lock(&box->irq_lock);
+	irq_spinlock_lock(&box->irq_lock, false);
 	
 	ASSERT(irq->notif_cfg.answerbox == box);
@@ -242,8 +234,8 @@
 	/* Free up the pseudo code and associated structures. */
 	code_free(irq->notif_cfg.code);
-
-	/* Remove the IRQ from the answerbox's list. */ 
+	
+	/* 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
@@ -253,19 +245,17 @@
 	 * the meantime.
 	 */
-	spinlock_unlock(&irq->lock);
-
+	irq_spinlock_unlock(&irq->lock, false);
+	
 	/* Remove the IRQ from the uspace IRQ hash table. */
 	hash_table_remove(&irq_uspace_hash_table, key, 2);
 	
-	spinlock_unlock(&irq_uspace_hash_table_lock);
-	spinlock_unlock(&box->irq_lock);
+	irq_spinlock_unlock(&box->irq_lock, false);
+	irq_spinlock_unlock(&irq_uspace_hash_table_lock, true);
 	
 	/* Free up the IRQ structure. */
 	free(irq);
 	
-	interrupts_restore(ipl);
 	return EOK;
 }
-
 
 /** Disconnect all IRQ notifications from an answerbox.
@@ -275,35 +265,32 @@
  * send notifications to it.
  *
- * @param box		Answerbox for which we want to carry out the cleanup.
+ * @param box Answerbox for which we want to carry out the cleanup.
+ *
  */
 void ipc_irq_cleanup(answerbox_t *box)
 {
-	ipl_t ipl;
-	
 loop:
-	ipl = interrupts_disable();
-	spinlock_lock(&irq_uspace_hash_table_lock);
-	spinlock_lock(&box->irq_lock);
+	irq_spinlock_lock(&irq_uspace_hash_table_lock, true);
+	irq_spinlock_lock(&box->irq_lock, false);
 	
 	while (box->irq_head.next != &box->irq_head) {
-		link_t *cur = box->irq_head.next;
-		irq_t *irq;
 		DEADLOCK_PROBE_INIT(p_irqlock);
-		unative_t key[2];
-		
-		irq = list_get_instance(cur, irq_t, notif_cfg.link);
-		if (!spinlock_trylock(&irq->lock)) {
+		
+		irq_t *irq = list_get_instance(box->irq_head.next, irq_t,
+		    notif_cfg.link);
+		
+		if (!irq_spinlock_trylock(&irq->lock)) {
 			/*
 			 * Avoid deadlock by trying again.
 			 */
-			spinlock_unlock(&box->irq_lock);
-			spinlock_unlock(&irq_uspace_hash_table_lock);
-			interrupts_restore(ipl);
+			irq_spinlock_unlock(&box->irq_lock, false);
+			irq_spinlock_unlock(&irq_uspace_hash_table_lock, true);
 			DEADLOCK_PROBE(p_irqlock, DEADLOCK_THRESHOLD);
 			goto loop;
 		}
+		
+		unative_t key[2];
 		key[0] = irq->inr;
 		key[1] = irq->devno;
-		
 		
 		ASSERT(irq->notif_cfg.answerbox == box);
@@ -322,5 +309,5 @@
 		 * didn't drop the hash table lock in the meantime.
 		 */
-		spinlock_unlock(&irq->lock);
+		irq_spinlock_unlock(&irq->lock, false);
 		
 		/* Remove from the hash table. */
@@ -330,22 +317,22 @@
 	}
 	
-	spinlock_unlock(&box->irq_lock);
-	spinlock_unlock(&irq_uspace_hash_table_lock);
-	interrupts_restore(ipl);
+	irq_spinlock_unlock(&box->irq_lock, false);
+	irq_spinlock_unlock(&irq_uspace_hash_table_lock, true);
 }
 
 /** Add a call to the proper answerbox queue.
  *
- * Assume irq->lock is locked.
- *
- * @param irq		IRQ structure referencing the target answerbox.
- * @param call		IRQ notification call.
+ * Assume irq->lock is locked and interrupts disabled.
+ *
+ * @param irq  IRQ structure referencing the target answerbox.
+ * @param call IRQ notification call.
+ *
  */
 static void send_call(irq_t *irq, call_t *call)
 {
-	spinlock_lock(&irq->notif_cfg.answerbox->irq_lock);
+	irq_spinlock_lock(&irq->notif_cfg.answerbox->irq_lock, false);
 	list_append(&call->link, &irq->notif_cfg.answerbox->irq_notifs);
-	spinlock_unlock(&irq->notif_cfg.answerbox->irq_lock);
-		
+	irq_spinlock_unlock(&irq->notif_cfg.answerbox->irq_lock, false);
+	
 	waitq_wakeup(&irq->notif_cfg.answerbox->wq, WAKEUP_FIRST);
 }
@@ -353,16 +340,14 @@
 /** Apply the top-half pseudo 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.
+ * @param irq IRQ structure.
+ *
+ * @return IRQ_ACCEPT if the interrupt is accepted by the
+ *         pseudocode, IRQ_DECLINE otherwise.
+ *
  */
 irq_ownership_t ipc_irq_top_half_claim(irq_t *irq)
 {
-	unsigned int i;
-	unative_t dstval;
 	irq_code_t *code = irq->notif_cfg.code;
-	unative_t *scratch = irq->notif_cfg.scratch;
-
+	uint32_t *scratch = irq->notif_cfg.scratch;
 	
 	if (!irq->notif_cfg.notify)
@@ -372,10 +357,13 @@
 		return IRQ_DECLINE;
 	
+	size_t i;
 	for (i = 0; i < code->cmdcount; i++) {
-		unsigned int srcarg = code->cmds[i].srcarg;
-		unsigned int dstarg = code->cmds[i].dstarg;
+		uint32_t dstval;
+		uintptr_t srcarg = code->cmds[i].srcarg;
+		uintptr_t dstarg = code->cmds[i].dstarg;
 		
 		if (srcarg >= IPC_CALL_LEN)
 			break;
+		
 		if (dstarg >= IPC_CALL_LEN)
 			break;
@@ -410,5 +398,5 @@
 			break;
 		case CMD_BTEST:
-			if (srcarg && dstarg) {
+			if ((srcarg) && (dstarg)) {
 				dstval = scratch[srcarg] & code->cmds[i].value;
 				scratch[dstarg] = dstval;
@@ -416,5 +404,5 @@
 			break;
 		case CMD_PREDICATE:
-			if (srcarg && !scratch[srcarg]) {
+			if ((srcarg) && (!scratch[srcarg])) {
 				i += code->cmds[i].value;
 				continue;
@@ -432,10 +420,10 @@
 }
 
-
 /* IRQ top-half handler.
  *
  * We expect interrupts to be disabled and the irq->lock already held.
  *
- * @param irq		IRQ structure.
+ * @param irq IRQ structure.
+ *
  */
 void ipc_irq_top_half_handler(irq_t *irq)
@@ -443,8 +431,9 @@
 	ASSERT(irq);
 
+	ASSERT(interrupts_disabled());
+	ASSERT(irq_spinlock_locked(&irq->lock));
+	
 	if (irq->notif_cfg.answerbox) {
-		call_t *call;
-
-		call = ipc_call_alloc(FRAME_ATOMIC);
+		call_t *call = ipc_call_alloc(FRAME_ATOMIC);
 		if (!call)
 			return;
@@ -453,5 +442,5 @@
 		/* Put a counter to the message */
 		call->priv = ++irq->notif_cfg.counter;
-
+		
 		/* Set up args */
 		IPC_SET_METHOD(call->data, irq->notif_cfg.method);
@@ -461,5 +450,5 @@
 		IPC_SET_ARG4(call->data, irq->notif_cfg.scratch[4]);
 		IPC_SET_ARG5(call->data, irq->notif_cfg.scratch[5]);
-
+		
 		send_call(irq, call);
 	}
@@ -468,28 +457,28 @@
 /** Send notification message.
  *
- * @param irq		IRQ structure.
- * @param a1		Driver-specific payload argument.
- * @param a2		Driver-specific payload argument.
- * @param a3		Driver-specific payload argument.
- * @param a4		Driver-specific payload argument.
- * @param a5		Driver-specific payload argument.
+ * @param irq IRQ structure.
+ * @param a1  Driver-specific payload argument.
+ * @param a2  Driver-specific payload argument.
+ * @param a3  Driver-specific payload argument.
+ * @param a4  Driver-specific payload argument.
+ * @param a5  Driver-specific payload argument.
+ *
  */
 void ipc_irq_send_msg(irq_t *irq, unative_t a1, unative_t a2, unative_t a3,
     unative_t a4, unative_t a5)
 {
-	call_t *call;
-
-	spinlock_lock(&irq->lock);
-
+	irq_spinlock_lock(&irq->lock, true);
+	
 	if (irq->notif_cfg.answerbox) {
-		call = ipc_call_alloc(FRAME_ATOMIC);
+		call_t *call = ipc_call_alloc(FRAME_ATOMIC);
 		if (!call) {
-			spinlock_unlock(&irq->lock);
+			irq_spinlock_unlock(&irq->lock, true);
 			return;
 		}
+		
 		call->flags |= IPC_CALL_NOTIF;
 		/* Put a counter to the message */
 		call->priv = ++irq->notif_cfg.counter;
-
+		
 		IPC_SET_METHOD(call->data, irq->notif_cfg.method);
 		IPC_SET_ARG1(call->data, a1);
@@ -501,5 +490,6 @@
 		send_call(irq, call);
 	}
-	spinlock_unlock(&irq->lock);
+	
+	irq_spinlock_unlock(&irq->lock, true);
 }
 
Index: kernel/generic/src/ipc/kbox.c
===================================================================
--- kernel/generic/src/ipc/kbox.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/generic/src/ipc/kbox.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -47,7 +47,5 @@
 void ipc_kbox_cleanup(void)
 {
-	bool have_kb_thread;
-
-	/* 
+	/*
 	 * Only hold kb.cleanup_lock while setting kb.finished -
 	 * this is enough.
@@ -56,12 +54,12 @@
 	TASK->kb.finished = true;
 	mutex_unlock(&TASK->kb.cleanup_lock);
-
-	have_kb_thread = (TASK->kb.thread != NULL);
-
+	
+	bool have_kb_thread = (TASK->kb.thread != NULL);
+	
 	/*
 	 * From now on nobody will try to connect phones or attach
 	 * kbox threads
 	 */
-
+	
 	/*
 	 * Disconnect all phones connected to our kbox. Passing true for
@@ -71,6 +69,6 @@
 	 */
 	ipc_answerbox_slam_phones(&TASK->kb.box, have_kb_thread);
-
-	/* 
+	
+	/*
 	 * If the task was being debugged, clean up debugging session.
 	 * This is necessarry as slamming the phones won't force
@@ -80,5 +78,5 @@
 	udebug_task_cleanup(TASK);
 	mutex_unlock(&TASK->udebug.lock);
-
+	
 	if (have_kb_thread) {
 		LOG("Join kb.thread.");
@@ -88,44 +86,40 @@
 		TASK->kb.thread = NULL;
 	}
-
+	
 	/* Answer all messages in 'calls' and 'dispatched_calls' queues. */
-	spinlock_lock(&TASK->kb.box.lock);
+	irq_spinlock_lock(&TASK->kb.box.lock, true);
 	ipc_cleanup_call_list(&TASK->kb.box.dispatched_calls);
 	ipc_cleanup_call_list(&TASK->kb.box.calls);
-	spinlock_unlock(&TASK->kb.box.lock);
+	irq_spinlock_unlock(&TASK->kb.box.lock, true);
 }
 
 /** Handle hangup message in kbox.
  *
- * @param call	The IPC_M_PHONE_HUNGUP call structure.
- * @param last	Output, the function stores @c true here if
- *		this was the last phone, @c false otherwise.
- **/
+ * @param call The IPC_M_PHONE_HUNGUP call structure.
+ * @param last Output, the function stores @c true here if
+ *             this was the last phone, @c false otherwise.
+ *
+ */
 static void kbox_proc_phone_hungup(call_t *call, bool *last)
 {
-	ipl_t ipl;
-
 	/* Was it our debugger, who hung up? */
 	if (call->sender == TASK->udebug.debugger) {
 		/* Terminate debugging session (if any). */
 		LOG("Terminate debugging session.");
-		ipl = interrupts_disable();
-		spinlock_lock(&TASK->lock);
+		irq_spinlock_lock(&TASK->lock, true);
 		udebug_task_cleanup(TASK);
-		spinlock_unlock(&TASK->lock);
-		interrupts_restore(ipl);
+		irq_spinlock_unlock(&TASK->lock, true);
 	} else {
 		LOG("Was not debugger.");
 	}
-
+	
 	LOG("Continue with hangup message.");
 	IPC_SET_RETVAL(call->data, 0);
 	ipc_answer(&TASK->kb.box, call);
-
+	
 	mutex_lock(&TASK->kb.cleanup_lock);
-
-	ipl = interrupts_disable();
-	spinlock_lock(&TASK->lock);
-	spinlock_lock(&TASK->kb.box.lock);
+	
+	irq_spinlock_lock(&TASK->lock, true);
+	irq_spinlock_lock(&TASK->kb.box.lock, false);
 	if (list_empty(&TASK->kb.box.connected_phones)) {
 		/*
@@ -133,5 +127,5 @@
 		 * gets freed and signal to the caller.
 		 */
-
+		
 		/* Only detach kbox thread unless already terminating. */
 		if (TASK->kb.finished == false) {
@@ -140,15 +134,13 @@
 			TASK->kb.thread = NULL;
 		}
-
+		
 		LOG("Phone list is empty.");
 		*last = true;
-	} else {
+	} else
 		*last = false;
-	}
-
-	spinlock_unlock(&TASK->kb.box.lock);
-	spinlock_unlock(&TASK->lock);
-	interrupts_restore(ipl);
-
+	
+	irq_spinlock_unlock(&TASK->kb.box.lock, false);
+	irq_spinlock_unlock(&TASK->lock, true);
+	
 	mutex_unlock(&TASK->kb.cleanup_lock);
 }
@@ -159,29 +151,27 @@
  * when all phones are disconnected from the kbox.
  *
- * @param arg	Ignored.
+ * @param arg Ignored.
+ *
  */
 static void kbox_thread_proc(void *arg)
 {
-	call_t *call;
-	bool done;
-
-	(void)arg;
+	(void) arg;
 	LOG("Starting.");
-	done = false;
-
+	bool done = false;
+	
 	while (!done) {
-		call = ipc_wait_for_call(&TASK->kb.box, SYNCH_NO_TIMEOUT,
+		call_t *call = ipc_wait_for_call(&TASK->kb.box, SYNCH_NO_TIMEOUT,
 			SYNCH_FLAGS_NONE);
-
+		
 		if (call == NULL)
-			continue;	/* Try again. */
-
+			continue;  /* Try again. */
+		
 		switch (IPC_GET_METHOD(call->data)) {
-
+		
 		case IPC_M_DEBUG_ALL:
 			/* Handle debug call. */
 			udebug_call_receive(call);
 			break;
-
+		
 		case IPC_M_PHONE_HUNGUP:
 			/*
@@ -192,5 +182,5 @@
 			kbox_proc_phone_hungup(call, &done);
 			break;
-
+		
 		default:
 			/* Ignore */
@@ -198,11 +188,10 @@
 		}
 	}
-
+	
 	LOG("Exiting.");
 }
 
 
-/**
- * Connect phone to a task kernel-box specified by id.
+/** Connect phone to a task kernel-box specified by id.
  *
  * Note that this is not completely atomic. For optimisation reasons, the task
@@ -211,68 +200,61 @@
  * cleanup code.
  *
- * @return 		Phone id on success, or negative error code.
+ * @return Phone id on success, or negative error code.
+ *
  */
 int ipc_connect_kbox(task_id_t taskid)
 {
-	int newphid;
-	task_t *ta;
-	thread_t *kb_thread;
-	ipl_t ipl;
-
-	ipl = interrupts_disable();
-	spinlock_lock(&tasks_lock);
-
-	ta = task_find_by_id(taskid);
-	if (ta == NULL) {
-		spinlock_unlock(&tasks_lock);
-		interrupts_restore(ipl);
+	irq_spinlock_lock(&tasks_lock, true);
+	
+	task_t *task = task_find_by_id(taskid);
+	if (task == NULL) {
+		irq_spinlock_unlock(&tasks_lock, true);
 		return ENOENT;
 	}
-
-	atomic_inc(&ta->refcount);
-
-	spinlock_unlock(&tasks_lock);
-	interrupts_restore(ipl);
-
-	mutex_lock(&ta->kb.cleanup_lock);
-
-	if (atomic_predec(&ta->refcount) == 0) {
-		mutex_unlock(&ta->kb.cleanup_lock);
-		task_destroy(ta);
+	
+	atomic_inc(&task->refcount);
+	
+	irq_spinlock_unlock(&tasks_lock, true);
+	
+	mutex_lock(&task->kb.cleanup_lock);
+	
+	if (atomic_predec(&task->refcount) == 0) {
+		mutex_unlock(&task->kb.cleanup_lock);
+		task_destroy(task);
 		return ENOENT;
 	}
-
-	if (ta->kb.finished != false) {
-		mutex_unlock(&ta->kb.cleanup_lock);
+	
+	if (task->kb.finished != false) {
+		mutex_unlock(&task->kb.cleanup_lock);
 		return EINVAL;
 	}
-
-	newphid = phone_alloc(TASK);
+	
+	int newphid = phone_alloc(TASK);
 	if (newphid < 0) {
-		mutex_unlock(&ta->kb.cleanup_lock);
+		mutex_unlock(&task->kb.cleanup_lock);
 		return ELIMIT;
 	}
-
+	
 	/* Connect the newly allocated phone to the kbox */
-	ipc_phone_connect(&TASK->phones[newphid], &ta->kb.box);
-
-	if (ta->kb.thread != NULL) {
-		mutex_unlock(&ta->kb.cleanup_lock);
+	ipc_phone_connect(&TASK->phones[newphid], &task->kb.box);
+	
+	if (task->kb.thread != NULL) {
+		mutex_unlock(&task->kb.cleanup_lock);
 		return newphid;
 	}
-
+	
 	/* Create a kbox thread */
-	kb_thread = thread_create(kbox_thread_proc, NULL, ta, 0,
+	thread_t *kb_thread = thread_create(kbox_thread_proc, NULL, task, 0,
 	    "kbox", false);
 	if (!kb_thread) {
-		mutex_unlock(&ta->kb.cleanup_lock);
+		mutex_unlock(&task->kb.cleanup_lock);
 		return ENOMEM;
 	}
-
-	ta->kb.thread = kb_thread;
+	
+	task->kb.thread = kb_thread;
 	thread_ready(kb_thread);
-
-	mutex_unlock(&ta->kb.cleanup_lock);
-
+	
+	mutex_unlock(&task->kb.cleanup_lock);
+	
 	return newphid;
 }
Index: kernel/generic/src/ipc/sysipc.c
===================================================================
--- kernel/generic/src/ipc/sysipc.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/generic/src/ipc/sysipc.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -56,11 +56,15 @@
  * requests.
  */
-#define DATA_XFER_LIMIT		(64 * 1024)
+#define DATA_XFER_LIMIT  (64 * 1024)
+
+#define STRUCT_TO_USPACE(dst, src)  copy_to_uspace((dst), (src), sizeof(*(src)))
 
 /** 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.
+ * @param phoneid Phone ID.
+ * @param phone   Place to store pointer to phone.
+ *
+ * @return EOK on success, EINVAL if ID is invalid.
+ *
  */
 static int phone_get(unative_t phoneid, phone_t **phone)
@@ -68,23 +72,22 @@
 	if (phoneid >= IPC_MAX_PHONES)
 		return EINVAL;
-
+	
 	*phone = &TASK->phones[phoneid];
 	return EOK;
 }
 
-#define STRUCT_TO_USPACE(dst, src)	copy_to_uspace(dst, src, sizeof(*(src)))
-
 /** Decide if the method is a system method.
  *
- * @param method	Method to be decided.
- *
- * @return		Return 1 if the method is a system method.
- *			Otherwise return 0.
- */
-static inline int method_is_system(unative_t method)
+ * @param method Method to be decided.
+ *
+ * @return true if the method is a system method.
+ *
+ */
+static inline bool method_is_system(unative_t method)
 {
 	if (method <= IPC_M_LAST_SYSTEM)
-		return 1;
-	return 0;
+		return true;
+	
+	return false;
 }
 
@@ -94,10 +97,10 @@
  *   it is useless
  *
- * @param method	Method to be decided.
- *
- * @return		Return 1 if the method is forwardable.
- *			Otherwise return 0.
- */
-static inline int method_is_forwardable(unative_t method)
+ * @param method Method to be decided.
+ *
+ * @return true if the method is forwardable.
+ *
+ */
+static inline bool method_is_forwardable(unative_t method)
 {
 	switch (method) {
@@ -106,7 +109,7 @@
 	case IPC_M_PHONE_HUNGUP:
 		/* This message is meant only for the original recipient. */
-		return 0;
+		return false;
 	default:
-		return 1;
+		return true;
 	}
 }
@@ -116,10 +119,10 @@
  * - some system messages may be forwarded but their content cannot be altered
  *
- * @param method	Method to be decided.
- *
- * @return		Return 1 if the method is immutable on forward.
- *			Otherwise return 0.
- */
-static inline int method_is_immutable(unative_t method)
+ * @param method Method to be decided.
+ *
+ * @return true if the method is immutable on forward.
+ *
+ */
+static inline bool method_is_immutable(unative_t method)
 {
 	switch (method) {
@@ -128,7 +131,7 @@
 	case IPC_M_DATA_WRITE:
 	case IPC_M_DATA_READ:
-		return 1;
+		return true;
 	default:
-		return 0;
+		return false;
 	}
 }
@@ -142,10 +145,10 @@
  * for answer_preprocess().
  *
- * @param call		Call structure to be decided.
- *
- * @return		Return 1 if the old call contents should be saved.
- *			Return 0 otherwise.
- */
-static inline int answer_need_old(call_t *call)
+ * @param call Call structure to be decided.
+ *
+ * @return true if the old call contents should be saved.
+ *
+ */
+static inline bool answer_need_old(call_t *call)
 {
 	switch (IPC_GET_METHOD(call->data)) {
@@ -158,7 +161,7 @@
 	case IPC_M_DATA_WRITE:
 	case IPC_M_DATA_READ:
-		return 1;
+		return true;
 	default:
-		return 0;
+		return false;
 	}
 }
@@ -168,13 +171,12 @@
  * This function is called directly after sys_ipc_answer().
  *
- * @param answer	Call structure with the answer.
- * @param olddata	Saved data of the request.
- *
- * @return		Return 0 on success or an error code. 
+ * @param answer  Call structure with the answer.
+ * @param olddata Saved data of the request.
+ *
+ * @return Return 0 on success or an error code.
+ *
  */
 static inline int answer_preprocess(call_t *answer, ipc_data_t *olddata)
 {
-	int phoneid;
-
 	if ((native_t) IPC_GET_RETVAL(answer->data) == EHANGUP) {
 		/* In case of forward, hangup the forwared phone,
@@ -182,19 +184,20 @@
 		 */
 		mutex_lock(&answer->data.phone->lock);
-		spinlock_lock(&TASK->answerbox.lock);
+		irq_spinlock_lock(&TASK->answerbox.lock, true);
 		if (answer->data.phone->state == IPC_PHONE_CONNECTED) {
 			list_remove(&answer->data.phone->link);
 			answer->data.phone->state = IPC_PHONE_SLAMMED;
 		}
-		spinlock_unlock(&TASK->answerbox.lock);
+		irq_spinlock_unlock(&TASK->answerbox.lock, true);
 		mutex_unlock(&answer->data.phone->lock);
 	}
-
+	
 	if (!olddata)
 		return 0;
-
+	
 	if (IPC_GET_METHOD(*olddata) == IPC_M_CONNECTION_CLONE) {
-		phoneid = IPC_GET_ARG1(*olddata);
-		phone_t *phone = &TASK->phones[phoneid]; 
+		int phoneid = IPC_GET_ARG1(*olddata);
+		phone_t *phone = &TASK->phones[phoneid];
+		
 		if (IPC_GET_RETVAL(answer->data) != EOK) {
 			/*
@@ -208,13 +211,14 @@
 			mutex_lock(&phone->lock);
 			if (phone->state == IPC_PHONE_CONNECTED) {
-				spinlock_lock(&phone->callee->lock);
+				irq_spinlock_lock(&phone->callee->lock, true);
 				list_remove(&phone->link);
 				phone->state = IPC_PHONE_SLAMMED;
-				spinlock_unlock(&phone->callee->lock);
+				irq_spinlock_unlock(&phone->callee->lock, true);
 			}
 			mutex_unlock(&phone->lock);
 		}
 	} else if (IPC_GET_METHOD(*olddata) == IPC_M_CONNECT_ME) {
-		phone_t *phone = (phone_t *)IPC_GET_ARG5(*olddata);
+		phone_t *phone = (phone_t *) IPC_GET_ARG5(*olddata);
+		
 		if (IPC_GET_RETVAL(answer->data) != EOK) {
 			/*
@@ -226,13 +230,14 @@
 			mutex_lock(&phone->lock);
 			if (phone->state == IPC_PHONE_CONNECTED) {
-				spinlock_lock(&phone->callee->lock);
+				irq_spinlock_lock(&phone->callee->lock, true);
 				list_remove(&phone->link);
 				phone->state = IPC_PHONE_SLAMMED;
-				spinlock_unlock(&phone->callee->lock);
+				irq_spinlock_unlock(&phone->callee->lock, true);
 			}
 			mutex_unlock(&phone->lock);
 		}
 	} else if (IPC_GET_METHOD(*olddata) == IPC_M_CONNECT_TO_ME) {
-		phoneid = IPC_GET_ARG5(*olddata);
+		int phoneid = IPC_GET_ARG5(*olddata);
+		
 		if (IPC_GET_RETVAL(answer->data) != EOK) {
 			/* The connection was not accepted */
@@ -254,15 +259,10 @@
 		if (!IPC_GET_RETVAL(answer->data)) {
 			/* Accepted, handle as_area receipt */
-			ipl_t ipl;
-			int rc;
-			as_t *as;
 			
-			ipl = interrupts_disable();
-			spinlock_lock(&answer->sender->lock);
-			as = answer->sender->as;
-			spinlock_unlock(&answer->sender->lock);
-			interrupts_restore(ipl);
+			irq_spinlock_lock(&answer->sender->lock, true);
+			as_t *as = answer->sender->as;
+			irq_spinlock_unlock(&answer->sender->lock, true);
 			
-			rc = as_area_share(as, IPC_GET_ARG1(*olddata),
+			int rc = as_area_share(as, IPC_GET_ARG1(*olddata),
 			    IPC_GET_ARG2(*olddata), AS,
 			    IPC_GET_ARG1(answer->data), IPC_GET_ARG3(*olddata));
@@ -272,15 +272,9 @@
 	} else if (IPC_GET_METHOD(*olddata) == IPC_M_SHARE_IN) {
 		if (!IPC_GET_RETVAL(answer->data)) { 
-			ipl_t ipl;
-			as_t *as;
-			int rc;
+			irq_spinlock_lock(&answer->sender->lock, true);
+			as_t *as = answer->sender->as;
+			irq_spinlock_unlock(&answer->sender->lock, true);
 			
-			ipl = interrupts_disable();
-			spinlock_lock(&answer->sender->lock);
-			as = answer->sender->as;
-			spinlock_unlock(&answer->sender->lock);
-			interrupts_restore(ipl);
-			
-			rc = as_area_share(AS, IPC_GET_ARG1(answer->data),
+			int rc = as_area_share(AS, IPC_GET_ARG1(answer->data),
 			    IPC_GET_ARG2(*olddata), as, IPC_GET_ARG1(*olddata),
 			    IPC_GET_ARG2(answer->data));
@@ -301,5 +295,5 @@
 				 */
 				IPC_SET_ARG1(answer->data, dst);
-
+				
 				answer->buffer = malloc(size, 0);
 				int rc = copy_from_uspace(answer->buffer,
@@ -320,15 +314,10 @@
 		if (!IPC_GET_RETVAL(answer->data)) {
 			/* The recipient agreed to receive data. */
-			int rc;
-			uintptr_t dst;
-			size_t size;
-			size_t max_size;
-
-			dst = (uintptr_t)IPC_GET_ARG1(answer->data);
-			size = (size_t)IPC_GET_ARG2(answer->data);
-			max_size = (size_t)IPC_GET_ARG2(*olddata);
-
+			uintptr_t dst = (uintptr_t)IPC_GET_ARG1(answer->data);
+			size_t size = (size_t)IPC_GET_ARG2(answer->data);
+			size_t max_size = (size_t)IPC_GET_ARG2(*olddata);
+			
 			if (size <= max_size) {
-				rc = copy_to_uspace((void *) dst,
+				int rc = copy_to_uspace((void *) dst,
 				    answer->buffer, size);
 				if (rc)
@@ -341,4 +330,5 @@
 		answer->buffer = NULL;
 	}
+	
 	return 0;
 }
@@ -352,7 +342,6 @@
 		mutex_lock(&p2->lock);
 		mutex_lock(&p1->lock);
-	} else {
+	} else
 		mutex_lock(&p1->lock);
-	}
 }
 
@@ -366,24 +355,20 @@
 /** Called before the request is sent.
  *
- * @param call		Call structure with the request.
- * @param phone		Phone that the call will be sent through.
- *
- * @return 		Return 0 on success, ELIMIT or EPERM on error.
+ * @param call  Call structure with the request.
+ * @param phone Phone that the call will be sent through.
+ *
+ * @return Return 0 on success, ELIMIT or EPERM on error.
+ *
  */
 static int request_preprocess(call_t *call, phone_t *phone)
 {
-	int newphid;
-	size_t size;
-	uintptr_t src;
-	int rc;
-
 	switch (IPC_GET_METHOD(call->data)) {
 	case IPC_M_CONNECTION_CLONE: {
 		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) {
@@ -391,4 +376,5 @@
 			return EINVAL;
 		}
+		
 		/*
 		 * We can be pretty sure now that both tasks exist and we are
@@ -396,13 +382,16 @@
 		 * we are effectively preventing them from finishing their
 		 * potential cleanup.
+		 *
 		 */
-		newphid = phone_alloc(phone->callee->task);
+		int newphid = phone_alloc(phone->callee->task);
 		if (newphid < 0) {
 			phones_unlock(cloned_phone, phone);
 			return ELIMIT;
 		}
+		
 		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);
@@ -412,8 +401,9 @@
 		IPC_SET_ARG5(call->data, (unative_t) phone);
 		break;
-	case IPC_M_CONNECT_ME_TO:
-		newphid = phone_alloc(TASK);
+	case IPC_M_CONNECT_ME_TO: {
+		int newphid = phone_alloc(TASK);
 		if (newphid < 0)
 			return ELIMIT;
+		
 		/* Set arg5 for server */
 		IPC_SET_ARG5(call->data, (unative_t) &TASK->phones[newphid]);
@@ -421,18 +411,23 @@
 		call->priv = newphid;
 		break;
-	case IPC_M_SHARE_OUT:
-		size = as_area_get_size(IPC_GET_ARG1(call->data));
+	}
+	case IPC_M_SHARE_OUT: {
+		size_t size = as_area_get_size(IPC_GET_ARG1(call->data));
 		if (!size)
 			return EPERM;
+		
 		IPC_SET_ARG2(call->data, size);
 		break;
-	case IPC_M_DATA_READ:
-		size = IPC_GET_ARG2(call->data);
+	}
+	case IPC_M_DATA_READ: {
+		size_t size = IPC_GET_ARG2(call->data);
 		if ((size <= 0 || (size > DATA_XFER_LIMIT)))
 			return ELIMIT;
+		
 		break;
-	case IPC_M_DATA_WRITE:
-		src = IPC_GET_ARG1(call->data);
-		size = IPC_GET_ARG2(call->data);
+	}
+	case IPC_M_DATA_WRITE: {
+		uintptr_t src = IPC_GET_ARG1(call->data);
+		size_t size = IPC_GET_ARG2(call->data);
 		
 		if (size > DATA_XFER_LIMIT)
@@ -440,10 +435,12 @@
 		
 		call->buffer = (uint8_t *) malloc(size, 0);
-		rc = copy_from_uspace(call->buffer, (void *) src, size);
+		int rc = copy_from_uspace(call->buffer, (void *) src, size);
 		if (rc != 0) {
 			free(call->buffer);
 			return rc;
 		}
+		
 		break;
+	}
 #ifdef CONFIG_UDEBUG
 	case IPC_M_DEBUG_ALL:
@@ -453,4 +450,5 @@
 		break;
 	}
+	
 	return 0;
 }
@@ -462,5 +460,6 @@
 /** Do basic kernel processing of received call answer.
  *
- * @param call		Call structure with the answer.
+ * @param call Call structure with the answer.
+ *
  */
 static void process_answer(call_t *call)
@@ -469,5 +468,5 @@
 	    (call->flags & IPC_CALL_FORWARDED))
 		IPC_SET_RETVAL(call->data, EFORWARD);
-
+	
 	if (call->flags & IPC_CALL_CONN_ME_TO) {
 		if (IPC_GET_RETVAL(call->data))
@@ -476,8 +475,11 @@
 			IPC_SET_ARG5(call->data, call->priv);
 	}
-
+	
 	if (call->buffer) {
-		/* This must be an affirmative answer to IPC_M_DATA_READ. */
-		/* or IPC_M_DEBUG_ALL/UDEBUG_M_MEM_READ... */
+		/*
+		 * This must be an affirmative answer to IPC_M_DATA_READ
+		 * or IPC_M_DEBUG_ALL/UDEBUG_M_MEM_READ...
+		 *
+		 */
 		uintptr_t dst = IPC_GET_ARG1(call->data);
 		size_t size = IPC_GET_ARG2(call->data);
@@ -492,16 +494,15 @@
 /** Do basic kernel processing of received call request.
  *
- * @param box		Destination answerbox structure.
- * @param call		Call structure with the request.
- *
- * @return 		Return 0 if the call should be passed to userspace.
- *			Return -1 if the call should be ignored.
+ * @param box  Destination answerbox structure.
+ * @param call Call structure with the request.
+ *
+ * @return 0 if the call should be passed to userspace.
+ * @return -1 if the call should be ignored.
+ *
  */
 static int process_request(answerbox_t *box, call_t *call)
 {
-	int phoneid;
-
 	if (IPC_GET_METHOD(call->data) == IPC_M_CONNECT_TO_ME) {
-		phoneid = phone_alloc(TASK);
+		int phoneid = phone_alloc(TASK);
 		if (phoneid < 0) { /* Failed to allocate phone */
 			IPC_SET_RETVAL(call->data, ELIMIT);
@@ -509,6 +510,8 @@
 			return -1;
 		}
+		
 		IPC_SET_ARG5(call->data, phoneid);
 	}
+	
 	switch (IPC_GET_METHOD(call->data)) {
 	case IPC_M_DEBUG_ALL:
@@ -517,4 +520,5 @@
 		break;
 	}
+	
 	return 0;
 }
@@ -525,31 +529,29 @@
  * the generic function (i.e. sys_ipc_call_sync_slow()).
  *
- * @param phoneid	Phone handle for the call.
- * @param method	Method of the call.
- * @param arg1		Service-defined payload argument.
- * @param arg2		Service-defined payload argument.
- * @param arg3		Service-defined payload argument.
- * @param data		Address of userspace structure where the reply call will
- *			be stored.
- *
- * @return		Returns 0 on success.
- *			Return ENOENT if there is no such phone handle.
+ * @param phoneid Phone handle for the call.
+ * @param method  Method of the call.
+ * @param arg1    Service-defined payload argument.
+ * @param arg2    Service-defined payload argument.
+ * @param arg3    Service-defined payload argument.
+ * @param data    Address of userspace structure where the reply call will
+ *                be stored.
+ *
+ * @return 0 on success.
+ * @return ENOENT if there is no such phone handle.
+ *
  */
 unative_t sys_ipc_call_sync_fast(unative_t phoneid, unative_t method,
     unative_t arg1, unative_t arg2, unative_t arg3, ipc_data_t *data)
 {
-	call_t *call;
 	phone_t *phone;
-	int res;
-	int rc;
-
 	if (phone_get(phoneid, &phone) != EOK)
 		return ENOENT;
 
-	call = ipc_call_alloc(0);
+	call_t *call = ipc_call_alloc(0);
 	IPC_SET_METHOD(call->data, method);
 	IPC_SET_ARG1(call->data, arg1);
 	IPC_SET_ARG2(call->data, arg2);
 	IPC_SET_ARG3(call->data, arg3);
+	
 	/*
 	 * To achieve deterministic behavior, zero out arguments that are beyond
@@ -558,6 +560,9 @@
 	IPC_SET_ARG4(call->data, 0);
 	IPC_SET_ARG5(call->data, 0);
-
-	if (!(res = request_preprocess(call, phone))) {
+	
+	int res = request_preprocess(call, phone);
+	int rc;
+	
+	if (!res) {
 #ifdef CONFIG_UDEBUG
 		udebug_stoppable_begin();
@@ -567,18 +572,20 @@
 		udebug_stoppable_end();
 #endif
+		
 		if (rc != EOK) {
 			/* The call will be freed by ipc_cleanup(). */
 			return rc;
 		}
+		
 		process_answer(call);
-
-	} else {
+		
+	} else
 		IPC_SET_RETVAL(call->data, res);
-	}
+	
 	rc = STRUCT_TO_USPACE(&data->args, &call->data.args);
 	ipc_call_free(call);
 	if (rc != 0)
 		return rc;
-
+	
 	return 0;
 }
@@ -586,24 +593,21 @@
 /** Make a synchronous IPC call allowing to transmit the entire payload.
  *
- * @param phoneid	Phone handle for the call.
- * @param question	Userspace address of call data with the request.
- * @param reply		Userspace address of call data where to store the
- *			answer.
- *
- * @return		Zero on success or an error code.
+ * @param phoneid  Phone handle for the call.
+ * @param question Userspace address of call data with the request.
+ * @param reply    Userspace address of call data where to store the
+ *                 answer.
+ *
+ * @return Zero on success or an error code.
+ *
  */
 unative_t sys_ipc_call_sync_slow(unative_t phoneid, ipc_data_t *question,
     ipc_data_t *reply)
 {
-	call_t *call;
 	phone_t *phone;
-	int res;
-	int rc;
-
 	if (phone_get(phoneid, &phone) != EOK)
 		return ENOENT;
 
-	call = ipc_call_alloc(0);
-	rc = copy_from_uspace(&call->data.args, &question->args,
+	call_t *call = ipc_call_alloc(0);
+	int rc = copy_from_uspace(&call->data.args, &question->args,
 	    sizeof(call->data.args));
 	if (rc != 0) {
@@ -611,7 +615,8 @@
 		return (unative_t) rc;
 	}
-
-
-	if (!(res = request_preprocess(call, phone))) {
+	
+	int res = request_preprocess(call, phone);
+	
+	if (!res) {
 #ifdef CONFIG_UDEBUG
 		udebug_stoppable_begin();
@@ -621,17 +626,19 @@
 		udebug_stoppable_end();
 #endif
+		
 		if (rc != EOK) {
 			/* The call will be freed by ipc_cleanup(). */
 			return rc;
 		}
+		
 		process_answer(call);
-	} else 
+	} else
 		IPC_SET_RETVAL(call->data, res);
-
+	
 	rc = STRUCT_TO_USPACE(&reply->args, &call->data.args);
 	ipc_call_free(call);
 	if (rc != 0)
 		return rc;
-
+	
 	return 0;
 }
@@ -639,5 +646,6 @@
 /** Check that the task did not exceed the allowed limit of asynchronous calls.
  *
- * @return 		Return 0 if limit not reached or -1 if limit exceeded.
+ * @return 0 if limit not reached or -1 if limit exceeded.
+ *
  */
 static int check_call_limit(void)
@@ -647,4 +655,5 @@
 		return -1;
 	}
+	
 	return 0;
 }
@@ -655,30 +664,28 @@
  * the generic function sys_ipc_call_async_slow().
  *
- * @param phoneid	Phone handle for the call.
- * @param method	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 		Return call hash on success.
- *			Return IPC_CALLRET_FATAL in case of a fatal error and 
- *			IPC_CALLRET_TEMPORARY if there are too many pending
- *			asynchronous requests; answers should be handled first.
+ * @param phoneid Phone handle for the call.
+ * @param method  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.
+ * @return IPC_CALLRET_FATAL in case of a fatal error.
+ * @return IPC_CALLRET_TEMPORARY if there are too many pending
+ *         asynchronous requests; answers should be handled first.
+ *
  */
 unative_t sys_ipc_call_async_fast(unative_t phoneid, unative_t method,
     unative_t arg1, unative_t arg2, unative_t arg3, unative_t arg4)
 {
-	call_t *call;
-	phone_t *phone;
-	int res;
-
 	if (check_call_limit())
 		return IPC_CALLRET_TEMPORARY;
-
+	
+	phone_t *phone;
 	if (phone_get(phoneid, &phone) != EOK)
 		return IPC_CALLRET_FATAL;
-
-	call = ipc_call_alloc(0);
+	
+	call_t *call = ipc_call_alloc(0);
 	IPC_SET_METHOD(call->data, method);
 	IPC_SET_ARG1(call->data, arg1);
@@ -686,4 +693,5 @@
 	IPC_SET_ARG3(call->data, arg3);
 	IPC_SET_ARG4(call->data, arg4);
+	
 	/*
 	 * To achieve deterministic behavior, zero out arguments that are beyond
@@ -691,10 +699,12 @@
 	 */
 	IPC_SET_ARG5(call->data, 0);
-
-	if (!(res = request_preprocess(call, phone)))
+	
+	int res = request_preprocess(call, phone);
+	
+	if (!res)
 		ipc_call(phone, call);
 	else
 		ipc_backsend_err(phone, call, res);
-
+	
 	return (unative_t) call;
 }
@@ -702,24 +712,21 @@
 /** Make an asynchronous IPC call allowing to transmit the entire payload.
  *
- * @param phoneid	Phone handle for the call.
- * @param data		Userspace address of call data with the request.
- *
- * @return		See sys_ipc_call_async_fast(). 
+ * @param phoneid Phone handle for the call.
+ * @param data    Userspace address of call data with the request.
+ *
+ * @return See sys_ipc_call_async_fast().
+ *
  */
 unative_t sys_ipc_call_async_slow(unative_t phoneid, ipc_data_t *data)
 {
-	call_t *call;
-	phone_t *phone;
-	int res;
-	int rc;
-
 	if (check_call_limit())
 		return IPC_CALLRET_TEMPORARY;
-
+	
+	phone_t *phone;
 	if (phone_get(phoneid, &phone) != EOK)
 		return IPC_CALLRET_FATAL;
 
-	call = ipc_call_alloc(0);
-	rc = copy_from_uspace(&call->data.args, &data->args,
+	call_t *call = ipc_call_alloc(0);
+	int rc = copy_from_uspace(&call->data.args, &data->args,
 	    sizeof(call->data.args));
 	if (rc != 0) {
@@ -727,45 +734,48 @@
 		return (unative_t) rc;
 	}
-	if (!(res = request_preprocess(call, phone)))
+	
+	int res = request_preprocess(call, phone);
+	
+	if (!res)
 		ipc_call(phone, call);
 	else
 		ipc_backsend_err(phone, call, res);
-
+	
 	return (unative_t) call;
 }
 
-/** Forward a received call to another destination - 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 method	New 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		Return 0 on succes, otherwise return an error code.
- *
- * Warning:	Make sure that ARG5 is not rewritten for certain system IPC
+/** Forward a received call to another destination
+ *
+ * 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 method  New 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.
+ *
+ * Warning: Make sure that ARG5 is not rewritten for certain system IPC
+ *
  */
 static unative_t sys_ipc_forward_common(unative_t callid, unative_t phoneid,
     unative_t method, unative_t arg1, unative_t arg2, unative_t arg3,
-    unative_t arg4, unative_t arg5, int mode, bool slow)
-{
-	call_t *call;
-	phone_t *phone;
-
-	call = get_call(callid);
+    unative_t arg4, unative_t arg5, unsigned int mode, bool slow)
+{
+	call_t *call = get_call(callid);
 	if (!call)
 		return ENOENT;
 	
 	call->flags |= IPC_CALL_FORWARDED;
-
+	
+	phone_t *phone;
 	if (phone_get(phoneid, &phone) != EOK) {
 		IPC_SET_RETVAL(call->data, EFORWARD);
@@ -773,5 +783,5 @@
 		return ENOENT;
 	}
-
+	
 	if (!method_is_forwardable(IPC_GET_METHOD(call->data))) {
 		IPC_SET_RETVAL(call->data, EFORWARD);
@@ -779,5 +789,5 @@
 		return EPERM;
 	}
-
+	
 	/*
 	 * Userspace is not allowed to change method of system methods on
@@ -790,8 +800,9 @@
 			if (IPC_GET_METHOD(call->data) == IPC_M_CONNECT_TO_ME)
 				phone_dealloc(IPC_GET_ARG5(call->data));
-
+			
 			IPC_SET_ARG1(call->data, method);
 			IPC_SET_ARG2(call->data, arg1);
 			IPC_SET_ARG3(call->data, arg2);
+			
 			if (slow) {
 				IPC_SET_ARG4(call->data, arg3);
@@ -812,18 +823,9 @@
 		}
 	}
-
+	
 	return ipc_forward(call, phone, &TASK->answerbox, mode);
 }
 
 /** Forward a received call to another destination - fast version.
- *
- * @param callid	Hash of the call to forward.
- * @param phoneid	Phone handle to use for forwarding.
- * @param method	New 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		Return 0 on succes, otherwise return an error code.
  *
  * In case the original method is a system method, ARG1, ARG2 and ARG3 are
@@ -833,7 +835,17 @@
  * is a set of immutable methods, for which the new method and 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 method  New 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.
+ *
  */
 unative_t sys_ipc_forward_fast(unative_t callid, unative_t phoneid,
-    unative_t method, unative_t arg1, unative_t arg2, int mode)
+    unative_t method, unative_t arg1, unative_t arg2, unsigned int mode)
 {
 	return sys_ipc_forward_common(callid, phoneid, method, arg1, arg2, 0, 0,
@@ -842,11 +854,4 @@
 
 /** Forward a received call to another destination - slow version.
- *
- * @param callid	Hash of the call to forward.
- * @param phoneid	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.
- *
- * @return		Return 0 on succes, otherwise return an error code.
  *
  * This function is the slow verision of the sys_ipc_forward_fast interface.
@@ -856,16 +861,22 @@
  * methods, it additionally stores the new value of arg3, arg4 and arg5,
  * respectively, to ARG3, ARG4 and ARG5, respectively.
+ *
+ * @param callid  Hash of the call to forward.
+ * @param phoneid 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.
+ *
+ * @return 0 on succes, otherwise an error code.
+ *
  */
 unative_t sys_ipc_forward_slow(unative_t callid, unative_t phoneid,
-    ipc_data_t *data, int mode)
+    ipc_data_t *data, unsigned int mode)
 {
 	ipc_data_t newdata;
-	int rc;
-
-	rc = copy_from_uspace(&newdata.args, &data->args,
+	int rc = copy_from_uspace(&newdata.args, &data->args,
 	    sizeof(newdata.args));
-	if (rc != 0) 
+	if (rc != 0)
 		return (unative_t) rc;
-
+	
 	return sys_ipc_forward_common(callid, phoneid,
 	    IPC_GET_METHOD(newdata), IPC_GET_ARG1(newdata),
@@ -879,34 +890,34 @@
  * than the generic sys_ipc_answer().
  *
- * @param callid	Hash of the call to be answered.
- * @param retval	Return value of the answer.
- * @param arg1		Service-defined return value.
- * @param arg2		Service-defined return value.
- * @param arg3		Service-defined return value.
- * @param arg4		Service-defined return value.
- *
- * @return		Return 0 on success, otherwise return an error code.	
+ * @param callid Hash of the call to be answered.
+ * @param retval Return value of the answer.
+ * @param arg1   Service-defined return value.
+ * @param arg2   Service-defined return value.
+ * @param arg3   Service-defined return value.
+ * @param arg4   Service-defined return value.
+ *
+ * @return 0 on success, otherwise an error code.
+ *
  */
 unative_t sys_ipc_answer_fast(unative_t callid, unative_t retval,
     unative_t arg1, unative_t arg2, unative_t arg3, unative_t arg4)
 {
-	call_t *call;
-	ipc_data_t saved_data;
-	int saveddata = 0;
-	int rc;
-
 	/* Do not answer notification callids */
 	if (callid & IPC_CALLID_NOTIFICATION)
 		return 0;
-
-	call = get_call(callid);
+	
+	call_t *call = get_call(callid);
 	if (!call)
 		return ENOENT;
-
+	
+	ipc_data_t saved_data;
+	bool saved;
+	
 	if (answer_need_old(call)) {
 		memcpy(&saved_data, &call->data, sizeof(call->data));
-		saveddata = 1;
-	}
-
+		saved = true;
+	} else
+		saved = false;
+	
 	IPC_SET_RETVAL(call->data, retval);
 	IPC_SET_ARG1(call->data, arg1);
@@ -914,4 +925,5 @@
 	IPC_SET_ARG3(call->data, arg3);
 	IPC_SET_ARG4(call->data, arg4);
+	
 	/*
 	 * To achieve deterministic behavior, zero out arguments that are beyond
@@ -919,6 +931,6 @@
 	 */
 	IPC_SET_ARG5(call->data, 0);
-	rc = answer_preprocess(call, saveddata ? &saved_data : NULL);
-
+	int rc = answer_preprocess(call, saved ? &saved_data : NULL);
+	
 	ipc_answer(&TASK->answerbox, call);
 	return rc;
@@ -927,37 +939,37 @@
 /** Answer an IPC call.
  *
- * @param callid	Hash of the call to be answered.
- * @param data		Userspace address of call data with the answer.
- *
- * @return		Return 0 on success, otherwise return an error code.
+ * @param callid Hash of the call to be answered.
+ * @param data   Userspace address of call data with the answer.
+ *
+ * @return 0 on success, otherwise an error code.
+ *
  */
 unative_t sys_ipc_answer_slow(unative_t callid, ipc_data_t *data)
 {
-	call_t *call;
-	ipc_data_t saved_data;
-	int saveddata = 0;
-	int rc;
-
 	/* Do not answer notification callids */
 	if (callid & IPC_CALLID_NOTIFICATION)
 		return 0;
-
-	call = get_call(callid);
+	
+	call_t *call = get_call(callid);
 	if (!call)
 		return ENOENT;
-
+	
+	ipc_data_t saved_data;
+	bool saved;
+	
 	if (answer_need_old(call)) {
 		memcpy(&saved_data, &call->data, sizeof(call->data));
-		saveddata = 1;
-	}
-	rc = copy_from_uspace(&call->data.args, &data->args, 
+		saved = true;
+	} else
+		saved = false;
+	
+	int rc = copy_from_uspace(&call->data.args, &data->args, 
 	    sizeof(call->data.args));
 	if (rc != 0)
 		return rc;
-
-	rc = answer_preprocess(call, saveddata ? &saved_data : NULL);
+	
+	rc = answer_preprocess(call, saved ? &saved_data : NULL);
 	
 	ipc_answer(&TASK->answerbox, call);
-
 	return rc;
 }
@@ -965,18 +977,19 @@
 /** Hang up a phone.
  *
- * @param		Phone handle of the phone to be hung up.
- *
- * @return		Return 0 on success or an error code.
+ * @param Phone handle of the phone to be hung up.
+ *
+ * @return 0 on success or an error code.
+ *
  */
 unative_t sys_ipc_hangup(unative_t phoneid)
 {
 	phone_t *phone;
-
+	
 	if (phone_get(phoneid, &phone) != EOK)
 		return ENOENT;
-
+	
 	if (ipc_phone_hangup(phone))
 		return -1;
-
+	
 	return 0;
 }
@@ -984,32 +997,36 @@
 /** Wait for an incoming IPC call or an answer.
  *
- * @param calldata	Pointer to buffer where the call/answer data is stored.
- * @param usec 		Timeout. See waitq_sleep_timeout() for explanation.
- * @param flags		Select mode of sleep operation. See waitq_sleep_timeout()
- *			for explanation.
- *
- * @return 		Hash of the call.
- *			If IPC_CALLID_NOTIFICATION bit is set in the hash, the
- *			call is a notification. IPC_CALLID_ANSWERED denotes an
- *			answer.
- */
-unative_t sys_ipc_wait_for_call(ipc_data_t *calldata, uint32_t usec, int flags)
+ * @param calldata Pointer to buffer where the call/answer data is stored.
+ * @param usec     Timeout. See waitq_sleep_timeout() for explanation.
+ * @param flags    Select mode of sleep operation. See waitq_sleep_timeout()
+ *                 for explanation.
+ *
+ * @return Hash of the call.
+ *         If IPC_CALLID_NOTIFICATION bit is set in the hash, the
+ *         call is a notification. IPC_CALLID_ANSWERED denotes an
+ *         answer.
+ *
+ */
+unative_t sys_ipc_wait_for_call(ipc_data_t *calldata, uint32_t usec,
+    unsigned int flags)
 {
 	call_t *call;
-
+	
 restart:
-
+	
 #ifdef CONFIG_UDEBUG
 	udebug_stoppable_begin();
-#endif	
+#endif
+	
 	call = ipc_wait_for_call(&TASK->answerbox, usec,
 	    flags | SYNCH_FLAGS_INTERRUPTIBLE);
-
+	
 #ifdef CONFIG_UDEBUG
 	udebug_stoppable_end();
 #endif
+	
 	if (!call)
 		return 0;
-
+	
 	if (call->flags & IPC_CALL_NOTIF) {
 		/* Set in_phone_hash to the interrupt counter */
@@ -1017,13 +1034,13 @@
 		
 		STRUCT_TO_USPACE(calldata, &call->data);
-
+		
 		ipc_call_free(call);
 		
 		return ((unative_t) call) | IPC_CALLID_NOTIFICATION;
 	}
-
+	
 	if (call->flags & IPC_CALL_ANSWERED) {
 		process_answer(call);
-
+		
 		if (call->flags & IPC_CALL_DISCARD_ANSWER) {
 			ipc_call_free(call);
@@ -1037,14 +1054,14 @@
 			atomic_dec(&TASK->active_calls);
 		}
-
+		
 		STRUCT_TO_USPACE(&calldata->args, &call->data.args);
 		ipc_call_free(call);
-
+		
 		return ((unative_t) call) | IPC_CALLID_ANSWERED;
 	}
-
+	
 	if (process_request(&TASK->answerbox, call))
 		goto restart;
-
+	
 	/* Include phone address('id') of the caller in the request,
 	 * copy whole call->data, not only call->data.args */
@@ -1055,23 +1072,27 @@
 		 */
 		ipc_data_t saved_data;
-		int saveddata = 0;
-
+		bool saved;
+		
 		if (answer_need_old(call)) {
 			memcpy(&saved_data, &call->data, sizeof(call->data));
-			saveddata = 1;
-		}
+			saved = true;
+		} else
+			saved = false;
 		
 		IPC_SET_RETVAL(call->data, EPARTY);
-		(void) answer_preprocess(call, saveddata ? &saved_data : NULL);
+		(void) answer_preprocess(call, saved ? &saved_data : NULL);
 		ipc_answer(&TASK->answerbox, call);
 		return 0;
 	}
-	return (unative_t)call;
-}
-
-/** Interrupt one thread from sys_ipc_wait_for_call(). */
+	
+	return (unative_t) call;
+}
+
+/** Interrupt one thread from sys_ipc_wait_for_call().
+ *
+ */
 unative_t sys_ipc_poke(void)
 {
-	waitq_unsleep(&TASK->answerbox.wq);	
+	waitq_unsleep(&TASK->answerbox.wq);
 	return EOK;
 }
@@ -1079,10 +1100,11 @@
 /** Connect an IRQ handler to a task.
  *
- * @param inr		IRQ number.
- * @param devno		Device number.
- * @param method	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_register().
+ * @param inr    IRQ number.
+ * @param devno  Device number.
+ * @param method 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_register().
+ *
  */
 unative_t sys_ipc_register_irq(inr_t inr, devno_t devno, unative_t method,
@@ -1091,5 +1113,5 @@
 	if (!(cap_get(TASK) & CAP_IRQ_REG))
 		return EPERM;
-
+	
 	return ipc_irq_register(&TASK->answerbox, inr, devno, method, ucode);
 }
@@ -1097,8 +1119,9 @@
 /** Disconnect an IRQ handler from a task.
  *
- * @param inr		IRQ number.
- * @param devno		Device number.
- *
- * @return		Zero on success or EPERM on error..
+ * @param inr   IRQ number.
+ * @param devno Device number.
+ *
+ * @return Zero on success or EPERM on error.
+ *
  */
 unative_t sys_ipc_unregister_irq(inr_t inr, devno_t devno)
@@ -1106,7 +1129,7 @@
 	if (!(cap_get(TASK) & CAP_IRQ_REG))
 		return EPERM;
-
+	
 	ipc_irq_unregister(&TASK->answerbox, inr, devno);
-
+	
 	return 0;
 }
@@ -1114,8 +1137,8 @@
 #include <console/console.h>
 
-/**
- * Syscall connect to a task by id.
- *
- * @return 		Phone id on success, or negative error code.
+/** Syscall connect to a task by id.
+ *
+ * @return Phone id on success, or negative error code.
+ *
  */
 unative_t sys_ipc_connect_kbox(sysarg64_t *uspace_taskid_arg)
@@ -1123,12 +1146,10 @@
 #ifdef CONFIG_UDEBUG
 	sysarg64_t taskid_arg;
-	int rc;
-	
-	rc = copy_from_uspace(&taskid_arg, uspace_taskid_arg, sizeof(sysarg64_t));
+	int rc = copy_from_uspace(&taskid_arg, uspace_taskid_arg, sizeof(sysarg64_t));
 	if (rc != 0)
 		return (unative_t) rc;
-
-	LOG("sys_ipc_connect_kbox(%" PRIu64 ")\n", taskid_arg.value);
-
+	
+	LOG("sys_ipc_connect_kbox(%" PRIu64 ")", taskid_arg.value);
+	
 	return ipc_connect_kbox(taskid_arg.value);
 #else
Index: kernel/generic/src/lib/elf.c
===================================================================
--- kernel/generic/src/lib/elf.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/generic/src/lib/elf.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -28,5 +28,5 @@
  */
 
-/** @addtogroup generic	
+/** @addtogroup generic
  * @{
  */
@@ -34,5 +34,5 @@
 /**
  * @file
- * @brief	Kernel ELF loader.
+ * @brief Kernel ELF loader.
  */
 
@@ -57,75 +57,72 @@
 };
 
-static int segment_header(elf_segment_header_t *entry, elf_header_t *elf,
-    as_t *as, int flags);
-static int section_header(elf_section_header_t *entry, elf_header_t *elf,
-    as_t *as);
-static int load_segment(elf_segment_header_t *entry, elf_header_t *elf,
-    as_t *as);
+static int segment_header(elf_segment_header_t *, elf_header_t *, as_t *,
+    unsigned int);
+static int section_header(elf_section_header_t *, elf_header_t *, as_t *);
+static int load_segment(elf_segment_header_t *, elf_header_t *, as_t *);
 
 /** ELF loader
  *
  * @param header Pointer to ELF header in memory
- * @param as Created and properly mapped address space
- * @param flags A combination of ELD_F_*
+ * @param as     Created and properly mapped address space
+ * @param flags  A combination of ELD_F_*
+ *
  * @return EE_OK on success
- */
-unsigned int elf_load(elf_header_t *header, as_t * as, int flags)
-{
-	int i, rc;
-
+ *
+ */
+unsigned int elf_load(elf_header_t *header, as_t *as, unsigned int flags)
+{
 	/* Identify ELF */
-	if (header->e_ident[EI_MAG0] != ELFMAG0 ||
-	    header->e_ident[EI_MAG1] != ELFMAG1 || 
-	    header->e_ident[EI_MAG2] != ELFMAG2 ||
-	    header->e_ident[EI_MAG3] != ELFMAG3) {
+	if ((header->e_ident[EI_MAG0] != ELFMAG0) ||
+	    (header->e_ident[EI_MAG1] != ELFMAG1) ||
+	    (header->e_ident[EI_MAG2] != ELFMAG2) ||
+	    (header->e_ident[EI_MAG3] != ELFMAG3))
 		return EE_INVALID;
-	}
 	
 	/* Identify ELF compatibility */
-	if (header->e_ident[EI_DATA] != ELF_DATA_ENCODING ||
-	    header->e_machine != ELF_MACHINE || 
-	    header->e_ident[EI_VERSION] != EV_CURRENT ||
-	    header->e_version != EV_CURRENT ||
-	    header->e_ident[EI_CLASS] != ELF_CLASS) {
+	if ((header->e_ident[EI_DATA] != ELF_DATA_ENCODING) ||
+	    (header->e_machine != ELF_MACHINE) ||
+	    (header->e_ident[EI_VERSION] != EV_CURRENT) ||
+	    (header->e_version != EV_CURRENT) ||
+	    (header->e_ident[EI_CLASS] != ELF_CLASS))
 		return EE_INCOMPATIBLE;
-	}
-
+	
 	if (header->e_phentsize != sizeof(elf_segment_header_t))
 		return EE_INCOMPATIBLE;
-
+	
 	if (header->e_shentsize != sizeof(elf_section_header_t))
 		return EE_INCOMPATIBLE;
-
+	
 	/* Check if the object type is supported. */
 	if (header->e_type != ET_EXEC)
 		return EE_UNSUPPORTED;
-
+	
 	/* Check if the ELF image starts on a page boundary */
-	if (ALIGN_UP((uintptr_t)header, PAGE_SIZE) != (uintptr_t)header)
+	if (ALIGN_UP((uintptr_t) header, PAGE_SIZE) != (uintptr_t) header)
 		return EE_UNSUPPORTED;
-
+	
 	/* Walk through all segment headers and process them. */
+	elf_half i;
 	for (i = 0; i < header->e_phnum; i++) {
-		elf_segment_header_t *seghdr;
-
-		seghdr = &((elf_segment_header_t *)(((uint8_t *) header) +
+		elf_segment_header_t *seghdr =
+		    &((elf_segment_header_t *)(((uint8_t *) header) +
 		    header->e_phoff))[i];
-		rc = segment_header(seghdr, header, as, flags);
+		
+		int rc = segment_header(seghdr, header, as, flags);
 		if (rc != EE_OK)
 			return rc;
 	}
-
+	
 	/* Inspect all section headers and proccess them. */
 	for (i = 0; i < header->e_shnum; i++) {
-		elf_section_header_t *sechdr;
-
-		sechdr = &((elf_section_header_t *)(((uint8_t *) header) +
+		elf_section_header_t *sechdr =
+		    &((elf_section_header_t *)(((uint8_t *) header) +
 		    header->e_shoff))[i];
-		rc = section_header(sechdr, header, as);
+		
+		int rc = section_header(sechdr, header, as);
 		if (rc != EE_OK)
 			return rc;
 	}
-
+	
 	return EE_OK;
 }
@@ -136,9 +133,10 @@
  *
  * @return NULL terminated description of error.
+ *
  */
 const char *elf_error(unsigned int rc)
 {
 	ASSERT(rc < sizeof(error_codes) / sizeof(char *));
-
+	
 	return error_codes[rc];
 }
@@ -147,11 +145,12 @@
  *
  * @param entry Segment header.
- * @param elf ELF header.
- * @param as Address space into wich the ELF is being loaded.
+ * @param elf   ELF header.
+ * @param as    Address space into wich the ELF is being loaded.
  *
  * @return EE_OK on success, error code otherwise.
+ *
  */
 static int segment_header(elf_segment_header_t *entry, elf_header_t *elf,
-    as_t *as, int flags)
+    as_t *as, unsigned int flags)
 {
 	switch (entry->p_type) {
@@ -170,7 +169,6 @@
 			return EE_UNSUPPORTED;
 		} */
-		if ((flags & ELD_F_LOADER) == 0) {
+		if ((flags & ELD_F_LOADER) == 0)
 			return EE_LOADER;
-		}
 		break;
 	case PT_SHLIB:
@@ -187,51 +185,53 @@
  *
  * @param entry Program header entry describing segment to be loaded.
- * @param elf ELF header.
- * @param as Address space into wich the ELF is being loaded.
+ * @param elf   ELF header.
+ * @param as    Address space into wich the ELF is being loaded.
  *
  * @return EE_OK on success, error code otherwise.
+ *
  */
 int load_segment(elf_segment_header_t *entry, elf_header_t *elf, as_t *as)
 {
-	as_area_t *a;
-	int flags = 0;
 	mem_backend_data_t backend_data;
-	uintptr_t base;
-	size_t mem_sz;
-	
 	backend_data.elf = elf;
 	backend_data.segment = entry;
-
+	
 	if (entry->p_align > 1) {
 		if ((entry->p_offset % entry->p_align) !=
-		    (entry->p_vaddr % entry->p_align)) {
+		    (entry->p_vaddr % entry->p_align))
 			return EE_INVALID;
-		}
-	}
-
+	}
+	
+	unsigned int flags = 0;
+	
 	if (entry->p_flags & PF_X)
 		flags |= AS_AREA_EXEC;
+	
 	if (entry->p_flags & PF_W)
 		flags |= AS_AREA_WRITE;
+	
 	if (entry->p_flags & PF_R)
 		flags |= AS_AREA_READ;
+	
 	flags |= AS_AREA_CACHEABLE;
-
-	/* 
+	
+	/*
 	 * Align vaddr down, inserting a little "gap" at the beginning.
 	 * Adjust area size, so that its end remains in place.
+	 *
 	 */
-	base = ALIGN_DOWN(entry->p_vaddr, PAGE_SIZE);
-	mem_sz = entry->p_memsz + (entry->p_vaddr - base);
-
-	a = as_area_create(as, flags, mem_sz, base,
+	uintptr_t base = ALIGN_DOWN(entry->p_vaddr, PAGE_SIZE);
+	size_t mem_sz = entry->p_memsz + (entry->p_vaddr - base);
+	
+	as_area_t *area = as_area_create(as, flags, mem_sz, base,
 	    AS_AREA_ATTR_NONE, &elf_backend, &backend_data);
-	if (!a)
+	if (!area)
 		return EE_MEMORY;
 	
 	/*
 	 * The segment will be mapped on demand by elf_page_fault().
+	 *
 	 */
-
+	
 	return EE_OK;
 }
@@ -240,8 +240,9 @@
  *
  * @param entry Segment header.
- * @param elf ELF header.
- * @param as Address space into wich the ELF is being loaded.
+ * @param elf   ELF header.
+ * @param as    Address space into wich the ELF is being loaded.
  *
  * @return EE_OK on success, error code otherwise.
+ *
  */
 static int section_header(elf_section_header_t *entry, elf_header_t *elf,
Index: kernel/generic/src/lib/sort.c
===================================================================
--- kernel/generic/src/lib/sort.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/generic/src/lib/sort.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -27,5 +27,5 @@
  */
 
-/** @addtogroup generic	
+/** @addtogroup generic
  * @{
  */
@@ -33,172 +33,193 @@
 /**
  * @file
- * @brief	Sorting functions.
+ * @brief Sorting functions.
  *
  * This files contains functions implementing several sorting
- * algorithms (e.g. quick sort and bubble sort).
- */
- 
+ * algorithms (e.g. quick sort and gnome sort).
+ *
+ */
+
 #include <mm/slab.h>
 #include <memstr.h>
 #include <sort.h>
-#include <panic.h>
-
-#define EBUFSIZE	32
-
-void _qsort(void * data, size_t n, size_t e_size, int (* cmp) (void * a, void * b), void *tmp, void *pivot);
-void _bubblesort(void * data, size_t n, size_t e_size, int (* cmp) (void * a, void * b), void *slot);
-
-/** 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 n Number of elements to be sorted.
- * @param e_size Size of one element.
- * @param cmp Comparator function.
- * 
- */
-void qsort(void * data, size_t n, size_t e_size, int (* cmp) (void * a, void * b))
-{
-	uint8_t buf_tmp[EBUFSIZE];
-	uint8_t buf_pivot[EBUFSIZE];
-	void * tmp = buf_tmp;
-	void * pivot = buf_pivot;
-
-	if (e_size > EBUFSIZE) {
-		pivot = (void *) malloc(e_size, 0);
-		tmp = (void *) malloc(e_size, 0);
+
+/** 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++;
 	}
-
-	_qsort(data, n, e_size, cmp, tmp, pivot);
-	
-	if (e_size > EBUFSIZE) {
-		free(tmp);
-		free(pivot);
-	}
 }
 
 /** Quicksort
  *
- * Apply generic quicksort algorithm on supplied data, using pre-allocated buffers.
- * 
- * @param data Pointer to data to be sorted.
- * @param n Number of elements to be sorted.
- * @param e_size Size of one element.
- * @param cmp Comparator function.
- * @param tmp Pointer to scratch memory buffer e_size bytes long.
- * @param pivot Pointer to scratch memory buffer e_size bytes long.
- * 
- */
-void _qsort(void * data, size_t n, size_t e_size, int (* cmp) (void * a, void * b), void *tmp, void *pivot)
-{
-	if (n > 4) {
-		unsigned int i = 0, j = n - 1;
-
-		memcpy(pivot, data, e_size);
-
-		while (1) {
-			while ((cmp(data + i * e_size, pivot) < 0) && (i < n))
+ * 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(data + j * e_size, pivot) >= 0) && (j > 0))
+			
+			while ((cmp(INDEX(data, j, elem_size), pivot, arg) >= 0) && (j > 0))
 				j--;
 			
 			if (i < j) {
-				memcpy(tmp, data + i * e_size, e_size);
-				memcpy(data + i * e_size, data + j * e_size, e_size);
-				memcpy(data + j * e_size, tmp, e_size);
-			} else {
+				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, e_size, cmp, tmp, pivot);
-		_qsort(data + (j + 1) * e_size, n - j - 1, e_size, cmp, tmp, pivot);
+		
+		_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 {
-		_bubblesort(data, n, e_size, cmp, tmp);
+		slot = (void *) ibuf_slot;
+		pivot = (void *) ibuf_pivot;
 	}
-}
-
-/** Bubblesort wrapper
- *
- * This is only a wrapper that takes care of memory allocation for storing
- * the slot element for generic bubblesort algorithm.
- * 
- * @param data Pointer to data to be sorted.
- * @param n Number of elements to be sorted.
- * @param e_size Size of one element.
- * @param cmp Comparator function.
- * 
- */
-void bubblesort(void * data, size_t n, size_t e_size, int (* cmp) (void * a, void * b))
-{
-	uint8_t buf_slot[EBUFSIZE];
-	void * slot = buf_slot;
-	
-	if (e_size > EBUFSIZE) {
-		slot = (void *) malloc(e_size, 0);
-	}
-
-	_bubblesort(data, n, e_size, cmp, slot);
-	
-	if (e_size > EBUFSIZE) {
+	
+	_qsort(data, cnt, elem_size, cmp, arg, slot, pivot);
+	
+	if (elem_size > IBUF_SIZE) {
+		free(pivot);
 		free(slot);
 	}
-}
-
-/** Bubblesort
- *
- * Apply generic bubblesort algorithm on supplied data, using pre-allocated buffer.
- * 
- * @param data Pointer to data to be sorted.
- * @param n Number of elements to be sorted.
- * @param e_size Size of one element.
- * @param cmp Comparator function.
- * @param slot Pointer to scratch memory buffer e_size bytes long.
- * 
- */
-void _bubblesort(void * data, size_t n, size_t e_size, int (* cmp) (void * a, void * b), void *slot)
-{
-	bool done = false;
-	void * p;
-
-	while (!done) {
-		done = true;
-		for (p = data; p < data + e_size * (n - 1); p = p + e_size) {
-			if (cmp(p, p + e_size) == 1) {
-				memcpy(slot, p, e_size);
-				memcpy(p, p + e_size, e_size);
-				memcpy(p + e_size, slot, e_size);
-				done = false;
-			}
-		}
-	}
-
-}
-
-/*
- * Comparator returns 1 if a > b, 0 if a == b, -1 if a < b
- */
-int int_cmp(void * a, void * b)
-{
-	return (* (int *) a > * (int*)b) ? 1 : (*(int *)a < * (int *)b) ? -1 : 0;
-}
-
-int uint8_t_cmp(void * a, void * b)
-{
-	return (* (uint8_t *) a > * (uint8_t *)b) ? 1 : (*(uint8_t *)a < * (uint8_t *)b) ? -1 : 0;
-}
-
-int uint16_t_cmp(void * a, void * b)
-{
-	return (* (uint16_t *) a > * (uint16_t *)b) ? 1 : (*(uint16_t *)a < * (uint16_t *)b) ? -1 : 0;
-}
-
-int uint32_t_cmp(void * a, void * b)
-{
-	return (* (uint32_t *) a > * (uint32_t *)b) ? 1 : (*(uint32_t *)a < * (uint32_t *)b) ? -1 : 0;
+	
+	return true;
 }
 
Index: kernel/generic/src/main/kinit.c
===================================================================
--- kernel/generic/src/main/kinit.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/generic/src/main/kinit.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -107,4 +107,5 @@
 	if (config.cpu_count > 1) {
 		waitq_initialize(&ap_completion_wq);
+		
 		/*
 		 * Create the kmp thread and wait for its completion.
@@ -115,7 +116,7 @@
 		thread = thread_create(kmp, NULL, TASK, THREAD_FLAG_WIRED, "kmp", true);
 		if (thread != NULL) {
-			spinlock_lock(&thread->lock);
+			irq_spinlock_lock(&thread->lock, false);
 			thread->cpu = &cpus[0];
-			spinlock_unlock(&thread->lock);
+			irq_spinlock_unlock(&thread->lock, false);
 			thread_ready(thread);
 		} else
@@ -124,18 +125,16 @@
 		thread_join(thread);
 		thread_detach(thread);
-	}
-	
-	if (config.cpu_count > 1) {
+		
+		/*
+		 * For each CPU, create its load balancing thread.
+		 */
 		size_t i;
 		
-		/*
-		 * For each CPU, create its load balancing thread.
-		 */
 		for (i = 0; i < config.cpu_count; i++) {
 			thread = thread_create(kcpulb, NULL, TASK, THREAD_FLAG_WIRED, "kcpulb", true);
 			if (thread != NULL) {
-				spinlock_lock(&thread->lock);
+				irq_spinlock_lock(&thread->lock, false);
 				thread->cpu = &cpus[i];
-				spinlock_unlock(&thread->lock);
+				irq_spinlock_unlock(&thread->lock, false);
 				thread_ready(thread);
 			} else
@@ -181,4 +180,5 @@
 		if (init.tasks[i].addr % FRAME_SIZE) {
 			printf("init[%" PRIs "].addr is not frame aligned\n", i);
+			programs[i].task = NULL;
 			continue;
 		}
@@ -199,5 +199,5 @@
 		str_cpy(namebuf + INIT_PREFIX_LEN,
 		    TASK_NAME_BUFLEN - INIT_PREFIX_LEN, name);
-
+		
 		int rc = program_create_from_image((void *) init.tasks[i].addr,
 		    namebuf, &programs[i]);
@@ -208,5 +208,5 @@
 			 */
 			cap_set(programs[i].task, CAP_CAP | CAP_MEM_MANAGER |
-			    CAP_IO_MANAGER | CAP_PREEMPT_CONTROL | CAP_IRQ_REG);
+			    CAP_IO_MANAGER | CAP_IRQ_REG);
 			
 			if (!ipc_phone_0)
@@ -222,5 +222,5 @@
 		}
 	}
-
+	
 	/*
 	 * Run user tasks.
@@ -230,5 +230,5 @@
 			program_ready(&programs[i]);
 	}
-
+	
 #ifdef CONFIG_KCONSOLE
 	if (!stdin) {
Index: kernel/generic/src/main/main.c
===================================================================
--- kernel/generic/src/main/main.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/generic/src/main/main.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -104,5 +104,5 @@
 
 /** Lowest safe stack virtual address. */
-uintptr_t stack_safe = 0;		
+uintptr_t stack_safe = 0;
 
 /*
@@ -113,9 +113,10 @@
  */
 static void main_bsp_separated_stack(void);
+
 #ifdef CONFIG_SMP
 static void main_ap_separated_stack(void);
 #endif
 
-#define CONFIG_STACK_SIZE	((1 << STACK_FRAMES) * STACK_SIZE)
+#define CONFIG_STACK_SIZE  ((1 << STACK_FRAMES) * STACK_SIZE)
 
 /** Main kernel routine for bootstrap CPU.
@@ -130,5 +131,5 @@
  *
  */
-void main_bsp(void)
+NO_TRACE void main_bsp(void)
 {
 	config.cpu_count = 1;
@@ -146,13 +147,13 @@
 	size_t i;
 	for (i = 0; i < init.cnt; i++) {
-		if (PA_overlaps(config.stack_base, config.stack_size,
+		if (PA_OVERLAPS(config.stack_base, config.stack_size,
 		    init.tasks[i].addr, init.tasks[i].size))
 			config.stack_base = ALIGN_UP(init.tasks[i].addr +
 			    init.tasks[i].size, config.stack_size);
 	}
-
+	
 	/* Avoid placing stack on top of boot allocations. */
 	if (ballocs.size) {
-		if (PA_overlaps(config.stack_base, config.stack_size,
+		if (PA_OVERLAPS(config.stack_base, config.stack_size,
 		    ballocs.base, ballocs.size))
 			config.stack_base = ALIGN_UP(ballocs.base +
@@ -170,5 +171,4 @@
 }
 
-
 /** Main kernel routine for bootstrap CPU using new stack.
  *
@@ -176,5 +176,5 @@
  *
  */
-void main_bsp_separated_stack(void) 
+void main_bsp_separated_stack(void)
 {
 	/* Keep this the first thing. */
@@ -183,6 +183,6 @@
 	version_print();
 	
-	LOG("\nconfig.base=%#" PRIp " config.kernel_size=%" PRIs
-	    "\nconfig.stack_base=%#" PRIp " config.stack_size=%" PRIs,
+	LOG("\nconfig.base=%p config.kernel_size=%" PRIs
+	    "\nconfig.stack_base=%p config.stack_size=%" PRIs,
 	    config.base, config.kernel_size, config.stack_base,
 	    config.stack_size);
@@ -194,5 +194,5 @@
 	 * commands.
 	 */
-	LOG_EXEC(kconsole_init());
+	kconsole_init();
 #endif
 	
@@ -201,54 +201,54 @@
 	 * starts adding its own handlers
 	 */
-	LOG_EXEC(exc_init());
+	exc_init();
 	
 	/*
 	 * Memory management subsystems initialization.
 	 */
-	LOG_EXEC(arch_pre_mm_init());
-	LOG_EXEC(frame_init());
+	arch_pre_mm_init();
+	frame_init();
 	
 	/* Initialize at least 1 memory segment big enough for slab to work. */
-	LOG_EXEC(slab_cache_init());
-	LOG_EXEC(sysinfo_init());
-	LOG_EXEC(btree_init());
-	LOG_EXEC(as_init());
-	LOG_EXEC(page_init());
-	LOG_EXEC(tlb_init());
-	LOG_EXEC(ddi_init());
-	LOG_EXEC(tasklet_init());
-	LOG_EXEC(arch_post_mm_init());
-	LOG_EXEC(arch_pre_smp_init());
-	LOG_EXEC(smp_init());
+	slab_cache_init();
+	sysinfo_init();
+	btree_init();
+	as_init();
+	page_init();
+	tlb_init();
+	ddi_init();
+	tasklet_init();
+	arch_post_mm_init();
+	arch_pre_smp_init();
+	smp_init();
 	
 	/* Slab must be initialized after we know the number of processors. */
-	LOG_EXEC(slab_enable_cpucache());
+	slab_enable_cpucache();
 	
 	printf("Detected %" PRIs " CPU(s), %" PRIu64" MiB free memory\n",
 	    config.cpu_count, SIZE2MB(zones_total_size()));
-
-	LOG_EXEC(cpu_init());
-	
-	LOG_EXEC(calibrate_delay_loop());
-	LOG_EXEC(clock_counter_init());
-	LOG_EXEC(timeout_init());
-	LOG_EXEC(scheduler_init());
-	LOG_EXEC(task_init());
-	LOG_EXEC(thread_init());
-	LOG_EXEC(futex_init());
+	
+	cpu_init();
+	
+	calibrate_delay_loop();
+	clock_counter_init();
+	timeout_init();
+	scheduler_init();
+	task_init();
+	thread_init();
+	futex_init();
 	
 	if (init.cnt > 0) {
 		size_t i;
 		for (i = 0; i < init.cnt; i++)
-			LOG("init[%" PRIs "].addr=%#" PRIp ", init[%" PRIs
-			    "].size=%#" PRIs, i, init.tasks[i].addr, i,
+			LOG("init[%" PRIs "].addr=%p, init[%" PRIs
+			    "].size=%" PRIs, i, init.tasks[i].addr, i,
 			    init.tasks[i].size);
 	} else
 		printf("No init binaries found.\n");
 	
-	LOG_EXEC(ipc_init());
-	LOG_EXEC(event_init());
-	LOG_EXEC(klog_init());
-	LOG_EXEC(stats_init());
+	ipc_init();
+	event_init();
+	klog_init();
+	stats_init();
 	
 	/*
@@ -266,5 +266,5 @@
 	if (!kinit_thread)
 		panic("Cannot create kinit thread.");
-	LOG_EXEC(thread_ready(kinit_thread));
+	thread_ready(kinit_thread);
 	
 	/*
@@ -276,6 +276,6 @@
 }
 
-
 #ifdef CONFIG_SMP
+
 /** Main kernel routine for application CPUs.
  *
@@ -296,5 +296,5 @@
 	 */
 	config.cpu_active++;
-
+	
 	/*
 	 * The THE structure is well defined because ctx.sp is used as stack.
@@ -311,7 +311,7 @@
 	calibrate_delay_loop();
 	arch_post_cpu_init();
-
+	
 	the_copy(THE, (the_t *) CPU->stack);
-
+	
 	/*
 	 * If we woke kmp up before we left the kernel stack, we could
@@ -326,5 +326,4 @@
 }
 
-
 /** Main kernel routine for application CPUs using new stack.
  *
@@ -338,9 +337,10 @@
 	 */
 	timeout_init();
-
+	
 	waitq_wakeup(&ap_completion_wq, WAKEUP_FIRST);
 	scheduler();
 	/* not reached */
 }
+
 #endif /* CONFIG_SMP */
 
Index: kernel/generic/src/mm/as.c
===================================================================
--- kernel/generic/src/mm/as.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/generic/src/mm/as.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -33,5 +33,5 @@
 /**
  * @file
- * @brief	Address space related functions.
+ * @brief Address space related functions.
  *
  * This file contains address space manipulation functions.
@@ -86,4 +86,5 @@
  * Each architecture decides what functions will be used to carry out
  * address space operations such as creating or locking page tables.
+ *
  */
 as_operations_t *as_operations = NULL;
@@ -91,4 +92,5 @@
 /**
  * Slab for as_t objects.
+ *
  */
 static slab_cache_t *as_slab;
@@ -100,4 +102,5 @@
  * - as->asid for each as of the as_t type
  * - asids_allocated counter
+ *
  */
 SPINLOCK_INITIALIZE(asidlock);
@@ -106,4 +109,5 @@
  * This list contains address spaces that are not active on any
  * processor and that have valid ASID.
+ *
  */
 LIST_INITIALIZE(inactive_as_with_asid_head);
@@ -112,26 +116,19 @@
 as_t *AS_KERNEL = NULL;
 
-static int area_flags_to_page_flags(int);
-static as_area_t *find_area_and_lock(as_t *, uintptr_t);
-static bool check_area_conflicts(as_t *, uintptr_t, size_t, as_area_t *);
-static void sh_info_remove_reference(share_info_t *);
-
-static int as_constructor(void *obj, int flags)
+NO_TRACE static int as_constructor(void *obj, unsigned int flags)
 {
 	as_t *as = (as_t *) obj;
-	int rc;
-
+	
 	link_initialize(&as->inactive_as_with_asid_link);
 	mutex_initialize(&as->lock, MUTEX_PASSIVE);
 	
-	rc = as_constructor_arch(as, flags);
+	int rc = as_constructor_arch(as, flags);
 	
 	return rc;
 }
 
-static int as_destructor(void *obj)
+NO_TRACE static size_t as_destructor(void *obj)
 {
 	as_t *as = (as_t *) obj;
-
 	return as_destructor_arch(as);
 }
@@ -141,5 +138,5 @@
 {
 	as_arch_init();
-
+	
 	as_slab = slab_cache_create("as_slab", sizeof(as_t), 0,
 	    as_constructor, as_destructor, SLAB_CACHE_MAGDEFERRED);
@@ -157,12 +154,11 @@
 /** Create address space.
  *
- * @param flags		Flags that influence the way in wich the address space
- * 			is created.
- */
-as_t *as_create(int flags)
-{
-	as_t *as;
-
-	as = (as_t *) slab_alloc(as_slab, 0);
+ * @param flags Flags that influence the way in wich the address
+ *              space is created.
+ *
+ */
+as_t *as_create(unsigned int flags)
+{
+	as_t *as = (as_t *) slab_alloc(as_slab, 0);
 	(void) as_create_arch(as, 0);
 	
@@ -176,4 +172,5 @@
 	atomic_set(&as->refcount, 0);
 	as->cpu_refcount = 0;
+	
 #ifdef AS_PAGE_TABLE
 	as->genarch.page_table = page_table_create(flags);
@@ -192,10 +189,9 @@
  * We know that we don't hold any spinlock.
  *
- * @param as		Address space to be destroyed.
+ * @param as Address space to be destroyed.
+ *
  */
 void as_destroy(as_t *as)
 {
-	ipl_t ipl;
-	bool cond;
 	DEADLOCK_PROBE_INIT(p_asidlock);
 
@@ -214,7 +210,9 @@
 	 * disabled to prevent nested context switches. We also depend on the
 	 * fact that so far no spinlocks are held.
+	 *
 	 */
 	preemption_disable();
-	ipl = interrupts_read();
+	ipl_t ipl = interrupts_read();
+	
 retry:
 	interrupts_disable();
@@ -224,30 +222,39 @@
 		goto retry;
 	}
-	preemption_enable();	/* Interrupts disabled, enable preemption */
-	if (as->asid != ASID_INVALID && as != AS_KERNEL) {
+	
+	/* Interrupts disabled, enable preemption */
+	preemption_enable();
+	
+	if ((as->asid != ASID_INVALID) && (as != AS_KERNEL)) {
 		if (as->cpu_refcount == 0)
 			list_remove(&as->inactive_as_with_asid_link);
+		
 		asid_put(as->asid);
 	}
+	
 	spinlock_unlock(&asidlock);
-
+	interrupts_restore(ipl);
+
+	
 	/*
 	 * Destroy address space areas of the address space.
 	 * The B+tree must be walked carefully because it is
 	 * also being destroyed.
-	 */	
-	for (cond = true; cond; ) {
-		btree_node_t *node;
-
+	 *
+	 */
+	bool cond = true;
+	while (cond) {
 		ASSERT(!list_empty(&as->as_area_btree.leaf_head));
-		node = list_get_instance(as->as_area_btree.leaf_head.next,
+		
+		btree_node_t *node =
+		    list_get_instance(as->as_area_btree.leaf_head.next,
 		    btree_node_t, leaf_link);
-
-		if ((cond = node->keys)) {
+		
+		if ((cond = node->keys))
 			as_area_destroy(as, node->key[0]);
-		}
-	}
-
+	}
+	
 	btree_destroy(&as->as_area_btree);
+	
 #ifdef AS_PAGE_TABLE
 	page_table_destroy(as->genarch.page_table);
@@ -255,7 +262,5 @@
 	page_table_destroy(NULL);
 #endif
-
-	interrupts_restore(ipl);
-
+	
 	slab_free(as_slab, as);
 }
@@ -266,7 +271,8 @@
  * space.
  *
- * @param a		Address space to be held.
- */
-void as_hold(as_t *as)
+ * @param as Address space to be held.
+ *
+ */
+NO_TRACE void as_hold(as_t *as)
 {
 	atomic_inc(&as->refcount);
@@ -278,7 +284,8 @@
  * space.
  *
- * @param a		Address space to be released.
- */
-void as_release(as_t *as)
+ * @param asAddress space to be released.
+ *
+ */
+NO_TRACE void as_release(as_t *as)
 {
 	if (atomic_predec(&as->refcount) == 0)
@@ -286,149 +293,304 @@
 }
 
+/** Check area conflicts with other areas.
+ *
+ * @param as         Address space.
+ * @param va         Starting virtual address of the area being tested.
+ * @param size       Size of the area being tested.
+ * @param avoid_area Do not touch this area.
+ *
+ * @return True if there is no conflict, false otherwise.
+ *
+ */
+NO_TRACE static bool check_area_conflicts(as_t *as, uintptr_t va, size_t size,
+    as_area_t *avoid_area)
+{
+	ASSERT(mutex_locked(&as->lock));
+	
+	/*
+	 * We don't want any area to have conflicts with NULL page.
+	 *
+	 */
+	if (overlaps(va, size, NULL, PAGE_SIZE))
+		return false;
+	
+	/*
+	 * The leaf node is found in O(log n), where n is proportional to
+	 * the number of address space areas belonging to as.
+	 * The check for conflicts is then attempted on the rightmost
+	 * record in the left neighbour, the leftmost record in the right
+	 * neighbour and all records in the leaf node itself.
+	 *
+	 */
+	btree_node_t *leaf;
+	as_area_t *area =
+	    (as_area_t *) btree_search(&as->as_area_btree, va, &leaf);
+	if (area) {
+		if (area != avoid_area)
+			return false;
+	}
+	
+	/* First, check the two border cases. */
+	btree_node_t *node =
+	    btree_leaf_node_left_neighbour(&as->as_area_btree, leaf);
+	if (node) {
+		area = (as_area_t *) node->value[node->keys - 1];
+		
+		mutex_lock(&area->lock);
+		
+		if (overlaps(va, size, area->base, area->pages * PAGE_SIZE)) {
+			mutex_unlock(&area->lock);
+			return false;
+		}
+		
+		mutex_unlock(&area->lock);
+	}
+	
+	node = btree_leaf_node_right_neighbour(&as->as_area_btree, leaf);
+	if (node) {
+		area = (as_area_t *) node->value[0];
+		
+		mutex_lock(&area->lock);
+		
+		if (overlaps(va, size, area->base, area->pages * PAGE_SIZE)) {
+			mutex_unlock(&area->lock);
+			return false;
+		}
+		
+		mutex_unlock(&area->lock);
+	}
+	
+	/* Second, check the leaf node. */
+	btree_key_t i;
+	for (i = 0; i < leaf->keys; i++) {
+		area = (as_area_t *) leaf->value[i];
+		
+		if (area == avoid_area)
+			continue;
+		
+		mutex_lock(&area->lock);
+		
+		if (overlaps(va, size, area->base, area->pages * PAGE_SIZE)) {
+			mutex_unlock(&area->lock);
+			return false;
+		}
+		
+		mutex_unlock(&area->lock);
+	}
+	
+	/*
+	 * So far, the area does not conflict with other areas.
+	 * Check if it doesn't conflict with kernel address space.
+	 *
+	 */
+	if (!KERNEL_ADDRESS_SPACE_SHADOWED) {
+		return !overlaps(va, size,
+		    KERNEL_ADDRESS_SPACE_START,
+		    KERNEL_ADDRESS_SPACE_END - KERNEL_ADDRESS_SPACE_START);
+	}
+	
+	return true;
+}
+
 /** Create address space area of common attributes.
  *
  * The created address space area is added to the target address space.
  *
- * @param as		Target address space.
- * @param flags		Flags of the area memory.
- * @param size		Size of area.
- * @param base		Base address of area.
- * @param attrs		Attributes of the area.
- * @param backend	Address space area backend. NULL if no backend is used.
- * @param backend_data	NULL or a pointer to an array holding two void *.
- *
- * @return		Address space area on success or NULL on failure.
- */
-as_area_t *
-as_area_create(as_t *as, int flags, size_t size, uintptr_t base, int attrs,
-    mem_backend_t *backend, mem_backend_data_t *backend_data)
-{
-	ipl_t ipl;
-	as_area_t *a;
-	
+ * @param as           Target address space.
+ * @param flags        Flags of the area memory.
+ * @param size         Size of area.
+ * @param base         Base address of area.
+ * @param attrs        Attributes of the area.
+ * @param backend      Address space area backend. NULL if no backend is used.
+ * @param backend_data NULL or a pointer to an array holding two void *.
+ *
+ * @return Address space area on success or NULL on failure.
+ *
+ */
+as_area_t *as_area_create(as_t *as, unsigned int flags, size_t size,
+    uintptr_t base, unsigned int attrs, mem_backend_t *backend,
+    mem_backend_data_t *backend_data)
+{
 	if (base % PAGE_SIZE)
 		return NULL;
-
+	
 	if (!size)
 		return NULL;
-
+	
 	/* Writeable executable areas are not supported. */
 	if ((flags & AS_AREA_EXEC) && (flags & AS_AREA_WRITE))
 		return NULL;
 	
-	ipl = interrupts_disable();
 	mutex_lock(&as->lock);
 	
 	if (!check_area_conflicts(as, base, size, NULL)) {
 		mutex_unlock(&as->lock);
-		interrupts_restore(ipl);
 		return NULL;
 	}
 	
-	a = (as_area_t *) malloc(sizeof(as_area_t), 0);
-
-	mutex_initialize(&a->lock, MUTEX_PASSIVE);
-	
-	a->as = as;
-	a->flags = flags;
-	a->attributes = attrs;
-	a->pages = SIZE2FRAMES(size);
-	a->base = base;
-	a->sh_info = NULL;
-	a->backend = backend;
+	as_area_t *area = (as_area_t *) malloc(sizeof(as_area_t), 0);
+	
+	mutex_initialize(&area->lock, MUTEX_PASSIVE);
+	
+	area->as = as;
+	area->flags = flags;
+	area->attributes = attrs;
+	area->pages = SIZE2FRAMES(size);
+	area->base = base;
+	area->sh_info = NULL;
+	area->backend = backend;
+	
 	if (backend_data)
-		a->backend_data = *backend_data;
+		area->backend_data = *backend_data;
 	else
-		memsetb(&a->backend_data, sizeof(a->backend_data), 0);
-
-	btree_create(&a->used_space);
-	
-	btree_insert(&as->as_area_btree, base, (void *) a, NULL);
-
+		memsetb(&area->backend_data, sizeof(area->backend_data), 0);
+	
+	btree_create(&area->used_space);
+	btree_insert(&as->as_area_btree, base, (void *) area, NULL);
+	
 	mutex_unlock(&as->lock);
-	interrupts_restore(ipl);
-
-	return a;
+	
+	return area;
+}
+
+/** Find address space area and lock it.
+ *
+ * @param as Address space.
+ * @param va Virtual address.
+ *
+ * @return Locked address space area containing va on success or
+ *         NULL on failure.
+ *
+ */
+NO_TRACE static as_area_t *find_area_and_lock(as_t *as, uintptr_t va)
+{
+	ASSERT(mutex_locked(&as->lock));
+	
+	btree_node_t *leaf;
+	as_area_t *area = (as_area_t *) btree_search(&as->as_area_btree, va, &leaf);
+	if (area) {
+		/* va is the base address of an address space area */
+		mutex_lock(&area->lock);
+		return area;
+	}
+	
+	/*
+	 * Search the leaf node and the righmost record of its left neighbour
+	 * to find out whether this is a miss or va belongs to an address
+	 * space area found there.
+	 *
+	 */
+	
+	/* First, search the leaf node itself. */
+	btree_key_t i;
+	
+	for (i = 0; i < leaf->keys; i++) {
+		area = (as_area_t *) leaf->value[i];
+		
+		mutex_lock(&area->lock);
+		
+		if ((area->base <= va) && (va < area->base + area->pages * PAGE_SIZE))
+			return area;
+		
+		mutex_unlock(&area->lock);
+	}
+	
+	/*
+	 * Second, locate the left neighbour and test its last record.
+	 * Because of its position in the B+tree, it must have base < va.
+	 *
+	 */
+	btree_node_t *lnode = btree_leaf_node_left_neighbour(&as->as_area_btree, leaf);
+	if (lnode) {
+		area = (as_area_t *) lnode->value[lnode->keys - 1];
+		
+		mutex_lock(&area->lock);
+		
+		if (va < area->base + area->pages * PAGE_SIZE)
+			return area;
+		
+		mutex_unlock(&area->lock);
+	}
+	
+	return NULL;
 }
 
 /** Find address space area and change it.
  *
- * @param as		Address space.
- * @param address	Virtual address belonging to the area to be changed.
- * 			Must be page-aligned.
- * @param size		New size of the virtual memory block starting at
- * 			address. 
- * @param flags		Flags influencing the remap operation. Currently unused.
- *
- * @return		Zero on success or a value from @ref errno.h otherwise.
- */ 
-int as_area_resize(as_t *as, uintptr_t address, size_t size, int flags)
-{
-	as_area_t *area;
-	ipl_t ipl;
-	size_t pages;
-	
-	ipl = interrupts_disable();
+ * @param as      Address space.
+ * @param address Virtual address belonging to the area to be changed.
+ *                Must be page-aligned.
+ * @param size    New size of the virtual memory block starting at
+ *                address.
+ * @param flags   Flags influencing the remap operation. Currently unused.
+ *
+ * @return Zero on success or a value from @ref errno.h otherwise.
+ *
+ */
+int as_area_resize(as_t *as, uintptr_t address, size_t size, unsigned int flags)
+{
 	mutex_lock(&as->lock);
 	
 	/*
 	 * Locate the area.
-	 */
-	area = find_area_and_lock(as, address);
+	 *
+	 */
+	as_area_t *area = find_area_and_lock(as, address);
 	if (!area) {
 		mutex_unlock(&as->lock);
-		interrupts_restore(ipl);
 		return ENOENT;
 	}
-
+	
 	if (area->backend == &phys_backend) {
 		/*
 		 * Remapping of address space areas associated
 		 * with memory mapped devices is not supported.
+		 *
 		 */
 		mutex_unlock(&area->lock);
 		mutex_unlock(&as->lock);
-		interrupts_restore(ipl);
 		return ENOTSUP;
 	}
+	
 	if (area->sh_info) {
 		/*
-		 * Remapping of shared address space areas 
+		 * Remapping of shared address space areas
 		 * is not supported.
+		 *
 		 */
 		mutex_unlock(&area->lock);
 		mutex_unlock(&as->lock);
-		interrupts_restore(ipl);
 		return ENOTSUP;
 	}
-
-	pages = SIZE2FRAMES((address - area->base) + size);
+	
+	size_t pages = SIZE2FRAMES((address - area->base) + size);
 	if (!pages) {
 		/*
 		 * Zero size address space areas are not allowed.
+		 *
 		 */
 		mutex_unlock(&area->lock);
 		mutex_unlock(&as->lock);
-		interrupts_restore(ipl);
 		return EPERM;
 	}
 	
 	if (pages < area->pages) {
-		bool cond;
 		uintptr_t start_free = area->base + pages * PAGE_SIZE;
-
+		
 		/*
 		 * Shrinking the area.
 		 * No need to check for overlaps.
-		 */
-
+		 *
+		 */
+		
 		page_table_lock(as, false);
-
+		
 		/*
 		 * Start TLB shootdown sequence.
-		 */
-		tlb_shootdown_start(TLB_INVL_PAGES, as->asid, area->base +
-		    pages * PAGE_SIZE, area->pages - pages);
-
+		 *
+		 */
+		ipl_t ipl = tlb_shootdown_start(TLB_INVL_PAGES, as->asid,
+		    area->base + pages * PAGE_SIZE, area->pages - pages);
+		
 		/*
 		 * Remove frames belonging to used space starting from
@@ -437,42 +599,46 @@
 		 * is also the right way to remove part of the used_space
 		 * B+tree leaf list.
-		 */		
-		for (cond = true; cond;) {
-			btree_node_t *node;
-		
+		 *
+		 */
+		bool cond = true;
+		while (cond) {
 			ASSERT(!list_empty(&area->used_space.leaf_head));
-			node = 
+			
+			btree_node_t *node =
 			    list_get_instance(area->used_space.leaf_head.prev,
 			    btree_node_t, leaf_link);
+			
 			if ((cond = (bool) node->keys)) {
-				uintptr_t b = node->key[node->keys - 1];
-				size_t c =
+				uintptr_t ptr = node->key[node->keys - 1];
+				size_t size =
 				    (size_t) node->value[node->keys - 1];
-				unsigned int i = 0;
-			
-				if (overlaps(b, c * PAGE_SIZE, area->base,
+				size_t i = 0;
+				
+				if (overlaps(ptr, size * PAGE_SIZE, area->base,
 				    pages * PAGE_SIZE)) {
 					
-					if (b + c * PAGE_SIZE <= start_free) {
+					if (ptr + size * PAGE_SIZE <= start_free) {
 						/*
 						 * The whole interval fits
 						 * completely in the resized
 						 * address space area.
+						 *
 						 */
 						break;
 					}
-		
+					
 					/*
 					 * Part of the interval corresponding
 					 * to b and c overlaps with the resized
 					 * address space area.
+					 *
 					 */
-		
-					cond = false;	/* we are almost done */
-					i = (start_free - b) >> PAGE_WIDTH;
+					
+					/* We are almost done */
+					cond = false;
+					i = (start_free - ptr) >> PAGE_WIDTH;
 					if (!used_space_remove(area, start_free,
-					    c - i))
-						panic("Cannot remove used "
-						    "space.");
+					    size - i))
+						panic("Cannot remove used space.");
 				} else {
 					/*
@@ -480,154 +646,198 @@
 					 * completely removed.
 					 */
-					if (!used_space_remove(area, b, c))
-						panic("Cannot remove used "
-						    "space.");
+					if (!used_space_remove(area, ptr, size))
+						panic("Cannot remove used space.");
 				}
-			
-				for (; i < c; i++) {
-					pte_t *pte;
-			
-					pte = page_mapping_find(as, b +
+				
+				for (; i < size; i++) {
+					pte_t *pte = page_mapping_find(as, ptr +
 					    i * PAGE_SIZE);
-					ASSERT(pte && PTE_VALID(pte) &&
-					    PTE_PRESENT(pte));
-					if (area->backend &&
-					    area->backend->frame_free) {
+					
+					ASSERT(pte);
+					ASSERT(PTE_VALID(pte));
+					ASSERT(PTE_PRESENT(pte));
+					
+					if ((area->backend) &&
+					    (area->backend->frame_free)) {
 						area->backend->frame_free(area,
-						    b + i * PAGE_SIZE,
+						    ptr + i * PAGE_SIZE,
 						    PTE_GET_FRAME(pte));
 					}
-					page_mapping_remove(as, b +
+					
+					page_mapping_remove(as, ptr +
 					    i * PAGE_SIZE);
 				}
 			}
 		}
-
+		
 		/*
 		 * Finish TLB shootdown sequence.
-		 */
-
+		 *
+		 */
+		
 		tlb_invalidate_pages(as->asid, area->base + pages * PAGE_SIZE,
 		    area->pages - pages);
-
+		
 		/*
 		 * Invalidate software translation caches (e.g. TSB on sparc64).
+		 *
 		 */
 		as_invalidate_translation_cache(as, area->base +
 		    pages * PAGE_SIZE, area->pages - pages);
-		tlb_shootdown_finalize();
-
+		tlb_shootdown_finalize(ipl);
+		
 		page_table_unlock(as, false);
-		
 	} else {
 		/*
 		 * Growing the area.
 		 * Check for overlaps with other address space areas.
+		 *
 		 */
 		if (!check_area_conflicts(as, address, pages * PAGE_SIZE,
 		    area)) {
 			mutex_unlock(&area->lock);
-			mutex_unlock(&as->lock);		
-			interrupts_restore(ipl);
+			mutex_unlock(&as->lock);
 			return EADDRNOTAVAIL;
 		}
-	} 
-
+	}
+	
 	area->pages = pages;
 	
 	mutex_unlock(&area->lock);
 	mutex_unlock(&as->lock);
-	interrupts_restore(ipl);
-
+	
 	return 0;
 }
 
+/** Remove reference to address space area share info.
+ *
+ * If the reference count drops to 0, the sh_info is deallocated.
+ *
+ * @param sh_info Pointer to address space area share info.
+ *
+ */
+NO_TRACE static void sh_info_remove_reference(share_info_t *sh_info)
+{
+	bool dealloc = false;
+	
+	mutex_lock(&sh_info->lock);
+	ASSERT(sh_info->refcount);
+	
+	if (--sh_info->refcount == 0) {
+		dealloc = true;
+		link_t *cur;
+		
+		/*
+		 * Now walk carefully the pagemap B+tree and free/remove
+		 * reference from all frames found there.
+		 */
+		for (cur = sh_info->pagemap.leaf_head.next;
+		    cur != &sh_info->pagemap.leaf_head; cur = cur->next) {
+			btree_node_t *node
+			    = list_get_instance(cur, btree_node_t, leaf_link);
+			btree_key_t i;
+			
+			for (i = 0; i < node->keys; i++)
+				frame_free((uintptr_t) node->value[i]);
+		}
+		
+	}
+	mutex_unlock(&sh_info->lock);
+	
+	if (dealloc) {
+		btree_destroy(&sh_info->pagemap);
+		free(sh_info);
+	}
+}
+
 /** Destroy address space area.
  *
- * @param as		Address space.
- * @param address	Address within the area to be deleted.
- *
- * @return		Zero on success or a value from @ref errno.h on failure.
+ * @param as      Address space.
+ * @param address Address within the area to be deleted.
+ *
+ * @return Zero on success or a value from @ref errno.h on failure.
+ *
  */
 int as_area_destroy(as_t *as, uintptr_t address)
 {
-	as_area_t *area;
-	uintptr_t base;
-	link_t *cur;
-	ipl_t ipl;
-
-	ipl = interrupts_disable();
 	mutex_lock(&as->lock);
-
-	area = find_area_and_lock(as, address);
+	
+	as_area_t *area = find_area_and_lock(as, address);
 	if (!area) {
 		mutex_unlock(&as->lock);
-		interrupts_restore(ipl);
 		return ENOENT;
 	}
-
-	base = area->base;
-
+	
+	uintptr_t base = area->base;
+	
 	page_table_lock(as, false);
-
+	
 	/*
 	 * Start TLB shootdown sequence.
 	 */
-	tlb_shootdown_start(TLB_INVL_PAGES, as->asid, area->base, area->pages);
-
+	ipl_t ipl = tlb_shootdown_start(TLB_INVL_PAGES, as->asid, area->base,
+	    area->pages);
+	
 	/*
 	 * Visit only the pages mapped by used_space B+tree.
 	 */
+	link_t *cur;
 	for (cur = area->used_space.leaf_head.next;
 	    cur != &area->used_space.leaf_head; cur = cur->next) {
 		btree_node_t *node;
-		unsigned int i;
+		btree_key_t i;
 		
 		node = list_get_instance(cur, btree_node_t, leaf_link);
 		for (i = 0; i < node->keys; i++) {
-			uintptr_t b = node->key[i];
-			size_t j;
-			pte_t *pte;
+			uintptr_t ptr = node->key[i];
+			size_t size;
 			
-			for (j = 0; j < (size_t) node->value[i]; j++) {
-				pte = page_mapping_find(as, b + j * PAGE_SIZE);
-				ASSERT(pte && PTE_VALID(pte) &&
-				    PTE_PRESENT(pte));
-				if (area->backend &&
-				    area->backend->frame_free) {
-					area->backend->frame_free(area,	b +
-					    j * PAGE_SIZE, PTE_GET_FRAME(pte));
+			for (size = 0; size < (size_t) node->value[i]; size++) {
+				pte_t *pte = page_mapping_find(as, ptr + size * PAGE_SIZE);
+				
+				ASSERT(pte);
+				ASSERT(PTE_VALID(pte));
+				ASSERT(PTE_PRESENT(pte));
+				
+				if ((area->backend) &&
+				    (area->backend->frame_free)) {
+					area->backend->frame_free(area,
+					    ptr + size * PAGE_SIZE, PTE_GET_FRAME(pte));
 				}
-				page_mapping_remove(as, b + j * PAGE_SIZE);				
+				
+				page_mapping_remove(as, ptr + size * PAGE_SIZE);
 			}
 		}
 	}
-
+	
 	/*
 	 * Finish TLB shootdown sequence.
-	 */
-
+	 *
+	 */
+	
 	tlb_invalidate_pages(as->asid, area->base, area->pages);
-
+	
 	/*
 	 * Invalidate potential software translation caches (e.g. TSB on
 	 * sparc64).
+	 *
 	 */
 	as_invalidate_translation_cache(as, area->base, area->pages);
-	tlb_shootdown_finalize();
-
+	tlb_shootdown_finalize(ipl);
+	
 	page_table_unlock(as, false);
 	
 	btree_destroy(&area->used_space);
-
+	
 	area->attributes |= AS_AREA_ATTR_PARTIAL;
 	
 	if (area->sh_info)
 		sh_info_remove_reference(area->sh_info);
-		
+	
 	mutex_unlock(&area->lock);
-
+	
 	/*
 	 * Remove the empty area from address space.
+	 *
 	 */
 	btree_remove(&as->as_area_btree, base, NULL);
@@ -636,5 +846,4 @@
 	
 	mutex_unlock(&as->lock);
-	interrupts_restore(ipl);
 	return 0;
 }
@@ -647,76 +856,69 @@
  * sh_info of the source area. The process of duplicating the
  * mapping is done through the backend share function.
- * 
- * @param src_as	Pointer to source address space.
- * @param src_base	Base address of the source address space area.
- * @param acc_size	Expected size of the source area.
- * @param dst_as	Pointer to destination address space.
- * @param dst_base	Target base address.
+ *
+ * @param src_as         Pointer to source address space.
+ * @param src_base       Base address of the source address space area.
+ * @param acc_size       Expected size of the source area.
+ * @param dst_as         Pointer to destination address space.
+ * @param dst_base       Target base address.
  * @param dst_flags_mask Destination address space area flags mask.
  *
- * @return		Zero on success or ENOENT if there is no such task or if
- * 			there is no such address space area, EPERM if there was
- * 			a problem in accepting the area or ENOMEM if there was a
- * 			problem in allocating destination address space area.
- * 			ENOTSUP is returned if the address space area backend
- * 			does not support sharing.
+ * @return Zero on success.
+ * @return ENOENT if there is no such task or such address space.
+ * @return EPERM if there was a problem in accepting the area.
+ * @return ENOMEM if there was a problem in allocating destination
+ *         address space area.
+ * @return ENOTSUP if the address space area backend does not support
+ *         sharing.
+ *
  */
 int as_area_share(as_t *src_as, uintptr_t src_base, size_t acc_size,
-    as_t *dst_as, uintptr_t dst_base, int dst_flags_mask)
-{
-	ipl_t ipl;
-	int src_flags;
-	size_t src_size;
-	as_area_t *src_area, *dst_area;
-	share_info_t *sh_info;
-	mem_backend_t *src_backend;
-	mem_backend_data_t src_backend_data;
-	
-	ipl = interrupts_disable();
+    as_t *dst_as, uintptr_t dst_base, unsigned int dst_flags_mask)
+{
 	mutex_lock(&src_as->lock);
-	src_area = find_area_and_lock(src_as, src_base);
+	as_area_t *src_area = find_area_and_lock(src_as, src_base);
 	if (!src_area) {
 		/*
 		 * Could not find the source address space area.
+		 *
 		 */
 		mutex_unlock(&src_as->lock);
-		interrupts_restore(ipl);
 		return ENOENT;
 	}
-
-	if (!src_area->backend || !src_area->backend->share) {
+	
+	if ((!src_area->backend) || (!src_area->backend->share)) {
 		/*
 		 * There is no backend or the backend does not
 		 * know how to share the area.
+		 *
 		 */
 		mutex_unlock(&src_area->lock);
 		mutex_unlock(&src_as->lock);
-		interrupts_restore(ipl);
 		return ENOTSUP;
 	}
 	
-	src_size = src_area->pages * PAGE_SIZE;
-	src_flags = src_area->flags;
-	src_backend = src_area->backend;
-	src_backend_data = src_area->backend_data;
-
+	size_t src_size = src_area->pages * PAGE_SIZE;
+	unsigned int src_flags = src_area->flags;
+	mem_backend_t *src_backend = src_area->backend;
+	mem_backend_data_t src_backend_data = src_area->backend_data;
+	
 	/* Share the cacheable flag from the original mapping */
 	if (src_flags & AS_AREA_CACHEABLE)
 		dst_flags_mask |= AS_AREA_CACHEABLE;
-
-	if (src_size != acc_size ||
-	    (src_flags & dst_flags_mask) != dst_flags_mask) {
+	
+	if ((src_size != acc_size) ||
+	    ((src_flags & dst_flags_mask) != dst_flags_mask)) {
 		mutex_unlock(&src_area->lock);
 		mutex_unlock(&src_as->lock);
-		interrupts_restore(ipl);
 		return EPERM;
 	}
-
+	
 	/*
 	 * Now we are committed to sharing the area.
 	 * First, prepare the area for sharing.
 	 * Then it will be safe to unlock it.
-	 */
-	sh_info = src_area->sh_info;
+	 *
+	 */
+	share_info_t *sh_info = src_area->sh_info;
 	if (!sh_info) {
 		sh_info = (share_info_t *) malloc(sizeof(share_info_t), 0);
@@ -725,6 +927,8 @@
 		btree_create(&sh_info->pagemap);
 		src_area->sh_info = sh_info;
+		
 		/*
 		 * Call the backend to setup sharing.
+		 *
 		 */
 		src_area->backend->share(src_area);
@@ -734,8 +938,8 @@
 		mutex_unlock(&sh_info->lock);
 	}
-
+	
 	mutex_unlock(&src_area->lock);
 	mutex_unlock(&src_as->lock);
-
+	
 	/*
 	 * Create copy of the source address space area.
@@ -745,7 +949,8 @@
 	 * The flags of the source area are masked against dst_flags_mask
 	 * to support sharing in less privileged mode.
-	 */
-	dst_area = as_area_create(dst_as, dst_flags_mask, src_size, dst_base,
-	    AS_AREA_ATTR_PARTIAL, src_backend, &src_backend_data);
+	 *
+	 */
+	as_area_t *dst_area = as_area_create(dst_as, dst_flags_mask, src_size,
+	    dst_base, AS_AREA_ATTR_PARTIAL, src_backend, &src_backend_data);
 	if (!dst_area) {
 		/*
@@ -754,21 +959,19 @@
 		sh_info_remove_reference(sh_info);
 		
-		interrupts_restore(ipl);
 		return ENOMEM;
 	}
-
+	
 	/*
 	 * Now the destination address space area has been
 	 * fully initialized. Clear the AS_AREA_ATTR_PARTIAL
 	 * attribute and set the sh_info.
-	 */	
-	mutex_lock(&dst_as->lock);	
+	 *
+	 */
+	mutex_lock(&dst_as->lock);
 	mutex_lock(&dst_area->lock);
 	dst_area->attributes &= ~AS_AREA_ATTR_PARTIAL;
 	dst_area->sh_info = sh_info;
 	mutex_unlock(&dst_area->lock);
-	mutex_unlock(&dst_as->lock);	
-
-	interrupts_restore(ipl);
+	mutex_unlock(&dst_as->lock);
 	
 	return 0;
@@ -777,13 +980,12 @@
 /** Check access mode for address space area.
  *
- * The address space area must be locked prior to this call.
- *
- * @param area		Address space area.
- * @param access	Access mode.
- *
- * @return		False if access violates area's permissions, true
- * 			otherwise.
- */
-bool as_area_check_access(as_area_t *area, pf_access_t access)
+ * @param area   Address space area.
+ * @param access Access mode.
+ *
+ * @return False if access violates area's permissions, true
+ *         otherwise.
+ *
+ */
+NO_TRACE bool as_area_check_access(as_area_t *area, pf_access_t access)
 {
 	int flagmap[] = {
@@ -793,8 +995,36 @@
 	};
 
+	ASSERT(mutex_locked(&area->lock));
+	
 	if (!(area->flags & flagmap[access]))
 		return false;
 	
 	return true;
+}
+
+/** Convert address space area flags to page flags.
+ *
+ * @param aflags Flags of some address space area.
+ *
+ * @return Flags to be passed to page_mapping_insert().
+ *
+ */
+NO_TRACE static unsigned int area_flags_to_page_flags(unsigned int aflags)
+{
+	unsigned int flags = PAGE_USER | PAGE_PRESENT;
+	
+	if (aflags & AS_AREA_READ)
+		flags |= PAGE_READ;
+		
+	if (aflags & AS_AREA_WRITE)
+		flags |= PAGE_WRITE;
+	
+	if (aflags & AS_AREA_EXEC)
+		flags |= PAGE_EXEC;
+	
+	if (aflags & AS_AREA_CACHEABLE)
+		flags |= PAGE_CACHEABLE;
+	
+	return flags;
 }
 
@@ -813,27 +1043,17 @@
  *
  */
-int as_area_change_flags(as_t *as, int flags, uintptr_t address)
-{
-	as_area_t *area;
-	link_t *cur;
-	ipl_t ipl;
-	int page_flags;
-	uintptr_t *old_frame;
-	size_t frame_idx;
-	size_t used_pages;
-	
+int as_area_change_flags(as_t *as, unsigned int flags, uintptr_t address)
+{
 	/* Flags for the new memory mapping */
-	page_flags = area_flags_to_page_flags(flags);
-
-	ipl = interrupts_disable();
+	unsigned int page_flags = area_flags_to_page_flags(flags);
+	
 	mutex_lock(&as->lock);
-
-	area = find_area_and_lock(as, address);
+	
+	as_area_t *area = find_area_and_lock(as, address);
 	if (!area) {
 		mutex_unlock(&as->lock);
-		interrupts_restore(ipl);
 		return ENOENT;
 	}
-
+	
 	if ((area->sh_info) || (area->backend != &anon_backend)) {
 		/* Copying shared areas not supported yet */
@@ -841,67 +1061,73 @@
 		mutex_unlock(&area->lock);
 		mutex_unlock(&as->lock);
-		interrupts_restore(ipl);
 		return ENOTSUP;
 	}
-
+	
 	/*
 	 * Compute total number of used pages in the used_space B+tree
-	 */
-	used_pages = 0;
-
+	 *
+	 */
+	size_t used_pages = 0;
+	link_t *cur;
+	
 	for (cur = area->used_space.leaf_head.next;
 	    cur != &area->used_space.leaf_head; cur = cur->next) {
-		btree_node_t *node;
-		unsigned int i;
-		
-		node = list_get_instance(cur, btree_node_t, leaf_link);
-		for (i = 0; i < node->keys; i++) {
+		btree_node_t *node
+		    = list_get_instance(cur, btree_node_t, leaf_link);
+		btree_key_t i;
+		
+		for (i = 0; i < node->keys; i++)
 			used_pages += (size_t) node->value[i];
-		}
-	}
-
+	}
+	
 	/* An array for storing frame numbers */
-	old_frame = malloc(used_pages * sizeof(uintptr_t), 0);
-
+	uintptr_t *old_frame = malloc(used_pages * sizeof(uintptr_t), 0);
+	
 	page_table_lock(as, false);
-
+	
 	/*
 	 * Start TLB shootdown sequence.
-	 */
-	tlb_shootdown_start(TLB_INVL_PAGES, as->asid, area->base, area->pages);
-
+	 *
+	 */
+	ipl_t ipl = tlb_shootdown_start(TLB_INVL_PAGES, as->asid, area->base,
+	    area->pages);
+	
 	/*
 	 * Remove used pages from page tables and remember their frame
 	 * numbers.
-	 */
-	frame_idx = 0;
-
+	 *
+	 */
+	size_t frame_idx = 0;
+	
 	for (cur = area->used_space.leaf_head.next;
 	    cur != &area->used_space.leaf_head; cur = cur->next) {
-		btree_node_t *node;
-		unsigned int i;
-		
-		node = list_get_instance(cur, btree_node_t, leaf_link);
+		btree_node_t *node
+		    = list_get_instance(cur, btree_node_t, leaf_link);
+		btree_key_t i;
+		
 		for (i = 0; i < node->keys; i++) {
-			uintptr_t b = node->key[i];
-			size_t j;
-			pte_t *pte;
+			uintptr_t ptr = node->key[i];
+			size_t size;
 			
-			for (j = 0; j < (size_t) node->value[i]; j++) {
-				pte = page_mapping_find(as, b + j * PAGE_SIZE);
-				ASSERT(pte && PTE_VALID(pte) &&
-				    PTE_PRESENT(pte));
+			for (size = 0; size < (size_t) node->value[i]; size++) {
+				pte_t *pte = page_mapping_find(as, ptr + size * PAGE_SIZE);
+				
+				ASSERT(pte);
+				ASSERT(PTE_VALID(pte));
+				ASSERT(PTE_PRESENT(pte));
+				
 				old_frame[frame_idx++] = PTE_GET_FRAME(pte);
-
+				
 				/* Remove old mapping */
-				page_mapping_remove(as, b + j * PAGE_SIZE);
+				page_mapping_remove(as, ptr + size * PAGE_SIZE);
 			}
 		}
 	}
-
+	
 	/*
 	 * Finish TLB shootdown sequence.
-	 */
-
+	 *
+	 */
+	
 	tlb_invalidate_pages(as->asid, area->base, area->pages);
 	
@@ -909,15 +1135,16 @@
 	 * Invalidate potential software translation caches (e.g. TSB on
 	 * sparc64).
+	 *
 	 */
 	as_invalidate_translation_cache(as, area->base, area->pages);
-	tlb_shootdown_finalize();
-
+	tlb_shootdown_finalize(ipl);
+	
 	page_table_unlock(as, false);
-
+	
 	/*
 	 * Set the new flags.
 	 */
 	area->flags = flags;
-
+	
 	/*
 	 * Map pages back in with new flags. This step is kept separate
@@ -926,36 +1153,34 @@
 	 */
 	frame_idx = 0;
-
+	
 	for (cur = area->used_space.leaf_head.next;
 	    cur != &area->used_space.leaf_head; cur = cur->next) {
-		btree_node_t *node;
-		unsigned int i;
-		
-		node = list_get_instance(cur, btree_node_t, leaf_link);
+		btree_node_t *node
+		    = list_get_instance(cur, btree_node_t, leaf_link);
+		btree_key_t i;
+		
 		for (i = 0; i < node->keys; i++) {
-			uintptr_t b = node->key[i];
-			size_t j;
+			uintptr_t ptr = node->key[i];
+			size_t size;
 			
-			for (j = 0; j < (size_t) node->value[i]; j++) {
+			for (size = 0; size < (size_t) node->value[i]; size++) {
 				page_table_lock(as, false);
-
+				
 				/* Insert the new mapping */
-				page_mapping_insert(as, b + j * PAGE_SIZE,
+				page_mapping_insert(as, ptr + size * PAGE_SIZE,
 				    old_frame[frame_idx++], page_flags);
-
+				
 				page_table_unlock(as, false);
 			}
 		}
 	}
-
+	
 	free(old_frame);
-
+	
 	mutex_unlock(&area->lock);
 	mutex_unlock(&as->lock);
-	interrupts_restore(ipl);
-
+	
 	return 0;
 }
-
 
 /** Handle page fault within the current address space.
@@ -967,18 +1192,17 @@
  * Interrupts are assumed disabled.
  *
- * @param page		Faulting page.
- * @param access	Access mode that caused the page fault (i.e.
- * 			read/write/exec).
- * @param istate	Pointer to the interrupted state.
- *
- * @return		AS_PF_FAULT on page fault, AS_PF_OK on success or
- * 			AS_PF_DEFER if the fault was caused by copy_to_uspace()
- * 			or copy_from_uspace().
+ * @param page   Faulting page.
+ * @param access Access mode that caused the page fault (i.e.
+ *               read/write/exec).
+ * @param istate Pointer to the interrupted state.
+ *
+ * @return AS_PF_FAULT on page fault.
+ * @return AS_PF_OK on success.
+ * @return AS_PF_DEFER if the fault was caused by copy_to_uspace()
+ *         or copy_from_uspace().
+ *
  */
 int as_page_fault(uintptr_t page, pf_access_t access, istate_t *istate)
 {
-	pte_t *pte;
-	as_area_t *area;
-	
 	if (!THREAD)
 		return AS_PF_FAULT;
@@ -988,14 +1212,15 @@
 	
 	mutex_lock(&AS->lock);
-	area = find_area_and_lock(AS, page);
+	as_area_t *area = find_area_and_lock(AS, page);
 	if (!area) {
 		/*
 		 * No area contained mapping for 'page'.
 		 * Signal page fault to low-level handler.
+		 *
 		 */
 		mutex_unlock(&AS->lock);
 		goto page_fault;
 	}
-
+	
 	if (area->attributes & AS_AREA_ATTR_PARTIAL) {
 		/*
@@ -1005,17 +1230,18 @@
 		mutex_unlock(&area->lock);
 		mutex_unlock(&AS->lock);
-		goto page_fault;		
-	}
-
-	if (!area->backend || !area->backend->page_fault) {
+		goto page_fault;
+	}
+	
+	if ((!area->backend) || (!area->backend->page_fault)) {
 		/*
 		 * The address space area is not backed by any backend
 		 * or the backend cannot handle page faults.
+		 *
 		 */
 		mutex_unlock(&area->lock);
 		mutex_unlock(&AS->lock);
-		goto page_fault;		
-	}
-
+		goto page_fault;
+	}
+	
 	page_table_lock(AS, false);
 	
@@ -1023,5 +1249,7 @@
 	 * To avoid race condition between two page faults on the same address,
 	 * we need to make sure the mapping has not been already inserted.
-	 */
+	 *
+	 */
+	pte_t *pte;
 	if ((pte = page_mapping_find(AS, page))) {
 		if (PTE_PRESENT(pte)) {
@@ -1039,4 +1267,5 @@
 	/*
 	 * Resort to the backend page fault handler.
+	 *
 	 */
 	if (area->backend->page_fault(area, page, access) != AS_PF_OK) {
@@ -1051,5 +1280,5 @@
 	mutex_unlock(&AS->lock);
 	return AS_PF_OK;
-
+	
 page_fault:
 	if (THREAD->in_copy_from_uspace) {
@@ -1064,5 +1293,5 @@
 		return AS_PF_FAULT;
 	}
-
+	
 	return AS_PF_DEFER;
 }
@@ -1076,6 +1305,7 @@
  * When this function is enetered, no spinlocks may be held.
  *
- * @param old		Old address space or NULL.
- * @param new		New address space.
+ * @param old Old address space or NULL.
+ * @param new New address space.
+ *
  */
 void as_switch(as_t *old_as, as_t *new_as)
@@ -1083,12 +1313,14 @@
 	DEADLOCK_PROBE_INIT(p_asidlock);
 	preemption_disable();
+	
 retry:
 	(void) interrupts_disable();
 	if (!spinlock_trylock(&asidlock)) {
-		/* 
+		/*
 		 * Avoid deadlock with TLB shootdown.
 		 * We can enable interrupts here because
 		 * preemption is disabled. We should not be
 		 * holding any other lock.
+		 *
 		 */
 		(void) interrupts_enable();
@@ -1097,11 +1329,12 @@
 	}
 	preemption_enable();
-
+	
 	/*
 	 * First, take care of the old address space.
-	 */	
+	 */
 	if (old_as) {
 		ASSERT(old_as->cpu_refcount);
-		if((--old_as->cpu_refcount == 0) && (old_as != AS_KERNEL)) {
+		
+		if ((--old_as->cpu_refcount == 0) && (old_as != AS_KERNEL)) {
 			/*
 			 * The old address space is no longer active on
@@ -1109,19 +1342,23 @@
 			 * list of inactive address spaces with assigned
 			 * ASID.
+			 *
 			 */
 			ASSERT(old_as->asid != ASID_INVALID);
+			
 			list_append(&old_as->inactive_as_with_asid_link,
 			    &inactive_as_with_asid_head);
 		}
-
+		
 		/*
 		 * Perform architecture-specific tasks when the address space
 		 * is being removed from the CPU.
+		 *
 		 */
 		as_deinstall_arch(old_as);
 	}
-
+	
 	/*
 	 * Second, prepare the new address space.
+	 *
 	 */
 	if ((new_as->cpu_refcount++ == 0) && (new_as != AS_KERNEL)) {
@@ -1131,4 +1368,5 @@
 			new_as->asid = asid_get();
 	}
+	
 #ifdef AS_PAGE_TABLE
 	SET_PTL0_ADDRESS(new_as->genarch.page_table);
@@ -1138,7 +1376,8 @@
 	 * Perform architecture-specific steps.
 	 * (e.g. write ASID to hardware register etc.)
+	 *
 	 */
 	as_install_arch(new_as);
-
+	
 	spinlock_unlock(&asidlock);
 	
@@ -1146,43 +1385,16 @@
 }
 
-/** Convert address space area flags to page flags.
- *
- * @param aflags	Flags of some address space area.
- *
- * @return		Flags to be passed to page_mapping_insert().
- */
-int area_flags_to_page_flags(int aflags)
-{
-	int flags;
-
-	flags = PAGE_USER | PAGE_PRESENT;
-	
-	if (aflags & AS_AREA_READ)
-		flags |= PAGE_READ;
-		
-	if (aflags & AS_AREA_WRITE)
-		flags |= PAGE_WRITE;
-	
-	if (aflags & AS_AREA_EXEC)
-		flags |= PAGE_EXEC;
-	
-	if (aflags & AS_AREA_CACHEABLE)
-		flags |= PAGE_CACHEABLE;
-		
-	return flags;
-}
-
 /** Compute flags for virtual address translation subsytem.
  *
- * The address space area must be locked.
- * Interrupts must be disabled.
- *
- * @param a		Address space area.
- *
- * @return		Flags to be used in page_mapping_insert().
- */
-int as_area_get_flags(as_area_t *a)
-{
-	return area_flags_to_page_flags(a->flags);
+ * @param area Address space area.
+ *
+ * @return Flags to be used in page_mapping_insert().
+ *
+ */
+NO_TRACE unsigned int as_area_get_flags(as_area_t *area)
+{
+	ASSERT(mutex_locked(&area->lock));
+
+	return area_flags_to_page_flags(area->flags);
 }
 
@@ -1192,10 +1404,11 @@
  * table.
  *
- * @param flags		Flags saying whether the page table is for the kernel
- * 			address space.
- *
- * @return		First entry of the page table.
- */
-pte_t *page_table_create(int flags)
+ * @param flags Flags saying whether the page table is for the kernel
+ *              address space.
+ *
+ * @return First entry of the page table.
+ *
+ */
+NO_TRACE pte_t *page_table_create(unsigned int flags)
 {
 	ASSERT(as_operations);
@@ -1209,7 +1422,8 @@
  * Destroy page table in architecture specific way.
  *
- * @param page_table	Physical address of PTL0.
- */
-void page_table_destroy(pte_t *page_table)
+ * @param page_table Physical address of PTL0.
+ *
+ */
+NO_TRACE void page_table_destroy(pte_t *page_table)
 {
 	ASSERT(as_operations);
@@ -1223,13 +1437,14 @@
  * This function should be called before any page_mapping_insert(),
  * page_mapping_remove() and page_mapping_find().
- * 
+ *
  * Locking order is such that address space areas must be locked
  * prior to this call. Address space can be locked prior to this
  * call in which case the lock argument is false.
  *
- * @param as		Address space.
- * @param lock		If false, do not attempt to lock as->lock.
- */
-void page_table_lock(as_t *as, bool lock)
+ * @param as   Address space.
+ * @param lock If false, do not attempt to lock as->lock.
+ *
+ */
+NO_TRACE void page_table_lock(as_t *as, bool lock)
 {
 	ASSERT(as_operations);
@@ -1241,8 +1456,9 @@
 /** Unlock page table.
  *
- * @param as		Address space.
- * @param unlock	If false, do not attempt to unlock as->lock.
- */
-void page_table_unlock(as_t *as, bool unlock)
+ * @param as     Address space.
+ * @param unlock If false, do not attempt to unlock as->lock.
+ *
+ */
+NO_TRACE void page_table_unlock(as_t *as, bool unlock)
 {
 	ASSERT(as_operations);
@@ -1252,169 +1468,41 @@
 }
 
-
-/** Find address space area and lock it.
- *
- * The address space must be locked and interrupts must be disabled.
- *
- * @param as		Address space.
- * @param va		Virtual address.
- *
- * @return		Locked address space area containing va on success or
- * 			NULL on failure.
- */
-as_area_t *find_area_and_lock(as_t *as, uintptr_t va)
-{
-	as_area_t *a;
-	btree_node_t *leaf, *lnode;
-	unsigned int i;
-	
-	a = (as_area_t *) btree_search(&as->as_area_btree, va, &leaf);
-	if (a) {
-		/* va is the base address of an address space area */
-		mutex_lock(&a->lock);
-		return a;
-	}
-	
-	/*
-	 * Search the leaf node and the righmost record of its left neighbour
-	 * to find out whether this is a miss or va belongs to an address
-	 * space area found there.
-	 */
-	
-	/* First, search the leaf node itself. */
-	for (i = 0; i < leaf->keys; i++) {
-		a = (as_area_t *) leaf->value[i];
-		mutex_lock(&a->lock);
-		if ((a->base <= va) && (va < a->base + a->pages * PAGE_SIZE)) {
-			return a;
-		}
-		mutex_unlock(&a->lock);
-	}
-
-	/*
-	 * Second, locate the left neighbour and test its last record.
-	 * Because of its position in the B+tree, it must have base < va.
-	 */
-	lnode = btree_leaf_node_left_neighbour(&as->as_area_btree, leaf);
-	if (lnode) {
-		a = (as_area_t *) lnode->value[lnode->keys - 1];
-		mutex_lock(&a->lock);
-		if (va < a->base + a->pages * PAGE_SIZE) {
-			return a;
-		}
-		mutex_unlock(&a->lock);
-	}
-
-	return NULL;
-}
-
-/** Check area conflicts with other areas.
- *
- * The address space must be locked and interrupts must be disabled.
- *
- * @param as		Address space.
- * @param va		Starting virtual address of the area being tested.
- * @param size		Size of the area being tested.
- * @param avoid_area	Do not touch this area. 
- *
- * @return		True if there is no conflict, false otherwise.
- */
-bool
-check_area_conflicts(as_t *as, uintptr_t va, size_t size, as_area_t *avoid_area)
-{
-	as_area_t *a;
-	btree_node_t *leaf, *node;
-	unsigned int i;
-	
-	/*
-	 * We don't want any area to have conflicts with NULL page.
-	 */
-	if (overlaps(va, size, NULL, PAGE_SIZE))
-		return false;
-	
-	/*
-	 * The leaf node is found in O(log n), where n is proportional to
-	 * the number of address space areas belonging to as.
-	 * The check for conflicts is then attempted on the rightmost
-	 * record in the left neighbour, the leftmost record in the right
-	 * neighbour and all records in the leaf node itself.
-	 */
-	
-	if ((a = (as_area_t *) btree_search(&as->as_area_btree, va, &leaf))) {
-		if (a != avoid_area)
-			return false;
-	}
-	
-	/* First, check the two border cases. */
-	if ((node = btree_leaf_node_left_neighbour(&as->as_area_btree, leaf))) {
-		a = (as_area_t *) node->value[node->keys - 1];
-		mutex_lock(&a->lock);
-		if (overlaps(va, size, a->base, a->pages * PAGE_SIZE)) {
-			mutex_unlock(&a->lock);
-			return false;
-		}
-		mutex_unlock(&a->lock);
-	}
-	node = btree_leaf_node_right_neighbour(&as->as_area_btree, leaf);
-	if (node) {
-		a = (as_area_t *) node->value[0];
-		mutex_lock(&a->lock);
-		if (overlaps(va, size, a->base, a->pages * PAGE_SIZE)) {
-			mutex_unlock(&a->lock);
-			return false;
-		}
-		mutex_unlock(&a->lock);
-	}
-	
-	/* Second, check the leaf node. */
-	for (i = 0; i < leaf->keys; i++) {
-		a = (as_area_t *) leaf->value[i];
-	
-		if (a == avoid_area)
-			continue;
-	
-		mutex_lock(&a->lock);
-		if (overlaps(va, size, a->base, a->pages * PAGE_SIZE)) {
-			mutex_unlock(&a->lock);
-			return false;
-		}
-		mutex_unlock(&a->lock);
-	}
-
-	/*
-	 * So far, the area does not conflict with other areas.
-	 * Check if it doesn't conflict with kernel address space.
-	 */	 
-	if (!KERNEL_ADDRESS_SPACE_SHADOWED) {
-		return !overlaps(va, size, 
-		    KERNEL_ADDRESS_SPACE_START,
-		    KERNEL_ADDRESS_SPACE_END - KERNEL_ADDRESS_SPACE_START);
-	}
-
-	return true;
+/** Test whether page tables are locked.
+ *
+ * @param as Address space where the page tables belong.
+ *
+ * @return True if the page tables belonging to the address soace
+ *         are locked, otherwise false.
+ */
+NO_TRACE bool page_table_locked(as_t *as)
+{
+	ASSERT(as_operations);
+	ASSERT(as_operations->page_table_locked);
+
+	return as_operations->page_table_locked(as);
 }
 
 /** Return size of the address space area with given base.
  *
- * @param base		Arbitrary address insede the address space area.
- *
- * @return		Size of the address space area in bytes or zero if it
- *			does not exist.
+ * @param base Arbitrary address inside the address space area.
+ *
+ * @return Size of the address space area in bytes or zero if it
+ *         does not exist.
+ *
  */
 size_t as_area_get_size(uintptr_t base)
 {
-	ipl_t ipl;
-	as_area_t *src_area;
 	size_t size;
-
-	ipl = interrupts_disable();
-	src_area = find_area_and_lock(AS, base);
+	
+	page_table_lock(AS, true);
+	as_area_t *src_area = find_area_and_lock(AS, base);
+	
 	if (src_area) {
 		size = src_area->pages * PAGE_SIZE;
 		mutex_unlock(&src_area->lock);
-	} else {
+	} else
 		size = 0;
-	}
-	interrupts_restore(ipl);
+	
+	page_table_unlock(AS, true);
 	return size;
 }
@@ -1424,33 +1512,33 @@
  * The address space area must be already locked.
  *
- * @param a		Address space area.
- * @param page		First page to be marked.
- * @param count		Number of page to be marked.
- *
- * @return		Zero on failure and non-zero on success.
- */
-int used_space_insert(as_area_t *a, uintptr_t page, size_t count)
-{
-	btree_node_t *leaf, *node;
-	size_t pages;
-	unsigned int i;
-
+ * @param area  Address space area.
+ * @param page  First page to be marked.
+ * @param count Number of page to be marked.
+ *
+ * @return Zero on failure and non-zero on success.
+ *
+ */
+int used_space_insert(as_area_t *area, uintptr_t page, size_t count)
+{
+	ASSERT(mutex_locked(&area->lock));
 	ASSERT(page == ALIGN_DOWN(page, PAGE_SIZE));
 	ASSERT(count);
-
-	pages = (size_t) btree_search(&a->used_space, page, &leaf);
+	
+	btree_node_t *leaf;
+	size_t pages = (size_t) btree_search(&area->used_space, page, &leaf);
 	if (pages) {
 		/*
 		 * We hit the beginning of some used space.
+		 *
 		 */
 		return 0;
 	}
-
+	
 	if (!leaf->keys) {
-		btree_insert(&a->used_space, page, (void *) count, leaf);
+		btree_insert(&area->used_space, page, (void *) count, leaf);
 		return 1;
 	}
-
-	node = btree_leaf_node_left_neighbour(&a->used_space, leaf);
+	
+	btree_node_t *node = btree_leaf_node_left_neighbour(&area->used_space, leaf);
 	if (node) {
 		uintptr_t left_pg = node->key[node->keys - 1];
@@ -1463,6 +1551,7 @@
 		 * somewhere between the rightmost interval of
 		 * the left neigbour and the first interval of the leaf.
-		 */
-		 
+		 *
+		 */
+		
 		if (page >= right_pg) {
 			/* Do nothing. */
@@ -1474,5 +1563,5 @@
 		    right_cnt * PAGE_SIZE)) {
 			/* The interval intersects with the right interval. */
-			return 0;			
+			return 0;
 		} else if ((page == left_pg + left_cnt * PAGE_SIZE) &&
 		    (page + count * PAGE_SIZE == right_pg)) {
@@ -1480,12 +1569,14 @@
 			 * The interval can be added by merging the two already
 			 * present intervals.
+			 *
 			 */
 			node->value[node->keys - 1] += count + right_cnt;
-			btree_remove(&a->used_space, right_pg, leaf);
-			return 1; 
+			btree_remove(&area->used_space, right_pg, leaf);
+			return 1;
 		} else if (page == left_pg + left_cnt * PAGE_SIZE) {
-			/* 
+			/*
 			 * The interval can be added by simply growing the left
 			 * interval.
+			 *
 			 */
 			node->value[node->keys - 1] += count;
@@ -1496,4 +1587,5 @@
 			 * the right interval down and increasing its size
 			 * accordingly.
+			 *
 			 */
 			leaf->value[0] += count;
@@ -1504,6 +1596,7 @@
 			 * The interval is between both neigbouring intervals,
 			 * but cannot be merged with any of them.
+			 *
 			 */
-			btree_insert(&a->used_space, page, (void *) count,
+			btree_insert(&area->used_space, page, (void *) count,
 			    leaf);
 			return 1;
@@ -1512,10 +1605,11 @@
 		uintptr_t right_pg = leaf->key[0];
 		size_t right_cnt = (size_t) leaf->value[0];
-	
+		
 		/*
 		 * Investigate the border case in which the left neighbour does
 		 * not exist but the interval fits from the left.
-		 */
-		 
+		 *
+		 */
+		
 		if (overlaps(page, count * PAGE_SIZE, right_pg,
 		    right_cnt * PAGE_SIZE)) {
@@ -1527,4 +1621,5 @@
 			 * right interval down and increasing its size
 			 * accordingly.
+			 *
 			 */
 			leaf->key[0] = page;
@@ -1535,12 +1630,13 @@
 			 * The interval doesn't adjoin with the right interval.
 			 * It must be added individually.
+			 *
 			 */
-			btree_insert(&a->used_space, page, (void *) count,
+			btree_insert(&area->used_space, page, (void *) count,
 			    leaf);
 			return 1;
 		}
 	}
-
-	node = btree_leaf_node_right_neighbour(&a->used_space, leaf);
+	
+	node = btree_leaf_node_right_neighbour(&area->used_space, leaf);
 	if (node) {
 		uintptr_t left_pg = leaf->key[leaf->keys - 1];
@@ -1553,6 +1649,7 @@
 		 * somewhere between the leftmost interval of
 		 * the right neigbour and the last interval of the leaf.
-		 */
-
+		 *
+		 */
+		
 		if (page < left_pg) {
 			/* Do nothing. */
@@ -1564,5 +1661,5 @@
 		    right_cnt * PAGE_SIZE)) {
 			/* The interval intersects with the right interval. */
-			return 0;			
+			return 0;
 		} else if ((page == left_pg + left_cnt * PAGE_SIZE) &&
 		    (page + count * PAGE_SIZE == right_pg)) {
@@ -1570,13 +1667,15 @@
 			 * The interval can be added by merging the two already
 			 * present intervals.
-			 * */
+			 *
+			 */
 			leaf->value[leaf->keys - 1] += count + right_cnt;
-			btree_remove(&a->used_space, right_pg, node);
-			return 1; 
+			btree_remove(&area->used_space, right_pg, node);
+			return 1;
 		} else if (page == left_pg + left_cnt * PAGE_SIZE) {
 			/*
 			 * The interval can be added by simply growing the left
 			 * interval.
-			 * */
+			 *
+			 */
 			leaf->value[leaf->keys - 1] +=  count;
 			return 1;
@@ -1586,4 +1685,5 @@
 			 * the right interval down and increasing its size
 			 * accordingly.
+			 *
 			 */
 			node->value[0] += count;
@@ -1594,6 +1694,7 @@
 			 * The interval is between both neigbouring intervals,
 			 * but cannot be merged with any of them.
+			 *
 			 */
-			btree_insert(&a->used_space, page, (void *) count,
+			btree_insert(&area->used_space, page, (void *) count,
 			    leaf);
 			return 1;
@@ -1602,10 +1703,11 @@
 		uintptr_t left_pg = leaf->key[leaf->keys - 1];
 		size_t left_cnt = (size_t) leaf->value[leaf->keys - 1];
-	
+		
 		/*
 		 * Investigate the border case in which the right neighbour
 		 * does not exist but the interval fits from the right.
-		 */
-		 
+		 *
+		 */
+		
 		if (overlaps(page, count * PAGE_SIZE, left_pg,
 		    left_cnt * PAGE_SIZE)) {
@@ -1616,4 +1718,5 @@
 			 * The interval can be added by growing the left
 			 * interval.
+			 *
 			 */
 			leaf->value[leaf->keys - 1] += count;
@@ -1623,6 +1726,7 @@
 			 * The interval doesn't adjoin with the left interval.
 			 * It must be added individually.
+			 *
 			 */
-			btree_insert(&a->used_space, page, (void *) count,
+			btree_insert(&area->used_space, page, (void *) count,
 			    leaf);
 			return 1;
@@ -1634,5 +1738,7 @@
 	 * only between two other intervals of the leaf. The two border cases
 	 * were already resolved.
-	 */
+	 *
+	 */
+	btree_key_t i;
 	for (i = 1; i < leaf->keys; i++) {
 		if (page < leaf->key[i]) {
@@ -1641,9 +1747,10 @@
 			size_t left_cnt = (size_t) leaf->value[i - 1];
 			size_t right_cnt = (size_t) leaf->value[i];
-
+			
 			/*
 			 * The interval fits between left_pg and right_pg.
+			 *
 			 */
-
+			
 			if (overlaps(page, count * PAGE_SIZE, left_pg,
 			    left_cnt * PAGE_SIZE)) {
@@ -1651,4 +1758,5 @@
 				 * The interval intersects with the left
 				 * interval.
+				 *
 				 */
 				return 0;
@@ -1658,6 +1766,7 @@
 				 * The interval intersects with the right
 				 * interval.
+				 *
 				 */
-				return 0;			
+				return 0;
 			} else if ((page == left_pg + left_cnt * PAGE_SIZE) &&
 			    (page + count * PAGE_SIZE == right_pg)) {
@@ -1665,12 +1774,14 @@
 				 * The interval can be added by merging the two
 				 * already present intervals.
+				 *
 				 */
 				leaf->value[i - 1] += count + right_cnt;
-				btree_remove(&a->used_space, right_pg, leaf);
-				return 1; 
+				btree_remove(&area->used_space, right_pg, leaf);
+				return 1;
 			} else if (page == left_pg + left_cnt * PAGE_SIZE) {
 				/*
 				 * The interval can be added by simply growing
 				 * the left interval.
+				 *
 				 */
 				leaf->value[i - 1] += count;
@@ -1678,8 +1789,9 @@
 			} else if (page + count * PAGE_SIZE == right_pg) {
 				/*
-			         * The interval can be addded by simply moving
+				 * The interval can be addded by simply moving
 				 * base of the right interval down and
 				 * increasing its size accordingly.
-			 	 */
+				 *
+				 */
 				leaf->value[i] += count;
 				leaf->key[i] = page;
@@ -1690,6 +1802,7 @@
 				 * intervals, but cannot be merged with any of
 				 * them.
+				 *
 				 */
-				btree_insert(&a->used_space, page,
+				btree_insert(&area->used_space, page,
 				    (void *) count, leaf);
 				return 1;
@@ -1697,5 +1810,5 @@
 		}
 	}
-
+	
 	panic("Inconsistency detected while adding %" PRIs " pages of used "
 	    "space at %p.", count, page);
@@ -1706,28 +1819,28 @@
  * The address space area must be already locked.
  *
- * @param a		Address space area.
- * @param page		First page to be marked.
- * @param count		Number of page to be marked.
- *
- * @return		Zero on failure and non-zero on success.
- */
-int used_space_remove(as_area_t *a, uintptr_t page, size_t count)
-{
-	btree_node_t *leaf, *node;
-	size_t pages;
-	unsigned int i;
-
+ * @param area  Address space area.
+ * @param page  First page to be marked.
+ * @param count Number of page to be marked.
+ *
+ * @return Zero on failure and non-zero on success.
+ *
+ */
+int used_space_remove(as_area_t *area, uintptr_t page, size_t count)
+{
+	ASSERT(mutex_locked(&area->lock));
 	ASSERT(page == ALIGN_DOWN(page, PAGE_SIZE));
 	ASSERT(count);
-
-	pages = (size_t) btree_search(&a->used_space, page, &leaf);
+	
+	btree_node_t *leaf;
+	size_t pages = (size_t) btree_search(&area->used_space, page, &leaf);
 	if (pages) {
 		/*
 		 * We are lucky, page is the beginning of some interval.
+		 *
 		 */
 		if (count > pages) {
 			return 0;
 		} else if (count == pages) {
-			btree_remove(&a->used_space, page, leaf);
+			btree_remove(&area->used_space, page, leaf);
 			return 1;
 		} else {
@@ -1735,5 +1848,7 @@
 			 * Find the respective interval.
 			 * Decrease its size and relocate its start address.
+			 *
 			 */
+			btree_key_t i;
 			for (i = 0; i < leaf->keys; i++) {
 				if (leaf->key[i] == page) {
@@ -1746,10 +1861,10 @@
 		}
 	}
-
-	node = btree_leaf_node_left_neighbour(&a->used_space, leaf);
-	if (node && page < leaf->key[0]) {
+	
+	btree_node_t *node = btree_leaf_node_left_neighbour(&area->used_space, leaf);
+	if ((node) && (page < leaf->key[0])) {
 		uintptr_t left_pg = node->key[node->keys - 1];
 		size_t left_cnt = (size_t) node->value[node->keys - 1];
-
+		
 		if (overlaps(left_pg, left_cnt * PAGE_SIZE, page,
 		    count * PAGE_SIZE)) {
@@ -1761,4 +1876,5 @@
 				 * removed by updating the size of the bigger
 				 * interval.
+				 *
 				 */
 				node->value[node->keys - 1] -= count;
@@ -1766,6 +1882,4 @@
 			} else if (page + count * PAGE_SIZE <
 			    left_pg + left_cnt*PAGE_SIZE) {
-				size_t new_cnt;
-				
 				/*
 				 * The interval is contained in the rightmost
@@ -1774,9 +1888,10 @@
 				 * the original interval and also inserting a
 				 * new interval.
+				 *
 				 */
-				new_cnt = ((left_pg + left_cnt * PAGE_SIZE) -
+				size_t new_cnt = ((left_pg + left_cnt * PAGE_SIZE) -
 				    (page + count*PAGE_SIZE)) >> PAGE_WIDTH;
 				node->value[node->keys - 1] -= count + new_cnt;
-				btree_insert(&a->used_space, page +
+				btree_insert(&area->used_space, page +
 				    count * PAGE_SIZE, (void *) new_cnt, leaf);
 				return 1;
@@ -1784,15 +1899,14 @@
 		}
 		return 0;
-	} else if (page < leaf->key[0]) {
+	} else if (page < leaf->key[0])
 		return 0;
-	}
 	
 	if (page > leaf->key[leaf->keys - 1]) {
 		uintptr_t left_pg = leaf->key[leaf->keys - 1];
 		size_t left_cnt = (size_t) leaf->value[leaf->keys - 1];
-
+		
 		if (overlaps(left_pg, left_cnt * PAGE_SIZE, page,
 		    count * PAGE_SIZE)) {
-			if (page + count * PAGE_SIZE == 
+			if (page + count * PAGE_SIZE ==
 			    left_pg + left_cnt * PAGE_SIZE) {
 				/*
@@ -1800,4 +1914,5 @@
 				 * interval of the leaf and can be removed by
 				 * updating the size of the bigger interval.
+				 *
 				 */
 				leaf->value[leaf->keys - 1] -= count;
@@ -1805,6 +1920,4 @@
 			} else if (page + count * PAGE_SIZE < left_pg +
 			    left_cnt * PAGE_SIZE) {
-				size_t new_cnt;
-				
 				/*
 				 * The interval is contained in the rightmost
@@ -1813,9 +1926,10 @@
 				 * original interval and also inserting a new
 				 * interval.
+				 *
 				 */
-				new_cnt = ((left_pg + left_cnt * PAGE_SIZE) -
+				size_t new_cnt = ((left_pg + left_cnt * PAGE_SIZE) -
 				    (page + count * PAGE_SIZE)) >> PAGE_WIDTH;
 				leaf->value[leaf->keys - 1] -= count + new_cnt;
-				btree_insert(&a->used_space, page +
+				btree_insert(&area->used_space, page +
 				    count * PAGE_SIZE, (void *) new_cnt, leaf);
 				return 1;
@@ -1823,5 +1937,5 @@
 		}
 		return 0;
-	}	
+	}
 	
 	/*
@@ -1829,9 +1943,10 @@
 	 * Now the interval can be only between intervals of the leaf. 
 	 */
+	btree_key_t i;
 	for (i = 1; i < leaf->keys - 1; i++) {
 		if (page < leaf->key[i]) {
 			uintptr_t left_pg = leaf->key[i - 1];
 			size_t left_cnt = (size_t) leaf->value[i - 1];
-
+			
 			/*
 			 * Now the interval is between intervals corresponding
@@ -1847,4 +1962,5 @@
 					 * be removed by updating the size of
 					 * the bigger interval.
+					 *
 					 */
 					leaf->value[i - 1] -= count;
@@ -1852,6 +1968,4 @@
 				} else if (page + count * PAGE_SIZE <
 				    left_pg + left_cnt * PAGE_SIZE) {
-					size_t new_cnt;
-				
 					/*
 					 * The interval is contained in the
@@ -1861,10 +1975,10 @@
 					 * also inserting a new interval.
 					 */
-					new_cnt = ((left_pg +
+					size_t new_cnt = ((left_pg +
 					    left_cnt * PAGE_SIZE) -
 					    (page + count * PAGE_SIZE)) >>
 					    PAGE_WIDTH;
 					leaf->value[i - 1] -= count + new_cnt;
-					btree_insert(&a->used_space, page +
+					btree_insert(&area->used_space, page +
 					    count * PAGE_SIZE, (void *) new_cnt,
 					    leaf);
@@ -1875,5 +1989,5 @@
 		}
 	}
-
+	
 error:
 	panic("Inconsistency detected while removing %" PRIs " pages of used "
@@ -1881,43 +1995,4 @@
 }
 
-/** Remove reference to address space area share info.
- *
- * If the reference count drops to 0, the sh_info is deallocated.
- *
- * @param sh_info	Pointer to address space area share info.
- */
-void sh_info_remove_reference(share_info_t *sh_info)
-{
-	bool dealloc = false;
-
-	mutex_lock(&sh_info->lock);
-	ASSERT(sh_info->refcount);
-	if (--sh_info->refcount == 0) {
-		dealloc = true;
-		link_t *cur;
-		
-		/*
-		 * Now walk carefully the pagemap B+tree and free/remove
-		 * reference from all frames found there.
-		 */
-		for (cur = sh_info->pagemap.leaf_head.next;
-		    cur != &sh_info->pagemap.leaf_head; cur = cur->next) {
-			btree_node_t *node;
-			unsigned int i;
-			
-			node = list_get_instance(cur, btree_node_t, leaf_link);
-			for (i = 0; i < node->keys; i++) 
-				frame_free((uintptr_t) node->value[i]);
-		}
-		
-	}
-	mutex_unlock(&sh_info->lock);
-	
-	if (dealloc) {
-		btree_destroy(&sh_info->pagemap);
-		free(sh_info);
-	}
-}
-
 /*
  * Address space related syscalls.
@@ -1925,5 +2000,5 @@
 
 /** Wrapper for as_area_create(). */
-unative_t sys_as_area_create(uintptr_t address, size_t size, int flags)
+unative_t sys_as_area_create(uintptr_t address, size_t size, unsigned int flags)
 {
 	if (as_area_create(AS, flags | AS_AREA_CACHEABLE, size, address,
@@ -1935,5 +2010,5 @@
 
 /** Wrapper for as_area_resize(). */
-unative_t sys_as_area_resize(uintptr_t address, size_t size, int flags)
+unative_t sys_as_area_resize(uintptr_t address, size_t size, unsigned int flags)
 {
 	return (unative_t) as_area_resize(AS, address, size, 0);
@@ -1941,5 +2016,5 @@
 
 /** Wrapper for as_area_change_flags(). */
-unative_t sys_as_area_change_flags(uintptr_t address, int flags)
+unative_t sys_as_area_change_flags(uintptr_t address, unsigned int flags)
 {
 	return (unative_t) as_area_change_flags(AS, flags, address);
@@ -1954,77 +2029,66 @@
 /** Get list of adress space areas.
  *
- * @param as		Address space.
- * @param obuf		Place to save pointer to returned buffer.
- * @param osize		Place to save size of returned buffer.
+ * @param as    Address space.
+ * @param obuf  Place to save pointer to returned buffer.
+ * @param osize Place to save size of returned buffer.
+ *
  */
 void as_get_area_info(as_t *as, as_area_info_t **obuf, size_t *osize)
 {
-	ipl_t ipl;
-	size_t area_cnt, area_idx, i;
+	mutex_lock(&as->lock);
+	
+	/* First pass, count number of areas. */
+	
+	size_t area_cnt = 0;
 	link_t *cur;
-
-	as_area_info_t *info;
-	size_t isize;
-
-	ipl = interrupts_disable();
-	mutex_lock(&as->lock);
-
-	/* First pass, count number of areas. */
-
-	area_cnt = 0;
-
+	
 	for (cur = as->as_area_btree.leaf_head.next;
 	    cur != &as->as_area_btree.leaf_head; cur = cur->next) {
-		btree_node_t *node;
-
-		node = list_get_instance(cur, btree_node_t, leaf_link);
+		btree_node_t *node =
+		    list_get_instance(cur, btree_node_t, leaf_link);
 		area_cnt += node->keys;
 	}
-
-        isize = area_cnt * sizeof(as_area_info_t);
-	info = malloc(isize, 0);
-
+	
+	size_t isize = area_cnt * sizeof(as_area_info_t);
+	as_area_info_t *info = malloc(isize, 0);
+	
 	/* Second pass, record data. */
-
-	area_idx = 0;
-
+	
+	size_t area_idx = 0;
+	
 	for (cur = as->as_area_btree.leaf_head.next;
 	    cur != &as->as_area_btree.leaf_head; cur = cur->next) {
-		btree_node_t *node;
-
-		node = list_get_instance(cur, btree_node_t, leaf_link);
-
+		btree_node_t *node =
+		    list_get_instance(cur, btree_node_t, leaf_link);
+		btree_key_t i;
+		
 		for (i = 0; i < node->keys; i++) {
 			as_area_t *area = node->value[i];
-
+			
 			ASSERT(area_idx < area_cnt);
 			mutex_lock(&area->lock);
-
+			
 			info[area_idx].start_addr = area->base;
 			info[area_idx].size = FRAMES2SIZE(area->pages);
 			info[area_idx].flags = area->flags;
 			++area_idx;
-
+			
 			mutex_unlock(&area->lock);
 		}
 	}
-
+	
 	mutex_unlock(&as->lock);
-	interrupts_restore(ipl);
-
+	
 	*obuf = info;
 	*osize = isize;
 }
 
-
 /** Print out information about address space.
  *
- * @param as		Address space.
+ * @param as Address space.
+ *
  */
 void as_print(as_t *as)
 {
-	ipl_t ipl;
-	
-	ipl = interrupts_disable();
 	mutex_lock(&as->lock);
 	
@@ -2033,12 +2097,11 @@
 	for (cur = as->as_area_btree.leaf_head.next;
 	    cur != &as->as_area_btree.leaf_head; cur = cur->next) {
-		btree_node_t *node;
-		
-		node = list_get_instance(cur, btree_node_t, leaf_link);
-		
-		unsigned int i;
+		btree_node_t *node
+		    = list_get_instance(cur, btree_node_t, leaf_link);
+		btree_key_t i;
+		
 		for (i = 0; i < node->keys; i++) {
 			as_area_t *area = node->value[i];
-		
+			
 			mutex_lock(&area->lock);
 			printf("as_area: %p, base=%p, pages=%" PRIs
@@ -2050,5 +2113,4 @@
 	
 	mutex_unlock(&as->lock);
-	interrupts_restore(ipl);
 }
 
Index: kernel/generic/src/mm/backend_anon.c
===================================================================
--- kernel/generic/src/mm/backend_anon.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/generic/src/mm/backend_anon.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -79,4 +79,7 @@
 {
 	uintptr_t frame;
+
+	ASSERT(page_table_locked(AS));
+	ASSERT(mutex_locked(&area->lock));
 
 	if (!as_area_check_access(area, access))
@@ -168,4 +171,7 @@
 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));
+
 	frame_free(frame);
 }
@@ -183,4 +189,7 @@
 {
 	link_t *cur;
+
+	ASSERT(mutex_locked(&area->as->lock));
+	ASSERT(mutex_locked(&area->lock));
 
 	/*
Index: kernel/generic/src/mm/backend_elf.c
===================================================================
--- kernel/generic/src/mm/backend_elf.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/generic/src/mm/backend_elf.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -86,4 +86,7 @@
 	bool dirty = false;
 
+	ASSERT(page_table_locked(AS));
+	ASSERT(mutex_locked(&area->lock));
+
 	if (!as_area_check_access(area, access))
 		return AS_PF_FAULT;
@@ -235,6 +238,10 @@
 	uintptr_t start_anon;
 
-	ASSERT((page >= ALIGN_DOWN(entry->p_vaddr, PAGE_SIZE)) &&
-	    (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;
 
@@ -263,6 +270,4 @@
  * are put into the pagemap.
  *
- * The address space and address space area must be locked prior to the call.
- *
  * @param area		Address space area.
  */
@@ -273,4 +278,7 @@
 	btree_node_t *leaf, *node;
 	uintptr_t start_anon = entry->p_vaddr + entry->p_filesz;
+
+	ASSERT(mutex_locked(&area->as->lock));
+	ASSERT(mutex_locked(&area->lock));
 
 	/*
Index: kernel/generic/src/mm/backend_phys.c
===================================================================
--- kernel/generic/src/mm/backend_phys.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/generic/src/mm/backend_phys.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -72,4 +72,7 @@
 	uintptr_t base = area->backend_data.base;
 
+	ASSERT(page_table_locked(AS));
+	ASSERT(mutex_locked(&area->lock));
+
 	if (!as_area_check_access(area, access))
 		return AS_PF_FAULT;
@@ -93,4 +96,6 @@
 void phys_share(as_area_t *area)
 {
+	ASSERT(mutex_locked(&area->as->lock));
+	ASSERT(mutex_locked(&area->lock));
 }
 
Index: kernel/generic/src/mm/frame.c
===================================================================
--- kernel/generic/src/mm/frame.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/generic/src/mm/frame.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -66,8 +66,8 @@
  * available.
  */
-mutex_t mem_avail_mtx;
-condvar_t mem_avail_cv;
-size_t mem_avail_req = 0;  /**< Number of frames requested. */
-size_t mem_avail_gen = 0;  /**< Generation counter. */
+static mutex_t mem_avail_mtx;
+static condvar_t mem_avail_cv;
+static size_t mem_avail_req = 0;  /**< Number of frames requested. */
+static size_t mem_avail_gen = 0;  /**< Generation counter. */
 
 /********************/
@@ -75,20 +75,20 @@
 /********************/
 
-static inline size_t frame_index(zone_t *zone, frame_t *frame)
+NO_TRACE static inline size_t frame_index(zone_t *zone, frame_t *frame)
 {
 	return (size_t) (frame - zone->frames);
 }
 
-static inline size_t frame_index_abs(zone_t *zone, frame_t *frame)
+NO_TRACE static inline size_t frame_index_abs(zone_t *zone, frame_t *frame)
 {
 	return (size_t) (frame - zone->frames) + zone->base;
 }
 
-static inline bool frame_index_valid(zone_t *zone, size_t index)
+NO_TRACE static inline bool frame_index_valid(zone_t *zone, size_t index)
 {
 	return (index < zone->count);
 }
 
-static inline size_t make_frame_index(zone_t *zone, frame_t *frame)
+NO_TRACE static inline size_t make_frame_index(zone_t *zone, frame_t *frame)
 {
 	return (frame - zone->frames);
@@ -100,5 +100,5 @@
  *
  */
-static void frame_initialize(frame_t *frame)
+NO_TRACE static void frame_initialize(frame_t *frame)
 {
 	frame->refcount = 1;
@@ -121,5 +121,6 @@
  *
  */
-static size_t zones_insert_zone(pfn_t base, size_t count)
+NO_TRACE static size_t zones_insert_zone(pfn_t base, size_t count,
+    zone_flags_t flags)
 {
 	if (zones.count + 1 == ZONES_MAX) {
@@ -131,7 +132,23 @@
 	for (i = 0; i < zones.count; i++) {
 		/* Check for overlap */
-		if (overlaps(base, count,
-		    zones.info[i].base, zones.info[i].count)) {
-			printf("Zones overlap!\n");
+		if (overlaps(zones.info[i].base, zones.info[i].count,
+		    base, count)) {
+			
+			/*
+			 * If the overlaping zones are of the same type
+			 * and the new zone is completely within the previous
+			 * one, then quietly ignore the new zone.
+			 *
+			 */
+			
+			if ((zones.info[i].flags != flags) ||
+			    (!iswithin(zones.info[i].base, zones.info[i].count,
+			    base, count))) {
+				printf("Zone (%p, %p) overlaps with previous zone (%p, %p)!\n",
+				    PFN2ADDR(base), PFN2ADDR(count),
+				    PFN2ADDR(zones.info[i].base),
+				    PFN2ADDR(zones.info[i].count));
+			}
+			
 			return (size_t) -1;
 		}
@@ -144,6 +161,7 @@
 	for (j = zones.count; j > i; j--) {
 		zones.info[j] = zones.info[j - 1];
-		zones.info[j].buddy_system->data =
-		    (void *) &zones.info[j - 1];
+		if (zones.info[j].buddy_system != NULL)
+			zones.info[j].buddy_system->data =
+			    (void *) &zones.info[j];
 	}
 	
@@ -162,5 +180,5 @@
  */
 #ifdef CONFIG_DEBUG
-static size_t total_frames_free(void)
+NO_TRACE static size_t total_frames_free(void)
 {
 	size_t total = 0;
@@ -171,5 +189,5 @@
 	return total;
 }
-#endif
+#endif /* CONFIG_DEBUG */
 
 /** Find a zone with a given frames.
@@ -185,5 +203,5 @@
  *
  */
-size_t find_zone(pfn_t frame, size_t count, size_t hint)
+NO_TRACE size_t find_zone(pfn_t frame, size_t count, size_t hint)
 {
 	if (hint >= zones.count)
@@ -199,4 +217,5 @@
 		if (i >= zones.count)
 			i = 0;
+		
 	} while (i != hint);
 	
@@ -205,5 +224,5 @@
 
 /** @return True if zone can allocate specified order */
-static bool zone_can_alloc(zone_t *zone, uint8_t order)
+NO_TRACE static bool zone_can_alloc(zone_t *zone, uint8_t order)
 {
 	return (zone_flags_available(zone->flags)
@@ -221,5 +240,6 @@
  *
  */
-static size_t find_free_zone(uint8_t order, zone_flags_t flags, size_t hint)
+NO_TRACE static size_t find_free_zone(uint8_t order, zone_flags_t flags,
+    size_t hint)
 {
 	if (hint >= zones.count)
@@ -242,4 +262,5 @@
 		if (i >= zones.count)
 			i = 0;
+		
 	} while (i != hint);
 	
@@ -260,6 +281,6 @@
  *
  */
-static link_t *zone_buddy_find_block(buddy_system_t *buddy, link_t *child,
-    uint8_t order)
+NO_TRACE static link_t *zone_buddy_find_block(buddy_system_t *buddy,
+    link_t *child, uint8_t order)
 {
 	frame_t *frame = list_get_instance(child, frame_t, buddy_link);
@@ -283,5 +304,6 @@
  *
  */
-static link_t *zone_buddy_find_buddy(buddy_system_t *buddy, link_t *block) 
+NO_TRACE static link_t *zone_buddy_find_buddy(buddy_system_t *buddy,
+    link_t *block)
 {
 	frame_t *frame = list_get_instance(block, frame_t, buddy_link);
@@ -296,5 +318,5 @@
 		index = (frame_index(zone, frame)) +
 		    (1 << frame->buddy_order);
-	} else {	/* is_right */
+	} else {  /* is_right */
 		index = (frame_index(zone, frame)) -
 		    (1 << frame->buddy_order);
@@ -319,5 +341,5 @@
  *
  */
-static link_t *zone_buddy_bisect(buddy_system_t *buddy, link_t *block)
+NO_TRACE static link_t *zone_buddy_bisect(buddy_system_t *buddy, link_t *block)
 {
 	frame_t *frame_l = list_get_instance(block, frame_t, buddy_link);
@@ -337,6 +359,6 @@
  *
  */
-static link_t *zone_buddy_coalesce(buddy_system_t *buddy, link_t *block_1,
-    link_t *block_2)
+NO_TRACE static link_t *zone_buddy_coalesce(buddy_system_t *buddy,
+    link_t *block_1, link_t *block_2)
 {
 	frame_t *frame1 = list_get_instance(block_1, frame_t, buddy_link);
@@ -353,5 +375,5 @@
  *
  */
-static void zone_buddy_set_order(buddy_system_t *buddy, link_t *block,
+NO_TRACE static void zone_buddy_set_order(buddy_system_t *buddy, link_t *block,
     uint8_t order)
 {
@@ -367,5 +389,6 @@
  *
  */
-static uint8_t zone_buddy_get_order(buddy_system_t *buddy, link_t *block)
+NO_TRACE static uint8_t zone_buddy_get_order(buddy_system_t *buddy,
+    link_t *block)
 {
 	return list_get_instance(block, frame_t, buddy_link)->buddy_order;
@@ -378,5 +401,5 @@
  *
  */
-static void zone_buddy_mark_busy(buddy_system_t *buddy, link_t * block)
+NO_TRACE static void zone_buddy_mark_busy(buddy_system_t *buddy, link_t *block)
 {
 	list_get_instance(block, frame_t, buddy_link)->refcount = 1;
@@ -387,6 +410,8 @@
  * @param buddy Buddy system.
  * @param block Buddy system block.
- */
-static void zone_buddy_mark_available(buddy_system_t *buddy, link_t *block)
+ *
+ */
+NO_TRACE static void zone_buddy_mark_available(buddy_system_t *buddy,
+    link_t *block)
 {
 	list_get_instance(block, frame_t, buddy_link)->refcount = 0;
@@ -419,5 +444,5 @@
  *
  */
-static pfn_t zone_frame_alloc(zone_t *zone, uint8_t order)
+NO_TRACE static pfn_t zone_frame_alloc(zone_t *zone, uint8_t order)
 {
 	ASSERT(zone_flags_available(zone->flags));
@@ -447,5 +472,5 @@
  *
  */
-static void zone_frame_free(zone_t *zone, size_t frame_idx)
+NO_TRACE static void zone_frame_free(zone_t *zone, size_t frame_idx)
 {
 	ASSERT(zone_flags_available(zone->flags));
@@ -468,5 +493,5 @@
 
 /** Return frame from zone. */
-static frame_t *zone_get_frame(zone_t *zone, size_t frame_idx)
+NO_TRACE static frame_t *zone_get_frame(zone_t *zone, size_t frame_idx)
 {
 	ASSERT(frame_idx < zone->count);
@@ -475,5 +500,5 @@
 
 /** Mark frame in zone unavailable to allocation. */
-static void zone_mark_unavailable(zone_t *zone, size_t frame_idx)
+NO_TRACE static void zone_mark_unavailable(zone_t *zone, size_t frame_idx)
 {
 	ASSERT(zone_flags_available(zone->flags));
@@ -504,5 +529,6 @@
  *
  */
-static void zone_merge_internal(size_t z1, size_t z2, zone_t *old_z1, buddy_system_t *buddy)
+NO_TRACE static void zone_merge_internal(size_t z1, size_t z2, zone_t *old_z1,
+    buddy_system_t *buddy)
 {
 	ASSERT(zone_flags_available(zones.info[z1].flags));
@@ -600,5 +626,5 @@
  *
  */
-static void return_config_frames(size_t znum, pfn_t pfn, size_t count)
+NO_TRACE static void return_config_frames(size_t znum, pfn_t pfn, size_t count)
 {
 	ASSERT(zone_flags_available(zones.info[znum].flags));
@@ -635,5 +661,6 @@
  *
  */
-static void zone_reduce_region(size_t znum, pfn_t frame_idx, size_t count)
+NO_TRACE static void zone_reduce_region(size_t znum, pfn_t frame_idx,
+    size_t count)
 {
 	ASSERT(zone_flags_available(zones.info[znum].flags));
@@ -673,6 +700,5 @@
 bool zone_merge(size_t z1, size_t z2)
 {
-	ipl_t ipl = interrupts_disable();
-	spinlock_lock(&zones.lock);
+	irq_spinlock_lock(&zones.lock, true);
 	
 	bool ret = true;
@@ -737,6 +763,7 @@
 	for (i = z2 + 1; i < zones.count; i++) {
 		zones.info[i - 1] = zones.info[i];
-		zones.info[i - 1].buddy_system->data =
-		    (void *) &zones.info[i - 1];
+		if (zones.info[i - 1].buddy_system != NULL)
+			zones.info[i - 1].buddy_system->data =
+			    (void *) &zones.info[i - 1];
 	}
 	
@@ -744,6 +771,5 @@
 	
 errout:
-	spinlock_unlock(&zones.lock);
-	interrupts_restore(ipl);
+	irq_spinlock_unlock(&zones.lock, true);
 	
 	return ret;
@@ -777,5 +803,6 @@
  *
  */
-static void zone_construct(zone_t *zone, buddy_system_t *buddy, pfn_t start, size_t count, zone_flags_t flags)
+NO_TRACE static void zone_construct(zone_t *zone, buddy_system_t *buddy,
+    pfn_t start, size_t count, zone_flags_t flags)
 {
 	zone->base = start;
@@ -820,5 +847,5 @@
  *
  */
-uintptr_t zone_conf_size(size_t count)
+size_t zone_conf_size(size_t count)
 {
 	return (count * sizeof(frame_t) + buddy_conf_size(fnzb(count)));
@@ -841,8 +868,8 @@
  *
  */
-size_t zone_create(pfn_t start, size_t count, pfn_t confframe, zone_flags_t flags)
-{
-	ipl_t ipl = interrupts_disable();
-	spinlock_lock(&zones.lock);
+size_t zone_create(pfn_t start, size_t count, pfn_t confframe,
+    zone_flags_t flags)
+{
+	irq_spinlock_lock(&zones.lock, true);
 	
 	if (zone_flags_available(flags)) {  /* Create available zone */
@@ -887,8 +914,7 @@
 		}
 		
-		size_t znum = zones_insert_zone(start, count);
+		size_t znum = zones_insert_zone(start, count, flags);
 		if (znum == (size_t) -1) {
-			spinlock_unlock(&zones.lock);
-			interrupts_restore(ipl);
+			irq_spinlock_unlock(&zones.lock, true);
 			return (size_t) -1;
 		}
@@ -905,6 +931,5 @@
 		}
 		
-		spinlock_unlock(&zones.lock);
-		interrupts_restore(ipl);
+		irq_spinlock_unlock(&zones.lock, true);
 		
 		return znum;
@@ -912,14 +937,12 @@
 	
 	/* Non-available zone */
-	size_t znum = zones_insert_zone(start, count);
+	size_t znum = zones_insert_zone(start, count, flags);
 	if (znum == (size_t) -1) {
-		spinlock_unlock(&zones.lock);
-		interrupts_restore(ipl);
+		irq_spinlock_unlock(&zones.lock, true);
 		return (size_t) -1;
 	}
 	zone_construct(&zones.info[znum], NULL, start, count, flags);
 	
-	spinlock_unlock(&zones.lock);
-	interrupts_restore(ipl);
+	irq_spinlock_unlock(&zones.lock, true);
 	
 	return znum;
@@ -933,6 +956,5 @@
 void frame_set_parent(pfn_t pfn, void *data, size_t hint)
 {
-	ipl_t ipl = interrupts_disable();
-	spinlock_lock(&zones.lock);
+	irq_spinlock_lock(&zones.lock, true);
 	
 	size_t znum = find_zone(pfn, 1, hint);
@@ -943,12 +965,10 @@
 	    pfn - zones.info[znum].base)->parent = data;
 	
-	spinlock_unlock(&zones.lock);
-	interrupts_restore(ipl);
+	irq_spinlock_unlock(&zones.lock, true);
 }
 
 void *frame_get_parent(pfn_t pfn, size_t hint)
 {
-	ipl_t ipl = interrupts_disable();
-	spinlock_lock(&zones.lock);
+	irq_spinlock_lock(&zones.lock, true);
 	
 	size_t znum = find_zone(pfn, 1, hint);
@@ -959,6 +979,5 @@
 	    pfn - zones.info[znum].base)->parent;
 	
-	spinlock_unlock(&zones.lock);
-	interrupts_restore(ipl);
+	irq_spinlock_unlock(&zones.lock, true);
 	
 	return res;
@@ -977,10 +996,8 @@
 {
 	size_t size = ((size_t) 1) << order;
-	ipl_t ipl;
 	size_t hint = pzone ? (*pzone) : 0;
 	
 loop:
-	ipl = interrupts_disable();
-	spinlock_lock(&zones.lock);
+	irq_spinlock_lock(&zones.lock, true);
 	
 	/*
@@ -993,11 +1010,7 @@
 	   if it does not help, reclaim all */
 	if ((znum == (size_t) -1) && (!(flags & FRAME_NO_RECLAIM))) {
-		spinlock_unlock(&zones.lock);
-		interrupts_restore(ipl);
-		
+		irq_spinlock_unlock(&zones.lock, true);
 		size_t freed = slab_reclaim(0);
-		
-		ipl = interrupts_disable();
-		spinlock_lock(&zones.lock);
+		irq_spinlock_lock(&zones.lock, true);
 		
 		if (freed > 0)
@@ -1006,11 +1019,7 @@
 		
 		if (znum == (size_t) -1) {
-			spinlock_unlock(&zones.lock);
-			interrupts_restore(ipl);
-			
+			irq_spinlock_unlock(&zones.lock, true);
 			freed = slab_reclaim(SLAB_RECLAIM_ALL);
-			
-			ipl = interrupts_disable();
-			spinlock_lock(&zones.lock);
+			irq_spinlock_lock(&zones.lock, true);
 			
 			if (freed > 0)
@@ -1022,6 +1031,5 @@
 	if (znum == (size_t) -1) {
 		if (flags & FRAME_ATOMIC) {
-			spinlock_unlock(&zones.lock);
-			interrupts_restore(ipl);
+			irq_spinlock_unlock(&zones.lock, true);
 			return NULL;
 		}
@@ -1031,7 +1039,6 @@
 #endif
 		
-		spinlock_unlock(&zones.lock);
-		interrupts_restore(ipl);
-
+		irq_spinlock_unlock(&zones.lock, true);
+		
 		if (!THREAD)
 			panic("Cannot wait for memory to become available.");
@@ -1069,6 +1076,5 @@
 	    + zones.info[znum].base;
 	
-	spinlock_unlock(&zones.lock);
-	interrupts_restore(ipl);
+	irq_spinlock_unlock(&zones.lock, true);
 	
 	if (pzone)
@@ -1092,6 +1098,5 @@
 void frame_free(uintptr_t frame)
 {
-	ipl_t ipl = interrupts_disable();
-	spinlock_lock(&zones.lock);
+	irq_spinlock_lock(&zones.lock, true);
 	
 	/*
@@ -1105,6 +1110,5 @@
 	zone_frame_free(&zones.info[znum], pfn - zones.info[znum].base);
 	
-	spinlock_unlock(&zones.lock);
-	interrupts_restore(ipl);
+	irq_spinlock_unlock(&zones.lock, true);
 	
 	/*
@@ -1130,8 +1134,7 @@
  *
  */
-void frame_reference_add(pfn_t pfn)
-{
-	ipl_t ipl = interrupts_disable();
-	spinlock_lock(&zones.lock);
+NO_TRACE void frame_reference_add(pfn_t pfn)
+{
+	irq_spinlock_lock(&zones.lock, true);
 	
 	/*
@@ -1144,13 +1147,13 @@
 	zones.info[znum].frames[pfn - zones.info[znum].base].refcount++;
 	
-	spinlock_unlock(&zones.lock);
-	interrupts_restore(ipl);
-}
-
-/** Mark given range unavailable in frame zones. */
-void frame_mark_unavailable(pfn_t start, size_t count)
-{
-	ipl_t ipl = interrupts_disable();
-	spinlock_lock(&zones.lock);
+	irq_spinlock_unlock(&zones.lock, true);
+}
+
+/** Mark given range unavailable in frame zones.
+ *
+ */
+NO_TRACE void frame_mark_unavailable(pfn_t start, size_t count)
+{
+	irq_spinlock_lock(&zones.lock, true);
 	
 	size_t i;
@@ -1164,14 +1167,15 @@
 	}
 	
-	spinlock_unlock(&zones.lock);
-	interrupts_restore(ipl);
-}
-
-/** Initialize physical memory management. */
+	irq_spinlock_unlock(&zones.lock, true);
+}
+
+/** Initialize physical memory management.
+ *
+ */
 void frame_init(void)
 {
 	if (config.cpu_active == 1) {
 		zones.count = 0;
-		spinlock_initialize(&zones.lock, "zones.lock");
+		irq_spinlock_initialize(&zones.lock, "frame.zones.lock");
 		mutex_initialize(&mem_avail_mtx, MUTEX_ACTIVE);
 		condvar_initialize(&mem_avail_cv);
@@ -1204,9 +1208,10 @@
 }
 
-/** Return total size of all zones. */
+/** Return total size of all zones.
+ *
+ */
 uint64_t zones_total_size(void)
 {
-	ipl_t ipl = interrupts_disable();
-	spinlock_lock(&zones.lock);
+	irq_spinlock_lock(&zones.lock, true);
 	
 	uint64_t total = 0;
@@ -1215,6 +1220,5 @@
 		total += (uint64_t) FRAMES2SIZE(zones.info[i].count);
 	
-	spinlock_unlock(&zones.lock);
-	interrupts_restore(ipl);
+	irq_spinlock_unlock(&zones.lock, true);
 	
 	return total;
@@ -1229,6 +1233,5 @@
 	ASSERT(free != NULL);
 	
-	ipl_t ipl = interrupts_disable();
-	spinlock_lock(&zones.lock);
+	irq_spinlock_lock(&zones.lock, true);
 	
 	*total = 0;
@@ -1248,19 +1251,18 @@
 	}
 	
-	spinlock_unlock(&zones.lock);
-	interrupts_restore(ipl);
-}
-
-/** Prints list of zones. */
+	irq_spinlock_unlock(&zones.lock, true);
+}
+
+/** Prints list of zones.
+ *
+ */
 void zones_print_list(void)
 {
 #ifdef __32_BITS__
-	printf("#  base address frames       flags    free frames  busy frames\n");
-	printf("-- ------------ ------------ -------- ------------ ------------\n");
+	printf("[nr] [base addr] [frames    ] [flags ] [free frames ] [busy frames ]\n");
 #endif
 
 #ifdef __64_BITS__
-	printf("#  base address          frames      flags    free frames  busy frames\n");
-	printf("-- -------------------- ------------ -------- ------------ ------------\n");
+	printf("[nr] [base address    ] [frames    ] [flags ] [free frames ] [busy frames ]\n");
 #endif
 	
@@ -1278,10 +1280,8 @@
 	size_t i;
 	for (i = 0;; i++) {
-		ipl_t ipl = interrupts_disable();
-		spinlock_lock(&zones.lock);
+		irq_spinlock_lock(&zones.lock, true);
 		
 		if (i >= zones.count) {
-			spinlock_unlock(&zones.lock);
-			interrupts_restore(ipl);
+			irq_spinlock_unlock(&zones.lock, true);
 			break;
 		}
@@ -1293,17 +1293,16 @@
 		size_t busy_count = zones.info[i].busy_count;
 		
-		spinlock_unlock(&zones.lock);
-		interrupts_restore(ipl);
+		irq_spinlock_unlock(&zones.lock, true);
 		
 		bool available = zone_flags_available(flags);
 		
-		printf("%-2" PRIs, i);
+		printf("%-4" PRIs, i);
 		
 #ifdef __32_BITS__
-		printf("   %10p", base);
+		printf("  %10p", base);
 #endif
 		
 #ifdef __64_BITS__
-		printf("   %18p", base);
+		printf(" %18p", base);
 #endif
 		
@@ -1314,5 +1313,5 @@
 		
 		if (available)
-			printf("%12" PRIs " %12" PRIs,
+			printf("%14" PRIs " %14" PRIs,
 			    free_count, busy_count);
 		
@@ -1328,6 +1327,5 @@
 void zone_print_one(size_t num)
 {
-	ipl_t ipl = interrupts_disable();
-	spinlock_lock(&zones.lock);
+	irq_spinlock_lock(&zones.lock, true);
 	size_t znum = (size_t) -1;
 	
@@ -1341,6 +1339,5 @@
 	
 	if (znum == (size_t) -1) {
-		spinlock_unlock(&zones.lock);
-		interrupts_restore(ipl);
+		irq_spinlock_unlock(&zones.lock, true);
 		printf("Zone not found.\n");
 		return;
@@ -1353,6 +1350,5 @@
 	size_t busy_count = zones.info[i].busy_count;
 	
-	spinlock_unlock(&zones.lock);
-	interrupts_restore(ipl);
+	irq_spinlock_unlock(&zones.lock, true);
 	
 	bool available = zone_flags_available(flags);
Index: kernel/generic/src/mm/page.c
===================================================================
--- kernel/generic/src/mm/page.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/generic/src/mm/page.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -33,10 +33,11 @@
 /**
  * @file
- * @brief	Virtual Address Translation subsystem.
+ * @brief Virtual Address Translation subsystem.
  *
  * This file contains code for creating, destroying and searching
  * mappings between virtual addresses and physical addresses.
  * Functions here are mere wrappers that call the real implementation.
- * They however, define the single interface. 
+ * They however, define the single interface.
+ *
  */
 
@@ -55,4 +56,5 @@
  * will do an implicit serialization by virtue of running the TLB shootdown
  * interrupt handler.
+ *
  */
 
@@ -83,18 +85,18 @@
  * of page boundaries.
  *
- * @param s		Address of the structure.
- * @param size		Size of the structure.
+ * @param addr Address of the structure.
+ * @param size Size of the structure.
+ *
  */
-void map_structure(uintptr_t s, size_t size)
+void map_structure(uintptr_t addr, size_t size)
 {
-	int i, cnt, length;
-
-	length = size + (s - (s & ~(PAGE_SIZE - 1)));
-	cnt = length / PAGE_SIZE + (length % PAGE_SIZE > 0);
-
+	size_t length = size + (addr - (addr & ~(PAGE_SIZE - 1)));
+	size_t cnt = length / PAGE_SIZE + (length % PAGE_SIZE > 0);
+	
+	size_t i;
 	for (i = 0; i < cnt; i++)
-		page_mapping_insert(AS_KERNEL, s + i * PAGE_SIZE,
-		    s + i * PAGE_SIZE, PAGE_NOT_CACHEABLE | PAGE_WRITE);
-
+		page_mapping_insert(AS_KERNEL, addr + i * PAGE_SIZE,
+		    addr + i * PAGE_SIZE, PAGE_NOT_CACHEABLE | PAGE_WRITE);
+	
 	/* Repel prefetched accesses to the old mapping. */
 	memory_barrier();
@@ -106,17 +108,19 @@
  * using flags. Allocate and setup any missing page tables.
  *
- * The page table must be locked and interrupts must be disabled.
+ * @param as    Address space to wich page belongs.
+ * @param page  Virtual address of the page to be mapped.
+ * @param frame Physical address of memory frame to which the mapping is
+ *              done.
+ * @param flags Flags to be used for mapping.
  *
- * @param as		Address space to wich page belongs.
- * @param page		Virtual address of the page to be mapped.
- * @param frame		Physical address of memory frame to which the mapping is
- * 			done.
- * @param flags		Flags to be used for mapping.
  */
-void page_mapping_insert(as_t *as, uintptr_t page, uintptr_t frame, int flags)
+NO_TRACE void page_mapping_insert(as_t *as, uintptr_t page, uintptr_t frame,
+    unsigned int flags)
 {
+	ASSERT(page_table_locked(as));
+	
 	ASSERT(page_mapping_operations);
 	ASSERT(page_mapping_operations->mapping_insert);
-	
+
 	page_mapping_operations->mapping_insert(as, page, frame, flags);
 	
@@ -131,16 +135,17 @@
  * this call visible.
  *
- * The page table must be locked and interrupts must be disabled.
+ * @param as   Address space to wich page belongs.
+ * @param page Virtual address of the page to be demapped.
  *
- * @param as		Address space to wich page belongs.
- * @param page		Virtual address of the page to be demapped.
  */
-void page_mapping_remove(as_t *as, uintptr_t page)
+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);
 	
 	page_mapping_operations->mapping_remove(as, page);
-
+	
 	/* Repel prefetched accesses to the old mapping. */
 	memory_barrier();
@@ -151,17 +156,18 @@
  * Find mapping for virtual page.
  *
- * The page table must be locked and interrupts must be disabled.
+ * @param as   Address space to wich page belongs.
+ * @param page Virtual page.
  *
- * @param as		Address space to wich page belongs.
- * @param page		Virtual page.
+ * @return NULL if there is no such mapping; requested mapping
+ *         otherwise.
  *
- * @return		NULL if there is no such mapping; requested mapping
- * 			otherwise.
  */
-pte_t *page_mapping_find(as_t *as, uintptr_t page)
+NO_TRACE pte_t *page_mapping_find(as_t *as, uintptr_t page)
 {
+	ASSERT(page_table_locked(as));
+	
 	ASSERT(page_mapping_operations);
 	ASSERT(page_mapping_operations->mapping_find);
-
+	
 	return page_mapping_operations->mapping_find(as, page);
 }
Index: kernel/generic/src/mm/slab.c
===================================================================
--- kernel/generic/src/mm/slab.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/generic/src/mm/slab.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -33,5 +33,5 @@
 /**
  * @file
- * @brief	Slab allocator.
+ * @brief Slab allocator.
  *
  * The slab allocator is closely modelled after OpenSolaris slab allocator.
@@ -50,5 +50,5 @@
  *
  * The slab allocator supports per-CPU caches ('magazines') to facilitate
- * good SMP scaling. 
+ * good SMP scaling.
  *
  * When a new object is being allocated, it is first checked, if it is 
@@ -65,9 +65,9 @@
  * thrashing when somebody is allocating/deallocating 1 item at the magazine
  * size boundary. LIFO order is enforced, which should avoid fragmentation
- * as much as possible. 
- *  
+ * as much as possible.
+ *
  * Every cache contains list of full slabs and list of partially full slabs.
  * Empty slabs are immediately freed (thrashing will be avoided because
- * of magazines). 
+ * of magazines).
  *
  * The slab information structure is kept inside the data area, if possible.
@@ -95,7 +95,8 @@
  *
  * @todo
- * it might be good to add granularity of locks even to slab level,
+ * It might be good to add granularity of locks even to slab level,
  * we could then try_spinlock over all partial slabs and thus improve
- * scalability even on slab level
+ * scalability even on slab level.
+ *
  */
 
@@ -114,11 +115,13 @@
 #include <macros.h>
 
-SPINLOCK_INITIALIZE(slab_cache_lock);
+IRQ_SPINLOCK_STATIC_INITIALIZE(slab_cache_lock);
 static LIST_INITIALIZE(slab_cache_list);
 
 /** Magazine cache */
 static slab_cache_t mag_cache;
+
 /** Cache for cache descriptors */
 static slab_cache_t slab_cache_cache;
+
 /** Cache for external slab descriptors
  * This time we want per-cpu cache, so do not make it static
@@ -128,6 +131,8 @@
  */
 static slab_cache_t *slab_extern_cache;
+
 /** Caches for malloc */
 static slab_cache_t *malloc_caches[SLAB_MAX_MALLOC_W - SLAB_MIN_MALLOC_W + 1];
+
 static const char *malloc_names[] =  {
 	"malloc-16",
@@ -154,34 +159,37 @@
 /** Slab descriptor */
 typedef struct {
-	slab_cache_t *cache; 	/**< Pointer to parent cache. */
-	link_t link;       	/**< List of full/partial slabs. */
-	void *start;       	/**< Start address of first available item. */
-	size_t available; 	/**< Count of available items in this slab. */
-	size_t nextavail; 	/**< The index of next available item. */
+	slab_cache_t *cache;  /**< Pointer to parent cache. */
+	link_t link;          /**< List of full/partial slabs. */
+	void *start;          /**< Start address of first available item. */
+	size_t available;     /**< Count of available items in this slab. */
+	size_t nextavail;     /**< The index of next available item. */
 } slab_t;
 
 #ifdef CONFIG_DEBUG
-static int _slab_initialized = 0;
+static unsigned int _slab_initialized = 0;
 #endif
 
 /**************************************/
 /* Slab allocation functions          */
-
-/**
- * Allocate frames for slab space and initialize
- *
- */
-static slab_t *slab_space_alloc(slab_cache_t *cache, int flags)
-{
-	void *data;
+/**************************************/
+
+/** Allocate frames for slab space and initialize
+ *
+ */
+NO_TRACE static slab_t *slab_space_alloc(slab_cache_t *cache,
+    unsigned int flags)
+{
+	
+	
+	size_t zone = 0;
+	
+	void *data = frame_alloc_generic(cache->order, FRAME_KA | flags, &zone);
+	if (!data) {
+		return NULL;
+	}
+	
 	slab_t *slab;
 	size_t fsize;
-	unsigned int i;
-	size_t zone = 0;
-	
-	data = frame_alloc_generic(cache->order, FRAME_KA | flags, &zone);
-	if (!data) {
-		return NULL;
-	}
+	
 	if (!(cache->flags & SLAB_CACHE_SLINSIDE)) {
 		slab = slab_alloc(slab_extern_cache, flags);
@@ -196,61 +204,63 @@
 	
 	/* Fill in slab structures */
-	for (i = 0; i < ((unsigned int) 1 << cache->order); i++)
+	size_t i;
+	for (i = 0; i < ((size_t) 1 << cache->order); i++)
 		frame_set_parent(ADDR2PFN(KA2PA(data)) + i, slab, zone);
-
+	
 	slab->start = data;
 	slab->available = cache->objects;
 	slab->nextavail = 0;
 	slab->cache = cache;
-
+	
 	for (i = 0; i < cache->objects; i++)
-		*((int *) (slab->start + i*cache->size)) = i + 1;
-
+		*((size_t *) (slab->start + i * cache->size)) = i + 1;
+	
 	atomic_inc(&cache->allocated_slabs);
 	return slab;
 }
 
-/**
- * Deallocate space associated with slab
+/** Deallocate space associated with slab
  *
  * @return number of freed frames
- */
-static size_t slab_space_free(slab_cache_t *cache, slab_t *slab)
+ *
+ */
+NO_TRACE static size_t slab_space_free(slab_cache_t *cache, slab_t *slab)
 {
 	frame_free(KA2PA(slab->start));
-	if (! (cache->flags & SLAB_CACHE_SLINSIDE))
+	if (!(cache->flags & SLAB_CACHE_SLINSIDE))
 		slab_free(slab_extern_cache, slab);
-
+	
 	atomic_dec(&cache->allocated_slabs);
 	
-	return 1 << cache->order;
+	return (1 << cache->order);
 }
 
 /** Map object to slab structure */
-static slab_t * obj2slab(void *obj)
+NO_TRACE static slab_t *obj2slab(void *obj)
 {
 	return (slab_t *) frame_get_parent(ADDR2PFN(KA2PA(obj)), 0);
 }
 
-/**************************************/
+/******************/
 /* Slab functions */
-
-
-/**
- * Return object to slab and call a destructor
+/******************/
+
+/** Return object to slab and call a destructor
  *
  * @param slab If the caller knows directly slab of the object, otherwise NULL
  *
  * @return Number of freed pages
- */
-static size_t slab_obj_destroy(slab_cache_t *cache, void *obj, slab_t *slab)
-{
-	int freed = 0;
-
+ *
+ */
+NO_TRACE static size_t slab_obj_destroy(slab_cache_t *cache, void *obj,
+    slab_t *slab)
+{
 	if (!slab)
 		slab = obj2slab(obj);
-
+	
 	ASSERT(slab->cache == cache);
-
+	
+	size_t freed = 0;
+	
 	if (cache->destructor)
 		freed = cache->destructor(obj);
@@ -258,9 +268,9 @@
 	spinlock_lock(&cache->slablock);
 	ASSERT(slab->available < cache->objects);
-
-	*((int *)obj) = slab->nextavail;
+	
+	*((size_t *) obj) = slab->nextavail;
 	slab->nextavail = (obj - slab->start) / cache->size;
 	slab->available++;
-
+	
 	/* Move it to correct list */
 	if (slab->available == cache->objects) {
@@ -268,7 +278,6 @@
 		list_remove(&slab->link);
 		spinlock_unlock(&cache->slablock);
-
+		
 		return freed + slab_space_free(cache, slab);
-
 	} else if (slab->available == 1) {
 		/* It was in full, move to partial */
@@ -276,26 +285,28 @@
 		list_prepend(&slab->link, &cache->partial_slabs);
 	}
+	
 	spinlock_unlock(&cache->slablock);
 	return freed;
 }
 
-/**
- * Take new object from slab or create new if needed
+/** Take new object from slab or create new if needed
  *
  * @return Object address or null
- */
-static void *slab_obj_create(slab_cache_t *cache, int flags)
-{
+ *
+ */
+NO_TRACE static void *slab_obj_create(slab_cache_t *cache, unsigned int flags)
+{
+	spinlock_lock(&cache->slablock);
+	
 	slab_t *slab;
-	void *obj;
-
-	spinlock_lock(&cache->slablock);
-
+	
 	if (list_empty(&cache->partial_slabs)) {
-		/* Allow recursion and reclaiming
+		/*
+		 * Allow recursion and reclaiming
 		 * - this should work, as the slab control structures
 		 *   are small and do not need to allocate with anything
 		 *   other than frame_alloc when they are allocating,
 		 *   that's why we should get recursion at most 1-level deep
+		 *
 		 */
 		spinlock_unlock(&cache->slablock);
@@ -303,4 +314,5 @@
 		if (!slab)
 			return NULL;
+		
 		spinlock_lock(&cache->slablock);
 	} else {
@@ -309,37 +321,40 @@
 		list_remove(&slab->link);
 	}
-	obj = slab->start + slab->nextavail * cache->size;
-	slab->nextavail = *((int *)obj);
+	
+	void *obj = slab->start + slab->nextavail * cache->size;
+	slab->nextavail = *((size_t *) obj);
 	slab->available--;
-
+	
 	if (!slab->available)
 		list_prepend(&slab->link, &cache->full_slabs);
 	else
 		list_prepend(&slab->link, &cache->partial_slabs);
-
+	
 	spinlock_unlock(&cache->slablock);
-
-	if (cache->constructor && cache->constructor(obj, flags)) {
+	
+	if ((cache->constructor) && (cache->constructor(obj, flags))) {
 		/* Bad, bad, construction failed */
 		slab_obj_destroy(cache, obj, slab);
 		return NULL;
 	}
+	
 	return obj;
 }
 
-/**************************************/
+/****************************/
 /* CPU-Cache slab functions */
-
-/**
- * Finds a full magazine in cache, takes it from list
- * and returns it 
- *
- * @param first If true, return first, else last mag
- */
-static slab_magazine_t *get_mag_from_cache(slab_cache_t *cache, int first)
+/****************************/
+
+/** Find a full magazine in cache, take it from list and return it
+ *
+ * @param first If true, return first, else last mag.
+ *
+ */
+NO_TRACE static slab_magazine_t *get_mag_from_cache(slab_cache_t *cache,
+    bool first)
 {
 	slab_magazine_t *mag = NULL;
 	link_t *cur;
-
+	
 	spinlock_lock(&cache->maglock);
 	if (!list_empty(&cache->magazines)) {
@@ -348,17 +363,22 @@
 		else
 			cur = cache->magazines.prev;
+		
 		mag = list_get_instance(cur, slab_magazine_t, link);
 		list_remove(&mag->link);
 		atomic_dec(&cache->magazine_counter);
 	}
+	
 	spinlock_unlock(&cache->maglock);
 	return mag;
 }
 
-/** Prepend magazine to magazine list in cache */
-static void put_mag_to_cache(slab_cache_t *cache, slab_magazine_t *mag)
+/** Prepend magazine to magazine list in cache
+ *
+ */
+NO_TRACE static void put_mag_to_cache(slab_cache_t *cache,
+    slab_magazine_t *mag)
 {
 	spinlock_lock(&cache->maglock);
-
+	
 	list_prepend(&mag->link, &cache->magazines);
 	atomic_inc(&cache->magazine_counter);
@@ -367,14 +387,15 @@
 }
 
-/**
- * Free all objects in magazine and free memory associated with magazine
+/** Free all objects in magazine and free memory associated with magazine
  *
  * @return Number of freed pages
- */
-static size_t magazine_destroy(slab_cache_t *cache, slab_magazine_t *mag)
-{
-	unsigned int i;
+ *
+ */
+NO_TRACE static size_t magazine_destroy(slab_cache_t *cache,
+    slab_magazine_t *mag)
+{
+	size_t i;
 	size_t frames = 0;
-
+	
 	for (i = 0; i < mag->busy; i++) {
 		frames += slab_obj_destroy(cache, mag->objs[i], NULL);
@@ -383,24 +404,23 @@
 	
 	slab_free(&mag_cache, mag);
-
+	
 	return frames;
 }
 
-/**
- * Find full magazine, set it as current and return it
- *
- * Assume cpu_magazine lock is held
- */
-static slab_magazine_t *get_full_current_mag(slab_cache_t *cache)
-{
-	slab_magazine_t *cmag, *lastmag, *newmag;
-
-	cmag = cache->mag_cache[CPU->id].current;
-	lastmag = cache->mag_cache[CPU->id].last;
+/** Find full magazine, set it as current and return it
+ *
+ */
+NO_TRACE static slab_magazine_t *get_full_current_mag(slab_cache_t *cache)
+{
+	slab_magazine_t *cmag = cache->mag_cache[CPU->id].current;
+	slab_magazine_t *lastmag = cache->mag_cache[CPU->id].last;
+	
+	ASSERT(spinlock_locked(&cache->mag_cache[CPU->id].lock));
+	
 	if (cmag) { /* First try local CPU magazines */
 		if (cmag->busy)
 			return cmag;
-
-		if (lastmag && lastmag->busy) {
+		
+		if ((lastmag) && (lastmag->busy)) {
 			cache->mag_cache[CPU->id].current = lastmag;
 			cache->mag_cache[CPU->id].last = cmag;
@@ -408,39 +428,40 @@
 		}
 	}
+	
 	/* Local magazines are empty, import one from magazine list */
-	newmag = get_mag_from_cache(cache, 1);
+	slab_magazine_t *newmag = get_mag_from_cache(cache, 1);
 	if (!newmag)
 		return NULL;
-
+	
 	if (lastmag)
 		magazine_destroy(cache, lastmag);
-
+	
 	cache->mag_cache[CPU->id].last = cmag;
 	cache->mag_cache[CPU->id].current = newmag;
+	
 	return newmag;
 }
 
-/**
- * Try to find object in CPU-cache magazines
+/** Try to find object in CPU-cache magazines
  *
  * @return Pointer to object or NULL if not available
- */
-static void *magazine_obj_get(slab_cache_t *cache)
-{
-	slab_magazine_t *mag;
-	void *obj;
-
+ *
+ */
+NO_TRACE static void *magazine_obj_get(slab_cache_t *cache)
+{
 	if (!CPU)
 		return NULL;
-
+	
 	spinlock_lock(&cache->mag_cache[CPU->id].lock);
-
-	mag = get_full_current_mag(cache);
+	
+	slab_magazine_t *mag = get_full_current_mag(cache);
 	if (!mag) {
 		spinlock_unlock(&cache->mag_cache[CPU->id].lock);
 		return NULL;
 	}
-	obj = mag->objs[--mag->busy];
+	
+	void *obj = mag->objs[--mag->busy];
 	spinlock_unlock(&cache->mag_cache[CPU->id].lock);
+	
 	atomic_dec(&cache->cached_objs);
 	
@@ -448,28 +469,25 @@
 }
 
-/**
- * Assure that the current magazine is empty, return pointer to it, or NULL if 
- * no empty magazine is available and cannot be allocated
- *
- * Assume mag_cache[CPU->id].lock is held
- *
- * We have 2 magazines bound to processor. 
- * First try the current. 
- *  If full, try the last.
- *   If full, put to magazines list.
- *   allocate new, exchange last & current
- *
- */
-static slab_magazine_t *make_empty_current_mag(slab_cache_t *cache)
-{
-	slab_magazine_t *cmag,*lastmag,*newmag;
-
-	cmag = cache->mag_cache[CPU->id].current;
-	lastmag = cache->mag_cache[CPU->id].last;
-
+/** Assure that the current magazine is empty, return pointer to it,
+ * or NULL if no empty magazine is available and cannot be allocated
+ *
+ * We have 2 magazines bound to processor.
+ * First try the current.
+ * If full, try the last.
+ * If full, put to magazines list.
+ *
+ */
+NO_TRACE static slab_magazine_t *make_empty_current_mag(slab_cache_t *cache)
+{
+	slab_magazine_t *cmag = cache->mag_cache[CPU->id].current;
+	slab_magazine_t *lastmag = cache->mag_cache[CPU->id].last;
+	
+	ASSERT(spinlock_locked(&cache->mag_cache[CPU->id].lock));
+	
 	if (cmag) {
 		if (cmag->busy < cmag->size)
 			return cmag;
-		if (lastmag && lastmag->busy < lastmag->size) {
+		
+		if ((lastmag) && (lastmag->busy < lastmag->size)) {
 			cache->mag_cache[CPU->id].last = cmag;
 			cache->mag_cache[CPU->id].current = lastmag;
@@ -477,40 +495,45 @@
 		}
 	}
+	
 	/* current | last are full | nonexistent, allocate new */
-	/* We do not want to sleep just because of caching */
-	/* Especially we do not want reclaiming to start, as 
-	 * this would deadlock */
-	newmag = slab_alloc(&mag_cache, FRAME_ATOMIC | FRAME_NO_RECLAIM);
+	
+	/*
+	 * We do not want to sleep just because of caching,
+	 * especially we do not want reclaiming to start, as
+	 * this would deadlock.
+	 *
+	 */
+	slab_magazine_t *newmag = slab_alloc(&mag_cache,
+	    FRAME_ATOMIC | FRAME_NO_RECLAIM);
 	if (!newmag)
 		return NULL;
+	
 	newmag->size = SLAB_MAG_SIZE;
 	newmag->busy = 0;
-
+	
 	/* Flush last to magazine list */
 	if (lastmag)
 		put_mag_to_cache(cache, lastmag);
-
+	
 	/* Move current as last, save new as current */
-	cache->mag_cache[CPU->id].last = cmag;	
-	cache->mag_cache[CPU->id].current = newmag;	
-
+	cache->mag_cache[CPU->id].last = cmag;
+	cache->mag_cache[CPU->id].current = newmag;
+	
 	return newmag;
 }
 
-/**
- * Put object into CPU-cache magazine
- *
- * @return 0 - success, -1 - could not get memory
- */
-static int magazine_obj_put(slab_cache_t *cache, void *obj)
-{
-	slab_magazine_t *mag;
-
+/** Put object into CPU-cache magazine
+ *
+ * @return 0 on success, -1 on no memory
+ *
+ */
+NO_TRACE static int magazine_obj_put(slab_cache_t *cache, void *obj)
+{
 	if (!CPU)
 		return -1;
-
+	
 	spinlock_lock(&cache->mag_cache[CPU->id].lock);
-
-	mag = make_empty_current_mag(cache);
+	
+	slab_magazine_t *mag = make_empty_current_mag(cache);
 	if (!mag) {
 		spinlock_unlock(&cache->mag_cache[CPU->id].lock);
@@ -519,94 +542,101 @@
 	
 	mag->objs[mag->busy++] = obj;
-
+	
 	spinlock_unlock(&cache->mag_cache[CPU->id].lock);
+	
 	atomic_inc(&cache->cached_objs);
+	
 	return 0;
 }
 
-
-/**************************************/
+/************************/
 /* Slab cache functions */
-
-/** Return number of objects that fit in certain cache size */
-static unsigned int comp_objects(slab_cache_t *cache)
+/************************/
+
+/** Return number of objects that fit in certain cache size
+ *
+ */
+NO_TRACE static size_t comp_objects(slab_cache_t *cache)
 {
 	if (cache->flags & SLAB_CACHE_SLINSIDE)
-		return ((PAGE_SIZE << cache->order) - sizeof(slab_t)) /
-		    cache->size;
-	else 
+		return ((PAGE_SIZE << cache->order)
+		    - sizeof(slab_t)) / cache->size;
+	else
 		return (PAGE_SIZE << cache->order) / cache->size;
 }
 
-/** Return wasted space in slab */
-static unsigned int badness(slab_cache_t *cache)
-{
-	unsigned int objects;
-	unsigned int ssize;
-
-	objects = comp_objects(cache);
-	ssize = PAGE_SIZE << cache->order;
+/** Return wasted space in slab
+ *
+ */
+NO_TRACE static size_t badness(slab_cache_t *cache)
+{
+	size_t objects = comp_objects(cache);
+	size_t ssize = PAGE_SIZE << cache->order;
+	
 	if (cache->flags & SLAB_CACHE_SLINSIDE)
 		ssize -= sizeof(slab_t);
+	
 	return ssize - objects * cache->size;
 }
 
-/**
- * Initialize mag_cache structure in slab cache
- */
-static bool make_magcache(slab_cache_t *cache)
-{
-	unsigned int i;
-	
+/** Initialize mag_cache structure in slab cache
+ *
+ */
+NO_TRACE static bool make_magcache(slab_cache_t *cache)
+{
 	ASSERT(_slab_initialized >= 2);
-
+	
 	cache->mag_cache = malloc(sizeof(slab_mag_cache_t) * config.cpu_count,
 	    FRAME_ATOMIC);
 	if (!cache->mag_cache)
 		return false;
-
+	
+	size_t i;
 	for (i = 0; i < config.cpu_count; i++) {
 		memsetb(&cache->mag_cache[i], sizeof(cache->mag_cache[i]), 0);
 		spinlock_initialize(&cache->mag_cache[i].lock,
-		    "slab_maglock_cpu");
-	}
+		    "slab.cache.mag_cache[].lock");
+	}
+	
 	return true;
 }
 
-/** Initialize allocated memory as a slab cache */
-static void _slab_cache_create(slab_cache_t *cache, const char *name,
-    size_t size, size_t align, int (*constructor)(void *obj, int kmflag),
-    int (*destructor)(void *obj), int flags)
-{
-	int pages;
-	ipl_t ipl;
-
+/** Initialize allocated memory as a slab cache
+ *
+ */
+NO_TRACE static void _slab_cache_create(slab_cache_t *cache, const char *name,
+    size_t size, size_t align, int (*constructor)(void *obj,
+    unsigned int kmflag), size_t (*destructor)(void *obj), unsigned int flags)
+{
 	memsetb(cache, sizeof(*cache), 0);
 	cache->name = name;
-
+	
 	if (align < sizeof(unative_t))
 		align = sizeof(unative_t);
+	
 	size = ALIGN_UP(size, align);
-		
+	
 	cache->size = size;
-
 	cache->constructor = constructor;
 	cache->destructor = destructor;
 	cache->flags = flags;
-
+	
 	list_initialize(&cache->full_slabs);
 	list_initialize(&cache->partial_slabs);
 	list_initialize(&cache->magazines);
-	spinlock_initialize(&cache->slablock, "slab_lock");
-	spinlock_initialize(&cache->maglock, "slab_maglock");
+	
+	spinlock_initialize(&cache->slablock, "slab.cache.slablock");
+	spinlock_initialize(&cache->maglock, "slab.cache.maglock");
+	
 	if (!(cache->flags & SLAB_CACHE_NOMAGAZINE))
 		(void) make_magcache(cache);
-
+	
 	/* Compute slab sizes, object counts in slabs etc. */
 	if (cache->size < SLAB_INSIDE_SIZE)
 		cache->flags |= SLAB_CACHE_SLINSIDE;
-
+	
 	/* Minimum slab order */
-	pages = SIZE2FRAMES(cache->size);
+	size_t pages = SIZE2FRAMES(cache->size);
+	
 	/* We need the 2^order >= pages */
 	if (pages == 1)
@@ -614,59 +644,58 @@
 	else
 		cache->order = fnzb(pages - 1) + 1;
-
-	while (badness(cache) > SLAB_MAX_BADNESS(cache)) {
+	
+	while (badness(cache) > SLAB_MAX_BADNESS(cache))
 		cache->order += 1;
-	}
+	
 	cache->objects = comp_objects(cache);
+	
 	/* If info fits in, put it inside */
 	if (badness(cache) > sizeof(slab_t))
 		cache->flags |= SLAB_CACHE_SLINSIDE;
-
+	
 	/* Add cache to cache list */
-	ipl = interrupts_disable();
-	spinlock_lock(&slab_cache_lock);
-
+	irq_spinlock_lock(&slab_cache_lock, true);
 	list_append(&cache->link, &slab_cache_list);
-
-	spinlock_unlock(&slab_cache_lock);
-	interrupts_restore(ipl);
-}
-
-/** Create slab cache  */
+	irq_spinlock_unlock(&slab_cache_lock, true);
+}
+
+/** Create slab cache 
+ *
+ */
 slab_cache_t *slab_cache_create(const char *name, size_t size, size_t align,
-    int (*constructor)(void *obj, int kmflag), int (*destructor)(void *obj),
-    int flags)
-{
-	slab_cache_t *cache;
-
-	cache = slab_alloc(&slab_cache_cache, 0);
+    int (*constructor)(void *obj, unsigned int kmflag),
+    size_t (*destructor)(void *obj), unsigned int flags)
+{
+	slab_cache_t *cache = slab_alloc(&slab_cache_cache, 0);
 	_slab_cache_create(cache, name, size, align, constructor, destructor,
 	    flags);
+	
 	return cache;
 }
 
-/** 
- * Reclaim space occupied by objects that are already free
+/** Reclaim space occupied by objects that are already free
  *
  * @param flags If contains SLAB_RECLAIM_ALL, do aggressive freeing
+ *
  * @return Number of freed pages
- */
-static size_t _slab_reclaim(slab_cache_t *cache, int flags)
-{
-	unsigned int i;
+ *
+ */
+NO_TRACE static size_t _slab_reclaim(slab_cache_t *cache, unsigned int flags)
+{
+	if (cache->flags & SLAB_CACHE_NOMAGAZINE)
+		return 0; /* Nothing to do */
+	
+	/*
+	 * We count up to original magazine count to avoid
+	 * endless loop
+	 */
+	atomic_count_t magcount = atomic_get(&cache->magazine_counter);
+	
 	slab_magazine_t *mag;
 	size_t frames = 0;
-	int magcount;
-	
-	if (cache->flags & SLAB_CACHE_NOMAGAZINE)
-		return 0; /* Nothing to do */
-
-	/* We count up to original magazine count to avoid
-	 * endless loop 
-	 */
-	magcount = atomic_get(&cache->magazine_counter);
-	while (magcount-- && (mag=get_mag_from_cache(cache, 0))) {
-		frames += magazine_destroy(cache,mag);
-		if (!(flags & SLAB_RECLAIM_ALL) && frames)
+	
+	while ((magcount--) && (mag = get_mag_from_cache(cache, 0))) {
+		frames += magazine_destroy(cache, mag);
+		if ((!(flags & SLAB_RECLAIM_ALL)) && (frames))
 			break;
 	}
@@ -675,7 +704,8 @@
 		/* Free cpu-bound magazines */
 		/* Destroy CPU magazines */
+		size_t i;
 		for (i = 0; i < config.cpu_count; i++) {
 			spinlock_lock(&cache->mag_cache[i].lock);
-
+			
 			mag = cache->mag_cache[i].current;
 			if (mag)
@@ -687,85 +717,88 @@
 				frames += magazine_destroy(cache, mag);
 			cache->mag_cache[i].last = NULL;
-
+			
 			spinlock_unlock(&cache->mag_cache[i].lock);
 		}
 	}
-
+	
 	return frames;
 }
 
-/** Check that there are no slabs and remove cache from system  */
+/** Check that there are no slabs and remove cache from system
+ *
+ */
 void slab_cache_destroy(slab_cache_t *cache)
 {
-	ipl_t ipl;
-
-	/* First remove cache from link, so that we don't need
+	/*
+	 * First remove cache from link, so that we don't need
 	 * to disable interrupts later
+	 *
 	 */
-
-	ipl = interrupts_disable();
-	spinlock_lock(&slab_cache_lock);
-
+	irq_spinlock_lock(&slab_cache_lock, true);
 	list_remove(&cache->link);
-
-	spinlock_unlock(&slab_cache_lock);
-	interrupts_restore(ipl);
-
-	/* Do not lock anything, we assume the software is correct and
-	 * does not touch the cache when it decides to destroy it */
+	irq_spinlock_unlock(&slab_cache_lock, true);
+	
+	/*
+	 * Do not lock anything, we assume the software is correct and
+	 * does not touch the cache when it decides to destroy it
+	 *
+	 */
 	
 	/* Destroy all magazines */
 	_slab_reclaim(cache, SLAB_RECLAIM_ALL);
-
+	
 	/* All slabs must be empty */
-	if (!list_empty(&cache->full_slabs) ||
-	    !list_empty(&cache->partial_slabs))
+	if ((!list_empty(&cache->full_slabs)) ||
+	    (!list_empty(&cache->partial_slabs)))
 		panic("Destroying cache that is not empty.");
-
+	
 	if (!(cache->flags & SLAB_CACHE_NOMAGAZINE))
 		free(cache->mag_cache);
+	
 	slab_free(&slab_cache_cache, cache);
 }
 
-/** Allocate new object from cache - if no flags given, always returns memory */
-void *slab_alloc(slab_cache_t *cache, int flags)
-{
-	ipl_t ipl;
+/** Allocate new object from cache - if no flags given, always returns memory
+ *
+ */
+void *slab_alloc(slab_cache_t *cache, unsigned int flags)
+{
+	/* Disable interrupts to avoid deadlocks with interrupt handlers */
+	ipl_t ipl = interrupts_disable();
+	
 	void *result = NULL;
 	
-	/* Disable interrupts to avoid deadlocks with interrupt handlers */
-	ipl = interrupts_disable();
-
-	if (!(cache->flags & SLAB_CACHE_NOMAGAZINE)) {
+	if (!(cache->flags & SLAB_CACHE_NOMAGAZINE))
 		result = magazine_obj_get(cache);
-	}
+	
 	if (!result)
 		result = slab_obj_create(cache, flags);
-
+	
 	interrupts_restore(ipl);
-
+	
 	if (result)
 		atomic_inc(&cache->allocated_objs);
-
+	
 	return result;
 }
 
-/** Return object to cache, use slab if known  */
-static void _slab_free(slab_cache_t *cache, void *obj, slab_t *slab)
-{
-	ipl_t ipl;
-
-	ipl = interrupts_disable();
-
+/** Return object to cache, use slab if known
+ *
+ */
+NO_TRACE static void _slab_free(slab_cache_t *cache, void *obj, slab_t *slab)
+{
+	ipl_t ipl = interrupts_disable();
+	
 	if ((cache->flags & SLAB_CACHE_NOMAGAZINE) ||
-	    magazine_obj_put(cache, obj)) {
+	    (magazine_obj_put(cache, obj)))
 		slab_obj_destroy(cache, obj, slab);
-
-	}
+	
 	interrupts_restore(ipl);
 	atomic_dec(&cache->allocated_objs);
 }
 
-/** Return slab object to cache */
+/** Return slab object to cache
+ *
+ */
 void slab_free(slab_cache_t *cache, void *obj)
 {
@@ -773,45 +806,37 @@
 }
 
-/* Go through all caches and reclaim what is possible */
-size_t slab_reclaim(int flags)
-{
-	slab_cache_t *cache;
+/** Go through all caches and reclaim what is possible
+ *
+ * Interrupts must be disabled before calling this function,
+ * otherwise  memory allocation from interrupts can deadlock.
+ *
+ */
+size_t slab_reclaim(unsigned int flags)
+{
+	irq_spinlock_lock(&slab_cache_lock, false);
+	
+	size_t frames = 0;
 	link_t *cur;
-	size_t frames = 0;
-
-	spinlock_lock(&slab_cache_lock);
-
-	/* TODO: Add assert, that interrupts are disabled, otherwise
-	 * memory allocation from interrupts can deadlock.
-	 */
-
 	for (cur = slab_cache_list.next; cur != &slab_cache_list;
 	    cur = cur->next) {
-		cache = list_get_instance(cur, slab_cache_t, link);
+		slab_cache_t *cache = list_get_instance(cur, slab_cache_t, link);
 		frames += _slab_reclaim(cache, flags);
 	}
-
-	spinlock_unlock(&slab_cache_lock);
-
+	
+	irq_spinlock_unlock(&slab_cache_lock, false);
+	
 	return frames;
 }
 
-
-/* Print list of slabs */
+/* Print list of slabs
+ *
+ */
 void slab_print_list(void)
 {
-	int skip = 0;
-
-	printf("slab name        size     pages  obj/pg slabs  cached allocated"
-	    " ctl\n");
-	printf("---------------- -------- ------ ------ ------ ------ ---------"
-	    " ---\n");
-
+	printf("[slab name       ] [size  ] [pages ] [obj/pg] [slabs ]"
+	    " [cached] [alloc ] [ctl]\n");
+	
+	size_t skip = 0;
 	while (true) {
-		slab_cache_t *cache;
-		link_t *cur;
-		ipl_t ipl;
-		int i;
-
 		/*
 		 * We must not hold the slab_cache_lock spinlock when printing
@@ -836,36 +861,34 @@
 		 * statistics.
 		 */
-
-		ipl = interrupts_disable();
-		spinlock_lock(&slab_cache_lock);
-
+		
+		irq_spinlock_lock(&slab_cache_lock, true);
+		
+		link_t *cur;
+		size_t i;
 		for (i = 0, cur = slab_cache_list.next;
-		    i < skip && cur != &slab_cache_list;
-		    i++, cur = cur->next)
-			;
-
+		    (i < skip) && (cur != &slab_cache_list);
+		    i++, cur = cur->next);
+		
 		if (cur == &slab_cache_list) {
-			spinlock_unlock(&slab_cache_lock);
-			interrupts_restore(ipl);
+			irq_spinlock_unlock(&slab_cache_lock, true);
 			break;
 		}
-
+		
 		skip++;
-
-		cache = list_get_instance(cur, slab_cache_t, link);
-
+		
+		slab_cache_t *cache = list_get_instance(cur, slab_cache_t, link);
+		
 		const char *name = cache->name;
 		uint8_t order = cache->order;
 		size_t size = cache->size;
-		unsigned int objects = cache->objects;
+		size_t objects = cache->objects;
 		long allocated_slabs = atomic_get(&cache->allocated_slabs);
 		long cached_objs = atomic_get(&cache->cached_objs);
 		long allocated_objs = atomic_get(&cache->allocated_objs);
-		int flags = cache->flags;
-		
-		spinlock_unlock(&slab_cache_lock);
-		interrupts_restore(ipl);
-		
-		printf("%-16s %8" PRIs " %6d %6u %6ld %6ld %9ld %-3s\n",
+		unsigned int flags = cache->flags;
+		
+		irq_spinlock_unlock(&slab_cache_lock, true);
+		
+		printf("%-18s %8" PRIs " %8u %8" PRIs " %8ld %8ld %8ld %-5s\n",
 		    name, size, (1 << order), objects, allocated_slabs,
 		    cached_objs, allocated_objs,
@@ -876,6 +899,4 @@
 void slab_cache_init(void)
 {
-	int i, size;
-
 	/* Initialize magazine cache */
 	_slab_cache_create(&mag_cache, "slab_magazine",
@@ -883,13 +904,18 @@
 	    sizeof(uintptr_t), NULL, NULL, SLAB_CACHE_NOMAGAZINE |
 	    SLAB_CACHE_SLINSIDE);
+	
 	/* Initialize slab_cache cache */
 	_slab_cache_create(&slab_cache_cache, "slab_cache",
 	    sizeof(slab_cache_cache), sizeof(uintptr_t), NULL, NULL,
 	    SLAB_CACHE_NOMAGAZINE | SLAB_CACHE_SLINSIDE);
+	
 	/* Initialize external slab cache */
 	slab_extern_cache = slab_cache_create("slab_extern", sizeof(slab_t), 0,
 	    NULL, NULL, SLAB_CACHE_SLINSIDE | SLAB_CACHE_MAGDEFERRED);
-
+	
 	/* Initialize structures for malloc */
+	size_t i;
+	size_t size;
+	
 	for (i = 0, size = (1 << SLAB_MIN_MALLOC_W);
 	    i < (SLAB_MAX_MALLOC_W - SLAB_MIN_MALLOC_W + 1);
@@ -898,4 +924,5 @@
 		    NULL, NULL, SLAB_CACHE_MAGDEFERRED);
 	}
+	
 #ifdef CONFIG_DEBUG
 	_slab_initialized = 1;
@@ -906,35 +933,32 @@
  *
  * Kernel calls this function, when it knows the real number of
- * processors. 
- * Allocate slab for cpucache and enable it on all existing
- * slabs that are SLAB_CACHE_MAGDEFERRED
+ * processors. Allocate slab for cpucache and enable it on all
+ * existing slabs that are SLAB_CACHE_MAGDEFERRED
+ *
  */
 void slab_enable_cpucache(void)
 {
-	link_t *cur;
-	slab_cache_t *s;
-
 #ifdef CONFIG_DEBUG
 	_slab_initialized = 2;
 #endif
-
-	spinlock_lock(&slab_cache_lock);
-	
+	
+	irq_spinlock_lock(&slab_cache_lock, false);
+	
+	link_t *cur;
 	for (cur = slab_cache_list.next; cur != &slab_cache_list;
-	    cur = cur->next){
-		s = list_get_instance(cur, slab_cache_t, link);
-		if ((s->flags & SLAB_CACHE_MAGDEFERRED) !=
+	    cur = cur->next) {
+		slab_cache_t *slab = list_get_instance(cur, slab_cache_t, link);
+		if ((slab->flags & SLAB_CACHE_MAGDEFERRED) !=
 		    SLAB_CACHE_MAGDEFERRED)
 			continue;
-		(void) make_magcache(s);
-		s->flags &= ~SLAB_CACHE_MAGDEFERRED;
-	}
-
-	spinlock_unlock(&slab_cache_lock);
-}
-
-/**************************************/
-/* kalloc/kfree functions             */
-void *malloc(unsigned int size, int flags)
+		
+		(void) make_magcache(slab);
+		slab->flags &= ~SLAB_CACHE_MAGDEFERRED;
+	}
+	
+	irq_spinlock_unlock(&slab_cache_lock, false);
+}
+
+void *malloc(size_t size, unsigned int flags)
 {
 	ASSERT(_slab_initialized);
@@ -943,11 +967,11 @@
 	if (size < (1 << SLAB_MIN_MALLOC_W))
 		size = (1 << SLAB_MIN_MALLOC_W);
-
-	int idx = fnzb(size - 1) - SLAB_MIN_MALLOC_W + 1;
-
+	
+	uint8_t idx = fnzb(size - 1) - SLAB_MIN_MALLOC_W + 1;
+	
 	return slab_alloc(malloc_caches[idx], flags);
 }
 
-void *realloc(void *ptr, unsigned int size, int flags)
+void *realloc(void *ptr, size_t size, unsigned int flags)
 {
 	ASSERT(_slab_initialized);
@@ -959,5 +983,5 @@
 		if (size < (1 << SLAB_MIN_MALLOC_W))
 			size = (1 << SLAB_MIN_MALLOC_W);
-		int idx = fnzb(size - 1) - SLAB_MIN_MALLOC_W + 1;
+		uint8_t idx = fnzb(size - 1) - SLAB_MIN_MALLOC_W + 1;
 		
 		new_ptr = slab_alloc(malloc_caches[idx], flags);
@@ -980,5 +1004,5 @@
 	if (!ptr)
 		return;
-
+	
 	slab_t *slab = obj2slab(ptr);
 	_slab_free(slab->cache, ptr, slab);
Index: kernel/generic/src/mm/tlb.c
===================================================================
--- kernel/generic/src/mm/tlb.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/generic/src/mm/tlb.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -33,5 +33,5 @@
 /**
  * @file
- * @brief	Generic TLB shootdown algorithm.
+ * @brief Generic TLB shootdown algorithm.
  *
  * The algorithm implemented here is based on the CMU TLB shootdown
@@ -53,11 +53,4 @@
 #include <cpu.h>
 
-/**
- * This lock is used for synchronisation between sender and
- * recipients of TLB shootdown message. It must be acquired
- * before CPU structure lock.
- */
-SPINLOCK_INITIALIZE(tlblock);
-
 void tlb_init(void)
 {
@@ -67,4 +60,12 @@
 #ifdef CONFIG_SMP
 
+/**
+ * This lock is used for synchronisation between sender and
+ * recipients of TLB shootdown message. It must be acquired
+ * before CPU structure lock.
+ *
+ */
+IRQ_SPINLOCK_STATIC_INITIALIZE(tlblock);
+
 /** Send TLB shootdown message.
  *
@@ -72,27 +73,27 @@
  * to all other processors.
  *
- * This function must be called with interrupts disabled.
+ * @param type  Type describing scope of shootdown.
+ * @param asid  Address space, if required by type.
+ * @param page  Virtual page address, if required by type.
+ * @param count Number of pages, if required by type.
  *
- * @param type Type describing scope of shootdown.
- * @param asid Address space, if required by type.
- * @param page Virtual page address, if required by type.
- * @param count Number of pages, if required by type.
+ * @return The interrupt priority level as it existed prior to this call.
+ *
  */
-void tlb_shootdown_start(tlb_invalidate_type_t type, asid_t asid,
+ipl_t tlb_shootdown_start(tlb_invalidate_type_t type, asid_t asid,
     uintptr_t page, size_t count)
 {
-	unsigned int i;
-
-	CPU->tlb_active = 0;
-	spinlock_lock(&tlblock);
+	ipl_t ipl = interrupts_disable();
+	CPU->tlb_active = false;
+	irq_spinlock_lock(&tlblock, false);
 	
+	size_t i;
 	for (i = 0; i < config.cpu_count; i++) {
-		cpu_t *cpu;
-		
 		if (i == CPU->id)
 			continue;
-
-		cpu = &cpus[i];
-		spinlock_lock(&cpu->lock);
+		
+		cpu_t *cpu = &cpus[i];
+		
+		irq_spinlock_lock(&cpu->lock, false);
 		if (cpu->tlb_messages_count == TLB_MESSAGE_QUEUE_LEN) {
 			/*
@@ -115,20 +116,28 @@
 			cpu->tlb_messages[idx].count = count;
 		}
-		spinlock_unlock(&cpu->lock);
+		irq_spinlock_unlock(&cpu->lock, false);
 	}
 	
 	tlb_shootdown_ipi_send();
-
-busy_wait:	
-	for (i = 0; i < config.cpu_count; i++)
+	
+busy_wait:
+	for (i = 0; i < config.cpu_count; i++) {
 		if (cpus[i].tlb_active)
 			goto busy_wait;
+	}
+	
+	return ipl;
 }
 
-/** Finish TLB shootdown sequence. */
-void tlb_shootdown_finalize(void)
+/** Finish TLB shootdown sequence.
+ *
+ * @param ipl Previous interrupt priority level.
+ *
+ */
+void tlb_shootdown_finalize(ipl_t ipl)
 {
-	spinlock_unlock(&tlblock);
-	CPU->tlb_active = 1;
+	irq_spinlock_unlock(&tlblock, false);
+	CPU->tlb_active = true;
+	interrupts_restore(ipl);
 }
 
@@ -138,28 +147,25 @@
 }
 
-/** Receive TLB shootdown message. */
+/** Receive TLB shootdown message.
+ *
+ */
 void tlb_shootdown_ipi_recv(void)
 {
-	tlb_invalidate_type_t type;
-	asid_t asid;
-	uintptr_t page;
-	size_t count;
-	unsigned int i;
-	
 	ASSERT(CPU);
 	
-	CPU->tlb_active = 0;
-	spinlock_lock(&tlblock);
-	spinlock_unlock(&tlblock);
+	CPU->tlb_active = false;
+	irq_spinlock_lock(&tlblock, false);
+	irq_spinlock_unlock(&tlblock, false);
 	
-	spinlock_lock(&CPU->lock);
+	irq_spinlock_lock(&CPU->lock, false);
 	ASSERT(CPU->tlb_messages_count <= TLB_MESSAGE_QUEUE_LEN);
-
+	
+	size_t i;
 	for (i = 0; i < CPU->tlb_messages_count; CPU->tlb_messages_count--) {
-		type = CPU->tlb_messages[i].type;
-		asid = CPU->tlb_messages[i].asid;
-		page = CPU->tlb_messages[i].page;
-		count = CPU->tlb_messages[i].count;
-
+		tlb_invalidate_type_t type = CPU->tlb_messages[i].type;
+		asid_t asid = CPU->tlb_messages[i].asid;
+		uintptr_t page = CPU->tlb_messages[i].page;
+		size_t count = CPU->tlb_messages[i].count;
+		
 		switch (type) {
 		case TLB_INVL_ALL:
@@ -170,5 +176,5 @@
 			break;
 		case TLB_INVL_PAGES:
-		    	ASSERT(count);
+			ASSERT(count);
 			tlb_invalidate_pages(asid, page, count);
 			break;
@@ -177,10 +183,11 @@
 			break;
 		}
+		
 		if (type == TLB_INVL_ALL)
 			break;
 	}
 	
-	spinlock_unlock(&CPU->lock);
-	CPU->tlb_active = 1;
+	irq_spinlock_unlock(&CPU->lock, false);
+	CPU->tlb_active = true;
 }
 
Index: kernel/generic/src/printf/vprintf.c
===================================================================
--- kernel/generic/src/printf/vprintf.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/generic/src/printf/vprintf.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -42,5 +42,5 @@
 #include <str.h>
 
-SPINLOCK_STATIC_INITIALIZE_NAME(printf_lock, "*printf_lock");
+IRQ_SPINLOCK_STATIC_INITIALIZE_NAME(printf_lock, "*printf_lock");
 
 static int vprintf_str_write(const char *str, size_t size, void *data)
@@ -93,11 +93,7 @@
 	};
 	
-	ipl_t ipl = interrupts_disable();
-	spinlock_lock(&printf_lock);
-	
+	irq_spinlock_lock(&printf_lock, true);
 	int ret = printf_core(fmt, &ps, ap);
-	
-	spinlock_unlock(&printf_lock);
-	interrupts_restore(ipl);
+	irq_spinlock_unlock(&printf_lock, true);
 	
 	return ret;
Index: kernel/generic/src/proc/program.c
===================================================================
--- kernel/generic/src/proc/program.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/generic/src/proc/program.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -145,5 +145,5 @@
 		
 		program_loader = image_addr;
-		LOG("Registered program loader at 0x%" PRIp "\n",
+		LOG("Registered program loader at 0x%" PRIp,
 		    image_addr);
 		
Index: kernel/generic/src/proc/scheduler.c
===================================================================
--- kernel/generic/src/proc/scheduler.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/generic/src/proc/scheduler.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -33,5 +33,5 @@
 /**
  * @file
- * @brief	Scheduler and load balancing.
+ * @brief Scheduler and load balancing.
  *
  * This file contains the scheduler and kcpulb kernel thread which
@@ -68,5 +68,5 @@
 static void scheduler_separated_stack(void);
 
-atomic_t nrdy;	/**< Number of ready threads in the system. */
+atomic_t nrdy;  /**< Number of ready threads in the system. */
 
 /** Carry out actions before new task runs. */
@@ -89,8 +89,8 @@
 	before_thread_runs_arch();
 #ifdef CONFIG_FPU_LAZY
-	if(THREAD == CPU->fpu_owner) 
+	if(THREAD == CPU->fpu_owner)
 		fpu_enable();
 	else
-		fpu_disable(); 
+		fpu_disable();
 #else
 	fpu_enable();
@@ -123,17 +123,18 @@
 restart:
 	fpu_enable();
-	spinlock_lock(&CPU->lock);
-
+	irq_spinlock_lock(&CPU->lock, false);
+	
 	/* Save old context */
-	if (CPU->fpu_owner != NULL) {  
-		spinlock_lock(&CPU->fpu_owner->lock);
+	if (CPU->fpu_owner != NULL) {
+		irq_spinlock_lock(&CPU->fpu_owner->lock, false);
 		fpu_context_save(CPU->fpu_owner->saved_fpu_context);
-		/* don't prevent migration */
+		
+		/* Don't prevent migration */
 		CPU->fpu_owner->fpu_context_engaged = 0;
-		spinlock_unlock(&CPU->fpu_owner->lock);
+		irq_spinlock_unlock(&CPU->fpu_owner->lock, false);
 		CPU->fpu_owner = NULL;
 	}
-
-	spinlock_lock(&THREAD->lock);
+	
+	irq_spinlock_lock(&THREAD->lock, false);
 	if (THREAD->fpu_context_exists) {
 		fpu_context_restore(THREAD->saved_fpu_context);
@@ -142,21 +143,23 @@
 		if (!THREAD->saved_fpu_context) {
 			/* Might sleep */
-			spinlock_unlock(&THREAD->lock);
-			spinlock_unlock(&CPU->lock);
+			irq_spinlock_unlock(&THREAD->lock, false);
+			irq_spinlock_unlock(&CPU->lock, false);
 			THREAD->saved_fpu_context =
 			    (fpu_context_t *) slab_alloc(fpu_context_slab, 0);
+			
 			/* We may have switched CPUs during slab_alloc */
-			goto restart; 
+			goto restart;
 		}
 		fpu_init();
 		THREAD->fpu_context_exists = 1;
 	}
+	
 	CPU->fpu_owner = THREAD;
 	THREAD->fpu_context_engaged = 1;
-	spinlock_unlock(&THREAD->lock);
-
-	spinlock_unlock(&CPU->lock);
-}
-#endif
+	irq_spinlock_unlock(&THREAD->lock, false);
+	
+	irq_spinlock_unlock(&CPU->lock, false);
+}
+#endif /* CONFIG_FPU_LAZY */
 
 /** Initialize scheduler
@@ -180,10 +183,6 @@
 static thread_t *find_best_thread(void)
 {
-	thread_t *t;
-	runq_t *r;
-	int i;
-
 	ASSERT(CPU != NULL);
-
+	
 loop:
 	
@@ -194,61 +193,58 @@
 		 * This improves energy saving and hyperthreading.
 		 */
-
-		 /* Mark CPU as it was idle this clock tick */
-		 spinlock_lock(&CPU->lock);
-		 CPU->idle = true;
-		 spinlock_unlock(&CPU->lock);
-
-		 interrupts_enable();
-		 /*
+		irq_spinlock_lock(&CPU->lock, false);
+		CPU->idle = true;
+		irq_spinlock_unlock(&CPU->lock, false);
+		interrupts_enable();
+		
+		/*
 		 * An interrupt might occur right now and wake up a thread.
 		 * In such case, the CPU will continue to go to sleep
 		 * even though there is a runnable thread.
 		 */
-		 cpu_sleep();
-		 interrupts_disable();
-		 goto loop;
-	}
-	
+		cpu_sleep();
+		interrupts_disable();
+		goto loop;
+	}
+	
+	unsigned int i;
 	for (i = 0; i < RQ_COUNT; i++) {
-		r = &CPU->rq[i];
-		spinlock_lock(&r->lock);
-		if (r->n == 0) {
+		irq_spinlock_lock(&(CPU->rq[i].lock), false);
+		if (CPU->rq[i].n == 0) {
 			/*
 			 * If this queue is empty, try a lower-priority queue.
 			 */
-			spinlock_unlock(&r->lock);
+			irq_spinlock_unlock(&(CPU->rq[i].lock), false);
 			continue;
 		}
-
+		
 		atomic_dec(&CPU->nrdy);
 		atomic_dec(&nrdy);
-		r->n--;
-
+		CPU->rq[i].n--;
+		
 		/*
 		 * Take the first thread from the queue.
 		 */
-		t = list_get_instance(r->rq_head.next, thread_t, rq_link);
-		list_remove(&t->rq_link);
-
-		spinlock_unlock(&r->lock);
-
-		spinlock_lock(&t->lock);
-		t->cpu = CPU;
-
-		t->ticks = us2ticks((i + 1) * 10000);
-		t->priority = i;	/* correct rq index */
-
+		thread_t *thread =
+		    list_get_instance(CPU->rq[i].rq_head.next, thread_t, rq_link);
+		list_remove(&thread->rq_link);
+		
+		irq_spinlock_pass(&(CPU->rq[i].lock), &thread->lock);
+		
+		thread->cpu = CPU;
+		thread->ticks = us2ticks((i + 1) * 10000);
+		thread->priority = i;  /* Correct rq index */
+		
 		/*
 		 * Clear the THREAD_FLAG_STOLEN flag so that t can be migrated
 		 * when load balancing needs emerge.
 		 */
-		t->flags &= ~THREAD_FLAG_STOLEN;
-		spinlock_unlock(&t->lock);
-
-		return t;
-	}
+		thread->flags &= ~THREAD_FLAG_STOLEN;
+		irq_spinlock_unlock(&thread->lock, false);
+		
+		return thread;
+	}
+	
 	goto loop;
-
 }
 
@@ -267,30 +263,31 @@
 {
 	link_t head;
-	runq_t *r;
-	int i, n;
-
+	
 	list_initialize(&head);
-	spinlock_lock(&CPU->lock);
+	irq_spinlock_lock(&CPU->lock, false);
+	
 	if (CPU->needs_relink > NEEDS_RELINK_MAX) {
+		int i;
 		for (i = start; i < RQ_COUNT - 1; i++) {
-			/* remember and empty rq[i + 1] */
-			r = &CPU->rq[i + 1];
-			spinlock_lock(&r->lock);
-			list_concat(&head, &r->rq_head);
-			n = r->n;
-			r->n = 0;
-			spinlock_unlock(&r->lock);
-		
-			/* append rq[i + 1] to rq[i] */
-			r = &CPU->rq[i];
-			spinlock_lock(&r->lock);
-			list_concat(&r->rq_head, &head);
-			r->n += n;
-			spinlock_unlock(&r->lock);
+			/* Remember and empty rq[i + 1] */
+			
+			irq_spinlock_lock(&CPU->rq[i + 1].lock, false);
+			list_concat(&head, &CPU->rq[i + 1].rq_head);
+			size_t n = CPU->rq[i + 1].n;
+			CPU->rq[i + 1].n = 0;
+			irq_spinlock_unlock(&CPU->rq[i + 1].lock, false);
+			
+			/* Append rq[i + 1] to rq[i] */
+			
+			irq_spinlock_lock(&CPU->rq[i].lock, false);
+			list_concat(&CPU->rq[i].rq_head, &head);
+			CPU->rq[i].n += n;
+			irq_spinlock_unlock(&CPU->rq[i].lock, false);
 		}
+		
 		CPU->needs_relink = 0;
 	}
-	spinlock_unlock(&CPU->lock);
-
+	
+	irq_spinlock_unlock(&CPU->lock, false);
 }
 
@@ -305,14 +302,14 @@
 {
 	volatile ipl_t ipl;
-
+	
 	ASSERT(CPU != NULL);
-
+	
 	ipl = interrupts_disable();
-
+	
 	if (atomic_get(&haltstate))
 		halt();
 	
 	if (THREAD) {
-		spinlock_lock(&THREAD->lock);
+		irq_spinlock_lock(&THREAD->lock, false);
 		
 		/* Update thread kernel accounting */
@@ -330,25 +327,27 @@
 			THREAD->last_cycle = get_cycle();
 			
-			spinlock_unlock(&THREAD->lock);
+			irq_spinlock_unlock(&THREAD->lock, false);
 			interrupts_restore(THREAD->saved_context.ipl);
 			
 			return;
 		}
-
+		
 		/*
 		 * Interrupt priority level of preempted thread is recorded
 		 * here to facilitate scheduler() invocations from
-		 * interrupts_disable()'d code (e.g. waitq_sleep_timeout()). 
+		 * interrupts_disable()'d code (e.g. waitq_sleep_timeout()).
+		 *
 		 */
 		THREAD->saved_context.ipl = ipl;
 	}
-
+	
 	/*
 	 * Through the 'THE' structure, we keep track of THREAD, TASK, CPU, VM
 	 * and preemption counter. At this point THE could be coming either
 	 * from THREAD's or CPU's stack.
+	 *
 	 */
 	the_copy(THE, (the_t *) CPU->stack);
-
+	
 	/*
 	 * We may not keep the old stack.
@@ -362,4 +361,5 @@
 	 * Therefore the scheduler() function continues in
 	 * scheduler_separated_stack().
+	 *
 	 */
 	context_save(&CPU->saved_context);
@@ -367,5 +367,6 @@
 	    (uintptr_t) CPU->stack, CPU_STACK_SIZE);
 	context_restore(&CPU->saved_context);
-	/* not reached */
+	
+	/* Not reached */
 }
 
@@ -376,13 +377,12 @@
  * switch to a new thread.
  *
- * Assume THREAD->lock is held.
  */
 void scheduler_separated_stack(void)
 {
-	int priority;
 	DEADLOCK_PROBE_INIT(p_joinwq);
 	task_t *old_task = TASK;
 	as_t *old_as = AS;
-
+	
+	ASSERT((!THREAD) || (irq_spinlock_locked(&THREAD->lock)));
 	ASSERT(CPU != NULL);
 	
@@ -391,36 +391,40 @@
 	 * possible destruction should thread_destroy() be called on this or any
 	 * other processor while the scheduler is still using them.
+	 *
 	 */
 	if (old_task)
 		task_hold(old_task);
+	
 	if (old_as)
 		as_hold(old_as);
-
+	
 	if (THREAD) {
-		/* must be run after the switch to scheduler stack */
+		/* Must be run after the switch to scheduler stack */
 		after_thread_ran();
-
+		
 		switch (THREAD->state) {
 		case Running:
-			spinlock_unlock(&THREAD->lock);
+			irq_spinlock_unlock(&THREAD->lock, false);
 			thread_ready(THREAD);
 			break;
-
+		
 		case Exiting:
 repeat:
 			if (THREAD->detached) {
-				thread_destroy(THREAD);
+				thread_destroy(THREAD, false);
 			} else {
 				/*
 				 * The thread structure is kept allocated until
 				 * somebody calls thread_detach() on it.
+				 *
 				 */
-				if (!spinlock_trylock(&THREAD->join_wq.lock)) {
+				if (!irq_spinlock_trylock(&THREAD->join_wq.lock)) {
 					/*
 					 * Avoid deadlock.
+					 *
 					 */
-					spinlock_unlock(&THREAD->lock);
+					irq_spinlock_unlock(&THREAD->lock, false);
 					delay(HZ);
-					spinlock_lock(&THREAD->lock);
+					irq_spinlock_lock(&THREAD->lock, false);
 					DEADLOCK_PROBE(p_joinwq,
 					    DEADLOCK_THRESHOLD);
@@ -429,8 +433,8 @@
 				_waitq_wakeup_unsafe(&THREAD->join_wq,
 				    WAKEUP_FIRST);
-				spinlock_unlock(&THREAD->join_wq.lock);
+				irq_spinlock_unlock(&THREAD->join_wq.lock, false);
 				
 				THREAD->state = Lingering;
-				spinlock_unlock(&THREAD->lock);
+				irq_spinlock_unlock(&THREAD->lock, false);
 			}
 			break;
@@ -439,31 +443,23 @@
 			/*
 			 * Prefer the thread after it's woken up.
+			 *
 			 */
 			THREAD->priority = -1;
-
+			
 			/*
 			 * We need to release wq->lock which we locked in
 			 * waitq_sleep(). Address of wq->lock is kept in
 			 * THREAD->sleep_queue.
+			 *
 			 */
-			spinlock_unlock(&THREAD->sleep_queue->lock);
-
-			/*
-			 * Check for possible requests for out-of-context
-			 * invocation.
-			 */
-			if (THREAD->call_me) {
-				THREAD->call_me(THREAD->call_me_with);
-				THREAD->call_me = NULL;
-				THREAD->call_me_with = NULL;
-			}
-
-			spinlock_unlock(&THREAD->lock);
-
+			irq_spinlock_unlock(&THREAD->sleep_queue->lock, false);
+			
+			irq_spinlock_unlock(&THREAD->lock, false);
 			break;
-
+		
 		default:
 			/*
 			 * Entering state is unexpected.
+			 *
 			 */
 			panic("tid%" PRIu64 ": unexpected state %s.",
@@ -471,19 +467,20 @@
 			break;
 		}
-
+		
 		THREAD = NULL;
 	}
-
+	
 	THREAD = find_best_thread();
 	
-	spinlock_lock(&THREAD->lock);
-	priority = THREAD->priority;
-	spinlock_unlock(&THREAD->lock);	
-
-	relink_rq(priority);		
-
+	irq_spinlock_lock(&THREAD->lock, false);
+	int priority = THREAD->priority;
+	irq_spinlock_unlock(&THREAD->lock, false);
+	
+	relink_rq(priority);
+	
 	/*
 	 * If both the old and the new task are the same, lots of work is
 	 * avoided.
+	 *
 	 */
 	if (TASK != THREAD->task) {
@@ -493,4 +490,5 @@
 		 * Note that it is possible for two tasks to share one address
 		 * space.
+		 (
 		 */
 		if (old_as != new_as) {
@@ -498,26 +496,28 @@
 			 * Both tasks and address spaces are different.
 			 * Replace the old one with the new one.
+			 *
 			 */
 			as_switch(old_as, new_as);
 		}
-
+		
 		TASK = THREAD->task;
 		before_task_runs();
 	}
-
+	
 	if (old_task)
 		task_release(old_task);
+	
 	if (old_as)
 		as_release(old_as);
 	
-	spinlock_lock(&THREAD->lock);	
+	irq_spinlock_lock(&THREAD->lock, false);
 	THREAD->state = Running;
-
+	
 #ifdef SCHEDULER_VERBOSE
 	printf("cpu%u: tid %" PRIu64 " (priority=%d, ticks=%" PRIu64 
 	    ", nrdy=%ld)\n", CPU->id, THREAD->tid, THREAD->priority,
 	    THREAD->ticks, atomic_get(&CPU->nrdy));
-#endif	
-
+#endif
+	
 	/*
 	 * Some architectures provide late kernel PA2KA(identity)
@@ -527,15 +527,18 @@
 	 * necessary, is to be mapped in before_thread_runs(). This
 	 * function must be executed before the switch to the new stack.
+	 *
 	 */
 	before_thread_runs();
-
+	
 	/*
 	 * Copy the knowledge of CPU, TASK, THREAD and preemption counter to
 	 * thread's stack.
+	 *
 	 */
 	the_copy(THE, (the_t *) THREAD->kstack);
 	
 	context_restore(&THREAD->saved_context);
-	/* not reached */
+	
+	/* Not reached */
 }
 
@@ -551,12 +554,7 @@
 void kcpulb(void *arg)
 {
-	thread_t *t;
-	int count;
 	atomic_count_t average;
-	unsigned int i;
-	int j;
-	int k = 0;
-	ipl_t ipl;
-
+	atomic_count_t rdy;
+	
 	/*
 	 * Detach kcpulb as nobody will call thread_join_timeout() on it.
@@ -569,5 +567,5 @@
 	 */
 	thread_sleep(1);
-
+	
 not_satisfied:
 	/*
@@ -575,46 +573,53 @@
 	 * other CPU's. Note that situation can have changed between two
 	 * passes. Each time get the most up to date counts.
+	 *
 	 */
 	average = atomic_get(&nrdy) / config.cpu_active + 1;
-	count = average - atomic_get(&CPU->nrdy);
-
-	if (count <= 0)
+	rdy = atomic_get(&CPU->nrdy);
+	
+	if (average <= rdy)
 		goto satisfied;
-
+	
+	atomic_count_t count = average - rdy;
+	
 	/*
 	 * Searching least priority queues on all CPU's first and most priority
 	 * queues on all CPU's last.
-	 */
-	for (j = RQ_COUNT - 1; j >= 0; j--) {
-		for (i = 0; i < config.cpu_active; i++) {
-			link_t *l;
-			runq_t *r;
-			cpu_t *cpu;
-
-			cpu = &cpus[(i + k) % config.cpu_active];
-
+	 *
+	 */
+	size_t acpu;
+	size_t acpu_bias = 0;
+	int rq;
+	
+	for (rq = RQ_COUNT - 1; rq >= 0; rq--) {
+		for (acpu = 0; acpu < config.cpu_active; acpu++) {
+			cpu_t *cpu = &cpus[(acpu + acpu_bias) % config.cpu_active];
+			
 			/*
 			 * Not interested in ourselves.
 			 * Doesn't require interrupt disabling for kcpulb has
 			 * THREAD_FLAG_WIRED.
+			 *
 			 */
 			if (CPU == cpu)
 				continue;
+			
 			if (atomic_get(&cpu->nrdy) <= average)
 				continue;
-
-			ipl = interrupts_disable();
-			r = &cpu->rq[j];
-			spinlock_lock(&r->lock);
-			if (r->n == 0) {
-				spinlock_unlock(&r->lock);
-				interrupts_restore(ipl);
+			
+			irq_spinlock_lock(&(cpu->rq[rq].lock), true);
+			if (cpu->rq[rq].n == 0) {
+				irq_spinlock_unlock(&(cpu->rq[rq].lock), true);
 				continue;
 			}
-		
-			t = NULL;
-			l = r->rq_head.prev;	/* search rq from the back */
-			while (l != &r->rq_head) {
-				t = list_get_instance(l, thread_t, rq_link);
+			
+			thread_t *thread = NULL;
+			
+			/* Search rq from the back */
+			link_t *link = cpu->rq[rq].rq_head.prev;
+			
+			while (link != &(cpu->rq[rq].rq_head)) {
+				thread = (thread_t *) list_get_instance(link, thread_t, rq_link);
+				
 				/*
 				 * We don't want to steal CPU-wired threads
@@ -624,33 +629,38 @@
 				 * steal threads whose FPU context is still in
 				 * CPU.
+				 *
 				 */
-				spinlock_lock(&t->lock);
-				if ((!(t->flags & (THREAD_FLAG_WIRED |
-				    THREAD_FLAG_STOLEN))) &&
-				    (!(t->fpu_context_engaged))) {
+				irq_spinlock_lock(&thread->lock, false);
+				
+				if ((!(thread->flags & (THREAD_FLAG_WIRED | THREAD_FLAG_STOLEN)))
+				    && (!(thread->fpu_context_engaged))) {
 					/*
-					 * Remove t from r.
+					 * Remove thread from ready queue.
 					 */
-					spinlock_unlock(&t->lock);
+					irq_spinlock_unlock(&thread->lock, false);
 					
 					atomic_dec(&cpu->nrdy);
 					atomic_dec(&nrdy);
-
-					r->n--;
-					list_remove(&t->rq_link);
-
+					
+					cpu->rq[rq].n--;
+					list_remove(&thread->rq_link);
+					
 					break;
 				}
-				spinlock_unlock(&t->lock);
-				l = l->prev;
-				t = NULL;
+				
+				irq_spinlock_unlock(&thread->lock, false);
+				
+				link = link->prev;
+				thread = NULL;
 			}
-			spinlock_unlock(&r->lock);
-
-			if (t) {
+			
+			if (thread) {
 				/*
-				 * Ready t on local CPU
+				 * Ready thread on local CPU
+				 *
 				 */
-				spinlock_lock(&t->lock);
+				
+				irq_spinlock_pass(&(cpu->rq[rq].lock), &thread->lock);
+				
 #ifdef KCPULB_VERBOSE
 				printf("kcpulb%u: TID %" PRIu64 " -> cpu%u, "
@@ -659,30 +669,32 @@
 				    atomic_get(&nrdy) / config.cpu_active);
 #endif
-				t->flags |= THREAD_FLAG_STOLEN;
-				t->state = Entering;
-				spinlock_unlock(&t->lock);
-	
-				thread_ready(t);
-
-				interrupts_restore(ipl);
-	
+				
+				thread->flags |= THREAD_FLAG_STOLEN;
+				thread->state = Entering;
+				
+				irq_spinlock_unlock(&thread->lock, true);
+				thread_ready(thread);
+				
 				if (--count == 0)
 					goto satisfied;
-					
+				
 				/*
 				 * We are not satisfied yet, focus on another
 				 * CPU next time.
+				 *
 				 */
-				k++;
+				acpu_bias++;
 				
 				continue;
-			}
-			interrupts_restore(ipl);
+			} else
+				irq_spinlock_unlock(&(cpu->rq[rq].lock), true);
+			
 		}
 	}
-
+	
 	if (atomic_get(&CPU->nrdy)) {
 		/*
 		 * Be a little bit light-weight and let migrated threads run.
+		 *
 		 */
 		scheduler();
@@ -691,60 +703,56 @@
 		 * We failed to migrate a single thread.
 		 * Give up this turn.
+		 *
 		 */
 		goto loop;
 	}
-		
+	
 	goto not_satisfied;
-
+	
 satisfied:
 	goto loop;
 }
-
 #endif /* CONFIG_SMP */
 
-
-/** Print information about threads & scheduler queues */
+/** Print information about threads & scheduler queues
+ *
+ */
 void sched_print_list(void)
 {
-	ipl_t ipl;
-	unsigned int cpu, i;
-	runq_t *r;
-	thread_t *t;
-	link_t *cur;
-
-	/* We are going to mess with scheduler structures,
-	 * let's not be interrupted */
-	ipl = interrupts_disable();
+	size_t cpu;
 	for (cpu = 0; cpu < config.cpu_count; cpu++) {
-
 		if (!cpus[cpu].active)
 			continue;
-
-		spinlock_lock(&cpus[cpu].lock);
+		
+		irq_spinlock_lock(&cpus[cpu].lock, true);
+		
 		printf("cpu%u: address=%p, nrdy=%ld, needs_relink=%" PRIs "\n",
 		    cpus[cpu].id, &cpus[cpu], atomic_get(&cpus[cpu].nrdy),
 		    cpus[cpu].needs_relink);
 		
+		unsigned int i;
 		for (i = 0; i < RQ_COUNT; i++) {
-			r = &cpus[cpu].rq[i];
-			spinlock_lock(&r->lock);
-			if (!r->n) {
-				spinlock_unlock(&r->lock);
+			irq_spinlock_lock(&(cpus[cpu].rq[i].lock), false);
+			if (cpus[cpu].rq[i].n == 0) {
+				irq_spinlock_unlock(&(cpus[cpu].rq[i].lock), false);
 				continue;
 			}
+			
 			printf("\trq[%u]: ", i);
-			for (cur = r->rq_head.next; cur != &r->rq_head;
-				cur = cur->next) {
-				t = list_get_instance(cur, thread_t, rq_link);
-				printf("%" PRIu64 "(%s) ", t->tid,
-				    thread_states[t->state]);
+			link_t *cur;
+			for (cur = cpus[cpu].rq[i].rq_head.next;
+			    cur != &(cpus[cpu].rq[i].rq_head);
+			    cur = cur->next) {
+				thread_t *thread = list_get_instance(cur, thread_t, rq_link);
+				printf("%" PRIu64 "(%s) ", thread->tid,
+				    thread_states[thread->state]);
 			}
 			printf("\n");
-			spinlock_unlock(&r->lock);
+			
+			irq_spinlock_unlock(&(cpus[cpu].rq[i].lock), false);
 		}
-		spinlock_unlock(&cpus[cpu].lock);
-	}
-	
-	interrupts_restore(ipl);
+		
+		irq_spinlock_unlock(&cpus[cpu].lock, true);
+	}
 }
 
Index: kernel/generic/src/proc/task.c
===================================================================
--- kernel/generic/src/proc/task.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/generic/src/proc/task.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -60,5 +60,5 @@
 
 /** Spinlock protecting the tasks_tree AVL tree. */
-SPINLOCK_INITIALIZE(tasks_lock);
+IRQ_SPINLOCK_INITIALIZE(tasks_lock);
 
 /** AVL tree of active tasks.
@@ -81,7 +81,9 @@
 /* Forward declarations. */
 static void task_kill_internal(task_t *);
-static int tsk_constructor(void *, int);
-
-/** Initialize kernel tasks support. */
+static int tsk_constructor(void *, unsigned int);
+
+/** Initialize kernel tasks support.
+ *
+ */
 void task_init(void)
 {
@@ -92,19 +94,23 @@
 }
 
-/*
+/** Task finish walker.
+ *
  * The idea behind this walker is to kill and count all tasks different from
  * TASK.
+ *
  */
 static bool task_done_walker(avltree_node_t *node, void *arg)
 {
-	task_t *t = avltree_get_instance(node, task_t, tasks_tree_node);
-	unsigned *cnt = (unsigned *) arg;
-	
-	if (t != TASK) {
+	task_t *task = avltree_get_instance(node, task_t, tasks_tree_node);
+	size_t *cnt = (size_t *) arg;
+	
+	if (task != TASK) {
 		(*cnt)++;
+		
 #ifdef CONFIG_DEBUG
-		printf("[%"PRIu64"] ", t->taskid);
-#endif
-		task_kill_internal(t);
+		printf("[%"PRIu64"] ", task->taskid);
+#endif
+		
+		task_kill_internal(task);
 	}
 	
@@ -113,51 +119,55 @@
 }
 
-/** Kill all tasks except the current task. */
+/** Kill all tasks except the current task.
+ *
+ */
 void task_done(void)
 {
-	unsigned tasks_left;
-	
-	do { /* Repeat until there are any tasks except TASK */
-		/* Messing with task structures, avoid deadlock */
+	size_t tasks_left;
+	
+	/* Repeat until there are any tasks except TASK */
+	do {
 #ifdef CONFIG_DEBUG
 		printf("Killing tasks... ");
 #endif
-		ipl_t ipl = interrupts_disable();
-		spinlock_lock(&tasks_lock);
+		
+		irq_spinlock_lock(&tasks_lock, true);
 		tasks_left = 0;
 		avltree_walk(&tasks_tree, task_done_walker, &tasks_left);
-		spinlock_unlock(&tasks_lock);
-		interrupts_restore(ipl);
+		irq_spinlock_unlock(&tasks_lock, true);
+		
 		thread_sleep(1);
+		
 #ifdef CONFIG_DEBUG
 		printf("\n");
 #endif
-	} while (tasks_left);
-}
-
-int tsk_constructor(void *obj, int kmflags)
-{
-	task_t *ta = obj;
-	int i;
-	
-	atomic_set(&ta->refcount, 0);
-	atomic_set(&ta->lifecount, 0);
-	atomic_set(&ta->active_calls, 0);
-	
-	spinlock_initialize(&ta->lock, "task_ta_lock");
-	mutex_initialize(&ta->futexes_lock, MUTEX_PASSIVE);
-	
-	list_initialize(&ta->th_head);
-	list_initialize(&ta->sync_box_head);
-	
-	ipc_answerbox_init(&ta->answerbox, ta);
+	} while (tasks_left > 0);
+}
+
+int tsk_constructor(void *obj, unsigned int kmflags)
+{
+	task_t *task = (task_t *) obj;
+	
+	atomic_set(&task->refcount, 0);
+	atomic_set(&task->lifecount, 0);
+	atomic_set(&task->active_calls, 0);
+	
+	irq_spinlock_initialize(&task->lock, "task_t_lock");
+	mutex_initialize(&task->futexes_lock, MUTEX_PASSIVE);
+	
+	list_initialize(&task->th_head);
+	list_initialize(&task->sync_box_head);
+	
+	ipc_answerbox_init(&task->answerbox, task);
+	
+	size_t i;
 	for (i = 0; i < IPC_MAX_PHONES; i++)
-		ipc_phone_init(&ta->phones[i]);
+		ipc_phone_init(&task->phones[i]);
 	
 #ifdef CONFIG_UDEBUG
 	/* Init kbox stuff */
-	ta->kb.thread = NULL;
-	ipc_answerbox_init(&ta->kb.box, ta);
-	mutex_initialize(&ta->kb.cleanup_lock, MUTEX_PASSIVE);
+	task->kb.thread = NULL;
+	ipc_answerbox_init(&task->kb.box, task);
+	mutex_initialize(&task->kb.cleanup_lock, MUTEX_PASSIVE);
 #endif
 	
@@ -175,86 +185,83 @@
 task_t *task_create(as_t *as, const char *name)
 {
-	ipl_t ipl;
-	task_t *ta;
-	
-	ta = (task_t *) slab_alloc(task_slab, 0);
-	task_create_arch(ta);
-	ta->as = as;
-	memcpy(ta->name, name, TASK_NAME_BUFLEN);
-	ta->name[TASK_NAME_BUFLEN - 1] = 0;
-	
-	ta->context = CONTEXT;
-	ta->capabilities = 0;
-	ta->ucycles = 0;
-	ta->kcycles = 0;
-
-	ta->ipc_info.call_sent = 0;
-	ta->ipc_info.call_recieved = 0;
-	ta->ipc_info.answer_sent = 0;
-	ta->ipc_info.answer_recieved = 0;
-	ta->ipc_info.irq_notif_recieved = 0;
-	ta->ipc_info.forwarded = 0;
-
+	task_t *task = (task_t *) slab_alloc(task_slab, 0);
+	task_create_arch(task);
+	
+	task->as = as;
+	str_cpy(task->name, TASK_NAME_BUFLEN, name);
+	
+	task->context = CONTEXT;
+	task->capabilities = 0;
+	task->ucycles = 0;
+	task->kcycles = 0;
+	
+	task->ipc_info.call_sent = 0;
+	task->ipc_info.call_received = 0;
+	task->ipc_info.answer_sent = 0;
+	task->ipc_info.answer_received = 0;
+	task->ipc_info.irq_notif_received = 0;
+	task->ipc_info.forwarded = 0;
+	
 #ifdef CONFIG_UDEBUG
 	/* Init debugging stuff */
-	udebug_task_init(&ta->udebug);
+	udebug_task_init(&task->udebug);
 	
 	/* Init kbox stuff */
-	ta->kb.finished = false;
+	task->kb.finished = false;
 #endif
 	
 	if ((ipc_phone_0) &&
-	    (context_check(ipc_phone_0->task->context, ta->context)))
-		ipc_phone_connect(&ta->phones[0], ipc_phone_0);
-	
-	btree_create(&ta->futexes);
+	    (context_check(ipc_phone_0->task->context, task->context)))
+		ipc_phone_connect(&task->phones[0], ipc_phone_0);
+	
+	btree_create(&task->futexes);
 	
 	/*
 	 * Get a reference to the address space.
 	 */
-	as_hold(ta->as);
-
-	ipl = interrupts_disable();
-	spinlock_lock(&tasks_lock);
-	ta->taskid = ++task_counter;
-	avltree_node_initialize(&ta->tasks_tree_node);
-	ta->tasks_tree_node.key = ta->taskid; 
-	avltree_insert(&tasks_tree, &ta->tasks_tree_node);
-	spinlock_unlock(&tasks_lock);
-	interrupts_restore(ipl);
-	
-	return ta;
+	as_hold(task->as);
+	
+	irq_spinlock_lock(&tasks_lock, true);
+	
+	task->taskid = ++task_counter;
+	avltree_node_initialize(&task->tasks_tree_node);
+	task->tasks_tree_node.key = task->taskid;
+	avltree_insert(&tasks_tree, &task->tasks_tree_node);
+	
+	irq_spinlock_unlock(&tasks_lock, true);
+	
+	return task;
 }
 
 /** Destroy task.
  *
- * @param t Task to be destroyed.
- *
- */
-void task_destroy(task_t *t)
+ * @param task Task to be destroyed.
+ *
+ */
+void task_destroy(task_t *task)
 {
 	/*
 	 * Remove the task from the task B+tree.
 	 */
-	spinlock_lock(&tasks_lock);
-	avltree_delete(&tasks_tree, &t->tasks_tree_node);
-	spinlock_unlock(&tasks_lock);
+	irq_spinlock_lock(&tasks_lock, true);
+	avltree_delete(&tasks_tree, &task->tasks_tree_node);
+	irq_spinlock_unlock(&tasks_lock, true);
 	
 	/*
 	 * Perform architecture specific task destruction.
 	 */
-	task_destroy_arch(t);
+	task_destroy_arch(task);
 	
 	/*
 	 * Free up dynamically allocated state.
 	 */
-	btree_destroy(&t->futexes);
+	btree_destroy(&task->futexes);
 	
 	/*
 	 * Drop our reference to the address space.
 	 */
-	as_release(t->as);
-	
-	slab_free(task_slab, t);
+	as_release(task->as);
+	
+	slab_free(task_slab, task);
 }
 
@@ -263,9 +270,10 @@
  * Holding a reference to a task prevents destruction of that task.
  *
- * @param t		Task to be held.
- */
-void task_hold(task_t *t)
-{
-	atomic_inc(&t->refcount);
+ * @param task Task to be held.
+ *
+ */
+void task_hold(task_t *task)
+{
+	atomic_inc(&task->refcount);
 }
 
@@ -274,10 +282,11 @@
  * The last one to release a reference to a task destroys the task.
  *
- * @param t		Task to be released.
- */
-void task_release(task_t *t)
-{
-	if ((atomic_predec(&t->refcount)) == 0)
-		task_destroy(t);
+ * @param task Task to be released.
+ *
+ */
+void task_release(task_t *task)
+{
+	if ((atomic_predec(&task->refcount)) == 0)
+		task_destroy(task);
 }
 
@@ -342,9 +351,12 @@
 task_t *task_find_by_id(task_id_t id)
 {
+	ASSERT(interrupts_disabled());
+	ASSERT(irq_spinlock_locked(&tasks_lock));
+
 	avltree_node_t *node =
 	    avltree_search(&tasks_tree, (avltree_key_t) id);
 	
 	if (node)
-		return avltree_get_instance(node, task_t, tasks_tree_node); 
+		return avltree_get_instance(node, task_t, tasks_tree_node);
 	
 	return NULL;
@@ -353,34 +365,40 @@
 /** Get accounting data of given task.
  *
- * Note that task lock of 't' must be already held and interrupts must be
+ * Note that task lock of 'task' must be already held and interrupts must be
  * already disabled.
  *
- * @param t       Pointer to thread.
+ * @param task    Pointer to the task.
  * @param ucycles Out pointer to sum of all user cycles.
  * @param kcycles Out pointer to sum of all kernel cycles.
  *
  */
-void task_get_accounting(task_t *t, uint64_t *ucycles, uint64_t *kcycles)
-{
+void task_get_accounting(task_t *task, uint64_t *ucycles, uint64_t *kcycles)
+{
+	ASSERT(interrupts_disabled());
+	ASSERT(irq_spinlock_locked(&task->lock));
+
 	/* Accumulated values of task */
-	uint64_t uret = t->ucycles;
-	uint64_t kret = t->kcycles;
+	uint64_t uret = task->ucycles;
+	uint64_t kret = task->kcycles;
 	
 	/* Current values of threads */
 	link_t *cur;
-	for (cur = t->th_head.next; cur != &t->th_head; cur = cur->next) {
-		thread_t *thr = list_get_instance(cur, thread_t, th_link);
-		
-		spinlock_lock(&thr->lock);
+	for (cur = task->th_head.next; cur != &task->th_head; cur = cur->next) {
+		thread_t *thread = list_get_instance(cur, thread_t, th_link);
+		
+		irq_spinlock_lock(&thread->lock, false);
+		
 		/* Process only counted threads */
-		if (!thr->uncounted) {
-			if (thr == THREAD) {
+		if (!thread->uncounted) {
+			if (thread == THREAD) {
 				/* Update accounting of current thread */
 				thread_update_accounting(false);
-			} 
-			uret += thr->ucycles;
-			kret += thr->kcycles;
+			}
+			
+			uret += thread->ucycles;
+			kret += thread->kcycles;
 		}
-		spinlock_unlock(&thr->lock);
+		
+		irq_spinlock_unlock(&thread->lock, false);
 	}
 	
@@ -389,5 +407,5 @@
 }
 
-static void task_kill_internal(task_t *ta)
+static void task_kill_internal(task_t *task)
 {
 	link_t *cur;
@@ -396,21 +414,22 @@
 	 * Interrupt all threads.
 	 */
-	spinlock_lock(&ta->lock);
-	for (cur = ta->th_head.next; cur != &ta->th_head; cur = cur->next) {
-		thread_t *thr;
+	irq_spinlock_lock(&task->lock, false);
+	for (cur = task->th_head.next; cur != &task->th_head; cur = cur->next) {
+		thread_t *thread = list_get_instance(cur, thread_t, th_link);
 		bool sleeping = false;
 		
-		thr = list_get_instance(cur, thread_t, th_link);
-		
-		spinlock_lock(&thr->lock);
-		thr->interrupted = true;
-		if (thr->state == Sleeping)
+		irq_spinlock_lock(&thread->lock, false);
+		
+		thread->interrupted = true;
+		if (thread->state == Sleeping)
 			sleeping = true;
-		spinlock_unlock(&thr->lock);
+		
+		irq_spinlock_unlock(&thread->lock, false);
 		
 		if (sleeping)
-			waitq_interrupt_sleep(thr);
+			waitq_interrupt_sleep(thread);
 	}
-	spinlock_unlock(&ta->lock);
+	
+	irq_spinlock_unlock(&task->lock, false);
 }
 
@@ -427,88 +446,98 @@
 int task_kill(task_id_t id)
 {
-	ipl_t ipl;
-	task_t *ta;
-
 	if (id == 1)
 		return EPERM;
 	
-	ipl = interrupts_disable();
-	spinlock_lock(&tasks_lock);
-	if (!(ta = task_find_by_id(id))) {
-		spinlock_unlock(&tasks_lock);
-		interrupts_restore(ipl);
+	irq_spinlock_lock(&tasks_lock, true);
+	
+	task_t *task = task_find_by_id(id);
+	if (!task) {
+		irq_spinlock_unlock(&tasks_lock, true);
 		return ENOENT;
 	}
-	task_kill_internal(ta);
-	spinlock_unlock(&tasks_lock);
-	interrupts_restore(ipl);
-	return 0;
+	
+	task_kill_internal(task);
+	irq_spinlock_unlock(&tasks_lock, true);
+	
+	return EOK;
 }
 
 static bool task_print_walker(avltree_node_t *node, void *arg)
 {
-	task_t *t = avltree_get_instance(node, task_t, tasks_tree_node);
-	int j;
-	
-	spinlock_lock(&t->lock);
+	bool *additional = (bool *) arg;
+	task_t *task = avltree_get_instance(node, task_t, tasks_tree_node);
+	irq_spinlock_lock(&task->lock, false);
 	
 	uint64_t ucycles;
 	uint64_t kcycles;
 	char usuffix, ksuffix;
-	task_get_accounting(t, &ucycles, &kcycles);
+	task_get_accounting(task, &ucycles, &kcycles);
 	order_suffix(ucycles, &ucycles, &usuffix);
 	order_suffix(kcycles, &kcycles, &ksuffix);
 	
-#ifdef __32_BITS__	
-	printf("%-6" PRIu64 " %-12s %-3" PRIu32 " %10p %10p %9" PRIu64 "%c %9"
-		PRIu64 "%c %7ld %6ld", t->taskid, t->name, t->context, t, t->as,
-		ucycles, usuffix, kcycles, ksuffix, atomic_get(&t->refcount),
-		atomic_get(&t->active_calls));
+#ifdef __32_BITS__
+	if (*additional)
+		printf("%-8" PRIu64 " %9lu %7lu", task->taskid,
+		    atomic_get(&task->refcount), atomic_get(&task->active_calls));
+	else
+		printf("%-8" PRIu64 " %-14s %-5" PRIu32 " %10p %10p"
+		    " %9" PRIu64 "%c %9" PRIu64 "%c\n", task->taskid,
+		    task->name, task->context, task, task->as,
+		    ucycles, usuffix, kcycles, ksuffix);
 #endif
 	
 #ifdef __64_BITS__
-	printf("%-6" PRIu64 " %-12s %-3" PRIu32 " %18p %18p %9" PRIu64 "%c %9"
-		PRIu64 "%c %7ld %6ld", t->taskid, t->name, t->context, t, t->as,
-		ucycles, usuffix, kcycles, ksuffix, atomic_get(&t->refcount),
-		atomic_get(&t->active_calls));
-#endif
-	
-	for (j = 0; j < IPC_MAX_PHONES; j++) {
-		if (t->phones[j].callee)
-			printf(" %d:%p", j, t->phones[j].callee);
+	if (*additional)
+		printf("%-8" PRIu64 " %9" PRIu64 "%c %9" PRIu64 "%c %9lu %7lu",
+		    task->taskid, ucycles, usuffix, kcycles, ksuffix,
+		    atomic_get(&task->refcount), atomic_get(&task->active_calls));
+	else
+		printf("%-8" PRIu64 " %-14s %-5" PRIu32 " %18p %18p\n",
+		    task->taskid, task->name, task->context, task, task->as);
+#endif
+	
+	if (*additional) {
+		size_t i;
+		for (i = 0; i < IPC_MAX_PHONES; i++) {
+			if (task->phones[i].callee)
+				printf(" %" PRIs ":%p", i, task->phones[i].callee);
+		}
+		printf("\n");
 	}
-	printf("\n");
-	
-	spinlock_unlock(&t->lock);
+	
+	irq_spinlock_unlock(&task->lock, false);
 	return true;
 }
 
-/** Print task list */
-void task_print_list(void)
-{
-	ipl_t ipl;
-	
+/** Print task list
+ *
+ * @param additional Print additional information.
+ *
+ */
+void task_print_list(bool additional)
+{
 	/* Messing with task structures, avoid deadlock */
-	ipl = interrupts_disable();
-	spinlock_lock(&tasks_lock);
+	irq_spinlock_lock(&tasks_lock, true);
 	
 #ifdef __32_BITS__
-	printf("taskid name         ctx address    as        "
-	    " ucycles    kcycles    threads calls  callee\n");
-	printf("------ ------------ --- ---------- ----------"
-	    " ---------- ---------- ------- ------ ------>\n");
+	if (additional)
+		printf("[id    ] [threads] [calls] [callee\n");
+	else
+		printf("[id    ] [name        ] [ctx] [address ] [as      ]"
+		    " [ucycles ] [kcycles ]\n");
 #endif
 	
 #ifdef __64_BITS__
-	printf("taskid name         ctx address            as                "
-	    " ucycles    kcycles    threads calls  callee\n");
-	printf("------ ------------ --- ------------------ ------------------"
-	    " ---------- ---------- ---------- ------- ------ ------>\n");
-#endif
-	
-	avltree_walk(&tasks_tree, task_print_walker, NULL);
-	
-	spinlock_unlock(&tasks_lock);
-	interrupts_restore(ipl);
+	if (additional)
+		printf("[id    ] [ucycles ] [kcycles ] [threads] [calls]"
+		    " [callee\n");
+	else
+		printf("[id    ] [name        ] [ctx] [address         ]"
+		    " [as              ]\n");
+#endif
+	
+	avltree_walk(&tasks_tree, task_print_walker, &additional);
+	
+	irq_spinlock_unlock(&tasks_lock, true);
 }
 
Index: kernel/generic/src/proc/the.c
===================================================================
--- kernel/generic/src/proc/the.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/generic/src/proc/the.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -33,5 +33,5 @@
 /**
  * @file
- * @brief	THE structure functions.
+ * @brief THE structure functions.
  *
  * This file contains functions to manage the THE structure.
@@ -44,5 +44,4 @@
 #include <arch.h>
 
-
 /** Initialize THE structure
  *
@@ -50,4 +49,5 @@
  *
  * @param the THE structure to be initialized.
+ *
  */
 void the_initialize(the_t *the)
@@ -66,6 +66,7 @@
  * @param src The source THE structure.
  * @param dst The destination THE structure.
+ *
  */
-void the_copy(the_t *src, the_t *dst)
+NO_TRACE void the_copy(the_t *src, the_t *dst)
 {
 	*dst = *src;
Index: kernel/generic/src/proc/thread.c
===================================================================
--- kernel/generic/src/proc/thread.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/generic/src/proc/thread.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -33,5 +33,5 @@
 /**
  * @file
- * @brief	Thread management functions.
+ * @brief Thread management functions.
  */
 
@@ -48,5 +48,4 @@
 #include <synch/spinlock.h>
 #include <synch/waitq.h>
-#include <synch/rwlock.h>
 #include <cpu.h>
 #include <str.h>
@@ -94,6 +93,7 @@
  *
  * For locking rules, see declaration thereof.
- */
-SPINLOCK_INITIALIZE(threads_lock);
+ *
+ */
+IRQ_SPINLOCK_INITIALIZE(threads_lock);
 
 /** AVL tree of all threads.
@@ -101,11 +101,13 @@
  * When a thread is found in the threads_tree AVL tree, it is guaranteed to
  * exist as long as the threads_lock is held.
- */
-avltree_t threads_tree;		
-
-SPINLOCK_INITIALIZE(tidlock);
-thread_id_t last_tid = 0;
+ *
+ */
+avltree_t threads_tree;
+
+IRQ_SPINLOCK_STATIC_INITIALIZE(tidlock);
+static thread_id_t last_tid = 0;
 
 static slab_cache_t *thread_slab;
+
 #ifdef CONFIG_FPU
 slab_cache_t *fpu_context_slab;
@@ -125,15 +127,13 @@
 	void *arg = THREAD->thread_arg;
 	THREAD->last_cycle = get_cycle();
-
+	
 	/* This is where each thread wakes up after its creation */
-	spinlock_unlock(&THREAD->lock);
+	irq_spinlock_unlock(&THREAD->lock, false);
 	interrupts_enable();
-
+	
 	f(arg);
 	
 	/* Accumulate accounting to the task */
-	ipl_t ipl = interrupts_disable();
-	
-	spinlock_lock(&THREAD->lock);
+	irq_spinlock_lock(&THREAD->lock, true);
 	if (!THREAD->uncounted) {
 		thread_update_accounting(true);
@@ -142,73 +142,74 @@
 		uint64_t kcycles = THREAD->kcycles;
 		THREAD->kcycles = 0;
-
-		spinlock_unlock(&THREAD->lock);
 		
-		spinlock_lock(&TASK->lock);
+		irq_spinlock_pass(&THREAD->lock, &TASK->lock);
 		TASK->ucycles += ucycles;
 		TASK->kcycles += kcycles;
-		spinlock_unlock(&TASK->lock);
+		irq_spinlock_unlock(&TASK->lock, true);
 	} else
-		spinlock_unlock(&THREAD->lock);
-	
-	interrupts_restore(ipl);
+		irq_spinlock_unlock(&THREAD->lock, true);
 	
 	thread_exit();
-	/* not reached */
-}
-
-/** Initialization and allocation for thread_t structure */
-static int thr_constructor(void *obj, int kmflags)
-{
-	thread_t *t = (thread_t *) obj;
-
-	spinlock_initialize(&t->lock, "thread_t_lock");
-	link_initialize(&t->rq_link);
-	link_initialize(&t->wq_link);
-	link_initialize(&t->th_link);
-
+	
+	/* Not reached */
+}
+
+/** Initialization and allocation for thread_t structure
+ *
+ */
+static int thr_constructor(void *obj, unsigned int kmflags)
+{
+	thread_t *thread = (thread_t *) obj;
+	
+	irq_spinlock_initialize(&thread->lock, "thread_t_lock");
+	link_initialize(&thread->rq_link);
+	link_initialize(&thread->wq_link);
+	link_initialize(&thread->th_link);
+	
 	/* call the architecture-specific part of the constructor */
-	thr_constructor_arch(t);
+	thr_constructor_arch(thread);
 	
 #ifdef CONFIG_FPU
 #ifdef CONFIG_FPU_LAZY
-	t->saved_fpu_context = NULL;
-#else
-	t->saved_fpu_context = slab_alloc(fpu_context_slab, kmflags);
-	if (!t->saved_fpu_context)
+	thread->saved_fpu_context = NULL;
+#else /* CONFIG_FPU_LAZY */
+	thread->saved_fpu_context = slab_alloc(fpu_context_slab, kmflags);
+	if (!thread->saved_fpu_context)
 		return -1;
-#endif
-#endif
-
-	t->kstack = (uint8_t *) frame_alloc(STACK_FRAMES, FRAME_KA | kmflags);
-	if (!t->kstack) {
+#endif /* CONFIG_FPU_LAZY */
+#endif /* CONFIG_FPU */
+	
+	thread->kstack = (uint8_t *) frame_alloc(STACK_FRAMES, FRAME_KA | kmflags);
+	if (!thread->kstack) {
 #ifdef CONFIG_FPU
-		if (t->saved_fpu_context)
-			slab_free(fpu_context_slab, t->saved_fpu_context);
+		if (thread->saved_fpu_context)
+			slab_free(fpu_context_slab, thread->saved_fpu_context);
 #endif
 		return -1;
 	}
-
+	
 #ifdef CONFIG_UDEBUG
-	mutex_initialize(&t->udebug.lock, MUTEX_PASSIVE);
-#endif
-
+	mutex_initialize(&thread->udebug.lock, MUTEX_PASSIVE);
+#endif
+	
 	return 0;
 }
 
 /** Destruction of thread_t object */
-static int thr_destructor(void *obj)
-{
-	thread_t *t = (thread_t *) obj;
-
+static size_t thr_destructor(void *obj)
+{
+	thread_t *thread = (thread_t *) obj;
+	
 	/* call the architecture-specific part of the destructor */
-	thr_destructor_arch(t);
-
-	frame_free(KA2PA(t->kstack));
+	thr_destructor_arch(thread);
+	
+	frame_free(KA2PA(thread->kstack));
+	
 #ifdef CONFIG_FPU
-	if (t->saved_fpu_context)
-		slab_free(fpu_context_slab, t->saved_fpu_context);
-#endif
-	return 1; /* One page freed */
+	if (thread->saved_fpu_context)
+		slab_free(fpu_context_slab, thread->saved_fpu_context);
+#endif
+	
+	return 1;  /* One page freed */
 }
 
@@ -221,13 +222,14 @@
 {
 	THREAD = NULL;
+	
 	atomic_set(&nrdy, 0);
 	thread_slab = slab_cache_create("thread_slab", sizeof(thread_t), 0,
 	    thr_constructor, thr_destructor, 0);
-
+	
 #ifdef CONFIG_FPU
 	fpu_context_slab = slab_cache_create("fpu_slab", sizeof(fpu_context_t),
 	    FPU_CONTEXT_ALIGN, NULL, NULL, 0);
 #endif
-
+	
 	avltree_create(&threads_tree);
 }
@@ -235,145 +237,128 @@
 /** Make thread ready
  *
- * Switch thread t to the ready state.
+ * Switch thread to the ready state.
  *
  * @param t Thread to make ready.
  *
  */
-void thread_ready(thread_t *t)
-{
-	cpu_t *cpu;
-	runq_t *r;
-	ipl_t ipl;
-	int i, avg;
-
-	ipl = interrupts_disable();
-
-	spinlock_lock(&t->lock);
-
-	ASSERT(!(t->state == Ready));
-
-	i = (t->priority < RQ_COUNT - 1) ? ++t->priority : t->priority;
-	
-	cpu = CPU;
-	if (t->flags & THREAD_FLAG_WIRED) {
-		ASSERT(t->cpu != NULL);
-		cpu = t->cpu;
+void thread_ready(thread_t *thread)
+{
+	irq_spinlock_lock(&thread->lock, true);
+	
+	ASSERT(!(thread->state == Ready));
+	
+	int i = (thread->priority < RQ_COUNT - 1)
+	    ? ++thread->priority : thread->priority;
+	
+	cpu_t *cpu = CPU;
+	if (thread->flags & THREAD_FLAG_WIRED) {
+		ASSERT(thread->cpu != NULL);
+		cpu = thread->cpu;
 	}
-	t->state = Ready;
-	spinlock_unlock(&t->lock);
+	thread->state = Ready;
+	
+	irq_spinlock_pass(&thread->lock, &(cpu->rq[i].lock));
 	
 	/*
-	 * Append t to respective ready queue on respective processor.
+	 * Append thread to respective ready queue
+	 * on respective processor.
 	 */
-	r = &cpu->rq[i];
-	spinlock_lock(&r->lock);
-	list_append(&t->rq_link, &r->rq_head);
-	r->n++;
-	spinlock_unlock(&r->lock);
-
+	
+	list_append(&thread->rq_link, &cpu->rq[i].rq_head);
+	cpu->rq[i].n++;
+	irq_spinlock_unlock(&(cpu->rq[i].lock), true);
+	
 	atomic_inc(&nrdy);
-	// FIXME: Why is the avg value never read?
-	avg = atomic_get(&nrdy) / config.cpu_active;
+	// FIXME: Why is the avg value not used
+	// avg = atomic_get(&nrdy) / config.cpu_active;
 	atomic_inc(&cpu->nrdy);
-
+}
+
+/** Create new thread
+ *
+ * Create a new thread.
+ *
+ * @param func      Thread's implementing function.
+ * @param arg       Thread's implementing function argument.
+ * @param task      Task to which the thread belongs. The caller must
+ *                  guarantee that the task won't cease to exist during the
+ *                  call. The task's lock may not be held.
+ * @param flags     Thread flags.
+ * @param name      Symbolic name (a copy is made).
+ * @param uncounted Thread's accounting doesn't affect accumulated task
+ *                  accounting.
+ *
+ * @return New thread's structure on success, NULL on failure.
+ *
+ */
+thread_t *thread_create(void (* func)(void *), void *arg, task_t *task,
+    unsigned int flags, const char *name, bool uncounted)
+{
+	thread_t *thread = (thread_t *) slab_alloc(thread_slab, 0);
+	if (!thread)
+		return NULL;
+	
+	/* Not needed, but good for debugging */
+	memsetb(thread->kstack, THREAD_STACK_SIZE * 1 << STACK_FRAMES, 0);
+	
+	irq_spinlock_lock(&tidlock, true);
+	thread->tid = ++last_tid;
+	irq_spinlock_unlock(&tidlock, true);
+	
+	context_save(&thread->saved_context);
+	context_set(&thread->saved_context, FADDR(cushion),
+	    (uintptr_t) thread->kstack, THREAD_STACK_SIZE);
+	
+	the_initialize((the_t *) thread->kstack);
+	
+	ipl_t ipl = interrupts_disable();
+	thread->saved_context.ipl = interrupts_read();
 	interrupts_restore(ipl);
-}
-
-/** Create new thread
- *
- * Create a new thread.
- *
- * @param func		Thread's implementing function.
- * @param arg		Thread's implementing function argument.
- * @param task		Task to which the thread belongs. The caller must
- * 			guarantee that the task won't cease to exist during the
- * 			call. The task's lock may not be held.
- * @param flags		Thread flags.
- * @param name		Symbolic name (a copy is made).
- * @param uncounted	Thread's accounting doesn't affect accumulated task
- * 			accounting.
- *
- * @return 		New thread's structure on success, NULL on failure.
- *
- */
-thread_t *thread_create(void (* func)(void *), void *arg, task_t *task,
-    int flags, const char *name, bool uncounted)
-{
-	thread_t *t;
-	ipl_t ipl;
-	
-	t = (thread_t *) slab_alloc(thread_slab, 0);
-	if (!t)
-		return NULL;
-	
-	/* Not needed, but good for debugging */
-	memsetb(t->kstack, THREAD_STACK_SIZE * 1 << STACK_FRAMES, 0);
-	
-	ipl = interrupts_disable();
-	spinlock_lock(&tidlock);
-	t->tid = ++last_tid;
-	spinlock_unlock(&tidlock);
-	interrupts_restore(ipl);
-	
-	context_save(&t->saved_context);
-	context_set(&t->saved_context, FADDR(cushion), (uintptr_t) t->kstack,
-	    THREAD_STACK_SIZE);
-	
-	the_initialize((the_t *) t->kstack);
-	
-	ipl = interrupts_disable();
-	t->saved_context.ipl = interrupts_read();
-	interrupts_restore(ipl);
-	
-	memcpy(t->name, name, THREAD_NAME_BUFLEN);
-	t->name[THREAD_NAME_BUFLEN - 1] = 0;
-	
-	t->thread_code = func;
-	t->thread_arg = arg;
-	t->ticks = -1;
-	t->ucycles = 0;
-	t->kcycles = 0;
-	t->uncounted = uncounted;
-	t->priority = -1;		/* start in rq[0] */
-	t->cpu = NULL;
-	t->flags = flags;
-	t->state = Entering;
-	t->call_me = NULL;
-	t->call_me_with = NULL;
-	
-	timeout_initialize(&t->sleep_timeout);
-	t->sleep_interruptible = false;
-	t->sleep_queue = NULL;
-	t->timeout_pending = 0;
-
-	t->in_copy_from_uspace = false;
-	t->in_copy_to_uspace = false;
-
-	t->interrupted = false;	
-	t->detached = false;
-	waitq_initialize(&t->join_wq);
-	
-	t->rwlock_holder_type = RWLOCK_NONE;
-		
-	t->task = task;
-	
-	t->fpu_context_exists = 0;
-	t->fpu_context_engaged = 0;
-
-	avltree_node_initialize(&t->threads_tree_node);
-	t->threads_tree_node.key = (uintptr_t) t;
-
+	
+	str_cpy(thread->name, THREAD_NAME_BUFLEN, name);
+	
+	thread->thread_code = func;
+	thread->thread_arg = arg;
+	thread->ticks = -1;
+	thread->ucycles = 0;
+	thread->kcycles = 0;
+	thread->uncounted = uncounted;
+	thread->priority = -1;          /* Start in rq[0] */
+	thread->cpu = NULL;
+	thread->flags = flags;
+	thread->state = Entering;
+	
+	timeout_initialize(&thread->sleep_timeout);
+	thread->sleep_interruptible = false;
+	thread->sleep_queue = NULL;
+	thread->timeout_pending = false;
+	
+	thread->in_copy_from_uspace = false;
+	thread->in_copy_to_uspace = false;
+	
+	thread->interrupted = false;
+	thread->detached = false;
+	waitq_initialize(&thread->join_wq);
+	
+	thread->task = task;
+	
+	thread->fpu_context_exists = 0;
+	thread->fpu_context_engaged = 0;
+	
+	avltree_node_initialize(&thread->threads_tree_node);
+	thread->threads_tree_node.key = (uintptr_t) thread;
+	
 #ifdef CONFIG_UDEBUG
 	/* Init debugging stuff */
-	udebug_thread_initialize(&t->udebug);
-#endif
-
-	/* might depend on previous initialization */
-	thread_create_arch(t);	
-
+	udebug_thread_initialize(&thread->udebug);
+#endif
+	
+	/* Might depend on previous initialization */
+	thread_create_arch(thread);
+	
 	if (!(flags & THREAD_FLAG_NOATTACH))
-		thread_attach(t, task);
-
-	return t;
+		thread_attach(thread, task);
+	
+	return thread;
 }
 
@@ -382,36 +367,38 @@
  * Detach thread from all queues, cpus etc. and destroy it.
  *
- * Assume thread->lock is held!!
- */
-void thread_destroy(thread_t *t)
-{
-	ASSERT(t->state == Exiting || t->state == Lingering);
-	ASSERT(t->task);
-	ASSERT(t->cpu);
-
-	spinlock_lock(&t->cpu->lock);
-	if (t->cpu->fpu_owner == t)
-		t->cpu->fpu_owner = NULL;
-	spinlock_unlock(&t->cpu->lock);
-
-	spinlock_unlock(&t->lock);
-
-	spinlock_lock(&threads_lock);
-	avltree_delete(&threads_tree, &t->threads_tree_node);
-	spinlock_unlock(&threads_lock);
-
+ * @param thread  Thread to be destroyed.
+ * @param irq_res Indicate whether it should unlock thread->lock
+ *                in interrupts-restore mode.
+ *
+ */
+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);
+	
+	irq_spinlock_lock(&thread->cpu->lock, false);
+	if (thread->cpu->fpu_owner == thread)
+		thread->cpu->fpu_owner = NULL;
+	irq_spinlock_unlock(&thread->cpu->lock, false);
+	
+	irq_spinlock_pass(&thread->lock, &threads_lock);
+	
+	avltree_delete(&threads_tree, &thread->threads_tree_node);
+	
+	irq_spinlock_pass(&threads_lock, &thread->task->lock);
+	
 	/*
 	 * Detach from the containing task.
 	 */
-	spinlock_lock(&t->task->lock);
-	list_remove(&t->th_link);
-	spinlock_unlock(&t->task->lock);	
-
+	list_remove(&thread->th_link);
+	irq_spinlock_unlock(&thread->task->lock, irq_res);
+	
 	/*
 	 * Drop the reference to the containing task.
 	 */
-	task_release(t->task);
-	
-	slab_free(thread_slab, t);
+	task_release(thread->task);
+	slab_free(thread_slab, thread);
 }
 
@@ -421,50 +408,51 @@
  * threads_tree.
  *
- * @param t	Thread to be attached to the task.
- * @param task	Task to which the thread is to be attached.
- */
-void thread_attach(thread_t *t, task_t *task)
-{
-	ipl_t ipl;
-
+ * @param t    Thread to be attached to the task.
+ * @param task Task to which the thread is to be attached.
+ *
+ */
+void thread_attach(thread_t *thread, task_t *task)
+{
 	/*
 	 * Attach to the specified task.
 	 */
-	ipl = interrupts_disable();
-	spinlock_lock(&task->lock);
-
+	irq_spinlock_lock(&task->lock, true);
+	
 	/* Hold a reference to the task. */
 	task_hold(task);
-
+	
 	/* Must not count kbox thread into lifecount */
-	if (t->flags & THREAD_FLAG_USPACE)
+	if (thread->flags & THREAD_FLAG_USPACE)
 		atomic_inc(&task->lifecount);
-
-	list_append(&t->th_link, &task->th_head);
-	spinlock_unlock(&task->lock);
-
+	
+	list_append(&thread->th_link, &task->th_head);
+	
+	irq_spinlock_pass(&task->lock, &threads_lock);
+	
 	/*
 	 * Register this thread in the system-wide list.
 	 */
-	spinlock_lock(&threads_lock);
-	avltree_insert(&threads_tree, &t->threads_tree_node);
-	spinlock_unlock(&threads_lock);
-	
-	interrupts_restore(ipl);
+	avltree_insert(&threads_tree, &thread->threads_tree_node);
+	irq_spinlock_unlock(&threads_lock, true);
 }
 
 /** Terminate thread.
  *
- * End current thread execution and switch it to the exiting state. All pending
- * timeouts are executed.
+ * End current thread execution and switch it to the exiting state.
+ * All pending timeouts are executed.
+ *
  */
 void thread_exit(void)
 {
-	ipl_t ipl;
-
 	if (THREAD->flags & THREAD_FLAG_USPACE) {
 #ifdef CONFIG_UDEBUG
 		/* Generate udebug THREAD_E event */
 		udebug_thread_e_event();
+
+		/*
+		 * This thread will not execute any code or system calls from
+		 * now on.
+		 */
+		udebug_stoppable_begin();
 #endif
 		if (atomic_predec(&TASK->lifecount) == 0) {
@@ -475,4 +463,5 @@
 			 * can only be created by threads of the same task.
 			 * We are safe to perform cleanup.
+			 *
 			 */
 			ipc_cleanup();
@@ -481,24 +470,21 @@
 		}
 	}
-
+	
 restart:
-	ipl = interrupts_disable();
-	spinlock_lock(&THREAD->lock);
-	if (THREAD->timeout_pending) { 
-		/* busy waiting for timeouts in progress */
-		spinlock_unlock(&THREAD->lock);
-		interrupts_restore(ipl);
+	irq_spinlock_lock(&THREAD->lock, true);
+	if (THREAD->timeout_pending) {
+		/* Busy waiting for timeouts in progress */
+		irq_spinlock_unlock(&THREAD->lock, true);
 		goto restart;
 	}
 	
 	THREAD->state = Exiting;
-	spinlock_unlock(&THREAD->lock);
+	irq_spinlock_unlock(&THREAD->lock, true);
+	
 	scheduler();
-
+	
 	/* Not reached */
-	while (1)
-		;
-}
-
+	while (true);
+}
 
 /** Thread sleep
@@ -515,5 +501,5 @@
 	while (sec > 0) {
 		uint32_t period = (sec > 1000) ? 1000 : sec;
-	
+		
 		thread_usleep(period * 1000000);
 		sec -= period;
@@ -523,18 +509,16 @@
 /** Wait for another thread to exit.
  *
- * @param t Thread to join on exit.
- * @param usec Timeout in microseconds.
- * @param flags Mode of operation.
+ * @param thread Thread to join on exit.
+ * @param usec   Timeout in microseconds.
+ * @param flags  Mode of operation.
  *
  * @return An error code from errno.h or an error code from synch.h.
- */
-int thread_join_timeout(thread_t *t, uint32_t usec, int flags)
-{
-	ipl_t ipl;
-	int rc;
-
-	if (t == THREAD)
+ *
+ */
+int thread_join_timeout(thread_t *thread, uint32_t usec, unsigned int flags)
+{
+	if (thread == THREAD)
 		return EINVAL;
-
+	
 	/*
 	 * Since thread join can only be called once on an undetached thread,
@@ -542,13 +526,9 @@
 	 */
 	
-	ipl = interrupts_disable();
-	spinlock_lock(&t->lock);
-	ASSERT(!t->detached);
-	spinlock_unlock(&t->lock);
-	interrupts_restore(ipl);
-	
-	rc = waitq_sleep_timeout(&t->join_wq, usec, flags);
-	
-	return rc;	
+	irq_spinlock_lock(&thread->lock, true);
+	ASSERT(!thread->detached);
+	irq_spinlock_unlock(&thread->lock, true);
+	
+	return waitq_sleep_timeout(&thread->join_wq, usec, flags);
 }
 
@@ -558,26 +538,28 @@
  * state, deallocate its resources.
  *
- * @param t Thread to be detached.
- */
-void thread_detach(thread_t *t)
-{
-	ipl_t ipl;
-
+ * @param thread Thread to be detached.
+ *
+ */
+void thread_detach(thread_t *thread)
+{
 	/*
 	 * Since the thread is expected not to be already detached,
 	 * pointer to it must be still valid.
 	 */
-	ipl = interrupts_disable();
-	spinlock_lock(&t->lock);
-	ASSERT(!t->detached);
-	if (t->state == Lingering) {
-		thread_destroy(t);	/* unlocks &t->lock */
-		interrupts_restore(ipl);
+	irq_spinlock_lock(&thread->lock, true);
+	ASSERT(!thread->detached);
+	
+	if (thread->state == Lingering) {
+		/*
+		 * Unlock &thread->lock and restore
+		 * interrupts in thread_destroy().
+		 */
+		thread_destroy(thread, true);
 		return;
 	} else {
-		t->detached = true;
+		thread->detached = true;
 	}
-	spinlock_unlock(&t->lock);
-	interrupts_restore(ipl);
+	
+	irq_spinlock_unlock(&thread->lock, true);
 }
 
@@ -598,99 +580,90 @@
 }
 
-/** Register thread out-of-context invocation
- *
- * Register a function and its argument to be executed
- * on next context switch to the current thread.
- *
- * @param call_me      Out-of-context function.
- * @param call_me_with Out-of-context function argument.
- *
- */
-void thread_register_call_me(void (* call_me)(void *), void *call_me_with)
-{
-	ipl_t ipl;
-	
-	ipl = interrupts_disable();
-	spinlock_lock(&THREAD->lock);
-	THREAD->call_me = call_me;
-	THREAD->call_me_with = call_me_with;
-	spinlock_unlock(&THREAD->lock);
-	interrupts_restore(ipl);
-}
-
 static bool thread_walker(avltree_node_t *node, void *arg)
 {
-	thread_t *t = avltree_get_instance(node, thread_t, threads_tree_node);
+	bool *additional = (bool *) arg;
+	thread_t *thread = avltree_get_instance(node, thread_t, threads_tree_node);
 	
 	uint64_t ucycles, kcycles;
 	char usuffix, ksuffix;
-	order_suffix(t->ucycles, &ucycles, &usuffix);
-	order_suffix(t->kcycles, &kcycles, &ksuffix);
-
+	order_suffix(thread->ucycles, &ucycles, &usuffix);
+	order_suffix(thread->kcycles, &kcycles, &ksuffix);
+	
 #ifdef __32_BITS__
-	printf("%-6" PRIu64" %-10s %10p %-8s %10p %-3" PRIu32 " %10p %10p %9"
-		PRIu64 "%c %9" PRIu64 "%c ", t->tid, t->name, t,
-		thread_states[t->state], t->task, t->task->context, t->thread_code,
-		t->kstack, ucycles, usuffix, kcycles, ksuffix);
-#endif
-
+	if (*additional)
+		printf("%-8" PRIu64" %10p %9" PRIu64 "%c %9" PRIu64 "%c ",
+		    thread->tid, thread->kstack, ucycles, usuffix,
+		    kcycles, ksuffix);
+	else
+		printf("%-8" PRIu64" %-14s %10p %-8s %10p %-5" PRIu32 " %10p\n",
+		    thread->tid, thread->name, thread, thread_states[thread->state],
+		    thread->task, thread->task->context, thread->thread_code);
+#endif
+	
 #ifdef __64_BITS__
-	printf("%-6" PRIu64" %-10s %18p %-8s %18p %-3" PRIu32 " %18p %18p %9"
-		PRIu64 "%c %9" PRIu64 "%c ", t->tid, t->name, t,
-		thread_states[t->state], t->task, t->task->context, t->thread_code,
-		t->kstack, ucycles, usuffix, kcycles, ksuffix);
+	if (*additional)
+		printf("%-8" PRIu64" %18p %18p\n"
+		    "         %9" PRIu64 "%c %9" PRIu64 "%c ",
+		    thread->tid, thread->thread_code, thread->kstack,
+		    ucycles, usuffix, kcycles, ksuffix);
+	else
+		printf("%-8" PRIu64" %-14s %18p %-8s %18p %-5" PRIu32 "\n",
+		    thread->tid, thread->name, thread, thread_states[thread->state],
+		    thread->task, thread->task->context);
+#endif
+	
+	if (*additional) {
+		if (thread->cpu)
+			printf("%-5u", thread->cpu->id);
+		else
+			printf("none ");
+		
+		if (thread->state == Sleeping) {
+#ifdef __32_BITS__
+			printf(" %10p", thread->sleep_queue);
 #endif
 			
-	if (t->cpu)
-		printf("%-4u", t->cpu->id);
+#ifdef __64_BITS__
+			printf(" %18p", thread->sleep_queue);
+#endif
+		}
+		
+		printf("\n");
+	}
+	
+	return true;
+}
+
+/** Print list of threads debug info
+ *
+ * @param additional Print additional information.
+ *
+ */
+void thread_print_list(bool additional)
+{
+	/* Messing with thread structures, avoid deadlock */
+	irq_spinlock_lock(&threads_lock, true);
+	
+#ifdef __32_BITS__
+	if (additional)
+		printf("[id    ] [stack   ] [ucycles ] [kcycles ] [cpu]"
+		    " [waitqueue]\n");
 	else
-		printf("none");
-			
-	if (t->state == Sleeping) {
-#ifdef __32_BITS__
-		printf(" %10p", t->sleep_queue);
-#endif
-
+		printf("[id    ] [name        ] [address ] [state ] [task    ]"
+		    " [ctx] [code    ]\n");
+#endif
+	
 #ifdef __64_BITS__
-		printf(" %18p", t->sleep_queue);
-#endif
-	}
-			
-	printf("\n");
-
-	return true;
-}
-
-/** Print list of threads debug info */
-void thread_print_list(void)
-{
-	ipl_t ipl;
-	
-	/* Messing with thread structures, avoid deadlock */
-	ipl = interrupts_disable();
-	spinlock_lock(&threads_lock);
-
-#ifdef __32_BITS__	
-	printf("tid    name       address    state    task       "
-		"ctx code       stack      ucycles    kcycles    cpu  "
-		"waitqueue\n");
-	printf("------ ---------- ---------- -------- ---------- "
-		"--- ---------- ---------- ---------- ---------- ---- "
-		"----------\n");
-#endif
-
-#ifdef __64_BITS__
-	printf("tid    name       address            state    task               "
-		"ctx code               stack              ucycles    kcycles    cpu  "
-		"waitqueue\n");
-	printf("------ ---------- ------------------ -------- ------------------ "
-		"--- ------------------ ------------------ ---------- ---------- ---- "
-		"------------------\n");
-#endif
-
-	avltree_walk(&threads_tree, thread_walker, NULL);
-
-	spinlock_unlock(&threads_lock);
-	interrupts_restore(ipl);
+	if (additional) {
+		printf("[id    ] [code            ] [stack           ]\n"
+		    "         [ucycles ] [kcycles ] [cpu] [waitqueue       ]\n");
+	} else
+		printf("[id    ] [name        ] [address         ] [state ]"
+		    " [task            ] [ctx]\n");
+#endif
+	
+	avltree_walk(&threads_tree, thread_walker, &additional);
+	
+	irq_spinlock_unlock(&threads_lock, true);
 }
 
@@ -700,13 +673,16 @@
  * interrupts must be already disabled.
  *
- * @param t Pointer to thread.
+ * @param thread Pointer to thread.
  *
  * @return True if thread t is known to the system, false otherwise.
- */
-bool thread_exists(thread_t *t)
-{
-	avltree_node_t *node;
-
-	node = avltree_search(&threads_tree, (avltree_key_t) ((uintptr_t) t));
+ *
+ */
+bool thread_exists(thread_t *thread)
+{
+	ASSERT(interrupts_disabled());
+	ASSERT(irq_spinlock_locked(&threads_lock));
+
+	avltree_node_t *node =
+	    avltree_search(&threads_tree, (avltree_key_t) ((uintptr_t) thread));
 	
 	return node != NULL;
@@ -718,14 +694,19 @@
  * interrupts must be already disabled.
  *
- * @param user	True to update user accounting, false for kernel.
+ * @param user True to update user accounting, false for kernel.
+ *
  */
 void thread_update_accounting(bool user)
 {
 	uint64_t time = get_cycle();
-	if (user) {
+
+	ASSERT(interrupts_disabled());
+	ASSERT(irq_spinlock_locked(&THREAD->lock));
+	
+	if (user)
 		THREAD->ucycles += time - THREAD->last_cycle;
-	} else {
+	else
 		THREAD->kcycles += time - THREAD->last_cycle;
-	}
+	
 	THREAD->last_cycle = time;
 }
@@ -757,4 +738,7 @@
 thread_t *thread_find_by_id(thread_id_t thread_id)
 {
+	ASSERT(interrupts_disabled());
+	ASSERT(irq_spinlock_locked(&threads_lock));
+
 	thread_iterator_t iterator;
 	
@@ -774,23 +758,21 @@
     size_t name_len, thread_id_t *uspace_thread_id)
 {
-	thread_t *t;
-	char namebuf[THREAD_NAME_BUFLEN];
-	uspace_arg_t *kernel_uarg;
-	int rc;
-
 	if (name_len > THREAD_NAME_BUFLEN - 1)
 		name_len = THREAD_NAME_BUFLEN - 1;
-
-	rc = copy_from_uspace(namebuf, uspace_name, name_len);
+	
+	char namebuf[THREAD_NAME_BUFLEN];
+	int rc = copy_from_uspace(namebuf, uspace_name, name_len);
 	if (rc != 0)
 		return (unative_t) rc;
-
+	
 	namebuf[name_len] = 0;
-
+	
 	/*
 	 * In case of failure, kernel_uarg will be deallocated in this function.
 	 * In case of success, kernel_uarg will be freed in uinit().
+	 *
 	 */
-	kernel_uarg = (uspace_arg_t *) malloc(sizeof(uspace_arg_t), 0);
+	uspace_arg_t *kernel_uarg =
+	    (uspace_arg_t *) malloc(sizeof(uspace_arg_t), 0);
 	
 	rc = copy_from_uspace(kernel_uarg, uspace_uarg, sizeof(uspace_arg_t));
@@ -799,13 +781,11 @@
 		return (unative_t) rc;
 	}
-
-	t = thread_create(uinit, kernel_uarg, TASK,
+	
+	thread_t *thread = thread_create(uinit, kernel_uarg, TASK,
 	    THREAD_FLAG_USPACE | THREAD_FLAG_NOATTACH, namebuf, false);
-	if (t) {
+	if (thread) {
 		if (uspace_thread_id != NULL) {
-			int rc;
-
-			rc = copy_to_uspace(uspace_thread_id, &t->tid,
-			    sizeof(t->tid));
+			rc = copy_to_uspace(uspace_thread_id, &thread->tid,
+			    sizeof(thread->tid));
 			if (rc != 0) {
 				/*
@@ -813,6 +793,7 @@
 				 * has already been created. We need to undo its
 				 * creation now.
+				 *
 				 */
-
+				
 				/*
 				 * The new thread structure is initialized, but
@@ -820,10 +801,11 @@
 				 * We can safely deallocate it.
 				 */
-				slab_free(thread_slab, t);
-			 	free(kernel_uarg);
-
+				slab_free(thread_slab, thread);
+				free(kernel_uarg);
+				
 				return (unative_t) rc;
 			 }
 		}
+		
 #ifdef CONFIG_UDEBUG
 		/*
@@ -833,15 +815,16 @@
 		 * THREAD_B events for threads that already existed
 		 * and could be detected with THREAD_READ before.
+		 *
 		 */
-		udebug_thread_b_event_attach(t, TASK);
+		udebug_thread_b_event_attach(thread, TASK);
 #else
-		thread_attach(t, TASK);
-#endif
-		thread_ready(t);
-
+		thread_attach(thread, TASK);
+#endif
+		thread_ready(thread);
+		
 		return 0;
 	} else
 		free(kernel_uarg);
-
+	
 	return (unative_t) ENOMEM;
 }
@@ -853,4 +836,5 @@
 {
 	thread_exit();
+	
 	/* Unreachable */
 	return 0;
@@ -863,4 +847,5 @@
  *
  * @return 0 on success or an error code from @ref errno.h.
+ *
  */
 unative_t sys_thread_get_id(thread_id_t *uspace_thread_id)
@@ -869,4 +854,5 @@
 	 * No need to acquire lock on THREAD because tid
 	 * remains constant for the lifespan of the thread.
+	 *
 	 */
 	return (unative_t) copy_to_uspace(uspace_thread_id, &THREAD->tid,
Index: kernel/generic/src/security/cap.c
===================================================================
--- kernel/generic/src/security/cap.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/generic/src/security/cap.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -27,15 +27,15 @@
  */
 
-/** @addtogroup generic	
+/** @addtogroup generic
  * @{
  */
 
 /**
- * @file	cap.c
- * @brief	Capabilities control.
+ * @file cap.c
+ * @brief Capabilities control.
  *
  * @see cap.h
  */
- 
+
 #include <security/cap.h>
 #include <proc/task.h>
@@ -48,37 +48,27 @@
 /** Set capabilities.
  *
- * @param t Task whose capabilities are to be changed.
+ * @param task Task whose capabilities are to be changed.
  * @param caps New set of capabilities.
+ *
  */
-void cap_set(task_t *t, cap_t caps)
+void cap_set(task_t *task, cap_t caps)
 {
-	ipl_t ipl;
-	
-	ipl = interrupts_disable();
-	spinlock_lock(&t->lock);
-	
-	t->capabilities = caps;
-	
-	spinlock_unlock(&t->lock);
-	interrupts_restore(ipl);
+	irq_spinlock_lock(&task->lock, true);
+	task->capabilities = caps;
+	irq_spinlock_unlock(&task->lock, true);
 }
 
 /** Get capabilities.
  *
- * @param t Task whose capabilities are to be returned.
+ * @param task Task whose capabilities are to be returned.
+ *
  * @return Task's capabilities.
+ *
  */
-cap_t cap_get(task_t *t)
+cap_t cap_get(task_t *task)
 {
-	ipl_t ipl;
-	cap_t caps;
-	
-	ipl = interrupts_disable();
-	spinlock_lock(&t->lock);
-	
-	caps = t->capabilities;
-	
-	spinlock_unlock(&t->lock);
-	interrupts_restore(ipl);
+	irq_spinlock_lock(&task->lock, true);
+	cap_t caps = task->capabilities;
+	irq_spinlock_unlock(&task->lock, true);
 	
 	return caps;
@@ -93,34 +83,29 @@
  *
  * @return Zero on success or an error code from @ref errno.h.
+ *
  */
 unative_t sys_cap_grant(sysarg64_t *uspace_taskid_arg, cap_t caps)
 {
-	sysarg64_t taskid_arg;
-	task_t *t;
-	ipl_t ipl;
-	int rc;
-	
 	if (!(cap_get(TASK) & CAP_CAP))
 		return (unative_t) EPERM;
 	
-	rc = copy_from_uspace(&taskid_arg, uspace_taskid_arg, sizeof(sysarg64_t));
+	sysarg64_t taskid_arg;
+	int rc = copy_from_uspace(&taskid_arg, uspace_taskid_arg, sizeof(sysarg64_t));
 	if (rc != 0)
 		return (unative_t) rc;
-		
-	ipl = interrupts_disable();
-	spinlock_lock(&tasks_lock);
-	t = task_find_by_id((task_id_t) taskid_arg.value);
-	if ((!t) || (!context_check(CONTEXT, t->context))) {
-		spinlock_unlock(&tasks_lock);
-		interrupts_restore(ipl);
+	
+	irq_spinlock_lock(&tasks_lock, true);
+	task_t *task = task_find_by_id((task_id_t) taskid_arg.value);
+	
+	if ((!task) || (!context_check(CONTEXT, task->context))) {
+		irq_spinlock_unlock(&tasks_lock, true);
 		return (unative_t) ENOENT;
 	}
 	
-	spinlock_lock(&t->lock);
-	cap_set(t, cap_get(t) | caps);
-	spinlock_unlock(&t->lock);
+	irq_spinlock_lock(&task->lock, false);
+	task->capabilities |= caps;
+	irq_spinlock_unlock(&task->lock, false);
 	
-	spinlock_unlock(&tasks_lock);
-	interrupts_restore(ipl);	
+	irq_spinlock_unlock(&tasks_lock, true);
 	return 0;
 }
@@ -135,25 +120,21 @@
  *
  * @return Zero on success or an error code from @ref errno.h.
+ *
  */
 unative_t sys_cap_revoke(sysarg64_t *uspace_taskid_arg, cap_t caps)
 {
 	sysarg64_t taskid_arg;
-	task_t *t;
-	ipl_t ipl;
-	int rc;
-	
-	rc = copy_from_uspace(&taskid_arg, uspace_taskid_arg, sizeof(sysarg64_t));
+	int rc = copy_from_uspace(&taskid_arg, uspace_taskid_arg, sizeof(sysarg64_t));
 	if (rc != 0)
 		return (unative_t) rc;
-
-	ipl = interrupts_disable();
-	spinlock_lock(&tasks_lock);	
-	t = task_find_by_id((task_id_t) taskid_arg.value);
-	if ((!t) || (!context_check(CONTEXT, t->context))) {
-		spinlock_unlock(&tasks_lock);
-		interrupts_restore(ipl);
+	
+	irq_spinlock_lock(&tasks_lock, true);
+	
+	task_t *task = task_find_by_id((task_id_t) taskid_arg.value);
+	if ((!task) || (!context_check(CONTEXT, task->context))) {
+		irq_spinlock_unlock(&tasks_lock, true);
 		return (unative_t) ENOENT;
 	}
-
+	
 	/*
 	 * Revoking capabilities is different from granting them in that
@@ -161,17 +142,16 @@
 	 * doesn't have CAP_CAP.
 	 */
-	if (!(cap_get(TASK) & CAP_CAP) || !(t == TASK)) {
-		spinlock_unlock(&tasks_lock);
-		interrupts_restore(ipl);
+	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 (unative_t) EPERM;
 	}
 	
-	spinlock_lock(&t->lock);
-	cap_set(t, cap_get(t) & ~caps);
-	spinlock_unlock(&t->lock);
-
-	spinlock_unlock(&tasks_lock);
-
-	interrupts_restore(ipl);
+	task->capabilities &= ~caps;
+	irq_spinlock_unlock(&TASK->lock, false);
+	
+	irq_spinlock_unlock(&tasks_lock, true);
 	return 0;
 }
@@ -179,3 +159,2 @@
 /** @}
  */
-
Index: kernel/generic/src/smp/ipi.c
===================================================================
--- kernel/generic/src/smp/ipi.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/generic/src/smp/ipi.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -47,8 +47,4 @@
  * @param ipi Message to broadcast.
  *
- * @bug The decision whether to actually send the IPI must be based
- *      on a different criterion. The current version has
- *      problems when some of the detected CPUs are marked
- *      disabled in machine configuration.
  */
 void ipi_broadcast(int ipi)
@@ -60,5 +56,5 @@
 	 */
 	
-	if ((config.cpu_active > 1) && (config.cpu_active == config.cpu_count))
+	if (config.cpu_count > 1)
 		ipi_broadcast_arch(ipi);
 }
Index: kernel/generic/src/synch/futex.c
===================================================================
--- kernel/generic/src/synch/futex.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/generic/src/synch/futex.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -37,5 +37,5 @@
 
 #include <synch/futex.h>
-#include <synch/rwlock.h>
+#include <synch/mutex.h>
 #include <synch/spinlock.h>
 #include <synch/synch.h>
@@ -65,9 +65,9 @@
 
 /**
- * Read-write lock protecting global futex hash table.
+ * Mutex protecting global futex hash table.
  * It is also used to serialize access to all futex_t structures.
  * Must be acquired before the task futex B+tree lock.
  */
-static rwlock_t futex_ht_lock;
+static mutex_t futex_ht_lock;
 
 /** Futex hash table. */
@@ -84,5 +84,5 @@
 void futex_init(void)
 {
-	rwlock_initialize(&futex_ht_lock);
+	mutex_initialize(&futex_ht_lock, MUTEX_PASSIVE);
 	hash_table_create(&futex_ht, FUTEX_HT_SIZE, 1, &futex_ht_ops);
 }
@@ -113,9 +113,6 @@
 	uintptr_t paddr;
 	pte_t *t;
-	ipl_t ipl;
 	int rc;
 	
-	ipl = interrupts_disable();
-
 	/*
 	 * Find physical address of futex counter.
@@ -125,5 +122,4 @@
 	if (!t || !PTE_VALID(t) || !PTE_PRESENT(t)) {
 		page_table_unlock(AS, true);
-		interrupts_restore(ipl);
 		return (unative_t) ENOENT;
 	}
@@ -131,6 +127,4 @@
 	page_table_unlock(AS, true);
 	
-	interrupts_restore(ipl);	
-
 	futex = futex_find(paddr);
 
@@ -156,7 +150,4 @@
 	uintptr_t paddr;
 	pte_t *t;
-	ipl_t ipl;
-	
-	ipl = interrupts_disable();
 	
 	/*
@@ -167,5 +158,4 @@
 	if (!t || !PTE_VALID(t) || !PTE_PRESENT(t)) {
 		page_table_unlock(AS, true);
-		interrupts_restore(ipl);
 		return (unative_t) ENOENT;
 	}
@@ -173,6 +163,4 @@
 	page_table_unlock(AS, true);
 	
-	interrupts_restore(ipl);
-
 	futex = futex_find(paddr);
 		
@@ -200,5 +188,5 @@
 	 * or allocate new one if it does not exist already.
 	 */
-	rwlock_read_lock(&futex_ht_lock);
+	mutex_lock(&futex_ht_lock);
 	item = hash_table_find(&futex_ht, &paddr);
 	if (item) {
@@ -212,66 +200,28 @@
 			/*
 			 * The futex is new to the current task.
-			 * However, we only have read access.
-			 * Gain write access and try again.
+			 * Upgrade its reference count and put it to the
+			 * current task's B+tree of known futexes.
 			 */
-			mutex_unlock(&TASK->futexes_lock);
-			goto gain_write_access;
+			futex->refcount++;
+			btree_insert(&TASK->futexes, paddr, futex, leaf);
 		}
 		mutex_unlock(&TASK->futexes_lock);
-
-		rwlock_read_unlock(&futex_ht_lock);
 	} else {
-gain_write_access:
+		futex = (futex_t *) malloc(sizeof(futex_t), 0);
+		futex_initialize(futex);
+		futex->paddr = paddr;
+		hash_table_insert(&futex_ht, &paddr, &futex->ht_link);
+			
 		/*
-		 * Upgrade to writer is not currently supported,
-		 * therefore, it is necessary to release the read lock
-		 * and reacquire it as a writer.
+		 * This is the first task referencing the futex.
+		 * It can be directly inserted into its
+		 * B+tree of known futexes.
 		 */
-		rwlock_read_unlock(&futex_ht_lock);
-
-		rwlock_write_lock(&futex_ht_lock);
-		/*
-		 * Avoid possible race condition by searching
-		 * the hash table once again with write access.
-		 */
-		item = hash_table_find(&futex_ht, &paddr);
-		if (item) {
-			futex = hash_table_get_instance(item, futex_t, ht_link);
-			
-			/*
-			 * See if this futex is known to the current task.
-			 */
-			mutex_lock(&TASK->futexes_lock);
-			if (!btree_search(&TASK->futexes, paddr, &leaf)) {
-				/*
-				 * The futex is new to the current task.
-				 * Upgrade its reference count and put it to the
-				 * current task's B+tree of known futexes.
-				 */
-				futex->refcount++;
-				btree_insert(&TASK->futexes, paddr, futex,
-				    leaf);
-			}
-			mutex_unlock(&TASK->futexes_lock);
-	
-			rwlock_write_unlock(&futex_ht_lock);
-		} else {
-			futex = (futex_t *) malloc(sizeof(futex_t), 0);
-			futex_initialize(futex);
-			futex->paddr = paddr;
-			hash_table_insert(&futex_ht, &paddr, &futex->ht_link);
-			
-			/*
-			 * This is the first task referencing the futex.
-			 * It can be directly inserted into its
-			 * B+tree of known futexes.
-			 */
-			mutex_lock(&TASK->futexes_lock);
-			btree_insert(&TASK->futexes, paddr, futex, NULL);
-			mutex_unlock(&TASK->futexes_lock);
-			
-			rwlock_write_unlock(&futex_ht_lock);
-		}
+		mutex_lock(&TASK->futexes_lock);
+		btree_insert(&TASK->futexes, paddr, futex, NULL);
+		mutex_unlock(&TASK->futexes_lock);
+		
 	}
+	mutex_unlock(&futex_ht_lock);
 	
 	return futex;
@@ -324,5 +274,5 @@
 	link_t *cur;
 	
-	rwlock_write_lock(&futex_ht_lock);
+	mutex_lock(&futex_ht_lock);
 	mutex_lock(&TASK->futexes_lock);
 
@@ -344,5 +294,5 @@
 	
 	mutex_unlock(&TASK->futexes_lock);
-	rwlock_write_unlock(&futex_ht_lock);
+	mutex_unlock(&futex_ht_lock);
 }
 
Index: kernel/generic/src/synch/mutex.c
===================================================================
--- kernel/generic/src/synch/mutex.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/generic/src/synch/mutex.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -53,4 +53,14 @@
 }
 
+/** Find out whether the mutex is currently locked.
+ *
+ * @param mtx		Mutex.
+ * @return 		True if the mutex is locked, false otherwise.
+ */
+bool mutex_locked(mutex_t *mtx)
+{
+	return semaphore_count_get(&mtx->sem) <= 0;
+}
+
 /** Acquire mutex.
  *
@@ -67,5 +77,5 @@
  *
  */
-int _mutex_lock_timeout(mutex_t *mtx, uint32_t usec, int flags)
+int _mutex_lock_timeout(mutex_t *mtx, uint32_t usec, unsigned int flags)
 {
 	int rc;
Index: rnel/generic/src/synch/rwlock.c
===================================================================
--- kernel/generic/src/synch/rwlock.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ 	(revision )
@@ -1,393 +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 sync
- * @{
- */
-
-/**
- * @file
- * @brief	Reader/Writer locks.
- *
- * A reader/writer lock can be held by multiple readers at a time.
- * Or it can be exclusively held by a sole writer at a time.
- *
- * These locks are not recursive.
- * Because a technique called direct hand-off is used and because
- * waiting takes place in a single wait queue, neither readers
- * nor writers will suffer starvation.
- *
- * If there is a writer followed by a reader waiting for the rwlock
- * and the writer times out, all leading readers are automatically woken up
- * and allowed in.
- */
-
-/*
- * NOTE ON rwlock_holder_type
- * This field is set on an attempt to acquire the exclusive mutex
- * to the respective value depending whether the caller is a reader
- * or a writer. The field is examined only if the thread had been
- * previously blocked on the exclusive mutex. Thus it is save
- * to store the rwlock type in the thread structure, because
- * each thread can block on only one rwlock at a time.
- */
- 
-#include <synch/rwlock.h>
-#include <synch/spinlock.h>
-#include <synch/mutex.h>
-#include <synch/waitq.h>
-#include <synch/synch.h>
-#include <adt/list.h>
-#include <arch/asm.h>
-#include <arch.h>
-#include <proc/thread.h>
-#include <panic.h>
-
-#define ALLOW_ALL		0
-#define ALLOW_READERS_ONLY	1
-
-static void let_others_in(rwlock_t *rwl, int readers_only);
-static void release_spinlock(void *arg);
-
-/** Initialize reader/writer lock
- *
- * Initialize reader/writer lock.
- *
- * @param rwl Reader/Writer lock.
- */
-void rwlock_initialize(rwlock_t *rwl) {
-	spinlock_initialize(&rwl->lock, "rwlock_t");
-	mutex_initialize(&rwl->exclusive, MUTEX_PASSIVE);
-	rwl->readers_in = 0;
-}
-
-/** Acquire reader/writer lock for reading
- *
- * Acquire reader/writer lock for reading.
- * Timeout and willingness to block may be specified.
- *
- * @param rwl Reader/Writer lock.
- * @param usec Timeout in microseconds.
- * @param flags Specify mode of operation.
- *
- * For exact description of possible combinations of
- * usec and flags, see comment for waitq_sleep_timeout().
- *
- * @return See comment for waitq_sleep_timeout().
- */
-int _rwlock_write_lock_timeout(rwlock_t *rwl, uint32_t usec, int flags)
-{
-	ipl_t ipl;
-	int rc;
-	
-	ipl = interrupts_disable();
-	spinlock_lock(&THREAD->lock);
-	THREAD->rwlock_holder_type = RWLOCK_WRITER;
-	spinlock_unlock(&THREAD->lock);	
-	interrupts_restore(ipl);
-
-	/*
-	 * Writers take the easy part.
-	 * They just need to acquire the exclusive mutex.
-	 */
-	rc = _mutex_lock_timeout(&rwl->exclusive, usec, flags);
-	if (SYNCH_FAILED(rc)) {
-
-		/*
-		 * Lock operation timed out or was interrupted.
-		 * The state of rwl is UNKNOWN at this point.
-		 * No claims about its holder can be made.
-		 */
-		 
-		ipl = interrupts_disable();
-		spinlock_lock(&rwl->lock);
-		/*
-		 * Now when rwl is locked, we can inspect it again.
-		 * If it is held by some readers already, we can let
-		 * readers from the head of the wait queue in.
-		 */
-		if (rwl->readers_in)
-			let_others_in(rwl, ALLOW_READERS_ONLY);
-		spinlock_unlock(&rwl->lock);
-		interrupts_restore(ipl);
-	}
-	
-	return rc;
-}
-
-/** Acquire reader/writer lock for writing
- *
- * Acquire reader/writer lock for writing.
- * Timeout and willingness to block may be specified.
- *
- * @param rwl Reader/Writer lock.
- * @param usec Timeout in microseconds.
- * @param flags Select mode of operation.
- *
- * For exact description of possible combinations of
- * usec and flags, see comment for waitq_sleep_timeout().
- *
- * @return See comment for waitq_sleep_timeout().
- */
-int _rwlock_read_lock_timeout(rwlock_t *rwl, uint32_t usec, int flags)
-{
-	int rc;
-	ipl_t ipl;
-	
-	ipl = interrupts_disable();
-	spinlock_lock(&THREAD->lock);
-	THREAD->rwlock_holder_type = RWLOCK_READER;
-	spinlock_unlock(&THREAD->lock);	
-
-	spinlock_lock(&rwl->lock);
-
-	/*
-	 * Find out whether we can get what we want without blocking.
-	 */
-	rc = mutex_trylock(&rwl->exclusive);
-	if (SYNCH_FAILED(rc)) {
-
-		/*
-		 * 'exclusive' mutex is being held by someone else.
-		 * If the holder is a reader and there is no one
-		 * else waiting for it, we can enter the critical
-		 * section.
-		 */
-
-		if (rwl->readers_in) {
-			spinlock_lock(&rwl->exclusive.sem.wq.lock);
-			if (list_empty(&rwl->exclusive.sem.wq.head)) {
-				/*
-				 * We can enter.
-				 */
-				spinlock_unlock(&rwl->exclusive.sem.wq.lock);
-				goto shortcut;
-			}
-			spinlock_unlock(&rwl->exclusive.sem.wq.lock);
-		}
-
-		/*
-		 * In order to prevent a race condition when a reader
-		 * could block another reader at the head of the waitq,
-		 * we register a function to unlock rwl->lock
-		 * after this thread is put asleep.
-		 */
-		#ifdef CONFIG_SMP
-		thread_register_call_me(release_spinlock, &rwl->lock);
-		#else
-		thread_register_call_me(release_spinlock, NULL);
-		#endif
-				 
-		rc = _mutex_lock_timeout(&rwl->exclusive, usec, flags);
-		switch (rc) {
-		case ESYNCH_WOULD_BLOCK:
-			/*
-			 * release_spinlock() wasn't called
-			 */
-			thread_register_call_me(NULL, NULL);
-			spinlock_unlock(&rwl->lock);
-		case ESYNCH_TIMEOUT:
-		case ESYNCH_INTERRUPTED:
-			/*
-			 * The sleep timed out.
-			 * We just restore interrupt priority level.
-			 */
-		case ESYNCH_OK_BLOCKED:		
-			/*
-			 * We were woken with rwl->readers_in already
-			 * incremented.
-			 *
-			 * Note that this arrangement avoids race condition
-			 * between two concurrent readers. (Race is avoided if
-			 * 'exclusive' is locked at the same time as
-			 * 'readers_in' is incremented. Same time means both
-			 * events happen atomically when rwl->lock is held.)
-			 */
-			interrupts_restore(ipl);
-			break;
-		case ESYNCH_OK_ATOMIC:
-			panic("_mutex_lock_timeout() == ESYNCH_OK_ATOMIC.");
-			break;
-		default:
-			panic("Invalid ESYNCH.");
-			break;
-		}
-		return rc;
-	}
-
-shortcut:
-
-	/*
-	 * We can increment readers_in only if we didn't go to sleep.
-	 * For sleepers, rwlock_let_others_in() will do the job.
-	 */
-	rwl->readers_in++;
-	
-	spinlock_unlock(&rwl->lock);
-	interrupts_restore(ipl);
-
-	return ESYNCH_OK_ATOMIC;
-}
-
-/** Release reader/writer lock held by writer
- *
- * Release reader/writer lock held by writer.
- * Handoff reader/writer lock ownership directly
- * to waiting readers or a writer.
- *
- * @param rwl Reader/Writer lock.
- */
-void rwlock_write_unlock(rwlock_t *rwl)
-{
-	ipl_t ipl;
-	
-	ipl = interrupts_disable();
-	spinlock_lock(&rwl->lock);
-	let_others_in(rwl, ALLOW_ALL);
-	spinlock_unlock(&rwl->lock);
-	interrupts_restore(ipl);
-	
-}
-
-/** Release reader/writer lock held by reader
- *
- * Release reader/writer lock held by reader.
- * Handoff reader/writer lock ownership directly
- * to a waiting writer or don't do anything if more
- * readers poses the lock.
- *
- * @param rwl Reader/Writer lock.
- */
-void rwlock_read_unlock(rwlock_t *rwl)
-{
-	ipl_t ipl;
-
-	ipl = interrupts_disable();
-	spinlock_lock(&rwl->lock);
-	if (!--rwl->readers_in)
-		let_others_in(rwl, ALLOW_ALL);
-	spinlock_unlock(&rwl->lock);
-	interrupts_restore(ipl);
-}
-
-
-/** Direct handoff of reader/writer lock ownership.
- *
- * Direct handoff of reader/writer lock ownership
- * to waiting readers or a writer.
- *
- * Must be called with rwl->lock locked.
- * Must be called with interrupts_disable()'d.
- *
- * @param rwl Reader/Writer lock.
- * @param readers_only See the description below.
- *
- * If readers_only is false: (unlock scenario)
- * Let the first sleeper on 'exclusive' mutex in, no matter
- * whether it is a reader or a writer. If there are more leading
- * readers in line, let each of them in.
- *
- * Otherwise: (timeout scenario)
- * Let all leading readers in.
- */
-void let_others_in(rwlock_t *rwl, int readers_only)
-{
-	rwlock_type_t type = RWLOCK_NONE;
-	thread_t *t = NULL;
-	bool one_more = true;
-	
-	spinlock_lock(&rwl->exclusive.sem.wq.lock);
-
-	if (!list_empty(&rwl->exclusive.sem.wq.head))
-		t = list_get_instance(rwl->exclusive.sem.wq.head.next, thread_t,
-		    wq_link);
-	do {
-		if (t) {
-			spinlock_lock(&t->lock);
-			type = t->rwlock_holder_type;
-			spinlock_unlock(&t->lock);			
-		}
-	
-		/*
-		 * If readers_only is true, we wake all leading readers
-		 * if and only if rwl is locked by another reader.
-		 * Assumption: readers_only ==> rwl->readers_in
-		 */
-		if (readers_only && (type != RWLOCK_READER))
-			break;
-
-
-		if (type == RWLOCK_READER) {
-			/*
-			 * Waking up a reader.
-			 * We are responsible for incrementing rwl->readers_in
-			 * for it.
-			 */
-			 rwl->readers_in++;
-		}
-
-		/*
-		 * Only the last iteration through this loop can increment
-		 * rwl->exclusive.sem.wq.missed_wakeup's. All preceeding
-		 * iterations will wake up a thread.
-		 */
-		/* We call the internal version of waitq_wakeup, which
-		 * relies on the fact that the waitq is already locked.
-		 */
-		_waitq_wakeup_unsafe(&rwl->exclusive.sem.wq, WAKEUP_FIRST);
-		
-		t = NULL;
-		if (!list_empty(&rwl->exclusive.sem.wq.head)) {
-			t = list_get_instance(rwl->exclusive.sem.wq.head.next,
-			    thread_t, wq_link);
-			if (t) {
-				spinlock_lock(&t->lock);
-				if (t->rwlock_holder_type != RWLOCK_READER)
-					one_more = false;
-				spinlock_unlock(&t->lock);	
-			}
-		}
-	} while ((type == RWLOCK_READER) && t && one_more);
-
-	spinlock_unlock(&rwl->exclusive.sem.wq.lock);
-}
-
-/** Release spinlock callback
- *
- * This is a callback function invoked from the scheduler.
- * The callback is registered in _rwlock_read_lock_timeout().
- *
- * @param arg Spinlock.
- */
-void release_spinlock(void *arg)
-{
-	spinlock_unlock((spinlock_t *) arg);
-}
-
-/** @}
- */
Index: kernel/generic/src/synch/semaphore.c
===================================================================
--- kernel/generic/src/synch/semaphore.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/generic/src/synch/semaphore.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -33,5 +33,5 @@
 /**
  * @file
- * @brief	Semaphores.
+ * @brief Semaphores.
  */
 
@@ -47,20 +47,12 @@
  * Initialize semaphore.
  *
- * @param s Semaphore.
+ * @param sem Semaphore.
  * @param val Maximal number of threads allowed to enter critical section.
+ *
  */
-void semaphore_initialize(semaphore_t *s, int val)
+void semaphore_initialize(semaphore_t *sem, int val)
 {
-	ipl_t ipl;
-	
-	waitq_initialize(&s->wq);
-	
-	ipl = interrupts_disable();
-
-	spinlock_lock(&s->wq.lock);
-	s->wq.missed_wakeups = val;
-	spinlock_unlock(&s->wq.lock);
-
-	interrupts_restore(ipl);
+	waitq_initialize(&sem->wq);
+	waitq_count_set(&sem->wq, val);
 }
 
@@ -70,6 +62,6 @@
  * Conditional mode and mode with timeout can be requested.
  *
- * @param s Semaphore.
- * @param usec Timeout in microseconds.
+ * @param sem   Semaphore.
+ * @param usec  Timeout in microseconds.
  * @param flags Select mode of operation.
  *
@@ -78,8 +70,9 @@
  *
  * @return See comment for waitq_sleep_timeout().
+ *
  */
-int _semaphore_down_timeout(semaphore_t *s, uint32_t usec, int flags)
+int _semaphore_down_timeout(semaphore_t *sem, uint32_t usec, unsigned int flags)
 {
-	return waitq_sleep_timeout(&s->wq, usec, flags); 
+	return waitq_sleep_timeout(&sem->wq, usec, flags);
 }
 
@@ -89,8 +82,20 @@
  *
  * @param s Semaphore.
+ *
  */
-void semaphore_up(semaphore_t *s)
+void semaphore_up(semaphore_t *sem)
 {
-	waitq_wakeup(&s->wq, WAKEUP_FIRST);
+	waitq_wakeup(&sem->wq, WAKEUP_FIRST);
+}
+
+/** Get the semaphore counter value.
+ *
+ * @param sem		Semaphore.
+ * @return		The number of threads that can down the semaphore
+ * 			without blocking.
+ */
+int semaphore_count_get(semaphore_t *sem)
+{
+	return waitq_count_get(&sem->wq);
 }
 
Index: kernel/generic/src/synch/spinlock.c
===================================================================
--- kernel/generic/src/synch/spinlock.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/generic/src/synch/spinlock.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -128,5 +128,5 @@
 void spinlock_unlock_debug(spinlock_t *lock)
 {
-	ASSERT(atomic_get(&lock->val) != 0);
+	ASSERT_SPINLOCK(spinlock_locked(lock), lock);
 	
 	/*
@@ -143,7 +143,6 @@
 /** Lock spinlock conditionally
  *
- * Lock spinlock conditionally.
- * If the spinlock is not available at the moment,
- * signal failure.
+ * Lock spinlock conditionally. If the spinlock is not available
+ * at the moment, signal failure.
  *
  * @param lock Pointer to spinlock_t structure.
@@ -168,6 +167,171 @@
 }
 
+/** Find out whether the spinlock is currently locked.
+ *
+ * @param lock		Spinlock.
+ * @return		True if the spinlock is locked, false otherwise.
+ */
+bool spinlock_locked(spinlock_t *lock)
+{
+	return atomic_get(&lock->val) != 0;
+}
+
 #endif
 
+/** Initialize interrupts-disabled spinlock
+ *
+ * @param lock IRQ spinlock to be initialized.
+ * @param name IRQ spinlock name.
+ *
+ */
+void irq_spinlock_initialize(irq_spinlock_t *lock, const char *name)
+{
+	spinlock_initialize(&(lock->lock), name);
+	lock->guard = false;
+	lock->ipl = 0;
+}
+
+/** Lock interrupts-disabled spinlock
+ *
+ * Lock a spinlock which requires disabled interrupts.
+ *
+ * @param lock    IRQ spinlock to be locked.
+ * @param irq_dis If true, interrupts are actually disabled
+ *                prior locking the spinlock. If false, interrupts
+ *                are expected to be already disabled.
+ *
+ */
+void irq_spinlock_lock(irq_spinlock_t *lock, bool irq_dis)
+{
+	if (irq_dis) {
+		ipl_t ipl = interrupts_disable();
+		spinlock_lock(&(lock->lock));
+		
+		lock->guard = true;
+		lock->ipl = ipl;
+	} else {
+		ASSERT_IRQ_SPINLOCK(interrupts_disabled(), lock);
+		
+		spinlock_lock(&(lock->lock));
+		ASSERT_IRQ_SPINLOCK(!lock->guard, lock);
+	}
+}
+
+/** Unlock interrupts-disabled spinlock
+ *
+ * Unlock a spinlock which requires disabled interrupts.
+ *
+ * @param lock    IRQ spinlock to be unlocked.
+ * @param irq_res If true, interrupts are restored to previously
+ *                saved interrupt level.
+ *
+ */
+void irq_spinlock_unlock(irq_spinlock_t *lock, bool irq_res)
+{
+	ASSERT_IRQ_SPINLOCK(interrupts_disabled(), lock);
+	
+	if (irq_res) {
+		ASSERT_IRQ_SPINLOCK(lock->guard, lock);
+		
+		lock->guard = false;
+		ipl_t ipl = lock->ipl;
+		
+		spinlock_unlock(&(lock->lock));
+		interrupts_restore(ipl);
+	} else {
+		ASSERT_IRQ_SPINLOCK(!lock->guard, lock);
+		spinlock_unlock(&(lock->lock));
+	}
+}
+
+/** Lock interrupts-disabled spinlock
+ *
+ * Lock an interrupts-disabled spinlock conditionally. If the
+ * spinlock is not available at the moment, signal failure.
+ * Interrupts are expected to be already disabled.
+ *
+ * @param lock IRQ spinlock to be locked conditionally.
+ *
+ * @return Zero on failure, non-zero otherwise.
+ *
+ */
+int irq_spinlock_trylock(irq_spinlock_t *lock)
+{
+	ASSERT_IRQ_SPINLOCK(interrupts_disabled(), lock);
+	int rc = spinlock_trylock(&(lock->lock));
+	
+	ASSERT_IRQ_SPINLOCK(!lock->guard, lock);
+	return rc;
+}
+
+/** Pass lock from one interrupts-disabled spinlock to another
+ *
+ * Pass lock from one IRQ spinlock to another IRQ spinlock
+ * without enabling interrupts during the process.
+ *
+ * The first IRQ spinlock is supposed to be locked.
+ *
+ * @param unlock IRQ spinlock to be unlocked.
+ * @param lock   IRQ spinlock to be locked.
+ *
+ */
+void irq_spinlock_pass(irq_spinlock_t *unlock, irq_spinlock_t *lock)
+{
+	ASSERT_IRQ_SPINLOCK(interrupts_disabled(), unlock);
+	
+	/* Pass guard from unlock to lock */
+	bool guard = unlock->guard;
+	ipl_t ipl = unlock->ipl;
+	unlock->guard = false;
+	
+	spinlock_unlock(&(unlock->lock));
+	spinlock_lock(&(lock->lock));
+	
+	ASSERT_IRQ_SPINLOCK(!lock->guard, lock);
+	
+	if (guard) {
+		lock->guard = true;
+		lock->ipl = ipl;
+	}
+}
+
+/** Hand-over-hand locking of interrupts-disabled spinlocks
+ *
+ * Implement hand-over-hand locking between two interrupts-disabled
+ * spinlocks without enabling interrupts during the process.
+ *
+ * The first IRQ spinlock is supposed to be locked.
+ *
+ * @param unlock IRQ spinlock to be unlocked.
+ * @param lock   IRQ spinlock to be locked.
+ *
+ */
+void irq_spinlock_exchange(irq_spinlock_t *unlock, irq_spinlock_t *lock)
+{
+	ASSERT_IRQ_SPINLOCK(interrupts_disabled(), unlock);
+	
+	spinlock_lock(&(lock->lock));
+	ASSERT_IRQ_SPINLOCK(!lock->guard, lock);
+	
+	/* Pass guard from unlock to lock */
+	if (unlock->guard) {
+		lock->guard = true;
+		lock->ipl = unlock->ipl;
+		unlock->guard = false;
+	}
+	
+	spinlock_unlock(&(unlock->lock));
+}
+
+/** Find out whether the IRQ spinlock is currently locked.
+ *
+ * @param lock		IRQ spinlock.
+ * @return		True if the IRQ spinlock is locked, false otherwise.
+ */
+bool irq_spinlock_locked(irq_spinlock_t *ilock)
+{
+	return spinlock_locked(&ilock->lock);
+}
+
 /** @}
  */
Index: kernel/generic/src/synch/waitq.c
===================================================================
--- kernel/generic/src/synch/waitq.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/generic/src/synch/waitq.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -33,5 +33,5 @@
 /**
  * @file
- * @brief	Wait queue.
+ * @brief Wait queue.
  *
  * Wait queue is the basic synchronization primitive upon which all
@@ -41,4 +41,5 @@
  * fashion. Conditional operation as well as timeouts and interruptions
  * are supported.
+ *
  */
 
@@ -56,5 +57,5 @@
 #include <arch/cycle.h>
 
-static void waitq_sleep_timed_out(void *data);
+static void waitq_sleep_timed_out(void *);
 
 /** Initialize wait queue
@@ -62,9 +63,10 @@
  * Initialize wait queue.
  *
- * @param wq		Pointer to wait queue to be initialized.
+ * @param wq Pointer to wait queue to be initialized.
+ *
  */
 void waitq_initialize(waitq_t *wq)
 {
-	spinlock_initialize(&wq->lock, "waitq_lock");
+	irq_spinlock_initialize(&wq->lock, "wq.lock");
 	list_initialize(&wq->head);
 	wq->missed_wakeups = 0;
@@ -81,41 +83,44 @@
  * timeout at all.
  *
- * @param data		Pointer to the thread that called waitq_sleep_timeout().
+ * @param data Pointer to the thread that called waitq_sleep_timeout().
+ *
  */
 void waitq_sleep_timed_out(void *data)
 {
-	thread_t *t = (thread_t *) data;
-	waitq_t *wq;
+	thread_t *thread = (thread_t *) data;
 	bool do_wakeup = false;
 	DEADLOCK_PROBE_INIT(p_wqlock);
-
-	spinlock_lock(&threads_lock);
-	if (!thread_exists(t))
+	
+	irq_spinlock_lock(&threads_lock, false);
+	if (!thread_exists(thread))
 		goto out;
-
+	
 grab_locks:
-	spinlock_lock(&t->lock);
-	if ((wq = t->sleep_queue)) {		/* assignment */
-		if (!spinlock_trylock(&wq->lock)) {
-			spinlock_unlock(&t->lock);
+	irq_spinlock_lock(&thread->lock, false);
+	
+	waitq_t *wq;
+	if ((wq = thread->sleep_queue)) {  /* Assignment */
+		if (!irq_spinlock_trylock(&wq->lock)) {
+			irq_spinlock_unlock(&thread->lock, false);
 			DEADLOCK_PROBE(p_wqlock, DEADLOCK_THRESHOLD);
-			goto grab_locks;	/* avoid deadlock */
-		}
-
-		list_remove(&t->wq_link);
-		t->saved_context = t->sleep_timeout_context;
+			/* Avoid deadlock */
+			goto grab_locks;
+		}
+		
+		list_remove(&thread->wq_link);
+		thread->saved_context = thread->sleep_timeout_context;
 		do_wakeup = true;
-		t->sleep_queue = NULL;
-		spinlock_unlock(&wq->lock);
-	}
-	
-	t->timeout_pending = false;
-	spinlock_unlock(&t->lock);
+		thread->sleep_queue = NULL;
+		irq_spinlock_unlock(&wq->lock, false);
+	}
+	
+	thread->timeout_pending = false;
+	irq_spinlock_unlock(&thread->lock, false);
 	
 	if (do_wakeup)
-		thread_ready(t);
-
+		thread_ready(thread);
+	
 out:
-	spinlock_unlock(&threads_lock);
+	irq_spinlock_unlock(&threads_lock, false);
 }
 
@@ -125,52 +130,54 @@
  * If the thread is not found sleeping, no action is taken.
  *
- * @param t		Thread to be interrupted.
- */
-void waitq_interrupt_sleep(thread_t *t)
-{
+ * @param thread Thread to be interrupted.
+ *
+ */
+void waitq_interrupt_sleep(thread_t *thread)
+{
+	bool do_wakeup = false;
+	DEADLOCK_PROBE_INIT(p_wqlock);
+	
+	irq_spinlock_lock(&threads_lock, true);
+	if (!thread_exists(thread))
+		goto out;
+	
+grab_locks:
+	irq_spinlock_lock(&thread->lock, false);
+	
 	waitq_t *wq;
-	bool do_wakeup = false;
-	ipl_t ipl;
-	DEADLOCK_PROBE_INIT(p_wqlock);
-
-	ipl = interrupts_disable();
-	spinlock_lock(&threads_lock);
-	if (!thread_exists(t))
-		goto out;
-
-grab_locks:
-	spinlock_lock(&t->lock);
-	if ((wq = t->sleep_queue)) {		/* assignment */
-		if (!(t->sleep_interruptible)) {
+	if ((wq = thread->sleep_queue)) {  /* Assignment */
+		if (!(thread->sleep_interruptible)) {
 			/*
 			 * The sleep cannot be interrupted.
+			 *
 			 */
-			spinlock_unlock(&t->lock);
+			irq_spinlock_unlock(&thread->lock, false);
 			goto out;
 		}
-			
-		if (!spinlock_trylock(&wq->lock)) {
-			spinlock_unlock(&t->lock);
+		
+		if (!irq_spinlock_trylock(&wq->lock)) {
+			irq_spinlock_unlock(&thread->lock, false);
 			DEADLOCK_PROBE(p_wqlock, DEADLOCK_THRESHOLD);
-			goto grab_locks;	/* avoid deadlock */
-		}
-
-		if (t->timeout_pending && timeout_unregister(&t->sleep_timeout))
-			t->timeout_pending = false;
-
-		list_remove(&t->wq_link);
-		t->saved_context = t->sleep_interruption_context;
+			/* Avoid deadlock */
+			goto grab_locks;
+		}
+		
+		if ((thread->timeout_pending) &&
+		    (timeout_unregister(&thread->sleep_timeout)))
+			thread->timeout_pending = false;
+		
+		list_remove(&thread->wq_link);
+		thread->saved_context = thread->sleep_interruption_context;
 		do_wakeup = true;
-		t->sleep_queue = NULL;
-		spinlock_unlock(&wq->lock);
-	}
-	spinlock_unlock(&t->lock);
-
+		thread->sleep_queue = NULL;
+		irq_spinlock_unlock(&wq->lock, false);
+	}
+	irq_spinlock_unlock(&thread->lock, false);
+	
 	if (do_wakeup)
-		thread_ready(t);
-
+		thread_ready(thread);
+	
 out:
-	spinlock_unlock(&threads_lock);
-	interrupts_restore(ipl);
+	irq_spinlock_unlock(&threads_lock, true);
 }
 
@@ -180,30 +187,31 @@
  * is sleeping interruptibly.
  *
- * @param wq		Pointer to wait queue.
+ * @param wq Pointer to wait queue.
+ *
  */
 void waitq_unsleep(waitq_t *wq)
 {
-	ipl_t ipl;
-
-	ipl = interrupts_disable();
-	spinlock_lock(&wq->lock);
-
+	irq_spinlock_lock(&wq->lock, true);
+	
 	if (!list_empty(&wq->head)) {
-		thread_t *t;
-		
-		t = list_get_instance(wq->head.next, thread_t, wq_link);
-		spinlock_lock(&t->lock);
-		ASSERT(t->sleep_interruptible);
-		if (t->timeout_pending && timeout_unregister(&t->sleep_timeout))
-			t->timeout_pending = false;
-		list_remove(&t->wq_link);
-		t->saved_context = t->sleep_interruption_context;
-		t->sleep_queue = NULL;
-		spinlock_unlock(&t->lock);
-		thread_ready(t);
-	}
-
-	spinlock_unlock(&wq->lock);
-	interrupts_restore(ipl);
+		thread_t *thread = list_get_instance(wq->head.next, thread_t, wq_link);
+		
+		irq_spinlock_lock(&thread->lock, false);
+		
+		ASSERT(thread->sleep_interruptible);
+		
+		if ((thread->timeout_pending) &&
+		    (timeout_unregister(&thread->sleep_timeout)))
+			thread->timeout_pending = false;
+		
+		list_remove(&thread->wq_link);
+		thread->saved_context = thread->sleep_interruption_context;
+		thread->sleep_queue = NULL;
+		
+		irq_spinlock_unlock(&thread->lock, false);
+		thread_ready(thread);
+	}
+	
+	irq_spinlock_unlock(&wq->lock, true);
 }
 
@@ -221,14 +229,14 @@
  * and all the *_timeout() functions use it.
  *
- * @param wq		Pointer to wait queue.
- * @param usec		Timeout in microseconds.
- * @param flags		Specify mode of the sleep.
+ * @param wq    Pointer to wait queue.
+ * @param usec  Timeout in microseconds.
+ * @param flags Specify mode of the sleep.
  *
  * The sleep can be interrupted only if the
  * SYNCH_FLAGS_INTERRUPTIBLE bit is specified in flags.
- * 
+ *
  * If usec is greater than zero, regardless of the value of the
  * SYNCH_FLAGS_NON_BLOCKING bit in flags, the call will not return until either
- * timeout, interruption or wakeup comes. 
+ * timeout, interruption or wakeup comes.
  *
  * If usec is zero and the SYNCH_FLAGS_NON_BLOCKING bit is not set in flags,
@@ -238,31 +246,22 @@
  * call will immediately return, reporting either success or failure.
  *
- * @return		Returns one of ESYNCH_WOULD_BLOCK, ESYNCH_TIMEOUT,
- * 			ESYNCH_INTERRUPTED, ESYNCH_OK_ATOMIC and
- * 			ESYNCH_OK_BLOCKED.
- *
- * @li	ESYNCH_WOULD_BLOCK means that the sleep failed because at the time of
- *	the call there was no pending wakeup.
- *
- * @li	ESYNCH_TIMEOUT means that the sleep timed out.
- *
- * @li	ESYNCH_INTERRUPTED means that somebody interrupted the sleeping thread.
- *
- * @li	ESYNCH_OK_ATOMIC means that the sleep succeeded and that there was
- * 	a pending wakeup at the time of the call. The caller was not put
- * 	asleep at all.
- * 
- * @li	ESYNCH_OK_BLOCKED means that the sleep succeeded; the full sleep was 
- * 	attempted.
- */
-int waitq_sleep_timeout(waitq_t *wq, uint32_t usec, int flags)
-{
-	ipl_t ipl;
-	int rc;
-
+ * @return ESYNCH_WOULD_BLOCK, meaning that the sleep failed because at the
+ *         time of the call there was no pending wakeup
+ * @return ESYNCH_TIMEOUT, meaning that the sleep timed out.
+ * @return ESYNCH_INTERRUPTED, meaning that somebody interrupted the sleeping
+ *         thread.
+ * @return ESYNCH_OK_ATOMIC, meaning that the sleep succeeded and that there
+ *         was a pending wakeup at the time of the call. The caller was not put
+ *         asleep at all.
+ * @return ESYNCH_OK_BLOCKED, meaning that the sleep succeeded; the full sleep
+ *         was attempted.
+ *
+ */
+int waitq_sleep_timeout(waitq_t *wq, uint32_t usec, unsigned int flags)
+{
 	ASSERT((!PREEMPTION_DISABLED) || (PARAM_NON_BLOCKING(flags, usec)));
 	
-	ipl = waitq_sleep_prepare(wq);
-	rc = waitq_sleep_timeout_unsafe(wq, usec, flags);
+	ipl_t ipl = waitq_sleep_prepare(wq);
+	int rc = waitq_sleep_timeout_unsafe(wq, usec, flags);
 	waitq_sleep_finish(wq, rc, ipl);
 	return rc;
@@ -274,7 +273,8 @@
  * and interrupts disabled.
  *
- * @param wq		Wait queue.
- *
- * @return		Interrupt level as it existed on entry to this function.
+ * @param wq Wait queue.
+ *
+ * @return Interrupt level as it existed on entry to this function.
+ *
  */
 ipl_t waitq_sleep_prepare(waitq_t *wq)
@@ -284,6 +284,6 @@
 restart:
 	ipl = interrupts_disable();
-
-	if (THREAD) {	/* needed during system initiailzation */
+	
+	if (THREAD) {  /* Needed during system initiailzation */
 		/*
 		 * Busy waiting for a delayed timeout.
@@ -292,15 +292,18 @@
 		 * Simply, the thread is not allowed to go to sleep if
 		 * there are timeouts in progress.
+		 *
 		 */
-		spinlock_lock(&THREAD->lock);
+		irq_spinlock_lock(&THREAD->lock, false);
+		
 		if (THREAD->timeout_pending) {
-			spinlock_unlock(&THREAD->lock);
+			irq_spinlock_unlock(&THREAD->lock, false);
 			interrupts_restore(ipl);
 			goto restart;
 		}
-		spinlock_unlock(&THREAD->lock);
-	}
-													
-	spinlock_lock(&wq->lock);
+		
+		irq_spinlock_unlock(&THREAD->lock, false);
+	}
+	
+	irq_spinlock_lock(&wq->lock, false);
 	return ipl;
 }
@@ -312,7 +315,8 @@
  * lock is released.
  *
- * @param wq		Wait queue.
- * @param rc		Return code of waitq_sleep_timeout_unsafe().
- * @param ipl		Interrupt level returned by waitq_sleep_prepare().
+ * @param wq  Wait queue.
+ * @param rc  Return code of waitq_sleep_timeout_unsafe().
+ * @param ipl Interrupt level returned by waitq_sleep_prepare().
+ *
  */
 void waitq_sleep_finish(waitq_t *wq, int rc, ipl_t ipl)
@@ -321,9 +325,10 @@
 	case ESYNCH_WOULD_BLOCK:
 	case ESYNCH_OK_ATOMIC:
-		spinlock_unlock(&wq->lock);
+		irq_spinlock_unlock(&wq->lock, false);
 		break;
 	default:
 		break;
 	}
+	
 	interrupts_restore(ipl);
 }
@@ -335,20 +340,20 @@
  * and followed by a call to waitq_sleep_finish().
  *
- * @param wq		See waitq_sleep_timeout().
- * @param usec		See waitq_sleep_timeout().
- * @param flags		See waitq_sleep_timeout().
- *
- * @return		See waitq_sleep_timeout().
- */
-int waitq_sleep_timeout_unsafe(waitq_t *wq, uint32_t usec, int flags)
-{
-	/* checks whether to go to sleep at all */
+ * @param wq    See waitq_sleep_timeout().
+ * @param usec  See waitq_sleep_timeout().
+ * @param flags See waitq_sleep_timeout().
+ *
+ * @return See waitq_sleep_timeout().
+ *
+ */
+int waitq_sleep_timeout_unsafe(waitq_t *wq, uint32_t usec, unsigned int flags)
+{
+	/* Checks whether to go to sleep at all */
 	if (wq->missed_wakeups) {
 		wq->missed_wakeups--;
 		return ESYNCH_OK_ATOMIC;
-	}
-	else {
+	} else {
 		if (PARAM_NON_BLOCKING(flags, usec)) {
-			/* return immediatelly instead of going to sleep */
+			/* Return immediatelly instead of going to sleep */
 			return ESYNCH_WOULD_BLOCK;
 		}
@@ -357,22 +362,24 @@
 	/*
 	 * Now we are firmly decided to go to sleep.
+	 *
 	 */
-	spinlock_lock(&THREAD->lock);
-
+	irq_spinlock_lock(&THREAD->lock, false);
+	
 	if (flags & SYNCH_FLAGS_INTERRUPTIBLE) {
-
 		/*
 		 * If the thread was already interrupted,
 		 * don't go to sleep at all.
+		 *
 		 */
 		if (THREAD->interrupted) {
-			spinlock_unlock(&THREAD->lock);
-			spinlock_unlock(&wq->lock);
+			irq_spinlock_unlock(&THREAD->lock, false);
+			irq_spinlock_unlock(&wq->lock, false);
 			return ESYNCH_INTERRUPTED;
 		}
-
+		
 		/*
 		 * Set context that will be restored if the sleep
 		 * of this thread is ever interrupted.
+		 *
 		 */
 		THREAD->sleep_interruptible = true;
@@ -380,12 +387,10 @@
 			/* Short emulation of scheduler() return code. */
 			THREAD->last_cycle = get_cycle();
-			spinlock_unlock(&THREAD->lock);
+			irq_spinlock_unlock(&THREAD->lock, false);
 			return ESYNCH_INTERRUPTED;
 		}
-
-	} else {
+	} else
 		THREAD->sleep_interruptible = false;
-	}
-
+	
 	if (usec) {
 		/* We use the timeout variant. */
@@ -393,28 +398,29 @@
 			/* Short emulation of scheduler() return code. */
 			THREAD->last_cycle = get_cycle();
-			spinlock_unlock(&THREAD->lock);
+			irq_spinlock_unlock(&THREAD->lock, false);
 			return ESYNCH_TIMEOUT;
 		}
+		
 		THREAD->timeout_pending = true;
 		timeout_register(&THREAD->sleep_timeout, (uint64_t) usec,
 		    waitq_sleep_timed_out, THREAD);
 	}
-
+	
 	list_append(&THREAD->wq_link, &wq->head);
-
+	
 	/*
 	 * Suspend execution.
+	 *
 	 */
 	THREAD->state = Sleeping;
 	THREAD->sleep_queue = wq;
-
-	spinlock_unlock(&THREAD->lock);
-
+	
+	irq_spinlock_unlock(&THREAD->lock, false);
+	
 	/* wq->lock is released in scheduler_separated_stack() */
-	scheduler(); 
+	scheduler();
 	
 	return ESYNCH_OK_BLOCKED;
 }
-
 
 /** Wake up first thread sleeping in a wait queue
@@ -426,18 +432,13 @@
  * timeout.
  *
- * @param wq		Pointer to wait queue.
- * @param mode		Wakeup mode.
+ * @param wq   Pointer to wait queue.
+ * @param mode Wakeup mode.
+ *
  */
 void waitq_wakeup(waitq_t *wq, wakeup_mode_t mode)
 {
-	ipl_t ipl;
-
-	ipl = interrupts_disable();
-	spinlock_lock(&wq->lock);
-
+	irq_spinlock_lock(&wq->lock, true);
 	_waitq_wakeup_unsafe(wq, mode);
-
-	spinlock_unlock(&wq->lock);
-	interrupts_restore(ipl);
+	irq_spinlock_unlock(&wq->lock, true);
 }
 
@@ -447,26 +448,30 @@
  * assumes wq->lock is already locked and interrupts are already disabled.
  *
- * @param wq		Pointer to wait queue.
- * @param mode		If mode is WAKEUP_FIRST, then the longest waiting
- * 			thread, if any, is woken up. If mode is WAKEUP_ALL, then
- *			all waiting threads, if any, are woken up. If there are
- *			no waiting threads to be woken up, the missed wakeup is
- *			recorded in the wait queue.
+ * @param wq   Pointer to wait queue.
+ * @param mode If mode is WAKEUP_FIRST, then the longest waiting
+ *             thread, if any, is woken up. If mode is WAKEUP_ALL, then
+ *             all waiting threads, if any, are woken up. If there are
+ *             no waiting threads to be woken up, the missed wakeup is
+ *             recorded in the wait queue.
+ *
  */
 void _waitq_wakeup_unsafe(waitq_t *wq, wakeup_mode_t mode)
 {
-	thread_t *t;
 	size_t count = 0;
 
-loop:	
+	ASSERT(interrupts_disabled());
+	ASSERT(irq_spinlock_locked(&wq->lock));
+	
+loop:
 	if (list_empty(&wq->head)) {
 		wq->missed_wakeups++;
-		if (count && mode == WAKEUP_ALL)
+		if ((count) && (mode == WAKEUP_ALL))
 			wq->missed_wakeups--;
+		
 		return;
 	}
-
+	
 	count++;
-	t = list_get_instance(wq->head.next, thread_t, wq_link);
+	thread_t *thread = list_get_instance(wq->head.next, thread_t, wq_link);
 	
 	/*
@@ -480,24 +485,55 @@
 	 * invariant must hold:
 	 *
-	 * t->sleep_queue != NULL <=> t sleeps in a wait queue
+	 * thread->sleep_queue != NULL <=> thread sleeps in a wait queue
 	 *
 	 * For an observer who locks the thread, the invariant
 	 * holds only when the lock is held prior to removing
 	 * it from the wait queue.
+	 *
 	 */
-	spinlock_lock(&t->lock);
-	list_remove(&t->wq_link);
-	
-	if (t->timeout_pending && timeout_unregister(&t->sleep_timeout))
-		t->timeout_pending = false;
-	t->sleep_queue = NULL;
-	spinlock_unlock(&t->lock);
-
-	thread_ready(t);
-
+	irq_spinlock_lock(&thread->lock, false);
+	list_remove(&thread->wq_link);
+	
+	if ((thread->timeout_pending) &&
+	    (timeout_unregister(&thread->sleep_timeout)))
+		thread->timeout_pending = false;
+	
+	thread->sleep_queue = NULL;
+	irq_spinlock_unlock(&thread->lock, false);
+	
+	thread_ready(thread);
+	
 	if (mode == WAKEUP_ALL)
 		goto loop;
 }
 
+/** Get the missed wakeups count.
+ *
+ * @param wq	Pointer to wait queue.
+ * @return	The wait queue's missed_wakeups count.
+ */
+int waitq_count_get(waitq_t *wq)
+{
+	int cnt;
+
+	irq_spinlock_lock(&wq->lock, true);
+	cnt = wq->missed_wakeups;
+	irq_spinlock_unlock(&wq->lock, true);
+
+	return cnt;
+}
+
+/** Set the missed wakeups count.
+ *
+ * @param wq	Pointer to wait queue.
+ * @param val	New value of the missed_wakeups count.
+ */
+void waitq_count_set(waitq_t *wq, int val)
+{
+	irq_spinlock_lock(&wq->lock, true);
+	wq->missed_wakeups = val;
+	irq_spinlock_unlock(&wq->lock, true);
+}
+
 /** @}
  */
Index: kernel/generic/src/syscall/syscall.c
===================================================================
--- kernel/generic/src/syscall/syscall.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/generic/src/syscall/syscall.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -59,24 +59,20 @@
     unative_t a4, unative_t a5, unative_t a6, unative_t id)
 {
-	unative_t rc;
-	ipl_t ipl;
-
 	/* Do userpace accounting */
-	ipl = interrupts_disable();
-	spinlock_lock(&THREAD->lock);
+	irq_spinlock_lock(&THREAD->lock, true);
 	thread_update_accounting(true);
-	spinlock_unlock(&THREAD->lock);
-	interrupts_restore(ipl);
-
+	irq_spinlock_unlock(&THREAD->lock, true);
+	
 #ifdef CONFIG_UDEBUG
 	/*
 	 * Early check for undebugged tasks. We do not lock anything as this
 	 * test need not be precise in either direction.
+	 *
 	 */
-	if (THREAD->udebug.active) {
+	if (THREAD->udebug.active)
 		udebug_syscall_event(a1, a2, a3, a4, a5, a6, id, 0, false);
-	}
 #endif
 	
+	unative_t rc;
 	if (id < SYSCALL_END) {
 		rc = syscall_table[id](a1, a2, a3, a4, a5, a6);
@@ -93,5 +89,5 @@
 	if (THREAD->udebug.active) {
 		udebug_syscall_event(a1, a2, a3, a4, a5, a6, id, rc, true);
-	
+		
 		/*
 		 * Stopping point needed for tasks that only invoke
@@ -103,11 +99,9 @@
 	}
 #endif
-
+	
 	/* Do kernel accounting */
-	(void) interrupts_disable();
-	spinlock_lock(&THREAD->lock);
+	irq_spinlock_lock(&THREAD->lock, true);
 	thread_update_accounting(false);
-	spinlock_unlock(&THREAD->lock);
-	interrupts_restore(ipl);
+	irq_spinlock_unlock(&THREAD->lock, true);
 	
 	return rc;
@@ -165,5 +159,4 @@
 	(syshandler_t) sys_physmem_map,
 	(syshandler_t) sys_iospace_enable,
-	(syshandler_t) sys_preempt_control,
 	(syshandler_t) sys_interrupt_enable,
 	
Index: kernel/generic/src/sysinfo/stats.c
===================================================================
--- kernel/generic/src/sysinfo/stats.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/generic/src/sysinfo/stats.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -44,4 +44,5 @@
 #include <proc/task.h>
 #include <proc/thread.h>
+#include <interrupt.h>
 #include <str.h>
 #include <errno.h>
@@ -52,4 +53,10 @@
 #define LOAD_FIXED_SHIFT  11
 
+/** Uspace load fixed-point precision */
+#define LOAD_USPACE_SHIFT  6
+
+/** Kernel load shift */
+#define LOAD_KERNEL_SHIFT  (LOAD_FIXED_SHIFT - LOAD_USPACE_SHIFT)
+
 /** 1.0 as fixed-point for load */
 #define LOAD_FIXED_1  (1 << LOAD_FIXED_SHIFT)
@@ -110,21 +117,16 @@
 	}
 	
-	/* Each CPU structure is locked separatelly */
-	ipl_t ipl = interrupts_disable();
-	
 	size_t i;
 	for (i = 0; i < config.cpu_count; i++) {
-		spinlock_lock(&cpus[i].lock);
+		irq_spinlock_lock(&cpus[i].lock, true);
 		
 		stats_cpus[i].id = cpus[i].id;
 		stats_cpus[i].active = cpus[i].active;
 		stats_cpus[i].frequency_mhz = cpus[i].frequency_mhz;
-		stats_cpus[i].busy_ticks = cpus[i].busy_ticks;
-		stats_cpus[i].idle_ticks = cpus[i].idle_ticks;
-		
-		spinlock_unlock(&cpus[i].lock);
-	}
-	
-	interrupts_restore(ipl);
+		stats_cpus[i].busy_cycles = cpus[i].busy_cycles;
+		stats_cpus[i].idle_cycles = cpus[i].idle_cycles;
+		
+		irq_spinlock_unlock(&cpus[i].lock, true);
+	}
 	
 	return ((void *) stats_cpus);
@@ -200,6 +202,4 @@
  *
  * Summarize task information into task statistics.
- * Task lock should be held and interrupts disabled
- * before executing this function.
  *
  * @param task       Task.
@@ -209,4 +209,7 @@
 static void produce_stats_task(task_t *task, stats_task_t *stats_task)
 {
+	ASSERT(interrupts_disabled());
+	ASSERT(irq_spinlock_locked(&task->lock));
+
 	stats_task->task_id = task->taskid;
 	str_cpy(stats_task->name, TASK_NAME_BUFLEN, task->name);
@@ -235,5 +238,5 @@
 	
 	/* Interrupts are already disabled */
-	spinlock_lock(&(task->lock));
+	irq_spinlock_lock(&(task->lock), false);
 	
 	/* Record the statistics and increment the iterator */
@@ -241,5 +244,5 @@
 	(*iterator)++;
 	
-	spinlock_unlock(&(task->lock));
+	irq_spinlock_unlock(&(task->lock), false);
 	
 	return true;
@@ -260,6 +263,5 @@
 {
 	/* Messing with task structures, avoid deadlock */
-	ipl_t ipl = interrupts_disable();
-	spinlock_lock(&tasks_lock);
+	irq_spinlock_lock(&tasks_lock, true);
 	
 	/* First walk the task tree to count the tasks */
@@ -269,7 +271,5 @@
 	if (count == 0) {
 		/* No tasks found (strange) */
-		spinlock_unlock(&tasks_lock);
-		interrupts_restore(ipl);
-		
+		irq_spinlock_unlock(&tasks_lock, true);
 		*size = 0;
 		return NULL;
@@ -278,6 +278,5 @@
 	*size = sizeof(stats_task_t) * count;
 	if (dry_run) {
-		spinlock_unlock(&tasks_lock);
-		interrupts_restore(ipl);
+		irq_spinlock_unlock(&tasks_lock, true);
 		return NULL;
 	}
@@ -286,7 +285,5 @@
 	if (stats_tasks == NULL) {
 		/* No free space for allocation */
-		spinlock_unlock(&tasks_lock);
-		interrupts_restore(ipl);
-		
+		irq_spinlock_unlock(&tasks_lock, true);
 		*size = 0;
 		return NULL;
@@ -297,6 +294,5 @@
 	avltree_walk(&tasks_tree, task_serialize_walker, (void *) &iterator);
 	
-	spinlock_unlock(&tasks_lock);
-	interrupts_restore(ipl);
+	irq_spinlock_unlock(&tasks_lock, true);
 	
 	return ((void *) stats_tasks);
@@ -306,6 +302,4 @@
  *
  * Summarize thread information into thread statistics.
- * Thread lock should be held and interrupts disabled
- * before executing this function.
  *
  * @param thread       Thread.
@@ -315,4 +309,7 @@
 static void produce_stats_thread(thread_t *thread, stats_thread_t *stats_thread)
 {
+	ASSERT(interrupts_disabled());
+	ASSERT(irq_spinlock_locked(&thread->lock));
+
 	stats_thread->thread_id = thread->tid;
 	stats_thread->task_id = thread->task->taskid;
@@ -346,5 +343,5 @@
 	
 	/* Interrupts are already disabled */
-	spinlock_lock(&thread->lock);
+	irq_spinlock_lock(&thread->lock, false);
 	
 	/* Record the statistics and increment the iterator */
@@ -352,5 +349,5 @@
 	(*iterator)++;
 	
-	spinlock_unlock(&thread->lock);
+	irq_spinlock_unlock(&thread->lock, false);
 	
 	return true;
@@ -371,6 +368,5 @@
 {
 	/* Messing with threads structures, avoid deadlock */
-	ipl_t ipl = interrupts_disable();
-	spinlock_lock(&threads_lock);
+	irq_spinlock_lock(&threads_lock, true);
 	
 	/* First walk the thread tree to count the threads */
@@ -380,7 +376,5 @@
 	if (count == 0) {
 		/* No threads found (strange) */
-		spinlock_unlock(&threads_lock);
-		interrupts_restore(ipl);
-		
+		irq_spinlock_unlock(&threads_lock, true);
 		*size = 0;
 		return NULL;
@@ -389,6 +383,5 @@
 	*size = sizeof(stats_thread_t) * count;
 	if (dry_run) {
-		spinlock_unlock(&threads_lock);
-		interrupts_restore(ipl);
+		irq_spinlock_unlock(&threads_lock, true);
 		return NULL;
 	}
@@ -397,7 +390,5 @@
 	if (stats_threads == NULL) {
 		/* No free space for allocation */
-		spinlock_unlock(&threads_lock);
-		interrupts_restore(ipl);
-		
+		irq_spinlock_unlock(&threads_lock, true);
 		*size = 0;
 		return NULL;
@@ -408,6 +399,5 @@
 	avltree_walk(&threads_tree, thread_serialize_walker, (void *) &iterator);
 	
-	spinlock_unlock(&threads_lock);
-	interrupts_restore(ipl);
+	irq_spinlock_unlock(&threads_lock, true);
 	
 	return ((void *) stats_threads);
@@ -443,12 +433,10 @@
 	
 	/* Messing with task structures, avoid deadlock */
-	ipl_t ipl = interrupts_disable();
-	spinlock_lock(&tasks_lock);
+	irq_spinlock_lock(&tasks_lock, true);
 	
 	task_t *task = task_find_by_id(task_id);
 	if (task == NULL) {
 		/* No task with this ID */
-		spinlock_unlock(&tasks_lock);
-		interrupts_restore(ipl);
+		irq_spinlock_unlock(&tasks_lock, true);
 		return ret;
 	}
@@ -459,5 +447,5 @@
 		ret.data.size = sizeof(stats_task_t);
 		
-		spinlock_unlock(&tasks_lock);
+		irq_spinlock_unlock(&tasks_lock, true);
 	} else {
 		/* Allocate stats_task_t structure */
@@ -465,6 +453,5 @@
 		    (stats_task_t *) malloc(sizeof(stats_task_t), FRAME_ATOMIC);
 		if (stats_task == NULL) {
-			spinlock_unlock(&tasks_lock);
-			interrupts_restore(ipl);
+			irq_spinlock_unlock(&tasks_lock, true);
 			return ret;
 		}
@@ -474,15 +461,12 @@
 		ret.data.data = (void *) stats_task;
 		ret.data.size = sizeof(stats_task_t);
-	
+		
 		/* Hand-over-hand locking */
-		spinlock_lock(&task->lock);
-		spinlock_unlock(&tasks_lock);
+		irq_spinlock_exchange(&tasks_lock, &task->lock);
 		
 		produce_stats_task(task, stats_task);
 		
-		spinlock_unlock(&task->lock);
-	}
-	
-	interrupts_restore(ipl);
+		irq_spinlock_unlock(&task->lock, true);
+	}
 	
 	return ret;
@@ -518,12 +502,10 @@
 	
 	/* Messing with threads structures, avoid deadlock */
-	ipl_t ipl = interrupts_disable();
-	spinlock_lock(&threads_lock);
+	irq_spinlock_lock(&threads_lock, true);
 	
 	thread_t *thread = thread_find_by_id(thread_id);
 	if (thread == NULL) {
 		/* No thread with this ID */
-		spinlock_unlock(&threads_lock);
-		interrupts_restore(ipl);
+		irq_spinlock_unlock(&threads_lock, true);
 		return ret;
 	}
@@ -534,5 +516,5 @@
 		ret.data.size = sizeof(stats_thread_t);
 		
-		spinlock_unlock(&threads_lock);
+		irq_spinlock_unlock(&threads_lock, true);
 	} else {
 		/* Allocate stats_thread_t structure */
@@ -540,6 +522,5 @@
 		    (stats_thread_t *) malloc(sizeof(stats_thread_t), FRAME_ATOMIC);
 		if (stats_thread == NULL) {
-			spinlock_unlock(&threads_lock);
-			interrupts_restore(ipl);
+			irq_spinlock_unlock(&threads_lock, true);
 			return ret;
 		}
@@ -551,13 +532,129 @@
 		
 		/* Hand-over-hand locking */
-		spinlock_lock(&thread->lock);
-		spinlock_unlock(&threads_lock);
+		irq_spinlock_exchange(&threads_lock, &thread->lock);
 		
 		produce_stats_thread(thread, stats_thread);
 		
-		spinlock_unlock(&thread->lock);
-	}
-	
-	interrupts_restore(ipl);
+		irq_spinlock_unlock(&thread->lock, true);
+	}
+	
+	return ret;
+}
+
+/** Get exceptions statistics
+ *
+ * @param item    Sysinfo item (unused).
+ * @param size    Size of the returned data.
+ * @param dry_run Do not get the data, just calculate the size.
+ *
+ * @return Data containing several stats_exc_t structures.
+ *         If the return value is not NULL, it should be freed
+ *         in the context of the sysinfo request.
+ */
+static void *get_stats_exceptions(struct sysinfo_item *item, size_t *size,
+    bool dry_run)
+{
+	*size = sizeof(stats_exc_t) * IVT_ITEMS;
+	
+	if ((dry_run) || (IVT_ITEMS == 0))
+		return NULL;
+	
+	stats_exc_t *stats_exceptions =
+	    (stats_exc_t *) malloc(*size, FRAME_ATOMIC);
+	if (stats_exceptions == NULL) {
+		/* No free space for allocation */
+		*size = 0;
+		return NULL;
+	}
+	
+#if (IVT_ITEMS > 0)
+	/* Messing with exception table, avoid deadlock */
+	irq_spinlock_lock(&exctbl_lock, true);
+	
+	unsigned int i;
+	for (i = 0; i < IVT_ITEMS; i++) {
+		stats_exceptions[i].id = i + IVT_FIRST;
+		str_cpy(stats_exceptions[i].desc, EXC_NAME_BUFLEN, exc_table[i].name);
+		stats_exceptions[i].hot = exc_table[i].hot;
+		stats_exceptions[i].cycles = exc_table[i].cycles;
+		stats_exceptions[i].count = exc_table[i].count;
+	}
+	
+	irq_spinlock_unlock(&exctbl_lock, true);
+#endif
+	
+	return ((void *) stats_exceptions);
+}
+
+/** Get exception statistics
+ *
+ * Get statistics of a given exception. The exception number
+ * is passed as a string (current limitation of the sysinfo
+ * interface, but it is still reasonable for the given purpose).
+ *
+ * @param name    Exception number (string-encoded number).
+ * @param dry_run Do not get the data, just calculate the size.
+ *
+ * @return Sysinfo return holder. The type of the returned
+ *         data is either SYSINFO_VAL_UNDEFINED (unknown
+ *         exception number or memory allocation error) or
+ *         SYSINFO_VAL_FUNCTION_DATA (in that case the
+ *         generated data should be freed within the
+ *         sysinfo request context).
+ *
+ */
+static sysinfo_return_t get_stats_exception(const char *name, bool dry_run)
+{
+	/* Initially no return value */
+	sysinfo_return_t ret;
+	ret.tag = SYSINFO_VAL_UNDEFINED;
+	
+	/* Parse the exception number */
+	uint64_t excn;
+	if (str_uint64(name, NULL, 0, true, &excn) != EOK)
+		return ret;
+	
+#if (IVT_FIRST > 0)
+	if (excn < IVT_FIRST)
+		return ret;
+#endif
+	
+#if (IVT_ITEMS + IVT_FIRST == 0)
+	return ret;
+#else
+	if (excn >= IVT_ITEMS + IVT_FIRST)
+		return ret;
+#endif
+	
+	if (dry_run) {
+		ret.tag = SYSINFO_VAL_FUNCTION_DATA;
+		ret.data.data = NULL;
+		ret.data.size = sizeof(stats_thread_t);
+	} else {
+		/* Update excn index for accessing exc_table */
+		excn -= IVT_FIRST;
+		
+		/* Allocate stats_exc_t structure */
+		stats_exc_t *stats_exception =
+		    (stats_exc_t *) malloc(sizeof(stats_exc_t), FRAME_ATOMIC);
+		if (stats_exception == NULL)
+			return ret;
+		
+		/* Messing with exception table, avoid deadlock */
+		irq_spinlock_lock(&exctbl_lock, true);
+		
+		/* Correct return value */
+		ret.tag = SYSINFO_VAL_FUNCTION_DATA;
+		ret.data.data = (void *) stats_exception;
+		ret.data.size = sizeof(stats_exc_t);
+		
+		stats_exception->id = excn;
+		str_cpy(stats_exception->desc, EXC_NAME_BUFLEN, exc_table[excn].name);
+		stats_exception->hot = exc_table[excn].hot;
+		stats_exception->cycles = exc_table[excn].cycles;
+		stats_exception->count = exc_table[excn].count;
+		
+		irq_spinlock_unlock(&exctbl_lock, true);
+	}
 	
 	return ret;
@@ -622,5 +719,5 @@
 	unsigned int i;
 	for (i = 0; i < LOAD_STEPS; i++)
-		stats_load[i] = avenrdy[i] << LOAD_FIXED_SHIFT;
+		stats_load[i] = avenrdy[i] << LOAD_KERNEL_SHIFT;
 	
 	mutex_unlock(&load_lock);
@@ -673,5 +770,5 @@
 {
 	mutex_initialize(&load_lock, MUTEX_PASSIVE);
-
+	
 	sysinfo_set_item_fn_val("system.uptime", NULL, get_stats_uptime);
 	sysinfo_set_item_fn_data("system.cpus", NULL, get_stats_cpus);
@@ -680,6 +777,8 @@
 	sysinfo_set_item_fn_data("system.tasks", NULL, get_stats_tasks);
 	sysinfo_set_item_fn_data("system.threads", NULL, get_stats_threads);
+	sysinfo_set_item_fn_data("system.exceptions", NULL, get_stats_exceptions);
 	sysinfo_set_subtree_fn("system.tasks", NULL, get_stats_task);
 	sysinfo_set_subtree_fn("system.threads", NULL, get_stats_thread);
+	sysinfo_set_subtree_fn("system.exceptions", NULL, get_stats_exception);
 }
 
Index: kernel/generic/src/sysinfo/sysinfo.c
===================================================================
--- kernel/generic/src/sysinfo/sysinfo.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/generic/src/sysinfo/sysinfo.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -58,5 +58,5 @@
  *
  */
-static int sysinfo_item_constructor(void *obj, int kmflag)
+NO_TRACE static int sysinfo_item_constructor(void *obj, unsigned int kmflag)
 {
 	sysinfo_item_t *item = (sysinfo_item_t *) obj;
@@ -78,5 +78,5 @@
  *
  */
-static int sysinfo_item_destructor(void *obj)
+NO_TRACE static size_t sysinfo_item_destructor(void *obj)
 {
 	sysinfo_item_t *item = (sysinfo_item_t *) obj;
@@ -120,5 +120,5 @@
  *
  */
-static sysinfo_item_t *sysinfo_find_item(const char *name,
+NO_TRACE static sysinfo_item_t *sysinfo_find_item(const char *name,
     sysinfo_item_t *subtree, sysinfo_return_t **ret, bool dry_run)
 {
@@ -180,5 +180,5 @@
  *
  */
-static sysinfo_item_t *sysinfo_create_path(const char *name,
+NO_TRACE static sysinfo_item_t *sysinfo_create_path(const char *name,
     sysinfo_item_t **psubtree)
 {
@@ -458,5 +458,5 @@
  *
  */
-static void sysinfo_indent(unsigned int depth)
+NO_TRACE static void sysinfo_indent(unsigned int depth)
 {
 	unsigned int i;
@@ -473,5 +473,5 @@
  *
  */
-static void sysinfo_dump_internal(sysinfo_item_t *root, unsigned int depth)
+NO_TRACE static void sysinfo_dump_internal(sysinfo_item_t *root, unsigned int depth)
 {
 	sysinfo_item_t *cur = root;
@@ -567,5 +567,5 @@
  *
  */
-static sysinfo_return_t sysinfo_get_item(const char *name,
+NO_TRACE static sysinfo_return_t sysinfo_get_item(const char *name,
     sysinfo_item_t **root, bool dry_run)
 {
@@ -622,5 +622,5 @@
  *
  */
-static sysinfo_return_t sysinfo_get_item_uspace(void *ptr, size_t size,
+NO_TRACE static sysinfo_return_t sysinfo_get_item_uspace(void *ptr, size_t size,
     bool dry_run)
 {
Index: kernel/generic/src/time/clock.c
===================================================================
--- kernel/generic/src/time/clock.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/generic/src/time/clock.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -33,11 +33,12 @@
 /**
  * @file
- * @brief	High-level clock interrupt handler.
+ * @brief High-level clock interrupt handler.
  *
  * This file contains the clock() function which is the source
  * of preemption. It is also responsible for executing expired
  * timeouts.
- */
- 
+ *
+ */
+
 #include <time/clock.h>
 #include <time/timeout.h>
@@ -56,4 +57,5 @@
 #include <mm/frame.h>
 #include <ddi/ddi.h>
+#include <arch/cycle.h>
 
 /* Pointer to variable with uptime */
@@ -63,6 +65,8 @@
 static parea_t clock_parea;
 
-/* Variable holding fragment of second, so that we would update
- * seconds correctly
+/** Fragment of second
+ *
+ * For updating  seconds correctly.
+ *
  */
 static unative_t secfrag = 0;
@@ -73,10 +77,9 @@
  * information about realtime data. We allocate 1 page with these 
  * data and update it periodically.
+ *
  */
 void clock_counter_init(void)
 {
-	void *faddr;
-
-	faddr = frame_alloc(ONE_FRAME, FRAME_ATOMIC);
+	void *faddr = frame_alloc(ONE_FRAME, FRAME_ATOMIC);
 	if (!faddr)
 		panic("Cannot allocate page for clock.");
@@ -87,12 +90,13 @@
 	uptime->seconds2 = 0;
 	uptime->useconds = 0;
-
+	
 	clock_parea.pbase = (uintptr_t) faddr;
 	clock_parea.frames = 1;
 	ddi_parea_register(&clock_parea);
-
+	
 	/*
 	 * Prepare information for the userspace so that it can successfully
 	 * physmem_map() the clock_parea.
+	 *
 	 */
 	sysinfo_set_item_val("clock.cacheable", NULL, (unative_t) true);
@@ -100,9 +104,9 @@
 }
 
-
 /** Update public counters
  *
  * Update it only on first processor
- * TODO: Do we really need so many write barriers? 
+ * TODO: Do we really need so many write barriers?
+ *
  */
 static void clock_update_counters(void)
@@ -122,4 +126,13 @@
 }
 
+static void cpu_update_accounting(void)
+{
+	irq_spinlock_lock(&CPU->lock, false);
+	uint64_t now = get_cycle();
+	CPU->busy_cycles += now - CPU->last_cycle;
+	CPU->last_cycle = now;
+	irq_spinlock_unlock(&CPU->lock, false);
+}
+
 /** Clock routine
  *
@@ -131,60 +144,62 @@
 void clock(void)
 {
-	link_t *l;
-	timeout_t *h;
-	timeout_handler_t f;
-	void *arg;
 	size_t missed_clock_ticks = CPU->missed_clock_ticks;
-	unsigned int i;
-
-	/* Account lost ticks to CPU usage */
-	if (CPU->idle) {
-		CPU->idle_ticks += missed_clock_ticks + 1;
-	} else {
-		CPU->busy_ticks += missed_clock_ticks + 1;
-	}
-	CPU->idle = false;
-
+	
+	/* Account CPU usage */
+	cpu_update_accounting();
+	
 	/*
 	 * To avoid lock ordering problems,
 	 * run all expired timeouts as you visit them.
+	 *
 	 */
+	size_t i;
 	for (i = 0; i <= missed_clock_ticks; i++) {
+		/* Update counters and accounting */
 		clock_update_counters();
-		spinlock_lock(&CPU->timeoutlock);
-		while ((l = CPU->timeout_active_head.next) != &CPU->timeout_active_head) {
-			h = list_get_instance(l, timeout_t, link);
-			spinlock_lock(&h->lock);
-			if (h->ticks-- != 0) {
-				spinlock_unlock(&h->lock);
+		cpu_update_accounting();
+		
+		irq_spinlock_lock(&CPU->timeoutlock, false);
+		
+		link_t *cur;
+		while ((cur = CPU->timeout_active_head.next) != &CPU->timeout_active_head) {
+			timeout_t *timeout = list_get_instance(cur, timeout_t, link);
+			
+			irq_spinlock_lock(&timeout->lock, false);
+			if (timeout->ticks-- != 0) {
+				irq_spinlock_unlock(&timeout->lock, false);
 				break;
 			}
-			list_remove(l);
-			f = h->handler;
-			arg = h->arg;
-			timeout_reinitialize(h);
-			spinlock_unlock(&h->lock);	
-			spinlock_unlock(&CPU->timeoutlock);
-
-			f(arg);
-
-			spinlock_lock(&CPU->timeoutlock);
+			
+			list_remove(cur);
+			timeout_handler_t handler = timeout->handler;
+			void *arg = timeout->arg;
+			timeout_reinitialize(timeout);
+			
+			irq_spinlock_unlock(&timeout->lock, false);
+			irq_spinlock_unlock(&CPU->timeoutlock, false);
+			
+			handler(arg);
+			
+			irq_spinlock_lock(&CPU->timeoutlock, false);
 		}
-		spinlock_unlock(&CPU->timeoutlock);
+		
+		irq_spinlock_unlock(&CPU->timeoutlock, false);
 	}
 	CPU->missed_clock_ticks = 0;
-
+	
 	/*
 	 * Do CPU usage accounting and find out whether to preempt THREAD.
+	 *
 	 */
-
+	
 	if (THREAD) {
 		uint64_t ticks;
 		
-		spinlock_lock(&CPU->lock);
+		irq_spinlock_lock(&CPU->lock, false);
 		CPU->needs_relink += 1 + missed_clock_ticks;
-		spinlock_unlock(&CPU->lock);	
-	
-		spinlock_lock(&THREAD->lock);
+		irq_spinlock_unlock(&CPU->lock, false);
+		
+		irq_spinlock_lock(&THREAD->lock, false);
 		if ((ticks = THREAD->ticks)) {
 			if (ticks >= 1 + missed_clock_ticks)
@@ -193,10 +208,7 @@
 				THREAD->ticks = 0;
 		}
-		spinlock_unlock(&THREAD->lock);
+		irq_spinlock_unlock(&THREAD->lock, false);
 		
 		if ((!ticks) && (!PREEMPTION_DISABLED)) {
-#ifdef CONFIG_UDEBUG
-			istate_t *istate;
-#endif
 			scheduler();
 #ifdef CONFIG_UDEBUG
@@ -205,11 +217,10 @@
 			 * before it begins executing userspace code.
 			 */
-			istate = THREAD->udebug.uspace_state;
-			if (istate && istate_from_uspace(istate))
+			istate_t *istate = THREAD->udebug.uspace_state;
+			if ((istate) && (istate_from_uspace(istate)))
 				udebug_before_thread_runs();
 #endif
 		}
 	}
-
 }
 
Index: kernel/generic/src/time/timeout.c
===================================================================
--- kernel/generic/src/time/timeout.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/generic/src/time/timeout.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -33,5 +33,5 @@
 /**
  * @file
- * @brief		Timeout management functions.
+ * @brief Timeout management functions.
  */
 
@@ -53,25 +53,23 @@
 void timeout_init(void)
 {
-	spinlock_initialize(&CPU->timeoutlock, "timeout_lock");
+	irq_spinlock_initialize(&CPU->timeoutlock, "cpu.timeoutlock");
 	list_initialize(&CPU->timeout_active_head);
 }
 
-
-/** Reinitialize timeout 
+/** Reinitialize timeout
  *
  * Initialize all members except the lock.
  *
- * @param t		Timeout to be initialized.
- *
- */
-void timeout_reinitialize(timeout_t *t)
-{
-	t->cpu = NULL;
-	t->ticks = 0;
-	t->handler = NULL;
-	t->arg = NULL;
-	link_initialize(&t->link);
-}
-
+ * @param timeout Timeout to be initialized.
+ *
+ */
+void timeout_reinitialize(timeout_t *timeout)
+{
+	timeout->cpu = NULL;
+	timeout->ticks = 0;
+	timeout->handler = NULL;
+	timeout->arg = NULL;
+	link_initialize(&timeout->link);
+}
 
 /** Initialize timeout
@@ -79,13 +77,12 @@
  * Initialize all members including the lock.
  *
- * @param t		Timeout to be initialized.
- *
- */
-void timeout_initialize(timeout_t *t)
-{
-	spinlock_initialize(&t->lock, "timeout_t_lock");
-	timeout_reinitialize(t);
-}
-
+ * @param timeout Timeout to be initialized.
+ *
+ */
+void timeout_initialize(timeout_t *timeout)
+{
+	irq_spinlock_initialize(&timeout->lock, "timeout_t_lock");
+	timeout_reinitialize(timeout);
+}
 
 /** Register timeout
@@ -95,70 +92,67 @@
  * time microseconds (or slightly more).
  *
- * @param t		Timeout structure.
- * @param time		Number of usec in the future to execute the handler.
- * @param f		Timeout handler function.
- * @param arg		Timeout handler argument.
- *
- */
-void
-timeout_register(timeout_t *t, uint64_t time, timeout_handler_t f, void *arg)
-{
-	timeout_t *hlp = NULL;
-	link_t *l, *m;
-	ipl_t ipl;
-	uint64_t sum;
-
-	ipl = interrupts_disable();
-	spinlock_lock(&CPU->timeoutlock);
-	spinlock_lock(&t->lock);
-
-	if (t->cpu)
-		panic("Unexpected: t->cpu != 0.");
-
-	t->cpu = CPU;
-	t->ticks = us2ticks(time);
-	
-	t->handler = f;
-	t->arg = arg;
-
-	/*
-	 * Insert t into the active timeouts list according to t->ticks.
-	 */
-	sum = 0;
-	l = CPU->timeout_active_head.next;
-	while (l != &CPU->timeout_active_head) {
-		hlp = list_get_instance(l, timeout_t, link);
-		spinlock_lock(&hlp->lock);
-		if (t->ticks < sum + hlp->ticks) {
-			spinlock_unlock(&hlp->lock);
+ * @param timeout Timeout structure.
+ * @param time    Number of usec in the future to execute the handler.
+ * @param handler Timeout handler function.
+ * @param arg     Timeout handler argument.
+ *
+ */
+void timeout_register(timeout_t *timeout, uint64_t time,
+    timeout_handler_t handler, void *arg)
+{
+	irq_spinlock_lock(&CPU->timeoutlock, true);
+	irq_spinlock_lock(&timeout->lock, false);
+	
+	if (timeout->cpu)
+		panic("Unexpected: timeout->cpu != 0.");
+	
+	timeout->cpu = CPU;
+	timeout->ticks = us2ticks(time);
+	
+	timeout->handler = handler;
+	timeout->arg = arg;
+	
+	/*
+	 * Insert timeout into the active timeouts list according to timeout->ticks.
+	 */
+	uint64_t sum = 0;
+	timeout_t *target = NULL;
+	link_t *cur;
+	for (cur = CPU->timeout_active_head.next;
+	    cur != &CPU->timeout_active_head; cur = cur->next) {
+		target = list_get_instance(cur, timeout_t, link);
+		irq_spinlock_lock(&target->lock, false);
+		
+		if (timeout->ticks < sum + target->ticks) {
+			irq_spinlock_unlock(&target->lock, false);
 			break;
 		}
-		sum += hlp->ticks;
-		spinlock_unlock(&hlp->lock);
-		l = l->next;
-	}
-
-	m = l->prev;
-	list_prepend(&t->link, m); /* avoid using l->prev */
-
-	/*
-	 * Adjust t->ticks according to ticks accumulated in h's predecessors.
-	 */
-	t->ticks -= sum;
-
-	/*
-	 * Decrease ticks of t's immediate succesor by t->ticks.
-	 */
-	if (l != &CPU->timeout_active_head) {
-		spinlock_lock(&hlp->lock);
-		hlp->ticks -= t->ticks;
-		spinlock_unlock(&hlp->lock);
-	}
-
-	spinlock_unlock(&t->lock);
-	spinlock_unlock(&CPU->timeoutlock);
-	interrupts_restore(ipl);
-}
-
+		
+		sum += target->ticks;
+		irq_spinlock_unlock(&target->lock, false);
+	}
+	
+	/* Avoid using cur->prev directly */
+	link_t *prev = cur->prev;
+	list_prepend(&timeout->link, prev);
+	
+	/*
+	 * Adjust timeout->ticks according to ticks
+	 * accumulated in target's predecessors.
+	 */
+	timeout->ticks -= sum;
+	
+	/*
+	 * Decrease ticks of timeout's immediate succesor by timeout->ticks.
+	 */
+	if (cur != &CPU->timeout_active_head) {
+		irq_spinlock_lock(&target->lock, false);
+		target->ticks -= timeout->ticks;
+		irq_spinlock_unlock(&target->lock, false);
+	}
+	
+	irq_spinlock_unlock(&timeout->lock, false);
+	irq_spinlock_unlock(&CPU->timeoutlock, true);
+}
 
 /** Unregister timeout
@@ -166,26 +160,22 @@
  * Remove timeout from timeout list.
  *
- * @param t		Timeout to unregister.
- *
- * @return		True on success, false on failure.
- */
-bool timeout_unregister(timeout_t *t)
-{
-	timeout_t *hlp;
-	link_t *l;
-	ipl_t ipl;
+ * @param timeout Timeout to unregister.
+ *
+ * @return True on success, false on failure.
+ *
+ */
+bool timeout_unregister(timeout_t *timeout)
+{
 	DEADLOCK_PROBE_INIT(p_tolock);
-
+	
 grab_locks:
-	ipl = interrupts_disable();
-	spinlock_lock(&t->lock);
-	if (!t->cpu) {
-		spinlock_unlock(&t->lock);
-		interrupts_restore(ipl);
+	irq_spinlock_lock(&timeout->lock, true);
+	if (!timeout->cpu) {
+		irq_spinlock_unlock(&timeout->lock, true);
 		return false;
 	}
-	if (!spinlock_trylock(&t->cpu->timeoutlock)) {
-		spinlock_unlock(&t->lock);
-		interrupts_restore(ipl);
+	
+	if (!irq_spinlock_trylock(&timeout->cpu->timeoutlock)) {
+		irq_spinlock_unlock(&timeout->lock, true);
 		DEADLOCK_PROBE(p_tolock, DEADLOCK_THRESHOLD);
 		goto grab_locks;
@@ -193,23 +183,22 @@
 	
 	/*
-	 * Now we know for sure that t hasn't been activated yet
-	 * and is lurking in t->cpu->timeout_active_head queue.
-	 */
-
-	l = t->link.next;
-	if (l != &t->cpu->timeout_active_head) {
-		hlp = list_get_instance(l, timeout_t, link);
-		spinlock_lock(&hlp->lock);
-		hlp->ticks += t->ticks;
-		spinlock_unlock(&hlp->lock);
-	}
-	
-	list_remove(&t->link);
-	spinlock_unlock(&t->cpu->timeoutlock);
-
-	timeout_reinitialize(t);
-	spinlock_unlock(&t->lock);
-
-	interrupts_restore(ipl);
+	 * Now we know for sure that timeout hasn't been activated yet
+	 * and is lurking in timeout->cpu->timeout_active_head queue.
+	 */
+	
+	link_t *cur = timeout->link.next;
+	if (cur != &timeout->cpu->timeout_active_head) {
+		timeout_t *tmp = list_get_instance(cur, timeout_t, link);
+		irq_spinlock_lock(&tmp->lock, false);
+		tmp->ticks += timeout->ticks;
+		irq_spinlock_unlock(&tmp->lock, false);
+	}
+	
+	list_remove(&timeout->link);
+	irq_spinlock_unlock(&timeout->cpu->timeoutlock, false);
+	
+	timeout_reinitialize(timeout);
+	irq_spinlock_unlock(&timeout->lock, true);
+	
 	return true;
 }
Index: kernel/generic/src/udebug/udebug.c
===================================================================
--- kernel/generic/src/udebug/udebug.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/generic/src/udebug/udebug.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -33,9 +33,9 @@
 /**
  * @file
- * @brief	Udebug hooks and data structure management.
+ * @brief Udebug hooks and data structure management.
  *
  * Udebug is an interface that makes userspace debuggers possible.
  */
- 
+
 #include <synch/waitq.h>
 #include <debug.h>
@@ -45,9 +45,9 @@
 #include <arch.h>
 
-
 /** Initialize udebug part of task structure.
  *
  * Called as part of task structure initialization.
- * @param ut	Pointer to the structure to initialize.
+ * @param ut Pointer to the structure to initialize.
+ *
  */
 void udebug_task_init(udebug_task_t *ut)
@@ -63,5 +63,7 @@
  *
  * Called as part of thread structure initialization.
- * @param ut	Pointer to the structure to initialize.
+ *
+ * @param ut Pointer to the structure to initialize.
+ *
  */
 void udebug_thread_initialize(udebug_thread_t *ut)
@@ -70,5 +72,5 @@
 	waitq_initialize(&ut->go_wq);
 	condvar_initialize(&ut->active_cv);
-
+	
 	ut->go_call = NULL;
 	ut->uspace_state = NULL;
@@ -76,5 +78,5 @@
 	ut->stoppable = true;
 	ut->active = false;
-	ut->cur_event = 0; /* none */
+	ut->cur_event = 0;  /* None */
 }
 
@@ -85,16 +87,14 @@
  * is received.
  *
- * @param wq	The wait queue used by the thread to wait for GO messages.
+ * @param wq The wait queue used by the thread to wait for GO messages.
+ *
  */
 static void udebug_wait_for_go(waitq_t *wq)
 {
-	int rc;
-	ipl_t ipl;
-
-	ipl = waitq_sleep_prepare(wq);
-
-	wq->missed_wakeups = 0;	/* Enforce blocking. */
-	rc = waitq_sleep_timeout_unsafe(wq, SYNCH_NO_TIMEOUT, SYNCH_FLAGS_NONE);
-
+	ipl_t ipl = waitq_sleep_prepare(wq);
+	
+	wq->missed_wakeups = 0;  /* Enforce blocking. */
+	int rc = waitq_sleep_timeout_unsafe(wq, SYNCH_NO_TIMEOUT, SYNCH_FLAGS_NONE);
+	
 	waitq_sleep_finish(wq, rc, ipl);
 }
@@ -102,69 +102,68 @@
 /** Start of stoppable section.
  *
- * A stoppable section is a section of code where if the thread can be stoped. In other words,
- * if a STOP operation is issued, the thread is guaranteed not to execute
- * any userspace instructions until the thread is resumed.
+ * A stoppable section is a section of code where if the thread can
+ * be stoped. In other words, if a STOP operation is issued, the thread
+ * is guaranteed not to execute any userspace instructions until the
+ * thread is resumed.
  *
  * Having stoppable sections is better than having stopping points, since
  * a thread can be stopped even when it is blocked indefinitely in a system
  * call (whereas it would not reach any stopping point).
+ *
  */
 void udebug_stoppable_begin(void)
 {
-	int nsc;
-	call_t *db_call, *go_call;
-
 	ASSERT(THREAD);
 	ASSERT(TASK);
-
+	
 	mutex_lock(&TASK->udebug.lock);
-
-	nsc = --TASK->udebug.not_stoppable_count;
-
+	
+	int nsc = --TASK->udebug.not_stoppable_count;
+	
 	/* Lock order OK, THREAD->udebug.lock is after TASK->udebug.lock */
 	mutex_lock(&THREAD->udebug.lock);
 	ASSERT(THREAD->udebug.stoppable == false);
 	THREAD->udebug.stoppable = true;
-
-	if (TASK->udebug.dt_state == UDEBUG_TS_BEGINNING && nsc == 0) {
+	
+	if ((TASK->udebug.dt_state == UDEBUG_TS_BEGINNING) && (nsc == 0)) {
 		/*
 		 * This was the last non-stoppable thread. Reply to
 		 * DEBUG_BEGIN call.
+		 *
 		 */
-
-		db_call = TASK->udebug.begin_call;
+		
+		call_t *db_call = TASK->udebug.begin_call;
 		ASSERT(db_call);
-
+		
 		TASK->udebug.dt_state = UDEBUG_TS_ACTIVE;
 		TASK->udebug.begin_call = NULL;
-
+		
 		IPC_SET_RETVAL(db_call->data, 0);
-		ipc_answer(&TASK->answerbox, db_call);		
-
+		ipc_answer(&TASK->answerbox, db_call);
 	} else if (TASK->udebug.dt_state == UDEBUG_TS_ACTIVE) {
 		/*
 		 * Active debugging session
 		 */
-
+		
 		if (THREAD->udebug.active == true &&
 		    THREAD->udebug.go == false) {
 			/*
 			 * Thread was requested to stop - answer go call
+			 *
 			 */
-
+			
 			/* Make sure nobody takes this call away from us */
-			go_call = THREAD->udebug.go_call;
+			call_t *go_call = THREAD->udebug.go_call;
 			THREAD->udebug.go_call = NULL;
 			ASSERT(go_call);
-
+			
 			IPC_SET_RETVAL(go_call->data, 0);
 			IPC_SET_ARG1(go_call->data, UDEBUG_EVENT_STOP);
-
+			
 			THREAD->udebug.cur_event = UDEBUG_EVENT_STOP;
-
-	    		ipc_answer(&TASK->answerbox, go_call);
+			ipc_answer(&TASK->answerbox, go_call);
 		}
 	}
-
+	
 	mutex_unlock(&THREAD->udebug.lock);
         mutex_unlock(&TASK->udebug.lock);
@@ -174,5 +173,7 @@
  *
  * This is the point where the thread will block if it is stopped.
- * (As, by definition, a stopped thread must not leave its stoppable section).
+ * (As, by definition, a stopped thread must not leave its stoppable
+ * section).
+ *
  */
 void udebug_stoppable_end(void)
@@ -181,11 +182,11 @@
 	mutex_lock(&TASK->udebug.lock);
 	mutex_lock(&THREAD->udebug.lock);
-
-	if (THREAD->udebug.active && THREAD->udebug.go == false) {
+	
+	if ((THREAD->udebug.active) && (THREAD->udebug.go == false)) {
 		mutex_unlock(&THREAD->udebug.lock);
 		mutex_unlock(&TASK->udebug.lock);
-
+		
 		udebug_wait_for_go(&THREAD->udebug.go_wq);
-
+		
 		goto restart;
 		/* Must try again - have to lose stoppability atomically. */
@@ -194,5 +195,5 @@
 		ASSERT(THREAD->udebug.stoppable == true);
 		THREAD->udebug.stoppable = false;
-
+		
 		mutex_unlock(&THREAD->udebug.lock);
 		mutex_unlock(&TASK->udebug.lock);
@@ -203,4 +204,5 @@
  *
  * This function is called from clock().
+ *
  */
 void udebug_before_thread_runs(void)
@@ -215,4 +217,5 @@
  * Must be called before and after servicing a system call. This generates
  * a SYSCALL_B or SYSCALL_E event, depending on the value of @a end_variant.
+ *
  */
 void udebug_syscall_event(unative_t a1, unative_t a2, unative_t a3,
@@ -220,12 +223,10 @@
     bool end_variant)
 {
-	call_t *call;
-	udebug_event_t etype;
-
-	etype = end_variant ? UDEBUG_EVENT_SYSCALL_E : UDEBUG_EVENT_SYSCALL_B;
-
+	udebug_event_t etype =
+	    end_variant ? UDEBUG_EVENT_SYSCALL_E : UDEBUG_EVENT_SYSCALL_B;
+	
 	mutex_lock(&TASK->udebug.lock);
 	mutex_lock(&THREAD->udebug.lock);
-
+	
 	/* Must only generate events when in debugging session and is go. */
 	if (THREAD->udebug.active != true || THREAD->udebug.go == false ||
@@ -235,14 +236,14 @@
 		return;
 	}
-
+	
 	/* Fill in the GO response. */
-	call = THREAD->udebug.go_call;
+	call_t *call = THREAD->udebug.go_call;
 	THREAD->udebug.go_call = NULL;
-
+	
 	IPC_SET_RETVAL(call->data, 0);
 	IPC_SET_ARG1(call->data, etype);
 	IPC_SET_ARG2(call->data, id);
 	IPC_SET_ARG3(call->data, rc);
-
+	
 	THREAD->udebug.syscall_args[0] = a1;
 	THREAD->udebug.syscall_args[1] = a2;
@@ -251,18 +252,19 @@
 	THREAD->udebug.syscall_args[4] = a5;
 	THREAD->udebug.syscall_args[5] = a6;
-
+	
 	/*
 	 * Make sure udebug.go is false when going to sleep
 	 * in case we get woken up by DEBUG_END. (At which
 	 * point it must be back to the initial true value).
+	 *
 	 */
 	THREAD->udebug.go = false;
 	THREAD->udebug.cur_event = etype;
-
+	
 	ipc_answer(&TASK->answerbox, call);
-
+	
 	mutex_unlock(&THREAD->udebug.lock);
 	mutex_unlock(&TASK->udebug.lock);
-
+	
 	udebug_wait_for_go(&THREAD->udebug.go_wq);
 }
@@ -280,49 +282,52 @@
  * and get a THREAD_B event for them.
  *
- * @param t	Structure of the thread being created. Not locked, as the
- *		thread is not executing yet.
- * @param ta	Task to which the thread should be attached.
- */
-void udebug_thread_b_event_attach(struct thread *t, struct task *ta)
-{
-	call_t *call;
-
+ * @param thread Structure of the thread being created. Not locked, as the
+ *               thread is not executing yet.
+ * @param task   Task to which the thread should be attached.
+ *
+ */
+void udebug_thread_b_event_attach(struct thread *thread, struct task *task)
+{
 	mutex_lock(&TASK->udebug.lock);
 	mutex_lock(&THREAD->udebug.lock);
-
-	thread_attach(t, ta);
-
+	
+	thread_attach(thread, task);
+	
 	LOG("Check state");
-
+	
 	/* Must only generate events when in debugging session */
 	if (THREAD->udebug.active != true) {
 		LOG("udebug.active: %s, udebug.go: %s",
-			THREAD->udebug.active ? "Yes(+)" : "No",
-			THREAD->udebug.go ? "Yes(-)" : "No");
+		    THREAD->udebug.active ? "Yes(+)" : "No",
+		    THREAD->udebug.go ? "Yes(-)" : "No");
+		
 		mutex_unlock(&THREAD->udebug.lock);
 		mutex_unlock(&TASK->udebug.lock);
 		return;
 	}
-
+	
 	LOG("Trigger event");
-	call = THREAD->udebug.go_call;
+	
+	call_t *call = THREAD->udebug.go_call;
+	
 	THREAD->udebug.go_call = NULL;
 	IPC_SET_RETVAL(call->data, 0);
 	IPC_SET_ARG1(call->data, UDEBUG_EVENT_THREAD_B);
-	IPC_SET_ARG2(call->data, (unative_t)t);
-
+	IPC_SET_ARG2(call->data, (unative_t) thread);
+	
 	/*
 	 * Make sure udebug.go is false when going to sleep
 	 * in case we get woken up by DEBUG_END. (At which
 	 * point it must be back to the initial true value).
+	 *
 	 */
 	THREAD->udebug.go = false;
 	THREAD->udebug.cur_event = UDEBUG_EVENT_THREAD_B;
-
+	
 	ipc_answer(&TASK->answerbox, call);
-
+	
 	mutex_unlock(&THREAD->udebug.lock);
 	mutex_unlock(&TASK->udebug.lock);
-
+	
 	LOG("Wait for Go");
 	udebug_wait_for_go(&THREAD->udebug.go_wq);
@@ -333,128 +338,127 @@
  * Must be called when the current thread is terminating.
  * Generates a THREAD_E event.
+ *
  */
 void udebug_thread_e_event(void)
 {
-	call_t *call;
-
 	mutex_lock(&TASK->udebug.lock);
 	mutex_lock(&THREAD->udebug.lock);
-
+	
 	LOG("Check state");
-
+	
 	/* Must only generate events when in debugging session. */
 	if (THREAD->udebug.active != true) {
 		LOG("udebug.active: %s, udebug.go: %s",
-			THREAD->udebug.active ? "Yes" : "No",
-			THREAD->udebug.go ? "Yes" : "No");
+		    THREAD->udebug.active ? "Yes" : "No",
+		    THREAD->udebug.go ? "Yes" : "No");
+		
 		mutex_unlock(&THREAD->udebug.lock);
 		mutex_unlock(&TASK->udebug.lock);
 		return;
 	}
-
+	
 	LOG("Trigger event");
-	call = THREAD->udebug.go_call;
+	
+	call_t *call = THREAD->udebug.go_call;
+	
 	THREAD->udebug.go_call = NULL;
 	IPC_SET_RETVAL(call->data, 0);
 	IPC_SET_ARG1(call->data, UDEBUG_EVENT_THREAD_E);
-
+	
 	/* Prevent any further debug activity in thread. */
 	THREAD->udebug.active = false;
-	THREAD->udebug.cur_event = 0;		/* none */
-	THREAD->udebug.go = false;	/* set to initial value */
-
+	THREAD->udebug.cur_event = 0;   /* None */
+	THREAD->udebug.go = false;      /* Set to initial value */
+	
 	ipc_answer(&TASK->answerbox, call);
-
+	
 	mutex_unlock(&THREAD->udebug.lock);
 	mutex_unlock(&TASK->udebug.lock);
-
-	/* 
+	
+	/*
 	 * This event does not sleep - debugging has finished
 	 * in this thread.
+	 *
 	 */
 }
 
-/**
- * Terminate task debugging session.
- *
- * Gracefully terminates the debugging session for a task. If the debugger
+/** Terminate task debugging session.
+ *
+ * Gracefully terminate the debugging session for a task. If the debugger
  * is still waiting for events on some threads, it will receive a
  * FINISHED event for each of them.
  *
- * @param ta	Task structure. ta->udebug.lock must be already locked.
- * @return	Zero on success or negative error code.
- */
-int udebug_task_cleanup(struct task *ta)
-{
-	thread_t *t;
+ * @param task Task structure. task->udebug.lock must be already locked.
+ *
+ * @return Zero on success or negative error code.
+ *
+ */
+int udebug_task_cleanup(struct task *task)
+{
+	ASSERT(mutex_locked(&task->udebug.lock));
+
+	if ((task->udebug.dt_state != UDEBUG_TS_BEGINNING) &&
+	    (task->udebug.dt_state != UDEBUG_TS_ACTIVE)) {
+		return EINVAL;
+	}
+	
+	LOG("Task %" PRIu64, task->taskid);
+	
+	/* Finish debugging of all userspace threads */
 	link_t *cur;
-	int flags;
-	ipl_t ipl;
-
-	if (ta->udebug.dt_state != UDEBUG_TS_BEGINNING &&
-	    ta->udebug.dt_state != UDEBUG_TS_ACTIVE) {
-		return EINVAL;
-	}
-
-	LOG("Task %" PRIu64, ta->taskid);
-
-	/* Finish debugging of all userspace threads */
-	for (cur = ta->th_head.next; cur != &ta->th_head; cur = cur->next) {
-		t = list_get_instance(cur, thread_t, th_link);
-
-		mutex_lock(&t->udebug.lock);
-
-		ipl = interrupts_disable();
-		spinlock_lock(&t->lock);
-
-		flags = t->flags;
-
-		spinlock_unlock(&t->lock);
-		interrupts_restore(ipl);
-
+	for (cur = task->th_head.next; cur != &task->th_head; cur = cur->next) {
+		thread_t *thread = list_get_instance(cur, thread_t, th_link);
+		
+		mutex_lock(&thread->udebug.lock);
+		unsigned int flags = thread->flags;
+		
 		/* Only process userspace threads. */
 		if ((flags & THREAD_FLAG_USPACE) != 0) {
 			/* Prevent any further debug activity in thread. */
-			t->udebug.active = false;
-			t->udebug.cur_event = 0;	/* none */
-
+			thread->udebug.active = false;
+			thread->udebug.cur_event = 0;   /* None */
+			
 			/* Is the thread still go? */
-			if (t->udebug.go == true) {
+			if (thread->udebug.go == true) {
 				/*
-				* Yes, so clear go. As active == false,
+				 * Yes, so clear go. As active == false,
 				 * this doesn't affect anything.
+				 (
 				 */
-				t->udebug.go = false;	
-
+				thread->udebug.go = false;
+				
 				/* Answer GO call */
 				LOG("Answer GO call with EVENT_FINISHED.");
-				IPC_SET_RETVAL(t->udebug.go_call->data, 0);
-				IPC_SET_ARG1(t->udebug.go_call->data,
+				
+				IPC_SET_RETVAL(thread->udebug.go_call->data, 0);
+				IPC_SET_ARG1(thread->udebug.go_call->data,
 				    UDEBUG_EVENT_FINISHED);
-
-				ipc_answer(&ta->answerbox, t->udebug.go_call);
-				t->udebug.go_call = NULL;
+				
+				ipc_answer(&task->answerbox, thread->udebug.go_call);
+				thread->udebug.go_call = NULL;
 			} else {
 				/*
 				 * Debug_stop is already at initial value.
 				 * Yet this means the thread needs waking up.
+				 *
 				 */
-
+				
 				/*
-				 * t's lock must not be held when calling
+				 * thread's lock must not be held when calling
 				 * waitq_wakeup.
+				 *
 				 */
-				waitq_wakeup(&t->udebug.go_wq, WAKEUP_FIRST);
+				waitq_wakeup(&thread->udebug.go_wq, WAKEUP_FIRST);
 			}
-			mutex_unlock(&t->udebug.lock);
-			condvar_broadcast(&t->udebug.active_cv);
-		} else {
-			mutex_unlock(&t->udebug.lock);
-		}
-	}
-
-	ta->udebug.dt_state = UDEBUG_TS_INACTIVE;
-	ta->udebug.debugger = NULL;
-
+			
+			mutex_unlock(&thread->udebug.lock);
+			condvar_broadcast(&thread->udebug.active_cv);
+		} else
+			mutex_unlock(&thread->udebug.lock);
+	}
+	
+	task->udebug.dt_state = UDEBUG_TS_INACTIVE;
+	task->udebug.debugger = NULL;
+	
 	return 0;
 }
@@ -466,9 +470,10 @@
  * a chance to examine the faulting thead/task. When the debugging session
  * is over, this function returns (so that thread/task cleanup can continue).
+ *
  */
 void udebug_thread_fault(void)
 {
 	udebug_stoppable_begin();
-
+	
 	/* Wait until a debugger attends to us. */
 	mutex_lock(&THREAD->udebug.lock);
@@ -476,5 +481,5 @@
 		condvar_wait(&THREAD->udebug.active_cv, &THREAD->udebug.lock);
 	mutex_unlock(&THREAD->udebug.lock);
-
+	
 	/* Make sure the debugging session is over before proceeding. */
 	mutex_lock(&THREAD->udebug.lock);
@@ -482,5 +487,5 @@
 		condvar_wait(&THREAD->udebug.active_cv, &THREAD->udebug.lock);
 	mutex_unlock(&THREAD->udebug.lock);
-
+	
 	udebug_stoppable_end();
 }
Index: kernel/generic/src/udebug/udebug_ops.c
===================================================================
--- kernel/generic/src/udebug/udebug_ops.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/generic/src/udebug/udebug_ops.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -33,5 +33,5 @@
 /**
  * @file
- * @brief	Udebug operations.
+ * @brief Udebug operations.
  *
  * Udebug operations on tasks and threads are implemented here. The
@@ -39,5 +39,5 @@
  * when servicing udebug IPC messages.
  */
- 
+
 #include <debug.h>
 #include <proc/task.h>
@@ -53,6 +53,5 @@
 #include <memstr.h>
 
-/**
- * Prepare a thread for a debugging operation.
+/** Prepare a thread for a debugging operation.
  *
  * Simply put, return thread t with t->udebug.lock held,
@@ -73,89 +72,84 @@
  * the t->lock spinlock to the t->udebug.lock mutex.
  *
- * @param t		Pointer, need not at all be valid.
- * @param being_go	Required thread state.
+ * @param thread   Pointer, need not at all be valid.
+ * @param being_go Required thread state.
  *
  * Returns EOK if all went well, or an error code otherwise.
- */
-static int _thread_op_begin(thread_t *t, bool being_go)
-{
-	ipl_t ipl;
-
-	mutex_lock(&TASK->udebug.lock);
-
+ *
+ */
+static int _thread_op_begin(thread_t *thread, bool being_go)
+{
+	mutex_lock(&TASK->udebug.lock);
+	
 	/* thread_exists() must be called with threads_lock held */
-	ipl = interrupts_disable();
-	spinlock_lock(&threads_lock);
-
-	if (!thread_exists(t)) {
-		spinlock_unlock(&threads_lock);
-		interrupts_restore(ipl);
+	irq_spinlock_lock(&threads_lock, true);
+	
+	if (!thread_exists(thread)) {
+		irq_spinlock_unlock(&threads_lock, true);
 		mutex_unlock(&TASK->udebug.lock);
 		return ENOENT;
 	}
-
-	/* t->lock is enough to ensure the thread's existence */
-	spinlock_lock(&t->lock);
-	spinlock_unlock(&threads_lock);
-
-	/* Verify that 't' is a userspace thread. */
-	if ((t->flags & THREAD_FLAG_USPACE) == 0) {
+	
+	/* thread->lock is enough to ensure the thread's existence */
+	irq_spinlock_exchange(&threads_lock, &thread->lock);
+	
+	/* Verify that 'thread' is a userspace thread. */
+	if ((thread->flags & THREAD_FLAG_USPACE) == 0) {
 		/* It's not, deny its existence */
-		spinlock_unlock(&t->lock);
-		interrupts_restore(ipl);
+		irq_spinlock_unlock(&thread->lock, true);
 		mutex_unlock(&TASK->udebug.lock);
 		return ENOENT;
 	}
-
+	
 	/* Verify debugging state. */
-	if (t->udebug.active != true) {
+	if (thread->udebug.active != true) {
 		/* Not in debugging session or undesired GO state */
-		spinlock_unlock(&t->lock);
-		interrupts_restore(ipl);
+		irq_spinlock_unlock(&thread->lock, true);
 		mutex_unlock(&TASK->udebug.lock);
 		return ENOENT;
 	}
-
+	
 	/*
 	 * Since the thread has active == true, TASK->udebug.lock
 	 * is enough to ensure its existence and that active remains
 	 * true.
+	 *
 	 */
-	spinlock_unlock(&t->lock);
-	interrupts_restore(ipl);
-
+	irq_spinlock_unlock(&thread->lock, true);
+	
 	/* Only mutex TASK->udebug.lock left. */
 	
 	/* Now verify that the thread belongs to the current task. */
-	if (t->task != TASK) {
+	if (thread->task != TASK) {
 		/* No such thread belonging this task*/
 		mutex_unlock(&TASK->udebug.lock);
 		return ENOENT;
 	}
-
+	
 	/*
 	 * Now we need to grab the thread's debug lock for synchronization
 	 * of the threads stoppability/stop state.
+	 *
 	 */
-	mutex_lock(&t->udebug.lock);
-
+	mutex_lock(&thread->udebug.lock);
+	
 	/* The big task mutex is no longer needed. */
 	mutex_unlock(&TASK->udebug.lock);
-
-	if (t->udebug.go != being_go) {
+	
+	if (thread->udebug.go != being_go) {
 		/* Not in debugging session or undesired GO state. */
-		mutex_unlock(&t->udebug.lock);
+		mutex_unlock(&thread->udebug.lock);
 		return EINVAL;
 	}
-
-	/* Only t->udebug.lock left. */
-
-	return EOK;	/* All went well. */
+	
+	/* Only thread->udebug.lock left. */
+	
+	return EOK;  /* All went well. */
 }
 
 /** End debugging operation on a thread. */
-static void _thread_op_end(thread_t *t)
-{
-	mutex_unlock(&t->udebug.lock);
+static void _thread_op_end(thread_t *thread)
+{
+	mutex_unlock(&thread->udebug.lock);
 }
 
@@ -171,49 +165,48 @@
  * all the threads become stoppable (i.e. they can be considered stopped).
  *
- * @param call	The BEGIN call we are servicing.
- * @return 	0 (OK, but not done yet), 1 (done) or negative error code.
+ * @param call The BEGIN call we are servicing.
+ *
+ * @return 0 (OK, but not done yet), 1 (done) or negative error code.
+ *
  */
 int udebug_begin(call_t *call)
 {
-	int reply;
-
-	thread_t *t;
-	link_t *cur;
-
-	LOG("Debugging task %llu", TASK->taskid);
-	mutex_lock(&TASK->udebug.lock);
-
+	LOG("Debugging task %" PRIu64, TASK->taskid);
+	
+	mutex_lock(&TASK->udebug.lock);
+	
 	if (TASK->udebug.dt_state != UDEBUG_TS_INACTIVE) {
 		mutex_unlock(&TASK->udebug.lock);
 		return EBUSY;
 	}
-
+	
 	TASK->udebug.dt_state = UDEBUG_TS_BEGINNING;
 	TASK->udebug.begin_call = call;
 	TASK->udebug.debugger = call->sender;
-
+	
+	int reply;
+	
 	if (TASK->udebug.not_stoppable_count == 0) {
 		TASK->udebug.dt_state = UDEBUG_TS_ACTIVE;
 		TASK->udebug.begin_call = NULL;
-		reply = 1; /* immediate reply */
-	} else {
-		reply = 0; /* no reply */
-	}
+		reply = 1;  /* immediate reply */
+	} else
+		reply = 0;  /* no reply */
 	
 	/* Set udebug.active on all of the task's userspace threads. */
-
+	
+	link_t *cur;
 	for (cur = TASK->th_head.next; cur != &TASK->th_head; cur = cur->next) {
-		t = list_get_instance(cur, thread_t, th_link);
-
-		mutex_lock(&t->udebug.lock);
-		if ((t->flags & THREAD_FLAG_USPACE) != 0) {
-			t->udebug.active = true;
-			mutex_unlock(&t->udebug.lock);
-			condvar_broadcast(&t->udebug.active_cv);
-		} else {
-			mutex_unlock(&t->udebug.lock);
-		}
-	}
-
+		thread_t *thread = list_get_instance(cur, thread_t, th_link);
+		
+		mutex_lock(&thread->udebug.lock);
+		if ((thread->flags & THREAD_FLAG_USPACE) != 0) {
+			thread->udebug.active = true;
+			mutex_unlock(&thread->udebug.lock);
+			condvar_broadcast(&thread->udebug.active_cv);
+		} else
+			mutex_unlock(&thread->udebug.lock);
+	}
+	
 	mutex_unlock(&TASK->udebug.lock);
 	return reply;
@@ -223,16 +216,16 @@
  *
  * Closes the debugging session for the current task.
+ *
  * @return Zero on success or negative error code.
+ *
  */
 int udebug_end(void)
 {
-	int rc;
-
 	LOG("Task %" PRIu64, TASK->taskid);
-
-	mutex_lock(&TASK->udebug.lock);
-	rc = udebug_task_cleanup(TASK);
-	mutex_unlock(&TASK->udebug.lock);
-
+	
+	mutex_lock(&TASK->udebug.lock);
+	int rc = udebug_task_cleanup(TASK);
+	mutex_unlock(&TASK->udebug.lock);
+	
 	return rc;
 }
@@ -242,21 +235,23 @@
  * Sets the event mask that determines which events are enabled.
  *
- * @param mask	Or combination of events that should be enabled.
- * @return	Zero on success or negative error code.
+ * @param mask Or combination of events that should be enabled.
+ *
+ * @return Zero on success or negative error code.
+ *
  */
 int udebug_set_evmask(udebug_evmask_t mask)
 {
 	LOG("mask = 0x%x", mask);
-
-	mutex_lock(&TASK->udebug.lock);
-
+	
+	mutex_lock(&TASK->udebug.lock);
+	
 	if (TASK->udebug.dt_state != UDEBUG_TS_ACTIVE) {
 		mutex_unlock(&TASK->udebug.lock);
 		return EINVAL;
 	}
-
+	
 	TASK->udebug.evmask = mask;
 	mutex_unlock(&TASK->udebug.lock);
-
+	
 	return 0;
 }
@@ -268,28 +263,27 @@
  * a debugging event or STOP occurs, at which point the thread loses GO.
  *
- * @param t	The thread to operate on (unlocked and need not be valid).
- * @param call	The GO call that we are servicing.
- */
-int udebug_go(thread_t *t, call_t *call)
-{
-	int rc;
-
-	/* On success, this will lock t->udebug.lock. */
-	rc = _thread_op_begin(t, false);
-	if (rc != EOK) {
+ * @param thread The thread to operate on (unlocked and need not be valid).
+ * @param call   The GO call that we are servicing.
+ *
+ */
+int udebug_go(thread_t *thread, call_t *call)
+{
+	/* On success, this will lock thread->udebug.lock. */
+	int rc = _thread_op_begin(thread, false);
+	if (rc != EOK)
 		return rc;
-	}
-
-	t->udebug.go_call = call;
-	t->udebug.go = true;
-	t->udebug.cur_event = 0;	/* none */
-
+	
+	thread->udebug.go_call = call;
+	thread->udebug.go = true;
+	thread->udebug.cur_event = 0;  /* none */
+	
 	/*
-	 * Neither t's lock nor threads_lock may be held during wakeup.
+	 * Neither thread's lock nor threads_lock may be held during wakeup.
+	 *
 	 */
-	waitq_wakeup(&t->udebug.go_wq, WAKEUP_FIRST);
-
-	_thread_op_end(t);
-
+	waitq_wakeup(&thread->udebug.go_wq, WAKEUP_FIRST);
+	
+	_thread_op_end(thread);
+	
 	return 0;
 }
@@ -300,50 +294,50 @@
  * can be considered stopped).
  *
- * @param t	The thread to operate on (unlocked and need not be valid).
- * @param call	The GO call that we are servicing.
- */
-int udebug_stop(thread_t *t, call_t *call)
-{
-	int rc;
-
+ * @param thread The thread to operate on (unlocked and need not be valid).
+ * @param call   The GO call that we are servicing.
+ *
+ */
+int udebug_stop(thread_t *thread, call_t *call)
+{
 	LOG("udebug_stop()");
-
+	
 	/*
-	 * On success, this will lock t->udebug.lock. Note that this makes sure
-	 * the thread is not stopped.
+	 * On success, this will lock thread->udebug.lock. Note that this
+	 * makes sure the thread is not stopped.
+	 *
 	 */
-	rc = _thread_op_begin(t, true);
-	if (rc != EOK) {
+	int rc = _thread_op_begin(thread, true);
+	if (rc != EOK)
 		return rc;
-	}
-
+	
 	/* Take GO away from the thread. */
-	t->udebug.go = false;
-
-	if (t->udebug.stoppable != true) {
+	thread->udebug.go = false;
+	
+	if (thread->udebug.stoppable != true) {
 		/* Answer will be sent when the thread becomes stoppable. */
-		_thread_op_end(t);
+		_thread_op_end(thread);
 		return 0;
 	}
-
+	
 	/*
 	 * Answer GO call.
+	 *
 	 */
-
+	
 	/* Make sure nobody takes this call away from us. */
-	call = t->udebug.go_call;
-	t->udebug.go_call = NULL;
-
+	call = thread->udebug.go_call;
+	thread->udebug.go_call = NULL;
+	
 	IPC_SET_RETVAL(call->data, 0);
 	IPC_SET_ARG1(call->data, UDEBUG_EVENT_STOP);
-
+	
 	THREAD->udebug.cur_event = UDEBUG_EVENT_STOP;
-
-	_thread_op_end(t);
-
+	
+	_thread_op_end(thread);
+	
 	mutex_lock(&TASK->udebug.lock);
 	ipc_answer(&TASK->answerbox, call);
 	mutex_unlock(&TASK->udebug.lock);
-
+	
 	return 0;
 }
@@ -365,29 +359,20 @@
  * a maximum size for the userspace buffer.
  *
- * @param buffer	The buffer for storing thread hashes.
- * @param buf_size	Buffer size in bytes.
- * @param stored	The actual number of bytes copied will be stored here.
- * @param needed	Total number of hashes that could have been saved.
+ * @param buffer   The buffer for storing thread hashes.
+ * @param buf_size Buffer size in bytes.
+ * @param stored   The actual number of bytes copied will be stored here.
+ * @param needed   Total number of hashes that could have been saved.
+ *
  */
 int udebug_thread_read(void **buffer, size_t buf_size, size_t *stored,
     size_t *needed)
 {
-	thread_t *t;
-	link_t *cur;
-	unative_t tid;
-	size_t copied_ids;
-	size_t extra_ids;
-	ipl_t ipl;
-	unative_t *id_buffer;
-	int flags;
-	size_t max_ids;
-
 	LOG("udebug_thread_read()");
-
+	
 	/* Allocate a buffer to hold thread IDs */
-	id_buffer = malloc(buf_size + 1, 0);
-
-	mutex_lock(&TASK->udebug.lock);
-
+	unative_t *id_buffer = malloc(buf_size + 1, 0);
+	
+	mutex_lock(&TASK->udebug.lock);
+	
 	/* Verify task state */
 	if (TASK->udebug.dt_state != UDEBUG_TS_ACTIVE) {
@@ -395,43 +380,41 @@
 		return EINVAL;
 	}
-
-	ipl = interrupts_disable();
-	spinlock_lock(&TASK->lock);
+	
+	irq_spinlock_lock(&TASK->lock, true);
+	
 	/* Copy down the thread IDs */
-
-	max_ids = buf_size / sizeof(unative_t);
-	copied_ids = 0;
-	extra_ids = 0;
-
+	
+	size_t max_ids = buf_size / sizeof(unative_t);
+	size_t copied_ids = 0;
+	size_t extra_ids = 0;
+	
 	/* FIXME: make sure the thread isn't past debug shutdown... */
+	link_t *cur;
 	for (cur = TASK->th_head.next; cur != &TASK->th_head; cur = cur->next) {
-		t = list_get_instance(cur, thread_t, th_link);
-
-		spinlock_lock(&t->lock);
-		flags = t->flags;
-		spinlock_unlock(&t->lock);
-
+		thread_t *thread = list_get_instance(cur, thread_t, th_link);
+		
+		irq_spinlock_lock(&thread->lock, false);
+		int flags = thread->flags;
+		irq_spinlock_unlock(&thread->lock, false);
+		
 		/* Not interested in kernel threads. */
 		if ((flags & THREAD_FLAG_USPACE) == 0)
 			continue;
-
+		
 		if (copied_ids < max_ids) {
 			/* Using thread struct pointer as identification hash */
-			tid = (unative_t) t;
-			id_buffer[copied_ids++] = tid;
-		} else {
+			id_buffer[copied_ids++] = (unative_t) thread;
+		} else
 			extra_ids++;
-		}
-	}
-
-	spinlock_unlock(&TASK->lock);
-	interrupts_restore(ipl);
-
-	mutex_unlock(&TASK->udebug.lock);
-
+	}
+	
+	irq_spinlock_unlock(&TASK->lock, true);
+	
+	mutex_unlock(&TASK->udebug.lock);
+	
 	*buffer = id_buffer;
 	*stored = copied_ids * sizeof(unative_t);
 	*needed = (copied_ids + extra_ids) * sizeof(unative_t);
-
+	
 	return 0;
 }
@@ -442,19 +425,19 @@
  * Also returns the size of the data.
  *
- * @param data		Place to store pointer to newly allocated block.
- * @param data_size	Place to store size of the data.
- *
- * @returns		EOK.
+ * @param data      Place to store pointer to newly allocated block.
+ * @param data_size Place to store size of the data.
+ *
+ * @returns EOK.
+ *
  */
 int udebug_name_read(char **data, size_t *data_size)
 {
-	size_t name_size;
-
-	name_size = str_size(TASK->name) + 1;
+	size_t name_size = str_size(TASK->name) + 1;
+	
 	*data = malloc(name_size, 0);
 	*data_size = name_size;
-
+	
 	memcpy(*data, TASK->name, name_size);
-
+	
 	return 0;
 }
@@ -470,35 +453,33 @@
  * this function will fail with an EINVAL error code.
  *
- * @param t		Thread where call arguments are to be read.
- * @param buffer	Place to store pointer to new buffer.
- * @return		EOK on success, ENOENT if @a t is invalid, EINVAL
- *			if thread state is not valid for this operation.
- */
-int udebug_args_read(thread_t *t, void **buffer)
-{
-	int rc;
-	unative_t *arg_buffer;
-
+ * @param thread Thread where call arguments are to be read.
+ * @param buffer Place to store pointer to new buffer.
+ *
+ * @return EOK on success, ENOENT if @a t is invalid, EINVAL
+ *         if thread state is not valid for this operation.
+ *
+ */
+int udebug_args_read(thread_t *thread, void **buffer)
+{
 	/* Prepare a buffer to hold the arguments. */
-	arg_buffer = malloc(6 * sizeof(unative_t), 0);
-
+	unative_t *arg_buffer = malloc(6 * sizeof(unative_t), 0);
+	
 	/* On success, this will lock t->udebug.lock. */
-	rc = _thread_op_begin(t, false);
-	if (rc != EOK) {
+	int rc = _thread_op_begin(thread, false);
+	if (rc != EOK)
 		return rc;
-	}
-
+	
 	/* Additionally we need to verify that we are inside a syscall. */
-	if (t->udebug.cur_event != UDEBUG_EVENT_SYSCALL_B &&
-	    t->udebug.cur_event != UDEBUG_EVENT_SYSCALL_E) {
-		_thread_op_end(t);
+	if ((thread->udebug.cur_event != UDEBUG_EVENT_SYSCALL_B) &&
+	    (thread->udebug.cur_event != UDEBUG_EVENT_SYSCALL_E)) {
+		_thread_op_end(thread);
 		return EINVAL;
 	}
-
+	
 	/* Copy to a local buffer before releasing the lock. */
-	memcpy(arg_buffer, t->udebug.syscall_args, 6 * sizeof(unative_t));
-
-	_thread_op_end(t);
-
+	memcpy(arg_buffer, thread->udebug.syscall_args, 6 * sizeof(unative_t));
+	
+	_thread_op_end(thread);
+	
 	*buffer = arg_buffer;
 	return 0;
@@ -514,35 +495,33 @@
  * call (as opposed to an exception). This is an implementation limit.
  *
- * @param t		Thread whose state is to be read.
- * @param buffer	Place to store pointer to new buffer.
- * @return		EOK on success, ENOENT if @a t is invalid, EINVAL
- *			if thread is not in valid state, EBUSY if istate
- *			is not available.
- */
-int udebug_regs_read(thread_t *t, void **buffer)
-{
-	istate_t *state, *state_buf;
-	int rc;
-
+ * @param thread Thread whose state is to be read.
+ * @param buffer Place to store pointer to new buffer.
+ *
+ * @return EOK on success, ENOENT if @a t is invalid, EINVAL
+ *         if thread is not in valid state, EBUSY if istate
+ *         is not available.
+ *
+ */
+int udebug_regs_read(thread_t *thread, void **buffer)
+{
 	/* Prepare a buffer to hold the data. */
-	state_buf = malloc(sizeof(istate_t), 0);
-
+	istate_t *state_buf = malloc(sizeof(istate_t), 0);
+	
 	/* On success, this will lock t->udebug.lock */
-	rc = _thread_op_begin(t, false);
-	if (rc != EOK) {
+	int rc = _thread_op_begin(thread, false);
+	if (rc != EOK)
 		return rc;
-	}
-
-	state = t->udebug.uspace_state;
+	
+	istate_t *state = thread->udebug.uspace_state;
 	if (state == NULL) {
-		_thread_op_end(t);
+		_thread_op_end(thread);
 		return EBUSY;
 	}
-
+	
 	/* Copy to the allocated buffer */
 	memcpy(state_buf, state, sizeof(istate_t));
-
-	_thread_op_end(t);
-
+	
+	_thread_op_end(thread);
+	
 	*buffer = (void *) state_buf;
 	return 0;
@@ -555,30 +534,32 @@
  * and a pointer to it is written into @a buffer.
  *
- * @param uspace_addr	Address from where to start reading.
- * @param n		Number of bytes to read.
- * @param buffer	For storing a pointer to the allocated buffer.
+ * @param uspace_addr Address from where to start reading.
+ * @param n           Number of bytes to read.
+ * @param buffer      For storing a pointer to the allocated buffer.
+ *
  */
 int udebug_mem_read(unative_t uspace_addr, size_t n, void **buffer)
 {
-	void *data_buffer;
-	int rc;
-
 	/* Verify task state */
 	mutex_lock(&TASK->udebug.lock);
-
+	
 	if (TASK->udebug.dt_state != UDEBUG_TS_ACTIVE) {
 		mutex_unlock(&TASK->udebug.lock);
 		return EBUSY;
 	}
-
-	data_buffer = malloc(n, 0);
-
-	/* NOTE: this is not strictly from a syscall... but that shouldn't
-	 * be a problem */
-	rc = copy_from_uspace(data_buffer, (void *)uspace_addr, n);
-	mutex_unlock(&TASK->udebug.lock);
-
-	if (rc != 0) return rc;
-
+	
+	void *data_buffer = malloc(n, 0);
+	
+	/*
+	 * NOTE: this is not strictly from a syscall... but that shouldn't
+	 * be a problem
+	 *
+	 */
+	int rc = copy_from_uspace(data_buffer, (void *) uspace_addr, n);
+	mutex_unlock(&TASK->udebug.lock);
+	
+	if (rc != 0)
+		return rc;
+	
 	*buffer = data_buffer;
 	return 0;
Index: rnel/test/synch/rwlock1.c
===================================================================
--- kernel/test/synch/rwlock1.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ 	(revision )
@@ -1,75 +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.
- */
-
-#include <test.h>
-#include <arch.h>
-#include <atomic.h>
-#include <print.h>
-#include <proc/thread.h>
-
-#include <synch/waitq.h>
-#include <synch/rwlock.h>
-
-#define READERS  50
-#define WRITERS  50
-
-static rwlock_t rwlock;
-
-const char *test_rwlock1(void)
-{
-	rwlock_initialize(&rwlock);
-	
-	rwlock_write_lock(&rwlock);
-	rwlock_write_unlock(&rwlock);
-	
-	rwlock_read_lock(&rwlock);
-	rwlock_read_lock(&rwlock);
-	rwlock_read_lock(&rwlock);
-	rwlock_read_lock(&rwlock);
-	rwlock_read_lock(&rwlock);
-	
-	rwlock_read_unlock(&rwlock);
-	rwlock_read_unlock(&rwlock);
-	rwlock_read_unlock(&rwlock);
-	rwlock_read_unlock(&rwlock);
-	rwlock_read_unlock(&rwlock);
-	
-	rwlock_write_lock(&rwlock);
-	rwlock_write_unlock(&rwlock);
-	
-	rwlock_read_lock(&rwlock);
-	rwlock_read_unlock(&rwlock);
-	
-	rwlock_write_lock(&rwlock);
-	rwlock_write_unlock(&rwlock);
-	
-	rwlock_read_lock(&rwlock);
-	rwlock_read_unlock(&rwlock);
-	
-	return NULL;
-}
Index: rnel/test/synch/rwlock1.def
===================================================================
--- kernel/test/synch/rwlock1.def	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ 	(revision )
@@ -1,6 +1,0 @@
-{
-	"rwlock1",
-	"RW-lock test 1",
-	&test_rwlock1,
-	true
-},
Index: rnel/test/synch/rwlock2.c
===================================================================
--- kernel/test/synch/rwlock2.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ 	(revision )
@@ -1,83 +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.
- */
-
-#include <test.h>
-#include <arch.h>
-#include <atomic.h>
-#include <print.h>
-#include <proc/thread.h>
-
-#include <synch/rwlock.h>
-
-#define READERS  50
-#define WRITERS  50
-
-static rwlock_t rwlock;
-
-static void writer(void *arg)
-{
-	TPRINTF("Trying to lock rwlock for writing....\n");
-	
-	rwlock_write_lock(&rwlock);
-	rwlock_write_unlock(&rwlock);
-	
-	TPRINTF("Trying to lock rwlock for reading....\n");
-	
-	rwlock_read_lock(&rwlock);
-	rwlock_read_unlock(&rwlock);
-}
-
-const char *test_rwlock2(void)
-{
-	thread_t *thrd;
-	
-	rwlock_initialize(&rwlock);
-	
-	rwlock_read_lock(&rwlock);
-	rwlock_read_lock(&rwlock);
-	rwlock_read_lock(&rwlock);
-	rwlock_read_lock(&rwlock);
-	
-	thrd = thread_create(writer, NULL, TASK, 0, "writer", false);
-	if (thrd)
-		thread_ready(thrd);
-	else
-		return "Could not create thread";
-	
-	thread_sleep(1);
-	
-	rwlock_read_unlock(&rwlock);
-	rwlock_read_unlock(&rwlock);
-	rwlock_read_unlock(&rwlock);
-	rwlock_read_unlock(&rwlock);
-	
-	thread_join(thrd);
-	thread_detach(thrd);
-	
-	return NULL;
-}
Index: rnel/test/synch/rwlock2.def
===================================================================
--- kernel/test/synch/rwlock2.def	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ 	(revision )
@@ -1,6 +1,0 @@
-{
-	"rwlock2",
-	"RW-lock test 2",
-	&test_rwlock2,
-	true
-},
Index: rnel/test/synch/rwlock3.c
===================================================================
--- kernel/test/synch/rwlock3.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ 	(revision )
@@ -1,89 +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.
- */
-
-#include <test.h>
-#include <arch.h>
-#include <atomic.h>
-#include <print.h>
-#include <proc/thread.h>
-
-#include <synch/rwlock.h>
-
-#define THREADS  4
-
-static atomic_t thread_count;
-static rwlock_t rwlock;
-
-static void reader(void *arg)
-{
-	thread_detach(THREAD);
-	
-	TPRINTF("cpu%u, tid %" PRIu64 ": trying to lock rwlock for reading....\n", CPU->id, THREAD->tid);
-	
-	rwlock_read_lock(&rwlock);
-	rwlock_read_unlock(&rwlock);
-	
-	TPRINTF("cpu%u, tid %" PRIu64 ": success\n", CPU->id, THREAD->tid);
-	TPRINTF("cpu%u, tid %" PRIu64 ": trying to lock rwlock for writing....\n", CPU->id, THREAD->tid);
-	
-	rwlock_write_lock(&rwlock);
-	rwlock_write_unlock(&rwlock);
-	
-	TPRINTF("cpu%u, tid %" PRIu64 ": success\n", CPU->id, THREAD->tid);
-	
-	atomic_dec(&thread_count);
-}
-
-const char *test_rwlock3(void)
-{
-	int i;
-	thread_t *thrd;
-	
-	atomic_set(&thread_count, THREADS);
-	
-	rwlock_initialize(&rwlock);
-	rwlock_write_lock(&rwlock);
-	
-	for (i = 0; i < THREADS; i++) {
-		thrd = thread_create(reader, NULL, TASK, 0, "reader", false);
-		if (thrd)
-			thread_ready(thrd);
-		else
-			TPRINTF("Could not create reader %d\n", i);
-	}
-	
-	thread_sleep(1);
-	rwlock_write_unlock(&rwlock);
-	
-	while (atomic_get(&thread_count) > 0) {
-		TPRINTF("Threads left: %ld\n", atomic_get(&thread_count));
-		thread_sleep(1);
-	}
-	
-	return NULL;
-}
Index: rnel/test/synch/rwlock3.def
===================================================================
--- kernel/test/synch/rwlock3.def	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ 	(revision )
@@ -1,6 +1,0 @@
-{
-	"rwlock3",
-	"RW-lock test 3",
-	&test_rwlock3,
-	true
-},
Index: rnel/test/synch/rwlock4.c
===================================================================
--- kernel/test/synch/rwlock4.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ 	(revision )
@@ -1,184 +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.
- */
-
-#include <test.h>
-#include <arch.h>
-#include <atomic.h>
-#include <print.h>
-#include <proc/thread.h>
-#include <typedefs.h>
-#include <arch/context.h>
-#include <context.h>
-
-#include <synch/waitq.h>
-#include <synch/rwlock.h>
-#include <synch/synch.h>
-#include <synch/spinlock.h>
-
-#define READERS  50
-#define WRITERS  50
-
-static atomic_t thread_count;
-static rwlock_t rwlock;
-static atomic_t threads_fault;
-
-SPINLOCK_INITIALIZE(rw_lock);
-
-static waitq_t can_start;
-
-static uint32_t seed = 0xdeadbeef;
-
-static uint32_t random(uint32_t max)
-{
-	uint32_t rc;
-	
-	spinlock_lock(&rw_lock);
-	rc = seed % max;
-	seed = (((seed << 2) ^ (seed >> 2)) * 487) + rc;
-	spinlock_unlock(&rw_lock);
-	return rc;
-}
-
-static void writer(void *arg)
-{
-	int rc, to;
-	thread_detach(THREAD);
-	waitq_sleep(&can_start);
-	
-	to = random(40000);
-	
-	TPRINTF("cpu%u, tid %" PRIu64 " w+ (%d)\n", CPU->id, THREAD->tid, to);
-	
-	rc = rwlock_write_lock_timeout(&rwlock, to);
-	if (SYNCH_FAILED(rc)) {
-		TPRINTF("cpu%u, tid %" PRIu64 " w!\n", CPU->id, THREAD->tid);
-		atomic_dec(&thread_count);
-		return;
-	}
-	
-	TPRINTF("cpu%u, tid %" PRIu64 " w=\n", CPU->id, THREAD->tid);
-	
-	if (rwlock.readers_in) {
-		TPRINTF("Oops.\n");
-		atomic_inc(&threads_fault);
-		atomic_dec(&thread_count);
-		return;
-	}
-	
-	thread_usleep(random(1000000));
-	
-	if (rwlock.readers_in) {
-		TPRINTF("Oops.\n");
-		atomic_inc(&threads_fault);
-		atomic_dec(&thread_count);
-		return;
-	}
-	
-	rwlock_write_unlock(&rwlock);
-	
-	TPRINTF("cpu%u, tid %" PRIu64 " w-\n", CPU->id, THREAD->tid);
-	atomic_dec(&thread_count);
-}
-
-static void reader(void *arg)
-{
-	int rc, to;
-	thread_detach(THREAD);
-	waitq_sleep(&can_start);
-	
-	to = random(2000);
-	
-	TPRINTF("cpu%u, tid %" PRIu64 " r+ (%d)\n", CPU->id, THREAD->tid, to);
-	
-	rc = rwlock_read_lock_timeout(&rwlock, to);
-	if (SYNCH_FAILED(rc)) {
-		TPRINTF("cpu%u, tid %" PRIu64 " r!\n", CPU->id, THREAD->tid);
-		atomic_dec(&thread_count);
-		return;
-	}
-	
-	TPRINTF("cpu%u, tid %" PRIu64 " r=\n", CPU->id, THREAD->tid);
-	
-	thread_usleep(30000);
-	rwlock_read_unlock(&rwlock);
-	
-	TPRINTF("cpu%u, tid %" PRIu64 " r-\n", CPU->id, THREAD->tid);
-	atomic_dec(&thread_count);
-}
-
-const char *test_rwlock4(void)
-{
-	context_t ctx;
-	uint32_t i;
-	
-	waitq_initialize(&can_start);
-	rwlock_initialize(&rwlock);
-	atomic_set(&threads_fault, 0);
-	
-	uint32_t rd = random(7) + 1;
-	uint32_t wr = random(5) + 1;
-	
-	atomic_set(&thread_count, rd + wr);
-	
-	thread_t *thrd;
-	
-	context_save(&ctx);
-	TPRINTF("sp=%#x, readers_in=%" PRIs "\n", ctx.sp, rwlock.readers_in);
-	TPRINTF("Creating %" PRIu32 " readers\n", rd);
-	
-	for (i = 0; i < rd; i++) {
-		thrd = thread_create(reader, NULL, TASK, 0, "reader", false);
-		if (thrd)
-			thread_ready(thrd);
-		else
-			TPRINTF("Could not create reader %" PRIu32 "\n", i);
-	}
-	
-	TPRINTF("Creating %" PRIu32 " writers\n", wr);
-	
-	for (i = 0; i < wr; i++) {
-		thrd = thread_create(writer, NULL, TASK, 0, "writer", false);
-		if (thrd)
-			thread_ready(thrd);
-		else
-			TPRINTF("Could not create writer %" PRIu32 "\n", i);
-	}
-	
-	thread_usleep(20000);
-	waitq_wakeup(&can_start, WAKEUP_ALL);
-	
-	while (atomic_get(&thread_count) > 0) {
-		TPRINTF("Threads left: %ld\n", atomic_get(&thread_count));
-		thread_sleep(1);
-	}
-	
-	if (atomic_get(&threads_fault) == 0)
-		return NULL;
-	
-	return "Test failed";
-}
Index: rnel/test/synch/rwlock4.def
===================================================================
--- kernel/test/synch/rwlock4.def	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ 	(revision )
@@ -1,6 +1,0 @@
-{
-	"rwlock4",
-	"RW-lock test 4",
-	&test_rwlock4,
-	true
-},
Index: rnel/test/synch/rwlock5.c
===================================================================
--- kernel/test/synch/rwlock5.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ 	(revision )
@@ -1,118 +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.
- */
-
-#include <test.h>
-#include <arch.h>
-#include <atomic.h>
-#include <print.h>
-#include <proc/thread.h>
-
-#include <synch/waitq.h>
-#include <synch/rwlock.h>
-
-#define READERS  50
-#define WRITERS  50
-
-static rwlock_t rwlock;
-
-static waitq_t can_start;
-static atomic_t items_read;
-static atomic_t items_written;
-
-static void writer(void *arg)
-{
-	thread_detach(THREAD);
-	
-	waitq_sleep(&can_start);
-	
-	rwlock_write_lock(&rwlock);
-	atomic_inc(&items_written);
-	rwlock_write_unlock(&rwlock);
-}
-
-static void reader(void *arg)
-{
-	thread_detach(THREAD);
-	
-	waitq_sleep(&can_start);
-	
-	rwlock_read_lock(&rwlock);
-	atomic_inc(&items_read);
-	rwlock_read_unlock(&rwlock);
-}
-
-const char *test_rwlock5(void)
-{
-	int i, j, k;
-	atomic_count_t readers;
-	atomic_count_t writers;
-	
-	waitq_initialize(&can_start);
-	rwlock_initialize(&rwlock);
-	
-	for (i = 1; i <= 3; i++) {
-		thread_t *thrd;
-		
-		atomic_set(&items_read, 0);
-		atomic_set(&items_written, 0);
-		
-		readers = i * READERS;
-		writers = (4 - i) * WRITERS;
-		
-		TPRINTF("Creating %ld readers and %ld writers...", readers, writers);
-		
-		for (j = 0; j < (READERS + WRITERS) / 2; j++) {
-			for (k = 0; k < i; k++) {
-				thrd = thread_create(reader, NULL, TASK, 0, "reader", false);
-				if (thrd)
-					thread_ready(thrd);
-				else
-					TPRINTF("Could not create reader %d\n", k);
-			}
-			for (k = 0; k < (4 - i); k++) {
-				thrd = thread_create(writer, NULL, TASK, 0, "writer", false);
-				if (thrd)
-					thread_ready(thrd);
-				else
-					TPRINTF("Could not create writer %d\n", k);
-			}
-		}
-		
-		TPRINTF("ok\n");
-		
-		thread_sleep(1);
-		waitq_wakeup(&can_start, WAKEUP_ALL);
-		
-		while ((items_read.count != readers) || (items_written.count != writers)) {
-			TPRINTF("%d readers remaining, %d writers remaining, readers_in=%d\n", readers - items_read.count, writers - items_written.count, rwlock.readers_in);
-			thread_usleep(100000);
-		}
-	}
-	
-	return NULL;
-}
Index: rnel/test/synch/rwlock5.def
===================================================================
--- kernel/test/synch/rwlock5.def	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ 	(revision )
@@ -1,6 +1,0 @@
-{
-	"rwlock5",
-	"RW-lock test 5",
-	&test_rwlock5,
-	true
-},
Index: kernel/test/test.c
===================================================================
--- kernel/test/test.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/test/test.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -51,9 +51,4 @@
 #include <mm/slab1.def>
 #include <mm/slab2.def>
-#include <synch/rwlock1.def>
-#include <synch/rwlock2.def>
-#include <synch/rwlock3.def>
-#include <synch/rwlock4.def>
-#include <synch/rwlock5.def>
 #include <synch/semaphore1.def>
 #include <synch/semaphore2.def>
Index: kernel/test/test.h
===================================================================
--- kernel/test/test.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ kernel/test/test.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -70,9 +70,4 @@
 extern const char *test_slab1(void);
 extern const char *test_slab2(void);
-extern const char *test_rwlock1(void);
-extern const char *test_rwlock2(void);
-extern const char *test_rwlock3(void);
-extern const char *test_rwlock4(void);
-extern const char *test_rwlock5(void);
 extern const char *test_semaphore1(void);
 extern const char *test_semaphore2(void);
Index: adme.txt
===================================================================
--- readme.txt	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ 	(revision )
@@ -1,1 +1,0 @@
-wiki url: http://lenkatrochtova.wz.cz/helenos-wiki/doku.php
Index: tools/autotool.py
===================================================================
--- tools/autotool.py	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ tools/autotool.py	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -54,14 +54,14 @@
 COMPILER_FAIL = "The compiler is probably not capable to compile HelenOS."
 
-PROBE_HEAD = """#define AUTOTOOL_DECLARE(category, subcategory, name, value) \\
+PROBE_HEAD = """#define AUTOTOOL_DECLARE(category, subcategory, tag, name, value) \\
 	asm volatile ( \\
-		"AUTOTOOL_DECLARE\\t" category "\\t" subcategory "\\t" name "\\t%[val]\\n" \\
+		"AUTOTOOL_DECLARE\\t" category "\\t" subcategory "\\t" tag "\\t" name "\\t%[val]\\n" \\
 		: \\
 		: [val] "n" (value) \\
 	)
 
-#define DECLARE_INTSIZE(type) \\
-	AUTOTOOL_DECLARE("intsize", "unsigned", #type, sizeof(unsigned type)); \\
-	AUTOTOOL_DECLARE("intsize", "signed", #type, sizeof(signed type))
+#define DECLARE_INTSIZE(tag, type) \\
+	AUTOTOOL_DECLARE("intsize", "unsigned", tag, #type, sizeof(unsigned type)); \\
+	AUTOTOOL_DECLARE("intsize", "signed", tag, #type, sizeof(signed type))
 
 int main(int argc, char *argv[])
@@ -195,5 +195,5 @@
 	
 	for typedef in sizes:
-		outf.write("\tDECLARE_INTSIZE(%s);\n" % typedef)
+		outf.write("\tDECLARE_INTSIZE(\"%s\", %s);\n" % (typedef['tag'], typedef['type']))
 	
 	outf.write(PROBE_TAIL)
@@ -228,4 +228,7 @@
 	signed_sizes = {}
 	
+	unsigned_tags = {}
+	signed_tags = {}
+	
 	for j in range(len(lines)):
 		tokens = lines[j].strip().split("\t")
@@ -238,6 +241,7 @@
 				category = tokens[1]
 				subcategory = tokens[2]
-				name = tokens[3]
-				value = tokens[4]
+				tag = tokens[3]
+				name = tokens[4]
+				value = tokens[5]
 				
 				if (category == "intsize"):
@@ -258,14 +262,17 @@
 					if (subcategory == "unsigned"):
 						unsigned_sizes[name] = value_int
+						unsigned_tags[tag] = value_int
 					elif (subcategory == "signed"):
 						signed_sizes[name] = value_int
+						signed_tags[tag] = value_int
 					else:
 						print_error(["Unexpected keyword \"%s\" in \"%s\" on line %s." % (subcategory, PROBE_OUTPUT, j), COMPILER_FAIL])
 	
-	return {'unsigned_sizes' : unsigned_sizes, 'signed_sizes' : signed_sizes}
-
-def detect_uints(unsigned_sizes, signed_sizes, bytes):
+	return {'unsigned_sizes' : unsigned_sizes, 'signed_sizes' : signed_sizes, 'unsigned_tags': unsigned_tags, 'signed_tags': signed_tags}
+
+def detect_uints(probe, bytes):
 	"Detect correct types for fixed-size integer types"
 	
+	macros = []
 	typedefs = []
 	
@@ -274,5 +281,5 @@
 		newtype = "uint%s_t" % (b * 8)
 		
-		for name, value in unsigned_sizes.items():
+		for name, value in probe['unsigned_sizes'].items():
 			if (value == b):
 				oldtype = "unsigned %s" % name
@@ -289,5 +296,5 @@
 		newtype = "int%s_t" % (b * 8)
 		
-		for name, value in signed_sizes.items():
+		for name, value in probe['signed_sizes'].items():
 			if (value == b):
 				oldtype = "signed %s" % name
@@ -300,5 +307,36 @@
 			             COMPILER_FAIL])
 	
-	return typedefs
+	for tag in ['CHAR', 'SHORT', 'INT', 'LONG', 'LLONG']:
+		fnd = False;
+		newmacro = "U%s" % tag
+		
+		for name, value in probe['unsigned_tags'].items():
+			if (name == tag):
+				oldmacro = "UINT%s" % (value * 8)
+				macros.append({'oldmacro': "%s_MIN" % oldmacro, 'newmacro': "%s_MIN" % newmacro})
+				macros.append({'oldmacro': "%s_MAX" % oldmacro, 'newmacro': "%s_MAX" % newmacro})
+				fnd = True
+				break
+		
+		if (not fnd):
+			print_error(['Unable to find appropriate size macro for %s' % newmacro,
+			             COMPILER_FAIL])
+		
+		fnd = False;
+		newmacro = tag
+		
+		for name, value in probe['signed_tags'].items():
+			if (name == tag):
+				oldmacro = "INT%s" % (value * 8)
+				macros.append({'oldmacro': "%s_MIN" % oldmacro, 'newmacro': "%s_MIN" % newmacro})
+				macros.append({'oldmacro': "%s_MAX" % oldmacro, 'newmacro': "%s_MAX" % newmacro})
+				fnd = True
+				break
+		
+		if (not fnd):
+			print_error(['Unable to find appropriate size macro for %s' % newmacro,
+			             COMPILER_FAIL])
+	
+	return {'macros': macros, 'typedefs': typedefs}
 
 def create_makefile(mkname, common):
@@ -316,5 +354,5 @@
 	outmk.close()
 
-def create_header(hdname, typedefs):
+def create_header(hdname, maps):
 	"Create header output"
 	
@@ -328,5 +366,10 @@
 	outhd.write('#define %s\n\n' % GUARD)
 	
-	for typedef in typedefs:
+	for macro in maps['macros']:
+		outhd.write('#define %s  %s\n' % (macro['newmacro'], macro['oldmacro']))
+	
+	outhd.write('\n')
+	
+	for typedef in maps['typedefs']:
 		outhd.write('typedef %s %s;\n' % (typedef['oldtype'], typedef['newtype']))
 	
@@ -465,13 +508,13 @@
 		probe = probe_compiler(common,
 			[
-				"char",
-				"short int",
-				"int",
-				"long int",
-				"long long int",
+				{'type': 'char', 'tag': 'CHAR'},
+				{'type': 'short int', 'tag': 'SHORT'},
+				{'type': 'int', 'tag': 'INT'},
+				{'type': 'long int', 'tag': 'LONG'},
+				{'type': 'long long int', 'tag': 'LLONG'}
 			]
 		)
 		
-		typedefs = detect_uints(probe['unsigned_sizes'], probe['signed_sizes'], [1, 2, 4, 8])
+		maps = detect_uints(probe, [1, 2, 4, 8])
 		
 	finally:
@@ -479,5 +522,5 @@
 	
 	create_makefile(MAKEFILE, common)
-	create_header(HEADER, typedefs)
+	create_header(HEADER, maps)
 	
 	return 0
Index: tools/checkers/howto.txt
===================================================================
--- tools/checkers/howto.txt	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
+++ tools/checkers/howto.txt	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -0,0 +1,28 @@
+Basic instructions
+------------------
+This is a very brief and preliminary description of the usage of source
+code checkers and verifiers located in this directory. It is not intended
+to be perfect since the formal verification is still work-in-progress, but
+it should at least give you some basic hints.
+
+If you want to try, say, the Clang static analyzer, follow the steps:
+
+1. Go to the root directory of HelenOS source tree.
+
+2. Run
+
+      make precheck
+
+   Configure the kernel according to your preferences. Remember that many
+   checkers have specific limitation on the target platform. They might
+   require the abstract platform abs32le or they might be suitable only
+   for platforms supported by some toolchain (e.g. ia32 and amd64 in the
+   case of Clang).
+
+3. As HelenOS compiles, Jobfiles (e.g. kernel/kernel.job) are created.
+
+4. Execute the checker while still in the source tree root directory. Do
+   not forget the argument "." which indicates the path to the source tree
+   root directory.
+
+      ./tools/checkers/clang.py .
Index: tools/checkers/vcc.h
===================================================================
--- tools/checkers/vcc.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
+++ tools/checkers/vcc.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2010 Martin Decky
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @file
+ *
+ * VCC specifications tight to the HelenOS-specific annotations.
+ *
+ */
+
+#ifndef HELENOS_VCC_H_
+#define HELENOS_VCC_H_
+
+typedef _Bool bool;
+
+#define __concat_identifiers_str(a, b)  a ## b
+#define __concat_identifiers(a, b)      __concat_identifiers_str(a, b)
+
+#define __specification_attr(key, value) \
+	__declspec(System.Diagnostics.Contracts.CodeContract.StringVccAttr, \
+	    key, value)
+
+#define __specification_type(name) \
+	__specification( \
+		typedef struct __concat_identifiers(_vcc_math_type_, name) { \
+			char _vcc_marker_for_math_type; \
+		} __concat_identifiers(\, name); \
+	)
+
+__specification(typedef void * \object;)
+__specification(typedef __int64 \integer;)
+__specification(typedef unsigned __int64 \size_t;)
+
+__specification_type(objset)
+
+__specification(struct \TypeState {
+	__specification(ghost \integer \claim_count;)
+	__specification(ghost bool \consistent;)
+	__specification(ghost \objset \owns;)
+	__specification(ghost \object \owner;)
+	__specification(ghost bool \valid;)
+};)
+
+__specification(bool \extent_mutable(\object);)
+__specification(\objset \extent(\object);)
+__specification(\objset \array_range(\object, \size_t);)
+__specification(bool \mutable_array(\object, \size_t);)
+
+#endif
+
+/** @}
+ */
Index: tools/checkers/vcc.py
===================================================================
--- tools/checkers/vcc.py	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ tools/checkers/vcc.py	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -36,13 +36,18 @@
 import subprocess
 import jobfile
+import re
 
 jobs = [
-	"kernel/kernel.job",
-	"uspace/srv/clip/clip.job"
+	"kernel/kernel.job"
 ]
+
+re_attribute = re.compile("__attribute__\s*\(\(.*\)\)")
+re_va_list = re.compile("__builtin_va_list")
+
+specification = ""
 
 def usage(prname):
 	"Print usage syntax"
-	print prname + " <ROOT>"
+	print prname + " <ROOT> [VCC_PATH]"
 
 def cygpath(upath):
@@ -54,7 +59,9 @@
 	"Preprocess source using GCC preprocessor and compatibility tweaks"
 	
+	global specification
+	
 	args = ['gcc', '-E']
 	args.extend(options.split())
-	args.append(srcfname)
+	args.extend(['-DCONFIG_VERIFY_VCC=1', srcfname])
 	
 	# Change working directory
@@ -66,10 +73,23 @@
 	
 	tmpf = file(tmpfname, "w")
+	tmpf.write(specification)
 	
 	for line in preproc.splitlines():
+		
 		# Ignore preprocessor directives
+		
 		if (line.startswith('#')):
 			continue
 		
+		# Remove __attribute__((.*)) GCC extension
+		
+		line = re.sub(re_attribute, "", line)
+		
+		# Ignore unsupported __builtin_va_list type
+		# (a better solution replacing __builrin_va_list with
+		# an emulated implementation is needed)
+		
+		line = re.sub(re_va_list, "void *", line)
+		
 		tmpf.write("%s\n" % line)
 	
@@ -80,5 +100,5 @@
 	return True
 
-def vcc(root, job):
+def vcc(vcc_path, root, job):
 	"Run Vcc on a jobfile"
 	
@@ -120,4 +140,7 @@
 		tmpfqname = os.path.join(base, tmpfname)
 		
+		vccfname = "%s.i" % srcfname
+		vccfqname = os.path.join(base, vccfname);
+		
 		# Only C files are interesting for us
 		if (tool != "cc"):
@@ -130,18 +153,22 @@
 		
 		# Run Vcc
-		
-		retval = subprocess.Popen(['vcc', cygpath(tmpfqname)]).wait()
-		
-		# Cleanup
+		print " -- %s --" % srcfname		
+		retval = subprocess.Popen([vcc_path, '/pointersize:32', '/newsyntax', cygpath(tmpfqname)]).wait()
+		
+		if (retval != 0):
+			return False
+		
+		# Cleanup, but only if verification was successful
+		# (to be able to examine the preprocessed file)
 		
 		if (os.path.isfile(tmpfqname)):
 			os.remove(tmpfqname)
-		
-		if (retval != 0):
-			return False
+			os.remove(vccfqname)
 	
 	return True
 
 def main():
+	global specification
+	
 	if (len(sys.argv) < 2):
 		usage(sys.argv[0])
@@ -149,4 +176,14 @@
 	
 	rootdir = os.path.abspath(sys.argv[1])
+	if (len(sys.argv) > 2):
+		vcc_path = sys.argv[2]
+	else:
+		vcc_path = "/cygdrive/c/Program Files (x86)/Microsoft Research/Vcc/Binaries/vcc"
+	
+	if (not os.path.isfile(vcc_path)):
+		print "%s is not a binary." % vcc_path
+		print "Please supply the full Cygwin path to Vcc as the second argument."
+		return
+	
 	config = os.path.join(rootdir, "HelenOS.config")
 	
@@ -156,6 +193,15 @@
 		return
 	
+	specpath = os.path.join(rootdir, "tools/checkers/vcc.h")
+	if (not os.path.isfile(specpath)):
+		print "%s not found." % config
+		return
+	
+	specfile = file(specpath, "r")
+	specification = specfile.read()
+	specfile.close()
+	
 	for job in jobs:
-		if (not vcc(rootdir, job)):
+		if (not vcc(vcc_path, rootdir, job)):
 			print
 			print "Failed job: %s" % job
Index: tools/mkfat.py
===================================================================
--- tools/mkfat.py	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ tools/mkfat.py	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -343,12 +343,18 @@
 def usage(prname):
 	"Print usage syntax"
-	print prname + " <PATH> <IMAGE>"
+	print prname + " <EXTRA_BYTES> <PATH> <IMAGE>"
 
 def main():
-	if (len(sys.argv) < 3):
+	if (len(sys.argv) < 4):
 		usage(sys.argv[0])
 		return
 	
-	path = os.path.abspath(sys.argv[1])
+	if (not sys.argv[1].isdigit()):
+		print "<EXTRA_BYTES> must be a number"
+		return
+	
+	extra_bytes = int(sys.argv[1])
+	
+	path = os.path.abspath(sys.argv[2])
 	if (not os.path.isdir(path)):
 		print "<PATH> must be a directory"
@@ -365,9 +371,9 @@
 	
 	# Make sure the filesystem is large enought for FAT16
-	size = subtree_size(path, cluster_size, dirent_size) + reserved_clusters * cluster_size
+	size = subtree_size(path, cluster_size, dirent_size) + reserved_clusters * cluster_size + extra_bytes
 	while (size / cluster_size < fat16_clusters):
 		if (cluster_size > sector_size):
 			cluster_size /= 2
-			size = subtree_size(path, cluster_size, dirent_size) + reserved_clusters * cluster_size
+			size = subtree_size(path, cluster_size, dirent_size) + reserved_clusters * cluster_size + extra_bytes
 		else:
 			size = fat16_clusters * cluster_size + reserved_clusters * cluster_size
@@ -381,5 +387,5 @@
 	data_start = root_start + root_size
 	
-	outf = file(sys.argv[2], "w")
+	outf = file(sys.argv[3], "w")
 	
 	boot_sector = xstruct.create(BOOT_SECTOR)
Index: tools/mkuimage.py
===================================================================
--- tools/mkuimage.py	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
+++ tools/mkuimage.py	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -0,0 +1,160 @@
+#!/usr/bin/env python
+#
+# 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.
+#
+
+"""
+Create legacy uImage (U-Boot image)
+"""
+
+from collections import deque
+import os
+import sys
+import xstruct
+import zlib
+
+UIMAGE_HEADER = """big:
+	uint32_t magic
+	uint32_t header_crc
+	uint32_t c_tstamp
+	uint32_t data_size
+	uint32_t load_addr
+	uint32_t start_addr
+	uint32_t data_crc
+	uint8_t os
+	uint8_t arch
+	uint8_t img_type
+	uint8_t compression
+	char img_name[32]
+"""
+
+def main():
+	args = deque(sys.argv)
+	cmd_name = args.popleft()
+	base_name = os.path.basename(cmd_name)
+	image_name = 'Noname'
+	load_addr = 0
+	start_addr = 0
+
+	while len(args) >= 2 and args[0][0] == '-':
+		opt = args.popleft()[1:]
+		optarg = args.popleft()
+
+		if opt == 'name':
+			image_name = optarg
+		elif opt == 'laddr':
+			load_addr = (int)(optarg, 0)
+		elif opt == 'saddr':
+			start_addr = (int)(optarg, 0)
+		else:
+			print base_name + ": Unrecognized option."
+			print_syntax(cmd_name)
+			return
+
+	if len(args) < 2:
+		print base_name + ": Argument missing."
+		print_syntax(cmd_name)
+		return
+
+	inf_name = args[0]
+	outf_name = args[1]
+
+	try:
+		mkuimage(inf_name, outf_name, image_name, load_addr, start_addr)
+	except:
+		os.remove(outf_name)
+		raise
+
+def mkuimage(inf_name, outf_name, image_name, load_addr, start_addr):
+	inf = file(inf_name, 'rb')
+	outf = file(outf_name, 'wb')
+
+	header = xstruct.create(UIMAGE_HEADER)
+	header_size = header.size()
+
+	#
+	# Write data
+	#
+	outf.seek(header_size, os.SEEK_SET)
+	data = inf.read()
+	data_size = inf.tell()
+	data_crc = calc_crc32(data)
+	data_tstamp = (int)(os.path.getmtime(inf_name))
+	outf.write(data)
+	data = ''
+
+	#
+	# Write header
+	#
+	outf.seek(0, os.SEEK_SET)
+
+	header.magic = 0x27051956	# uImage magic
+	header.header_crc = 0
+	header.c_tstamp = data_tstamp
+	header.data_size = data_size
+	header.load_addr = load_addr	# Address where to load image
+	header.start_addr = start_addr	# Address of entry point
+	header.data_crc = data_crc
+	header.os = 5			# Linux
+	header.arch = 2			# ARM
+	header.img_type = 2		# Kernel
+	header.compression = 0		# None
+	header.img_name = image_name
+
+	header_crc = calc_crc32(header.pack())
+	header.header_crc = header_crc
+
+	outf.write(header.pack())
+	outf.close()
+
+## Compute CRC32 of binary string.
+#
+# Works around bug in zlib.crc32() which returns signed int32 result
+# in Python < 3.0.
+#
+def calc_crc32(byteseq):
+	signed_crc = zlib.crc32(byteseq, 0)
+	if signed_crc < 0:
+		return (long(signed_crc) + 4294967296L) # 2^32L
+	else:
+		return signed_crc
+
+## Print command-line syntax.
+#
+def print_syntax(cmd):
+	print "syntax: " + cmd + " [<options>] <raw_image> <uImage>"
+	print
+	print "\traw_image\tInput image name (raw binary data)"
+	print "\tuImage\t\tOutput uImage name (U-Boot image)"
+	print
+	print "options:"
+	print "\t-name <name>\tImage name (default: 'Noname')"
+	print "\t-laddr <name>\tLoad address (default: 0x00000000)"
+	print "\t-saddr <name>\tStart address (default: 0x00000000)"
+
+if __name__ == '__main__':
+	main()
Index: tools/pack.py
===================================================================
--- tools/pack.py	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ tools/pack.py	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -191,5 +191,5 @@
 	link_in.close()
 	
-	link_out = file(os.path.join(arch_path, LINK), "w")
+	link_out = file(os.path.join(arch_path, "%s.comp" % LINK), "w")
 	link_out.write(template.replace("[[COMPONENTS]]", "\n".join(link_ctx)))
 	link_out.close()
Index: tools/toolchain.sh
===================================================================
--- tools/toolchain.sh	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ tools/toolchain.sh	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -1,3 +1,3 @@
-#!/bin/bash
+#! /bin/bash
 
 #
@@ -33,4 +33,5 @@
 		echo
 		echo "Script failed: $2"
+		
 		exit 1
 	fi
@@ -45,4 +46,5 @@
 		echo
 		echo "Checksum of ${FILE} does not match."
+		
 		exit 2
 	fi
@@ -71,4 +73,52 @@
 }
 
+change_title() {
+	echo -en "\e]0;$1\a"
+}
+
+show_countdown() {
+	TM="$1"
+	
+	if [ "${TM}" -eq 0 ] ; then
+		echo
+		return 0
+	fi
+	
+	echo -n "${TM} "
+	change_title "${TM}"
+	sleep 1
+	
+	TM="`expr "${TM}" - 1`"
+	show_countdown "${TM}"
+}
+
+show_dependencies() {
+	echo "IMPORTANT NOTICE:"
+	echo
+	echo "For a successful compilation and use of the cross-compiler"
+	echo "toolchain you need at least the following dependencies."
+	echo
+	echo "Please make sure that the dependencies are present in your"
+	echo "system. Otherwise the compilation process might fail after"
+	echo "a few seconds or minutes."
+	echo
+	echo " - SED, AWK, Flex, Bison, gzip, bzip2, Bourne Shell"
+	echo " - gettext, zlib, Texinfo, libelf, libgomp"
+	echo " - GNU Multiple Precision Library (GMP)"
+	echo " - GNU Make"
+	echo " - GNU tar"
+	echo " - GNU Coreutils"
+	echo " - GNU Sharutils"
+	echo " - MPFR"
+	echo " - MPC"
+	echo " - Parma Polyhedra Library (PPL)"
+	echo " - ClooG-PPL"
+	echo " - native C compiler, assembler and linker"
+	echo " - native C library with headers"
+	echo
+	
+	show_countdown 10
+}
+
 download_check() {
 	SOURCE="$1"
@@ -77,4 +127,5 @@
 	
 	if [ ! -f "${FILE}" ]; then
+		change_title "Downloading ${FILE}"
 		wget -c "${SOURCE}${FILE}"
 		check_error $? "Error downloading ${FILE}."
@@ -88,4 +139,5 @@
 	
 	if [ -d "${DIR}" ]; then
+		change_title "Removing ${DIR}"
 		echo " >>> Removing ${DIR}"
 		rm -fr "${DIR}"
@@ -97,4 +149,5 @@
 	DESC="$2"
 	
+	change_title "Creating ${DESC}"
 	echo ">>> Creating ${DESC}"
 	
@@ -108,5 +161,6 @@
 	DESC="$2"
 	
-	echo " >>> ${DESC}"
+	change_title "Unpacking ${DESC}"
+	echo " >>> Unpacking ${DESC}"
 	
 	tar -xjf "${FILE}"
@@ -142,5 +196,5 @@
 	
 	BINUTILS_VERSION="2.20"
-	GCC_VERSION="4.5.0"
+	GCC_VERSION="4.5.1"
 	
 	BINUTILS="binutils-${BINUTILS_VERSION}.tar.bz2"
@@ -165,7 +219,7 @@
 	echo ">>> Downloading tarballs"
 	download_check "${BINUTILS_SOURCE}" "${BINUTILS}" "ee2d3e996e9a2d669808713360fa96f8"
-	download_check "${GCC_SOURCE}" "${GCC_CORE}" "58eda33c3184303628f91c42a7ab15b5"
-	download_check "${GCC_SOURCE}" "${GCC_OBJC}" "8d8c01b6631b020cc6c167860fde2398"
-	download_check "${GCC_SOURCE}" "${GCC_CPP}" "5ab93605af40def4844eda09ca769c2d"
+	download_check "${GCC_SOURCE}" "${GCC_CORE}" "dc8959e31b01a65ce10d269614815054"
+	download_check "${GCC_SOURCE}" "${GCC_OBJC}" "3c11b7037896e967eddf8178af2ddd98"
+	download_check "${GCC_SOURCE}" "${GCC_CPP}" "b294953ff0bb2f20c7acb2bf005d832a"
 	
 	echo ">>> Removing previous content"
@@ -184,18 +238,26 @@
 	unpack_tarball "${GCC_CPP}" "C++"
 	
-	echo ">>> Compiling and installing binutils"
+	echo ">>> Processing binutils (${PLATFORM})"
 	cd "${BINUTILSDIR}"
 	check_error $? "Change directory failed."
 	patch_binutils "${PLATFORM}"
-	./configure "--target=${TARGET}" "--prefix=${PREFIX}" "--program-prefix=${TARGET}-" "--disable-nls"
+	
+	change_title "binutils: configure (${PLATFORM})"
+	./configure "--target=${TARGET}" "--prefix=${PREFIX}" "--program-prefix=${TARGET}-" --disable-nls
 	check_error $? "Error configuring binutils."
+	
+	change_title "binutils: make (${PLATFORM})"
 	make all install
 	check_error $? "Error compiling/installing binutils."
 	
-	echo ">>> Compiling and installing GCC"
+	echo ">>> Processing GCC (${PLATFORM})"
 	cd "${OBJDIR}"
 	check_error $? "Change directory failed."
+	
+	change_title "GCC: configure (${PLATFORM})"
 	"${GCCDIR}/configure" "--target=${TARGET}" "--prefix=${PREFIX}" "--program-prefix=${TARGET}-" --with-gnu-as --with-gnu-ld --disable-nls --disable-threads --enable-languages=c,objc,c++,obj-c++ --disable-multilib --disable-libgcj --without-headers --disable-shared --enable-lto
 	check_error $? "Error configuring GCC."
+	
+	change_title "GCC: make (${PLATFORM})"
 	PATH="${PATH}:${PREFIX}/bin" make all-gcc install-gcc
 	check_error $? "Error compiling/installing GCC."
@@ -216,4 +278,6 @@
 	show_usage
 fi
+
+show_dependencies
 
 case "$1" in
Index: uspace/Makefile
===================================================================
--- uspace/Makefile	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/Makefile	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -70,7 +70,9 @@
 	srv/hid/adb_mouse \
 	srv/hid/char_mouse \
+	srv/hid/s3c24xx_ts \
 	srv/hid/fb \
 	srv/hid/kbd \
 	srv/hw/char/i8042 \
+	srv/hw/char/s3c24xx_uart \
 	srv/hw/netif/dp8390 \
 	srv/net/cfg \
@@ -141,5 +143,5 @@
 	lib/softfloat \
 	lib/drv \
-	lib/socket \
+	lib/packet \
 	lib/net
 
Index: uspace/Makefile.common
===================================================================
--- uspace/Makefile.common	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/Makefile.common	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -89,6 +89,5 @@
 
 LIBDRV_PREFIX = $(LIB_PREFIX)/drv
-
-LIBSOCKET_PREFIX = $(LIB_PREFIX)/socket
+LIBPACKET_PREFIX = $(LIB_PREFIX)/packet
 LIBNET_PREFIX = $(LIB_PREFIX)/net
 
@@ -96,4 +95,10 @@
 
 LINKER_SCRIPT ?= $(LIBC_PREFIX)/arch/$(UARCH)/_link.ld
+
+ifeq ($(CONFIG_OPTIMIZE_FOR_SIZE),y)
+	OPTIMIZATION = s
+else
+	OPTIMIZATION = 3
+endif
 
 .PHONY: all clean
@@ -105,10 +110,4 @@
 	rm -f $(DEPEND) $(DEPEND_PREV) $(JOB) $(OUTPUT) $(EXTRA_OUTPUT) $(EXTRA_CLEAN)
 	find . -name '*.o' -follow -exec rm \{\} \;
-
-ifeq ($(CONFIG_OPTIMIZE_FOR_SIZE),y)
-OPTIMIZATION = s
-else
-OPTIMIZATION = 3
-endif
 
 GCC_CFLAGS = -I$(LIBC_PREFIX)/include -O$(OPTIMIZATION) -imacros $(CONFIG_HEADER) \
@@ -117,5 +116,5 @@
 	-Wall -Wextra -Wno-clobbered -Wno-unused-parameter -Wmissing-prototypes \
 	-Werror-implicit-function-declaration -Wwrite-strings \
-	-Werror -pipe -g -D__$(ENDIANESS)__
+	-pipe -g -D__$(ENDIANESS)__
 
 ICC_CFLAGS = -I$(LIBC_PREFIX)/include -O$(OPTIMIZATION) -imacros $(CONFIG_HEADER) \
@@ -124,5 +123,5 @@
 	-Wall -Wextra -Wno-clobbered -Wno-unused-parameter -Wmissing-prototypes \
 	-Werror-implicit-function-declaration -Wwrite-strings \
-	-Werror -pipe -g -D__$(ENDIANESS)__
+	-pipe -g -D__$(ENDIANESS)__
 
 CLANG_CFLAGS = -I$(LIBC_PREFIX)/include -O$(OPTIMIZATION) -imacros $(CONFIG_HEADER) \
@@ -133,4 +132,9 @@
 	-pipe -g -arch $(CLANG_ARCH) -D__$(ENDIANESS)__
 
+ifeq ($(CONFIG_DEBUG),y)
+	GCC_CFLAGS += -Werror
+	ICC_CFLAGS += -Werror
+endif
+
 ## Setup platform configuration
 #
@@ -169,5 +173,9 @@
 ifneq ($(BINARY),)
 %.disasm: $(BINARY)
+ifeq ($(CONFIG_LINE_DEBUG),y)
+	$(OBJDUMP) -d -S $< > $@
+else
 	$(OBJDUMP) -d $< > $@
+endif
 
 $(BINARY): $(LINKER_SCRIPT) $(OBJECTS) $(LIBS) $(BASE_LIBS)
Index: pace/app/getterm/Makefile.build
===================================================================
--- uspace/app/getterm/Makefile.build	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ 	(revision )
@@ -1,65 +1,0 @@
-#
-# Copyright (c) 2005 Martin Decky
-# Copyright (c) 2007 Jakub Jermar
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions
-# are met:
-#
-# - Redistributions of source code must retain the above copyright
-#   notice, this list of conditions and the following disclaimer.
-# - Redistributions in binary form must reproduce the above copyright
-#   notice, this list of conditions and the following disclaimer in the
-#   documentation and/or other materials provided with the distribution.
-# - The name of the author may not be used to endorse or promote products
-#   derived from this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
-# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
-# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
-# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
-# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
-# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-#
-
-## Setup toolchain
-#
-
-include Makefile.common
-include $(LIBC_PREFIX)/Makefile.toolchain
-include ../../../version
-
-DEFS += -DRELEASE=$(RELEASE) "-DNAME=$(NAME)"
-
-## Sources
-#
-
-SOURCES = \
-	getvc.c \
-	version.c
-
-OBJECTS := $(addsuffix .o,$(basename $(SOURCES)))
-
-.PHONY: all
-
-all: $(OUTPUT) $(OUTPUT).disasm
-
--include $(DEPEND)
-
-$(OUTPUT).disasm: $(OUTPUT)
-	$(OBJDUMP) -d $< > $@
-
-$(OUTPUT): $(OBJECTS) $(LIBS)
-	$(LD) -T $(LIBC_PREFIX)/arch/$(UARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map
-
-%.o: %.c $(DEPEND)
-	$(CC) $(DEFS) $(CFLAGS) -c $< -o $@
-
-$(DEPEND):
-	makedepend -f - -- $(DEPEND_DEFS) $(CFLAGS) -- $(SOURCES) > $@ 2> /dev/null
-	-[ -f $(DEPEND_PREV) ] && diff -q $(DEPEND_PREV) $@ && mv -f $(DEPEND_PREV) $@
Index: pace/app/getterm/Makefile.common
===================================================================
--- uspace/app/getterm/Makefile.common	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ 	(revision )
@@ -1,39 +1,0 @@
-#
-# Copyright (c) 2005 Martin Decky
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions
-# are met:
-#
-# - Redistributions of source code must retain the above copyright
-#   notice, this list of conditions and the following disclaimer.
-# - Redistributions in binary form must reproduce the above copyright
-#   notice, this list of conditions and the following disclaimer in the
-#   documentation and/or other materials provided with the distribution.
-# - The name of the author may not be used to endorse or promote products
-#   derived from this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
-# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
-# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
-# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
-# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
-# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-#
-
-
-## Common names
-#
-
-LIBC_PREFIX = ../../lib/libc
-SOFTINT_PREFIX = ../../lib/softint
-LIBS = $(LIBC_PREFIX)/libc.a
-
-DEPEND = Makefile.depend
-DEPEND_PREV = $(DEPEND).prev
-OUTPUT = getvc
Index: uspace/app/init/init.c
===================================================================
--- uspace/app/init/init.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/app/init/init.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -274,6 +274,8 @@
 	srv_start("/srv/cuda_adb");
 	srv_start("/srv/i8042");
+	srv_start("/srv/s3c24ser");
 	srv_start("/srv/adb_ms");
 	srv_start("/srv/char_ms");
+	srv_start("/srv/s3c24ts");
 	
 	spawn("/srv/fb");
Index: uspace/app/klog/klog.c
===================================================================
--- uspace/app/klog/klog.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/app/klog/klog.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -43,11 +43,15 @@
 #include <event.h>
 #include <errno.h>
+#include <str_error.h>
 #include <io/klog.h>
 
-#define NAME  "klog"
+#define NAME       "klog"
+#define LOG_FNAME  "/log/klog"
 
 /* Pointer to klog area */
 static wchar_t *klog;
 static size_t klog_length;
+
+static FILE *log;
 
 static void interrupt_received(ipc_callid_t callid, ipc_call_t *call)
@@ -58,6 +62,17 @@
 	size_t i;
 	
-	for (i = klog_len - klog_stored; i < klog_len; i++)
-		putchar(klog[(klog_start + i) % klog_length]);
+	for (i = klog_len - klog_stored; i < klog_len; i++) {
+		wchar_t ch = klog[(klog_start + i) % klog_length];
+		
+		putchar(ch);
+		
+		if (log != NULL)
+			fputc(ch, log);
+	}
+	
+	if (log != NULL) {
+		fflush(log);
+		fsync(fileno(log));
+	}
 }
 
@@ -91,4 +106,14 @@
 	}
 	
+	/*
+	 * Mode "a" would be definitively much better here, but it is
+	 * not well supported by the FAT driver.
+	 *
+	 */
+	log = fopen(LOG_FNAME, "w");
+	if (log == NULL)
+		printf("%s: Unable to create log file %s (%s)\n", NAME, LOG_FNAME,
+		    str_error(errno));
+	
 	async_set_interrupt_received(interrupt_received);
 	klog_update();
Index: uspace/app/netecho/Makefile
===================================================================
--- uspace/app/netecho/Makefile	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/app/netecho/Makefile	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -29,6 +29,6 @@
 
 USPACE_PREFIX = ../..
-LIBS = $(LIBSOCKET_PREFIX)/libsocket.a
-EXTRA_CFLAGS = -I$(LIBSOCKET_PREFIX)/include
+LIBS = 
+EXTRA_CFLAGS = 
 BINARY = netecho
 
Index: uspace/app/netecho/netecho.c
===================================================================
--- uspace/app/netecho/netecho.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/app/netecho/netecho.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -41,11 +41,11 @@
 #include <task.h>
 #include <arg_parse.h>
-
-#include <in.h>
-#include <in6.h>
-#include <inet.h>
-#include <socket.h>
-#include <net_err.h>
-#include <socket_parse.h>
+#include <err.h>
+
+#include <net/in.h>
+#include <net/in6.h>
+#include <net/inet.h>
+#include <net/socket.h>
+#include <net/socket_parse.h>
 
 #include "print_error.h"
Index: uspace/app/netecho/print_error.c
===================================================================
--- uspace/app/netecho/print_error.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/app/netecho/print_error.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -36,7 +36,7 @@
 
 #include <stdio.h>
+#include <errno.h>
 
-#include <icmp_codes.h>
-#include <socket_errno.h>
+#include <net/icmp_codes.h>
 
 #include "print_error.h"
Index: uspace/app/nettest1/Makefile
===================================================================
--- uspace/app/nettest1/Makefile	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/app/nettest1/Makefile	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -29,6 +29,6 @@
 
 USPACE_PREFIX = ../..
-LIBS = $(LIBSOCKET_PREFIX)/libsocket.a
-EXTRA_CFLAGS = -I$(LIBSOCKET_PREFIX)/include
+LIBS = 
+EXTRA_CFLAGS = 
 BINARY = nettest1
 
Index: uspace/app/nettest1/nettest.c
===================================================================
--- uspace/app/nettest1/nettest.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/app/nettest1/nettest.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -36,7 +36,7 @@
 
 #include <stdio.h>
-
-#include <socket.h>
-#include <net_err.h>
+#include <err.h>
+
+#include <net/socket.h>
 
 #include "nettest.h"
Index: uspace/app/nettest1/nettest.h
===================================================================
--- uspace/app/nettest1/nettest.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/app/nettest1/nettest.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -38,5 +38,5 @@
 #define __NET_TEST__
 
-#include <socket.h>
+#include <net/socket.h>
 
 /** Prints a mark.
Index: uspace/app/nettest1/nettest1.c
===================================================================
--- uspace/app/nettest1/nettest1.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/app/nettest1/nettest1.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -41,11 +41,11 @@
 #include <time.h>
 #include <arg_parse.h>
-
-#include <in.h>
-#include <in6.h>
-#include <inet.h>
-#include <socket.h>
-#include <net_err.h>
-#include <socket_parse.h>
+#include <err.h>
+
+#include <net/in.h>
+#include <net/in6.h>
+#include <net/inet.h>
+#include <net/socket.h>
+#include <net/socket_parse.h>
 
 #include "nettest.h"
Index: uspace/app/nettest2/Makefile
===================================================================
--- uspace/app/nettest2/Makefile	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/app/nettest2/Makefile	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -29,6 +29,6 @@
 
 USPACE_PREFIX = ../..
-LIBS = $(LIBSOCKET_PREFIX)/libsocket.a
-EXTRA_CFLAGS = -I$(LIBSOCKET_PREFIX)/include
+LIBS = 
+EXTRA_CFLAGS = 
 BINARY = nettest2
 
Index: uspace/app/nettest2/nettest2.c
===================================================================
--- uspace/app/nettest2/nettest2.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/app/nettest2/nettest2.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -41,11 +41,11 @@
 #include <time.h>
 #include <arg_parse.h>
-
-#include <in.h>
-#include <in6.h>
-#include <inet.h>
-#include <socket.h>
-#include <net_err.h>
-#include <socket_parse.h>
+#include <err.h>
+
+#include <net/in.h>
+#include <net/in6.h>
+#include <net/inet.h>
+#include <net/socket.h>
+#include <net/socket_parse.h>
 
 #include "nettest.h"
Index: uspace/app/ping/Makefile
===================================================================
--- uspace/app/ping/Makefile	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/app/ping/Makefile	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -29,6 +29,6 @@
 
 USPACE_PREFIX = ../..
-LIBS = $(LIBSOCKET_PREFIX)/libsocket.a
-EXTRA_CFLAGS = -I$(LIBSOCKET_PREFIX)/include
+LIBS = 
+EXTRA_CFLAGS = 
 BINARY = ping
 
Index: uspace/app/ping/ping.c
===================================================================
--- uspace/app/ping/ping.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/app/ping/ping.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -42,13 +42,13 @@
 #include <ipc/services.h>
 #include <str_error.h>
+#include <errno.h>
 #include <arg_parse.h>
 
-#include <icmp_api.h>
-#include <in.h>
-#include <in6.h>
-#include <inet.h>
-#include <ip_codes.h>
-#include <socket_errno.h>
-#include <socket_parse.h>
+#include <net/icmp_api.h>
+#include <net/in.h>
+#include <net/in6.h>
+#include <net/inet.h>
+#include <net/socket_parse.h>
+#include <net/ip_codes.h>
 
 #include "print_error.h"
Index: uspace/app/sbi/Makefile
===================================================================
--- uspace/app/sbi/Makefile	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/app/sbi/Makefile	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -35,6 +35,8 @@
 SOURCES = \
 	src/builtin/bi_boxed.c \
+	src/builtin/bi_char.c \
 	src/builtin/bi_error.c \
 	src/builtin/bi_fun.c \
+	src/builtin/bi_int.c \
 	src/builtin/bi_textfile.c \
 	src/builtin/bi_string.c \
Index: uspace/app/sbi/src/ancr.c
===================================================================
--- uspace/app/sbi/src/ancr.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/app/sbi/src/ancr.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -51,4 +51,5 @@
 #include <assert.h>
 #include "builtin.h"
+#include "cspan.h"
 #include "list.h"
 #include "mytypes.h"
@@ -61,4 +62,6 @@
 static void ancr_csi_dfs(stree_program_t *prog, stree_csi_t *csi);
 static void ancr_csi_process(stree_program_t *prog, stree_csi_t *node);
+static stree_csi_t *ancr_csi_get_pred(stree_program_t *prog, stree_csi_t *csi,
+    stree_texpr_t *pred_ref);
 static void ancr_csi_print_cycle(stree_program_t *prog, stree_csi_t *node);
 
@@ -128,44 +131,34 @@
  *
  * @param prog		Program being processed.
- * @param node		CSI node to process.
- */
-static void ancr_csi_process(stree_program_t *prog, stree_csi_t *node)
-{
-	stree_symbol_t *base_sym;
+ * @param csi		CSI node to process.
+ */
+static void ancr_csi_process(stree_program_t *prog, stree_csi_t *csi)
+{
 	stree_csi_t *base_csi, *outer_csi;
 	stree_csi_t *gf_class;
 
-	if (node->ancr_state == ws_visited) {
+	list_node_t *pred_n;
+	stree_texpr_t *pred;
+	stree_csi_t *pred_csi;
+
+	if (csi->ancr_state == ws_visited) {
 		/* Node already processed */
 		return;
 	}
 
-	if (node->ancr_state == ws_active) {
+	if (csi->ancr_state == ws_active) {
 		/* Error, closed reference loop. */
 		printf("Error: Circular class, struct or interface chain: ");
-		ancr_csi_print_cycle(prog, node);
+		ancr_csi_print_cycle(prog, csi);
 		printf(".\n");
 		exit(1);
 	}
 
-	node->ancr_state = ws_active;
-
-	outer_csi = csi_to_symbol(node)->outer_csi;
+	csi->ancr_state = ws_active;
+
+	outer_csi = csi_to_symbol(csi)->outer_csi;
 	gf_class = builtin_get_gf_class(prog->builtin);
 
-	/* Process outer CSI */
-	if (outer_csi != NULL)
-		ancr_csi_process(prog, outer_csi);
-
-	if (node->base_csi_ref != NULL) {
-		/* Resolve base CSI. */
-		base_sym = symbol_xlookup_in_csi(prog, outer_csi,
-			node->base_csi_ref);
-		base_csi = symbol_to_csi(base_sym);
-		assert(base_csi != NULL);
-
-		/* Process base CSI. */
-		ancr_csi_process(prog, base_csi);
-	} else if (node != gf_class) {
+	if (csi != gf_class){
 		/* Implicit inheritance from grandfather class. */
 		base_csi = gf_class;
@@ -175,7 +168,100 @@
 	}
 
+	/* Process outer CSI */
+	if (outer_csi != NULL)
+		ancr_csi_process(prog, outer_csi);
+
+	/*
+	 * Process inheritance list.
+	 */
+	pred_n = list_first(&csi->inherit);
+
+	/* For a class node, the first entry can be a class. */
+	if (csi->cc == csi_class && pred_n != NULL) {
+		pred = list_node_data(pred_n, stree_texpr_t *);
+		pred_csi = ancr_csi_get_pred(prog, csi, pred);
+		assert(pred_csi != NULL);
+
+		if (pred_csi->cc == csi_class) {
+			/* Process base class */
+			base_csi = pred_csi;
+			ancr_csi_process(prog, pred_csi);
+
+			pred_n = list_next(&csi->inherit, pred_n);
+		}
+	}
+
+	/* Following entires can only be interfaces. */
+	while (pred_n != NULL) {
+		pred = list_node_data(pred_n, stree_texpr_t *);
+		pred_csi = ancr_csi_get_pred(prog, csi, pred);
+		assert(pred_csi != NULL);
+
+		/* Process implemented or accumulated interface. */
+		ancr_csi_process(prog, pred_csi);
+
+		switch (pred_csi->cc) {
+		case csi_class:
+			switch (csi->cc) {
+			case csi_class:
+				cspan_print(csi->name->cspan);
+				printf(" Error: Only the first predecessor "
+				    "can be a class. ('");
+				symbol_print_fqn(csi_to_symbol(csi));
+				printf("' deriving from '");
+				symbol_print_fqn(csi_to_symbol(pred_csi));
+				printf("').\n");
+				exit(1);
+				break;
+			case csi_struct:
+				assert(b_false); /* XXX */
+			case csi_interface:
+				cspan_print(csi->name->cspan);
+				printf(" Error: Interface predecessor must be "
+				    "an interface ('");
+				symbol_print_fqn(csi_to_symbol(csi));
+				printf("' deriving from '");
+				symbol_print_fqn(csi_to_symbol(pred_csi));
+				printf("').\n");
+				exit(1);
+				break;
+			}
+		case csi_struct:
+			assert(b_false); /* XXX */
+		case csi_interface:
+			break;
+		}
+
+		pred_n = list_next(&csi->inherit, pred_n);
+	}
+
 	/* Store base CSI and update node state. */
-	node->ancr_state = ws_visited;
-	node->base_csi = base_csi;
+	csi->ancr_state = ws_visited;
+	csi->base_csi = base_csi;
+}
+
+/** Resolve CSI predecessor reference.
+ *
+ * Returns the CSI predecessor referenced by @a pred_ref.
+ * If the referenced CSI does not exist, an error is generated.
+ *
+ * @param prog		Program being processed.
+ * @param csi		CSI node to process.
+ * @param pred_ref	Type expression referencing the predecessor.
+ * @return		Predecessor CSI.
+ */
+static stree_csi_t *ancr_csi_get_pred(stree_program_t *prog, stree_csi_t *csi,
+    stree_texpr_t *pred_ref)
+{
+	stree_csi_t *outer_csi;
+	stree_symbol_t *pred_sym;
+	stree_csi_t *pred_csi;
+
+	outer_csi = csi_to_symbol(csi)->outer_csi;
+	pred_sym = symbol_xlookup_in_csi(prog, outer_csi, pred_ref);
+	pred_csi = symbol_to_csi(pred_sym);
+	assert(pred_csi != NULL); /* XXX */
+
+	return pred_csi;
 }
 
@@ -191,6 +277,8 @@
 {
 	stree_csi_t *n;
-	stree_symbol_t *base_sym, *node_sym;
-	stree_csi_t *base_csi, *outer_csi;
+	stree_symbol_t *pred_sym, *node_sym;
+	stree_csi_t *pred_csi, *outer_csi;
+	stree_texpr_t *pred;
+	list_node_t *pred_n;
 
 	n = node;
@@ -204,15 +292,22 @@
 		if (outer_csi != NULL && outer_csi->ancr_state == ws_active) {
 			node = outer_csi;
-		} else if (node->base_csi_ref != NULL) {
-			/* Resolve base CSI. */
-			base_sym = symbol_xlookup_in_csi(prog, outer_csi,
-				node->base_csi_ref);
-			base_csi = symbol_to_csi(base_sym);
-			assert(base_csi != NULL);
-
-			assert(base_csi->ancr_state == ws_active);
-			node = base_csi;
 		} else {
-			assert(b_false);
+			node = NULL;
+
+			pred_n = list_first(&node->inherit);
+			while (pred_n != NULL) {
+				pred = list_node_data(pred_n, stree_texpr_t *);
+				pred_sym = symbol_xlookup_in_csi(prog,
+				    outer_csi, pred);
+				pred_csi = symbol_to_csi(pred_sym);
+				assert(pred_csi != NULL);
+
+				if (pred_csi->ancr_state == ws_active) {
+					node = pred_csi;
+					break;
+				}
+			}
+
+			assert(node != NULL);
 		}
 	} while (n != node);
Index: uspace/app/sbi/src/bigint.c
===================================================================
--- uspace/app/sbi/src/bigint.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/app/sbi/src/bigint.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -360,28 +360,31 @@
 }
 
-/** Print bigint to standard output. */
-void bigint_print(bigint_t *bigint)
-{
+/** Convert bigint to string.
+ *
+ * @param bigint	Bigint to convert.
+ * @param dptr		Place to store pointer to new string.
+ */
+void bigint_get_as_string(bigint_t *bigint, char **dptr)
+{
+	static const char digits[] = { '0', '1', '2', '3', '4', '5', '6',
+	    '7', '8', '9' };
+
 	bigint_t val, tmp;
 	bigint_word_t rem;
-	size_t ndigits;
-	int *digits;
-	size_t idx;
-
-#ifdef DEBUG_BIGINT_TRACE
-	printf("Print bigint.\n");
+	size_t nchars;
+	char *str;
+	size_t idx;
+
+#ifdef DEBUG_BIGINT_TRACE
+	printf("Convert bigint to string.\n");
 #endif
 	assert(BIGINT_BASE >= 10);
 
-	if (bigint_is_zero(bigint)) {
-		putchar('0');
-		return;
-	}
-
-	if (bigint->negative)
-		putchar('-');
-
-	/* Compute number of digits. */
-	ndigits = 0;
+	/* Compute number of characters. */
+	nchars = 0;
+
+	if (bigint_is_zero(bigint) || bigint->negative)
+		nchars += 1; /* '0' or '-' */
+
 	bigint_clone(bigint, &val);
 	while (bigint_is_zero(&val) != b_true) {
@@ -390,17 +393,23 @@
 		bigint_shallow_copy(&tmp, &val);
 
-		ndigits += 1;
+		nchars += 1;
 	}
 	bigint_destroy(&val);
 
-	/* Store digits to array. */
-
-	digits = malloc(ndigits * sizeof(int));
-	if (digits == NULL) {
+	/* Store characters to array. */
+
+	str = malloc(nchars * sizeof(char) + 1);
+	if (str == NULL) {
 		printf("Memory allocation failed.\n");
 		exit(1);
 	}
 
-	idx = 0;
+	if (bigint_is_zero(bigint)) {
+		str[0] = '0';
+	} else if (bigint->negative) {
+		str[0] = '-';
+	}
+
+	idx = 1;
 	bigint_clone(bigint, &val);
 	while (bigint_is_zero(&val) != b_true) {
@@ -409,12 +418,27 @@
 		bigint_shallow_copy(&tmp, &val);
 
-		digits[idx++] = (int) rem;
-	}
+		str[nchars - idx] = digits[(int) rem];
+		++idx;
+	}
+
 	bigint_destroy(&val);
-
-	for (idx = 0; idx < ndigits; ++idx)
-		printf("%u", digits[ndigits - 1 - idx]);
-
-	free(digits);
+	str[nchars] = '\0';
+	*dptr = str;
+}
+
+/** Print bigint to standard output.
+ *
+ * @param bigint	Bigint to print.
+ */
+void bigint_print(bigint_t *bigint)
+{
+	char *str;
+
+#ifdef DEBUG_BIGINT_TRACE
+	printf("Print bigint.\n");
+#endif
+	bigint_get_as_string(bigint, &str);
+	printf("%s", str);
+	free(str);
 }
 
Index: uspace/app/sbi/src/bigint.h
===================================================================
--- uspace/app/sbi/src/bigint.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/app/sbi/src/bigint.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -48,4 +48,6 @@
 void bigint_sub(bigint_t *a, bigint_t *b, bigint_t *dest);
 void bigint_mul(bigint_t *a, bigint_t *b, bigint_t *dest);
+
+void bigint_get_as_string(bigint_t *bigint, char **dptr);
 void bigint_print(bigint_t *bigint);
 
Index: uspace/app/sbi/src/builtin.c
===================================================================
--- uspace/app/sbi/src/builtin.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/app/sbi/src/builtin.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -42,5 +42,7 @@
 #include "builtin/bi_boxed.h"
 #include "builtin/bi_error.h"
+#include "builtin/bi_char.h"
 #include "builtin/bi_fun.h"
+#include "builtin/bi_int.h"
 #include "builtin/bi_textfile.h"
 #include "builtin/bi_string.h"
@@ -52,4 +54,5 @@
 #include "os/os.h"
 #include "parse.h"
+#include "rdata.h"
 #include "run.h"
 #include "stree.h"
@@ -89,5 +92,7 @@
 
 	bi_error_declare(bi);
+	bi_char_declare(bi);
 	bi_fun_declare(bi);
+	bi_int_declare(bi);
 	bi_textfile_declare(bi);
 	bi_string_declare(bi);
@@ -105,5 +110,7 @@
 	bi_boxed_bind(bi);
 	bi_error_bind(bi);
+	bi_char_bind(bi);
 	bi_fun_bind(bi);
+	bi_int_bind(bi);
 	bi_textfile_bind(bi);
 	bi_string_bind(bi);
@@ -250,5 +257,4 @@
 {
 	stree_symbol_t *fun_sym;
-	builtin_t *bi;
 	builtin_proc_t bproc;
 
@@ -257,5 +263,4 @@
 #endif
 	fun_sym = proc->outer_symbol;
-	bi = run->program->builtin;
 
 	bproc = proc->bi_handler;
@@ -298,5 +303,40 @@
 }
 
-/** Declare a builtin function in @a csi.
+/** Return string value from builtin procedure.
+ *
+ * Makes it easy for a builtin procedure to return value of type @c string.
+ *
+ * @param run		Runner object
+ * @param str		String value. Must be allocated from heap and its
+ *			ownership is hereby given up.
+ */
+void builtin_return_string(run_t *run, const char *astr)
+{
+	rdata_string_t *rstring;
+	rdata_var_t *rvar;
+	rdata_value_t *rval;
+	rdata_item_t *ritem;
+
+	run_proc_ar_t *proc_ar;
+
+#ifdef DEBUG_RUN_TRACE
+	printf("Return string '%s' from builtin function.\n", astr);
+#endif
+	rstring = rdata_string_new();
+	rstring->value = astr;
+
+	rvar = rdata_var_new(vc_string);
+	rvar->u.string_v = rstring;
+	rval = rdata_value_new();
+	rval->var = rvar;
+
+	ritem = rdata_item_new(ic_value);
+	ritem->u.value = rval;
+
+	proc_ar = run_get_current_proc_ar(run);
+	proc_ar->retval = ritem;
+}
+
+/** Declare a static builtin function in @a csi.
  *
  * Declare a builtin function member of CSI @a csi. Deprecated in favor
@@ -314,4 +354,5 @@
 	stree_csimbr_t *csimbr;
 	stree_symbol_t *fun_sym;
+	stree_symbol_attr_t *sym_attr;
 
 	ident = stree_ident_new();
@@ -333,4 +374,8 @@
 	fun_sym->u.fun = fun;
 	fun_sym->outer_csi = csi;
+
+	sym_attr = stree_symbol_attr_new(sac_static);
+	list_append(&fun_sym->attr, sym_attr);
+
 	fun->symbol = fun_sym;
 	fun->proc->outer_symbol = fun_sym;
Index: uspace/app/sbi/src/builtin.h
===================================================================
--- uspace/app/sbi/src/builtin.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/app/sbi/src/builtin.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -40,4 +40,5 @@
 
 rdata_var_t *builtin_get_self_mbr_var(run_t *run, const char *mbr_name);
+void builtin_return_string(run_t *run, const char *str);
 
 stree_symbol_t *builtin_declare_fun(stree_csi_t *csi, const char *name);
Index: uspace/app/sbi/src/builtin/bi_char.c
===================================================================
--- uspace/app/sbi/src/builtin/bi_char.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
+++ uspace/app/sbi/src/builtin/bi_char.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -0,0 +1,96 @@
+/*
+ * 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.
+ */
+
+/** @file Char builtin binding. */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+#include "../bigint.h"
+#include "../builtin.h"
+#include "../debug.h"
+#include "../mytypes.h"
+#include "../os/os.h"
+#include "../rdata.h"
+#include "../run.h"
+#include "../strtab.h"
+
+#include "bi_char.h"
+
+static void bi_char_get_as_string(run_t *run);
+
+/** Declare Char builtin.
+ *
+ * @param bi	Builtin object
+ */
+void bi_char_declare(builtin_t *bi)
+{
+	(void) bi;
+}
+
+/** Bind Char builtin.
+ *
+ * @param bi	Builtin object
+ */
+void bi_char_bind(builtin_t *bi)
+{
+	builtin_fun_bind(bi, "Char", "get_as_string", bi_char_get_as_string);
+}
+
+/** Return string representation.
+ *
+ * @param run	Runner object
+ */
+static void bi_char_get_as_string(run_t *run)
+{
+        rdata_var_t *self_value_var;
+        bigint_t *cval;
+        char *str;
+        int char_val;
+        int rc;
+
+#ifdef DEBUG_RUN_TRACE
+	printf("Convert char to string.\n");
+#endif
+	/* Extract self.Value */
+	self_value_var = builtin_get_self_mbr_var(run, "Value");
+	assert(self_value_var->vc == vc_char);
+	cval = &self_value_var->u.char_v->value;
+
+	rc = bigint_get_value_int(cval, &char_val);
+	if (rc != EOK) {
+		/* XXX Should raise exception. */
+		builtin_return_string(run, os_str_dup("?"));
+		return;
+	}
+
+	str = os_chr_to_astr((wchar_t) char_val);
+
+	/* Ownership of str is transferred. */
+	builtin_return_string(run, str);
+}
Index: uspace/app/sbi/src/builtin/bi_char.h
===================================================================
--- uspace/app/sbi/src/builtin/bi_char.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
+++ uspace/app/sbi/src/builtin/bi_char.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2010 Jiri Svoboda
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef BI_CHAR_H_
+#define BI_CHAR_H_
+
+#include "../mytypes.h"
+
+void bi_char_declare(builtin_t *bi);
+void bi_char_bind(builtin_t *bi);
+
+#endif
Index: uspace/app/sbi/src/builtin/bi_fun.c
===================================================================
--- uspace/app/sbi/src/builtin/bi_fun.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/app/sbi/src/builtin/bi_fun.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -94,5 +94,5 @@
 	builtin_code_snippet(bi,
 		"class Task is\n"
-			"fun Exec(args : string[], packed), builtin;\n"
+			"fun Exec(args : string[], packed), static, builtin;\n"
 		"end\n");
 }
Index: uspace/app/sbi/src/builtin/bi_int.c
===================================================================
--- uspace/app/sbi/src/builtin/bi_int.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
+++ uspace/app/sbi/src/builtin/bi_int.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -0,0 +1,87 @@
+/*
+ * 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.
+ */
+
+/** @file Int builtin binding. */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+#include "../bigint.h"
+#include "../builtin.h"
+#include "../debug.h"
+#include "../mytypes.h"
+#include "../os/os.h"
+#include "../rdata.h"
+#include "../run.h"
+#include "../strtab.h"
+
+#include "bi_int.h"
+
+static void bi_int_get_as_string(run_t *run);
+
+/** Declare Int builtin.
+ *
+ * @param bi	Builtin object
+ */
+void bi_int_declare(builtin_t *bi)
+{
+	(void) bi;
+}
+
+/** Bind Int builtin.
+ *
+ * @param bi	Builtin object
+ */
+void bi_int_bind(builtin_t *bi)
+{
+	builtin_fun_bind(bi, "Int", "get_as_string", bi_int_get_as_string);
+}
+
+/** Return string representation.
+ *
+ * @param run	Runner object
+ */
+static void bi_int_get_as_string(run_t *run)
+{
+        rdata_var_t *self_value_var;
+        bigint_t *ival;
+        char *str;
+
+	/* Extract self.Value */
+	self_value_var = builtin_get_self_mbr_var(run, "Value");
+	assert(self_value_var->vc == vc_int);
+	ival = &self_value_var->u.int_v->value;
+
+	bigint_get_as_string(ival, &str);
+
+#ifdef DEBUG_RUN_TRACE
+	printf("Convert int to string '%s'.\n", str);
+#endif
+	/* Ownership of str is transferred. */
+	builtin_return_string(run, str);
+}
Index: uspace/app/sbi/src/builtin/bi_int.h
===================================================================
--- uspace/app/sbi/src/builtin/bi_int.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
+++ uspace/app/sbi/src/builtin/bi_int.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2010 Jiri Svoboda
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef BI_INT_H_
+#define BI_INT_H_
+
+#include "../mytypes.h"
+
+void bi_int_declare(builtin_t *bi);
+void bi_int_bind(builtin_t *bi);
+
+#endif
Index: uspace/app/sbi/src/builtin/bi_string.c
===================================================================
--- uspace/app/sbi/src/builtin/bi_string.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/app/sbi/src/builtin/bi_string.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -116,4 +116,5 @@
         rdata_var_t *self_value_var;
         const char *str;
+        const char *slice;
         size_t str_l;
 
@@ -125,11 +126,4 @@
 
 	int rc;
-
-	rdata_string_t *rstring;
-	rdata_var_t *rvar;
-	rdata_value_t *rval;
-	rdata_item_t *ritem;
-
-	run_proc_ar_t *proc_ar;
 
 	/* Extract self.Value */
@@ -165,17 +159,7 @@
 	    start, length, str);
 #endif
-	/* Construct return value. */
-	rstring = rdata_string_new();
-	rstring->value = os_str_aslice(str, start, length);
+	slice = os_str_aslice(str, start, length);
 
-	rvar = rdata_var_new(vc_string);
-	rvar->u.string_v = rstring;
-	rval = rdata_value_new();
-	rval->var = rvar;
-
-	ritem = rdata_item_new(ic_value);
-	ritem->u.value = rval;
-
-	proc_ar = run_get_current_proc_ar(run);
-	proc_ar->retval = ritem;
+	/* Ownership of slice is transferred. */
+	builtin_return_string(run, slice);
 }
Index: uspace/app/sbi/src/imode.c
===================================================================
--- uspace/app/sbi/src/imode.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/app/sbi/src/imode.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -130,7 +130,9 @@
 
 	/* Construct run context. */
+	run_gdata_init(&run);
+
 	run.thread_ar = run_thread_ar_new();
 	list_init(&run.thread_ar->proc_ar);
-	run_proc_ar_create(&run, NULL, proc, &proc_ar);
+	run_proc_ar_create(&run, run.gdata, proc, &proc_ar);
 	list_append(&run.thread_ar->proc_ar, proc_ar);
 
Index: uspace/app/sbi/src/input.c
===================================================================
--- uspace/app/sbi/src/input.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/app/sbi/src/input.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -206,5 +206,5 @@
 			*dp++ = *sp++;
 
-		*dp++ = '\0';
+		*dp = '\0';
 		input->str = sp;
 		*line = input->buffer;
Index: uspace/app/sbi/src/mytypes.h
===================================================================
--- uspace/app/sbi/src/mytypes.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/app/sbi/src/mytypes.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -43,4 +43,10 @@
 } walk_state_t;
 
+/** Static vs. nonstatic */
+typedef enum {
+	sn_nonstatic,
+	sn_static
+} statns_t;
+
 /** Error return codes. */
 #include <errno.h>
Index: uspace/app/sbi/src/os/helenos.c
===================================================================
--- uspace/app/sbi/src/os/helenos.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/app/sbi/src/os/helenos.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -173,4 +173,31 @@
 }
 
+/** Convert character to new string.
+ *
+ * @param chr		Character
+ * @return		Newly allocated string.
+ */
+char *os_chr_to_astr(wchar_t chr)
+{
+	char *str;
+	size_t offset;
+
+	str = malloc(STR_BOUNDS(1) + 1);
+	if (str == NULL) {
+		printf("Memory allocation error.\n");
+		exit(1);
+	}
+
+	offset = 0;
+	if (chr_encode(chr, str, &offset, STR_BOUNDS(1)) != EOK) {
+		/* XXX Should handle gracefully */
+		printf("String conversion error.\n");
+		exit(1);
+	}
+
+	str[offset] = '\0';
+	return str;
+}
+
 /** Display survival help message. */
 void os_input_disp_help(void)
Index: uspace/app/sbi/src/os/os.h
===================================================================
--- uspace/app/sbi/src/os/os.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/app/sbi/src/os/os.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -36,4 +36,5 @@
 size_t os_str_length(const char *str);
 int os_str_get_char(const char *str, int index, int *out_char);
+char *os_chr_to_astr(wchar_t chr);
 void os_input_disp_help(void);
 int os_input_line(char **ptr);
Index: uspace/app/sbi/src/os/posix.c
===================================================================
--- uspace/app/sbi/src/os/posix.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/app/sbi/src/os/posix.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -159,4 +159,25 @@
 }
 
+/** Convert character to new string.
+ *
+ * @param chr		Character
+ * @return		Newly allocated string.
+ */
+char *os_chr_to_astr(wchar_t chr)
+{
+	char *str;
+
+	str = malloc(2);
+	if (str == NULL) {
+		printf("Memory allocation error.\n");
+		exit(1);
+	}
+
+	str[0] = (char) chr;
+	str[1] = '\0';
+
+	return str;
+}
+
 #define OS_INPUT_BUFFER_SIZE 256
 static char os_input_buffer[OS_INPUT_BUFFER_SIZE];
Index: uspace/app/sbi/src/parse.c
===================================================================
--- uspace/app/sbi/src/parse.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/app/sbi/src/parse.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -35,4 +35,5 @@
 #include <assert.h>
 #include <stdlib.h>
+#include "cspan.h"
 #include "debug.h"
 #include "lex.h"
@@ -64,4 +65,5 @@
 static stree_prop_t *parse_prop(parse_t *parse, stree_csi_t *outer_csi);
 
+static void parse_symbol_attrs(parse_t *parse, stree_symbol_t *symbol);
 static stree_symbol_attr_t *parse_symbol_attr(parse_t *parse);
 
@@ -70,4 +72,6 @@
 static stree_fun_sig_t *parse_fun_sig(parse_t *parse);
 
+static void parse_prop_get(parse_t *parse, stree_prop_t *prop);
+static void parse_prop_set(parse_t *parse, stree_prop_t *prop);
 
 /*
@@ -175,4 +179,5 @@
 	stree_ident_t *targ_name;
 	stree_targ_t *targ;
+	stree_texpr_t *pref;
 
 	switch (dclass) {
@@ -212,7 +217,16 @@
 		/* Inheritance list */
 		lskip(parse);
-		csi->base_csi_ref = parse_texpr(parse);
-	} else {
-		csi->base_csi_ref = NULL;
+
+		while (b_true) {
+			pref = parse_texpr(parse);
+			if (parse_is_error(parse))
+				break;
+
+			list_append(&csi->inherit, pref);
+			if (lcur_lc(parse) != lc_plus)
+				break;
+
+			lskip(parse);
+		}
 	}
 
@@ -224,10 +238,24 @@
 		csimbr = parse_csimbr(parse, csi);
 		if (csimbr == NULL)
+			continue;
+
+		list_append(&csi->members, csimbr);
+	}
+
+	lmatch(parse, lc_end);
+
+	if (outer_csi != NULL) {
+		switch (outer_csi->cc) {
+		case csi_class:
+		case csi_struct:
 			break;
-
-		list_append(&csi->members, csimbr);
-	}
-
-	lmatch(parse, lc_end);
+		case csi_interface:
+			cspan_print(csi->name->cspan);
+			printf(" Error: CSI declared inside interface.\n");
+			parse_note_error(parse);
+			/* XXX Free csi */
+			return NULL;
+		}
+	}
 
 	return csi;
@@ -253,4 +281,6 @@
 	stree_prop_t *prop;
 
+	csimbr = NULL;
+
 	switch (lcur_lc(parse)) {
 	case lc_class:
@@ -258,21 +288,29 @@
 	case lc_interface:
 		csi = parse_csi(parse, lcur_lc(parse), outer_csi);
-		csimbr = stree_csimbr_new(csimbr_csi);
-		csimbr->u.csi = csi;
+		if (csi != NULL) {
+			csimbr = stree_csimbr_new(csimbr_csi);
+			csimbr->u.csi = csi;
+		}
 		break;
 	case lc_new:
 		ctor = parse_ctor(parse, outer_csi);
-		csimbr = stree_csimbr_new(csimbr_ctor);
-		csimbr->u.ctor = ctor;
+		if (ctor != NULL) {
+			csimbr = stree_csimbr_new(csimbr_ctor);
+			csimbr->u.ctor = ctor;
+		}
 		break;
 	case lc_deleg:
 		deleg = parse_deleg(parse, outer_csi);
-		csimbr = stree_csimbr_new(csimbr_deleg);
-		csimbr->u.deleg = deleg;
+		if (deleg != NULL) {
+			csimbr = stree_csimbr_new(csimbr_deleg);
+			csimbr->u.deleg = deleg;
+		}
 		break;
 	case lc_enum:
 		enum_d = parse_enum(parse, outer_csi);
-		csimbr = stree_csimbr_new(csimbr_enum);
-		csimbr->u.enum_d = enum_d;
+		if (enum_d != NULL) {
+			csimbr = stree_csimbr_new(csimbr_enum);
+			csimbr->u.enum_d = enum_d;
+		}
 		break;
 	case lc_fun:
@@ -283,6 +321,8 @@
 	case lc_var:
 		var = parse_var(parse, outer_csi);
-		csimbr = stree_csimbr_new(csimbr_var);
-		csimbr->u.var = var;
+		if (var != NULL) {
+			csimbr = stree_csimbr_new(csimbr_var);
+			csimbr->u.var = var;
+		}
 		break;
 	case lc_prop:
@@ -294,5 +334,4 @@
 		lunexpected_error(parse);
 		lex_next(parse->lex);
-		csimbr = NULL;
 		break;
 	}
@@ -311,5 +350,5 @@
 	stree_ctor_t *ctor;
 	stree_symbol_t *symbol;
-	stree_symbol_attr_t *attr;
+	cspan_t *cspan;
 
 	ctor = stree_ctor_new();
@@ -321,4 +360,5 @@
 
 	lmatch(parse, lc_new);
+	cspan = lprev_span(parse);
 
 	/* Fake identifier. */
@@ -334,5 +374,6 @@
 	ctor->sig = parse_fun_sig(parse);
 	if (ctor->sig->rtype != NULL) {
-		printf("Error: Constructor of CSI '");
+		cspan_print(cspan);
+		printf(" Error: Constructor of CSI '");
 		symbol_print_fqn(csi_to_symbol(outer_csi));
 		printf("' has a return type.\n");
@@ -340,12 +381,6 @@
 	}
 
-	list_init(&symbol->attr);
-
 	/* Parse attributes. */
-	while (lcur_lc(parse) == lc_comma && !parse_is_error(parse)) {
-		lskip(parse);
-		attr = parse_symbol_attr(parse);
-		list_append(&symbol->attr, attr);
-	}
+	parse_symbol_attrs(parse, symbol);
 
 	ctor->proc = stree_proc_new();
@@ -356,5 +391,6 @@
 
 		/* This constructor has no body. */
-		printf("Error: Constructor of CSI '");
+		cspan_print(cspan);
+		printf(" Error: Constructor of CSI '");
 		symbol_print_fqn(csi_to_symbol(outer_csi));
 		printf("' has no body.\n");
@@ -368,4 +404,16 @@
 	}
 
+	switch (outer_csi->cc) {
+	case csi_class:
+	case csi_struct:
+		break;
+	case csi_interface:
+		cspan_print(ctor->name->cspan);
+		printf(" Error: Constructor declared inside interface.\n");
+		parse_note_error(parse);
+		/* XXX Free ctor */
+		return NULL;
+	}
+
 	return ctor;
 }
@@ -409,4 +457,5 @@
 
 	if (list_is_empty(&enum_d->members)) {
+		cspan_print(enum_d->name->cspan);
 		printf("Error: Enum type '%s' has no members.\n",
 		    strtab_get_str(enum_d->name->sid));
@@ -416,4 +465,18 @@
 	lmatch(parse, lc_end);
 
+	if (outer_csi != NULL) {
+		switch (outer_csi->cc) {
+		case csi_class:
+		case csi_struct:
+			break;
+		case csi_interface:
+			cspan_print(enum_d->name->cspan);
+			printf(" Error: Enum declared inside interface.\n");
+			parse_note_error(parse);
+			/* XXX Free enum */
+			return NULL;
+		}
+	}
+
 	return enum_d;
 }
@@ -449,5 +512,4 @@
 	stree_deleg_t *deleg;
 	stree_symbol_t *symbol;
-	stree_symbol_attr_t *attr;
 
 	deleg = stree_deleg_new();
@@ -467,14 +529,20 @@
 	deleg->sig = parse_fun_sig(parse);
 
-	list_init(&symbol->attr);
-
 	/* Parse attributes. */
-	while (lcur_lc(parse) == lc_comma && !parse_is_error(parse)) {
-		lskip(parse);
-		attr = parse_symbol_attr(parse);
-		list_append(&symbol->attr, attr);
-	}
+	parse_symbol_attrs(parse, symbol);
 
 	lmatch(parse, lc_scolon);
+
+	switch (outer_csi->cc) {
+	case csi_class:
+	case csi_struct:
+		break;
+	case csi_interface:
+		cspan_print(deleg->name->cspan);
+		printf(" Error: Delegate declared inside interface.\n");
+		parse_note_error(parse);
+		/* XXX Free deleg */
+		return NULL;
+	}
 
 	return deleg;
@@ -491,5 +559,5 @@
 	stree_fun_t *fun;
 	stree_symbol_t *symbol;
-	stree_symbol_attr_t *attr;
+	bool_t body_expected;
 
 	fun = stree_fun_new();
@@ -508,12 +576,9 @@
 	fun->sig = parse_fun_sig(parse);
 
-	list_init(&symbol->attr);
-
 	/* Parse attributes. */
-	while (lcur_lc(parse) == lc_comma && !parse_is_error(parse)) {
-		lskip(parse);
-		attr = parse_symbol_attr(parse);
-		list_append(&symbol->attr, attr);
-	}
+	parse_symbol_attrs(parse, symbol);
+
+	body_expected = !stree_symbol_has_attr(symbol, sac_builtin) &&
+	    (outer_csi->cc != csi_interface);
 
 	fun->proc = stree_proc_new();
@@ -523,11 +588,13 @@
 		lskip(parse);
 
-		/* This function has no body. */
-		if (!stree_symbol_has_attr(symbol, sac_builtin)) {
-			printf("Error: Function '");
+		/* Body not present */
+		if (body_expected) {
+			cspan_print(fun->name->cspan);
+			printf(" Error: Function '");
 			symbol_print_fqn(symbol);
-			printf("' has no body.\n");
+			printf("' should have a body.\n");
 			parse_note_error(parse);
 		}
+
 		fun->proc->body = NULL;
 	} else {
@@ -535,4 +602,13 @@
 		fun->proc->body = parse_block(parse);
 		lmatch(parse, lc_end);
+
+		/* Body present */
+		if (!body_expected) {
+			cspan_print(fun->name->cspan);
+			printf(" Error: Function declaration '");
+			symbol_print_fqn(symbol);
+			printf("' should not have a body.\n");
+			parse_note_error(parse);
+		}
 	}
 
@@ -561,5 +637,20 @@
 	lmatch(parse, lc_colon);
 	var->type =  parse_texpr(parse);
+
+	parse_symbol_attrs(parse, symbol);
+
 	lmatch(parse, lc_scolon);
+
+	switch (outer_csi->cc) {
+	case csi_class:
+	case csi_struct:
+		break;
+	case csi_interface:
+		cspan_print(var->name->cspan);
+		printf(" Error: Variable declared inside interface.\n");
+		parse_note_error(parse);
+		/* XXX Free var */
+		return NULL;
+	}
 
 	return var;
@@ -576,4 +667,5 @@
 	stree_prop_t *prop;
 	stree_symbol_t *symbol;
+	bool_t body_expected;
 
 	stree_ident_t *ident;
@@ -625,4 +717,10 @@
 	lmatch(parse, lc_colon);
 	prop->type = parse_texpr(parse);
+
+	/* Parse attributes. */
+	parse_symbol_attrs(parse, symbol);
+
+	body_expected = (outer_csi->cc != csi_interface);
+
 	lmatch(parse, lc_is);
 
@@ -630,40 +728,8 @@
 		switch (lcur_lc(parse)) {
 		case lc_get:
-			lskip(parse);
-			lmatch(parse, lc_is);
-			if (prop->getter != NULL) {
-				printf("Error: Duplicate getter.\n");
-				(void) parse_block(parse); /* XXX Free */
-				lmatch(parse, lc_end);
-				parse_note_error(parse);
-				break;
-			}
-
-			/* Create setter procedure */
-			prop->getter = stree_proc_new();
-			prop->getter->body = parse_block(parse);
-			prop->getter->outer_symbol = symbol;
-
-			lmatch(parse, lc_end);
+			parse_prop_get(parse, prop);
 			break;
 		case lc_set:
-			lskip(parse);
-			prop->setter_arg = stree_proc_arg_new();
-			prop->setter_arg->name = parse_ident(parse);
-			prop->setter_arg->type = prop->type;
-			lmatch(parse, lc_is);
-			if (prop->setter != NULL) {
-				printf("Error: Duplicate setter.\n");
-				(void) parse_block(parse); /* XXX Free */
-				lmatch(parse, lc_end);
-				parse_note_error(parse);
-			}
-
-			/* Create setter procedure */
-			prop->setter = stree_proc_new();
-			prop->setter->body = parse_block(parse);
-			prop->setter->outer_symbol = symbol;
-
-			lmatch(parse, lc_end);
+			parse_prop_set(parse, prop);
 			break;
 		default:
@@ -677,24 +743,51 @@
 }
 
+/** Parse symbol attributes.
+ *
+ * Parse list of attributes and add them to @a symbol.
+ *
+ * @param parse		Parser object
+ * @param symbol	Symbol to add these attributes to
+ */
+static void parse_symbol_attrs(parse_t *parse, stree_symbol_t *symbol)
+{
+	stree_symbol_attr_t *attr;
+
+	/* Parse attributes. */
+	while (lcur_lc(parse) == lc_comma && !parse_is_error(parse)) {
+		lskip(parse);
+		attr = parse_symbol_attr(parse);
+		list_append(&symbol->attr, attr);
+	}
+}
+
 /** Parse symbol attribute.
  *
- * @param parse		Parser object.
- * @param outer_csi	CSI containing this declaration or @c NULL if global.
- * @return		New syntax tree node.
+ * @param parse		Parser object
+ * @return		New syntax tree node
  */
 static stree_symbol_attr_t *parse_symbol_attr(parse_t *parse)
 {
 	stree_symbol_attr_t *attr;
-
-	if (lcur_lc(parse) != lc_builtin) {
-		printf("Error: Unexpected attribute '");
+	symbol_attr_class_t sac;
+
+	/* Make compiler happy. */
+	sac = 0;
+
+	switch (lcur_lc(parse)) {
+	case lc_builtin: sac = sac_builtin; break;
+	case lc_static: sac = sac_static; break;
+	default:
+		cspan_print(lcur_span(parse));
+		printf(" Error: Unexpected attribute '");
 		lem_print(lcur(parse));
 		printf("'.\n");
 		parse_note_error(parse);
+		break;
 	}
 
 	lskip(parse);
 
-	attr = stree_symbol_attr_new(sac_builtin);
+	attr = stree_symbol_attr_new(sac);
 	return attr;
 }
@@ -718,5 +811,5 @@
 	printf("Parse procedure argument.\n");
 #endif
- 	list_init(&arg->attr);
+	list_init(&arg->attr);
 
 	/* Parse attributes. */
@@ -740,5 +833,6 @@
 
 	if (lcur_lc(parse) != lc_packed) {
-		printf("Error: Unexpected attribute '");
+		cspan_print(lcur_span(parse));
+		printf(" Error: Unexpected attribute '");
 		lem_print(lcur(parse));
 		printf("'.\n");
@@ -802,4 +896,138 @@
 
 	return sig;
+}
+
+/** Parse member property getter.
+ *
+ * @param parse		Parser object.
+ * @param prop		Property containing this declaration.
+ */
+static void parse_prop_get(parse_t *parse, stree_prop_t *prop)
+{
+	cspan_t *cspan;
+	stree_block_t *block;
+	stree_proc_t *getter;
+	bool_t body_expected;
+
+	body_expected = (prop->symbol->outer_csi->cc != csi_interface);
+
+	lskip(parse);
+	cspan = lprev_span(parse);
+
+	if (prop->getter != NULL) {
+		cspan_print(cspan);
+		printf(" Error: Duplicate getter.\n");
+		parse_note_error(parse);
+		return;
+	}
+
+	if (lcur_lc(parse) == lc_scolon) {
+		/* Body not present */
+		lskip(parse);
+		block = NULL;
+
+		if (body_expected) {
+			cspan_print(prop->name->cspan);
+			printf(" Error: Property '");
+			symbol_print_fqn(prop->symbol);
+			printf("' getter should have "
+			    "a body.\n");
+			parse_note_error(parse);
+		}
+	} else {
+		/* Body present */
+		lmatch(parse, lc_is);
+		block = parse_block(parse);
+		lmatch(parse, lc_end);
+
+		if (!body_expected) {
+			cspan_print(prop->name->cspan);
+			printf(" Error: Property '");
+			symbol_print_fqn(prop->symbol);
+			printf("' getter declaration should "
+			    "not have a body.\n");
+			parse_note_error(parse);
+
+			/* XXX Free block */
+			block = NULL;
+		}
+	}
+
+	/* Create getter procedure */
+	getter = stree_proc_new();
+	getter->body = block;
+	getter->outer_symbol = prop->symbol;
+
+	/* Store getter in property. */
+	prop->getter = getter;
+}
+
+
+/** Parse member property setter.
+ *
+ * @param parse		Parser object.
+ * @param prop		Property containing this declaration.
+ */
+static void parse_prop_set(parse_t *parse, stree_prop_t *prop)
+{
+	cspan_t *cspan;
+	stree_block_t *block;
+	stree_proc_t *setter;
+	bool_t body_expected;
+
+	body_expected = (prop->symbol->outer_csi->cc != csi_interface);
+
+	lskip(parse);
+	cspan = lprev_span(parse);
+
+	if (prop->setter != NULL) {
+		cspan_print(cspan);
+		printf(" Error: Duplicate setter.\n");
+		parse_note_error(parse);
+		return;
+	}
+
+	prop->setter_arg = stree_proc_arg_new();
+	prop->setter_arg->name = parse_ident(parse);
+	prop->setter_arg->type = prop->type;
+
+	if (lcur_lc(parse) == lc_scolon) {
+		/* Body not present */
+		lskip(parse);
+
+		block = NULL;
+
+		if (body_expected) {
+			cspan_print(prop->name->cspan);
+			printf(" Error: Property '");
+			symbol_print_fqn(prop->symbol);
+			printf("' setter should have "
+			    "a body.\n");
+			parse_note_error(parse);
+		}
+	} else {
+		/* Body present */
+		lmatch(parse, lc_is);
+		block = parse_block(parse);
+		lmatch(parse, lc_end);
+
+		if (!body_expected) {
+			cspan_print(prop->name->cspan);
+			printf(" Error: Property '");
+			symbol_print_fqn(prop->symbol);
+			printf("' setter declaration should "
+			    "not have a body.\n");
+			parse_note_error(parse);
+		}
+	}
+
+
+	/* Create setter procedure */
+	setter = stree_proc_new();
+	setter->body = block;
+	setter->outer_symbol = prop->symbol;
+
+	/* Store setter in property. */
+	prop->setter = setter;
 }
 
Index: uspace/app/sbi/src/program.c
===================================================================
--- uspace/app/sbi/src/program.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/app/sbi/src/program.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -85,4 +85,9 @@
  * is read from '<libdir>/libflist'. Each line of the file contains one file
  * name relative to <libdir>.
+ *
+ * @param program 	The program to which the parsed code is added.
+ * @return		EOK on success, EIO if some file comprising the
+ *			library is not found, EINVAL if the library
+ *			has syntax errors.
  */
 int program_lib_process(stree_program_t *program)
@@ -147,4 +152,4 @@
 	fclose(f);
 
-	return rc;
+	return EOK;
 }
Index: uspace/app/sbi/src/rdata.c
===================================================================
--- uspace/app/sbi/src/rdata.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/app/sbi/src/rdata.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -609,5 +609,5 @@
 	(void) src; (void) dest;
 	printf("Unimplemented: Copy object.\n");
-	exit(1);
+	abort();
 }
 
Index: uspace/app/sbi/src/rdata_t.h
===================================================================
--- uspace/app/sbi/src/rdata_t.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/app/sbi/src/rdata_t.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -71,9 +71,9 @@
  *
  * A delegate variable points to a static or non-static symbol. If the
- * symbol is non static, @c obj points to the object the symbol instance
+ * symbol is non static, @c obj points to the object the symbol
  * belongs to.
  */
 typedef struct {
-	/** Object or @c NULL if deleg. points to a CSI or static member. */
+	/** Object or @c NULL if deleg. points to a static function. */
 	struct rdata_var *obj;
 
@@ -107,4 +107,7 @@
 	/** Class of this object (symbol) */
 	struct stree_symbol *class_sym;
+
+	/** @c sn_static if this is a static object (i.e. class object) */
+	statns_t static_obj;
 
 	/** Map field name SID to field data */
Index: uspace/app/sbi/src/run.c
===================================================================
--- uspace/app/sbi/src/run.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/app/sbi/src/run.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -99,4 +99,5 @@
 	stree_symbol_t *main_fun_sym;
 	stree_fun_t *main_fun;
+	rdata_var_t *main_obj;
 	stree_ident_t *fake_ident;
 	list_t main_args;
@@ -111,4 +112,7 @@
 	list_init(&run->thread_ar->proc_ar);
 	run->thread_ar->bo_mode = bm_none;
+
+	/* Initialize global data structure. */
+	run_gdata_init(run);
 
 	/*
@@ -126,4 +130,6 @@
 	assert(main_fun != NULL);
 
+	main_obj = run_fun_sobject_find(run, main_fun);
+
 #ifdef DEBUG_RUN_TRACE
 	printf("Found function '"); symbol_print_fqn(main_fun_sym);
@@ -133,9 +139,26 @@
 	/* Run function @c main. */
 	list_init(&main_args);
-	run_proc_ar_create(run, NULL, main_fun->proc, &proc_ar);
+	run_proc_ar_create(run, main_obj, main_fun->proc, &proc_ar);
 	run_proc_ar_set_args(run, proc_ar, &main_args);
 	run_proc(run, proc_ar, &res);
 
 	run_exc_check_unhandled(run);
+}
+
+/** Initialize global data.
+ *
+ * @param run		Runner object
+ */
+void run_gdata_init(run_t *run)
+{
+	rdata_object_t *gobject;
+
+	run->gdata = rdata_var_new(vc_object);
+	gobject = rdata_object_new();
+	run->gdata->u.object_v = gobject;
+
+	gobject->class_sym = NULL;
+	gobject->static_obj = sn_static;
+	intmap_init(&gobject->fields);
 }
 
@@ -787,4 +810,102 @@
 	proc_ar = run_get_current_proc_ar(run);
 	return proc_ar->proc->outer_symbol->outer_csi;
+}
+
+/** Get static object (i.e. class object).
+ *
+ * Looks for a child static object named @a name in static object @a pobject.
+ * If the child does not exist yet, it is created.
+ *
+ * @param run		Runner object
+ * @param csi		CSI of the static object named @a name
+ * @param pobject	Parent static object
+ * @param name		Static object name
+ *
+ * @return		Static (class) object of the given name
+ */
+rdata_var_t *run_sobject_get(run_t *run, stree_csi_t *csi,
+    rdata_var_t *pobj_var, sid_t name)
+{
+	rdata_object_t *pobject;
+	rdata_var_t *mbr_var;
+	rdata_var_t *rvar;
+	stree_ident_t *ident;
+
+	assert(pobj_var->vc == vc_object);
+	pobject = pobj_var->u.object_v;
+#ifdef DEBUG_RUN_TRACE
+	printf("Get static object '%s' in '", strtab_get_str(name));
+	if (pobject->class_sym != NULL)
+		symbol_print_fqn(pobject->class_sym);
+	else
+		printf("global");
+#endif
+
+	assert(pobject->static_obj == sn_static);
+
+	mbr_var = intmap_get(&pobject->fields, name);
+	if (mbr_var != NULL) {
+#ifdef DEBUG_RUN_TRACE
+		printf("Return exising static object (mbr_var=%p).\n", mbr_var);
+#endif
+		/* Return existing object. */
+		return mbr_var;
+	}
+
+	/* Construct new object. */
+#ifdef DEBUG_RUN_TRACE
+	printf("Construct new static object.\n");
+#endif
+	ident = stree_ident_new();
+	ident->sid = name;
+
+	run_new_csi_inst(run, csi, sn_static, &rvar);
+
+	/* Store static object reference for future use. */
+	intmap_set(&pobject->fields, name, rvar);
+
+	return rvar;
+}
+
+/** Get static object for CSI.
+ *
+ * In situations where we do not have the parent static object and need
+ * to find static object for a CSI from the gdata root we use this.
+ *
+ * This is only used in special cases such as when invoking the entry
+ * point. This is too slow to use during normal execution.
+ *
+ * @param run		Runner object
+ * @param csi		CSI to get static object of
+ *
+ * @return		Static (class) object
+ */
+rdata_var_t *run_sobject_find(run_t *run, stree_csi_t *csi)
+{
+	rdata_var_t *pobj_var;
+
+	if (csi == NULL)
+		return run->gdata;
+
+	assert(csi->ancr_state == ws_visited);
+	pobj_var = run_sobject_find(run, csi_to_symbol(csi)->outer_csi);
+
+	return run_sobject_get(run, csi, pobj_var, csi->name->sid);
+}
+
+/** Get static object for CSI containing function.
+ *
+ * This is used to obtain active object for invoking static function
+ * @a fun. Only used in cases where we don't already have the object such
+ * as when running the entry point. Otherwise this would be slow.
+ *
+ * @param run		Runner object
+ * @param fun		Function to get static class object of
+ *
+ * @return		Static (class) object
+ */
+rdata_var_t *run_fun_sobject_find(run_t *run, stree_fun_t *fun)
+{
+	return run_sobject_find(run, fun_to_symbol(fun)->outer_csi);
 }
 
@@ -1512,5 +1633,5 @@
 
 	/* Create exception object. */
-	run_new_csi_inst(run, csi, &exc_vi);
+	run_new_csi_inst_ref(run, csi, sn_nonstatic, &exc_vi);
 	assert(exc_vi->ic == ic_value);
 
Index: uspace/app/sbi/src/run.h
===================================================================
--- uspace/app/sbi/src/run.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/app/sbi/src/run.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -33,4 +33,5 @@
 
 void run_init(run_t *run);
+void run_gdata_init(run_t *run);
 void run_program(run_t *run, stree_program_t *prog);
 void run_proc(run_t *run, run_proc_ar_t *proc_ar, rdata_item_t **res);
@@ -47,4 +48,9 @@
 run_block_ar_t *run_get_current_block_ar(run_t *run);
 stree_csi_t *run_get_current_csi(run_t *run);
+
+rdata_var_t *run_sobject_get(run_t *run, stree_csi_t *pcsi,
+    rdata_var_t *pobj_var, sid_t name);
+rdata_var_t *run_sobject_find(run_t *run, stree_csi_t *csi);
+rdata_var_t *run_fun_sobject_find(run_t *run, stree_fun_t *fun);
 
 void run_value_item_to_var(rdata_item_t *item, rdata_var_t **var);
Index: uspace/app/sbi/src/run_expr.c
===================================================================
--- uspace/app/sbi/src/run_expr.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/app/sbi/src/run_expr.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -104,4 +104,8 @@
 static void run_access_object(run_t *run, stree_access_t *access,
     rdata_item_t *arg, rdata_item_t **res);
+static void run_access_object_static(run_t *run, stree_access_t *access,
+    rdata_var_t *obj_var, rdata_item_t **res);
+static void run_access_object_nonstatic(run_t *run, stree_access_t *access,
+    rdata_var_t *obj_var, rdata_item_t **res);
 static void run_access_symbol(run_t *run, stree_access_t *access,
     rdata_item_t *arg, rdata_item_t **res);
@@ -207,4 +211,8 @@
 	rdata_var_t *member_var;
 
+	rdata_var_t *psobj;
+	rdata_var_t *sobj;
+	rdata_object_t *aobj;
+
 #ifdef DEBUG_RUN_TRACE
 	printf("Run nameref.\n");
@@ -238,13 +246,16 @@
 	/* Determine currently active object or CSI. */
 	proc_ar = run_get_current_proc_ar(run);
-	if (proc_ar->obj != NULL) {
-		assert(proc_ar->obj->vc == vc_object);
-		obj = proc_ar->obj->u.object_v;
-		csi_sym = obj->class_sym;
+
+	assert (proc_ar->obj != NULL);
+	assert(proc_ar->obj->vc == vc_object);
+	obj = proc_ar->obj->u.object_v;
+	csi_sym = obj->class_sym;
+
+	if (csi_sym != NULL) {
 		csi = symbol_to_csi(csi_sym);
 		assert(csi != NULL);
 	} else {
-		csi = proc_ar->proc->outer_symbol->outer_csi;
-		obj = NULL;
+		/* This happens in interactive mode. */
+		csi = NULL;
 	}
 
@@ -259,16 +270,11 @@
 		printf("Referencing CSI.\n");
 #endif
-		item = rdata_item_new(ic_value);
-		value = rdata_value_new();
-		var = rdata_var_new(vc_deleg);
-		deleg_v = rdata_deleg_new();
-
-		item->u.value = value;
-		value->var = var;
-		var->u.deleg_v = deleg_v;
-
-		deleg_v->obj = NULL;
-		deleg_v->sym = sym;
-		*res = item;
+		/* Obtain static object for the referenced CSI. */
+		psobj = run->gdata; /* XXX */
+		sobj = run_sobject_get(run, sym->u.csi, psobj,
+		    nameref->name->sid);
+
+		/* Return reference to the object. */
+		run_reference(run, sobj, res);
 		break;
 	case sc_ctor:
@@ -334,9 +340,6 @@
 		assert(csi != NULL);
 
-		/* XXX Assume variable is not static for now. */
-		assert(obj != NULL);
-
 		if (symbol_search_csi(run->program, csi, nameref->name)
-		    == NULL) {
+		    == NULL && !stree_symbol_is_static(sym)) {
 			/* Variable is not in the current object. */
 			printf("Error: Cannot access non-static member "
@@ -349,6 +352,22 @@
 		}
 
+		if (stree_symbol_is_static(sym)) {
+			/*
+			 * XXX This is too slow!
+			 *
+			 * However fixing this is non-trivial. We would
+			 * have to have pointer to static object available
+			 * for each object (therefore also for each object
+			 * type).
+			 */
+			sobj = run_sobject_find(run, sym->outer_csi);
+			assert(sobj->vc == vc_object);
+			aobj = sobj->u.object_v;
+		} else {
+			aobj = obj;
+		}
+
 		/* Find member variable in object. */
-		member_var = intmap_get(&obj->fields, nameref->name->sid);
+		member_var = intmap_get(&aobj->fields, nameref->name->sid);
 		assert(member_var != NULL);
 
@@ -1361,5 +1380,5 @@
 
 	/* Create CSI instance. */
-	run_new_csi_inst(run, csi, res);
+	run_new_csi_inst_ref(run, csi, sn_nonstatic, res);
 
 	/* Run the constructor. */
@@ -1467,5 +1486,5 @@
 }
 
-/** Evaluate delegate-member acccess.
+/** Evaluate delegate member acccess.
  *
  * @param run		Runner object
@@ -1477,41 +1496,11 @@
     rdata_item_t *arg, rdata_item_t **res)
 {
-	rdata_item_t *arg_vi;
-	rdata_value_t *arg_val;
-	rdata_deleg_t *deleg_v;
-	stree_symbol_t *member;
-
-#ifdef DEBUG_RUN_TRACE
-	printf("Run delegate access operation.\n");
-#endif
-	run_cvt_value_item(run, arg, &arg_vi);
-	arg_val = arg_vi->u.value;
-	assert(arg_val->var->vc == vc_deleg);
-
-	deleg_v = arg_val->var->u.deleg_v;
-	if (deleg_v->obj != NULL || deleg_v->sym->sc != sc_csi) {
-		printf("Error: Using '.' with delegate to different object "
-		    "than a CSI (%d).\n", deleg_v->sym->sc);
-		exit(1);
-	}
-
-	member = symbol_search_csi(run->program, deleg_v->sym->u.csi,
-	    access->member_name);
-
-	/* Member existence should be ensured by static type checking. */
-	assert(member != NULL);
-
-#ifdef DEBUG_RUN_TRACE
-	printf("Found member '%s'.\n",
-	    strtab_get_str(access->member_name->sid));
-#endif
-
-	/*
-	 * Reuse existing item, value, var, deleg.
-	 * XXX This is maybe not a good idea because it complicates memory
-	 * management as there is not a single owner 
-	 */
-	deleg_v->sym = member;
-	*res = arg;
+	(void) run;
+	(void) access;
+	(void) arg;
+	(void) res;
+
+	printf("Error: Using '.' with delegate.\n");
+	exit(1);
 }
 
@@ -1526,8 +1515,42 @@
     rdata_item_t *arg, rdata_item_t **res)
 {
+	rdata_var_t *obj_var;
+	rdata_object_t *object;
+
+#ifdef DEBUG_RUN_TRACE
+	printf("Run object access operation.\n");
+#endif
+	assert(arg->ic == ic_address);
+	assert(arg->u.address->ac == ac_var);
+
+	obj_var = arg->u.address->u.var_a->vref;
+	assert(obj_var->vc == vc_object);
+
+	object = obj_var->u.object_v;
+
+	if (object->static_obj == sn_static)
+		run_access_object_static(run, access, obj_var, res);
+	else
+		run_access_object_nonstatic(run, access, obj_var, res);
+}
+
+/** Evaluate static object member acccess.
+ *
+ * @param run		Runner object
+ * @param access	Access operation
+ * @param arg		Evaluated base expression
+ * @param res		Place to store result
+ */
+static void run_access_object_static(run_t *run, stree_access_t *access,
+    rdata_var_t *obj_var, rdata_item_t **res)
+{
+	rdata_object_t *object;
 	stree_symbol_t *member;
-	rdata_var_t *object_var;
-	rdata_object_t *object;
+	stree_csi_t *member_csi;
+
+	rdata_deleg_t *deleg_v;
 	rdata_item_t *ritem;
+	rdata_value_t *rvalue;
+	rdata_var_t *rvar;
 	rdata_address_t *address;
 	rdata_addr_var_t *addr_var;
@@ -1535,29 +1558,19 @@
 	rdata_aprop_named_t *aprop_named;
 	rdata_deleg_t *deleg_p;
-
-	rdata_value_t *value;
-	rdata_deleg_t *deleg_v;
-	rdata_var_t *var;
-
-#ifdef DEBUG_RUN_TRACE
-	printf("Run object access operation.\n");
-#endif
-	assert(arg->ic == ic_address);
-	assert(arg->u.address->ac == ac_var);
-	assert(arg->u.address->u.var_a->vref->vc == vc_object);
-
-	object_var = arg->u.address->u.var_a->vref;
-	object = object_var->u.object_v;
+	rdata_var_t *mvar;
+
+#ifdef DEBUG_RUN_TRACE
+	printf("Run static object access operation.\n");
+#endif
+	assert(obj_var->vc == vc_object);
+	object = obj_var->u.object_v;
+
+	assert(object->static_obj == sn_static);
 
 	member = symbol_search_csi(run->program, object->class_sym->u.csi,
 	    access->member_name);
 
-	if (member == NULL) {
-		printf("Error: Object of class '");
-		symbol_print_fqn(object->class_sym);
-		printf("' has no member named '%s'.\n",
-		    strtab_get_str(access->member_name->sid));
-		exit(1);
-	}
+	/* Member existence should be ensured by static type checking. */
+	assert(member != NULL);
 
 #ifdef DEBUG_RUN_TRACE
@@ -1566,11 +1579,26 @@
 #endif
 
-	/* Make compiler happy. */
-	ritem = NULL;
-
 	switch (member->sc) {
 	case sc_csi:
-		printf("Error: Accessing object member which is nested CSI.\n");
-		exit(1);
+		/* Get child static object. */
+		member_csi = symbol_to_csi(member);
+		assert(member_csi != NULL);
+
+		mvar = run_sobject_get(run, member_csi, obj_var,
+		    access->member_name->sid);
+
+		ritem = rdata_item_new(ic_address);
+		address = rdata_address_new(ac_var);
+		ritem->u.address = address;
+
+		addr_var = rdata_addr_var_new();
+		address->u.var_a = addr_var;
+		addr_var->vref = mvar;
+
+		*res = ritem;
+		break;
+	case sc_ctor:
+		/* It is not possible to reference a constructor explicitly. */
+		assert(b_false);
 	case sc_deleg:
 		printf("Error: Accessing object member which is a delegate.\n");
@@ -1579,32 +1607,33 @@
 		printf("Error: Accessing object member which is an enum.\n");
 		exit(1);
-	case sc_ctor:
-		/* It is not possible to reference a constructor explicitly. */
-		assert(b_false);
 	case sc_fun:
 		/* Construct anonymous delegate. */
 		ritem = rdata_item_new(ic_value);
-		value = rdata_value_new();
-		ritem->u.value = value;
-
-		var = rdata_var_new(vc_deleg);
-		value->var = var;
+		rvalue = rdata_value_new();
+		ritem->u.value = rvalue;
+
+		rvar = rdata_var_new(vc_deleg);
+		rvalue->var = rvar;
+
 		deleg_v = rdata_deleg_new();
-		var->u.deleg_v = deleg_v;
-
-		deleg_v->obj = arg->u.address->u.var_a->vref;
+		rvar->u.deleg_v = deleg_v;
+
+		deleg_v->obj = obj_var;
 		deleg_v->sym = member;
+		*res = ritem;
 		break;
 	case sc_var:
-		/* Construct variable address item. */
+		/* Get static object member variable. */
+		mvar = intmap_get(&object->fields, access->member_name->sid);
+
 		ritem = rdata_item_new(ic_address);
 		address = rdata_address_new(ac_var);
+		ritem->u.address = address;
+
 		addr_var = rdata_addr_var_new();
-		ritem->u.address = address;
 		address->u.var_a = addr_var;
-
-		addr_var->vref = intmap_get(&object->fields,
-		    access->member_name->sid);
-		assert(addr_var->vref != NULL);
+		addr_var->vref = mvar;
+
+		*res = ritem;
 		break;
 	case sc_prop:
@@ -1619,5 +1648,114 @@
 
 		deleg_p = rdata_deleg_new();
-		deleg_p->obj = object_var;
+		deleg_p->obj = obj_var;
+		deleg_p->sym = member;
+		addr_prop->u.named->prop_d = deleg_p;
+
+		*res = ritem;
+		break;
+	}
+}
+
+/** Evaluate object member acccess.
+ *
+ * @param run		Runner object
+ * @param access	Access operation
+ * @param arg		Evaluated base expression
+ * @param res		Place to store result
+ */
+static void run_access_object_nonstatic(run_t *run, stree_access_t *access,
+    rdata_var_t *obj_var, rdata_item_t **res)
+{
+	rdata_object_t *object;
+	stree_symbol_t *member;
+	rdata_item_t *ritem;
+	rdata_address_t *address;
+	rdata_addr_var_t *addr_var;
+	rdata_addr_prop_t *addr_prop;
+	rdata_aprop_named_t *aprop_named;
+	rdata_deleg_t *deleg_p;
+
+	rdata_value_t *value;
+	rdata_deleg_t *deleg_v;
+	rdata_var_t *var;
+
+#ifdef DEBUG_RUN_TRACE
+	printf("Run nonstatic object access operation.\n");
+#endif
+	assert(obj_var->vc == vc_object);
+	object = obj_var->u.object_v;
+
+	assert(object->static_obj == sn_nonstatic);
+
+	member = symbol_search_csi(run->program, object->class_sym->u.csi,
+	    access->member_name);
+
+	if (member == NULL) {
+		printf("Error: Object of class '");
+		symbol_print_fqn(object->class_sym);
+		printf("' has no member named '%s'.\n",
+		    strtab_get_str(access->member_name->sid));
+		exit(1);
+	}
+
+#ifdef DEBUG_RUN_TRACE
+	printf("Found member '%s'.\n",
+	    strtab_get_str(access->member_name->sid));
+#endif
+
+	/* Make compiler happy. */
+	ritem = NULL;
+
+	switch (member->sc) {
+	case sc_csi:
+		printf("Error: Accessing object member which is nested CSI.\n");
+		exit(1);
+	case sc_ctor:
+		/* It is not possible to reference a constructor explicitly. */
+		assert(b_false);
+	case sc_deleg:
+		printf("Error: Accessing object member which is a delegate.\n");
+		exit(1);
+	case sc_enum:
+		printf("Error: Accessing object member which is an enum.\n");
+		exit(1);
+	case sc_fun:
+		/* Construct anonymous delegate. */
+		ritem = rdata_item_new(ic_value);
+		value = rdata_value_new();
+		ritem->u.value = value;
+
+		var = rdata_var_new(vc_deleg);
+		value->var = var;
+		deleg_v = rdata_deleg_new();
+		var->u.deleg_v = deleg_v;
+
+		deleg_v->obj = obj_var;
+		deleg_v->sym = member;
+		break;
+	case sc_var:
+		/* Construct variable address item. */
+		ritem = rdata_item_new(ic_address);
+		address = rdata_address_new(ac_var);
+		addr_var = rdata_addr_var_new();
+		ritem->u.address = address;
+		address->u.var_a = addr_var;
+
+		addr_var->vref = intmap_get(&object->fields,
+		    access->member_name->sid);
+		assert(addr_var->vref != NULL);
+		break;
+	case sc_prop:
+		/* Construct named property address. */
+		ritem = rdata_item_new(ic_address);
+		address = rdata_address_new(ac_prop);
+		addr_prop = rdata_addr_prop_new(apc_named);
+		aprop_named = rdata_aprop_named_new();
+		ritem->u.address = address;
+		address->u.prop_a = addr_prop;
+		addr_prop->u.named = aprop_named;
+
+		deleg_p = rdata_deleg_new();
+		deleg_p->obj = obj_var;
 		deleg_p->sym = member;
 		addr_prop->u.named->prop_d = deleg_p;
@@ -2168,5 +2306,4 @@
 	rdata_item_t *rdest_i, *rsrc_i;
 	rdata_item_t *rsrc_vi;
-	rdata_value_t *src_val;
 
 #ifdef DEBUG_RUN_TRACE
@@ -2187,5 +2324,4 @@
 	run_cvt_value_item(run, rsrc_i, &rsrc_vi);
 	assert(rsrc_vi->ic == ic_value);
-	src_val = rsrc_vi->u.value;
 
 	if (rdest_i->ic != ic_address) {
@@ -2331,5 +2467,5 @@
 
 	/* Construct object of the relevant boxed type. */
-	run_new_csi_inst(run, csi, res);
+	run_new_csi_inst_ref(run, csi, sn_nonstatic, res);
 
 	/* Set the 'Value' field */
@@ -2348,5 +2484,5 @@
 }
 
-/** Create new CSI instance.
+/** Create new CSI instance and return reference to it.
  *
  * Create a new object, instance of @a csi.
@@ -2357,9 +2493,47 @@
  * run any constructor.
  *
- * @param run		Runner object
- * @param as_op		@c as conversion expression
- * @param res		Place to store result
- */
-void run_new_csi_inst(run_t *run, stree_csi_t *csi, rdata_item_t **res)
+ * If @a sn is @c sn_nonstatic a regular object is created, containing all
+ * non-static member variables. If @a sn is @c sn_static a static object
+ * is created, containing all static member variables.
+ *
+ * @param run		Runner object
+ * @param csi		CSI to create instance of
+ * @param sn		@c sn_static to create a static (class) object,
+ *			@c sn_nonstatic to create a regular object
+ * @param res		Place to store result
+ */
+void run_new_csi_inst_ref(run_t *run, stree_csi_t *csi, statns_t sn,
+    rdata_item_t **res)
+{
+	rdata_var_t *obj_var;
+
+	/* Create object. */
+	run_new_csi_inst(run, csi, sn, &obj_var);
+
+	/* Create reference to the new object. */
+	run_reference(run, obj_var, res);
+}
+
+/** Create new CSI instance.
+ *
+ * Create a new object, instance of @a csi.
+ * XXX This does not work with generics as @a csi cannot specify a generic
+ * type.
+ *
+ * Initialize the fields with default values of their types, but do not
+ * run any constructor.
+ *
+ * If @a sn is @c sn_nonstatic a regular object is created, containing all
+ * non-static member variables. If @a sn is @c sn_static a static object
+ * is created, containing all static member variables.
+ *
+ * @param run		Runner object
+ * @param csi		CSI to create instance of
+ * @param sn		@c sn_static to create a static (class) object,
+ *			@c sn_nonstatic to create a regular object
+ * @param res		Place to store result
+ */
+void run_new_csi_inst(run_t *run, stree_csi_t *csi, statns_t sn,
+    rdata_var_t **res)
 {
 	rdata_object_t *obj;
@@ -2368,4 +2542,6 @@
 	stree_symbol_t *csi_sym;
 	stree_csimbr_t *csimbr;
+	stree_var_t *var;
+	statns_t var_sn;
 
 	rdata_var_t *mbr_var;
@@ -2384,4 +2560,5 @@
 	obj = rdata_object_new();
 	obj->class_sym = csi_sym;
+	obj->static_obj = sn;
 	intmap_init(&obj->fields);
 
@@ -2389,22 +2566,31 @@
 	obj_var->u.object_v = obj;
 
-	/* Create object fields. */
+	/* For this CSI and all base CSIs */
 	while (csi != NULL) {
+
+		/* For all members */
 		node = list_first(&csi->members);
 		while (node != NULL) {
 			csimbr = list_node_data(node, stree_csimbr_t *);
+
+			/* Is it a member variable? */
 			if (csimbr->cc == csimbr_var) {
-				/* Compute field type. XXX Memoize. */
-				run_texpr(run->program, csi,
-				    csimbr->u.var->type,
-				    &field_ti);
-
-				/* Create and initialize field. */
-				run_var_new(run, field_ti, &mbr_var);
-
-				/* Add to field map. */
-				intmap_set(&obj->fields,
-				    csimbr->u.var->name->sid,
-				    mbr_var);
+				var = csimbr->u.var;
+
+				/* Is it static/nonstatic? */
+				var_sn = stree_symbol_has_attr(
+				    var_to_symbol(var), sac_static);
+				if (var_sn == sn) {
+					/* Compute field type. XXX Memoize. */
+					run_texpr(run->program, csi, var->type,
+					    &field_ti);
+
+					/* Create and initialize field. */
+					run_var_new(run, field_ti, &mbr_var);
+
+					/* Add to field map. */
+					intmap_set(&obj->fields, var->name->sid,
+					    mbr_var);
+				}
 			}
 
@@ -2416,6 +2602,5 @@
 	}
 
-	/* Create reference to the new object. */
-	run_reference(run, obj_var, res);
+	*res = obj_var;
 }
 
Index: uspace/app/sbi/src/run_expr.h
===================================================================
--- uspace/app/sbi/src/run_expr.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/app/sbi/src/run_expr.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -34,5 +34,9 @@
 void run_expr(run_t *run, stree_expr_t *expr, rdata_item_t **res);
 
-void run_new_csi_inst(run_t *run, stree_csi_t *csi, rdata_item_t **res);
+void run_new_csi_inst_ref(run_t *run, stree_csi_t *csi, statns_t sn,
+    rdata_item_t **res);
+void run_new_csi_inst(run_t *run, stree_csi_t *csi, statns_t sn,
+    rdata_var_t **res);
+
 bool_t run_item_boolean_value(run_t *run, rdata_item_t *item);
 
Index: uspace/app/sbi/src/run_t.h
===================================================================
--- uspace/app/sbi/src/run_t.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/app/sbi/src/run_t.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -114,4 +114,7 @@
 	/** Thread-private state */
 	run_thread_ar_t *thread_ar;
+
+	/** Global state */
+	struct rdata_var *gdata;
 } run_t;
 
Index: uspace/app/sbi/src/run_texpr.c
===================================================================
--- uspace/app/sbi/src/run_texpr.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/app/sbi/src/run_texpr.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -140,4 +140,7 @@
 	}
 
+	/* Make compiler happy. */
+	titem = NULL;
+
 	switch (sym->sc) {
 	case sc_csi:
@@ -147,5 +150,5 @@
 		titem->u.tobject = tobject;
 
-		tobject->static_ref = b_false;
+		tobject->static_ref = sn_nonstatic;
 		tobject->csi = sym->u.csi;
 		list_init(&tobject->targs);
@@ -278,4 +281,7 @@
 	(void) tliteral;
 
+	/* Make compiler happy. */
+	tpc = 0;
+
 	switch (tliteral->tlc) {
 	case tlc_bool: tpc = tpc_bool; break;
@@ -342,4 +348,7 @@
 	}
 
+	/* Make compiler happy. */
+	titem = NULL;
+
 	switch (sym->sc) {
 	case sc_csi:
@@ -349,5 +358,5 @@
 		titem->u.tobject = tobject;
 
-		tobject->static_ref = b_false;
+		tobject->static_ref = sn_nonstatic;
 		tobject->csi = sym->u.csi;
 		list_init(&tobject->targs);
@@ -429,5 +438,4 @@
 
 	list_node_t *farg_n;
-	stree_targ_t *farg;
 
 #ifdef DEBUG_RUN_TRACE
@@ -450,5 +458,5 @@
 	}
 
-	tobject->static_ref = b_false;
+	tobject->static_ref = sn_nonstatic;
 	tobject->csi = base_ti->u.tobject->csi;
 	list_init(&tobject->targs);
@@ -458,5 +466,4 @@
 	arg_n = list_first(&tapply->targs);
 	while (farg_n != NULL && arg_n != NULL) {
-		farg = list_node_data(farg_n, stree_targ_t *);
 		arg = list_node_data(arg_n, stree_texpr_t *);
 
Index: uspace/app/sbi/src/stree.c
===================================================================
--- uspace/app/sbi/src/stree.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/app/sbi/src/stree.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -92,6 +92,9 @@
 	csi->ancr_state = ws_unvisited;
 	csi->name = NULL;
-	csi->base_csi_ref = NULL;
+	csi->base_csi = NULL;
+	list_init(&csi->inherit);
+	list_init(&csi->impl_if_ti);
 	list_init(&csi->members);
+
 	return csi;
 }
@@ -930,4 +933,6 @@
 
 	symbol->sc = sc;
+	list_init(&symbol->attr);
+
 	return symbol;
 }
@@ -1018,4 +1023,34 @@
 
 	/* We went all the way to the root and did not find b. */
+	return b_false;
+}
+
+/** Determine if @a symbol is static.
+ *
+ * @param symbol	Symbol
+ * @return		@c b_true if symbol is static, @c b_false otherwise
+ */
+bool_t stree_symbol_is_static(stree_symbol_t *symbol)
+{
+	/* Module-wide symbols are static. */
+	if (symbol->outer_csi == NULL)
+		return b_true;
+
+	/* Symbols with @c static attribute are static. */
+	if (stree_symbol_has_attr(symbol, sac_static))
+		return b_true;
+
+	switch (symbol->sc) {
+	case sc_csi:
+	case sc_deleg:
+	case sc_enum:
+		return b_true;
+	case sc_ctor:
+	case sc_fun:
+	case sc_var:
+	case sc_prop:
+		break;
+	}
+
 	return b_false;
 }
Index: uspace/app/sbi/src/stree.h
===================================================================
--- uspace/app/sbi/src/stree.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/app/sbi/src/stree.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -96,4 +96,5 @@
 bool_t stree_arg_has_attr(stree_proc_arg_t *arg, arg_attr_class_t aac);
 bool_t stree_is_csi_derived_from_csi(stree_csi_t *a, stree_csi_t *b);
+bool_t stree_symbol_is_static(stree_symbol_t *symbol);
 stree_targ_t *stree_csi_find_targ(stree_csi_t *csi, stree_ident_t *ident);
 stree_embr_t *stree_enum_find_mbr(stree_enum_t *enum_d, stree_ident_t *ident);
Index: uspace/app/sbi/src/stree_t.h
===================================================================
--- uspace/app/sbi/src/stree_t.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/app/sbi/src/stree_t.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -639,4 +639,7 @@
 	/** Variadic argument or @c NULL if none. */
 	stree_proc_arg_t *varg;
+
+	/** Type of the property */
+	struct tdata_item *titem;
 } stree_prop_t;
 
@@ -698,9 +701,12 @@
 	struct stree_symbol *symbol;
 
-	/** Type expression referencing base CSI. */
-	stree_texpr_t *base_csi_ref;
+	/** Type expressions referencing inherited CSIs. */
+	list_t inherit; /* of stree_texpr_t */
 
 	/** Base CSI. Only available when ancr_state == ws_visited. */
 	struct stree_csi *base_csi;
+
+	/** Types of implemented or accumulated interfaces. */
+	list_t impl_if_ti; /* of tdata_item_t */
 
 	/** Node state for ancr walks. */
@@ -736,5 +742,8 @@
 typedef enum {
 	/** Builtin symbol (interpreter hook) */
-	sac_builtin
+	sac_builtin,
+
+	/** Static symbol */
+	sac_static
 } symbol_attr_class_t;
 
Index: uspace/app/sbi/src/stype.c
===================================================================
--- uspace/app/sbi/src/stype.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/app/sbi/src/stype.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -63,4 +63,14 @@
 static void stype_fun_body(stype_t *stype, stree_fun_t *fun);
 static void stype_block(stype_t *stype, stree_block_t *block);
+
+static void stype_class_impl_check(stype_t *stype, stree_csi_t *csi);
+static void stype_class_impl_check_if(stype_t *stype, stree_csi_t *csi,
+    tdata_item_t *iface_ti);
+static void stype_class_impl_check_mbr(stype_t *stype, stree_csi_t *csi,
+    tdata_tvv_t *if_tvv, stree_csimbr_t *ifmbr);
+static void stype_class_impl_check_fun(stype_t *stype,
+    stree_symbol_t *cfun_sym, tdata_tvv_t *if_tvv, stree_symbol_t *ifun_sym);
+static void stype_class_impl_check_prop(stype_t *stype,
+    stree_symbol_t *cprop_sym, tdata_tvv_t *if_tvv, stree_symbol_t *iprop_sym);
 
 static void stype_vdecl(stype_t *stype, stree_vdecl_t *vdecl_s);
@@ -90,6 +100,4 @@
 static stree_expr_t *stype_convert_tvref(stype_t *stype, stree_expr_t *expr,
     tdata_item_t *dest);
-static void stype_convert_failure(stype_t *stype, stree_expr_t *expr,
-    tdata_item_t *dest);
 
 static bool_t stype_fun_sig_equal(stype_t *stype, tdata_fun_sig_t *asig,
@@ -168,4 +176,7 @@
 	}
 
+	if (csi->cc == csi_class)
+		stype_class_impl_check(stype, csi);
+
 	stype->current_csi = prev_ctx;
 }
@@ -310,6 +321,4 @@
 
 		enum_d->titem = titem;
-	} else {
-		titem = enum_d->titem;
 	}
 }
@@ -453,5 +462,5 @@
 	assert(stype->proc_vr == NULL);
 
-	/* Builtin functions do not have a body. */
+	/* Declarations and builtin functions do not have a body. */
 	if (fun->proc->body == NULL)
 		return;
@@ -475,7 +484,4 @@
 {
 	tdata_item_t *titem;
-
-	(void) stype;
-	(void) var;
 
 	run_texpr(stype->program, stype->current_csi, var->type,
@@ -484,5 +490,4 @@
 		/* An error occured. */
 		stype_note_error(stype);
-		return;
 	}
 }
@@ -500,13 +505,18 @@
 	printf("'.\n");
 #endif
+	if (prop->titem == NULL)
+		stype_prop_header(stype, prop);
+
 	stype->proc_vr = stype_proc_vr_new();
 	list_init(&stype->proc_vr->block_vr);
 
-	if (prop->getter != NULL) {
+	/* Property declarations do not have a getter body. */
+	if (prop->getter != NULL && prop->getter->body != NULL) {
 		stype->proc_vr->proc = prop->getter;
 		stype_block(stype, prop->getter->body);
 	}
 
-	if (prop->setter != NULL) {
+	/* Property declarations do not have a setter body. */
+	if (prop->setter != NULL && prop->setter->body != NULL) {
 		stype->proc_vr->proc = prop->setter;
 		stype_block(stype, prop->setter->body);
@@ -515,4 +525,29 @@
 	free(stype->proc_vr);
 	stype->proc_vr = NULL;
+}
+
+/** Type property header.
+ *
+ * @param stype		Static typing object
+ * @param prop		Property
+ */
+void stype_prop_header(stype_t *stype, stree_prop_t *prop)
+{
+	tdata_item_t *titem;
+
+#ifdef DEBUG_TYPE_TRACE
+	printf("Type property '");
+	symbol_print_fqn(prop_to_symbol(prop));
+	printf("' header.\n");
+#endif
+	run_texpr(stype->program, stype->current_csi, prop->type,
+	    &titem);
+	if (titem->tic == tic_ignore) {
+		/* An error occured. */
+		stype_note_error(stype);
+		return;
+	}
+
+	prop->titem = titem;
 }
 
@@ -552,4 +587,286 @@
 	assert(list_node_data(bvr_n, stype_block_vr_t *) == block_vr);
 	list_remove(&stype->proc_vr->block_vr, bvr_n);
+}
+
+/** Verify that class fully implements all interfaces as it claims.
+ *
+ * @param stype		Static typing object
+ * @param csi		CSI to check
+ */
+static void stype_class_impl_check(stype_t *stype, stree_csi_t *csi)
+{
+	list_node_t *pred_n;
+	stree_texpr_t *pred_te;
+	tdata_item_t *pred_ti;
+
+#ifdef DEBUG_TYPE_TRACE
+	printf("Verify that class implements all interfaces.\n");
+#endif
+	assert(csi->cc == csi_class);
+
+	pred_n = list_first(&csi->inherit);
+	while (pred_n != NULL) {
+		pred_te = list_node_data(pred_n, stree_texpr_t *);
+		run_texpr(stype->program, csi, pred_te, &pred_ti);
+
+		assert(pred_ti->tic == tic_tobject);
+		switch (pred_ti->u.tobject->csi->cc) {
+		case csi_class:
+			break;
+		case csi_struct:
+			assert(b_false);
+		case csi_interface:
+			/* Store to impl_if_ti for later use. */
+			list_append(&csi->impl_if_ti, pred_ti);
+
+			/* Check implementation of this interface. */
+			stype_class_impl_check_if(stype, csi, pred_ti);
+			break;
+		}
+
+		pred_n = list_next(&csi->inherit, pred_n);
+	}
+}
+
+/** Verify that class fully implements an interface.
+ *
+ * @param stype		Static typing object
+ * @param csi		CSI to check
+ * @param iface		Interface that must be fully implemented
+ */
+static void stype_class_impl_check_if(stype_t *stype, stree_csi_t *csi,
+    tdata_item_t *iface_ti)
+{
+	tdata_tvv_t *iface_tvv;
+	list_node_t *pred_n;
+	tdata_item_t *pred_ti;
+	tdata_item_t *pred_sti;
+
+	stree_csi_t *iface;
+	list_node_t *ifmbr_n;
+	stree_csimbr_t *ifmbr;
+
+	assert(csi->cc == csi_class);
+
+	assert(iface_ti->tic == tic_tobject);
+	iface = iface_ti->u.tobject->csi;
+	assert(iface->cc = csi_interface);
+
+#ifdef DEBUG_TYPE_TRACE
+	printf("Verify that class fully implements interface.\n");
+#endif
+	/* Compute TVV for this interface reference. */
+	stype_titem_to_tvv(stype, iface_ti, &iface_tvv);
+
+	/*
+	 * Recurse to accumulated interfaces.
+	 */
+	pred_n = list_first(&iface->impl_if_ti);
+	while (pred_n != NULL) {
+		pred_ti = list_node_data(pred_n, tdata_item_t *);
+		assert(pred_ti->tic == tic_tobject);
+		assert(pred_ti->u.tobject->csi->cc == csi_interface);
+
+		/* Substitute real type parameters to predecessor reference. */
+		tdata_item_subst(pred_ti, iface_tvv, &pred_sti);
+
+		/* Check accumulated interface. */
+		stype_class_impl_check_if(stype, csi, pred_sti);
+
+		pred_n = list_next(&iface->impl_if_ti, pred_n);
+	}
+
+	/*
+	 * Check all interface members.
+	 */
+	ifmbr_n = list_first(&iface->members);
+	while (ifmbr_n != NULL) {
+		ifmbr = list_node_data(ifmbr_n, stree_csimbr_t *);
+		stype_class_impl_check_mbr(stype, csi, iface_tvv, ifmbr);
+
+		ifmbr_n = list_next(&iface->members, ifmbr_n);
+	}
+}
+
+/** Verify that class fully implements an interface member.
+ *
+ * @param stype		Static typing object
+ * @param csi		CSI to check
+ * @param if_tvv	TVV for @a ifmbr
+ * @param ifmbr		Interface that must be fully implemented
+ */
+static void stype_class_impl_check_mbr(stype_t *stype, stree_csi_t *csi,
+    tdata_tvv_t *if_tvv, stree_csimbr_t *ifmbr)
+{
+	stree_symbol_t *cmbr_sym;
+	stree_symbol_t *ifmbr_sym;
+	stree_ident_t *ifmbr_name;
+
+	assert(csi->cc == csi_class);
+
+#ifdef DEBUG_TYPE_TRACE
+	printf("Verify that class implements interface member.\n");
+#endif
+	ifmbr_name = stree_csimbr_get_name(ifmbr);
+
+	cmbr_sym = symbol_search_csi(stype->program, csi, ifmbr_name);
+	if (cmbr_sym == NULL) {
+		printf("Error: CSI '");
+		symbol_print_fqn(csi_to_symbol(csi));
+		printf("' should implement '");
+		symbol_print_fqn(csimbr_to_symbol(ifmbr));
+		printf("' but it does not.\n");
+		stype_note_error(stype);
+		return;
+	}
+
+	ifmbr_sym = csimbr_to_symbol(ifmbr);
+	if (cmbr_sym->sc != ifmbr_sym->sc) {
+		printf("Error: CSI '");
+		symbol_print_fqn(csi_to_symbol(csi));
+		printf("' implements '");
+		symbol_print_fqn(csimbr_to_symbol(ifmbr));
+		printf("' as a different kind of symbol.\n");
+		stype_note_error(stype);
+	}
+
+	switch (cmbr_sym->sc) {
+	case sc_csi:
+	case sc_ctor:
+	case sc_deleg:
+	case sc_enum:
+		/*
+		 * Checked at parse time. Interface should not have these
+		 * member types.
+		 */
+		assert(b_false);
+	case sc_fun:
+		stype_class_impl_check_fun(stype, cmbr_sym, if_tvv, ifmbr_sym);
+		break;
+	case sc_var:
+		/*
+		 * Checked at parse time. Interface should not have these
+		 * member types.
+		 */
+		assert(b_false);
+	case sc_prop:
+		stype_class_impl_check_prop(stype, cmbr_sym, if_tvv, ifmbr_sym);
+		break;
+	}
+}
+
+/** Verify that class properly implements a function from an interface.
+ *
+ * @param stype		Static typing object
+ * @param cfun_sym	Function symbol in class
+ * @param if_tvv	TVV for @a ifun_sym
+ * @param ifun_sym	Function declaration symbol in interface
+ */
+static void stype_class_impl_check_fun(stype_t *stype,
+    stree_symbol_t *cfun_sym, tdata_tvv_t *if_tvv, stree_symbol_t *ifun_sym)
+{
+	stree_fun_t *cfun;
+	tdata_fun_t *tcfun;
+	stree_fun_t *ifun;
+	tdata_item_t *sifun_ti;
+	tdata_fun_t *tifun;
+
+#ifdef DEBUG_TYPE_TRACE
+	printf("Verify that class '");
+	symbol_print_fqn(csi_to_symbol(cfun_sym->outer_csi));
+	printf("' implements function '");
+	symbol_print_fqn(ifun_sym);
+	printf("' properly.\n");
+#endif
+	assert(cfun_sym->sc == sc_fun);
+	cfun = cfun_sym->u.fun;
+
+	assert(ifun_sym->sc == sc_fun);
+	ifun = ifun_sym->u.fun;
+
+	assert(cfun->titem->tic == tic_tfun);
+	tcfun = cfun->titem->u.tfun;
+
+	tdata_item_subst(ifun->titem, if_tvv, &sifun_ti);
+	assert(sifun_ti->tic == tic_tfun);
+	tifun = sifun_ti->u.tfun;
+
+	if (!stype_fun_sig_equal(stype, tcfun->tsig, tifun->tsig)) {
+		cspan_print(cfun->name->cspan);
+		printf(" Error: Type of function '");
+		symbol_print_fqn(cfun_sym);
+		printf("' (");
+		tdata_item_print(cfun->titem);
+		printf(") does not match type of '");
+		symbol_print_fqn(ifun_sym);
+		printf("' (");
+		tdata_item_print(sifun_ti);
+		printf(") which it should implement.\n");
+		stype_note_error(stype);
+	}
+}
+
+/** Verify that class properly implements a function from an interface.
+ *
+ * @param stype		Static typing object
+ * @param cprop_sym	Property symbol in class
+ * @param if_tvv	TVV for @a ifun_sym
+ * @param iprop_sym	Property declaration symbol in interface
+ */
+static void stype_class_impl_check_prop(stype_t *stype,
+    stree_symbol_t *cprop_sym, tdata_tvv_t *if_tvv, stree_symbol_t *iprop_sym)
+{
+	stree_prop_t *cprop;
+	stree_prop_t *iprop;
+	tdata_item_t *siprop_ti;
+
+#ifdef DEBUG_TYPE_TRACE
+	printf("Verify that class '");
+	symbol_print_fqn(csi_to_symbol(cprop_sym->outer_csi));
+	printf("' implements property '");
+	symbol_print_fqn(iprop_sym);
+	printf("' properly.\n");
+#endif
+	assert(cprop_sym->sc == sc_prop);
+	cprop = cprop_sym->u.prop;
+
+	assert(iprop_sym->sc == sc_prop);
+	iprop = iprop_sym->u.prop;
+
+	tdata_item_subst(iprop->titem, if_tvv, &siprop_ti);
+
+	if (!tdata_item_equal(cprop->titem, siprop_ti)) {
+		cspan_print(cprop->name->cspan);
+		printf(" Error: Type of property '");
+		symbol_print_fqn(cprop_sym);
+		printf("' (");
+		tdata_item_print(cprop->titem);
+		printf(") does not match type of '");
+		symbol_print_fqn(iprop_sym);
+		printf("' (");
+		tdata_item_print(siprop_ti);
+		printf(") which it should implement.\n");
+		stype_note_error(stype);
+	}
+
+	if (iprop->getter != NULL && cprop->getter == NULL) {
+		cspan_print(cprop->name->cspan);
+		printf(" Error: Property '");
+		symbol_print_fqn(cprop_sym);
+		printf("' is missing a getter, which is required by '");
+		symbol_print_fqn(iprop_sym);
+		printf("'.\n");
+		stype_note_error(stype);
+	}
+
+	if (iprop->setter != NULL && cprop->setter == NULL) {
+		cspan_print(cprop->name->cspan);
+		printf(" Error: Property '");
+		symbol_print_fqn(cprop_sym);
+		printf("' is missing a setter, which is required by '");
+		symbol_print_fqn(iprop_sym);
+		printf("'.\n");
+		stype_note_error(stype);
+	}
 }
 
@@ -824,6 +1141,8 @@
 	stype_expr(stype, exp_s->expr);
 
-	if (want_value == b_false && exp_s->expr->titem != NULL)
-		printf("Warning: Expression value ignored.\n");
+	if (want_value == b_false && exp_s->expr->titem != NULL) {
+		cspan_print(exp_s->expr->cspan);
+		printf(" Warning: Expression value ignored.\n");
+	}
 }
 
@@ -925,5 +1244,5 @@
 
 	if (src->tic == tic_tebase) {
-		stype_convert_failure(stype, expr, dest);
+		stype_convert_failure(stype, convc_implicit, expr, dest);
 		printf("Invalid use of reference to enum type in "
 		    "expression.\n");
@@ -932,5 +1251,5 @@
 
 	if (src->tic != dest->tic) {
-		stype_convert_failure(stype, expr, dest);
+		stype_convert_failure(stype, convc_implicit, expr, dest);
 		return expr;
 	}
@@ -987,5 +1306,5 @@
 	/* Check if both have the same tprimitive class. */
 	if (src->u.tprimitive->tpc != dest->u.tprimitive->tpc)
-		stype_convert_failure(stype, expr, dest);
+		stype_convert_failure(stype, convc_implicit, expr, dest);
 
 	return expr;
@@ -1020,4 +1339,7 @@
 	bi = stype->program->builtin;
 	csi_sym = csi_to_symbol(dest->u.tobject->csi);
+
+	/* Make compiler happy. */
+	bp_sym = NULL;
 
 	switch (src->u.tprimitive->tpc) {
@@ -1028,5 +1350,5 @@
 	case tpc_string: bp_sym = bi->boxed_string; break;
 	case tpc_resource:
-		stype_convert_failure(stype, expr, dest);
+		stype_convert_failure(stype, convc_implicit, expr, dest);
 		return expr;
 	}
@@ -1034,5 +1356,5 @@
 	/* Target type must be boxed @a src or Object */
 	if (csi_sym != bp_sym && csi_sym != bi->gf_class)
-		stype_convert_failure(stype, expr, dest);
+		stype_convert_failure(stype, convc_implicit, expr, dest);
 
 	/* Patch the code to box the primitive value */
@@ -1058,80 +1380,31 @@
 {
 	tdata_item_t *src;
-	tdata_item_t *cur;
-	stree_csi_t *cur_csi;
-	tdata_tvv_t *tvv;
-	tdata_item_t *b_ti, *bs_ti;
+	tdata_item_t *pred_ti;
 
 #ifdef DEBUG_TYPE_TRACE
 	printf("Convert object type.\n");
 #endif
-	list_node_t *ca_n, *da_n;
-	tdata_item_t *carg, *darg;
-
 	src = expr->titem;
 	assert(src->tic == tic_tobject);
 	assert(dest->tic == tic_tobject);
 
-	cur = src;
-
-	while (cur->u.tobject->csi != dest->u.tobject->csi) {
-
-		cur_csi = cur->u.tobject->csi;
-		stype_titem_to_tvv(stype, cur, &tvv);
-
-		if (cur_csi->base_csi_ref != NULL) {
-			run_texpr(stype->program, cur_csi, cur_csi->base_csi_ref, &b_ti);
-			if (b_ti->tic == tic_ignore) {
-				/* An error occured. */
-				stype_note_error(stype);
-				return expr;
-			}
-
-			tdata_item_subst(b_ti, tvv, &bs_ti);
-			cur = bs_ti;
-			assert(cur->tic == tic_tobject);
-
-		} else if (cur_csi->base_csi != NULL) {
-			/* No explicit reference. Use grandfather class. */
-			cur = tdata_item_new(tic_tobject);
-			cur->u.tobject = tdata_object_new();
-			cur->u.tobject->csi = cur_csi->base_csi;
-			cur->u.tobject->static_ref = b_false;
-
-			list_init(&cur->u.tobject->targs);
-		} else {
-			/* No match */
-			stype_convert_failure(stype, expr, dest);
-			return expr;
-		}
-	}
-
-	/* Verify that type arguments match */
-	ca_n = list_first(&cur->u.tobject->targs);
-	da_n = list_first(&dest->u.tobject->targs);
-
-	while (ca_n != NULL && da_n != NULL) {
-		carg = list_node_data(ca_n, tdata_item_t *);
-		darg = list_node_data(da_n, tdata_item_t *);
-
-		if (tdata_item_equal(carg, darg) != b_true) {
-			/* Diferent argument type */
-			stype_convert_failure(stype, expr, dest);
-			printf("Different argument type '");
-			tdata_item_print(carg);
-			printf("' vs. '");
-			tdata_item_print(darg);
-			printf("'.\n");
-			return expr;
-		}
-
-		ca_n = list_next(&cur->u.tobject->targs, ca_n);
-		da_n = list_next(&dest->u.tobject->targs, da_n);
-	}
-
-	if (ca_n != NULL || da_n != NULL) {
-		/* Diferent number of arguments */
-		stype_convert_failure(stype, expr, dest);
-		printf("Different number of arguments.\n");
+	/*
+	 * Find predecessor of the right type. This determines the
+	 * type arguments that the destination type should have.
+	 */
+	pred_ti = stype_tobject_find_pred(stype, src, dest);
+	if (pred_ti == NULL) {
+		stype_convert_failure(stype, convc_implicit, expr, dest);
+		printf("Not a base class or implemented or accumulated "
+		    "interface.\n");
+		return expr;
+	}
+
+	/*
+	 * Verify that type arguments match with those specified for
+	 * conversion destination.
+	 */
+	if (stype_targs_check_equal(stype, pred_ti, dest) != EOK) {
+		stype_convert_failure(stype, convc_implicit, expr, dest);
 		return expr;
 	}
@@ -1160,5 +1433,5 @@
 	/* Compare rank and base type. */
 	if (src->u.tarray->rank != dest->u.tarray->rank) {
-		stype_convert_failure(stype, expr, dest);
+		stype_convert_failure(stype, convc_implicit, expr, dest);
 		return expr;
 	}
@@ -1167,5 +1440,5 @@
 	if (tdata_item_equal(src->u.tarray->base_ti,
 	    dest->u.tarray->base_ti) != b_true) {
-		stype_convert_failure(stype, expr, dest);
+		stype_convert_failure(stype, convc_implicit, expr, dest);
 	}
 
@@ -1205,5 +1478,5 @@
 	/* Both must be the same delegate. */
 	if (sdeleg->deleg != ddeleg->deleg) {
-		stype_convert_failure(stype, expr, dest);
+		stype_convert_failure(stype, convc_implicit, expr, dest);
 		return expr;
 	}
@@ -1240,5 +1513,5 @@
 	/* Both must be of the same enum type (with the same declaration). */
 	if (senum->enum_d != denum->enum_d) {
-		stype_convert_failure(stype, expr, dest);
+		stype_convert_failure(stype, convc_implicit, expr, dest);
 		return expr;
 	}
@@ -1279,5 +1552,5 @@
 
 	if (!stype_fun_sig_equal(stype, ssig, dsig)) {
-		stype_convert_failure(stype, expr, dest);
+		stype_convert_failure(stype, convc_implicit, expr, dest);
 		return expr;
 	}
@@ -1311,5 +1584,5 @@
 	/* Currently only allow if both types are the same. */
 	if (src->u.tvref->targ != dest->u.tvref->targ) {
-		stype_convert_failure(stype, expr, dest);
+		stype_convert_failure(stype, convc_implicit, expr, dest);
 		return expr;
 	}
@@ -1324,9 +1597,14 @@
  * @param dest		Destination type
  */
-static void stype_convert_failure(stype_t *stype, stree_expr_t *expr,
-    tdata_item_t *dest)
+void stype_convert_failure(stype_t *stype, stype_conv_class_t convc,
+    stree_expr_t *expr, tdata_item_t *dest)
 {
 	cspan_print(expr->cspan);
-	printf(" Error: Cannot convert ");
+	printf(" Error: ");
+	switch (convc) {
+	case convc_implicit: printf("Cannot implicitly convert '"); break;
+	case convc_as: printf("Cannot use 'as' to convert '"); break;
+	}
+
 	tdata_item_print(expr->titem);
 	printf(" to ");
@@ -1397,4 +1675,166 @@
 }
 
+/** Find predecessor CSI and return its type item.
+ *
+ * Looks for predecessor of CSI type @a src that matches @a dest.
+ * The type maches if they use the same generic CSI definition, type
+ * arguments are ignored. If found, returns the type arguments that
+ * @a dest should have in order to be a true predecessor of @a src.
+ *
+ * @param stype		Static typing object
+ * @param src		Source type
+ * @param dest		Destination type
+ * @return		Type matching @a dest with correct type arguments
+ */
+tdata_item_t *stype_tobject_find_pred(stype_t *stype, tdata_item_t *src,
+    tdata_item_t *dest)
+{
+	stree_csi_t *src_csi;
+	tdata_tvv_t *tvv;
+	tdata_item_t *b_ti, *bs_ti;
+
+	list_node_t *pred_n;
+	stree_texpr_t *pred_te;
+
+	tdata_item_t *res_ti;
+
+#ifdef DEBUG_TYPE_TRACE
+	printf("Find CSI predecessor.\n");
+#endif
+	assert(src->tic == tic_tobject);
+	assert(dest->tic == tic_tobject);
+
+	if (src->u.tobject->csi == dest->u.tobject->csi)
+		return src;
+
+	src_csi = src->u.tobject->csi;
+	stype_titem_to_tvv(stype, src, &tvv);
+
+	res_ti = NULL;
+
+	switch (dest->u.tobject->csi->cc) {
+	case csi_class:
+		/* Destination is a class. Look at base class. */
+		pred_te = symbol_get_base_class_ref(stype->program,
+		    src_csi);
+		if (pred_te != NULL) {
+			run_texpr(stype->program, src_csi, pred_te,
+			    &b_ti);
+		} else if (src_csi->base_csi != NULL &&
+			src->u.tobject->csi->cc == csi_class) {
+			/* No explicit reference. Use grandfather class. */
+		    	b_ti = tdata_item_new(tic_tobject);
+			b_ti->u.tobject = tdata_object_new();
+			b_ti->u.tobject->csi = src_csi->base_csi;
+			b_ti->u.tobject->static_ref = sn_nonstatic;
+
+			list_init(&b_ti->u.tobject->targs);
+		} else {
+			/* No match */
+			return NULL;
+		}
+
+		/* Substitute type variables to get predecessor type. */
+		tdata_item_subst(b_ti, tvv, &bs_ti);
+		assert(bs_ti->tic == tic_tobject);
+
+		/* Recurse to compute the rest of the path. */
+		res_ti = stype_tobject_find_pred(stype, bs_ti, dest);
+	    	if (b_ti->tic == tic_ignore) {
+			/* An error occured. */
+			return NULL;
+		}
+		break;
+	case csi_struct:
+		assert(b_false);
+	case csi_interface:
+		/*
+		 * Destination is an interface. Look at implemented
+		 * or accumulated interfaces.
+		 */
+		pred_n = list_first(&src_csi->inherit);
+		while (pred_n != NULL) {
+			pred_te = list_node_data(pred_n, stree_texpr_t *);
+			run_texpr(stype->program, src_csi, pred_te,
+			    &b_ti);
+
+			/* Substitute type variables to get predecessor type. */
+			tdata_item_subst(b_ti, tvv, &bs_ti);
+			assert(bs_ti->tic == tic_tobject);
+
+			/* Recurse to compute the rest of the path. */
+			res_ti = stype_tobject_find_pred(stype, bs_ti, dest);
+			if (res_ti != NULL)
+				break;
+
+			pred_n = list_next(&src_csi->inherit, pred_n);
+		}
+		break;
+	}
+
+	return res_ti;
+}
+
+/** Check whether type arguments of expression type and another type are equal.
+ *
+ * Compare type arguments of the type of @a expr and of type @a b_ti.
+ * @a convc denotes the type of conversion for which we perform this check
+ * (for sake of error reporting).
+ *
+ * If the type arguments are not equal a typing error and a conversion error
+ * message is generated.
+ *
+ * @param stype		Static typing object
+ * @param expr		Expression
+ * @param b_ti		b_tiination type
+ * @return		EOK if equal, EINVAL if not.
+ */
+int stype_targs_check_equal(stype_t *stype, tdata_item_t *a_ti,
+    tdata_item_t *b_ti)
+{
+	list_node_t *arg_a_n, *arg_b_n;
+	tdata_item_t *arg_a, *arg_b;
+
+	(void) stype;
+
+#ifdef DEBUG_TYPE_TRACE
+	printf("Check if type arguments match.\n");
+#endif
+	assert(a_ti->tic == tic_tobject);
+	assert(b_ti->tic == tic_tobject);
+
+	/*
+	 * Verify that type arguments match with those specified for
+	 * conversion b_tiination.
+	 */
+	arg_a_n = list_first(&a_ti->u.tobject->targs);
+	arg_b_n = list_first(&b_ti->u.tobject->targs);
+
+	while (arg_a_n != NULL && arg_b_n != NULL) {
+		arg_a = list_node_data(arg_a_n, tdata_item_t *);
+		arg_b = list_node_data(arg_b_n, tdata_item_t *);
+
+		if (tdata_item_equal(arg_a, arg_b) != b_true) {
+			/* Diferent argument type */
+			printf("Different argument type '");
+			tdata_item_print(arg_a);
+			printf("' vs. '");
+			tdata_item_print(arg_b);
+			printf("'.\n");
+			return EINVAL;
+		}
+
+		arg_a_n = list_next(&a_ti->u.tobject->targs, arg_a_n);
+		arg_b_n = list_next(&b_ti->u.tobject->targs, arg_b_n);
+	}
+
+	if (arg_a_n != NULL || arg_b_n != NULL) {
+		/* Diferent number of arguments */
+		printf("Different number of arguments.\n");
+		return EINVAL;
+	}
+
+	return EOK;
+}
 
 
@@ -1448,6 +1888,15 @@
 
 	/* Compare return type */
-	if (!tdata_item_equal(asig->rtype, bsig->rtype))
-		return b_false;
+
+	if (asig->rtype != NULL || bsig->rtype != NULL) {
+		if (asig->rtype == NULL ||
+		    bsig->rtype == NULL) {
+			return b_false;
+		}
+
+		if (!tdata_item_equal(asig->rtype, bsig->rtype)) {
+			return b_false;
+		}
+	}
 
 	return b_true;
Index: uspace/app/sbi/src/stype.h
===================================================================
--- uspace/app/sbi/src/stype.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/app/sbi/src/stype.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -37,4 +37,5 @@
 void stype_enum(stype_t *stype, stree_enum_t *enum_d);
 void stype_fun_header(stype_t *stype, stree_fun_t *fun);
+void stype_prop_header(stype_t *stype, stree_prop_t *prop);
 void stype_stat(stype_t *stype, stree_stat_t *stat, bool_t want_value);
 
@@ -44,5 +45,11 @@
 stree_expr_t *stype_convert(stype_t *stype, stree_expr_t *expr,
     tdata_item_t *dest);
+void stype_convert_failure(stype_t *stype, stype_conv_class_t convc,
+    stree_expr_t *expr, tdata_item_t *dest);
 stree_expr_t *stype_box_expr(stype_t *stype, stree_expr_t *expr);
+tdata_item_t *stype_tobject_find_pred(stype_t *stype, tdata_item_t *src,
+    tdata_item_t *dest);
+int stype_targs_check_equal(stype_t *stype, tdata_item_t *a_ti,
+    tdata_item_t *b_ti);
 
 tdata_fun_sig_t *stype_deleg_get_sig(stype_t *stype, tdata_deleg_t *tdeleg);
Index: uspace/app/sbi/src/stype_expr.c
===================================================================
--- uspace/app/sbi/src/stype_expr.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/app/sbi/src/stype_expr.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -97,5 +97,5 @@
 static void stype_new(stype_t *stype, stree_new_t *new,
     tdata_item_t **rtitem);
-static void stype_new_object_args(stype_t *stype, stree_new_t *new_op,
+static void stype_new_object(stype_t *stype, stree_new_t *new_op,
     tdata_item_t *obj_ti);
 
@@ -194,4 +194,5 @@
 	tdata_ebase_t *tebase;
 	stree_fun_t *fun;
+	bool_t static_ctx;
 
 #ifdef DEBUG_TYPE_TRACE
@@ -257,4 +258,30 @@
 	}
 
+	/* Determine if current procedure is static. */
+	static_ctx = stree_symbol_is_static(stype->proc_vr->proc->outer_symbol);
+
+	/*
+	 * If the symbol is not found in current CSI, then we access it
+	 * in a static context. (Context of current object cannot be used.)
+	 */
+	if (sym->outer_csi != stype->current_csi)
+		static_ctx = b_true;
+
+	/* Check for referencing non-static symbol in static context. */
+	if (static_ctx && !stree_symbol_is_static(sym)) {
+		cspan_print(nameref->expr->cspan);
+		printf(" Error: Referencing non-static symbol '");
+		symbol_print_fqn(sym);
+		printf("' in static context.\n");
+		stype_note_error(stype);
+		*rtitem = stype_recovery_titem(stype);
+		return;
+	}
+
+	/* Referencing static member in non-static context is allowed. */
+
+	/* Make compiler happy. */
+	titem = NULL;
+
 	switch (sym->sc) {
 	case sc_var:
@@ -263,6 +290,7 @@
 		break;
 	case sc_prop:
-		run_texpr(stype->program, stype->current_csi,
-		    sym->u.prop->type, &titem);
+		/* Type property header if it has not been typed yet. */
+		stype_prop_header(stype, sym->u.prop);
+		titem = sym->u.prop->titem;
 		break;
 	case sc_csi:
@@ -274,6 +302,5 @@
 		titem->u.tobject = tobject;
 
-		/* This is a static CSI reference. */
-		tobject->static_ref = b_true;
+		tobject->static_ref = sn_static;
 		tobject->csi = csi;
 		break;
@@ -330,4 +357,7 @@
 	(void) stype;
 
+	/* Make compiler happy. */
+	tpc = 0;
+
 	switch (literal->ltc) {
 	case ltc_bool: tpc = tpc_bool; break;
@@ -375,5 +405,5 @@
 	titem->u.tobject = tobject;
 
-	tobject->static_ref = b_false;
+	tobject->static_ref = sn_nonstatic;
 	tobject->csi = cur_csi;
 	list_init(&tobject->targs);
@@ -513,4 +543,7 @@
 	tdata_item_t *res_ti;
 
+	/* Make compiler happy. */
+	rtpc = 0;
+
 	switch (binop->bc) {
 	case bo_equal:
@@ -560,4 +593,7 @@
 	(void) stype;
 
+	/* Make compiler happy. */
+	rtpc = 0;
+
 	switch (binop->bc) {
 	case bo_equal:
@@ -604,4 +640,7 @@
 	(void) stype;
 
+	/* Make compiler happy. */
+	rtpc = 0;
+
 	switch (binop->bc) {
 	case bo_equal:
@@ -666,4 +705,7 @@
 	tdata_item_t *res_ti;
 
+	/* Make compiler happy. */
+	rtpc = 0;
+
 	switch (binop->bc) {
 	case bo_equal:
@@ -941,5 +983,5 @@
 
 	if ((*rtitem)->tic == tic_tobject)
-		stype_new_object_args(stype, new_op, *rtitem);
+		stype_new_object(stype, new_op, *rtitem);
 }
 
@@ -949,5 +991,5 @@
  * @param new_op	@c new operation
  */
-static void stype_new_object_args(stype_t *stype, stree_new_t *new_op,
+static void stype_new_object(stype_t *stype, stree_new_t *new_op,
     tdata_item_t *obj_ti)
 {
@@ -957,7 +999,17 @@
 	stree_ident_t *ctor_ident;
 	tdata_fun_sig_t *tsig;
+	tdata_tvv_t *obj_tvv;
+	tdata_item_t *ctor_sti;
 
 	assert(obj_ti->tic == tic_tobject);
 	csi = obj_ti->u.tobject->csi;
+
+	if (csi->cc == csi_interface) {
+		cspan_print(new_op->expr->cspan);
+		printf(" Error: Cannot instantiate an interface.\n");
+		stype_note_error(stype);
+		return;
+	}
+
 	ctor_ident = stree_ident_new();
 	ctor_ident->sid = strtab_get_sid(CTOR_IDENT);
@@ -986,6 +1038,11 @@
 		return;
 
-	assert(ctor->titem->tic == tic_tfun);
-	tsig = ctor->titem->u.tfun->tsig;
+	/* Substitute type arguments in constructor type. */
+	stype_titem_to_tvv(stype, obj_ti, &obj_tvv);
+	tdata_item_subst(ctor->titem, obj_tvv, &ctor_sti);
+	/* XXX Free obj_tvv */
+
+	assert(ctor_sti->tic == tic_tfun);
+	tsig = ctor_sti->u.tfun->tsig;
 
 	stype_call_args(stype, new_op->expr->cspan, &tsig->arg_ti,
@@ -1104,4 +1161,5 @@
 	tdata_item_t *mtitem;
 	tdata_tvv_t *tvv;
+	stree_csi_t *member_csi;
 
 #ifdef DEBUG_TYPE_TRACE
@@ -1131,13 +1189,43 @@
 	    strtab_get_str(access->member_name->sid));
 #endif
+	/* Check for accessing non-static member in static context. */
+	if (tobject->static_ref == sn_static &&
+	    !stree_symbol_is_static(member_sym)) {
+		cspan_print(access->member_name->cspan);
+		printf(" Error: Accessing non-static member '");
+		symbol_print_fqn(member_sym);
+		printf("' in static context.\n");
+		stype_note_error(stype);
+		*rtitem = stype_recovery_titem(stype);
+		return;
+	}
+
+	/* Check for accessing static member in non-static context. */
+	if (tobject->static_ref != sn_static &&
+	    stree_symbol_is_static(member_sym)) {
+		cspan_print(access->member_name->cspan);
+		printf(" Error: Accessing static member '");
+		symbol_print_fqn(member_sym);
+		printf("' in non-static context.\n");
+		stype_note_error(stype);
+		*rtitem = stype_recovery_titem(stype);
+		return;
+	}
+
+	/* Make compiler happy. */
+	mtitem = NULL;
 
 	switch (member_sym->sc) {
 	case sc_csi:
-		cspan_print(access->member_name->cspan);
-		printf(" Error: Accessing object member which is nested "
-		    "CSI.\n");
-		stype_note_error(stype);
-		*rtitem = stype_recovery_titem(stype);
-		return;
+		member_csi = symbol_to_csi(member_sym);
+		assert(member_csi != NULL);
+
+		mtitem = tdata_item_new(tic_tobject);
+		tobject = tdata_object_new();
+		mtitem->u.tobject = tobject;
+
+		tobject->static_ref = sn_static;
+		tobject->csi = member_csi;
+		break;
 	case sc_ctor:
 		/* It is not possible to reference a constructor explicitly. */
@@ -1337,11 +1425,8 @@
 	stree_expr_t *carg;
 
-	int cnt;
-
 	/* Type and check regular arguments. */
 	fargt_n = list_first(farg_tis);
 	arg_n = list_first(args);
 
-	cnt = 0;
 	while (fargt_n != NULL && arg_n != NULL) {
 		farg_ti = list_node_data(fargt_n, tdata_item_t *);
@@ -1656,4 +1741,5 @@
 {
 	tdata_item_t *titem;
+	tdata_item_t *pred_ti;
 
 #ifdef DEBUG_TYPE_TRACE
@@ -1664,13 +1750,21 @@
 	run_texpr(stype->program, stype->current_csi, as_op->dtype, &titem);
 
-	/* Check that target type is derived from argument type. */
-	if (tdata_is_ti_derived_from_ti(titem, as_op->arg->titem) != b_true) {
-		cspan_print(as_op->dtype->cspan);
-		printf(" Error: Target of 'as' operator '");
-		tdata_item_print(titem);
-		printf("' is not derived from '");
-		tdata_item_print(as_op->arg->titem);
-		printf("'.\n");
-		stype_note_error(stype);
+	pred_ti = stype_tobject_find_pred(stype, titem, as_op->arg->titem);
+	if (pred_ti == NULL) {
+		/* No CSI match. */
+		stype_convert_failure(stype, convc_as, as_op->arg, titem);
+		*rtitem = titem;
+		return;
+	}
+
+	/*
+	 * Verify that type arguments match with those specified for
+	 * conversion destination.
+	 */
+	if (stype_targs_check_equal(stype, pred_ti, as_op->arg->titem)
+	    != EOK) {
+		stype_convert_failure(stype, convc_as, as_op->arg, titem);
+		*rtitem = titem;
+		return;
 	}
 
@@ -1720,5 +1814,5 @@
 
 	btitem->u.tobject = tobject;
-	tobject->static_ref = b_false;
+	tobject->static_ref = sn_nonstatic;
 	tobject->csi = symbol_to_csi(csi_sym);
 	assert(tobject->csi != NULL);
Index: uspace/app/sbi/src/stype_t.h
===================================================================
--- uspace/app/sbi/src/stype_t.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/app/sbi/src/stype_t.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -59,4 +59,12 @@
 } stype_proc_vr_t;
 
+/** Conversion class */
+typedef enum {
+	/** Implicit conversion */
+	convc_implicit,
+	/** 'as' conversion */
+	convc_as
+} stype_conv_class_t;
+
 /** Static typer state object */
 typedef struct stype {
Index: uspace/app/sbi/src/symbol.c
===================================================================
--- uspace/app/sbi/src/symbol.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/app/sbi/src/symbol.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -42,5 +42,4 @@
 static stree_symbol_t *symbol_find_epoint_rec(stree_program_t *prog,
     stree_ident_t *name, stree_csi_t *csi);
-static stree_symbol_t *csimbr_to_symbol(stree_csimbr_t *csimbr);
 static stree_ident_t *symbol_get_ident(stree_symbol_t *symbol);
 
@@ -132,5 +131,4 @@
     stree_csi_t *scope, stree_ident_t *name)
 {
-	stree_symbol_t *base_csi_sym;
 	stree_csi_t *base_csi;
 	stree_symbol_t *symbol;
@@ -142,12 +140,7 @@
 
 	/* Try inherited members. */
-	if (scope->base_csi_ref != NULL) {
-		base_csi_sym = symbol_xlookup_in_csi(prog,
-		    csi_to_symbol(scope)->outer_csi, scope->base_csi_ref);
-		base_csi = symbol_to_csi(base_csi_sym);
-		assert(base_csi != NULL);
-
+	base_csi = symbol_get_base_class(prog, scope);
+	if (base_csi != NULL)
 		return symbol_search_csi(prog, base_csi, name);
-	}
 
 	/* No match */
@@ -212,4 +205,7 @@
 		modm = list_node_data(node, stree_modm_t *);
 
+		/* Make compiler happy. */
+		mbr_name = NULL;
+
 		switch (modm->mc) {
 		case mc_csi: mbr_name = modm->u.csi->name; break;
@@ -217,5 +213,11 @@
 		}
 
+		/* The Clang static analyzer is just too picky. */
+		assert(mbr_name != NULL);
+
 		if (name->sid == mbr_name->sid) {
+			/* Make compiler happy. */
+			symbol = NULL;
+
 			/* Match */
 			switch (modm->mc) {
@@ -231,4 +233,75 @@
 		node = list_next(&prog->module->members, node);
 	}
+
+	return NULL;
+}
+
+/** Get explicit base class for a CSI.
+ *
+ * Note that if there is no explicit base class (class is derived implicitly
+ * from @c object, then @c NULL is returned.
+ *
+ * @param prog	Program to look in
+ * @param csi	CSI
+ *
+ * @return	Base class (CSI) or @c NULL if no explicit base class.
+ */
+stree_csi_t *symbol_get_base_class(stree_program_t *prog, stree_csi_t *csi)
+{
+	list_node_t *pred_n;
+	stree_texpr_t *pred;
+	stree_symbol_t *pred_sym;
+	stree_csi_t *pred_csi;
+	stree_csi_t *outer_csi;
+
+	outer_csi = csi_to_symbol(csi)->outer_csi;
+
+	pred_n = list_first(&csi->inherit);
+	if (pred_n == NULL)
+		return NULL;
+
+	pred = list_node_data(pred_n, stree_texpr_t *);
+	pred_sym = symbol_xlookup_in_csi(prog, outer_csi, pred);
+	pred_csi = symbol_to_csi(pred_sym);
+	assert(pred_csi != NULL); /* XXX! */
+
+	if (pred_csi->cc == csi_class)
+		return pred_csi;
+
+	return NULL;
+}
+
+/** Get type expression referencing base class for a CSI.
+ *
+ * Note that if there is no explicit base class (class is derived implicitly
+ * from @c object, then @c NULL is returned.
+ *
+ * @param prog	Program to look in
+ * @param csi	CSI
+ *
+ * @return	Type expression or @c NULL if no explicit base class.
+ */
+stree_texpr_t *symbol_get_base_class_ref(stree_program_t *prog,
+    stree_csi_t *csi)
+{
+	list_node_t *pred_n;
+	stree_texpr_t *pred;
+	stree_symbol_t *pred_sym;
+	stree_csi_t *pred_csi;
+	stree_csi_t *outer_csi;
+
+	outer_csi = csi_to_symbol(csi)->outer_csi;
+
+	pred_n = list_first(&csi->inherit);
+	if (pred_n == NULL)
+		return NULL;
+
+	pred = list_node_data(pred_n, stree_texpr_t *);
+	pred_sym = symbol_xlookup_in_csi(prog, outer_csi, pred);
+	pred_csi = symbol_to_csi(pred_sym);
+	assert(pred_csi != NULL); /* XXX! */
+
+	if (pred_csi->cc == csi_class)
+		return pred;
 
 	return NULL;
@@ -286,4 +359,5 @@
 	stree_csimbr_t *csimbr;
 	stree_symbol_t *entry, *etmp;
+	stree_symbol_t *fun_sym;
 
 	entry = NULL;
@@ -305,10 +379,13 @@
 			break;
 		case csimbr_fun:
-			if (csimbr->u.fun->name->sid == name->sid) {
+			fun_sym = fun_to_symbol(csimbr->u.fun);
+
+			if (csimbr->u.fun->name->sid == name->sid &&
+			    stree_symbol_has_attr(fun_sym, sac_static)) {
 				if (entry != NULL) {
 					printf("Error: Duplicate entry point.\n");
 					exit(1);
 				}
-				entry = fun_to_symbol(csimbr->u.fun);
+				entry = fun_sym;
 			}
 		default:
@@ -494,5 +571,5 @@
  * @return		Symbol
  */
-static stree_symbol_t *csimbr_to_symbol(stree_csimbr_t *csimbr)
+stree_symbol_t *csimbr_to_symbol(stree_csimbr_t *csimbr)
 {
 	stree_symbol_t *symbol;
@@ -569,4 +646,7 @@
 	stree_ident_t *ident;
 
+	/* Make compiler happy. */
+	ident = NULL;
+
 	switch (symbol->sc) {
 	case sc_csi: ident = symbol->u.csi->name; break;
Index: uspace/app/sbi/src/symbol.h
===================================================================
--- uspace/app/sbi/src/symbol.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/app/sbi/src/symbol.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -40,4 +40,7 @@
 stree_symbol_t *symbol_search_csi_no_base(stree_program_t *prog,
     stree_csi_t *scope, stree_ident_t *name);
+stree_csi_t *symbol_get_base_class(stree_program_t *prog, stree_csi_t *csi);
+stree_texpr_t *symbol_get_base_class_ref(stree_program_t *prog,
+    stree_csi_t *csi);
 stree_symbol_t *symbol_find_epoint(stree_program_t *prog, stree_ident_t *name);
 
@@ -57,4 +60,6 @@
 stree_symbol_t *prop_to_symbol(stree_prop_t *prop);
 
+stree_symbol_t *csimbr_to_symbol(stree_csimbr_t *csimbr);
+
 void symbol_print_fqn(stree_symbol_t *symbol);
 
Index: uspace/app/sbi/src/tdata.c
===================================================================
--- uspace/app/sbi/src/tdata.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/app/sbi/src/tdata.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -343,6 +343,8 @@
 	/* Plain copy */
 	tnew = tdata_ebase_new();
+	tnew->enum_d = tebase->enum_d;
+
 	*res = tdata_item_new(tic_tebase);
-	(*res)->u.tebase = tebase;
+	(*res)->u.tebase = tnew;
 }
 
@@ -362,6 +364,8 @@
 	/* Plain copy */
 	tnew = tdata_enum_new();
+	tnew->enum_d = tenum->enum_d;
+
 	*res = tdata_item_new(tic_tenum);
-	(*res)->u.tenum = tenum;
+	(*res)->u.tenum = tnew;
 }
 
Index: uspace/app/sbi/src/tdata_t.h
===================================================================
--- uspace/app/sbi/src/tdata_t.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/app/sbi/src/tdata_t.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -58,6 +58,6 @@
 /** Object type. */
 typedef struct {
-	/** @c true if expression is a static CSI reference */
-	bool_t static_ref;
+	/** @c sn_static if expression is a static CSI reference */
+	statns_t static_ref;
 
 	/** CSI definition */
Index: uspace/app/tasks/tasks.c
===================================================================
--- uspace/app/tasks/tasks.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/app/tasks/tasks.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -165,8 +165,8 @@
 	for (i = 0; i < count; i++) {
 		if (cpus[i].active) {
-			printf("cpu%u: %" PRIu16 " MHz, busy ticks: "
-			    "%" PRIu64 ", idle ticks: %" PRIu64 "\n",
-			    cpus[i].id, cpus[i].frequency_mhz, cpus[i].busy_ticks,
-			    cpus[i].idle_ticks);
+			printf("cpu%u: %" PRIu16 " MHz, busy cycles: "
+			    "%" PRIu64 ", idle cycles: %" PRIu64 "\n",
+			    cpus[i].id, cpus[i].frequency_mhz, cpus[i].busy_cycles,
+			    cpus[i].idle_cycles);
 		} else {
 			printf("cpu%u: inactive\n", cpus[i].id);
Index: uspace/app/top/screen.c
===================================================================
--- uspace/app/top/screen.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/app/top/screen.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -126,7 +126,7 @@
 }
 
-static void print_float(fixed_float ffloat, unsigned int precision)
-{
-	printf("%2" PRIu64 ".", ffloat.upper / ffloat.lower);
+static void print_percent(fixed_float ffloat, unsigned int precision)
+{
+	printf("%3" PRIu64 ".", ffloat.upper / ffloat.lower);
 	
 	unsigned int i;
@@ -136,4 +136,20 @@
 		rest = (rest % ffloat.lower) * 10;
 	}
+	
+	printf("%%");
+}
+
+static void print_string(const char *str)
+{
+	ipcarg_t cols;
+	ipcarg_t rows;
+	screen_get_size(&cols, &rows);
+	
+	ipcarg_t c;
+	ipcarg_t r;
+	screen_get_pos(&c, &r);
+	
+	if (c < cols)
+		printf("%.*s", cols - c - 1, str);
 }
 
@@ -206,13 +222,20 @@
 	for (i = 0; i < data->cpus_count; i++) {
 		if (data->cpus[i].active) {
-			printf("cpu%u (%4" PRIu16 " MHz): busy ticks: "
-			    "%" PRIu64 ", idle ticks: %" PRIu64,
+			uint64_t busy;
+			uint64_t idle;
+			char busy_suffix;
+			char idle_suffix;
+			
+			order_suffix(data->cpus[i].busy_cycles, &busy, &busy_suffix);
+			order_suffix(data->cpus[i].idle_cycles, &idle, &idle_suffix);
+			
+			printf("cpu%u (%4" PRIu16 " MHz): busy cycles: "
+			    "%" PRIu64 "%c, idle cycles: %" PRIu64 "%c",
 			    data->cpus[i].id, data->cpus[i].frequency_mhz,
-			    data->cpus[i].busy_ticks, data->cpus[i].idle_ticks);
+			    busy, busy_suffix, idle, idle_suffix);
 			puts(", idle: ");
-			print_float(data->cpus_perc[i].idle, 2);
-			puts("%, busy: ");
-			print_float(data->cpus_perc[i].busy, 2);
-			puts("%");
+			print_percent(data->cpus_perc[i].idle, 2);
+			puts(", busy: ");
+			print_percent(data->cpus_perc[i].busy, 2);
 		} else
 			printf("cpu%u inactive", data->cpus[i].id);
@@ -244,8 +267,9 @@
 }
 
-static inline void print_task_head(void)
+static inline void print_tasks_head(void)
 {
 	screen_style_inverted();
-	printf("      ID  Threads      Mem      %%Mem %%uCycles %%kCycles  Name");
+	printf("[taskid] [threads] [virtual] [%%virt] [%%user]"
+	    " [%%kernel] [name");
 	screen_newline();
 	screen_style_normal();
@@ -264,17 +288,20 @@
 	size_t i;
 	for (i = 0; (i < data->tasks_count) && (row < rows); i++, row++) {
+		stats_task_t *task = data->tasks + data->tasks_map[i];
+		perc_task_t *perc = data->tasks_perc + data->tasks_map[i];
+		
 		uint64_t virtmem;
 		char virtmem_suffix;
-		order_suffix(data->tasks[i].virtmem, &virtmem, &virtmem_suffix);
-		
-		printf("%8" PRIu64 " %8u %8" PRIu64 "%c ", data->tasks[i].task_id,
-		    data->tasks[i].threads, virtmem, virtmem_suffix);
+		order_suffix(task->virtmem, &virtmem, &virtmem_suffix);
+		
+		printf("%-8" PRIu64 " %9u %8" PRIu64 "%c ", task->task_id,
+		    task->threads, virtmem, virtmem_suffix);
+		print_percent(perc->virtmem, 2);
+		puts(" ");
+		print_percent(perc->ucycles, 2);
 		puts("   ");
-		print_float(data->tasks_perc[i].virtmem, 2);
-		puts("%   ");
-		print_float(data->tasks_perc[i].ucycles, 2);
-		puts("%   ");
-		print_float(data->tasks_perc[i].kcycles, 2);
-		printf("%% %s", data->tasks[i].name);
+		print_percent(perc->kcycles, 2);
+		puts(" ");
+		print_string(task->name);
 		
 		screen_newline();
@@ -290,5 +317,6 @@
 {
 	screen_style_inverted();
-	printf("      ID Calls sent Calls recv Answs sent Answs recv  IRQn recv       Forw Name");
+	printf("[taskid] [cls snt] [cls rcv] [ans snt]"
+	    " [ans rcv] [irq rcv] [forward] [name");
 	screen_newline();
 	screen_style_normal();
@@ -307,15 +335,130 @@
 	size_t i;
 	for (i = 0; (i < data->tasks_count) && (row < rows); i++, row++) {
-		printf("%8" PRIu64 " %10" PRIu64 " %10" PRIu64 " %10" PRIu64
-		     " %10" PRIu64 " %10" PRIu64 " %10" PRIu64 " %s",
-		     data->tasks[i].task_id, data->tasks[i].ipc_info.call_sent,
-		     data->tasks[i].ipc_info.call_recieved,
-		     data->tasks[i].ipc_info.answer_sent,
-		     data->tasks[i].ipc_info.answer_recieved,
-		     data->tasks[i].ipc_info.irq_notif_recieved,
-		     data->tasks[i].ipc_info.forwarded, data->tasks[i].name);
-		
-		screen_newline();
-	}
+		uint64_t call_sent;
+		uint64_t call_received;
+		uint64_t answer_sent;
+		uint64_t answer_received;
+		uint64_t irq_notif_received;
+		uint64_t forwarded;
+		
+		char call_sent_suffix;
+		char call_received_suffix;
+		char answer_sent_suffix;
+		char answer_received_suffix;
+		char irq_notif_received_suffix;
+		char forwarded_suffix;
+		
+		order_suffix(data->tasks[i].ipc_info.call_sent, &call_sent,
+		    &call_sent_suffix);
+		order_suffix(data->tasks[i].ipc_info.call_received,
+		    &call_received, &call_received_suffix);
+		order_suffix(data->tasks[i].ipc_info.answer_sent,
+		    &answer_sent, &answer_sent_suffix);
+		order_suffix(data->tasks[i].ipc_info.answer_received,
+		    &answer_received, &answer_received_suffix);
+		order_suffix(data->tasks[i].ipc_info.irq_notif_received,
+		    &irq_notif_received, &irq_notif_received_suffix);
+		order_suffix(data->tasks[i].ipc_info.forwarded, &forwarded,
+		    &forwarded_suffix);
+		
+		printf("%-8" PRIu64 " %8" PRIu64 "%c %8" PRIu64 "%c"
+		     " %8" PRIu64 "%c %8" PRIu64 "%c %8" PRIu64 "%c"
+		     " %8" PRIu64 "%c ", data->tasks[i].task_id,
+		     call_sent, call_sent_suffix,
+		     call_received, call_received_suffix,
+		     answer_sent, answer_sent_suffix,
+		     answer_received, answer_received_suffix,
+		     irq_notif_received, irq_notif_received_suffix,
+		     forwarded, forwarded_suffix);
+		print_string(data->tasks[i].name);
+		
+		screen_newline();
+	}
+	
+	while (row < rows) {
+		screen_newline();
+		row++;
+	}
+}
+
+static inline void print_excs_head(void)
+{
+	screen_style_inverted();
+	printf("[exc   ] [count   ] [%%count] [cycles  ] [%%cycles] [description");
+	screen_newline();
+	screen_style_normal();
+}
+
+static inline void print_excs(data_t *data)
+{
+	ipcarg_t cols;
+	ipcarg_t rows;
+	screen_get_size(&cols, &rows);
+	
+	ipcarg_t col;
+	ipcarg_t row;
+	screen_get_pos(&col, &row);
+	
+	size_t i;
+	for (i = 0; (i < data->exceptions_count) && (row < rows); i++) {
+		/* Filter-out cold exceptions if not instructed otherwise */
+		if ((!excs_all) && (!data->exceptions[i].hot))
+			continue;
+		
+		uint64_t count;
+		uint64_t cycles;
+		
+		char count_suffix;
+		char cycles_suffix;
+		
+		order_suffix(data->exceptions[i].count, &count, &count_suffix);
+		order_suffix(data->exceptions[i].cycles, &cycles, &cycles_suffix);
+		
+		printf("%-8u %9" PRIu64 "%c  ",
+		     data->exceptions[i].id, count, count_suffix);
+		print_percent(data->exceptions_perc[i].count, 2);
+		printf(" %9" PRIu64 "%c   ", cycles, cycles_suffix);
+		print_percent(data->exceptions_perc[i].cycles, 2);
+		puts(" ");
+		print_string(data->exceptions[i].desc);
+		
+		screen_newline();
+		row++;
+	}
+	
+	while (row < rows) {
+		screen_newline();
+		row++;
+	}
+}
+
+static void print_help(void)
+{
+	ipcarg_t cols;
+	ipcarg_t rows;
+	screen_get_size(&cols, &rows);
+	
+	ipcarg_t col;
+	ipcarg_t row;
+	screen_get_pos(&col, &row);
+	
+	screen_newline();
+	
+	printf("Operation modes:");
+	screen_newline();
+	
+	printf(" t .. tasks statistics");
+	screen_newline();
+	
+	printf(" i .. IPC statistics");
+	screen_newline();
+	
+	printf(" e .. exceptions statistics");
+	screen_newline();
+	
+	printf("      a .. toggle display of all/hot exceptions");
+	screen_newline();
+	
+	row += 6;
 	
 	while (row < rows) {
@@ -338,10 +481,20 @@
 	screen_newline();
 	
-	if (operation_type == OP_IPC) {
+	switch (op_mode) {
+	case OP_TASKS:
+		print_tasks_head();
+		print_tasks(data);
+		break;
+	case OP_IPC:
 		print_ipc_head();
 		print_ipc(data);
-	} else {
-		print_task_head();
-		print_tasks(data);
+		break;
+	case OP_EXCS:
+		print_excs_head();
+		print_excs(data);
+		break;
+	case OP_HELP:
+		print_tasks_head();
+		print_help();
 	}
 	
Index: uspace/app/top/top.c
===================================================================
--- uspace/app/top/top.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/app/top/top.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -44,4 +44,5 @@
 #include <arch/barrier.h>
 #include <errno.h>
+#include <sort.h>
 #include "screen.h"
 #include "input.h"
@@ -56,5 +57,7 @@
 #define MINUTE  60
 
-int operation_type;
+op_mode_t op_mode = OP_TASKS;
+sort_mode_t sort_mode = SORT_TASK_CYCLES;
+bool excs_all = false;
 
 static const char *read_data(data_t *target)
@@ -66,6 +69,13 @@
 	target->tasks = NULL;
 	target->tasks_perc = NULL;
+	target->tasks_map = NULL;
 	target->threads = NULL;
+	target->exceptions = NULL;
+	target->exceptions_perc = NULL;
 	target->physmem = NULL;
+	target->ucycles_diff = NULL;
+	target->kcycles_diff = NULL;
+	target->ecycles_diff = NULL;
+	target->ecount_diff = NULL;
 	
 	/* Get current time */
@@ -110,4 +120,9 @@
 		return "Not enough memory for task utilization";
 	
+	target->tasks_map =
+	    (size_t *) calloc(target->tasks_count, sizeof(size_t));
+	if (target->tasks_map == NULL)
+		return "Not enough memory for task map";
+	
 	/* Get threads */
 	target->threads = stats_get_threads(&(target->threads_count));
@@ -115,8 +130,39 @@
 		return "Cannot get threads";
 	
+	/* Get Exceptions */
+	target->exceptions = stats_get_exceptions(&(target->exceptions_count));
+	if (target->exceptions == NULL)
+		return "Cannot get exceptions";
+	
+	target->exceptions_perc =
+	    (perc_exc_t *) calloc(target->exceptions_count, sizeof(perc_exc_t));
+	if (target->exceptions_perc == NULL)
+		return "Not enough memory for exception utilization";
+	
 	/* Get physical memory */
 	target->physmem = stats_get_physmem();
 	if (target->physmem == NULL)
 		return "Cannot get physical memory";
+	
+	target->ucycles_diff = calloc(target->tasks_count,
+	    sizeof(uint64_t));
+	if (target->ucycles_diff == NULL)
+		return "Not enough memory for user utilization";
+	
+	/* Allocate memory for computed values */
+	target->kcycles_diff = calloc(target->tasks_count,
+	    sizeof(uint64_t));
+	if (target->kcycles_diff == NULL)
+		return "Not enough memory for kernel utilization";
+	
+	target->ecycles_diff = calloc(target->exceptions_count,
+	    sizeof(uint64_t));
+	if (target->ecycles_diff == NULL)
+		return "Not enough memory for exception cycles utilization";
+	
+	target->ecount_diff = calloc(target->exceptions_count,
+	    sizeof(uint64_t));
+	if (target->ecount_diff == NULL)
+		return "Not enough memory for exception count utilization";
 	
 	return NULL;
@@ -129,19 +175,7 @@
  *
  */
-static const char *compute_percentages(data_t *old_data, data_t *new_data)
-{
-	/* Allocate memory */
-	
-	uint64_t *ucycles_diff = calloc(new_data->tasks_count, sizeof(uint64_t));
-	if (ucycles_diff == NULL)
-		return "Not enough memory for user utilization";
-	
-	uint64_t *kcycles_diff = calloc(new_data->tasks_count, sizeof(uint64_t));
-	if (kcycles_diff == NULL) {
-		free(ucycles_diff);
-		return "Not enough memory for kernel utilization";
-	}
-	
-	/* For each CPU: Compute total ticks and divide it between
+static void compute_percentages(data_t *old_data, data_t *new_data)
+{
+	/* For each CPU: Compute total cycles and divide it between
 	   user and kernel */
 	
@@ -149,7 +183,7 @@
 	for (i = 0; i < new_data->cpus_count; i++) {
 		uint64_t idle =
-		    new_data->cpus[i].idle_ticks - old_data->cpus[i].idle_ticks;
+		    new_data->cpus[i].idle_cycles - old_data->cpus[i].idle_cycles;
 		uint64_t busy =
-		    new_data->cpus[i].busy_ticks - old_data->cpus[i].busy_ticks;
+		    new_data->cpus[i].busy_cycles - old_data->cpus[i].busy_cycles;
 		uint64_t sum = idle + busy;
 		
@@ -160,7 +194,7 @@
 	/* For all tasks compute sum and differencies of all cycles */
 	
-	uint64_t virtmem_total = 1;  /* Must NOT be zero */
-	uint64_t ucycles_total = 1;  /* Must NOT be zero */
-	uint64_t kcycles_total = 1;  /* Must NOT be zero */
+	uint64_t virtmem_total = 0;
+	uint64_t ucycles_total = 0;
+	uint64_t kcycles_total = 0;
 	
 	for (i = 0; i < new_data->tasks_count; i++) {
@@ -178,20 +212,20 @@
 		if (!found) {
 			/* This is newly borned task, ignore it */
-			ucycles_diff[i] = 0;
-			kcycles_diff[i] = 0;
+			new_data->ucycles_diff[i] = 0;
+			new_data->kcycles_diff[i] = 0;
 			continue;
 		}
 		
-		ucycles_diff[i] =
+		new_data->ucycles_diff[i] =
 		    new_data->tasks[i].ucycles - old_data->tasks[j].ucycles;
-		kcycles_diff[i] =
+		new_data->kcycles_diff[i] =
 		    new_data->tasks[i].kcycles - old_data->tasks[j].kcycles;
 		
 		virtmem_total += new_data->tasks[i].virtmem;
-		ucycles_total += ucycles_diff[i];
-		kcycles_total += kcycles_diff[i];
-	}
-	
-	/* For each task: Compute percential change */
+		ucycles_total += new_data->ucycles_diff[i];
+		kcycles_total += new_data->kcycles_diff[i];
+	}
+	
+	/* For each task compute percential change */
 	
 	for (i = 0; i < new_data->tasks_count; i++) {
@@ -199,15 +233,83 @@
 		    new_data->tasks[i].virtmem * 100, virtmem_total);
 		FRACTION_TO_FLOAT(new_data->tasks_perc[i].ucycles,
-		    ucycles_diff[i] * 100, ucycles_total);
+		    new_data->ucycles_diff[i] * 100, ucycles_total);
 		FRACTION_TO_FLOAT(new_data->tasks_perc[i].kcycles,
-		    kcycles_diff[i] * 100, kcycles_total);
-	}
-	
-	/* Cleanup */
-	
-	free(ucycles_diff);
-	free(kcycles_diff);
-	
-	return NULL;
+		    new_data->kcycles_diff[i] * 100, kcycles_total);
+	}
+	
+	/* For all exceptions compute sum and differencies of cycles */
+	
+	uint64_t ecycles_total = 0;
+	uint64_t ecount_total = 0;
+	
+	for (i = 0; i < new_data->exceptions_count; i++) {
+		/*
+		 * March exception with the previous instance.
+		 * This is quite paranoid since exceptions do not
+		 * usually disappear, but it does not hurt.
+		 */
+		
+		bool found = false;
+		size_t j;
+		for (j = 0; j < old_data->exceptions_count; j++) {
+			if (new_data->exceptions[i].id == old_data->exceptions[j].id) {
+				found = true;
+				break;
+			}
+		}
+		
+		if (!found) {
+			/* This is a new exception, ignore it */
+			new_data->ecycles_diff[i] = 0;
+			new_data->ecount_diff[i] = 0;
+			continue;
+		}
+		
+		new_data->ecycles_diff[i] =
+		    new_data->exceptions[i].cycles - old_data->exceptions[j].cycles;
+		new_data->ecount_diff[i] =
+		    new_data->exceptions[i].count - old_data->exceptions[i].count;
+		
+		ecycles_total += new_data->ecycles_diff[i];
+		ecount_total += new_data->ecount_diff[i];
+	}
+	
+	/* For each exception compute percential change */
+	
+	for (i = 0; i < new_data->exceptions_count; i++) {
+		FRACTION_TO_FLOAT(new_data->exceptions_perc[i].cycles,
+		    new_data->ecycles_diff[i] * 100, ecycles_total);
+		FRACTION_TO_FLOAT(new_data->exceptions_perc[i].count,
+		    new_data->ecount_diff[i] * 100, ecount_total);
+	}
+}
+
+static int cmp_data(void *a, void *b, void *arg)
+{
+	size_t ia = *((size_t *) a);
+	size_t ib = *((size_t *) b);
+	data_t *data = (data_t *) arg;
+	
+	uint64_t acycles = data->ucycles_diff[ia] + data->kcycles_diff[ia];
+	uint64_t bcycles = data->ucycles_diff[ib] + data->kcycles_diff[ib];
+	
+	if (acycles > bcycles)
+		return -1;
+	
+	if (acycles < bcycles)
+		return 1;
+	
+	return 0;
+}
+
+static void sort_data(data_t *data)
+{
+	size_t i;
+	
+	for (i = 0; i < data->tasks_count; i++)
+		data->tasks_map[i] = i;
+	
+	qsort((void *) data->tasks_map, data->tasks_count,
+	    sizeof(size_t), cmp_data, (void *) data);
 }
 
@@ -232,6 +334,24 @@
 		free(target->threads);
 	
+	if (target->exceptions != NULL)
+		free(target->exceptions);
+	
+	if (target->exceptions_perc != NULL)
+		free(target->exceptions_perc);
+	
 	if (target->physmem != NULL)
 		free(target->physmem);
+	
+	if (target->ucycles_diff != NULL)
+		free(target->ucycles_diff);
+	
+	if (target->kcycles_diff != NULL)
+		free(target->kcycles_diff);
+	
+	if (target->ecycles_diff != NULL)
+		free(target->ecycles_diff);
+	
+	if (target->ecount_diff != NULL)
+		free(target->ecount_diff);
 }
 
@@ -249,9 +369,7 @@
 	
 	/* Compute some rubbish to have initialised values */
-	if ((ret = compute_percentages(&data_prev, &data_prev)) != NULL)
-		goto out;
+	compute_percentages(&data_prev, &data_prev);
 	
 	/* And paint screen until death */
-	operation_type = OP_TASKS;
 	while (true) {
 		int c = tgetchar(UPDATE_INTERVAL);
@@ -262,9 +380,6 @@
 			}
 			
-			if ((ret = compute_percentages(&data_prev, &data)) != NULL) {
-				free_data(&data);
-				goto out;
-			}
-			
+			compute_percentages(&data_prev, &data);
+			sort_data(&data);
 			print_data(&data);
 			free_data(&data_prev);
@@ -275,16 +390,33 @@
 		
 		switch (c) {
+			case 't':
+				print_warning("Showing task statistics");
+				op_mode = OP_TASKS;
+				break;
+			case 'i':
+				print_warning("Showing IPC statistics");
+				op_mode = OP_IPC;
+				break;
+			case 'e':
+				print_warning("Showing exception statistics");
+				op_mode = OP_EXCS;
+				break;
+			case 'h':
+				print_warning("Showing help");
+				op_mode = OP_HELP;
+				break;
 			case 'q':
 				goto out;
-			case 'i':
-				print_warning("Showing IPC statistics");
-				operation_type = OP_IPC;
-				break;
-			case 't':
-				print_warning("Showing task statistics");
-				operation_type = OP_TASKS;
-				break;
+			case 'a':
+				if (op_mode == OP_EXCS) {
+					excs_all = !excs_all;
+					if (excs_all)
+						print_warning("Showing all exceptions");
+					else
+						print_warning("Showing only hot exceptions");
+					break;
+				}
 			default:
-				print_warning("Unknown command: %c", c);
+				print_warning("Unknown command \"%c\", use \"h\" for help", c);
 				break;
 		}
Index: uspace/app/top/top.h
===================================================================
--- uspace/app/top/top.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/app/top/top.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -39,13 +39,29 @@
 #include <time.h>
 
-#define FRACTION_TO_FLOAT(float, a, b) { \
-	(float).upper = (a); \
-	(float).lower = (b); \
-}
+#define FRACTION_TO_FLOAT(float, a, b) \
+	do { \
+		if ((b) != 0) { \
+			(float).upper = (a); \
+			(float).lower = (b); \
+		} else { \
+			(float).upper = 0; \
+			(float).lower = 1; \
+		} \
+	} while (0)
 
-#define OP_TASKS  1
-#define OP_IPC    2
+typedef enum {
+	OP_TASKS,
+	OP_IPC,
+	OP_EXCS,
+	OP_HELP
+} op_mode_t;
 
-extern int operation_type;
+typedef enum {
+	SORT_TASK_CYCLES
+} sort_mode_t;
+
+extern op_mode_t op_mode;
+extern sort_mode_t sort_mode;
+extern bool excs_all;
 
 typedef struct {
@@ -60,8 +76,13 @@
 
 typedef struct {
+	fixed_float virtmem;
 	fixed_float ucycles;
 	fixed_float kcycles;
-	fixed_float virtmem;
 } perc_task_t;
+
+typedef struct {
+	fixed_float cycles;
+	fixed_float count;
+} perc_exc_t;
 
 typedef struct {
@@ -85,9 +106,19 @@
 	stats_task_t *tasks;
 	perc_task_t *tasks_perc;
+	size_t *tasks_map;
 	
 	size_t threads_count;
 	stats_thread_t *threads;
 	
+	size_t exceptions_count;
+	stats_exc_t *exceptions;
+	perc_exc_t *exceptions_perc;
+	
 	stats_physmem_t *physmem;
+	
+	uint64_t *ucycles_diff;
+	uint64_t *kcycles_diff;
+	uint64_t *ecycles_diff;
+	uint64_t *ecount_diff;
 } data_t;
 
Index: uspace/app/trace/syscalls.c
===================================================================
--- uspace/app/trace/syscalls.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/app/trace/syscalls.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -73,6 +73,5 @@
     [SYS_PHYSMEM_MAP] = { "physmem_map",		4,	V_ERRNO },
     [SYS_IOSPACE_ENABLE] = { "iospace_enable",		1,	V_ERRNO },
-    [SYS_PREEMPT_CONTROL] = { "preempt_control",	1,	V_ERRNO },
-	[SYS_INTERRUPT_ENABLE] = { "interrupt_enable",	2,	V_ERRNO },
+    [SYS_INTERRUPT_ENABLE] = { "interrupt_enable",	2,	V_ERRNO },
 
     [SYS_SYSINFO_GET_TAG] = { "sysinfo_get_tag",		2,	V_INTEGER },
Index: uspace/dist/src/sysel/demos/arith.sy
===================================================================
--- uspace/dist/src/sysel/demos/arith.sy	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/dist/src/sysel/demos/arith.sy	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -28,5 +28,5 @@
 
 class ArithmeticDemo is
-	fun Main() is
+	fun Main(), static is
 		-- Test addition, multiplication and precedence.
 		Builtin.Write("2*2 + 2*2 = ");
@@ -88,5 +88,5 @@
 
 	-- Return factorial of n.
-	fun Factorial(n : int) : int is
+	fun Factorial(n : int) : int, static is
 		var i : int;
 		var val : int;
Index: uspace/dist/src/sysel/demos/array.sy
===================================================================
--- uspace/dist/src/sysel/demos/array.sy	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/dist/src/sysel/demos/array.sy	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -28,5 +28,5 @@
 
 class ArrayDemo is
-	fun Main() is
+	fun Main(), static is
 		var a : int[,];
 		var i : int;
Index: uspace/dist/src/sysel/demos/autobox.sy
===================================================================
--- uspace/dist/src/sysel/demos/autobox.sy	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/dist/src/sysel/demos/autobox.sy	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -28,5 +28,5 @@
 
 class AutoboxingDemo is
-	fun Main() is
+	fun Main(), static is
 		var b : Bool;
 		var c : Char;
@@ -51,5 +51,5 @@
 	end
 
-	fun foo(args : Object[], packed) is
+	fun foo(args : Object[], packed), static is
 	end
 end
Index: uspace/dist/src/sysel/demos/count.sy
===================================================================
--- uspace/dist/src/sysel/demos/count.sy	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/dist/src/sysel/demos/count.sy	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -28,5 +28,5 @@
 
 class CountDemo is
-	fun Count(a : int; b : int) is
+	fun Count(a : int; b : int), static is
 		var i : int;
 
@@ -39,5 +39,5 @@
 	end
 
-	fun Main() is
+	fun Main(), static is
 		Count(0, 10);
 	end
Index: uspace/dist/src/sysel/demos/ctor.sy
===================================================================
--- uspace/dist/src/sysel/demos/ctor.sy	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/dist/src/sysel/demos/ctor.sy	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -28,5 +28,5 @@
 
 class ConstructorDemo is
-	fun Main() is
+	fun Main(), static is
 		var a : A;
 
Index: uspace/dist/src/sysel/demos/deleg.sy
===================================================================
--- uspace/dist/src/sysel/demos/deleg.sy	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/dist/src/sysel/demos/deleg.sy	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -28,5 +28,5 @@
 
 class DelegateDemo is
-	fun Main() is
+	fun Main(), static is
 		var demo : DelegateClass;
 
Index: uspace/dist/src/sysel/demos/enum.sy
===================================================================
--- uspace/dist/src/sysel/demos/enum.sy	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/dist/src/sysel/demos/enum.sy	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -28,5 +28,5 @@
 
 class EnumDemo is
-	fun Main() is
+	fun Main(), static is
 		var color : ChessColor;
 
Index: uspace/dist/src/sysel/demos/except.sy
===================================================================
--- uspace/dist/src/sysel/demos/except.sy	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/dist/src/sysel/demos/except.sy	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -28,10 +28,10 @@
 
 class ExceptionDemo is
-	fun foo() is
+	fun foo(), static is
 	        Builtin.WriteLine("Entered foo().");
 		raise new BaseException();
 	end
 
-	fun Main() is
+	fun Main(), static is
 		do
 			foo();
Index: uspace/dist/src/sysel/demos/gen.sy
===================================================================
--- uspace/dist/src/sysel/demos/gen.sy	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/dist/src/sysel/demos/gen.sy	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -30,5 +30,5 @@
 
 class GenericsDemo is
-	fun Main() is
+	fun Main(), static is
 		Builtin.WriteLine("Let's try some generics.");
 
Index: uspace/dist/src/sysel/demos/hello.sy
===================================================================
--- uspace/dist/src/sysel/demos/hello.sy	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/dist/src/sysel/demos/hello.sy	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -28,5 +28,5 @@
 
 class HelloWorld is
-	fun Main() is
+	fun Main(), static is
 		Builtin.WriteLine("Hello world!");
 	end
Index: uspace/dist/src/sysel/demos/hexec.sy
===================================================================
--- uspace/dist/src/sysel/demos/hexec.sy	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/dist/src/sysel/demos/hexec.sy	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -28,5 +28,5 @@
 
 class HelenOSExecDemo is
-	fun Main() is
+	fun Main(), static is
 		Task.Exec("/app/tester");
 		Task.Exec("/app/tester", "print1");
Index: uspace/dist/src/sysel/demos/htxtfile.sy
===================================================================
--- uspace/dist/src/sysel/demos/htxtfile.sy	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/dist/src/sysel/demos/htxtfile.sy	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -28,5 +28,5 @@
 
 class TextFileDemo is
-	fun Main() is
+	fun Main(), static is
 		var name : string;
 		var line : string;
Index: uspace/dist/src/sysel/demos/iface.sy
===================================================================
--- uspace/dist/src/sysel/demos/iface.sy	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
+++ uspace/dist/src/sysel/demos/iface.sy	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -0,0 +1,87 @@
+--
+-- 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:
+--
+-- o Redistributions of source code must retain the above copyright
+--   notice, this list of conditions and the following disclaimer.
+-- o Redistributions in binary form must reproduce the above copyright
+--   notice, this list of conditions and the following disclaimer in the
+--   documentation and/or other materials provided with the distribution.
+-- o The name of the author may not be used to endorse or promote products
+--   derived from this software without specific prior written permission.
+--
+-- THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+-- IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+-- OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+-- IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+-- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+-- NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+-- DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+-- THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+-- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+-- THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+--
+
+class InterfaceDemo is
+	fun Main(), static is
+		-- Create new instance of Foo
+		var f : Foo;
+		f = new Foo();
+
+		-- Variable of interface type
+		var g : IA/int;
+
+		-- Implicit conversion to interface implemented by Foo
+		g = f;
+
+		-- Explicit conversion of interface type IA/int to class type
+		-- Foo. Foo is implementing the interface IA/int.
+		f = g as Foo;
+
+		Builtin.WriteLine(g.a());
+	end
+end
+
+-- Generic interface implemented by class Foo
+interface IA/t is
+	fun a() : t;
+end
+
+-- Non-generic interface implemented by class Foo
+interface IB is
+	fun b();
+	prop P : int is
+		get;
+		set value;
+	end
+end
+
+-- Base class of Foo
+class A is
+end
+
+-- Class unrelated to Foo
+class B is
+end
+
+-- Foo is derived from A and implements IA/int and IB
+class Foo : A + IA/int + IB is
+	fun a() : int is
+		return 0;
+	end
+
+	fun b() is
+	end
+
+	prop P : int is
+		get is
+			return 1;
+		end
+		set value is
+		end
+	end
+end
Index: uspace/dist/src/sysel/demos/inherit.sy
===================================================================
--- uspace/dist/src/sysel/demos/inherit.sy	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/dist/src/sysel/demos/inherit.sy	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -43,5 +43,5 @@
 
 class InheritanceDemo is
-	fun Main() is
+	fun Main(), static is
 		var a : A;
 		var c : C;
Index: uspace/dist/src/sysel/demos/list.sy
===================================================================
--- uspace/dist/src/sysel/demos/list.sy	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/dist/src/sysel/demos/list.sy	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -29,5 +29,5 @@
 -- Using the List class from the library.
 class ListDemo is
-	fun Main() is
+	fun Main(), static is
 		var list : List/int;
 
@@ -39,10 +39,9 @@
 		list.Append(8);
 
-		var n : ListNode/int;
+		var e : IEnumerator/int;
 
-		n = list.First;
-		while n != nil do
-			Builtin.WriteLine(n.Data);
-			n = n.Next;
+		e = list.GetEnumerator();
+		while e.MoveNext() do
+			Builtin.WriteLine(e.Data);
 		end
 	end
Index: uspace/dist/src/sysel/demos/map.sy
===================================================================
--- uspace/dist/src/sysel/demos/map.sy	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/dist/src/sysel/demos/map.sy	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -29,5 +29,5 @@
 -- Using the Map class from the library.
 class MapDemo is
-	fun Main() is
+	fun Main(), static is
 		var map : Map/string/int;
 
@@ -39,8 +39,12 @@
 		map["four"] = 4;
 
-		Builtin.WriteLine(map["one"]);
-		Builtin.WriteLine(map["two"]);
-		Builtin.WriteLine(map["three"]);
-		Builtin.WriteLine(map["four"]);
+		var e : IEnumerator/string;
+
+		e = map.GetEnumerator();
+		while e.MoveNext() do
+			Builtin.Write(e.Data);
+			Builtin.Write(" -> ");
+			Builtin.WriteLine(map[e.Data]);
+		end
 	end
 end
Index: uspace/dist/src/sysel/demos/property.sy
===================================================================
--- uspace/dist/src/sysel/demos/property.sy	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/dist/src/sysel/demos/property.sy	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -98,5 +98,5 @@
 
 class PropertyDemo is
-	fun Main() is
+	fun Main(), static is
 		var a : Foo;
 		var i : int;
Index: uspace/dist/src/sysel/demos/string.sy
===================================================================
--- uspace/dist/src/sysel/demos/string.sy	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/dist/src/sysel/demos/string.sy	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -28,5 +28,5 @@
 
 class StringDemo is
-	fun Main() is
+	fun Main(), static is
 		-- Concatenate some strings.
 		Builtin.WriteLine("One-" + "two-" + "three!");
Index: uspace/dist/src/sysel/demos/svar.sy
===================================================================
--- uspace/dist/src/sysel/demos/svar.sy	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
+++ uspace/dist/src/sysel/demos/svar.sy	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -0,0 +1,59 @@
+--
+-- 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:
+--
+-- o Redistributions of source code must retain the above copyright
+--   notice, this list of conditions and the following disclaimer.
+-- o Redistributions in binary form must reproduce the above copyright
+--   notice, this list of conditions and the following disclaimer in the
+--   documentation and/or other materials provided with the distribution.
+-- o The name of the author may not be used to endorse or promote products
+--   derived from this software without specific prior written permission.
+--
+-- THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+-- IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+-- OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+-- IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+-- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+-- NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+-- DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+-- THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+-- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+-- THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+--
+
+class StaticPropertyDemo is
+	fun Main(), static is
+		-- Test static member variable
+		A.B.a = 1;
+		Builtin.WriteLine(A.B.a);
+		A.B.a = 2;
+		Builtin.WriteLine(A.B.a);
+
+		-- Test static property
+		A.B.P = 1;
+		Builtin.WriteLine(A.B.P);
+		A.B.P = 2;
+		Builtin.WriteLine(A.B.P);
+	end
+end
+
+class A is
+	class B is
+		var a : int, static;
+
+		prop P : int, static is
+			get is
+				return a;
+			end
+
+			set value is
+				a = value;
+			end
+		end
+	end
+end
Index: uspace/dist/src/sysel/demos/varargs.sy
===================================================================
--- uspace/dist/src/sysel/demos/varargs.sy	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/dist/src/sysel/demos/varargs.sy	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -33,5 +33,5 @@
 	-- with the attribute 'packed'.
 	--
-	fun Print(args : string[], packed) is
+	fun Print(args : string[], packed), static is
 		var i : int;
 		var error : bool;
@@ -53,5 +53,5 @@
 	end
 
-	fun Main() is
+	fun Main(), static is
 		Print("One", "Two", "Three", "Four", "Five");
 	end
Index: uspace/dist/src/sysel/lib/arith.sy
===================================================================
--- uspace/dist/src/sysel/lib/arith.sy	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/dist/src/sysel/lib/arith.sy	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -29,5 +29,5 @@
 class Arith is
 	-- Return factorial of n.
-	fun Factorial(n : int) : int is
+	fun Factorial(n : int) : int, static is
 		var i : int;
 		var val : int;
Index: uspace/dist/src/sysel/lib/boxed.sy
===================================================================
--- uspace/dist/src/sysel/lib/boxed.sy	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/dist/src/sysel/lib/boxed.sy	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -38,8 +38,26 @@
 class Char is
 	var Value : char;
+
+	fun get_as_string() : string, builtin;
+
+	-- String representation.
+	prop AsString : string is
+		get is
+			return get_as_string();
+		end
+	end
 end
 
 class Int is
 	var Value : int;
+
+	fun get_as_string() : string, builtin;
+
+	-- String representation.
+	prop AsString : string is
+		get is
+			return get_as_string();
+		end
+	end
 end
 
Index: uspace/dist/src/sysel/lib/ienum.sy
===================================================================
--- uspace/dist/src/sysel/lib/ienum.sy	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
+++ uspace/dist/src/sysel/lib/ienum.sy	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -0,0 +1,41 @@
+--
+-- 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:
+--
+-- o Redistributions of source code must retain the above copyright
+--   notice, this list of conditions and the following disclaimer.
+-- o Redistributions in binary form must reproduce the above copyright
+--   notice, this list of conditions and the following disclaimer in the
+--   documentation and/or other materials provided with the distribution.
+-- o The name of the author may not be used to endorse or promote products
+--   derived from this software without specific prior written permission.
+--
+-- THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+-- IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+-- OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+-- IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+-- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+-- NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+-- DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+-- THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+-- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+-- THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+--
+
+-- Enumerable collection interface.
+interface IEnumerable/tdata is
+	fun GetEnumerator() : IEnumerator/tdata;
+end
+
+-- Enumerator interface.
+interface IEnumerator/tdata is
+	fun MoveNext() : bool;
+
+	prop Data : tdata is
+		get;
+	end
+end
Index: uspace/dist/src/sysel/lib/libflist
===================================================================
--- uspace/dist/src/sysel/lib/libflist	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/dist/src/sysel/lib/libflist	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -1,4 +1,5 @@
 arith.sy
 boxed.sy
+ienum.sy
 list.sy
 map.sy
Index: uspace/dist/src/sysel/lib/list.sy
===================================================================
--- uspace/dist/src/sysel/lib/list.sy	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/dist/src/sysel/lib/list.sy	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -28,5 +28,5 @@
 
 -- Doubly-linked list.
-class List/t is
+class List/t : IEnumerable/t is
 	var head : ListNode/t;
 
@@ -59,6 +59,11 @@
 	prop First : ListNode/t is
 		get is
-		    return get_first();
+			return get_first();
 		end
+	end
+
+	-- Return first node in the list or @c nil if there is none.
+	fun GetEnumerator() : IEnumerator/t is
+		return new ListEnumerator/t(get_first());
 	end
 
@@ -131,4 +136,32 @@
 		end
 	end
+end
 
+class ListEnumerator/t : IEnumerator/t is
+	var first : ListNode/t;
+	var current : ListNode/t;
+	var started : bool;
+
+	new(first_node : ListNode/t) is
+		first = first_node;
+		current = nil;
+		started = false;
+	end
+
+	fun MoveNext() : bool is
+		if started then
+			current = current.Next;
+		else
+			current = first;
+			started = true;
+		end
+
+		return current != nil;
+	end
+
+	prop Data : t is
+		get is
+			return current.Data;
+		end
+	end
 end
Index: uspace/dist/src/sysel/lib/map.sy
===================================================================
--- uspace/dist/src/sysel/lib/map.sy	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/dist/src/sysel/lib/map.sy	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -91,4 +91,8 @@
 		end
 	end
+
+	fun GetEnumerator() : IEnumerator/tkey is
+		return new MapEnumerator/tkey/tvalue(data.get_first());
+	end
 end
 
@@ -97,2 +101,31 @@
 	var Value : tvalue;
 end
+
+class MapEnumerator/tkey/tvalue : IEnumerator/tkey is
+	var first : ListNode/(MapPair/tkey/tvalue);
+	var current : ListNode/(MapPair/tkey/tvalue);
+	var started : bool;
+
+	new(first_node : ListNode/(MapPair/tkey/tvalue)) is
+		first = first_node;
+		current = nil;
+		started = false;
+	end
+
+	fun MoveNext() : bool is
+		if started then
+			current = current.Next;
+		else
+			current = first;
+			started = true;
+		end
+
+		return current != nil;
+	end
+
+	prop Data : tkey is
+		get is
+			return current.Data.Key;
+		end
+	end
+end
Index: uspace/lib/c/Makefile
===================================================================
--- uspace/lib/c/Makefile	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/lib/c/Makefile	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -87,8 +87,12 @@
 	generic/ipc.c \
 	generic/async.c \
+	generic/async_rel.c \
 	generic/loader.c \
 	generic/getopt.c \
 	generic/adt/list.o \
 	generic/adt/hash_table.o \
+	generic/adt/dynamic_fifo.c \
+	generic/adt/measured_strings.c \
+	generic/adt/char_map.c \
 	generic/time.c \
 	generic/err.c \
@@ -98,6 +102,14 @@
 	generic/vfs/vfs.c \
 	generic/vfs/canonify.c \
+	generic/net/inet.c \
+	generic/net/icmp_common.c \
+	generic/net/icmp_api.c \
+	generic/net/modules.c \
+	generic/net/packet.c \
+	generic/net/socket_client.c \
+	generic/net/socket_parse.c \
 	generic/stacktrace.c \
 	generic/arg_parse.c \
+	generic/sort.c \
 	generic/stats.c
 
Index: pace/lib/c/Makefile.toolchain
===================================================================
--- uspace/lib/c/Makefile.toolchain	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ 	(revision )
@@ -1,128 +1,0 @@
-#
-# Copyright (C) 2005 Martin Decky
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions
-# are met:
-#
-# - Redistributions of source code must retain the above copyright
-#   notice, this list of conditions and the following disclaimer.
-# - Redistributions in binary form must reproduce the above copyright
-#   notice, this list of conditions and the following disclaimer in the
-#   documentation and/or other materials provided with the distribution.
-# - The name of the author may not be used to endorse or promote products
-#   derived from this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
-# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
-# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
-# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
-# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
-# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-#
-
-GCC_CFLAGS = -I$(LIBC_PREFIX)/include -O3 -imacros $(LIBC_PREFIX)/../../../config.h \
-	-fexec-charset=UTF-8 -fwide-exec-charset=UTF-32$(ENDIANESS) \
-	-finput-charset=UTF-8 -ffreestanding -fno-builtin -nostdlib -nostdinc \
-	-Wall -Wextra -Wno-unused-parameter -Wmissing-prototypes \
-	-Werror-implicit-function-declaration -pipe -g -D__$(ENDIANESS)__
-
-ICC_CFLAGS = -I$(LIBC_PREFIX)/include -O3 -imacros $(LIBC_PREFIX)/../../../config.h \
-	-fexec-charset=UTF-8 -fwide-exec-charset=UTF-32$(ENDIANESS) \
-	-finput-charset=UTF-8 -ffreestanding -fno-builtin -nostdlib -nostdinc \
-	-Wall -Wextra -Wno-unused-parameter -Wmissing-prototypes \
-	-Werror-implicit-function-declaration -pipe -g -D__$(ENDIANESS)__
-
-CLANG_CFLAGS = -I$(LIBC_PREFIX)/include -O3 -imacros $(LIBC_PREFIX)/../../../config.h \
-	-fexec-charset=UTF-8 -fwide-exec-charset=UTF-32$(ENDIANESS) \
-	-finput-charset=UTF-8 -ffreestanding -fno-builtin -nostdlib -nostdinc \
-	-Wall -Wextra -Wno-unused-parameter -Wmissing-prototypes \
-	-Werror-implicit-function-declaration -pipe -g -arch $(CLANG_ARCH) \
-	-D__$(ENDIANESS)__
-
-LFLAGS = -M -N $(SOFTINT_PREFIX)/libsoftint.a
-AFLAGS =
-
-## Cross-toolchain prefix
-#
-
-ifndef CROSS_PREFIX
-	CROSS_PREFIX = /usr/local
-endif
-
-## Setup platform configuration
-#
-
--include $(LIBC_PREFIX)/../../../Makefile.config
--include $(LIBC_PREFIX)/../../../config.defs
--include $(LIBC_PREFIX)/arch/$(UARCH)/Makefile.inc
-
-## Simple detection of the host system
-#
-HOST = $(shell uname)
-
-## On Solaris, some utilities have different names
-#
-ifeq ($(HOST),SunOS)
-	BINUTILS_PREFIX = "g"
-else
-	BINUTILS_PREFIX = ""
-endif
-
-## Toolchain configuration
-#
-
-JOBFILE = $(LIBC_PREFIX)/../../../tools/jobfile.py
-
-ifeq ($(COMPILER),gcc_cross)
-	CC = $(TOOLCHAIN_DIR)/$(TARGET)-gcc
-	GCC = $(CC)
-	AS = $(TOOLCHAIN_DIR)/$(TARGET)-as
-	LD = $(TOOLCHAIN_DIR)/$(TARGET)-ld
-	AR = $(TOOLCHAIN_DIR)/$(TARGET)-ar
-	OBJCOPY = $(TOOLCHAIN_DIR)/$(TARGET)-objcopy
-	OBJDUMP = $(TOOLCHAIN_DIR)/$(TARGET)-objdump
-	CFLAGS = $(GCC_CFLAGS)
-	DEPEND_DEFS = $(DEFS) $(CONFIG_DEFS)
-endif
-
-ifeq ($(COMPILER),gcc_native)
-	CC = gcc
-	GCC = $(CC)
-	AS = $(BINUTILS_PREFIX)as
-	LD = $(BINUTILS_PREFIX)ld
-	AR = $(BINUTILS_PREFIX)ar
-	OBJCOPY = $(BINUTILS_PREFIX)objcopy
-	OBJDUMP = $(BINUTILS_PREFIX)objdump
-	CFLAGS = $(GCC_CFLAGS)
-	DEPEND_DEFS = $(DEFS) $(CONFIG_DEFS)
-endif
-
-ifeq ($(COMPILER),icc)
-	CC = icc
-	GCC = gcc
-	AS = as
-	LD = ld
-	AR = ar
-	OBJCOPY = objcopy
-	OBJDUMP = objdump
-	CFLAGS = $(ICC_CFLAGS)
-	DEPEND_DEFS = $(DEFS) $(CONFIG_DEFS)
-endif
-
-ifeq ($(COMPILER),clang)
-	CC = clang
-	GCC = gcc
-	AS = $(BINUTILS_PREFIX)as
-	LD = $(BINUTILS_PREFIX)ld
-	AR = $(BINUTILS_PREFIX)ar
-	OBJCOPY = $(BINUTILS_PREFIX)objcopy
-	OBJDUMP = $(BINUTILS_PREFIX)objdump
-	CFLAGS = $(CLANG_CFLAGS)
-	DEPEND_DEFS = $(DEFS) $(CONFIG_DEFS)
-endif
Index: pace/lib/c/arch/abs32le/include/limits.h
===================================================================
--- uspace/lib/c/arch/abs32le/include/limits.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ 	(revision )
@@ -1,51 +1,0 @@
-/*
- * Copyright (c) 2010 Martin Decky
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/** @addtogroup libcabs32le
- * @{
- */
-/** @file
- */
-
-#ifndef LIBC_abs32le__LIMITS_H_
-#define LIBC_abs32le__LIMITS_H_
-
-#define LONG_MIN MIN_INT32
-#define LONG_MAX MAX_INT32
-#define ULONG_MIN MIN_UINT32
-#define ULONG_MAX MAX_UINT32
-
-#define SIZE_MIN MIN_UINT32
-#define SIZE_MAX MAX_UINT32
-#define SSIZE_MIN MIN_INT32
-#define SSIZE_MAX MAX_INT32
-
-#endif
-
-/** @}
- */
Index: uspace/lib/c/arch/abs32le/include/types.h
===================================================================
--- uspace/lib/c/arch/abs32le/include/types.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/lib/c/arch/abs32le/include/types.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -40,4 +40,10 @@
 #include <libarch/common.h>
 
+#define SIZE_MIN  UINT32_MIN
+#define SIZE_MAX  UINT32_MAX
+
+#define SSIZE_MIN  INT32_MIN
+#define SSIZE_MAX  INT32_MAX
+
 typedef uint32_t sysarg_t;
 
Index: pace/lib/c/arch/amd64/include/limits.h
===================================================================
--- uspace/lib/c/arch/amd64/include/limits.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ 	(revision )
@@ -1,51 +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 libcamd64
- * @{
- */
-/** @file
- */
-
-#ifndef LIBC_amd64_LIMITS_H_
-#define LIBC_amd64_LIMITS_H_
-
-#define LONG_MIN MIN_INT64
-#define LONG_MAX MAX_INT64
-#define ULONG_MIN MIN_UINT64
-#define ULONG_MAX MAX_UINT64
-
-#define SIZE_MIN MIN_UINT64
-#define SIZE_MAX MAX_UINT64
-#define SSIZE_MIN MIN_INT64
-#define SSIZE_MAX MAX_INT64
-
-#endif
-
-/** @}
- */
Index: uspace/lib/c/arch/amd64/include/types.h
===================================================================
--- uspace/lib/c/arch/amd64/include/types.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/lib/c/arch/amd64/include/types.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -40,4 +40,10 @@
 #include <libarch/common.h>
 
+#define SIZE_MIN  UINT64_MIN
+#define SIZE_MAX  UINT64_MAX
+
+#define SSIZE_MIN  INT64_MIN
+#define SSIZE_MAX  INT64_MAX
+
 typedef uint64_t sysarg_t;
 
Index: pace/lib/c/arch/arm32/include/limits.h
===================================================================
--- uspace/lib/c/arch/arm32/include/limits.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ 	(revision )
@@ -1,52 +1,0 @@
-/*
- * Copyright (c) 2007 Michal Kebrt
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/** @addtogroup libcarm32
- * @{
- */
-/** @file
- *  @brief Limits declarations.
- */
-
-#ifndef LIBC_arm32__LIMITS_H_
-#define LIBC_arm32__LIMITS_H_
-
-#define LONG_MIN MIN_INT32
-#define LONG_MAX MAX_INT32
-#define ULONG_MIN MIN_UINT32
-#define ULONG_MAX MAX_UINT32
-
-#define SIZE_MIN MIN_UINT32
-#define SIZE_MAX MAX_UINT32
-#define SSIZE_MIN MIN_INT32
-#define SSIZE_MAX MAX_INT32
-
-#endif
-
-/** @}
- */
Index: uspace/lib/c/arch/arm32/include/types.h
===================================================================
--- uspace/lib/c/arch/arm32/include/types.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/lib/c/arch/arm32/include/types.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -41,4 +41,10 @@
 #include <libarch/common.h>
 
+#define SIZE_MIN  UINT32_MIN
+#define SIZE_MAX  UINT32_MAX
+
+#define SSIZE_MIN  INT32_MIN
+#define SSIZE_MAX  INT32_MAX
+
 typedef uint32_t sysarg_t;
 
Index: pace/lib/c/arch/ia32/include/limits.h
===================================================================
--- uspace/lib/c/arch/ia32/include/limits.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ 	(revision )
@@ -1,51 +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 libcia32
- * @{
- */
-/** @file
- */
-
-#ifndef LIBC_ia32__LIMITS_H_
-#define LIBC_ia32__LIMITS_H_
-
-#define LONG_MIN MIN_INT32
-#define LONG_MAX MAX_INT32
-#define ULONG_MIN MIN_UINT32
-#define ULONG_MAX MAX_UINT32
-
-#define SIZE_MIN MIN_UINT32
-#define SIZE_MAX MAX_UINT32
-#define SSIZE_MIN MIN_INT32
-#define SSIZE_MAX MAX_INT32
-
-#endif
-
-/** @}
- */
Index: uspace/lib/c/arch/ia32/include/types.h
===================================================================
--- uspace/lib/c/arch/ia32/include/types.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/lib/c/arch/ia32/include/types.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -40,4 +40,10 @@
 #include <libarch/common.h>
 
+#define SIZE_MIN  UINT32_MIN
+#define SIZE_MAX  UINT32_MAX
+
+#define SSIZE_MIN  INT32_MIN
+#define SSIZE_MAX  INT32_MAX
+
 typedef uint32_t sysarg_t;
 
Index: pace/lib/c/arch/ia64/include/limits.h
===================================================================
--- uspace/lib/c/arch/ia64/include/limits.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ 	(revision )
@@ -1,51 +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 libcia64
- * @{
- */
-/** @file
- */
-
-#ifndef LIBC_ia64_LIMITS_H_
-#define LIBC_ia64_LIMITS_H_
-
-#define LONG_MIN MIN_INT64
-#define LONG_MAX MAX_INT64
-#define ULONG_MIN MIN_UINT64
-#define ULONG_MAX MAX_UINT64
-
-#define SIZE_MIN MIN_UINT64
-#define SIZE_MAX MAX_UINT64
-#define SSIZE_MIN MIN_INT64
-#define SSIZE_MAX MAX_INT64
-
-#endif
-
-/** @}
- */
Index: uspace/lib/c/arch/ia64/include/types.h
===================================================================
--- uspace/lib/c/arch/ia64/include/types.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/lib/c/arch/ia64/include/types.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -40,4 +40,10 @@
 #include <libarch/common.h>
 
+#define SIZE_MIN  UINT64_MIN
+#define SIZE_MAX  UINT64_MAX
+
+#define SSIZE_MIN  INT64_MIN
+#define SSIZE_MAX  INT64_MAX
+
 typedef struct {
 	uint64_t lo;
Index: uspace/lib/c/arch/ia64/src/entry.s
===================================================================
--- uspace/lib/c/arch/ia64/src/entry.s	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/lib/c/arch/ia64/src/entry.s	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -39,5 +39,5 @@
 __entry:
 	alloc loc0 = ar.pfs, 0, 1, 2, 0
-	movl r1 = _gp
+	movl gp = _gp
 
 	# Pass PCB pointer as the first argument to __main
Index: uspace/lib/c/arch/ia64/src/thread_entry.s
===================================================================
--- uspace/lib/c/arch/ia64/src/thread_entry.s	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/lib/c/arch/ia64/src/thread_entry.s	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -37,5 +37,5 @@
 	alloc loc0 = ar.pfs, 0, 1, 1, 0
 
-	movl r1 = _gp
+	movl gp = _gp
 	
 	#
Index: pace/lib/c/arch/mips32/include/limits.h
===================================================================
--- uspace/lib/c/arch/mips32/include/limits.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ 	(revision )
@@ -1,52 +1,0 @@
-/*
- * Copyright (c) 2006 Josef Cejka
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/** @addtogroup libcmips32
- * @{
- */
-/** @file
- * @ingroup libcmips32eb
- */
-
-#ifndef LIBC_mips32__LIMITS_H_
-#define LIBC_mips32__LIMITS_H_
-
-#define LONG_MIN MIN_INT32
-#define LONG_MAX MAX_INT32
-#define ULONG_MIN MIN_UINT32
-#define ULONG_MAX MAX_UINT32
-
-#define SIZE_MIN MIN_UINT32
-#define SIZE_MAX MAX_UINT32
-#define SSIZE_MIN MIN_INT32
-#define SSIZE_MAX MAX_INT32
-
-#endif
-
-/** @}
- */
Index: uspace/lib/c/arch/mips32/include/types.h
===================================================================
--- uspace/lib/c/arch/mips32/include/types.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/lib/c/arch/mips32/include/types.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -41,4 +41,10 @@
 #include <libarch/common.h>
 
+#define SIZE_MIN  UINT32_MIN
+#define SIZE_MAX  UINT32_MAX
+
+#define SSIZE_MIN  INT32_MIN
+#define SSIZE_MAX  INT32_MAX
+
 typedef uint32_t sysarg_t;
 
Index: pace/lib/c/arch/mips32eb/include/limits.h
===================================================================
--- uspace/lib/c/arch/mips32eb/include/limits.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ 	(revision )
@@ -1,1 +1,0 @@
-../../mips32/include/limits.h
Index: pace/lib/c/arch/ppc32/include/limits.h
===================================================================
--- uspace/lib/c/arch/ppc32/include/limits.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ 	(revision )
@@ -1,51 +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 libcppc32
- * @{
- */
-/** @file
- */
-
-#ifndef LIBC_ppc32_LIMITS_H_
-#define LIBC_ppc32_LIMITS_H_
-
-#define LONG_MIN MIN_INT32
-#define LONG_MAX MAX_INT32
-#define ULONG_MIN MIN_UINT32
-#define ULONG_MAX MAX_UINT32
-
-#define SIZE_MIN MIN_UINT32
-#define SIZE_MAX MAX_UINT32
-#define SSIZE_MIN MIN_INT32
-#define SSIZE_MAX MAX_INT32
-
-#endif
-
-/** @}
- */
Index: uspace/lib/c/arch/ppc32/include/types.h
===================================================================
--- uspace/lib/c/arch/ppc32/include/types.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/lib/c/arch/ppc32/include/types.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -40,4 +40,10 @@
 #include <libarch/common.h>
 
+#define SIZE_MIN  UINT32_MIN
+#define SIZE_MAX  UINT32_MAX
+
+#define SSIZE_MIN  INT32_MIN
+#define SSIZE_MAX  INT32_MAX
+
 typedef uint32_t sysarg_t;
 
Index: uspace/lib/c/arch/sparc64/Makefile.common
===================================================================
--- uspace/lib/c/arch/sparc64/Makefile.common	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/lib/c/arch/sparc64/Makefile.common	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -27,5 +27,5 @@
 #
 
-GCC_CFLAGS += -mcpu=ultrasparc -m64
+GCC_CFLAGS += -mcpu=ultrasparc -m64 -mcmodel=medlow
 LFLAGS = -no-check-sections
 
Index: pace/lib/c/arch/sparc64/include/limits.h
===================================================================
--- uspace/lib/c/arch/sparc64/include/limits.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ 	(revision )
@@ -1,51 +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 libcsparc64
- * @{
- */
-/** @file
- */
-
-#ifndef LIBC_sparc64_LIMITS_H_
-#define LIBC_sparc64_LIMITS_H_
-
-#define LONG_MIN MIN_INT64
-#define LONG_MAX MAX_INT64
-#define ULONG_MIN MIN_UINT64
-#define ULONG_MAX MAX_UINT64
-
-#define SIZE_MIN MIN_UINT64
-#define SIZE_MAX MAX_UINT64
-#define SSIZE_MIN MIN_INT64
-#define SSIZE_MAX MAX_INT64
-
-#endif
-
-/** @}
- */
Index: uspace/lib/c/arch/sparc64/include/types.h
===================================================================
--- uspace/lib/c/arch/sparc64/include/types.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/lib/c/arch/sparc64/include/types.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -40,4 +40,10 @@
 #include <libarch/common.h>
 
+#define SIZE_MIN  UINT64_MIN
+#define SIZE_MAX  UINT64_MAX
+
+#define SSIZE_MIN  INT64_MIN
+#define SSIZE_MAX  INT64_MAX
+
 typedef uint64_t sysarg_t;
 
Index: uspace/lib/c/arch/sparc64/src/thread_entry.s
===================================================================
--- uspace/lib/c/arch/sparc64/src/thread_entry.s	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/lib/c/arch/sparc64/src/thread_entry.s	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -38,8 +38,12 @@
 	# Create the first stack frame.
 	#
+	save %sp, -176, %sp
+	flushw
+	add %g0, -0x7ff, %fp
 
-	#save %sp, -176, %sp
-	#flushw
-	#add %g0, -0x7ff, %fp
+	#
+	# Propagate the input arguments to the new window.
+	#
+	mov %i0, %o0
 
 	sethi %hi(_gp), %l7
Index: uspace/lib/c/generic/adt/char_map.c
===================================================================
--- uspace/lib/c/generic/adt/char_map.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
+++ uspace/lib/c/generic/adt/char_map.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -0,0 +1,347 @@
+/*
+ * Copyright (c) 2009 Lukas Mejdrech
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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
+ *  Character string to integer map implementation.
+ *  @see char_map.h
+ */
+
+#include <adt/char_map.h>
+
+#include <errno.h>
+#include <malloc.h>
+#include <mem.h>
+#include <unistd.h>
+
+/** Internal magic value for a consistency check. */
+#define CHAR_MAP_MAGIC_VALUE	0x12345611
+
+/** Adds the value with the key to the map.
+ *
+ * Creates new nodes to map the key.
+ *
+ * @param[in,out] map	The character string to integer map.
+ * @param[in] identifier The key zero ('\0') terminated character string.
+ *			The key character string is processed until the first
+ *			terminating zero ('\0') character after the given
+ *			length is found.
+ * @param[in] length	The key character string length. The parameter may be
+ *			zero (0) which means that the string is processed until
+ *			the terminating zero ('\0') character is found.
+ * @param[in] value	The integral value to be stored for the key character
+ *			string.
+ * @returns		EOK on success.
+ * @returns		ENOMEM if there is not enough memory left.
+ * @returns		EEXIST if the key character string is already used.
+ */
+static int
+char_map_add_item(char_map_ref map, const char *identifier, size_t length,
+    const int value)
+{
+	if (map->next == (map->size - 1)) {
+		char_map_ref *tmp;
+
+		tmp = (char_map_ref *) realloc(map->items,
+		    sizeof(char_map_ref) * 2 * map->size);
+		if (!tmp)
+			return ENOMEM;
+
+		map->size *= 2;
+		map->items = tmp;
+	}
+
+	map->items[map->next] = (char_map_ref) malloc(sizeof(char_map_t));
+	if (!map->items[map->next])
+		return ENOMEM;
+
+	if (char_map_initialize(map->items[map->next]) != EOK) {
+		free(map->items[map->next]);
+		map->items[map->next] = NULL;
+		return ENOMEM;
+	}
+
+	map->items[map->next]->c = * identifier;
+	++ identifier;
+	++ map->next;
+	if ((length > 1) || ((length == 0) && (*identifier))) {
+		map->items[map->next - 1]->value = CHAR_MAP_NULL;
+		return char_map_add_item(map->items[map->next - 1], identifier,
+		    length ? length - 1 : 0, value);
+	} else {
+		map->items[map->next - 1]->value = value;
+	}
+
+	return EOK;
+}
+
+/** Checks if the map is valid.
+ *
+ * @param[in] map	The character string to integer map.
+ * @returns		TRUE if the map is valid.
+ * @returns		FALSE otherwise.
+ */
+static int char_map_is_valid(const char_map_ref map)
+{
+	return map && (map->magic == CHAR_MAP_MAGIC_VALUE);
+}
+
+/** Adds the value with the key to the map.
+ *
+ * @param[in,out] map	The character string to integer map.
+ * @param[in] identifier The key zero ('\0') terminated character string. The
+ *			key character string is processed until the first
+ *			terminating zero ('\0') character after the given
+ *			length is found.
+ * @param[in] length	The key character string length. The parameter may be
+ *			zero (0) which means that the string is processed until
+ *			the terminating zero ('\\0') character is found.
+ * @param[in] value	The integral value to be stored for the key character
+ *			string.
+ * @returns		EOK on success.
+ * @returns		EINVAL if the map is not valid.
+ * @returns		EINVAL if the identifier parameter is NULL.
+ * @returns		EINVAL if the length parameter zero (0) and the
+ *			identifier parameter is an empty character string (the
+ *			first character is the terminating zero ('\0')
+ *			character.
+ * @returns		EEXIST if the key character string is already used.
+ * @returns		Other error codes as defined for the
+ *			char_map_add_item() function.
+ */
+int
+char_map_add(char_map_ref map, const char *identifier, size_t length,
+    const int value)
+{
+	if (char_map_is_valid(map) && (identifier) &&
+	    ((length) || (*identifier))) {
+		int index;
+
+		for (index = 0; index < map->next; ++ index) {
+			if (map->items[index]->c != *identifier)
+				continue;
+				
+			++ identifier;
+			if((length > 1) || ((length == 0) && (*identifier))) {
+				return char_map_add(map->items[index],
+				    identifier, length ? length - 1 : 0, value);
+			} else {
+				if (map->items[index]->value != CHAR_MAP_NULL)
+					return EEXISTS;
+
+				map->items[index]->value = value;
+				return EOK;
+			}
+		}
+		return char_map_add_item(map, identifier, length, value);
+	}
+
+	return EINVAL;
+}
+
+/** Clears and destroys the map.
+ *
+ * @param[in,out] map	The character string to integer map.
+ */
+void char_map_destroy(char_map_ref map)
+{
+	if (char_map_is_valid(map)) {
+		int index;
+
+		map->magic = 0;
+		for (index = 0; index < map->next; ++index)
+			char_map_destroy(map->items[index]);
+
+		free(map->items);
+		map->items = NULL;
+	}
+}
+
+/** Returns the node assigned to the key from the map.
+ *
+ * @param[in] map	The character string to integer map.
+ * @param[in] identifier The key zero ('\0') terminated character string. The
+ *			key character string is processed until the first
+ *			terminating zero ('\0') character after the given length
+ *			is found.
+ * @param[in] length	The key character string length. The parameter may be
+ *			zero (0) which means that the string is processed until
+ *			the terminating zero ('\0') character is found.
+ * @returns		The node holding the integral value assigned to the key
+ *			character string.
+ * @returns		NULL if the key is not assigned a node.
+ */
+static char_map_ref
+char_map_find_node(const char_map_ref map, const char *identifier,
+    size_t length)
+{
+	if (!char_map_is_valid(map))
+		return NULL;
+
+	if (length || (*identifier)) {
+		int index;
+
+		for (index = 0; index < map->next; ++index) {
+			if (map->items[index]->c == *identifier) {
+				++identifier;
+				if (length == 1)
+					return map->items[index];
+
+				return char_map_find_node(map->items[index],
+				    identifier, length ? length - 1 : 0);
+			}
+		}
+
+		return NULL;
+	}
+
+	return map;
+}
+
+/** Excludes the value assigned to the key from the map.
+ *
+ * The entry is cleared from the map.
+ *
+ * @param[in,out] map	The character string to integer map.
+ * @param[in] identifier The key zero ('\0') terminated character string. The
+ *			key character string is processed until the first
+ *			terminating zero ('\0') character after the given length
+ *			is found.
+ * @param[in] length	The key character string length. The parameter may be
+ *			zero (0) which means that the string is processed until
+ *			the terminating zero ('\0') character is found.
+ * @returns		The integral value assigned to the key character string.
+ * @returns		CHAR_MAP_NULL if the key is not assigned a value.
+ */
+int char_map_exclude(char_map_ref map, const char *identifier, size_t length)
+{
+	char_map_ref node;
+
+	node = char_map_find_node(map, identifier, length);
+	if (node) {
+		int value;
+
+		value = node->value;
+		node->value = CHAR_MAP_NULL;
+		return value;
+	}
+	return CHAR_MAP_NULL;
+}
+
+/** Returns the value assigned to the key from the map.
+ *
+ *  @param[in] map	The character string to integer map.
+ *  @param[in] identifier The key zero ('\0') terminated character string. The
+ *			key character string is processed until the first
+ *			terminating zero ('\0') character after the given length
+ *			is found.
+ *  @param[in] length	The key character string length. The parameter may be
+ *			zero (0) which means that the string is processed until
+ *			the terminating zero ('\0') character is found.
+ *  @returns		The integral value assigned to the key character string.
+ *  @returns		CHAR_MAP_NULL if the key is not assigned a value.
+ */
+int char_map_find(const char_map_ref map, const char *identifier, size_t length)
+{
+	char_map_ref node;
+
+	node = char_map_find_node(map, identifier, length);
+	return node ? node->value : CHAR_MAP_NULL;
+}
+
+/** Initializes the map.
+ *
+ *  @param[in,out] map	The character string to integer map.
+ *  @returns		EOK on success.
+ *  @returns		EINVAL if the map parameter is NULL.
+ *  @returns		ENOMEM if there is not enough memory left.
+ */
+int char_map_initialize(char_map_ref map)
+{
+	if (!map)
+		return EINVAL;
+
+	map->c = '\0';
+	map->value = CHAR_MAP_NULL;
+	map->size = 2;
+	map->next = 0;
+
+	map->items = malloc(sizeof(char_map_ref) * map->size);
+	if (!map->items) {
+		map->magic = 0;
+		return ENOMEM;
+	}
+
+	map->items[map->next] = NULL;
+	map->magic = CHAR_MAP_MAGIC_VALUE;
+
+	return EOK;
+}
+
+/** Adds or updates the value with the key to the map.
+ *
+ *  @param[in,out] map	The character string to integer map.
+ *  @param[in] identifier The key zero ('\0') terminated character string. The
+ *			key character string is processed until the first
+ *			terminating zero ('\0') character after the given length
+ *			is found.
+ *  @param[in] length	The key character string length. The parameter may be
+ *			zero (0) which means that the string is processed until
+ *			the terminating zero ('\0') character is found.
+ *  @param[in] value	The integral value to be stored for the key character
+ *			string.
+ *  @returns		EOK on success.
+ *  @returns		EINVAL if the map is not valid.
+ *  @returns		EINVAL if the identifier parameter is NULL.
+ *  @returns		EINVAL if the length parameter zero (0) and the
+ *			identifier parameter is an empty character string (the
+ *			first character is the terminating zero ('\0) character.
+ *  @returns		EEXIST if the key character string is already used.
+ *  @returns		Other error codes as defined for the char_map_add_item()
+ *			function.
+ */
+int
+char_map_update(char_map_ref map, const char *identifier, const size_t length,
+    const int value)
+{
+	char_map_ref node;
+
+	node = char_map_find_node(map, identifier, length);
+	if (node) {
+		node->value = value;
+		return EOK;
+	}
+	
+	return char_map_add(map, identifier, length, value);
+}
+
+/** @}
+ */
Index: uspace/lib/c/generic/adt/dynamic_fifo.c
===================================================================
--- uspace/lib/c/generic/adt/dynamic_fifo.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
+++ uspace/lib/c/generic/adt/dynamic_fifo.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -0,0 +1,206 @@
+/*
+ * Copyright (c) 2009 Lukas Mejdrech
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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
+ * Dynamic first in first out positive integer queue implementation.
+ */
+
+#include <errno.h>
+#include <malloc.h>
+#include <mem.h>
+
+#include <adt/dynamic_fifo.h>
+
+/** Internal magic value for a consistency check. */
+#define DYN_FIFO_MAGIC_VALUE	0x58627659
+
+/** Returns the next queue index.
+ *
+ * The queue field is circular.
+ *
+ * @param[in] fifo	The dynamic queue.
+ * @param[in] index	The actual index to be shifted.
+ */
+#define NEXT_INDEX(fifo, index)	(((index) + 1) % ((fifo)->size + 1))
+
+/** Checks if the queue is valid.
+ *
+ * @param[in] fifo	The dynamic queue.
+ * @returns		TRUE if the queue is valid.
+ * @returns		FALSE otherwise.
+ */
+static int dyn_fifo_is_valid(dyn_fifo_ref fifo)
+{
+	return fifo && (fifo->magic_value == DYN_FIFO_MAGIC_VALUE);
+}
+
+/** Initializes the dynamic queue.
+ *
+ * @param[in,out] fifo	The dynamic queue.
+ * @param[in] size	The initial queue size.
+ * @returns		EOK on success.
+ * @returns		EINVAL if the queue is not valid.
+ * @returns		EBADMEM if the fifo parameter is NULL.
+ * @returns		ENOMEM if there is not enough memory left.
+ */
+int dyn_fifo_initialize(dyn_fifo_ref fifo, int size)
+{
+	if (!fifo)
+		return EBADMEM;
+
+	if (size <= 0)
+		return EINVAL;
+
+	fifo->items = (int *) malloc(sizeof(int) * size + 1);
+	if (!fifo->items)
+		return ENOMEM;
+
+	fifo->size = size;
+	fifo->head = 0;
+	fifo->tail = 0;
+	fifo->magic_value = DYN_FIFO_MAGIC_VALUE;
+
+	return EOK;
+}
+
+/** Appends a new item to the queue end.
+ *
+ * @param[in,out] fifo	The dynamic queue.
+ * @param[in] value	The new item value. Should be positive.
+ * @param[in] max_size	The maximum queue size. The queue is not resized beyound
+ *			this limit. May be zero or negative to indicate no
+ *			limit.
+ * @returns		EOK on success.
+ * @returns		EINVAL if the queue is not valid.
+ * @returns		ENOMEM if there is not enough memory left.
+ */
+int dyn_fifo_push(dyn_fifo_ref fifo, int value, int max_size)
+{
+	int * new_items;
+
+	if (!dyn_fifo_is_valid(fifo))
+		return EINVAL;
+
+	if (NEXT_INDEX(fifo, fifo->tail) == fifo->head) {
+		if ((max_size > 0) && ((fifo->size * 2) > max_size)) {
+			if(fifo->size >= max_size)
+				return ENOMEM;
+		} else {
+			max_size = fifo->size * 2;
+		}
+
+		new_items = realloc(fifo->items, sizeof(int) * max_size + 1);
+		if (!new_items)
+			return ENOMEM;
+
+		fifo->items = new_items;
+		if (fifo->tail < fifo->head) {
+			if (fifo->tail < max_size - fifo->size) {
+				memcpy(fifo->items + fifo->size + 1,
+				    fifo->items, fifo->tail * sizeof(int));
+				fifo->tail += fifo->size + 1;
+			} else {
+				memcpy(fifo->items + fifo->size + 1,
+				    fifo->items,
+				    (max_size - fifo->size) * sizeof(int));
+				memcpy(fifo->items,
+				    fifo->items + max_size - fifo->size,
+				    fifo->tail - max_size + fifo->size);
+				fifo->tail -= max_size - fifo->size;
+			}
+		}
+		fifo->size = max_size;
+	}
+
+	fifo->items[fifo->tail] = value;
+	fifo->tail = NEXT_INDEX(fifo, fifo->tail);
+	return EOK;
+}
+
+/** Returns and excludes the first item in the queue.
+ *
+ * @param[in,out] fifoi	The dynamic queue.
+ * @returns		Value of the first item in the queue.
+ * @returns		EINVAL if the queue is not valid.
+ * @returns		ENOENT if the queue is empty.
+ */
+int dyn_fifo_pop(dyn_fifo_ref fifo)
+{
+	int value;
+
+	if (!dyn_fifo_is_valid(fifo))
+		return EINVAL;
+
+	if (fifo->head == fifo->tail)
+		return ENOENT;
+
+	value = fifo->items[fifo->head];
+	fifo->head = NEXT_INDEX(fifo, fifo->head);
+	return value;
+}
+
+/** Returns and keeps the first item in the queue.
+ *
+ * @param[in,out] fifo	The dynamic queue.
+ * @returnsi		Value of the first item in the queue.
+ * @returns		EINVAL if the queue is not valid.
+ * @returns		ENOENT if the queue is empty.
+ */
+int dyn_fifo_value(dyn_fifo_ref fifo)
+{
+	if (!dyn_fifo_is_valid(fifo))
+		return EINVAL;
+
+	if (fifo->head == fifo->tail)
+		return ENOENT;
+
+	return fifo->items[fifo->head];
+}
+
+/** Clears and destroys the queue.
+ *
+ *  @param[in,out] fifo		The dynamic queue.
+ *  @returns			EOK on success.
+ *  @returns			EINVAL if the queue is not valid.
+ */
+int dyn_fifo_destroy(dyn_fifo_ref fifo)
+{
+	if (!dyn_fifo_is_valid(fifo))
+		return EINVAL;
+
+	free(fifo->items);
+	fifo->magic_value = 0;
+	return EOK;
+}
+
+/** @}
+ */
Index: uspace/lib/c/generic/adt/measured_strings.c
===================================================================
--- uspace/lib/c/generic/adt/measured_strings.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
+++ uspace/lib/c/generic/adt/measured_strings.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -0,0 +1,415 @@
+/*
+ * Copyright (c) 2009 Lukas Mejdrech
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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
+ * Character string with measured length implementation.
+ * @see measured_strings.h
+ */
+
+#include <adt/measured_strings.h>
+#include <malloc.h>
+#include <mem.h>
+#include <unistd.h>
+#include <errno.h>
+#include <err.h>
+#include <async.h>
+
+/** Creates a new measured string bundled with a copy of the given string
+ * itself as one memory block.
+ *
+ * If the measured string is being freed, whole memory block is freed.
+ * The measured string should be used only as a constant.
+ *
+ * @param[in] string	The initial character string to be stored.
+ * @param[in] length	The length of the given string without the terminating
+ *			zero ('/0') character. If the length is zero (0), the
+ *			actual length is computed. The given length is used and
+ *			appended with the terminating zero ('\\0') character
+ *			otherwise.
+ * @returns		The new bundled character string with measured length.
+ * @returns		NULL if there is not enough memory left.
+ */
+measured_string_ref
+measured_string_create_bulk(const char * string, size_t length)
+{
+	measured_string_ref new;
+
+	if (length == 0) {
+		while (string[length])
+			++length;
+	}
+	new = (measured_string_ref) malloc(sizeof(measured_string_t) +
+	    (sizeof(char) * (length + 1)));
+	if (!new)
+		return NULL;
+
+	new->length = length;
+	new->value = ((char *) new) + sizeof(measured_string_t);
+	// append terminating zero explicitly - to be safe
+	memcpy(new->value, string, new->length);
+	new->value[new->length] = '\0';
+
+	return new;
+}
+
+/** Copies the given measured string with separated header and data parts.
+ *
+ * @param[in] source	The source measured string to be copied.
+ * @returns		The copy of the given measured string.
+ * @returns		NULL if the source parameter is NULL.
+ * @returns		NULL if there is not enough memory left.
+ */
+measured_string_ref measured_string_copy(measured_string_ref source)
+{
+	measured_string_ref new;
+
+	if (!source)
+		return NULL;
+
+	new = (measured_string_ref) malloc(sizeof(measured_string_t));
+	if (new) {
+		new->value = (char *) malloc(source->length + 1);
+		if (new->value) {
+			new->length = source->length;
+			memcpy(new->value, source->value, new->length);
+			new->value[new->length] = '\0';
+			return new;
+		} else {
+			free(new);
+		}
+	}
+
+	return NULL;
+}
+
+/** Receives a measured strings array from a calling module.
+ *
+ * Creates the array and the data memory blocks.
+ * This method should be used only while processing IPC messages as the array
+ * size has to be negotiated in advance.
+ *
+ *  @param[out] strings	The received measured strings array.
+ *  @param[out] data	The measured strings data. This memory block stores the
+ *			actual character strings.
+ *  @param[in] count	The size of the measured strings array.
+ *  @returns		EOK on success.
+ *  @returns		EINVAL if the strings or data parameter is NULL.
+ *  @returns		EINVAL if the count parameter is zero (0).
+ *  @returns		EINVAL if the sent array differs in size.
+ *  @returns		EINVAL if there is inconsistency in sent measured
+ *			strings' lengths (should not occur).
+ *  @returns		ENOMEM if there is not enough memory left.
+ *  @returns		Other error codes as defined for the
+ *			async_data_write_finalize() function.
+ */
+int
+measured_strings_receive(measured_string_ref *strings, char **data,
+    size_t count)
+{
+	ERROR_DECLARE;
+
+	size_t *lengths;
+	size_t index;
+	size_t length;
+	char *next;
+	ipc_callid_t callid;
+
+	if ((!strings) || (!data) || (count <= 0))
+		return EINVAL;
+
+	lengths = (size_t *) malloc(sizeof(size_t) * (count + 1));
+	if (!lengths)
+		return ENOMEM;
+
+	if ((!async_data_write_receive(&callid, &length)) ||
+	    (length != sizeof(size_t) * (count + 1))) {
+		free(lengths);
+		return EINVAL;
+	}
+	if(ERROR_OCCURRED(async_data_write_finalize(callid, lengths,
+	    sizeof(size_t) * (count + 1)))) {
+		free(lengths);
+		return ERROR_CODE;
+	}
+
+	*data = malloc(lengths[count]);
+	if (!(*data)) {
+		free(lengths);
+		return ENOMEM;
+	}
+	(*data)[lengths[count] - 1] = '\0';
+
+	*strings = (measured_string_ref) malloc(sizeof(measured_string_t) *
+	    count);
+	if (!(*strings)) {
+		free(lengths);
+		free(*data);
+		return ENOMEM;
+	}
+
+	next = *data;
+	for (index = 0; index < count; ++index) {
+		(*strings)[index].length = lengths[index];
+		if (lengths[index] > 0) {
+			if ((!async_data_write_receive(&callid, &length)) ||
+			    (length != lengths[index])) {
+				free(*data);
+				free(*strings);
+				free(lengths);
+				return EINVAL;
+			}
+			ERROR_PROPAGATE(async_data_write_finalize(callid, next,
+			    lengths[index]));
+			(*strings)[index].value = next;
+			next += lengths[index];
+			*next = '\0';
+			++next;
+		} else {
+			(*strings)[index].value = NULL;
+		}
+	}
+
+	free(lengths);
+	return EOK;
+}
+
+/** Computes the lengths of the measured strings in the given array.
+ *
+ * @param[in] strings	The measured strings array to be processed.
+ * @param[in] count	The measured strings array size.
+ * @returns		The computed sizes array.
+ * @returns		NULL if there is not enough memory left.
+ */
+static size_t *prepare_lengths(const measured_string_ref strings, size_t count)
+{
+	size_t *lengths;
+	size_t index;
+	size_t length;
+
+	lengths = (size_t *) malloc(sizeof(size_t) * (count + 1));
+	if (!lengths)
+		return NULL;
+
+	length = 0;
+	for (index = 0; index < count; ++ index) {
+		lengths[index] = strings[index].length;
+		length += lengths[index] + 1;
+	}
+	lengths[count] = length;
+	return lengths;
+}
+
+/** Replies the given measured strings array to a calling module.
+ *
+ * This method should be used only while processing IPC messages as the array
+ * size has to be negotiated in advance.
+ *
+ * @param[in] strings	The measured strings array to be transferred.
+ * @param[in] count	The measured strings array size.
+ * @returns		EOK on success.
+ * @returns		EINVAL if the strings parameter is NULL.
+ * @returns		EINVAL if the count parameter is zero (0).
+ * @returns		EINVAL if the calling module does not accept the given
+ *			array size.
+ * @returns		EINVAL if there is inconsistency in sent measured
+ *			strings' lengths (should not occur).
+ * @returns		Other error codes as defined for the
+ *			async_data_read_finalize() function.
+ */
+int measured_strings_reply(const measured_string_ref strings, size_t count)
+{
+	ERROR_DECLARE;
+
+	size_t *lengths;
+	size_t index;
+	size_t length;
+	ipc_callid_t callid;
+
+	if ((!strings) || (count <= 0))
+		return EINVAL;
+
+	lengths = prepare_lengths(strings, count);
+	if (!lengths)
+		return ENOMEM;
+
+	if ((!async_data_read_receive(&callid, &length)) ||
+	    (length != sizeof(size_t) * (count + 1))) {
+		free(lengths);
+		return EINVAL;
+	}
+	if (ERROR_OCCURRED(async_data_read_finalize(callid, lengths,
+	    sizeof(size_t) * (count + 1)))) {
+		free(lengths);
+		return ERROR_CODE;
+	}
+	free(lengths);
+
+	for (index = 0; index < count; ++ index) {
+		if (strings[index].length > 0) {
+			if((!async_data_read_receive(&callid, &length))	||
+			    (length != strings[index].length)) {
+				return EINVAL;
+			}
+			ERROR_PROPAGATE(async_data_read_finalize(callid,
+			    strings[index].value, strings[index].length));
+		}
+	}
+
+	return EOK;
+}
+
+/** Receives a measured strings array from another module.
+ *
+ * Creates the array and the data memory blocks.
+ * This method should be used only following other IPC messages as the array
+ * size has to be negotiated in advance.
+ *
+ * @param[in] phone	The other module phone.
+ * @param[out] strings	The returned measured strings array.
+ * @param[out] data	The measured strings data. This memory block stores the
+ *			actual character strings.
+ * @param[in] count	The size of the measured strings array.
+ * @returns		EOK on success.
+ * @returns		EINVAL if the strings or data parameter is NULL.
+ * @returns		EINVAL if the phone or count parameter is not positive.
+ * @returns		EINVAL if the sent array differs in size.
+ * @returns		ENOMEM if there is not enough memory left.
+ * @returns		Other error codes as defined for the
+ *			async_data_read_start() function.
+ */
+int
+measured_strings_return(int phone, measured_string_ref *strings, char **data,
+    size_t count)
+{
+	ERROR_DECLARE;
+
+	size_t *lengths;
+	size_t index;
+	char *next;
+
+	if ((phone <= 0) || (!strings) || (!data) || (count <= 0))
+		return EINVAL;
+
+	lengths = (size_t *) malloc(sizeof(size_t) * (count + 1));
+	if (!lengths)
+		return ENOMEM;
+
+	if (ERROR_OCCURRED(async_data_read_start(phone, lengths,
+	    sizeof(size_t) * (count + 1)))) {
+		free(lengths);
+		return ERROR_CODE;
+	}
+
+	*data = malloc(lengths[count]);
+	if (!(*data)) {
+		free(lengths);
+		return ENOMEM;
+	}
+
+	*strings = (measured_string_ref) malloc(sizeof(measured_string_t) *
+	    count);
+	if (!(*strings)) {
+		free(lengths);
+		free(*data);
+		return ENOMEM;
+	}
+
+	next = *data;
+	for (index = 0; index < count; ++ index) {
+		(*strings)[index].length = lengths[index];
+		if (lengths[index] > 0) {
+			ERROR_PROPAGATE(async_data_read_start(phone, next,
+			    lengths[index]));
+			(*strings)[index].value = next;
+			next += lengths[index];
+			*next = '\0';
+			++ next;
+		} else {
+			(*strings)[index].value = NULL;
+		}
+	}
+
+	free(lengths);
+	return EOK;
+}
+
+/** Sends the given measured strings array to another module.
+ *
+ * This method should be used only following other IPC messages as the array
+ * size has to be negotiated in advance.
+ *
+ * @param[in] phone	The other module phone.
+ * @param[in] strings	The measured strings array to be transferred.
+ * @param[in] count	The measured strings array size.
+ * @returns		EOK on success.
+ * @returns		EINVAL if the strings parameter is NULL.
+ * @returns		EINVAL if the phone or count parameter is not positive.
+ * @returns		Other error codes as defined for the
+ *			async_data_write_start() function.
+ */
+int
+measured_strings_send(int phone, const measured_string_ref strings,
+    size_t count)
+{
+	ERROR_DECLARE;
+
+	size_t *lengths;
+	size_t index;
+
+	if ((phone <= 0) || (!strings) || (count <= 0))
+		return EINVAL;
+
+	lengths = prepare_lengths(strings, count);
+	if (!lengths)
+		return ENOMEM;
+
+	if (ERROR_OCCURRED(async_data_write_start(phone, lengths,
+	    sizeof(size_t) * (count + 1)))) {
+		free(lengths);
+		return ERROR_CODE;
+	}
+
+	free(lengths);
+
+	for (index = 0; index < count; ++index) {
+		if (strings[index].length > 0) {
+			ERROR_PROPAGATE(async_data_write_start(phone,
+			    strings[index].value, strings[index].length));
+		}
+	}
+
+	return EOK;
+}
+
+/** @}
+ */
+
Index: uspace/lib/c/generic/async_rel.c
===================================================================
--- uspace/lib/c/generic/async_rel.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
+++ uspace/lib/c/generic/async_rel.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -0,0 +1,307 @@
+/*
+ * Copyright (c) 2010 Jakub Jermar
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup libc
+ * @{
+ */
+/** @file
+ */
+
+/**
+ * This file implements simple relation support for the async framework.
+ *
+ * By the term "relation", we mean a logical data path between a client and a
+ * server over which the client can send multiple, potentially blocking,
+ * requests to the server.
+ *
+ * Clients and servers are naturally connected using IPC phones, thus an IPC
+ * phone represents a connection between a client and a server. In one
+ * connection, there can be many relations.
+ *
+ * Relations are useful in situations in which there is only one IPC connection
+ * between the client and the server, but the client wants to be able to make
+ * multiple parallel requests. Using only a single phone and without any other
+ * provisions, all requests would have to be serialized. On the other hand, the
+ * client can make as many parallel requests as there are active relations.
+ *
+ * There are several possible implementations of relations. This implementation
+ * uses additional phones to represent relations. Using phones both for the
+ * primary connection and also for its relations has several advantages:
+ *
+ * - to make a series of requests over a relation, the client can continue to
+ *   use the existing async framework APIs
+ * - the server supports relations by the virtue of spawning a new connection
+ *   fibril, just as it does for every new connection even without relations
+ * - the implementation is pretty straightforward; a very naive implementation
+ *   would be to make each request using a fresh phone (that is what we have
+ *   done in the past); a slightly better approach would be to cache connected
+ *   phones so that they can be reused by a later relation within the same
+ *   connection (that is what this implementation does)
+ *
+ * The main disadvantages of using phones to represent relations are:
+ *
+ * - if there are too many relations (even cached ones), the task may hit its
+ *   limit on the maximum number of connected phones, which could prevent the
+ *   task from making new IPC connections to other tasks
+ * - if there are too many IPC connections already, it may be impossible to
+ *   create a relation by connecting a new phone thanks to the task's limit on
+ *   the maximum number of connected phones
+ *
+ * These problems can be helped by increasing the limit on the maximum number of
+ * connected phones to some reasonable value and by limiting the number of
+ * phones cached to some fraction of this limit.
+ *
+ * The cache itself has a mechanism to close some number of unused phones if a
+ * new phone cannot be connected, but the outter world currently does not have a
+ * way to ask the phone cache to shrink.
+ *
+ * To minimize the confusion stemming from the fact that we use phones for two
+ * things (the primary IPC connection and also each relation), this file makes
+ * the distinction by using the term 'key phone' for the former and 'relation
+ * phone' for the latter. Under the hood, all phones remain equal, of course.
+ *
+ * There is a small inefficiency in that the cache repeatedly allocates and
+ * deallocated the rel_node_t structures when in fact it could keep the
+ * allocated structures around and reuse them later. But such a solution would
+ * be effectively implementing a poor man's slab allocator while it would be
+ * better to have the slab allocator ported to uspace so that everyone could
+ * benefit from it.
+ */
+
+#include <async_rel.h>
+#include <ipc/ipc.h>
+#include <fibril_synch.h>
+#include <adt/list.h>
+#include <adt/hash_table.h>
+#include <malloc.h>
+#include <errno.h>
+#include <assert.h>
+
+#define KEY_NODE_HASH_BUCKETS	16
+
+typedef struct {
+	link_t link;		/**< Key node hash table link. */
+	int key_phone;		/**< The phone serving as a key. */
+	link_t rel_head;	/**< List of open relation phones. */
+} key_node_t;
+
+typedef struct {
+	link_t rel_link;	/**< Link for the list of relation phones. */
+	link_t global_link;	/**< Link for the global list of phones. */
+	int rel_phone;		/**< Connected relation phone. */
+} rel_node_t;
+
+/**
+ * Mutex protecting the global_rel_head list and the key_node_hash hash table.
+ */
+static fibril_mutex_t async_rel_mutex;
+
+/**
+ * List of all currently unused relation phones.
+ */
+static LIST_INITIALIZE(global_rel_head);
+
+/**
+ * Hash table containing lists of available relation phones for all key
+ * phones.
+ */
+static hash_table_t key_node_hash;
+
+static hash_index_t kn_hash(unsigned long *key)
+{
+	return *key % KEY_NODE_HASH_BUCKETS;
+}
+
+static int kn_compare(unsigned long *key, hash_count_t keys, link_t *item)
+{
+	key_node_t *knp = hash_table_get_instance(item, key_node_t, link);
+
+	return *key == (unsigned long) knp->key_phone;
+}
+
+static void kn_remove_callback(link_t *item)
+{
+}
+
+static hash_table_operations_t key_node_hash_ops = {
+	.hash = kn_hash,
+	.compare = kn_compare,
+	.remove_callback = kn_remove_callback
+};
+
+/** Initialize the async_rel subsystem.
+ *
+ * Needs to be called prior to any other interface in this file.
+ */
+int async_rel_init(void)
+{
+	fibril_mutex_initialize(&async_rel_mutex);
+	list_initialize(&global_rel_head);
+	return hash_table_create(&key_node_hash, KEY_NODE_HASH_BUCKETS, 1,
+	    &key_node_hash_ops);
+}
+
+static void key_node_initialize(key_node_t *knp)
+{
+	link_initialize(&knp->link);
+	knp->key_phone = -1;
+	list_initialize(&knp->rel_head);
+}
+
+static void rel_node_initialize(rel_node_t *rnp)
+{
+	link_initialize(&rnp->rel_link);
+	link_initialize(&rnp->global_link);
+	rnp->rel_phone = -1;
+}
+
+/** Create a new relation for a connection represented by a key phone.
+ *
+ * @param key_phone	Phone representing the connection.
+ * @return		Phone representing the new relation or a negative error
+ *			code.
+ */
+int async_relation_create(int key_phone)
+{
+	unsigned long key = (unsigned long) key_phone;
+	link_t *lnk;
+	key_node_t *knp;
+	rel_node_t *rnp;
+	int rel_phone;
+
+	fibril_mutex_lock(&async_rel_mutex);
+	lnk = hash_table_find(&key_node_hash, &key);
+	if (!lnk) {
+		/*
+		 * The key node was not found in the hash table. Try to allocate
+		 * and hash in a new one.
+		 */
+		knp = (key_node_t *) malloc(sizeof(key_node_t));
+		if (!knp) {
+			/*
+			 * As a possible improvement, we could make a one-time
+			 * attempt to create a phone without trying to add the
+			 * key node into the hash.
+			 */
+			fibril_mutex_unlock(&async_rel_mutex);
+			return ENOMEM;
+		}
+		key_node_initialize(knp);
+		knp->key_phone = key_phone;
+		hash_table_insert(&key_node_hash, &key, &knp->link);
+	} else {
+		/*
+		 * Found the key node.
+		 */
+		knp = hash_table_get_instance(lnk, key_node_t, link);
+	}
+
+	if (!list_empty(&knp->rel_head)) {
+		/*
+		 * There are available relation phones for the key phone.
+		 */
+		rnp = list_get_instance(knp->rel_head.next, rel_node_t,
+		    rel_link);
+		list_remove(&rnp->rel_link);
+		list_remove(&rnp->global_link);
+		
+		rel_phone = rnp->rel_phone;
+		free(rnp);
+	} else {
+		/*
+		 * There are no available relation phones for the key phone.
+		 * Make a one-time attempt to connect a new relation phone.
+		 */
+retry:
+		rel_phone = ipc_connect_me_to(key_phone, 0, 0, 0);
+		if (rel_phone >= 0) {
+			/* success, do nothing */
+		} else if (!list_empty(&global_rel_head)) {
+			/*
+			 * We did not manage to connect a new phone. But we can
+			 * try to hangup some currently unused phones and try
+			 * again.
+			 */
+			rnp = list_get_instance(global_rel_head.next,
+			    rel_node_t, global_link);
+			list_remove(&rnp->global_link);
+			list_remove(&rnp->rel_link);
+			rel_phone = rnp->rel_phone;
+			free(rnp);
+			ipc_hangup(rel_phone);
+			goto retry;
+		} else {
+			/*
+			 * This is unfortunate. We failed both to find a cached
+			 * phone or to create a new one even after cleaning up
+			 * the cache. This is most likely due to too many key
+			 * phones being kept connected.
+			 */
+			rel_phone = ELIMIT;
+		}
+	}
+
+	fibril_mutex_unlock(&async_rel_mutex);
+	return rel_phone;
+}
+
+/** Destroy a relation.
+ *
+ * @param key_phone	Phone representing the connection.
+ * @param rel_phone	Phone representing the relation within the connection.
+ */
+void async_relation_destroy(int key_phone, int rel_phone)
+{
+	unsigned long key = (unsigned long) key_phone;
+	key_node_t *knp;
+	rel_node_t *rnp;
+	link_t *lnk;
+
+	fibril_mutex_lock(&async_rel_mutex);
+	lnk = hash_table_find(&key_node_hash, &key);
+	assert(lnk);
+	knp = hash_table_get_instance(lnk, key_node_t, link);
+	rnp = (rel_node_t *) malloc(sizeof(rel_node_t));
+	if (!rnp) {
+		/*
+		 * Being unable to remember the connected relation phone here
+		 * means that we simply hangup.
+		 */
+		fibril_mutex_unlock(&async_rel_mutex);
+		ipc_hangup(rel_phone);
+		return;
+	}
+	rel_node_initialize(rnp);
+	rnp->rel_phone = rel_phone;
+	list_append(&rnp->rel_link, &knp->rel_head);
+	list_append(&rnp->global_link, &global_rel_head);
+	fibril_mutex_unlock(&async_rel_mutex);
+}
+
+/** @}
+ */
Index: uspace/lib/c/generic/ddi.c
===================================================================
--- uspace/lib/c/generic/ddi.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/lib/c/generic/ddi.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -96,13 +96,4 @@
 }
 
-/** Interrupt control
- *
- * @param enable	1 - enable interrupts, 0 - disable interrupts
- */
-int preemption_control(int enable)
-{
-	return __SYSCALL1(SYS_PREEMPT_CONTROL, (sysarg_t) enable);
-}
-
 /** Enable an interrupt.
  * 
Index: uspace/lib/c/generic/io/io.c
===================================================================
--- uspace/lib/c/generic/io/io.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/lib/c/generic/io/io.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -757,4 +757,14 @@
 }
 
+int fileno(FILE *stream)
+{
+	if (stream->klog) {
+		errno = EBADF;
+		return -1;
+	}
+	
+	return stream->fd;
+}
+
 int fphone(FILE *stream)
 {
Index: uspace/lib/c/generic/libc.c
===================================================================
--- uspace/lib/c/generic/libc.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/lib/c/generic/libc.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -50,4 +50,5 @@
 #include <ipc/ipc.h>
 #include <async.h>
+#include <async_rel.h>
 #include <as.h>
 #include <loader/pcb.h>
@@ -65,4 +66,5 @@
 	__heap_init();
 	__async_init();
+	(void) async_rel_init();
 	fibril_t *fibril = fibril_setup();
 	__tcb_set(fibril->tcb);
Index: uspace/lib/c/generic/net/icmp_api.c
===================================================================
--- uspace/lib/c/generic/net/icmp_api.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
+++ uspace/lib/c/generic/net/icmp_api.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2009 Lukas Mejdrech
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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
+ * ICMP application interface implementation.
+ * @see icmp_api.h
+ */
+
+#include <net/icmp_api.h>
+#include <net/socket_codes.h>
+#include <net/inet.h>
+#include <net/modules.h>
+#include <net/ip_codes.h>
+
+#include <async.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <errno.h>
+
+#include <ipc/ipc.h>
+#include <ipc/services.h>
+#include <ipc/icmp.h>
+
+/** Requests an echo message.
+ *
+ * Sends a packet with specified parameters to the target host and waits for the
+ * reply upto the given timeout. Blocks the caller until the reply or the
+ * timeout occurs.
+ *
+ * @param[in] icmp_phone The ICMP module phone used for (semi)remote calls.
+ * @param[in] size	The message data length in bytes.
+ * @param[in] timeout	The timeout in milliseconds.
+ * @param[in] ttl	The time to live.
+ * @param[in] tos	The type of service.
+ * @param[in] dont_fragment The value indicating whether the datagram must not
+ *			be fragmented. Is used as a MTU discovery.
+ * @param[in] addr	The target host address.
+ * @param[in] addrlen	The torget host address length.
+ * @returns		ICMP_ECHO on success.
+ * @returns		ETIMEOUT if the reply has not arrived before the
+ *			timeout.
+ * @returns		ICMP type of the received error notification.
+ * @returns		EINVAL if the addrlen parameter is less or equal to
+ *			zero.
+ * @returns		ENOMEM if there is not enough memory left.
+ * @returns		EPARTY if there was an internal error.
+ */
+int
+icmp_echo_msg(int icmp_phone, size_t size, mseconds_t timeout, ip_ttl_t ttl,
+    ip_tos_t tos, int dont_fragment, const struct sockaddr *addr,
+    socklen_t addrlen)
+{
+	aid_t message_id;
+	ipcarg_t result;
+
+	if (addrlen <= 0)
+		return EINVAL;
+
+	message_id = async_send_5(icmp_phone, NET_ICMP_ECHO, size, timeout, ttl,
+	    tos, (ipcarg_t) dont_fragment, NULL);
+
+	// send the address
+	async_data_write_start(icmp_phone, addr, (size_t) addrlen);
+
+	async_wait_for(message_id, &result);
+	return (int) result;
+}
+
+/** @}
+ */
Index: uspace/lib/c/generic/net/icmp_common.c
===================================================================
--- uspace/lib/c/generic/net/icmp_common.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
+++ uspace/lib/c/generic/net/icmp_common.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2009 Lukas Mejdrech
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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
+ * ICMP common interface implementation.
+ * @see icmp_common.h
+ */
+
+#include <net/modules.h>
+#include <net/icmp_common.h>
+
+#include <ipc/services.h>
+#include <ipc/icmp.h>
+
+#include <sys/time.h>
+#include <async.h>
+
+/** Connects to the ICMP module.
+ *
+ * @param service	The ICMP module service. Ignored parameter.
+ * @param[in] timeout	The connection timeout in microseconds. No timeout if
+ *			set to zero.
+ * @returns		The ICMP module phone on success.
+ * @returns		ETIMEOUT if the connection timeouted.
+ */
+int icmp_connect_module(services_t service, suseconds_t timeout)
+{
+	int phone;
+
+	phone = connect_to_service_timeout(SERVICE_ICMP, timeout);
+	if (phone >= 0)
+		async_req_0_0(phone, NET_ICMP_INIT);
+
+	return phone;
+}
+
+/** @}
+ */
Index: uspace/lib/c/generic/net/inet.c
===================================================================
--- uspace/lib/c/generic/net/inet.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
+++ uspace/lib/c/generic/net/inet.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -0,0 +1,190 @@
+/*
+ * Copyright (c) 2009 Lukas Mejdrech
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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
+ * Internet protocol address conversion functions implementation.
+ */
+
+#include <net/socket_codes.h>
+#include <net/in.h>
+#include <net/in6.h>
+#include <net/inet.h>
+
+#include <errno.h>
+#include <mem.h>
+#include <stdio.h>
+#include <str.h>
+
+/** Prints the address into the character buffer.
+ *
+ *  @param[in] family	The address family.
+ *  @param[in] data	The address data.
+ *  @param[out] address	The character buffer to be filled.
+ *  @param[in] length	The buffer length.
+ *  @returns		EOK on success.
+ *  @returns		EINVAL if the data or address parameter is NULL.
+ *  @returns		ENOMEM if the character buffer is not long enough.
+ *  @returns		ENOTSUP if the address family is not supported.
+ */
+int
+inet_ntop(uint16_t family, const uint8_t *data, char *address, size_t length)
+{
+	if ((!data) || (!address))
+		return EINVAL;
+
+	switch (family) {
+	case AF_INET:
+		// check the output buffer size
+		if (length < INET_ADDRSTRLEN)
+			return ENOMEM;
+			
+		// fill the buffer with the IPv4 address
+		snprintf(address, length, "%hhu.%hhu.%hhu.%hhu",
+		    data[0], data[1], data[2], data[3]);
+
+		return EOK;
+
+	case AF_INET6:
+		// check the output buffer size
+		if (length < INET6_ADDRSTRLEN)
+			return ENOMEM;
+		
+		// fill the buffer with the IPv6 address
+		snprintf(address, length,
+		    "%hhx%hhx:%hhx%hhx:%hhx%hhx:%hhx%hhx:%hhx%hhx:%hhx%hhx:"
+		    "%hhx%hhx:%hhx%hhx",
+		    data[0], data[1], data[2], data[3], data[4], data[5],
+		    data[6], data[7], data[8], data[9], data[10], data[11],
+		    data[12], data[13], data[14], data[15]);
+		
+		return EOK;
+
+	default:
+		return ENOTSUP;
+	}
+}
+
+/** Parses the character string into the address.
+ *
+ *  If the string is shorter than the full address, zero bytes are added.
+ *
+ *  @param[in] family	The address family.
+ *  @param[in] address	The character buffer to be parsed.
+ *  @param[out] data	The address data to be filled.
+ *  @returns		EOK on success.
+ *  @returns		EINVAL if the data parameter is NULL.
+ *  @returns		ENOENT if the address parameter is NULL.
+ *  @returns		ENOTSUP if the address family is not supported.
+ */
+int inet_pton(uint16_t family, const char *address, uint8_t *data)
+{
+	/** The base number of the values. */
+	int base;
+	/** The number of bytes per a section. */
+	size_t bytes;
+	/** The number of bytes of the address data. */
+	int count;
+
+	const char *next;
+	char *last;
+	int index;
+	size_t shift;
+	unsigned long value;
+
+	if (!data)
+		return EINVAL;
+
+	// set the processing parameters
+	switch (family) {
+	case AF_INET:
+		count = 4;
+		base = 10;
+		bytes = 1;
+		break;
+
+	case AF_INET6:
+		count = 16;
+		base = 16;
+		bytes = 4;
+		break;
+
+	default:
+		return ENOTSUP;
+	}
+
+	// erase if no address
+	if (!address) {
+		bzero(data, count);
+		return ENOENT;
+	}
+
+	// process the string from the beginning
+	next = address;
+	index = 0;
+	do {
+		// if the actual character is set
+		if (next && *next) {
+
+			// if not on the first character
+			if (index) {
+				// move to the next character
+				++next;
+			}
+
+			// parse the actual integral value
+			value = strtoul(next, &last, base);
+			// remember the last problematic character
+			// should be either '.' or ':' but is ignored to be more
+			// generic
+			next = last;
+
+			// fill the address data byte by byte
+			shift = bytes - 1;
+			do {
+				// like little endian
+				data[index + shift] = value;
+				value >>= 8;
+			} while(shift --);
+
+			index += bytes;
+		} else {
+			// erase the rest of the address
+			bzero(data + index, count - index);
+			return EOK;
+		}
+	} while (index < count);
+
+	return EOK;
+}
+
+/** @}
+ */
Index: uspace/lib/c/generic/net/modules.c
===================================================================
--- uspace/lib/c/generic/net/modules.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
+++ uspace/lib/c/generic/net/modules.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -0,0 +1,294 @@
+/*
+ * Copyright (c) 2009 Lukas Mejdrech
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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
+ * Generic module functions implementation. 
+ *
+ * @todo MAKE IT POSSIBLE TO REMOVE THIS FILE VIA EITHER REPLACING PART OF ITS
+ * FUNCTIONALITY OR VIA INTEGRATING ITS FUNCTIONALITY MORE TIGHTLY WITH THE REST
+ * OF THE SYSTEM.
+ */
+
+#include <async.h>
+#include <malloc.h>
+#include <err.h>
+#include <sys/time.h>
+
+#include <ipc/ipc.h>
+#include <ipc/services.h>
+
+#include <net/modules.h>
+
+/** The time between connect requests in microseconds. */
+#define MODULE_WAIT_TIME	(10 * 1000)
+
+/** Answers the call.
+ *
+ * @param[in] callid	The call identifier.
+ * @param[in] result	The message processing result.
+ * @param[in] answer	The message processing answer.
+ * @param[in] answer_count The number of answer parameters.
+ */
+void
+answer_call(ipc_callid_t callid, int result, ipc_call_t *answer,
+    int answer_count)
+{
+	// choose the most efficient answer function
+	if (answer || (!answer_count)) {
+		switch (answer_count) {
+		case 0:
+			ipc_answer_0(callid, (ipcarg_t) result);
+			break;
+		case 1:
+			ipc_answer_1(callid, (ipcarg_t) result,
+			    IPC_GET_ARG1(*answer));
+			break;
+		case 2:
+			ipc_answer_2(callid, (ipcarg_t) result,
+			    IPC_GET_ARG1(*answer), IPC_GET_ARG2(*answer));
+			break;
+		case 3:
+			ipc_answer_3(callid, (ipcarg_t) result,
+			    IPC_GET_ARG1(*answer), IPC_GET_ARG2(*answer),
+			    IPC_GET_ARG3(*answer));
+			break;
+		case 4:
+			ipc_answer_4(callid, (ipcarg_t) result,
+			    IPC_GET_ARG1(*answer), IPC_GET_ARG2(*answer),
+			    IPC_GET_ARG3(*answer), IPC_GET_ARG4(*answer));
+			break;
+		case 5:
+		default:
+			ipc_answer_5(callid, (ipcarg_t) result,
+			    IPC_GET_ARG1(*answer), IPC_GET_ARG2(*answer),
+			    IPC_GET_ARG3(*answer), IPC_GET_ARG4(*answer),
+			    IPC_GET_ARG5(*answer));
+			break;
+		}
+	}
+}
+
+/** Create bidirectional connection with the needed module service and registers
+ * the message receiver.
+ *
+ * @param[in] need	The needed module service.
+ * @param[in] arg1	The first parameter.
+ * @param[in] arg2	The second parameter.
+ * @param[in] arg3	The third parameter.
+ * @param[in] client_receiver The message receiver.
+ *
+ * @return		The phone of the needed service.
+ * @return		Other error codes as defined for the ipc_connect_to_me()
+ *			function.
+ */
+int bind_service(services_t need, ipcarg_t arg1, ipcarg_t arg2, ipcarg_t arg3,
+    async_client_conn_t client_receiver)
+{
+	return bind_service_timeout(need, arg1, arg2, arg3, client_receiver, 0);
+}
+
+/** Create bidirectional connection with the needed module service and registers
+ * the message receiver.
+ *
+ * @param[in] need	The needed module service.
+ * @param[in] arg1	The first parameter.
+ * @param[in] arg2	The second parameter.
+ * @param[in] arg3	The third parameter.
+ * @param[in] client_receiver The message receiver.
+ * @param[in] timeout	The connection timeout in microseconds. No timeout if
+ * 			set to zero (0).
+ *
+ * @return		The phone of the needed service.
+ * @return		ETIMEOUT if the connection timeouted.
+ * @return		Other error codes as defined for the ipc_connect_to_me()
+ *			function.
+ *
+ */
+int bind_service_timeout(services_t need, ipcarg_t arg1, ipcarg_t arg2,
+    ipcarg_t arg3, async_client_conn_t client_receiver, suseconds_t timeout)
+{
+	ERROR_DECLARE;
+	
+	/* Connect to the needed service */
+	int phone = connect_to_service_timeout(need, timeout);
+	if (phone >= 0) {
+		/* Request the bidirectional connection */
+		ipcarg_t phonehash;
+		if (ERROR_OCCURRED(ipc_connect_to_me(phone, arg1, arg2, arg3,
+		    &phonehash))) {
+			ipc_hangup(phone);
+			return ERROR_CODE;
+		}
+		async_new_connection(phonehash, 0, NULL, client_receiver);
+	}
+	
+	return phone;
+}
+
+/** Connects to the needed module.
+ *
+ * @param[in] need	The needed module service.
+ * @returns		The phone of the needed service.
+ */
+int connect_to_service(services_t need)
+{
+	return connect_to_service_timeout(need, 0);
+}
+
+/** Connects to the needed module.
+ *
+ *  @param[in] need	The needed module service.
+ *  @param[in] timeout	The connection timeout in microseconds. No timeout if
+ *			set to zero (0).
+ *  @returns		The phone of the needed service.
+ *  @returns		ETIMEOUT if the connection timeouted.
+ */
+int connect_to_service_timeout(services_t need, suseconds_t timeout)
+{
+	int phone;
+
+	// if no timeout is set
+	if (timeout <= 0)
+		return async_connect_me_to_blocking(PHONE_NS, need, 0, 0);
+
+	while (true) {
+		phone = async_connect_me_to(PHONE_NS, need, 0, 0);
+		if ((phone >= 0) || (phone != ENOENT))
+			return phone;
+
+		// end if no time is left
+		if (timeout <= 0)
+			return ETIMEOUT;
+
+		// wait the minimum of the module wait time and the timeout
+		usleep((timeout <= MODULE_WAIT_TIME) ?
+		    timeout : MODULE_WAIT_TIME);
+		timeout -= MODULE_WAIT_TIME;
+	}
+}
+
+/** Receives data from the other party.
+ *
+ * The received data buffer is allocated and returned.
+ *
+ * @param[out] data	The data buffer to be filled.
+ * @param[out] length	The buffer length.
+ * @returns		EOK on success.
+ * @returns		EBADMEM if the data or the length parameter is NULL.
+ * @returns		EINVAL if the client does not send data.
+ * @returns		ENOMEM if there is not enough memory left.
+ * @returns		Other error codes as defined for the
+ *			async_data_write_finalize() function.
+ */
+int data_receive(void **data, size_t *length)
+{
+	ERROR_DECLARE;
+
+	ipc_callid_t callid;
+
+	if (!data || !length)
+		return EBADMEM;
+
+	// fetch the request
+	if (!async_data_write_receive(&callid, length))
+		return EINVAL;
+
+	// allocate the buffer
+	*data = malloc(*length);
+	if (!*data)
+		return ENOMEM;
+
+	// fetch the data
+	if (ERROR_OCCURRED(async_data_write_finalize(callid, *data, *length))) {
+		free(data);
+		return ERROR_CODE;
+	}
+
+	return EOK;
+}
+
+/** Replies the data to the other party.
+ *
+ * @param[in] data	The data buffer to be sent.
+ * @param[in] data_length The buffer length.
+ * @returns		EOK on success.
+ * @returns		EINVAL if the client does not expect the data.
+ * @returns		EOVERFLOW if the client does not expect all the data.
+ *			Only partial data are transfered.
+ * @returns		Other error codes as defined for the
+ *			async_data_read_finalize() function.
+ */
+int data_reply(void *data, size_t data_length)
+{
+	size_t length;
+	ipc_callid_t callid;
+
+	// fetch the request
+	if (!async_data_read_receive(&callid, &length))
+		return EINVAL;
+
+	// check the requested data size
+	if (length < data_length) {
+		async_data_read_finalize(callid, data, length);
+		return EOVERFLOW;
+	}
+
+	// send the data
+	return async_data_read_finalize(callid, data, data_length);
+}
+
+/** Refreshes answer structure and parameters count.
+ *
+ * Erases all attributes.
+ *
+ * @param[in,out] answer The message processing answer structure.
+ * @param[in,out] answer_count The number of answer parameters.
+ */
+void refresh_answer(ipc_call_t *answer, int *answer_count)
+{
+	if (answer_count)
+		*answer_count = 0;
+
+	if (answer) {
+		IPC_SET_RETVAL(*answer, 0);
+		// just to be precize
+		IPC_SET_METHOD(*answer, 0);
+		IPC_SET_ARG1(*answer, 0);
+		IPC_SET_ARG2(*answer, 0);
+		IPC_SET_ARG3(*answer, 0);
+		IPC_SET_ARG4(*answer, 0);
+		IPC_SET_ARG5(*answer, 0);
+	}
+}
+
+/** @}
+ */
Index: uspace/lib/c/generic/net/packet.c
===================================================================
--- uspace/lib/c/generic/net/packet.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
+++ uspace/lib/c/generic/net/packet.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -0,0 +1,424 @@
+/*
+ * Copyright (c) 2009 Lukas Mejdrech
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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
+ *  Packet map and queue implementation.
+ *  This file has to be compiled with both the packet server and the client.
+ */
+
+#include <malloc.h>
+#include <mem.h>
+#include <fibril_synch.h>
+#include <unistd.h>
+#include <errno.h>
+#include <err.h>
+
+#include <sys/mman.h>
+
+#include <adt/generic_field.h>
+#include <net/packet.h>
+#include <net/packet_header.h>
+
+/** Packet map page size. */
+#define PACKET_MAP_SIZE	100
+
+/** Returns the packet map page index.
+ * @param[in] packet_id The packet identifier.
+ */
+#define PACKET_MAP_PAGE(packet_id)	(((packet_id) - 1) / PACKET_MAP_SIZE)
+
+/** Returns the packet index in the corresponding packet map page.
+ *  @param[in] packet_id The packet identifier.
+ */
+#define PACKET_MAP_INDEX(packet_id)	(((packet_id) - 1) % PACKET_MAP_SIZE)
+
+/** Type definition of the packet map page. */
+typedef packet_t packet_map_t[PACKET_MAP_SIZE];
+
+/** Type definition of the packet map page pointer. */
+typedef packet_map_t * packet_map_ref;
+
+/** Packet map.
+ * Maps packet identifiers to the packet references.
+ * @see generic_field.h
+ */
+GENERIC_FIELD_DECLARE(gpm, packet_map_t);
+
+/** Packet map global data. */
+static struct {
+	/** Safety lock. */
+	fibril_rwlock_t lock;
+	/** Packet map. */
+	gpm_t packet_map;
+} pm_globals;
+
+GENERIC_FIELD_IMPLEMENT(gpm, packet_map_t);
+
+/** Initializes the packet map.
+ *
+ * @returns		EOK on success.
+ * @returns		ENOMEM if there is not enough memory left.
+ */
+int pm_init(void)
+{
+	ERROR_DECLARE;
+
+	fibril_rwlock_initialize(&pm_globals.lock);
+	fibril_rwlock_write_lock(&pm_globals.lock);
+	ERROR_PROPAGATE(gpm_initialize(&pm_globals.packet_map));
+	fibril_rwlock_write_unlock(&pm_globals.lock);
+	return EOK;
+}
+
+/** Finds the packet mapping.
+ *
+ * @param[in] packet_id	The packet identifier to be found.
+ * @returns		The found packet reference.
+ * @returns		NULL if the mapping does not exist.
+ */
+packet_t pm_find(packet_id_t packet_id)
+{
+	packet_map_ref map;
+	packet_t packet;
+
+	if (!packet_id)
+		return NULL;
+
+	fibril_rwlock_read_lock(&pm_globals.lock);
+	if (packet_id > PACKET_MAP_SIZE * gpm_count(&pm_globals.packet_map)) {
+		fibril_rwlock_read_unlock(&pm_globals.lock);
+		return NULL;
+	}
+	map = gpm_get_index(&pm_globals.packet_map, PACKET_MAP_PAGE(packet_id));
+	if (!map) {
+		fibril_rwlock_read_unlock(&pm_globals.lock);
+		return NULL;
+	}
+	packet = (*map) [PACKET_MAP_INDEX(packet_id)];
+	fibril_rwlock_read_unlock(&pm_globals.lock);
+	return packet;
+}
+
+/** Adds the packet mapping.
+ *
+ * @param[in] packet	The packet to be remembered.
+ * @returns		EOK on success.
+ * @returns		EINVAL if the packet is not valid.
+ * @returns		EINVAL if the packet map is not initialized.
+ * @returns		ENOMEM if there is not enough memory left.
+ */
+int pm_add(packet_t packet)
+{
+	ERROR_DECLARE;
+
+	packet_map_ref map;
+
+	if (!packet_is_valid(packet))
+		return EINVAL;
+
+	fibril_rwlock_write_lock(&pm_globals.lock);
+
+	if (PACKET_MAP_PAGE(packet->packet_id) <
+	    gpm_count(&pm_globals.packet_map)) {
+		map = gpm_get_index(&pm_globals.packet_map,
+		    PACKET_MAP_PAGE(packet->packet_id));
+	} else {
+		do {
+			map = (packet_map_ref) malloc(sizeof(packet_map_t));
+			if (!map) {
+				fibril_rwlock_write_unlock(&pm_globals.lock);
+				return ENOMEM;
+			}
+			bzero(map, sizeof(packet_map_t));
+			if ((ERROR_CODE =
+			    gpm_add(&pm_globals.packet_map, map)) < 0) {
+				fibril_rwlock_write_unlock(&pm_globals.lock);
+				free(map);
+				return ERROR_CODE;
+			}
+		} while (PACKET_MAP_PAGE(packet->packet_id) >=
+		    gpm_count(&pm_globals.packet_map));
+	}
+
+	(*map) [PACKET_MAP_INDEX(packet->packet_id)] = packet;
+	fibril_rwlock_write_unlock(&pm_globals.lock);
+	return EOK;
+}
+
+/** Releases the packet map. */
+void pm_destroy(void)
+{
+	int count;
+	int index;
+	packet_map_ref map;
+	packet_t packet;
+
+	fibril_rwlock_write_lock(&pm_globals.lock);
+	count = gpm_count(&pm_globals.packet_map);
+	while (count > 0) {
+		map = gpm_get_index(&pm_globals.packet_map, count - 1);
+		for (index = PACKET_MAP_SIZE - 1; index >= 0; --index) {
+			packet = (*map)[index];
+			if (packet_is_valid(packet))
+				munmap(packet, packet->length);
+		}
+	}
+	gpm_destroy(&pm_globals.packet_map);
+	// leave locked
+}
+
+/** Add packet to the sorted queue.
+ *
+ * The queue is sorted in the ascending order.
+ * The packet is inserted right before the packets of the same order value.
+ *
+ * @param[in,out] first	The first packet of the queue. Sets the first packet of
+ *			the queue. The original first packet may be shifted by
+ *			the new packet.
+ * @param[in] packet	The packet to be added.
+ * @param[in] order	The packet order value.
+ * @param[in] metric	The metric value of the packet.
+ * @returns		EOK on success.
+ * @returns		EINVAL if the first parameter is NULL.
+ * @returns		EINVAL if the packet is not valid.
+ */
+int pq_add(packet_t * first, packet_t packet, size_t order, size_t metric)
+{
+	packet_t item;
+
+	if (!first || !packet_is_valid(packet))
+		return EINVAL;
+
+	pq_set_order(packet, order, metric);
+	if (packet_is_valid(*first)) {
+		item = * first;
+		do {
+			if (item->order < order) {
+				if (item->next) {
+					item = pm_find(item->next);
+				} else {
+					item->next = packet->packet_id;
+					packet->previous = item->packet_id;
+					return EOK;
+				}
+			} else {
+				packet->previous = item->previous;
+				packet->next = item->packet_id;
+				item->previous = packet->packet_id;
+				item = pm_find(packet->previous);
+				if (item)
+					item->next = packet->packet_id;
+				else
+					*first = packet;
+				return EOK;
+			}
+		} while (packet_is_valid(item));
+	}
+	*first = packet;
+	return EOK;
+}
+
+/** Finds the packet with the given order.
+ *
+ * @param[in] first	The first packet of the queue.
+ * @param[in] order	The packet order value.
+ * @returns		The packet with the given order.
+ * @returns		NULL if the first packet is not valid.
+ * @returns		NULL if the packet is not found.
+ */
+packet_t pq_find(packet_t packet, size_t order)
+{
+	packet_t item;
+
+	if (!packet_is_valid(packet))
+		return NULL;
+
+	item = packet;
+	do {
+		if (item->order == order)
+			return item;
+
+		item = pm_find(item->next);
+	} while (item && (item != packet) && packet_is_valid(item));
+
+	return NULL;
+}
+
+/** Inserts packet after the given one.
+ *
+ * @param[in] packet	The packet in the queue.
+ * @param[in] new_packet The new packet to be inserted.
+ * @returns		EOK on success.
+ * @returns		EINVAL if etiher of the packets is invalid.
+ */
+int pq_insert_after(packet_t packet, packet_t new_packet)
+{
+	packet_t item;
+
+	if (!packet_is_valid(packet) || !packet_is_valid(new_packet))
+		return EINVAL;
+
+	new_packet->previous = packet->packet_id;
+	new_packet->next = packet->next;
+	item = pm_find(packet->next);
+	if (item)
+		item->previous = new_packet->packet_id;
+	packet->next = new_packet->packet_id;
+
+	return EOK;
+}
+
+/** Detach the packet from the queue.
+ *
+ * @param[in] packet	The packet to be detached.
+ * @returns		The next packet in the queue. If the packet is the first
+ *			one of the queue, this becomes the new first one.
+ * @returns		NULL if there is no packet left.
+ * @returns		NULL if the packet is not valid.
+ */
+packet_t pq_detach(packet_t packet)
+{
+	packet_t next;
+	packet_t previous;
+
+	if (!packet_is_valid(packet))
+		return NULL;
+
+	next = pm_find(packet->next);
+	if (next) {
+		next->previous = packet->previous;
+		previous = pm_find(next->previous);
+		if (previous)
+			previous->next = next->packet_id;
+	}
+	packet->previous = 0;
+	packet->next = 0;
+	return next;
+}
+
+/** Sets the packet order and metric attributes.
+ *
+ * @param[in] packeti	The packet to be set.
+ * @param[in] order	The packet order value.
+ * @param[in] metric	The metric value of the packet.
+ * @returns		EOK on success.
+ * @returns		EINVAL if the packet is invalid.
+ */
+int pq_set_order(packet_t packet, size_t order, size_t metric)
+{
+	if (!packet_is_valid(packet))
+		return EINVAL;
+
+	packet->order = order;
+	packet->metric = metric;
+	return EOK;
+}
+
+/** Sets the packet order and metric attributes.
+ *
+ * @param[in] packet	The packet to be set.
+ * @param[out] order	The packet order value.
+ * @param[out] metric	The metric value of the packet.
+ * @returns		EOK on success.
+ * @returns		EINVAL if the packet is invalid.
+ */
+int pq_get_order(packet_t packet, size_t *order, size_t *metric)
+{
+	if (!packet_is_valid(packet))
+		return EINVAL;
+
+	if (order)
+		*order = packet->order;
+
+	if (metric)
+		*metric = packet->metric;
+
+	return EOK;
+}
+
+/** Releases the whole queue.
+ *
+ * Detaches all packets of the queue and calls the packet_release() for each of
+ * them.
+ *
+ * @param[in] first	The first packet of the queue.
+ * @param[in] packet_release The releasing function called for each of the
+ *			packets after its detachment.
+ */
+void pq_destroy(packet_t first, void (*packet_release)(packet_t packet))
+{
+	packet_t actual;
+	packet_t next;
+
+	actual = first;
+	while (packet_is_valid(actual)) {
+		next = pm_find(actual->next);
+		actual->next = 0;
+		actual->previous = 0;
+		if(packet_release)
+			packet_release(actual);
+		actual = next;
+	}
+}
+
+/** Returns the next packet in the queue.
+ *
+ * @param[in] packet	The packet queue member.
+ * @returns		The next packet in the queue.
+ * @returns		NULL if there is no next packet.
+ * @returns		NULL if the packet is not valid.
+ */
+packet_t pq_next(packet_t packet)
+{
+	if (!packet_is_valid(packet))
+		return NULL;
+
+	return pm_find(packet->next);
+}
+
+/** Returns the previous packet in the queue.
+ *
+ * @param[in] packet	The packet queue member.
+ * @returns		The previous packet in the queue.
+ * @returns		NULL if there is no previous packet.
+ * @returns		NULL if the packet is not valid.
+ */
+packet_t pq_previous(packet_t packet)
+{
+	if (!packet_is_valid(packet))
+		return NULL;
+
+	return pm_find(packet->previous);
+}
+
+/** @}
+ */
Index: uspace/lib/c/generic/net/socket_client.c
===================================================================
--- uspace/lib/c/generic/net/socket_client.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
+++ uspace/lib/c/generic/net/socket_client.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -0,0 +1,1222 @@
+/*
+ * Copyright (c) 2009 Lukas Mejdrech
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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
+ * Socket application program interface (API) implementation.
+ * @see socket.h for more information.
+ * This is a part of the network application library.
+ */
+
+#include <assert.h>
+#include <async.h>
+#include <fibril_synch.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <err.h>
+
+#include <ipc/services.h>
+#include <ipc/socket.h>
+
+#include <net/modules.h>
+#include <net/in.h>
+#include <net/socket.h>
+#include <adt/dynamic_fifo.h>
+#include <adt/int_map.h>
+
+/** Initial received packet queue size. */
+#define SOCKET_INITIAL_RECEIVED_SIZE	4
+
+/** Maximum received packet queue size. */
+#define SOCKET_MAX_RECEIVED_SIZE	0
+
+/** Initial waiting sockets queue size. */
+#define SOCKET_INITIAL_ACCEPTED_SIZE	1
+
+/** Maximum waiting sockets queue size. */
+#define SOCKET_MAX_ACCEPTED_SIZE	0
+
+/** Default timeout for connections in microseconds. */
+#define SOCKET_CONNECT_TIMEOUT	(1 * 1000 * 1000)
+
+/**
+ * Maximum number of random attempts to find a new socket identifier before
+ * switching to the sequence.
+ */
+#define SOCKET_ID_TRIES			100
+
+/** Type definition of the socket specific data.
+ * @see socket
+ */
+typedef struct socket socket_t;
+
+/** Type definition of the socket specific data pointer.
+ * @see socket
+ */
+typedef socket_t *socket_ref;
+
+/** Socket specific data.
+ *
+ * Each socket lock locks only its structure part and any number of them may be
+ * locked simultaneously.
+ */
+struct socket {
+	/** Socket identifier. */
+	int socket_id;
+	/** Parent module phone. */
+	int phone;
+	/** Parent module service. */
+	services_t service;
+
+	/**
+	 * Underlying protocol header size.
+	 * Sending and receiving optimalization.
+	 */
+	size_t header_size;
+
+	/** Packet data fragment size. Sending optimization. */
+	size_t data_fragment_size;
+
+	/**
+	 * Sending safety lock.
+	 * Locks the header_size and data_fragment_size attributes.
+	 */
+	fibril_rwlock_t sending_lock;
+
+	/** Received packets queue. */
+	dyn_fifo_t received;
+
+	/**
+	 * Received packets safety lock.
+	 * Used for receiving and receive notifications.
+	 * Locks the received attribute.
+	 */
+	fibril_mutex_t receive_lock;
+
+	/** Received packets signaling. Signaled upon receive notification. */
+	fibril_condvar_t receive_signal;
+	/** Waiting sockets queue. */
+	dyn_fifo_t accepted;
+
+	/**
+	 * Waiting sockets safety lock.
+	 * Used for accepting and accept notifications.
+	 * Locks the accepted attribute.
+	 */
+	fibril_mutex_t accept_lock;
+
+	/** Waiting sockets signaling. Signaled upon accept notification. */
+	fibril_condvar_t accept_signal;
+
+	/**
+	 * The number of blocked functions called.
+	 * Used while waiting for the received packets or accepted sockets.
+	 */
+	int blocked;
+};
+
+/** Sockets map.
+ * Maps socket identifiers to the socket specific data.
+ * @see int_map.h
+ */
+INT_MAP_DECLARE(sockets, socket_t);
+
+/** Socket client library global data. */
+static struct socket_client_globals {
+	/** TCP module phone. */
+	int tcp_phone;
+	/** UDP module phone. */
+	int udp_phone;
+
+//	/** The last socket identifier.
+//	 */
+//	int last_id;
+
+	/** Active sockets. */
+	sockets_ref sockets;
+
+	/** Safety lock.
+	 * Write lock is used only for adding or removing sockets.
+	 * When locked for writing, no other socket locks need to be locked.
+	 * When locked for reading, any other socket locks may be locked.
+	 * No socket lock may be locked if this lock is unlocked.
+	 */
+	fibril_rwlock_t lock;
+} socket_globals = {
+	.tcp_phone = -1,
+	.udp_phone = -1,
+//	.last_id = 0,
+	.sockets = NULL,
+	.lock = FIBRIL_RWLOCK_INITIALIZER(socket_globals.lock)
+};
+
+INT_MAP_IMPLEMENT(sockets, socket_t);
+
+/** Returns the active sockets.
+ *
+ *  @returns		The active sockets.
+ */
+static sockets_ref socket_get_sockets(void)
+{
+	if (!socket_globals.sockets) {
+		socket_globals.sockets =
+		    (sockets_ref) malloc(sizeof(sockets_t));
+		if (!socket_globals.sockets)
+			return NULL;
+
+		if (sockets_initialize(socket_globals.sockets) != EOK) {
+			free(socket_globals.sockets);
+			socket_globals.sockets = NULL;
+		}
+
+		srand(task_get_id());
+	}
+
+	return socket_globals.sockets;
+}
+
+/** Default thread for new connections.
+ *
+ * @param[in] iid	The initial message identifier.
+ * @param[in] icall	The initial message call structure.
+ */
+static void socket_connection(ipc_callid_t iid, ipc_call_t * icall)
+{
+	ERROR_DECLARE;
+
+	ipc_callid_t callid;
+	ipc_call_t call;
+	socket_ref socket;
+
+loop:
+	callid = async_get_call(&call);
+
+	switch (IPC_GET_METHOD(call)) {
+	case NET_SOCKET_RECEIVED:
+	case NET_SOCKET_ACCEPTED:
+	case NET_SOCKET_DATA_FRAGMENT_SIZE:
+		fibril_rwlock_read_lock(&socket_globals.lock);
+
+		// find the socket
+		socket = sockets_find(socket_get_sockets(),
+		    SOCKET_GET_SOCKET_ID(call));
+		if (!socket) {
+			ERROR_CODE = ENOTSOCK;
+			fibril_rwlock_read_unlock(&socket_globals.lock);
+			break;
+		}
+		
+		switch (IPC_GET_METHOD(call)) {
+		case NET_SOCKET_RECEIVED:
+			fibril_mutex_lock(&socket->receive_lock);
+			// push the number of received packet fragments
+			if (!ERROR_OCCURRED(dyn_fifo_push(&socket->received,
+			    SOCKET_GET_DATA_FRAGMENTS(call),
+			    SOCKET_MAX_RECEIVED_SIZE))) {
+				// signal the received packet
+				fibril_condvar_signal(&socket->receive_signal);
+			}
+			fibril_mutex_unlock(&socket->receive_lock);
+			break;
+
+		case NET_SOCKET_ACCEPTED:
+			// push the new socket identifier
+			fibril_mutex_lock(&socket->accept_lock);
+			if (!ERROR_OCCURRED(dyn_fifo_push(&socket->accepted,
+			    1, SOCKET_MAX_ACCEPTED_SIZE))) {
+				// signal the accepted socket
+				fibril_condvar_signal(&socket->accept_signal);
+			}
+			fibril_mutex_unlock(&socket->accept_lock);
+			break;
+
+		default:
+			ERROR_CODE = ENOTSUP;
+		}
+
+		if ((SOCKET_GET_DATA_FRAGMENT_SIZE(call) > 0) &&
+		    (SOCKET_GET_DATA_FRAGMENT_SIZE(call) !=
+		    socket->data_fragment_size)) {
+			fibril_rwlock_write_lock(&socket->sending_lock);
+
+			// set the data fragment size
+			socket->data_fragment_size =
+			    SOCKET_GET_DATA_FRAGMENT_SIZE(call);
+
+			fibril_rwlock_write_unlock(&socket->sending_lock);
+		}
+
+		fibril_rwlock_read_unlock(&socket_globals.lock);
+		break;
+
+	default:
+		ERROR_CODE = ENOTSUP;
+	}
+
+	ipc_answer_0(callid, (ipcarg_t) ERROR_CODE);
+	goto loop;
+}
+
+/** Returns the TCP module phone.
+ *
+ * Connects to the TCP module if necessary.
+ *
+ * @returns		The TCP module phone.
+ * @returns		Other error codes as defined for the
+ *			bind_service_timeout() function.
+ */
+static int socket_get_tcp_phone(void)
+{
+	if (socket_globals.tcp_phone < 0) {
+		socket_globals.tcp_phone = bind_service_timeout(SERVICE_TCP,
+		    0, 0, SERVICE_TCP, socket_connection,
+		    SOCKET_CONNECT_TIMEOUT);
+	}
+
+	return socket_globals.tcp_phone;
+}
+
+/** Returns the UDP module phone.
+ *
+ * Connects to the UDP module if necessary.
+ *
+ * @returns		The UDP module phone.
+ * @returns		Other error codes as defined for the
+ *			bind_service_timeout() function.
+ */
+static int socket_get_udp_phone(void)
+{
+	if (socket_globals.udp_phone < 0) {
+		socket_globals.udp_phone = bind_service_timeout(SERVICE_UDP,
+		    0, 0, SERVICE_UDP, socket_connection,
+		    SOCKET_CONNECT_TIMEOUT);
+	}
+
+	return socket_globals.udp_phone;
+}
+
+/** Tries to find a new free socket identifier.
+ *
+ * @returns		The new socket identifier.
+ * @returns		ELIMIT if there is no socket identifier available.
+ */
+static int socket_generate_new_id(void)
+{
+	sockets_ref sockets;
+	int socket_id = 0;
+	int count;
+
+	sockets = socket_get_sockets();
+	count = 0;
+//	socket_id = socket_globals.last_id;
+
+	do {
+		if (count < SOCKET_ID_TRIES) {
+			socket_id = rand() % INT_MAX;
+			++count;
+		} else if (count == SOCKET_ID_TRIES) {
+			socket_id = 1;
+			++count;
+		// only this branch for last_id
+		} else {
+			if (socket_id < INT_MAX) {
+				++socket_id;
+/*			} else if(socket_globals.last_id) {
+ *				socket_globals.last_id = 0;
+ *				socket_id = 1;
+ */			} else {
+				return ELIMIT;
+			}
+		}
+	} while (sockets_find(sockets, socket_id));
+
+//	last_id = socket_id
+	return socket_id;
+}
+
+/** Initializes a new socket specific data.
+ *
+ * @param[in,out] socket The socket to be initialized.
+ * @param[in] socket_id	The new socket identifier.
+ * @param[in] phone	The parent module phone.
+ * @param[in] service	The parent module service.
+ */
+static void
+socket_initialize(socket_ref socket, int socket_id, int phone,
+    services_t service)
+{
+	socket->socket_id = socket_id;
+	socket->phone = phone;
+	socket->service = service;
+	dyn_fifo_initialize(&socket->received, SOCKET_INITIAL_RECEIVED_SIZE);
+	dyn_fifo_initialize(&socket->accepted, SOCKET_INITIAL_ACCEPTED_SIZE);
+	fibril_mutex_initialize(&socket->receive_lock);
+	fibril_condvar_initialize(&socket->receive_signal);
+	fibril_mutex_initialize(&socket->accept_lock);
+	fibril_condvar_initialize(&socket->accept_signal);
+	fibril_rwlock_initialize(&socket->sending_lock);
+}
+
+/** Creates a new socket.
+ *
+ * @param[in] domain	The socket protocol family.
+ * @param[in] type	Socket type.
+ * @param[in] protocol	Socket protocol.
+ * @returns		The socket identifier on success.
+ * @returns		EPFNOTSUPPORT if the protocol family is not supported.
+ * @returns		ESOCKNOTSUPPORT if the socket type is not supported.
+ * @returns		EPROTONOSUPPORT if the protocol is not supported.
+ * @returns		ENOMEM if there is not enough memory left.
+ * @returns		ELIMIT if there was not a free socket identifier found
+ *			this time.
+ * @returns		Other error codes as defined for the NET_SOCKET message.
+ * @returns		Other error codes as defined for the
+ *			bind_service_timeout() function.
+ */
+int socket(int domain, int type, int protocol)
+{
+	ERROR_DECLARE;
+
+	socket_ref socket;
+	int phone;
+	int socket_id;
+	services_t service;
+	ipcarg_t fragment_size;
+	ipcarg_t header_size;
+
+	// find the appropriate service
+	switch (domain) {
+	case PF_INET:
+		switch (type) {
+		case SOCK_STREAM:
+			if (!protocol)
+				protocol = IPPROTO_TCP;
+
+			switch (protocol) {
+			case IPPROTO_TCP:
+				phone = socket_get_tcp_phone();
+				service = SERVICE_TCP;
+				break;
+			default:
+				return EPROTONOSUPPORT;
+			}
+
+			break;
+
+		case SOCK_DGRAM:
+			if (!protocol)
+				protocol = IPPROTO_UDP;
+
+			switch (protocol) {
+			case IPPROTO_UDP:
+				phone = socket_get_udp_phone();
+				service = SERVICE_UDP;
+				break;
+			default:
+				return EPROTONOSUPPORT;
+			}
+
+			break;
+
+		case SOCK_RAW:
+		default:
+			return ESOCKTNOSUPPORT;
+		}
+
+		break;
+
+	case PF_INET6:
+	default:
+		return EPFNOSUPPORT;
+	}
+
+	if (phone < 0)
+		return phone;
+
+	// create a new socket structure
+	socket = (socket_ref) malloc(sizeof(socket_t));
+	if (!socket)
+		return ENOMEM;
+
+	bzero(socket, sizeof(*socket));
+	fibril_rwlock_write_lock(&socket_globals.lock);
+
+	// request a new socket
+	socket_id = socket_generate_new_id();
+	if (socket_id <= 0) {
+		fibril_rwlock_write_unlock(&socket_globals.lock);
+		free(socket);
+		return socket_id;
+	}
+
+	if (ERROR_OCCURRED((int) async_req_3_3(phone, NET_SOCKET, socket_id, 0,
+	    service, NULL, &fragment_size, &header_size))) {
+		fibril_rwlock_write_unlock(&socket_globals.lock);
+		free(socket);
+		return ERROR_CODE;
+	}
+
+	socket->data_fragment_size = (size_t) fragment_size;
+	socket->header_size = (size_t) header_size;
+
+	// finish the new socket initialization
+	socket_initialize(socket, socket_id, phone, service);
+	// store the new socket
+	ERROR_CODE = sockets_add(socket_get_sockets(), socket_id, socket);
+
+	fibril_rwlock_write_unlock(&socket_globals.lock);
+	if (ERROR_CODE < 0) {
+		dyn_fifo_destroy(&socket->received);
+		dyn_fifo_destroy(&socket->accepted);
+		free(socket);
+		async_msg_3(phone, NET_SOCKET_CLOSE, (ipcarg_t) socket_id, 0,
+		    service);
+		return ERROR_CODE;
+	}
+
+	return socket_id;
+}
+
+/** Sends message to the socket parent module with specified data.
+ *
+ * @param[in] socket_id	Socket identifier.
+ * @param[in] message	The action message.
+ * @param[in] arg2	The second message parameter.
+ * @param[in] data	The data to be sent.
+ * @param[in] datalength The data length.
+ * @returns		EOK on success.
+ * @returns		ENOTSOCK if the socket is not found.
+ * @returns		EBADMEM if the data parameter is NULL.
+ * @returns		NO_DATA if the datalength parameter is zero (0).
+ * @returns		Other error codes as defined for the spcific message.
+ */
+static int
+socket_send_data(int socket_id, ipcarg_t message, ipcarg_t arg2,
+    const void *data, size_t datalength)
+{
+	socket_ref socket;
+	aid_t message_id;
+	ipcarg_t result;
+
+	if (!data)
+		return EBADMEM;
+
+	if (!datalength)
+		return NO_DATA;
+
+	fibril_rwlock_read_lock(&socket_globals.lock);
+
+	// find the socket
+	socket = sockets_find(socket_get_sockets(), socket_id);
+	if (!socket) {
+		fibril_rwlock_read_unlock(&socket_globals.lock);
+		return ENOTSOCK;
+	}
+
+	// request the message
+	message_id = async_send_3(socket->phone, message,
+	    (ipcarg_t) socket->socket_id, arg2, socket->service, NULL);
+	// send the address
+	async_data_write_start(socket->phone, data, datalength);
+
+	fibril_rwlock_read_unlock(&socket_globals.lock);
+	async_wait_for(message_id, &result);
+	return (int) result;
+}
+
+/** Binds the socket to a port address.
+ *
+ * @param[in] socket_id	Socket identifier.
+ * @param[in] my_addr	The port address.
+ * @param[in] addrlen	The address length.
+ * @returns		EOK on success.
+ * @returns		ENOTSOCK if the socket is not found.
+ * @returns		EBADMEM if the my_addr parameter is NULL.
+ * @returns		NO_DATA if the addlen parameter is zero.
+ * @returns		Other error codes as defined for the NET_SOCKET_BIND
+ *			message.
+ */
+int bind(int socket_id, const struct sockaddr * my_addr, socklen_t addrlen)
+{
+	if (addrlen <= 0)
+		return EINVAL;
+
+	// send the address
+	return socket_send_data(socket_id, NET_SOCKET_BIND, 0, my_addr,
+	    (size_t) addrlen);
+}
+
+/** Sets the number of connections waiting to be accepted.
+ *
+ * @param[in] socket_id	Socket identifier.
+ * @param[in] backlog	The maximum number of waiting sockets to be accepted.
+ * @returns		EOK on success.
+ * @returns		EINVAL if the backlog parameter is not positive (<=0).
+ * @returns		ENOTSOCK if the socket is not found.
+ * @returns		Other error codes as defined for the NET_SOCKET_LISTEN
+ *			message.
+ */
+int listen(int socket_id, int backlog)
+{
+	socket_ref socket;
+	int result;
+
+	if (backlog <= 0)
+		return EINVAL;
+
+	fibril_rwlock_read_lock(&socket_globals.lock);
+
+	// find the socket
+	socket = sockets_find(socket_get_sockets(), socket_id);
+	if (!socket) {
+		fibril_rwlock_read_unlock(&socket_globals.lock);
+		return ENOTSOCK;
+	}
+
+	// request listen backlog change
+	result = (int) async_req_3_0(socket->phone, NET_SOCKET_LISTEN,
+	    (ipcarg_t) socket->socket_id, (ipcarg_t) backlog, socket->service);
+
+	fibril_rwlock_read_unlock(&socket_globals.lock);
+	return result;
+}
+
+/** Accepts waiting socket.
+ *
+ * Blocks until such a socket exists.
+ *
+ * @param[in] socket_id	Socket identifier.
+ * @param[out] cliaddr	The remote client address.
+ * @param[in] addrlen	The address length.
+ * @returns		EOK on success.
+ * @returns		EBADMEM if the cliaddr or addrlen parameter is NULL.
+ * @returns		EINVAL if the backlog parameter is not positive (<=0).
+ * @returns		ENOTSOCK if the socket is not found.
+ * @returns		Other error codes as defined for the NET_SOCKET_ACCEPT
+ *			message.
+ */
+int accept(int socket_id, struct sockaddr * cliaddr, socklen_t * addrlen)
+{
+	socket_ref socket;
+	socket_ref new_socket;
+	aid_t message_id;
+	ipcarg_t ipc_result;
+	int result;
+	ipc_call_t answer;
+
+	if (!cliaddr || !addrlen)
+		return EBADMEM;
+
+	fibril_rwlock_write_lock(&socket_globals.lock);
+
+	// find the socket
+	socket = sockets_find(socket_get_sockets(), socket_id);
+	if (!socket) {
+		fibril_rwlock_write_unlock(&socket_globals.lock);
+		return ENOTSOCK;
+	}
+
+	fibril_mutex_lock(&socket->accept_lock);
+
+	// wait for an accepted socket
+	++ socket->blocked;
+	while (dyn_fifo_value(&socket->accepted) <= 0) {
+		fibril_rwlock_write_unlock(&socket_globals.lock);
+		fibril_condvar_wait(&socket->accept_signal, &socket->accept_lock);
+		// drop the accept lock to avoid deadlock
+		fibril_mutex_unlock(&socket->accept_lock);
+		fibril_rwlock_write_lock(&socket_globals.lock);
+		fibril_mutex_lock(&socket->accept_lock);
+	}
+	-- socket->blocked;
+
+	// create a new scoket
+	new_socket = (socket_ref) malloc(sizeof(socket_t));
+	if (!new_socket) {
+		fibril_mutex_unlock(&socket->accept_lock);
+		fibril_rwlock_write_unlock(&socket_globals.lock);
+		return ENOMEM;
+	}
+	bzero(new_socket, sizeof(*new_socket));
+	socket_id = socket_generate_new_id();
+	if (socket_id <= 0) {
+		fibril_mutex_unlock(&socket->accept_lock);
+		fibril_rwlock_write_unlock(&socket_globals.lock);
+		free(new_socket);
+		return socket_id;
+	}
+	socket_initialize(new_socket, socket_id, socket->phone,
+	    socket->service);
+	result = sockets_add(socket_get_sockets(), new_socket->socket_id,
+	    new_socket);
+	if (result < 0) {
+		fibril_mutex_unlock(&socket->accept_lock);
+		fibril_rwlock_write_unlock(&socket_globals.lock);
+		free(new_socket);
+		return result;
+	}
+
+	// request accept
+	message_id = async_send_5(socket->phone, NET_SOCKET_ACCEPT,
+	    (ipcarg_t) socket->socket_id, 0, socket->service, 0,
+	    new_socket->socket_id, &answer);
+
+	// read address
+	ipc_data_read_start(socket->phone, cliaddr, *addrlen);
+	fibril_rwlock_write_unlock(&socket_globals.lock);
+	async_wait_for(message_id, &ipc_result);
+	result = (int) ipc_result;
+	if (result > 0) {
+		if (result != socket_id)
+			result = EINVAL;
+
+		// dequeue the accepted socket if successful
+		dyn_fifo_pop(&socket->accepted);
+		// set address length
+		*addrlen = SOCKET_GET_ADDRESS_LENGTH(answer);
+		new_socket->data_fragment_size =
+		    SOCKET_GET_DATA_FRAGMENT_SIZE(answer);
+	} else if (result == ENOTSOCK) {
+		// empty the queue if no accepted sockets
+		while (dyn_fifo_pop(&socket->accepted) > 0)
+			;
+	}
+
+	fibril_mutex_unlock(&socket->accept_lock);
+	return result;
+}
+
+/** Connects socket to the remote server.
+ *
+ * @param[in] socket_id	Socket identifier.
+ * @param[in] serv_addr	The remote server address.
+ * @param[in] addrlen	The address length.
+ * @returns		EOK on success.
+ * @returns		EBADMEM if the serv_addr parameter is NULL.
+ * @returns		NO_DATA if the addlen parameter is zero.
+ * @returns		ENOTSOCK if the socket is not found.
+ * @returns		Other error codes as defined for the NET_SOCKET_CONNECT
+ *			message.
+ */
+int connect(int socket_id, const struct sockaddr *serv_addr, socklen_t addrlen)
+{
+	if (!serv_addr)
+		return EDESTADDRREQ;
+
+	if (!addrlen)
+		return EDESTADDRREQ;
+
+	// send the address
+	return socket_send_data(socket_id, NET_SOCKET_CONNECT, 0, serv_addr,
+	    addrlen);
+}
+
+/** Clears and destroys the socket.
+ *
+ * @param[in] socket	The socket to be destroyed.
+ */
+static void socket_destroy(socket_ref socket)
+{
+	int accepted_id;
+
+	// destroy all accepted sockets
+	while ((accepted_id = dyn_fifo_pop(&socket->accepted)) >= 0)
+		socket_destroy(sockets_find(socket_get_sockets(), accepted_id));
+
+	dyn_fifo_destroy(&socket->received);
+	dyn_fifo_destroy(&socket->accepted);
+	sockets_exclude(socket_get_sockets(), socket->socket_id);
+}
+
+/** Closes the socket.
+ *
+ * @param[in] socket_id	Socket identifier.
+ * @returns		EOK on success.
+ * @returns		ENOTSOCK if the socket is not found.
+ * @returns		EINPROGRESS if there is another blocking function in
+ *			progress.
+ * @returns		Other error codes as defined for the NET_SOCKET_CLOSE
+ *			message.
+ */
+int closesocket(int socket_id)
+{
+	ERROR_DECLARE;
+
+	socket_ref socket;
+
+	fibril_rwlock_write_lock(&socket_globals.lock);
+
+	socket = sockets_find(socket_get_sockets(), socket_id);
+	if (!socket) {
+		fibril_rwlock_write_unlock(&socket_globals.lock);
+		return ENOTSOCK;
+	}
+	if (socket->blocked) {
+		fibril_rwlock_write_unlock(&socket_globals.lock);
+		return EINPROGRESS;
+	}
+
+	// request close
+	ERROR_PROPAGATE((int) async_req_3_0(socket->phone, NET_SOCKET_CLOSE,
+	    (ipcarg_t) socket->socket_id, 0, socket->service));
+	// free the socket structure
+	socket_destroy(socket);
+
+	fibril_rwlock_write_unlock(&socket_globals.lock);
+	return EOK;
+}
+
+/** Sends data via the socket to the remote address.
+ *
+ * Binds the socket to a free port if not already connected/bound.
+ *
+ * @param[in] message	The action message.
+ * @param[in] socket_id Socket identifier.
+ * @param[in] data	The data to be sent.
+ * @param[in] datalength The data length.
+ * @param[in] flags	Various send flags.
+ * @param[in] toaddr	The destination address. May be NULL for connected
+ *			sockets.
+ * @param[in] addrlen	The address length. Used only if toaddr is not NULL.
+ * @returns		EOK on success.
+ * @returns		ENOTSOCK if the socket is not found.
+ * @returns		EBADMEM if the data or toaddr parameter is NULL.
+ * @returns		NO_DATA if the datalength or the addrlen parameter is
+ *			zero (0).
+ * @returns		Other error codes as defined for the NET_SOCKET_SENDTO
+ *			message.
+ */
+static int
+sendto_core(ipcarg_t message, int socket_id, const void *data,
+    size_t datalength, int flags, const struct sockaddr *toaddr,
+    socklen_t addrlen)
+{
+	socket_ref socket;
+	aid_t message_id;
+	ipcarg_t result;
+	size_t fragments;
+	ipc_call_t answer;
+
+	if (!data)
+		return EBADMEM;
+
+	if (!datalength)
+		return NO_DATA;
+
+	fibril_rwlock_read_lock(&socket_globals.lock);
+
+	// find socket
+	socket = sockets_find(socket_get_sockets(), socket_id);
+	if (!socket) {
+		fibril_rwlock_read_unlock(&socket_globals.lock);
+		return ENOTSOCK;
+	}
+
+	fibril_rwlock_read_lock(&socket->sending_lock);
+
+	// compute data fragment count
+	if (socket->data_fragment_size > 0) {
+		fragments = (datalength + socket->header_size) /
+		    socket->data_fragment_size;
+		if ((datalength + socket->header_size) %
+		    socket->data_fragment_size)
+			++fragments;
+	} else {
+		fragments = 1;
+	}
+
+	// request send
+	message_id = async_send_5(socket->phone, message,
+	    (ipcarg_t) socket->socket_id,
+	    (fragments == 1 ? datalength : socket->data_fragment_size),
+	    socket->service, (ipcarg_t) flags, fragments, &answer);
+
+	// send the address if given
+	if (!toaddr ||
+	    (async_data_write_start(socket->phone, toaddr, addrlen) == EOK)) {
+		if (fragments == 1) {
+			// send all if only one fragment
+			async_data_write_start(socket->phone, data, datalength);
+		} else {
+			// send the first fragment
+			async_data_write_start(socket->phone, data,
+			    socket->data_fragment_size - socket->header_size);
+			data = ((const uint8_t *) data) +
+			    socket->data_fragment_size - socket->header_size;
+	
+			// send the middle fragments
+			while (--fragments > 1) {
+				async_data_write_start(socket->phone, data,
+				    socket->data_fragment_size);
+				data = ((const uint8_t *) data) +
+				    socket->data_fragment_size;
+			}
+
+			// send the last fragment
+			async_data_write_start(socket->phone, data,
+			    (datalength + socket->header_size) %
+			    socket->data_fragment_size);
+		}
+	}
+
+	async_wait_for(message_id, &result);
+
+	if ((SOCKET_GET_DATA_FRAGMENT_SIZE(answer) > 0) &&
+	    (SOCKET_GET_DATA_FRAGMENT_SIZE(answer) !=
+	    socket->data_fragment_size)) {
+		// set the data fragment size
+		socket->data_fragment_size =
+		    SOCKET_GET_DATA_FRAGMENT_SIZE(answer);
+	}
+
+	fibril_rwlock_read_unlock(&socket->sending_lock);
+	fibril_rwlock_read_unlock(&socket_globals.lock);
+	return (int) result;
+}
+
+/** Sends data via the socket.
+ *
+ * @param[in] socket_id	Socket identifier.
+ * @param[in] data	The data to be sent.
+ * @param[in] datalength The data length.
+ * @param[in] flags	Various send flags.
+ * @returns		EOK on success.
+ * @returns		ENOTSOCK if the socket is not found.
+ * @returns		EBADMEM if the data parameter is NULL.
+ * @returns		NO_DATA if the datalength parameter is zero.
+ * @returns		Other error codes as defined for the NET_SOCKET_SEND
+ *			message.
+ */
+int send(int socket_id, void *data, size_t datalength, int flags)
+{
+	// without the address
+	return sendto_core(NET_SOCKET_SEND, socket_id, data, datalength, flags,
+	    NULL, 0);
+}
+
+/** Sends data via the socket to the remote address.
+ *
+ * Binds the socket to a free port if not already connected/bound.
+ *
+ * @param[in] socket_id	Socket identifier.
+ * @param[in] data	The data to be sent.
+ * @param[in] datalength The data length.
+ * @param[in] flags	Various send flags.
+ * @param[in] toaddr	The destination address.
+ * @param[in] addrlen	The address length.
+ * @returns		EOK on success.
+ * @returns		ENOTSOCK if the socket is not found.
+ * @returns		EBADMEM if the data or toaddr parameter is NULL.
+ * @returns		NO_DATA if the datalength or the addrlen parameter is
+ *			zero.
+ * @returns		Other error codes as defined for the NET_SOCKET_SENDTO
+ *			message.
+ */
+int
+sendto(int socket_id, const void *data, size_t datalength, int flags,
+    const struct sockaddr *toaddr, socklen_t addrlen)
+{
+	if (!toaddr)
+		return EDESTADDRREQ;
+
+	if (!addrlen)
+		return EDESTADDRREQ;
+
+	// with the address
+	return sendto_core(NET_SOCKET_SENDTO, socket_id, data, datalength,
+	    flags, toaddr, addrlen);
+}
+
+/** Receives data via the socket.
+ *
+ * @param[in] message	The action message.
+ * @param[in] socket_id	Socket identifier.
+ * @param[out] data	The data buffer to be filled.
+ * @param[in] datalength The data length.
+ * @param[in] flags	Various receive flags.
+ * @param[out] fromaddr	The source address. May be NULL for connected sockets.
+ * @param[in,out] addrlen The address length. The maximum address length is
+ *			read. The actual address length is set. Used only if
+ *			fromaddr is not NULL.
+ * @returns		EOK on success.
+ * @returns		ENOTSOCK if the socket is not found.
+ * @returns		EBADMEM if the data parameter is NULL.
+ * @returns		NO_DATA if the datalength or addrlen parameter is zero.
+ * @returns		Other error codes as defined for the spcific message.
+ */
+static int
+recvfrom_core(ipcarg_t message, int socket_id, void *data, size_t datalength,
+    int flags, struct sockaddr *fromaddr, socklen_t *addrlen)
+{
+	socket_ref socket;
+	aid_t message_id;
+	ipcarg_t ipc_result;
+	int result;
+	size_t fragments;
+	size_t *lengths;
+	size_t index;
+	ipc_call_t answer;
+
+	if (!data)
+		return EBADMEM;
+
+	if (!datalength)
+		return NO_DATA;
+
+	if (fromaddr && !addrlen)
+		return EINVAL;
+
+	fibril_rwlock_read_lock(&socket_globals.lock);
+
+	// find the socket
+	socket = sockets_find(socket_get_sockets(), socket_id);
+	if (!socket) {
+		fibril_rwlock_read_unlock(&socket_globals.lock);
+		return ENOTSOCK;
+	}
+
+	fibril_mutex_lock(&socket->receive_lock);
+	// wait for a received packet
+	++socket->blocked;
+	while ((result = dyn_fifo_value(&socket->received)) <= 0) {
+		fibril_rwlock_read_unlock(&socket_globals.lock);
+		fibril_condvar_wait(&socket->receive_signal,
+		    &socket->receive_lock);
+
+		// drop the receive lock to avoid deadlock
+		fibril_mutex_unlock(&socket->receive_lock);
+		fibril_rwlock_read_lock(&socket_globals.lock);
+		fibril_mutex_lock(&socket->receive_lock);
+	}
+	--socket->blocked;
+	fragments = (size_t) result;
+
+	// prepare lengths if more fragments
+	if (fragments > 1) {
+		lengths = (size_t *) malloc(sizeof(size_t) * fragments +
+		    sizeof(size_t));
+		if (!lengths) {
+			fibril_mutex_unlock(&socket->receive_lock);
+			fibril_rwlock_read_unlock(&socket_globals.lock);
+			return ENOMEM;
+		}
+
+		// request packet data
+		message_id = async_send_4(socket->phone, message,
+		    (ipcarg_t) socket->socket_id, 0, socket->service,
+		    (ipcarg_t) flags, &answer);
+
+		// read the address if desired
+		if(!fromaddr ||
+		    (async_data_read_start(socket->phone, fromaddr,
+		    *addrlen) == EOK)) {
+			// read the fragment lengths
+			if (async_data_read_start(socket->phone, lengths,
+			    sizeof(int) * (fragments + 1)) == EOK) {
+				if (lengths[fragments] <= datalength) {
+
+					// read all fragments if long enough
+					for (index = 0; index < fragments;
+					    ++index) {
+						async_data_read_start(
+						    socket->phone, data,
+						    lengths[index]);
+						data = ((uint8_t *) data) +
+						    lengths[index];
+					}
+				}
+			}
+		}
+
+		free(lengths);
+	} else {
+		// request packet data
+		message_id = async_send_4(socket->phone, message,
+		    (ipcarg_t) socket->socket_id, 0, socket->service,
+		    (ipcarg_t) flags, &answer);
+
+		// read the address if desired
+		if (!fromaddr ||
+		    (async_data_read_start(socket->phone, fromaddr,
+		        *addrlen) == EOK)) {
+			// read all if only one fragment
+			async_data_read_start(socket->phone, data, datalength);
+		}
+	}
+
+	async_wait_for(message_id, &ipc_result);
+	result = (int) ipc_result;
+	if (result == EOK) {
+		// dequeue the received packet
+		dyn_fifo_pop(&socket->received);
+		// return read data length
+		result = SOCKET_GET_READ_DATA_LENGTH(answer);
+		// set address length
+		if (fromaddr && addrlen)
+			*addrlen = SOCKET_GET_ADDRESS_LENGTH(answer);
+	}
+
+	fibril_mutex_unlock(&socket->receive_lock);
+	fibril_rwlock_read_unlock(&socket_globals.lock);
+	return result;
+}
+
+/** Receives data via the socket.
+ *
+ * @param[in] socket_id	Socket identifier.
+ * @param[out] data	The data buffer to be filled.
+ * @param[in] datalength The data length.
+ * @param[in] flags	Various receive flags.
+ * @returns		EOK on success.
+ * @returns		ENOTSOCK if the socket is not found.
+ * @returns		EBADMEM if the data parameter is NULL.
+ * @returns		NO_DATA if the datalength parameter is zero.
+ * @returns		Other error codes as defined for the NET_SOCKET_RECV
+ *			message.
+ */
+int recv(int socket_id, void *data, size_t datalength, int flags)
+{
+	// without the address
+	return recvfrom_core(NET_SOCKET_RECV, socket_id, data, datalength,
+	    flags, NULL, NULL);
+}
+
+/** Receives data via the socket.
+ *
+ * @param[in] socket_id	Socket identifier.
+ * @param[out] data	The data buffer to be filled.
+ * @param[in] datalength The data length.
+ * @param[in] flags	Various receive flags.
+ * @param[out] fromaddr	The source address.
+ * @param[in,out] addrlen The address length. The maximum address length is
+ *			read. The actual address length is set.
+ * @returns		EOK on success.
+ * @returns		ENOTSOCK if the socket is not found.
+ * @returns		EBADMEM if the data or fromaddr parameter is NULL.
+ * @returns		NO_DATA if the datalength or addrlen parameter is zero.
+ * @returns		Other error codes as defined for the NET_SOCKET_RECVFROM
+ *			message.
+ */
+int
+recvfrom(int socket_id, void *data, size_t datalength, int flags,
+    struct sockaddr *fromaddr, socklen_t *addrlen)
+{
+	if (!fromaddr)
+		return EBADMEM;
+
+	if (!addrlen)
+		return NO_DATA;
+
+	// with the address
+	return recvfrom_core(NET_SOCKET_RECVFROM, socket_id, data, datalength,
+	    flags, fromaddr, addrlen);
+}
+
+/** Gets socket option.
+ *
+ * @param[in] socket_id	Socket identifier.
+ * @param[in] level	The socket options level.
+ * @param[in] optname	The socket option to be get.
+ * @param[out] value	The value buffer to be filled.
+ * @param[in,out] optlen The value buffer length. The maximum length is read.
+ *			The actual length is set.
+ * @returns		EOK on success.
+ * @returns		ENOTSOCK if the socket is not found.
+ * @returns		EBADMEM if the value or optlen parameter is NULL.
+ * @returns		NO_DATA if the optlen parameter is zero.
+ * @returns		Other error codes as defined for the
+ *			NET_SOCKET_GETSOCKOPT message.
+ */
+int
+getsockopt(int socket_id, int level, int optname, void *value, size_t *optlen)
+{
+	socket_ref socket;
+	aid_t message_id;
+	ipcarg_t result;
+
+	if (!value || !optlen)
+		return EBADMEM;
+
+	if (!*optlen)
+		return NO_DATA;
+
+	fibril_rwlock_read_lock(&socket_globals.lock);
+
+	// find the socket
+	socket = sockets_find(socket_get_sockets(), socket_id);
+	if (!socket) {
+		fibril_rwlock_read_unlock(&socket_globals.lock);
+		return ENOTSOCK;
+	}
+
+	// request option value
+	message_id = async_send_3(socket->phone, NET_SOCKET_GETSOCKOPT,
+	    (ipcarg_t) socket->socket_id, (ipcarg_t) optname, socket->service,
+	    NULL);
+
+	// read the length
+	if (async_data_read_start(socket->phone, optlen,
+	    sizeof(*optlen)) == EOK) {
+		// read the value
+		async_data_read_start(socket->phone, value, *optlen);
+	}
+
+	fibril_rwlock_read_unlock(&socket_globals.lock);
+	async_wait_for(message_id, &result);
+	return (int) result;
+}
+
+/** Sets socket option.
+ *
+ * @param[in] socket_id	Socket identifier.
+ * @param[in] level	The socket options level.
+ * @param[in] optname	The socket option to be set.
+ * @param[in] value	The value to be set.
+ * @param[in] optlen	The value length.
+ * @returns		EOK on success.
+ * @returns		ENOTSOCK if the socket is not found.
+ * @returns		EBADMEM if the value parameter is NULL.
+ * @returns		NO_DATA if the optlen parameter is zero.
+ * @returns		Other error codes as defined for the
+ *			NET_SOCKET_SETSOCKOPT message.
+ */
+int
+setsockopt(int socket_id, int level, int optname, const void *value,
+    size_t optlen)
+{
+	// send the value
+	return socket_send_data(socket_id, NET_SOCKET_SETSOCKOPT,
+	    (ipcarg_t) optname, value, optlen);
+}
+
+/** @}
+ */
Index: uspace/lib/c/generic/net/socket_parse.c
===================================================================
--- uspace/lib/c/generic/net/socket_parse.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
+++ uspace/lib/c/generic/net/socket_parse.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -0,0 +1,122 @@
+/*
+ * Copyright (c) 2009 Lukas Mejdrech
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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 socket
+ * @{
+ */
+
+/** @file
+ * Command-line argument parsing functions related to networking.
+ */
+
+#include <net/socket_parse.h>
+#include <net/socket.h>
+#include <arg_parse.h>
+#include <errno.h>
+#include <str.h>
+
+/** Translate the character string to the address family number.
+ *
+ * @param[in]  name The address family name.
+ * @param[out] af   The corresponding address family number
+ *                  or EAFNOSUPPORTED.
+ *
+ * @return EOK on success.
+ * @return ENOTSUP on unsupported address family.
+ *
+ */
+int socket_parse_address_family(const char *name, int *af)
+{
+	if (str_lcmp(name, "AF_INET", 7) == 0) {
+		*af = AF_INET;
+		return EOK;
+	}
+	
+	if (str_lcmp(name, "AF_INET6", 8) == 0) {
+		*af = AF_INET6;
+		return EOK;
+	}
+	
+	*af = EAFNOSUPPORT;
+	return ENOTSUP;
+}
+
+/** Translate the character string to the protocol family number.
+ *
+ * @param[in]  name The protocol family name.
+ * @param[out] pf   The corresponding protocol family number
+ *                  or EPFNOSUPPORTED.
+ *
+ * @return EOK on success.
+ * @return ENOTSUP on unsupported protocol family.
+ *
+ */
+int socket_parse_protocol_family(const char *name, int *pf)
+{
+	if (str_lcmp(name, "PF_INET", 7) == 0) {
+		*pf = PF_INET;
+		return EOK;
+	}
+	
+	if (str_lcmp(name, "PF_INET6", 8) == 0) {
+		*pf = PF_INET6;
+		return EOK;
+	}
+	
+	*pf = EPFNOSUPPORT;
+	return ENOTSUP;
+}
+
+/** Translate the character string to the socket type number.
+ *
+ * @param[in]  name  The socket type name.
+ * @param[out] sockt The corresponding socket type number
+ *                   or ESOCKTNOSUPPORT.
+ *
+ * @return EOK on success.
+ * @return ENOTSUP on unsupported socket type.
+ *
+ */
+int socket_parse_socket_type(const char *name, int *sockt)
+{
+	if (str_lcmp(name, "SOCK_DGRAM", 11) == 0) {
+		*sockt = SOCK_DGRAM;
+		return EOK;
+	}
+	
+	if (str_lcmp(name, "SOCK_STREAM", 12) == 0) {
+		*sockt = SOCK_STREAM;
+		return EOK;
+	}
+	
+	*sockt = ESOCKTNOSUPPORT;
+	return ENOTSUP;
+}
+
+/** @}
+ */
Index: uspace/lib/c/generic/sort.c
===================================================================
--- uspace/lib/c/generic/sort.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
+++ uspace/lib/c/generic/sort.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -0,0 +1,223 @@
+/*
+ * 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/stats.c
===================================================================
--- uspace/lib/c/generic/stats.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/lib/c/generic/stats.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -184,4 +184,48 @@
 }
 
+/** Get exception statistics.
+ *
+ * @param count Number of records returned.
+ *
+ * @return Array of stats_exc_t structures.
+ *         If non-NULL then it should be eventually freed
+ *         by free().
+ *
+ */
+stats_exc_t *stats_get_exceptions(size_t *count)
+{
+	size_t size = 0;
+	stats_exc_t *stats_exceptions =
+	    (stats_exc_t *) sysinfo_get_data("system.exceptions", &size);
+	
+	assert((size % sizeof(stats_exc_t)) == 0);
+	
+	*count = size / sizeof(stats_exc_t);
+	return stats_exceptions;
+}
+
+/** Get single exception statistics
+ *
+ * @param excn Exception number we are interested in.
+ *
+ * @return Pointer to the stats_exc_t structure.
+ *         If non-NULL then it should be eventually freed
+ *         by free().
+ *
+ */
+stats_exc_t *stats_get_exception(unsigned int excn)
+{
+	char name[SYSINFO_STATS_MAX_PATH];
+	snprintf(name, SYSINFO_STATS_MAX_PATH, "system.exceptionss.%u", excn);
+	
+	size_t size = 0;
+	stats_exc_t *stats_exception =
+	    (stats_exc_t *) sysinfo_get_data(name, &size);
+	
+	assert((size == sizeof(stats_exc_t)) || (size == 0));
+	
+	return stats_exception;
+}
+
 /** Get system load
  *
Index: uspace/lib/c/generic/str.c
===================================================================
--- uspace/lib/c/generic/str.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/lib/c/generic/str.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -37,5 +37,5 @@
 #include <stdlib.h>
 #include <assert.h>
-#include <limits.h>
+#include <stdint.h>
 #include <ctype.h>
 #include <malloc.h>
Index: uspace/lib/c/include/adt/char_map.h
===================================================================
--- uspace/lib/c/include/adt/char_map.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
+++ uspace/lib/c/include/adt/char_map.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2009 Lukas Mejdrech
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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
+ *  Character string to integer map.
+ */
+
+#ifndef LIBC_CHAR_MAP_H_
+#define LIBC_CHAR_MAP_H_
+
+#include <libarch/types.h>
+
+/** Invalid assigned value used also if an&nbsp;entry does not exist. */
+#define CHAR_MAP_NULL	(-1)
+
+/** Type definition of the character string to integer map.
+ *  @see char_map
+ */
+typedef struct char_map	char_map_t;
+
+/** Type definition of the character string to integer map pointer.
+ *  @see char_map
+ */
+typedef char_map_t *char_map_ref;
+
+/** Character string to integer map item.
+ *
+ * This structure recursivelly contains itself as a character by character tree.
+ * The actually mapped character string consists of all the parent characters
+ * and the actual one.
+ */
+struct char_map {
+	/** Actually mapped character. */
+	char c;
+	/** Stored integral value. */
+	int value;
+	/** Next character array size. */
+	int size;
+	/** First free position in the next character array. */
+	int next;
+	/** Next character array. */
+	char_map_ref *items;
+	/** Consistency check magic value. */
+	int magic;
+};
+
+extern int char_map_initialize(char_map_ref);
+extern void char_map_destroy(char_map_ref);
+extern int char_map_exclude(char_map_ref, const char *, size_t);
+extern int char_map_add(char_map_ref, const char *, size_t, const int);
+extern int char_map_find(const char_map_ref, const char *, size_t);
+extern int char_map_update(char_map_ref, const char *, size_t, const int);
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/include/adt/dynamic_fifo.h
===================================================================
--- uspace/lib/c/include/adt/dynamic_fifo.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
+++ uspace/lib/c/include/adt/dynamic_fifo.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2009 Lukas Mejdrech
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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
+ * Dynamic first in first out positive integer queue.
+ * Possitive integer values only.
+ */
+
+#ifndef LIBC_DYNAMIC_FIFO_H_
+#define LIBC_DYNAMIC_FIFO_H_
+
+/** Type definition of the dynamic fifo queue.
+ * @see dyn_fifo
+ */
+typedef struct dyn_fifo	dyn_fifo_t;
+
+/** Type definition of the dynamic fifo queue pointer.
+ *  @see dyn_fifo
+ */
+typedef dyn_fifo_t *dyn_fifo_ref;
+
+/** Dynamic first in first out positive integer queue.
+ * Possitive integer values only.
+ * The queue automatically resizes if needed.
+ */
+struct dyn_fifo {
+	/** Stored item field. */
+	int *items;
+	/** Actual field size. */
+	int size;
+	/** First item in the queue index. */
+	int head;
+	/** Last item in the queue index. */
+	int tail;
+	/** Consistency check magic value. */
+	int magic_value;
+};
+
+extern int dyn_fifo_initialize(dyn_fifo_ref, int);
+extern int dyn_fifo_destroy(dyn_fifo_ref);
+extern int dyn_fifo_push(dyn_fifo_ref, int, int);
+extern int dyn_fifo_pop(dyn_fifo_ref);
+extern int dyn_fifo_value(dyn_fifo_ref);
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/include/adt/generic_char_map.h
===================================================================
--- uspace/lib/c/include/adt/generic_char_map.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
+++ uspace/lib/c/include/adt/generic_char_map.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -0,0 +1,163 @@
+/*
+ * Copyright (c) 2009 Lukas Mejdrech
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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
+ *  Character string to generic type map.
+ */
+
+#ifndef LIBC_GENERIC_CHAR_MAP_H_
+#define LIBC_GENERIC_CHAR_MAP_H_
+
+#include <unistd.h>
+#include <errno.h>
+#include <err.h>
+
+#include <adt/char_map.h>
+#include <adt/generic_field.h>
+
+/** Internal magic value for a&nbsp;map consistency check. */
+#define GENERIC_CHAR_MAP_MAGIC_VALUE	0x12345622
+
+/** Character string to generic type map declaration.
+ *  @param[in] name	Name of the map.
+ *  @param[in] type	Inner object type.
+ */
+#define GENERIC_CHAR_MAP_DECLARE(name, type) \
+	GENERIC_FIELD_DECLARE(name##_items, type) \
+	\
+	typedef	struct name name##_t; \
+	typedef	name##_t *name##_ref; \
+	\
+	struct	name { \
+		char_map_t names; \
+		name##_items_t values; \
+		int magic; \
+	}; \
+	\
+	int name##_add(name##_ref, const char *, const size_t, type *); \
+	int name##_count(name##_ref); \
+	void name##_destroy(name##_ref); \
+	void name##_exclude(name##_ref, const char *, const size_t); \
+	type *name##_find(name##_ref, const char *, const size_t); \
+	int name##_initialize(name##_ref); \
+	int name##_is_valid(name##_ref);
+
+/** Character string to generic type map implementation.
+ *
+ * Should follow declaration with the same parameters.
+ *
+ * @param[in] name	Name of the map.
+ * @param[in] type	Inner object type.
+ */
+#define GENERIC_CHAR_MAP_IMPLEMENT(name, type) \
+	GENERIC_FIELD_IMPLEMENT(name##_items, type) \
+	\
+	int name##_add(name##_ref map, const char *name, const size_t length, \
+	     type *value) \
+	{ \
+		ERROR_DECLARE; \
+		int index; \
+		if (!name##_is_valid(map)) \
+			return EINVAL; \
+		index = name##_items_add(&map->values, value); \
+		if (index < 0) \
+			return index; \
+		if (ERROR_OCCURRED(char_map_add(&map->names, name, length, \
+		    index))) { \
+			name##_items_exclude_index(&map->values, index); \
+			return ERROR_CODE; \
+		} \
+		return EOK; \
+	} \
+	\
+	int name##_count(name##_ref map) \
+	{ \
+		return name##_is_valid(map) ? \
+		    name##_items_count(&map->values) : -1; \
+	} \
+	\
+	void name##_destroy(name##_ref map) \
+	{ \
+		if (name##_is_valid(map)) { \
+			char_map_destroy(&map->names); \
+			name##_items_destroy(&map->values); \
+		} \
+	} \
+	\
+	void name##_exclude(name##_ref map, const char *name, \
+	    const size_t length) \
+	{ \
+		if (name##_is_valid(map)) { \
+			int index; \
+			index = char_map_exclude(&map->names, name, length); \
+			if (index != CHAR_MAP_NULL) \
+				name##_items_exclude_index(&map->values, \
+				     index); \
+		} \
+	} \
+	\
+	type *name##_find(name##_ref map, const char *name, \
+	    const size_t length) \
+	{ \
+		if (name##_is_valid(map)) { \
+			int index; \
+			index = char_map_find(&map->names, name, length); \
+			if( index != CHAR_MAP_NULL) \
+				return name##_items_get_index(&map->values, \
+				    index); \
+		} \
+		return NULL; \
+	} \
+	\
+	int name##_initialize(name##_ref map) \
+	{ \
+		ERROR_DECLARE; \
+		if (!map) \
+			return EINVAL; \
+		ERROR_PROPAGATE(char_map_initialize(&map->names)); \
+		if (ERROR_OCCURRED(name##_items_initialize(&map->values))) { \
+			char_map_destroy(&map->names); \
+			return ERROR_CODE; \
+		} \
+		map->magic = GENERIC_CHAR_MAP_MAGIC_VALUE; \
+		return EOK; \
+	} \
+	\
+	int name##_is_valid(name##_ref map) \
+	{ \
+		return map && (map->magic == GENERIC_CHAR_MAP_MAGIC_VALUE); \
+	}
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/include/adt/generic_field.h
===================================================================
--- uspace/lib/c/include/adt/generic_field.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
+++ uspace/lib/c/include/adt/generic_field.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -0,0 +1,163 @@
+/*
+ * Copyright (c) 2009 Lukas Mejdrech
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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
+ *  Generic type field.
+ */
+
+#ifndef LIBC_GENERIC_FIELD_H_
+#define LIBC_GENERIC_FIELD_H_
+
+#include <errno.h>
+#include <malloc.h>
+#include <mem.h>
+#include <unistd.h>
+
+/** Internal magic value for a&nbsp;field consistency check. */
+#define GENERIC_FIELD_MAGIC_VALUE		0x55667788
+
+/** Generic type field declaration.
+ *
+ * @param[in] name	Name of the field.
+ * @param[in] type	Inner object type.
+ */
+#define GENERIC_FIELD_DECLARE(name, type) \
+	typedef	struct name name##_t; \
+	typedef	name##_t *name##_ref; \
+	\
+	struct	name { \
+		int size; \
+		int next; \
+		type **items; \
+		int magic; \
+	}; \
+	\
+	int name##_add(name##_ref, type *); \
+	int name##_count(name##_ref); \
+	void name##_destroy(name##_ref); \
+	void name##_exclude_index(name##_ref, int); \
+	type **name##_get_field(name##_ref); \
+	type *name##_get_index(name##_ref, int); \
+	int name##_initialize(name##_ref); \
+	int name##_is_valid(name##_ref);
+
+/** Generic type field implementation.
+ *
+ * Should follow declaration with the same parameters.
+ *
+ * @param[in] name	Name of the field.
+ * @param[in] type	Inner object type.
+ */
+#define GENERIC_FIELD_IMPLEMENT(name, type) \
+	int name##_add(name##_ref field, type *value) \
+	{ \
+		if (name##_is_valid(field)) { \
+			if (field->next == (field->size - 1)) { \
+				type **tmp; \
+				tmp = (type **) realloc(field->items, \
+				    sizeof(type *) * 2 * field->size); \
+				if (!tmp) \
+					return ENOMEM; \
+				field->size *= 2; \
+				field->items = tmp; \
+			} \
+			field->items[field->next] = value; \
+			++field->next; \
+			field->items[field->next] = NULL; \
+			return field->next - 1; \
+		} \
+		return EINVAL; \
+	} \
+	\
+	int name##_count(name##_ref field) \
+	{ \
+		return name##_is_valid(field) ? field->next : -1; \
+	} \
+	\
+	void name##_destroy(name##_ref field) \
+	{ \
+		if (name##_is_valid(field)) { \
+			int index; \
+			field->magic = 0; \
+			for (index = 0; index < field->next; ++ index) { \
+				if (field->items[index]) \
+					free(field->items[index]); \
+			} \
+			free(field->items); \
+		} \
+	} \
+	 \
+	void name##_exclude_index(name##_ref field, int index) \
+	{ \
+		if (name##_is_valid(field) && (index >= 0) && \
+		    (index < field->next) && (field->items[index])) { \
+			free(field->items[index]); \
+			field->items[index] = NULL; \
+		} \
+	} \
+	 \
+	type *name##_get_index(name##_ref field, int index) \
+	{ \
+		if (name##_is_valid(field) && (index >= 0) && \
+		    (index < field->next) && (field->items[index])) \
+			return field->items[index]; \
+		return NULL; \
+	} \
+	\
+	type **name##_get_field(name##_ref field) \
+	{ \
+		return name##_is_valid(field) ? field->items : NULL; \
+	} \
+	\
+	int name##_initialize(name##_ref field) \
+	{ \
+		if (!field) \
+			return EINVAL; \
+		field->size = 2; \
+		field->next = 0; \
+		field->items = (type **) malloc(sizeof(type *) * field->size); \
+		if (!field->items) \
+			return ENOMEM; \
+		field->items[field->next] = NULL; \
+		field->magic = GENERIC_FIELD_MAGIC_VALUE; \
+		return EOK; \
+	} \
+	\
+	int name##_is_valid(name##_ref field) \
+	{ \
+		return field && (field->magic == GENERIC_FIELD_MAGIC_VALUE); \
+	}
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/include/adt/int_map.h
===================================================================
--- uspace/lib/c/include/adt/int_map.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
+++ uspace/lib/c/include/adt/int_map.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -0,0 +1,260 @@
+/*
+ * Copyright (c) 2009 Lukas Mejdrech
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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
+ *  Integer to generic type map.
+ */
+
+#ifndef LIBC_INT_MAP_H_
+#define LIBC_INT_MAP_H_
+
+#include <errno.h>
+#include <malloc.h>
+#include <mem.h>
+#include <unistd.h>
+
+/** Internal magic value for a map consistency check. */
+#define INT_MAP_MAGIC_VALUE		0x11223344
+
+/** Internal magic value for an item consistency check. */
+#define INT_MAP_ITEM_MAGIC_VALUE	0x55667788
+
+/** Integer to generic type map declaration.
+ *
+ * @param[in] name	Name of the map.
+ * @param[in] type	Inner object type.
+ */
+#define INT_MAP_DECLARE(name, type) \
+	typedef	struct name name##_t; \
+	typedef	name##_t *name##_ref; \
+	typedef	struct name##_item name##_item_t; \
+	typedef	name##_item_t *name##_item_ref; \
+	\
+	struct	name##_item { \
+		int key; \
+		type *value; \
+		int magic; \
+	}; \
+	\
+	struct	name { \
+		int size; \
+		int next; \
+		name##_item_ref items; \
+		int magic; \
+	}; \
+	\
+	int name##_add(name##_ref, int, type *); \
+	void name##_clear(name##_ref); \
+	int name##_count(name##_ref); \
+	void name##_destroy(name##_ref); \
+	void name##_exclude(name##_ref, int); \
+	void name##_exclude_index(name##_ref, int); \
+	type *name##_find(name##_ref, int); \
+	int name##_update(name##_ref, int, int); \
+	type *name##_get_index(name##_ref, int); \
+	int name##_initialize(name##_ref); \
+	int name##_is_valid(name##_ref); \
+	void name##_item_destroy(name##_item_ref); \
+	int name##_item_is_valid(name##_item_ref);
+
+/** Integer to generic type map implementation.
+ *
+ * Should follow declaration with the same parameters.
+ *
+ * @param[in] name	Name of the map.
+ * @param[in] type	Inner object type.
+ */
+#define INT_MAP_IMPLEMENT(name, type) \
+	int name##_add(name##_ref map, int key, type *value) \
+	{ \
+		if (name##_is_valid(map)) { \
+			if (map->next == (map->size - 1)) { \
+				name##_item_ref tmp; \
+				tmp = (name##_item_ref) realloc(map->items, \
+				    sizeof(name##_item_t) * 2 * map->size); \
+				if (!tmp) \
+					return ENOMEM; \
+				map->size *= 2; \
+				map->items = tmp; \
+			} \
+			map->items[map->next].key = key; \
+			map->items[map->next].value = value; \
+			map->items[map->next].magic = INT_MAP_ITEM_MAGIC_VALUE; \
+			++map->next; \
+			map->items[map->next].magic = 0; \
+			return map->next - 1; \
+		} \
+		return EINVAL; \
+	} \
+	\
+	void name##_clear(name##_ref map) \
+	{ \
+		if (name##_is_valid(map)) { \
+			int index; \
+			for (index = 0; index < map->next; ++index) { \
+				if (name##_item_is_valid(&map->items[index])) { \
+					name##_item_destroy( \
+					    &map->items[index]); \
+				} \
+			} \
+			map->next = 0; \
+			map->items[map->next].magic = 0; \
+		} \
+	} \
+	\
+	int name##_count(name##_ref map) \
+	{ \
+		return name##_is_valid(map) ? map->next : -1; \
+	} \
+	\
+	void name##_destroy(name##_ref map) \
+	{ \
+		if (name##_is_valid(map)) { \
+			int index; \
+			map->magic = 0; \
+			for (index = 0; index < map->next; ++index) { \
+				if (name##_item_is_valid(&map->items[index])) { \
+					name##_item_destroy( \
+					    &map->items[index]); \
+				} \
+			} \
+			free(map->items); \
+		} \
+	} \
+	\
+	void name##_exclude(name##_ref map, int key) \
+	{ \
+		if (name##_is_valid(map)) { \
+			int index; \
+			for (index = 0; index < map->next; ++index) { \
+				if (name##_item_is_valid(&map->items[index]) && \
+				    (map->items[index].key == key)) { \
+					name##_item_destroy( \
+					    &map->items[index]); \
+				} \
+			} \
+		} \
+	} \
+	\
+	void name##_exclude_index(name##_ref map, int index) \
+	{ \
+		if (name##_is_valid(map) && (index >= 0) && \
+		    (index < map->next) && \
+		    name##_item_is_valid(&map->items[index])) { \
+			name##_item_destroy(&map->items[index]); \
+		} \
+	} \
+	\
+	type *name##_find(name##_ref map, int key) \
+	{ \
+		if (name##_is_valid(map)) { \
+			int index; \
+			for (index = 0; index < map->next; ++index) { \
+				if (name##_item_is_valid(&map->items[index]) && \
+				    (map->items[index].key == key)) { \
+					return map->items[index].value; \
+				} \
+			} \
+		} \
+		return NULL; \
+	} \
+	\
+	int name##_update(name##_ref map, int key, int new_key) \
+	{ \
+		if (name##_is_valid(map)) { \
+			int index; \
+			for (index = 0; index < map->next; ++index) { \
+				if (name##_item_is_valid(&map->items[index])) { \
+					if (map->items[index].key == new_key) \
+						return EEXIST; \
+					if (map->items[index].key == key) { \
+						map->items[index].key = \
+						    new_key; \
+						return EOK; \
+					} \
+				} \
+			} \
+		} \
+		return ENOENT; \
+	} \
+	\
+	type *name##_get_index(name##_ref map, int index) \
+	{ \
+		if (name##_is_valid(map) && (index >= 0) && \
+		    (index < map->next) && \
+		    name##_item_is_valid(&map->items[index])) { \
+			return map->items[index].value; \
+		} \
+		return NULL; \
+	} \
+	\
+	int name##_initialize(name##_ref map) \
+	{ \
+		if (!map) \
+			return EINVAL; \
+		map->size = 2; \
+		map->next = 0; \
+		map->items = (name##_item_ref) malloc(sizeof(name##_item_t) * \
+		    map->size); \
+		if (!map->items) \
+			return ENOMEM; \
+		map->items[map->next].magic = 0; \
+		map->magic = INT_MAP_MAGIC_VALUE; \
+		return EOK; \
+	} \
+	\
+	int name##_is_valid(name##_ref map) \
+	{ \
+		return map && (map->magic == INT_MAP_MAGIC_VALUE); \
+	} \
+	\
+	void name##_item_destroy(name##_item_ref item) \
+	{ \
+		if (name##_item_is_valid(item)) { \
+			item->magic = 0; \
+			if (item->value) { \
+				free(item->value); \
+				item->value = NULL; \
+			} \
+		} \
+	} \
+	\
+	int name##_item_is_valid(name##_item_ref item) \
+	{ \
+		return item && (item->magic == INT_MAP_ITEM_MAGIC_VALUE); \
+	}
+
+#endif
+
+/** @}
+ */
+
Index: uspace/lib/c/include/adt/measured_strings.h
===================================================================
--- uspace/lib/c/include/adt/measured_strings.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
+++ uspace/lib/c/include/adt/measured_strings.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2009 Lukas Mejdrech
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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
+ * Character string with measured length.
+ * The structure has been designed for serialization of character strings
+ * between modules.
+ */
+
+#ifndef LIBC_MEASURED_STRINGS_H_
+#define LIBC_MEASURED_STRINGS_H_
+
+#include <sys/types.h>
+
+/** Type definition of the character string with measured length.
+ *  @see measured_string
+ */
+typedef struct measured_string measured_string_t;
+
+/** Type definition of the character string with measured length pointer.
+ *  @see measured_string
+ */
+typedef measured_string_t *measured_string_ref;
+
+/** Character string with measured length.
+ *
+ * This structure has been designed for serialization of character strings
+ * between modules.
+ */
+struct measured_string {
+	/** Character string data. */
+	char * value;
+	/** Character string length. */
+	size_t length;
+};
+
+extern measured_string_ref measured_string_create_bulk(const char *, size_t);
+extern measured_string_ref measured_string_copy(measured_string_ref);
+extern int measured_strings_receive(measured_string_ref *, char **, size_t);
+extern int measured_strings_reply(const measured_string_ref, size_t);
+extern int measured_strings_return(int, measured_string_ref *, char **, size_t);
+extern int measured_strings_send(int, const measured_string_ref, size_t);
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/include/async_rel.h
===================================================================
--- uspace/lib/c/include/async_rel.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
+++ uspace/lib/c/include/async_rel.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2010 Jakub Jermar
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup libc
+ * @{
+ */
+/** @file
+ */
+
+#ifndef LIBC_ASYNC_REL_H_
+#define LIBC_ASYNC_REL_H_
+
+extern int async_rel_init(void);
+extern int async_relation_create(int);
+extern void async_relation_destroy(int, int);
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/include/byteorder.h
===================================================================
--- uspace/lib/c/include/byteorder.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/lib/c/include/byteorder.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -80,4 +80,9 @@
 #endif
 
+#define htons(n)	host2uint16_t_be((n))
+#define htonl(n)	host2uint32_t_be((n))
+#define ntohs(n)	uint16_t_be2host((n))
+#define ntohl(n)	uint32_t_be2host((n))
+
 static inline uint64_t uint64_t_byteorder_swap(uint64_t n)
 {
Index: uspace/lib/c/include/ddi.h
===================================================================
--- uspace/lib/c/include/ddi.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/lib/c/include/ddi.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -41,5 +41,4 @@
 extern int physmem_map(void *, void *, unsigned long, int);
 extern int iospace_enable(task_id_t, void *, unsigned long);
-extern int preemption_control(int);
 extern int pio_enable(void *, size_t, void **);
 extern int interrupt_enable(int);
Index: uspace/lib/c/include/err.h
===================================================================
--- uspace/lib/c/include/err.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/lib/c/include/err.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -36,4 +36,11 @@
 #define LIBC_ERR_H_
 
+#include <stdio.h>
+#include <errno.h>
+
+#ifdef CONFIG_DEBUG
+#include <str_error.h>
+#endif
+
 #define errx(status, fmt, ...) { \
 	printf((fmt), ##__VA_ARGS__); \
@@ -41,4 +48,52 @@
 }
 
+
+/** An actual stored error code.  */
+#define ERROR_CODE  error_check_return_value
+
+/** An error processing routines declaration.
+ *
+ * This has to be declared in the block where the error processing
+ * is desired.
+ */
+#define ERROR_DECLARE  int ERROR_CODE
+
+/** Store the value as an error code and checks if an error occurred.
+ *
+ * @param[in] value	The value to be checked. May be a function call.
+ * @return		False if the value indicates success (EOK).
+ * @return		True otherwise.
+ */
+#ifdef CONFIG_DEBUG
+
+#define ERROR_OCCURRED(value) \
+	(((ERROR_CODE = (value)) != EOK) && \
+	({ \
+		fprintf(stderr, "libsocket error at %s:%d (%s)\n", \
+		__FILE__, __LINE__, str_error(ERROR_CODE)); \
+		1; \
+	}))
+
+#else
+
+#define ERROR_OCCURRED(value)	((ERROR_CODE = (value)) != EOK)
+
+#endif
+
+#define ERROR_NONE(value)	!ERROR_OCCURRED((value))
+
+/** Error propagation
+ *
+ * Check if an error occurred and immediately exit the actual
+ * function returning the error code.
+ *
+ * @param[in] value	The value to be checked. May be a function call.
+ *
+ */
+
+#define ERROR_PROPAGATE(value) \
+	if (ERROR_OCCURRED(value)) \
+		return ERROR_CODE
+
 #endif
 
Index: uspace/lib/c/include/errno.h
===================================================================
--- uspace/lib/c/include/errno.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/lib/c/include/errno.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -56,4 +56,40 @@
 #define EMLINK        (-266)
 
+/** An API function is called while another blocking function is in progress. */
+#define EINPROGRESS	(-10036)
+
+/** The socket identifier is not valid. */
+#define ENOTSOCK	(-10038)
+
+/** The destination address required. */
+#define EDESTADDRREQ	(-10039)
+
+/** Protocol is not supported.  */
+#define EPROTONOSUPPORT	(-10043)
+
+/** Socket type is not supported. */
+#define ESOCKTNOSUPPORT	(-10044)
+
+/** Protocol family is not supported. */
+#define EPFNOSUPPORT	(-10046)
+
+/** Address family is not supported. */
+#define EAFNOSUPPORT	(-10047)
+
+/** Address is already in use. */
+#define EADDRINUSE	(-10048)
+
+/** The socket is not connected or bound. */
+#define ENOTCONN	(-10057)
+
+/** The requested operation was not performed.
+ *  Try again later.
+ */
+#define TRY_AGAIN	(-11002)
+
+/** No data.
+ */
+#define NO_DATA		(-11004)
+
 #endif
 
Index: uspace/lib/c/include/fibril_synch.h
===================================================================
--- uspace/lib/c/include/fibril_synch.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/lib/c/include/fibril_synch.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -47,6 +47,6 @@
 } fibril_mutex_t;
 
-#define FIBRIL_MUTEX_INITIALIZE(name) \
-	fibril_mutex_t name = {	\
+#define FIBRIL_MUTEX_INITIALIZER(name) \
+	{ \
 		.counter = 1, \
 		.waiters = { \
@@ -55,4 +55,7 @@
 		} \
 	}
+	
+#define FIBRIL_MUTEX_INITIALIZE(name) \
+	fibril_mutex_t name = FIBRIL_MUTEX_INITIALIZER(name) 
 
 typedef struct {
@@ -62,6 +65,6 @@
 } fibril_rwlock_t;
 
-#define FIBRIL_RWLOCK_INITIALIZE(name) \
-	fibril_rwlock_t name = { \
+#define FIBRIL_RWLOCK_INITIALIZER(name) \
+	{ \
 		.readers = 0, \
 		.writers = 0, \
@@ -72,10 +75,13 @@
 	}
 
+#define FIBRIL_RWLOCK_INITIALIZE(name) \
+	fibril_rwlock_t name = FIBRIL_RWLOCK_INITIALIZER(name)
+
 typedef struct {
 	link_t waiters;
 } fibril_condvar_t;
 
-#define FIBRIL_CONDVAR_INITIALIZE(name) \
-	fibril_condvar_t name = { \
+#define FIBRIL_CONDVAR_INITIALIZER(name) \
+	{ \
 		.waiters = { \
 			.next = &name.waiters, \
@@ -83,4 +89,7 @@
 		} \
 	}
+
+#define FIBRIL_CONDVAR_INITIALIZE(name) \
+	fibril_condvar_t name = FIBRIL_CONDVAR_INITIALIZER(name)
 
 extern void fibril_mutex_initialize(fibril_mutex_t *);
Index: uspace/lib/c/include/ipc/arp.h
===================================================================
--- uspace/lib/c/include/ipc/arp.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
+++ uspace/lib/c/include/ipc/arp.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2009 Lukas Mejdrech
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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
+ * ARP module messages.
+ * @see arp_interface.h
+ */
+
+#ifndef LIBC_ARP_MESSAGES_
+#define LIBC_ARP_MESSAGES_
+
+#include <ipc/ipc.h>
+#include <ipc/net.h>
+
+/** ARP module messages. */
+typedef enum {
+	/** Clean cache message.
+	 * @see arp_clean_cache()
+	 */
+	NET_ARP_CLEAN_CACHE = NET_ARP_FIRST,
+	/** Clear address cache message.
+	 * @see arp_clear_address_msg()
+	 */
+	NET_ARP_CLEAR_ADDRESS,
+	/** Clear device cache message.
+	 * @see arp_clear_device_req()
+	 */
+	NET_ARP_CLEAR_DEVICE,
+	/** New device message.
+	 * @see arp_device_req()
+	 */
+	NET_ARP_DEVICE,
+	/** Address translation message.
+	 * @see arp_translate_req()
+	 */
+	NET_ARP_TRANSLATE
+} arp_messages;
+
+/** @name ARP specific message parameters definitions */
+/*@{*/
+
+/** Returns the protocol service message parameter.
+ * @param[in] call The message call structure.
+ */
+#define ARP_GET_NETIF(call) \
+	({ \
+		services_t service = (services_t) IPC_GET_ARG2(*call); \
+		service; \
+	})
+
+/*@}*/
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/include/ipc/icmp.h
===================================================================
--- uspace/lib/c/include/ipc/icmp.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
+++ uspace/lib/c/include/ipc/icmp.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -0,0 +1,169 @@
+/*
+ * Copyright (c) 2009 Lukas Mejdrech
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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
+ * ICMP module messages.
+ * @see icmp_interface.h
+ */
+
+#ifndef LIBC_ICMP_MESSAGES_
+#define LIBC_ICMP_MESSAGES_
+
+#include <ipc/ipc.h>
+#include <ipc/net.h>
+#include <sys/types.h>
+#include <sys/time.h>
+
+#include <net/icmp_codes.h>
+
+/** ICMP module messages. */
+typedef enum {
+	/** Sends echo request. @see icmp_echo() */
+	NET_ICMP_ECHO = NET_ICMP_FIRST,
+	
+	/**
+	 * Sends destination unreachable error message.
+	 * @see icmp_destination_unreachable_msg()
+	 */
+	NET_ICMP_DEST_UNREACH,
+	
+	/**
+	 * Sends source quench error message.
+	 * @see icmp_source_quench_msg()
+	 */
+	NET_ICMP_SOURCE_QUENCH,
+	
+	/**
+	 * Sends time exceeded error message.
+	 * @see icmp_time_exceeded_msg()
+	 */
+	NET_ICMP_TIME_EXCEEDED,
+	
+	/**
+	 * Sends parameter problem error message.
+	 * @see icmp_parameter_problem_msg()
+	 */
+	NET_ICMP_PARAMETERPROB,
+	
+	/** Initializes new connection. */
+	NET_ICMP_INIT
+} icmp_messages;
+
+/** @name ICMP specific message parameters definitions */
+/*@{*/
+
+/** Returns the ICMP code message parameter.
+ *
+ * @param[in] call	The message call structure.
+ */
+#define ICMP_GET_CODE(call) \
+	({ \
+		icmp_code_t code = (icmp_code_t) IPC_GET_ARG1(*call); \
+		code; \
+	})
+
+/** Returns the ICMP link MTU message parameter.
+ *
+ * @param[in] call	The message call structure.
+ */
+#define ICMP_GET_MTU(call) \
+	({ \
+		icmp_param_t mtu = (icmp_param_t) IPC_GET_ARG3(*call); \
+		mtu; \
+	})
+
+/** Returns the pointer message parameter.
+ *
+ * @param[in] call	The message call structure.
+ */
+#define ICMP_GET_POINTER(call) \
+	({ \
+		icmp_param_t pointer = (icmp_param_t) IPC_GET_ARG3(*call); \
+		pointer; \
+	})
+
+/** Returns the size message parameter.
+ *
+ * @param[in] call	The message call structure.
+ */
+#define ICMP_GET_SIZE(call) \
+	({ \
+		size_t size = (size_t) IPC_GET_ARG1(call); \
+		size; \
+	})
+
+/** Returns the timeout message parameter.
+ *
+ * @param[in] call	The message call structure.
+ */
+#define ICMP_GET_TIMEOUT(call) \
+	({ \
+		suseconds_t timeout = (suseconds_t) IPC_GET_ARG2(call); \
+		timeout; \
+	})
+
+/** Returns the time to live message parameter.
+ *
+ * @param[in] call	The message call structure.
+ */
+#define ICMP_GET_TTL(call) \
+	({ \
+		ip_ttl_t ttl = (ip_ttl_t) IPC_GET_ARG3(call); \
+		ttl; \
+	})
+
+/** Returns the type of service message parameter.
+ *
+ * @param[in] call	The message call structure.
+ */
+#define ICMP_GET_TOS(call) \
+	({ \
+		ip_tos_t tos = (ip_tos_t) IPC_GET_ARG4(call); \
+		tos; \
+	})
+
+/** Returns the dont fragment message parameter.
+ *
+ * @param[in] call	The message call structure.
+ */
+#define ICMP_GET_DONT_FRAGMENT(call) \
+	({ \
+		int dont_fragment = (int) IPC_GET_ARG5(call); \
+		dont_fragment; \
+	})
+
+/*@}*/
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/include/ipc/il.h
===================================================================
--- uspace/lib/c/include/ipc/il.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
+++ uspace/lib/c/include/ipc/il.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2009 Lukas Mejdrech
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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
+ * Internetwork layer modules messages.
+ * @see il_interface.h
+ * @see ip_interface.h
+ */
+
+#ifndef LIBC_IL_MESSAGES_H_
+#define LIBC_IL_MESSAGES_H_
+
+#include <ipc/ipc.h>
+#include <ipc/net.h>
+
+/** Internet layer modules messages. */
+typedef enum {
+	/** New device message.
+	 * @see ip_device_req()
+	 */
+	NET_IL_DEVICE = NET_IL_FIRST,
+	/** Device state changed message.
+	 * @see il_device_state_msg()
+	 */
+	NET_IL_DEVICE_STATE,
+	/** Device MTU changed message.
+	 * @see il_mtu_changed_msg()
+	 */
+	NET_IL_MTU_CHANGED,
+	/** Packet size message.
+	 * @see il_packet_size_req()
+	 */
+	NET_IL_PACKET_SPACE,
+	/** Packet received message.
+	 * @see il_received_msg()
+	 */
+	NET_IL_RECEIVED,
+	/** Packet send message.
+	 * @see il_send_msg()
+	 */
+	NET_IL_SEND
+} il_messages;
+
+/** @name Internetwork layer specific message parameters definitions */
+/*@{*/
+
+/** Return the protocol number message parameter.
+ * @param[in] call The message call structure.
+ */
+#define IL_GET_PROTO(call)	(int) IPC_GET_ARG1(*call)
+
+/** Return the registering service message parameter.
+ * @param[in] call The message call structure.
+ */
+#define IL_GET_SERVICE(call)	(services_t) IPC_GET_ARG2(*call)
+
+/*@}*/
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/include/ipc/ip.h
===================================================================
--- uspace/lib/c/include/ipc/ip.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
+++ uspace/lib/c/include/ipc/ip.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -0,0 +1,123 @@
+/*
+ * Copyright (c) 2009 Lukas Mejdrech
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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
+ * IP module messages.
+ * @see ip_interface.h
+ */
+
+#ifndef LIBC_IP_MESSAGES_H_
+#define LIBC_IP_MESSAGES_H_
+
+#include <ipc/ipc.h>
+#include <ipc/net.h>
+
+#include <net/in.h>
+#include <net/ip_codes.h>
+
+/** IP module messages. */
+typedef enum {
+	/** Adds the routing entry.
+	 * @see ip_add_route()
+	 */
+	NET_IP_ADD_ROUTE = NET_IP_FIRST,
+	/** Gets the actual route information.
+	 * @see ip_get_route()
+	 */
+	NET_IP_GET_ROUTE,
+	/** Processes the received error notification.
+	 * @see ip_received_error_msg()
+	 */
+	NET_IP_RECEIVED_ERROR,
+	/** Sets the default gateway.
+	 * @see ip_set_default_gateway()
+	 */
+	NET_IP_SET_GATEWAY
+} ip_messages;
+
+/** @name IP specific message parameters definitions */
+/*@{*/
+
+/** Returns the address message parameter.
+ * @param[in] call The message call structure.
+ */
+#define IP_GET_ADDRESS(call) \
+	({ \
+		in_addr_t addr; \
+		addr.s_addr = IPC_GET_ARG3(*call); \
+		addr; \
+	})
+
+/** Returns the gateway message parameter.
+ * @param[in] call The message call structure.
+ */
+#define IP_GET_GATEWAY(call) \
+	({ \
+		in_addr_t addr; \
+		addr.s_addr = IPC_GET_ARG2(*call); \
+		addr; \
+	})
+
+/** Sets the header length in the message answer.
+ * @param[out] answer The message answer structure.
+ */
+#define IP_SET_HEADERLEN(answer, value) \
+	do { \
+		ipcarg_t argument = (ipcarg_t) (value); \
+		IPC_SET_ARG2(*answer, argument); \
+	} while (0)
+
+/** Returns the network mask message parameter.
+ * @param[in] call The message call structure.
+ */
+#define IP_GET_NETMASK(call) \
+	({ \
+		in_addr_t addr; \
+		addr.s_addr = IPC_GET_ARG4(*call); \
+		addr; \
+	})
+
+/** Returns the protocol message parameter.
+ * @param[in] call The message call structure.
+ */
+#define IP_GET_PROTOCOL(call) \
+	({ \
+		ip_protocol_t protocol = (ip_protocol_t) IPC_GET_ARG1(*call); \
+		protocol; \
+	})
+
+/*@}*/
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/include/ipc/net.h
===================================================================
--- uspace/lib/c/include/ipc/net.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
+++ uspace/lib/c/include/ipc/net.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -0,0 +1,417 @@
+/*
+ * Copyright (c) 2009 Lukas Mejdrech
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup libcipc
+ *  @{
+ */
+
+/** @file
+ *  Networking common message definitions.
+ */
+
+#ifndef LIBC_NET_MESSAGES_H_
+#define LIBC_NET_MESSAGES_H_
+
+#include <ipc/ipc.h>
+#include <ipc/services.h>
+
+#include <net/device.h>
+#include <net/packet.h>
+
+/** Returns a value indicating whether the value is in the interval.
+ * @param[in] item	The value to be checked.
+ * @param[in] first_inclusive The first value in the interval inclusive.
+ * @param[in] last_exclusive The first value after the interval.
+ */
+#define IS_IN_INTERVAL(item, first_inclusive, last_exclusive) \
+	(((item) >= (first_inclusive)) && ((item) < (last_exclusive)))
+
+/** @name Networking message counts */
+/*@{*/
+
+/** The number of ARP messages. */
+#define NET_ARP_COUNT		5
+
+/** The number of Ethernet messages. */
+#define NET_ETH_COUNT		0
+
+/** The number of ICMP messages. */
+#define NET_ICMP_COUNT		6
+
+/** The number of inter-network messages. */
+#define NET_IL_COUNT		6
+
+/** The number of IP messages. */
+#define NET_IP_COUNT		4
+
+/** The number of general networking messages. */
+#define NET_NET_COUNT		3
+
+/** The number of network interface driver messages. */
+#define NET_NETIF_COUNT		6
+
+/** The number of network interface layer messages. */
+#define NET_NIL_COUNT		7
+
+/** The number of packet management system messages. */
+#define NET_PACKET_COUNT	5
+
+/** The number of socket messages. */
+#define NET_SOCKET_COUNT	14
+
+/** The number of TCP messages. */
+#define NET_TCP_COUNT		0
+
+/** The number of transport layer messages. */
+#define NET_TL_COUNT		1
+
+/** The number of UDP messages. */
+#define NET_UDP_COUNT		0
+
+/*@}*/
+
+/** @name Networking message intervals
+ */
+/*@{*/
+
+/** The first networking message. */
+#define NET_FIRST		2000
+
+/** The first network interface layer message. */
+#define NET_NETIF_FIRST		NET_FIRST
+
+/** The last network interface layer message. */
+#define NET_NETIF_LAST		(NET_NETIF_FIRST + NET_NETIF_COUNT)
+
+/** The first general networking message. */
+#define NET_NET_FIRST		(NET_NETIF_LAST + 0)
+
+/** The last general networking message. */
+#define NET_NET_LAST		(NET_NET_FIRST + NET_NET_COUNT)
+
+/** The first network interface layer message. */
+#define NET_NIL_FIRST		(NET_NET_LAST + 0)
+
+/** The last network interface layer message. */
+#define NET_NIL_LAST		(NET_NIL_FIRST + NET_NIL_COUNT)
+
+/** The first Ethernet message. */
+#define NET_ETH_FIRST		(NET_NIL_LAST + 0)
+
+/** The last Ethernet message. */
+#define NET_ETH_LAST		(NET_ETH_FIRST + NET_ETH_COUNT)
+
+/** The first inter-network message. */
+#define NET_IL_FIRST		(NET_ETH_LAST + 0)
+
+/** The last inter-network message. */
+#define NET_IL_LAST		(NET_IL_FIRST + NET_IL_COUNT)
+
+/** The first IP message. */
+#define NET_IP_FIRST		(NET_IL_LAST + 0)
+
+/** The last IP message. */
+#define NET_IP_LAST		(NET_IP_FIRST + NET_IP_COUNT)
+
+/** The first ARP message. */
+#define NET_ARP_FIRST		(NET_IP_LAST + 0)
+
+/** The last ARP message. */
+#define NET_ARP_LAST		(NET_ARP_FIRST + NET_ARP_COUNT)
+
+/** The first ICMP message. */
+#define NET_ICMP_FIRST		(NET_ARP_LAST + 0)
+
+/** The last ICMP message. */
+#define NET_ICMP_LAST		(NET_ICMP_FIRST + NET_ICMP_COUNT)
+
+/** The first ICMP message. */
+#define NET_TL_FIRST		(NET_ICMP_LAST + 0)
+
+/** The last ICMP message. */
+#define NET_TL_LAST		(NET_TL_FIRST + NET_TL_COUNT)
+
+/** The first UDP message. */
+#define NET_UDP_FIRST		(NET_TL_LAST + 0)
+
+/** The last UDP message. */
+#define NET_UDP_LAST		(NET_UDP_FIRST + NET_UDP_COUNT)
+
+/** The first TCP message. */
+#define NET_TCP_FIRST		(NET_UDP_LAST + 0)
+
+/** The last TCP message. */
+#define NET_TCP_LAST		(NET_TCP_FIRST + NET_TCP_COUNT)
+
+/** The first socket message. */
+#define NET_SOCKET_FIRST	(NET_TCP_LAST + 0)
+
+/** The last socket message. */
+#define NET_SOCKET_LAST		(NET_SOCKET_FIRST + NET_SOCKET_COUNT)
+
+/** The first packet management system message. */
+#define NET_PACKET_FIRST	(NET_SOCKET_LAST + 0)
+
+/** The last packet management system message. */
+#define NET_PACKET_LAST		(NET_PACKET_FIRST + NET_PACKET_COUNT)
+
+/** The last networking message. */
+#define NET_LAST		NET_PACKET_LAST
+
+/** The number of networking messages. */
+#define NET_COUNT		(NET_LAST - NET_FIRST)
+
+/** Returns a value indicating whether the IPC call is a generic networking
+ * message.
+ * @param[in] call The IPC call to be checked.
+ */
+#define IS_NET_MESSAGE(call) \
+	IS_IN_INTERVAL(IPC_GET_METHOD(*call), NET_FIRST, NET_LAST)
+
+/** Returns a value indicating whether the IPC call is an ARP message.
+ * @param[in] call The IPC call to be checked.
+ */
+#define IS_NET_ARP_MESSAGE(call) \
+	IS_IN_INTERVAL(IPC_GET_METHOD(*call), NET_ARP_FIRST, NET_ARP_LAST)
+
+/** Returns a value indicating whether the IPC call is an Ethernet message.
+ * @param[in] call The IPC call to be checked.
+ */
+#define IS_NET_ETH_MESSAGE(call) \
+	IS_IN_INTERVAL(IPC_GET_METHOD(*call), NET_ETH_FIRST, NET_ETH_LAST)
+
+/** Returns a value indicating whether the IPC call is an ICMP message.
+ * @param[in] call The IPC call to be checked.
+ */
+#define IS_NET_ICMP_MESSAGE(call) \
+	IS_IN_INTERVAL(IPC_GET_METHOD(*call), NET_ICMP_FIRST, NET_ICMP_LAST)
+
+/** Returns a value indicating whether the IPC call is an inter-network layer
+ * message.
+ * @param[in] call The IPC call to be checked.
+ */
+#define IS_NET_IL_MESSAGE(call) \
+	IS_IN_INTERVAL(IPC_GET_METHOD(*call), NET_IL_FIRST, NET_IL_LAST)
+
+/** Returns a value indicating whether the IPC call is an IP message.
+ * @param[in] call The IPC call to be checked.
+ */
+#define IS_NET_IP_MESSAGE(call) \
+	IS_IN_INTERVAL(IPC_GET_METHOD(*call), NET_IP_FIRST, NET_IP_LAST)
+
+/** Returns a value indicating whether the IPC call is a generic networking
+ * message.
+ * @param[in] call The IPC call to be checked.
+ */
+#define IS_NET_NET_MESSAGE(call) \
+	IS_IN_INTERVAL(IPC_GET_METHOD(*call), NET_NET_FIRST, NET_NET_LAST)
+
+/** Returns a value indicating whether the IPC call is a network interface layer
+ * message.
+ * @param[in] call The IPC call to be checked.
+ */
+#define IS_NET_NIL_MESSAGE(call) \
+	IS_IN_INTERVAL(IPC_GET_METHOD(*call), NET_NIL_FIRST, NET_NIL_LAST)
+
+/** Returns a value indicating whether the IPC call is a packet manaagement
+ * system message.
+ * @param[in] call The IPC call to be checked.
+ */
+#define IS_NET_PACKET_MESSAGE(call) \
+	IS_IN_INTERVAL(IPC_GET_METHOD(*call), NET_PACKET_FIRST, NET_PACKET_LAST)
+
+/** Returns a value indicating whether the IPC call is a socket message.
+ * @param[in] call The IPC call to be checked.
+ */
+#define IS_NET_SOCKET_MESSAGE(call) \
+	IS_IN_INTERVAL(IPC_GET_METHOD(*call), NET_SOCKET_FIRST, NET_SOCKET_LAST)
+
+/** Returns a value indicating whether the IPC call is a TCP message.
+ * @param[in] call The IPC call to be checked.
+ */
+#define IS_NET_TCP_MESSAGE(call) \
+	IS_IN_INTERVAL(IPC_GET_METHOD(*call), NET_TCP_FIRST, NET_TCP_LAST)
+
+/** Returns a value indicating whether the IPC call is a transport layer message.
+ * @param[in] call The IPC call to be checked.
+ */
+#define IS_NET_TL_MESSAGE(call) \
+	IS_IN_INTERVAL(IPC_GET_METHOD(*call), NET_TL_FIRST, NET_TL_LAST)
+
+/** Returns a value indicating whether the IPC call is a UDP message.
+ * @param[in] call The IPC call to be checked.
+ */
+#define IS_NET_UDP_MESSAGE(call) \
+	IS_IN_INTERVAL(IPC_GET_METHOD(*call), NET_UDP_FIRST, NET_UDP_LAST)
+
+/*@}*/
+
+/** @name Networking specific message arguments definitions */
+/*@{*/
+
+/** Returns the device identifier message argument.
+ * @param[in] call The message call structure.
+ */
+#define IPC_GET_DEVICE(call) \
+	({ \
+		device_id_t device_id = (device_id_t) IPC_GET_ARG1(*call); \
+		device_id; \
+	})
+
+/** Returns the packet identifier message argument.
+ * @param[in] call The message call structure.
+ */
+#define IPC_GET_PACKET(call) \
+	({ \
+		packet_id_t packet_id = (packet_id_t) IPC_GET_ARG2(*call); \
+		packet_id; \
+	})
+
+/** Returns the count message argument.
+ * @param[in] call The message call structure.
+ */
+#define IPC_GET_COUNT(call) \
+	({ \
+		size_t size = (size_t) IPC_GET_ARG2(*call); \
+		size; \
+	})
+
+/** Returns the device state message argument.
+ * @param[in] call The message call structure.
+ */
+#define IPC_GET_STATE(call) \
+	({ \
+		device_state_t state = (device_state_t) IPC_GET_ARG2(*call); \
+		state; \
+	})
+
+/** Returns the maximum transmission unit message argument.
+ * @param[in] call The message call structure.
+ */
+#define IPC_GET_MTU(call) \
+	({ \
+		size_t size = (size_t) IPC_GET_ARG2(*call); \
+		size; \
+	})
+
+/** Returns the device driver service message argument.
+ * @param[in] call The message call structure.
+ */
+#define IPC_GET_SERVICE(call) \
+	({ \
+		services_t service = (services_t) IPC_GET_ARG3(*call); \
+		service; \
+	})
+
+/** Returns the target service message argument.
+ * @param[in] call The message call structure.
+ */
+#define IPC_GET_TARGET(call) \
+	({ \
+		services_t service = (services_t) IPC_GET_ARG3(*call); \
+		service; \
+	})
+
+/** Returns the sender service message argument.
+ * @param[in] call The message call structure.
+ */
+#define IPC_GET_SENDER(call) \
+	({ \
+		services_t service = (services_t) IPC_GET_ARG3(*call); \
+		service; \
+	})
+
+/** Returns the error service message argument.
+ * @param[in] call The message call structure.
+ */
+#define IPC_GET_ERROR(call) \
+	({ \
+		services_t service = (services_t) IPC_GET_ARG4(*call); \
+		service; \
+	})
+
+/** Returns the phone message argument.
+ * @param[in] call The message call structure.
+ */
+#define IPC_GET_PHONE(call) \
+	({ \
+		int phone = (int) IPC_GET_ARG5(*call); \
+		phone; \
+	})
+
+/** Sets the device identifier in the message answer.
+ * @param[out] answer The message answer structure.
+ */
+#define IPC_SET_DEVICE(answer, value) \
+	do { \
+		ipcarg_t argument = (ipcarg_t) (value); \
+		IPC_SET_ARG1(*answer, argument); \
+	} while (0)
+
+/** Sets the minimum address length in the message answer.
+ * @param[out] answer The message answer structure.
+ */
+#define IPC_SET_ADDR(answer, value) \
+	do { \
+		ipcarg_t argument = (ipcarg_t) (value); \
+		IPC_SET_ARG1(*answer, argument); \
+	} while (0)
+
+/** Sets the minimum prefix size in the message answer.
+ * @param[out] answer The message answer structure.
+ */
+#define IPC_SET_PREFIX(answer, value) \
+	do { \
+		ipcarg_t argument = (ipcarg_t) (value); \
+		IPC_SET_ARG2(*answer, argument); \
+	} while (0)
+
+/** Sets the maximum content size in the message answer.
+ * @param[out] answer The message answer structure.
+ */
+#define IPC_SET_CONTENT(answer, value) \
+	do { \
+		ipcarg_t argument = (ipcarg_t) (value); \
+		IPC_SET_ARG3(*answer, argument); \
+	} while (0)
+
+/** Sets the minimum suffix size in the message answer.
+ * @param[out] answer The message answer structure.
+ */
+#define IPC_SET_SUFFIX(answer, value) \
+	do { \
+		ipcarg_t argument = (ipcarg_t) (value); \
+		IPC_SET_ARG4(*answer, argument); \
+	} while (0)
+
+/*@}*/
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/include/ipc/net_net.h
===================================================================
--- uspace/lib/c/include/ipc/net_net.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
+++ uspace/lib/c/include/ipc/net_net.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2009 Lukas Mejdrech
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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
+ * Networking subsystem central module messages.
+ * @see net_interface.h
+ */
+
+#ifndef LIBC_NET_NET_MESSAGES_H_
+#define LIBC_NET_NET_MESSAGES_H_
+
+#include <ipc/ipc.h>
+#include <ipc/net.h>
+
+/** Networking subsystem central module messages. */
+typedef enum {
+	/** Returns the general configuration
+	 * @see net_get_conf_req()
+	 */
+	NET_NET_GET_CONF = NET_FIRST,
+	/** Returns the device specific configuration
+	 * @see net_get_device_conf_req()
+	 */
+	NET_NET_GET_DEVICE_CONF,
+	/** Starts the networking stack. */
+	NET_NET_STARTUP,
+} net_messages;
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/include/ipc/netif.h
===================================================================
--- uspace/lib/c/include/ipc/netif.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
+++ uspace/lib/c/include/ipc/netif.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2009 Lukas Mejdrech
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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
+ * Network interface common module messages.
+ */
+
+#ifndef LIBC_NETIF_MESSAGES_H_
+#define LIBC_NETIF_MESSAGES_H_
+
+#include <ipc/ipc.h>
+#include <ipc/net.h>
+
+/** Network interface common module messages. */
+typedef enum {
+	/** Probe device message.
+	 * @see netif_probe_req()
+	 */
+	NET_NETIF_PROBE = NET_NETIF_FIRST,
+	/** Send packet message.
+	 * @see netif_send_msg()
+	 */
+	NET_NETIF_SEND,
+	/** Start device message.
+	 * @see netif_start_req()
+	 */
+	NET_NETIF_START,
+	/** Get device usage statistics message.
+	 * @see netif_stats_req()
+	 */
+	NET_NETIF_STATS,
+	/** Stop device message.
+	 * @see netif_stop_req()
+	 */
+	NET_NETIF_STOP,
+	/** Get device address message.
+	 * @see netif_get_addr_req()
+	 */
+	NET_NETIF_GET_ADDR,
+} netif_messages;
+
+/** @name Network interface specific message parameters definitions */
+/*@{*/
+
+/** Return the interrupt number message parameter.
+ * @param[in] call The message call structure.
+ */
+#define NETIF_GET_IRQ(call) \
+	({ \
+		int irq = (int) IPC_GET_ARG2(*call); \
+		irq; \
+	})
+
+/** Return the input/output address message parameter.
+ * @param[in] call The message call structure.
+ */
+#define NETIF_GET_IO(call) \
+	({ \
+		int io = (int) IPC_GET_ARG3(*call); \
+		io; \
+	})
+
+/*@}*/
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/include/ipc/nil.h
===================================================================
--- uspace/lib/c/include/ipc/nil.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
+++ uspace/lib/c/include/ipc/nil.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2009 Lukas Mejdrech
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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
+ * Network interface layer module messages.
+ */
+
+#ifndef LIBC_NIL_MESSAGES_H_
+#define LIBC_NIL_MESSAGES_H_
+
+#include <ipc/ipc.h>
+#include <ipc/net.h>
+
+/** Network interface layer module messages. */
+typedef enum {
+	/** New device or update MTU message.
+	 * @see nil_device_req()
+	 */
+	NET_NIL_DEVICE = NET_NIL_FIRST,
+	/** New device state message.
+	 * @see nil_device_state_msg()
+	 */
+	NET_NIL_DEVICE_STATE,
+	/** Received packet queue message.
+	 * @see nil_received_msg()
+	 */
+	NET_NIL_RECEIVED,
+	/** Send packet queue message.
+	 * @see nil_send_msg()
+	 */
+	NET_NIL_SEND,
+	/** Packet size message.
+	 * @see nil_packet_size_req()
+	 */
+	NET_NIL_PACKET_SPACE,
+	/** Device local hardware address message.
+	 * @see nil_get_addr()
+	 */
+	NET_NIL_ADDR,
+	/** Device broadcast hardware address message.
+	 * @see nil_get_broadcast_addr()
+	 */
+	NET_NIL_BROADCAST_ADDR,
+} nil_messages;
+
+/** @name Network interface layer specific message parameters definitions */
+/*@{*/
+
+/** Return the protocol service message parameter. */
+#define NIL_GET_PROTO(call) \
+	({ \
+		services_t service = (services_t) IPC_GET_ARG2(*call); \
+		service; \
+	})
+
+/*@}*/
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/include/ipc/packet.h
===================================================================
--- uspace/lib/c/include/ipc/packet.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
+++ uspace/lib/c/include/ipc/packet.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2009 Lukas Mejdrech
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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
+ *  Packet server module messages.
+ */
+
+#ifndef LIBC_PACKET_MESSAGES_
+#define LIBC_PACKET_MESSAGES_
+
+#include <ipc/ipc.h>
+#include <ipc/net.h>
+
+/** Packet server module messages. */
+typedef enum {
+	/** Create packet message with specified content length.
+	 * @see packet_get_1()
+	 */
+	NET_PACKET_CREATE_1 = NET_PACKET_FIRST,
+	
+	/**
+	 * Create packet message with specified address length, prefix, content
+	 * and suffix.
+	 * @see packet_get_4()
+	 */
+	NET_PACKET_CREATE_4,
+	
+	/** Get packet message.
+	 * @see packet_return() */
+	NET_PACKET_GET,
+	
+	/** Get packet size message.
+	 * @see packet_translate()
+	 */
+	NET_PACKET_GET_SIZE,
+	
+	/** Release packet message.
+	 * @see pq_release()
+	 */
+	NET_PACKET_RELEASE
+} packet_messages;
+
+/** Returns the protocol service message parameter. */
+#define ARP_GET_PROTO(call)	(services_t) IPC_GET_ARG2(*call)
+
+/** Returns the packet identifier message parameter. */
+#define IPC_GET_ID(call)	(packet_id_t) IPC_GET_ARG1(*call)
+
+/** Returns the maximal content length message parameter. */
+#define IPC_GET_CONTENT(call)	(size_t) IPC_GET_ARG1(*call)
+
+/** Returns the maximal address length message parameter. */
+#define IPC_GET_ADDR_LEN(call)	(size_t) IPC_GET_ARG2(*call)
+
+/** Returns the maximal prefix length message parameter. */
+#define IPC_GET_PREFIX(call)	(size_t) IPC_GET_ARG3(*call)
+
+/** Returns the maximal suffix length message parameter. */
+#define IPC_GET_SUFFIX(call)	(size_t) IPC_GET_ARG4(*call)
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/include/ipc/socket.h
===================================================================
--- uspace/lib/c/include/ipc/socket.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
+++ uspace/lib/c/include/ipc/socket.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -0,0 +1,230 @@
+/*
+ * Copyright (c) 2009 Lukas Mejdrech
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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
+ * Socket messages.
+ */
+
+#ifndef LIBC_SOCKET_MESSAGES_H_
+#define LIBC_SOCKET_MESSAGES_H_
+
+#include <ipc/ipc.h>
+#include <ipc/net.h>
+
+/** Socket client messages. */
+typedef enum {
+	/** Creates a new socket. @see socket() */
+	NET_SOCKET = NET_SOCKET_FIRST,
+	/** Binds the socket. @see bind() */
+	NET_SOCKET_BIND,
+	/** Creates a new socket. @see socket() */
+	NET_SOCKET_LISTEN,
+	/** Accepts an incomming connection. @see accept() */
+	NET_SOCKET_ACCEPT,
+	/** Connects the socket. @see connect() */
+	NET_SOCKET_CONNECT,
+	/** Closes the socket. @see closesocket() */
+	NET_SOCKET_CLOSE,
+	/** Sends data via the stream socket. @see send() */
+	NET_SOCKET_SEND,
+	/** Sends data via the datagram socket. @see sendto() */
+	NET_SOCKET_SENDTO,
+	/** Receives data from the stream socket. @see socket() */
+	NET_SOCKET_RECV,
+	/** Receives data from the datagram socket. @see socket() */
+	NET_SOCKET_RECVFROM,
+	/** Gets the socket option. @see getsockopt() */
+	NET_SOCKET_GETSOCKOPT,
+	/** Sets the socket option. @see setsockopt() */
+	NET_SOCKET_SETSOCKOPT,
+	/** New socket for acceptence notification message. */
+	NET_SOCKET_ACCEPTED,
+	/** New data received notification message. */
+	NET_SOCKET_RECEIVED,
+	/** New socket data fragment size notification message. */
+	NET_SOCKET_DATA_FRAGMENT_SIZE
+} socket_messages;
+
+/** @name Socket specific message parameters definitions
+ */
+/*@{*/
+
+/** Sets the socket identifier in the message answer.
+ * @param[out] answer	The message answer structure.
+ */
+#define SOCKET_SET_SOCKET_ID(answer, value) \
+	do { \
+		ipcarg_t argument = (ipcarg_t) (value); \
+		IPC_SET_ARG1(answer, argument); \
+	} while (0)
+
+/** Returns the socket identifier message parameter.
+ * @param[in] call	The message call structure.
+ */
+#define SOCKET_GET_SOCKET_ID(call) \
+	({ \
+		int socket_id = (int) IPC_GET_ARG1(call); \
+		socket_id; \
+	})
+
+/** Sets the read data length in the message answer.
+ * @param[out] answer	The message answer structure.
+ */
+#define SOCKET_SET_READ_DATA_LENGTH(answer, value) \
+	do { \
+		ipcarg_t argument = (ipcarg_t) (value); \
+		IPC_SET_ARG1(answer, argument); \
+	} while (0)
+
+/** Returns the read data length message parameter.
+ * @param[in] call	The message call structure.
+ */
+#define SOCKET_GET_READ_DATA_LENGTH(call) \
+	({ \
+		int data_length = (int) IPC_GET_ARG1(call); \
+		data_length; \
+	})
+
+/** Returns the backlog message parameter.
+ * @param[in] call	The message call structure.
+ */
+#define SOCKET_GET_BACKLOG(call) \
+	({ \
+		int backlog = (int) IPC_GET_ARG2(call); \
+		backlog; \
+	})
+
+/** Returns the option level message parameter.
+ * @param[in] call	The message call structure.
+ */
+#define SOCKET_GET_OPT_LEVEL(call) \
+	({ \
+		int opt_level = (int) IPC_GET_ARG2(call); \
+		opt_level; \
+	})
+
+/** Returns the data fragment size message parameter.
+ * @param[in] call	The message call structure.
+ */
+#define SOCKET_GET_DATA_FRAGMENT_SIZE(call) \
+	({ \
+		size_t size = (size_t) IPC_GET_ARG2(call); \
+		size; \
+	})
+
+/** Sets the data fragment size in the message answer.
+ * @param[out] answer	The message answer structure.
+ */
+#define SOCKET_SET_DATA_FRAGMENT_SIZE(answer, value) \
+	do { \
+		ipcarg_t argument = (ipcarg_t) (value); \
+		IPC_SET_ARG2(answer, argument); \
+	} while (0)
+
+/** Sets the address length in the message answer.
+ * @param[out] answer	The message answer structure.
+ */
+#define SOCKET_SET_ADDRESS_LENGTH(answer, value) \
+	do { \
+		ipcarg_t argument = (ipcarg_t) (value); \
+		IPC_SET_ARG3(answer, argument);\
+	} while (0)
+
+/** Returns the address length message parameter.
+ * @param[in] call	The message call structure.
+ */
+#define SOCKET_GET_ADDRESS_LENGTH(call) \
+	({ \
+		socklen_t address_length = (socklen_t) IPC_GET_ARG3(call); \
+		address_length; \
+	})
+
+/** Sets the header size in the message answer.
+ * @param[out] answer	The message answer structure.
+ */
+#define SOCKET_SET_HEADER_SIZE(answer, value) \
+	do { \
+		ipcarg_t argument = (ipcarg_t) (value); \
+		IPC_SET_ARG3(answer, argument); \
+	} while (0)
+
+/** Returns the header size message parameter.
+ *  @param[in] call	The message call structure.
+ */
+#define SOCKET_GET_HEADER_SIZE(call) \
+	({ \
+		size_t size = (size_t) IPC_GET_ARG3(call); \
+		size; \
+	})
+
+/** Returns the flags message parameter.
+ *  @param[in] call	The message call structure.
+ */
+#define SOCKET_GET_FLAGS(call) \
+	({ \
+		int flags = (int) IPC_GET_ARG4(call); \
+		flags; \
+	})
+
+/** Returns the option name message parameter.
+ *  @param[in] call	The message call structure.
+ */
+#define SOCKET_GET_OPT_NAME(call) \
+	({ \
+		int opt_name = (int) IPC_GET_ARG4(call); \
+		opt_name; \
+	})
+
+/** Returns the data fragments message parameter.
+ *  @param[in] call	The message call structure.
+ */
+#define SOCKET_GET_DATA_FRAGMENTS(call) \
+	({ \
+		int fragments = (int) IPC_GET_ARG5(call); \
+		fragments; \
+	})
+
+/** Returns the new socket identifier message parameter.
+ *  @param[in] call	The message call structure.
+ */
+#define SOCKET_GET_NEW_SOCKET_ID(call) \
+	({ \
+		int socket_id = (int) IPC_GET_ARG5(call); \
+		socket_id; \
+	})
+
+/*@}*/
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/include/ipc/tl.h
===================================================================
--- uspace/lib/c/include/ipc/tl.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
+++ uspace/lib/c/include/ipc/tl.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2009 Lukas Mejdrech
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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
+ * Transport layer modules messages.
+ * @see tl_interface.h
+ */
+
+#ifndef LIBC_TL_MESSAGES_H_
+#define LIBC_TL_MESSAGES_H_
+
+#include <ipc/ipc.h>
+#include <ipc/net.h>
+
+/** Transport layer modules messages. */
+typedef enum {
+	/** Packet received message.
+	 * @see tl_received_msg()
+	 */
+	NET_TL_RECEIVED = NET_TL_FIRST
+} tl_messages;
+
+#endif
+
+/** @}
+ */
Index: pace/lib/c/include/limits.h
===================================================================
--- uspace/lib/c/include/limits.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ 	(revision )
@@ -1,84 +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_LIMITS_H_
-#define LIBC_LIMITS_H_
-
-#include <stdint.h>
-#include <libarch/limits.h>
-
-/* char */
-#define SCHAR_MIN MIN_INT8
-#define SCHAR_MAX MAX_INT8
-#define UCHAR_MIN MIN_UINT8
-#define UCHAR_MAX MAX_UINT8
-
-#ifdef __CHAR_UNSIGNED__
-	#define CHAR_MIN UCHAR_MIN
-	#define CHAR_MAX UCHAR_MAX
-#else
-	#define CHAR_MIN SCHAR_MIN
-	#define CHAR_MAX SCHAR_MAX
-#endif
-
-/* short int */
-#define SHRT_MIN MIN_INT16
-#define SHRT_MAX MAX_INT16
-#define USHRT_MIN MIN_UINT16
-#define USHRT_MAX MAX_UINT16
-
-/* int */
-#define INT_MIN MIN_INT32
-#define INT_MAX MAX_INT32
-#define UINT_MIN MIN_UINT32
-#define UINT_MAX MAX_UINT32
-
-/* long long int */
-#define LLONG_MIN MIN_INT64
-#define LLONG_MAX MAX_INT64
-#define ULLONG_MIN MIN_UINT64
-#define ULLONG_MAX MAX_UINT64
-
-/* off64_t */
-#define OFF64_MIN MIN_INT64
-#define OFF64_MAX MAX_INT64
-
-/* aoff64_t */
-#define AOFF64_MIN MIN_UINT64
-#define AOFF64_MAX MAX_UINT64
-
-#endif
-
-/** @}
- */
Index: uspace/lib/c/include/net/device.h
===================================================================
--- uspace/lib/c/include/net/device.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
+++ uspace/lib/c/include/net/device.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -0,0 +1,141 @@
+/*
+ * Copyright (c) 2009 Lukas Mejdrech
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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
+ * Device identifier, state and usage statistics.
+ */
+
+#ifndef LIBC_DEVICE_ID_TYPE_H_
+#define LIBC_DEVICE_ID_TYPE_H_
+
+#include <adt/int_map.h>
+
+/** Device identifier to generic type map declaration. */
+#define DEVICE_MAP_DECLARE	INT_MAP_DECLARE
+
+/** Device identifier to generic type map implementation. */
+#define DEVICE_MAP_IMPLEMENT	INT_MAP_IMPLEMENT
+
+/** Invalid device identifier. */
+#define DEVICE_INVALID_ID	(-1)
+
+/** Device identifier type. */
+typedef int device_id_t;
+
+/** Device state type. */
+typedef enum device_state device_state_t;
+
+/** Type definition of the device usage statistics.
+ * @see device_stats
+ */
+typedef struct device_stats device_stats_t;
+
+/** Type definition of the device usage statistics pointer.
+ * @see device_stats
+ */
+typedef device_stats_t *device_stats_ref;
+
+/** Device state. */
+enum device_state {
+	/** Device not present or not initialized. */
+	NETIF_NULL = 0,
+	/** Device present and stopped. */
+	NETIF_STOPPED,
+	/** Device present and active. */
+	NETIF_ACTIVE,
+	/** Device present but unable to transmit. */
+	NETIF_CARRIER_LOST
+};
+
+/** Device usage statistics. */
+struct device_stats {
+	/** Total packets received. */
+	unsigned long receive_packets;
+	/** Total packets transmitted. */
+	unsigned long send_packets;
+	/** Total bytes received. */
+	unsigned long receive_bytes;
+	/** Total bytes transmitted. */
+	unsigned long send_bytes;
+	/** Bad packets received counter. */
+	unsigned long receive_errors;
+	/** Packet transmition problems counter. */
+	unsigned long send_errors;
+	/** No space in buffers counter. */
+	unsigned long receive_dropped;
+	/** No space available counter. */
+	unsigned long send_dropped;
+	/** Total multicast packets received. */
+	unsigned long multicast;
+	/** The number of collisions due to congestion on the medium. */
+	unsigned long collisions;
+
+	/* detailed receive_errors */
+
+	/** Received packet length error counter. */
+	unsigned long receive_length_errors;
+	/** Receiver buffer overflow counter. */
+	unsigned long receive_over_errors;
+	/** Received packet with crc error counter. */
+	unsigned long receive_crc_errors;
+	/** Received frame alignment error counter. */
+	unsigned long receive_frame_errors;
+	/** Receiver fifo overrun counter. */
+	unsigned long receive_fifo_errors;
+	/** Receiver missed packet counter. */
+	unsigned long receive_missed_errors;
+
+	/* detailed send_errors */
+
+	/** Transmitter aborted counter. */
+	unsigned long send_aborted_errors;
+	/** Transmitter carrier errors counter. */
+	unsigned long send_carrier_errors;
+	/** Transmitter fifo overrun counter. */
+	unsigned long send_fifo_errors;
+	/** Transmitter carrier errors counter. */
+	unsigned long send_heartbeat_errors;
+	/** Transmitter window errors counter. */
+	unsigned long send_window_errors;
+
+	/* for cslip etc */
+	
+	/** Total compressed packets received. */
+	unsigned long receive_compressed;
+	/** Total compressed packet transmitted. */
+	unsigned long send_compressed;
+};
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/include/net/icmp_api.h
===================================================================
--- uspace/lib/c/include/net/icmp_api.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
+++ uspace/lib/c/include/net/icmp_api.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2009 Lukas Mejdrech
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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
+ * ICMP module application interface.
+ */
+
+#ifndef LIBC_ICMP_API_H_
+#define LIBC_ICMP_API_H_
+
+#include <net/socket_codes.h>
+#include <net/inet.h>
+#include <sys/types.h>
+#include <sys/time.h>
+
+#include <adt/measured_strings.h>
+#include <net/ip_codes.h>
+#include <net/icmp_codes.h>
+#include <net/icmp_common.h>
+
+/** @name ICMP module application interface
+ * This interface is used by other application modules.
+ */
+/*@{*/
+
+extern int icmp_echo_msg(int, size_t, mseconds_t, ip_ttl_t, ip_tos_t, int,
+    const struct sockaddr *, socklen_t);
+
+/*@}*/
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/include/net/icmp_codes.h
===================================================================
--- uspace/lib/c/include/net/icmp_codes.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
+++ uspace/lib/c/include/net/icmp_codes.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -0,0 +1,280 @@
+/*
+ * Copyright (c) 2009 Lukas Mejdrech
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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
+ * ICMP types and codes according to the on-line IANA - ICMP Type Numbers
+ *
+ * http://www.iana.org/assignments/icmp-parameters>
+ *
+ * cited September 14 2009.
+ */
+
+#ifndef LIBC_ICMP_CODES_H_
+#define LIBC_ICMP_CODES_H_
+
+/** ICMP type type definition. */
+typedef uint8_t icmp_type_t;
+
+/** ICMP code type definition. */
+typedef uint8_t icmp_code_t;
+
+/** ICMP parameter type definition. */
+typedef uint16_t icmp_param_t;
+
+/** @name ICMP types definitions */
+/*@{*/
+
+/** Echo Reply. */
+#define ICMP_ECHOREPLY		0
+
+/** Destination Unreachable. */
+#define ICMP_DEST_UNREACH	3
+
+/** Source Quench. */
+#define ICMP_SOURCE_QUENCH	4
+
+/** Redirect. */
+#define ICMP_REDIRECT		5
+
+/** Alternate Host Address. */
+#define ICMP_ALTERNATE_ADDR	6
+
+/** Echo Request. */
+#define ICMP_ECHO		8
+
+/** Router Advertisement. */
+#define ICMP_ROUTER_ADV		9
+
+/** Router solicitation. */
+#define ICMP_ROUTER_SOL		10
+
+/** Time Exceeded. */
+#define ICMP_TIME_EXCEEDED	11
+
+/** Parameter Problem. */
+#define ICMP_PARAMETERPROB	12
+
+/** Timestamp Request. */
+#define ICMP_TIMESTAMP		13
+
+/** Timestamp Reply. */
+#define ICMP_TIMESTAMPREPLY	14
+
+/** Information Request. */
+#define ICMP_INFO_REQUEST	15
+
+/** Information Reply. */
+#define ICMP_INFO_REPLY		16
+
+/** Address Mask Request. */
+#define ICMP_ADDRESS		17
+
+/** Address Mask Reply. */
+#define ICMP_ADDRESSREPLY	18
+
+/** Traceroute. */
+#define ICMP_TRACEROUTE		30
+
+/** Datagram Conversion Error. */
+#define ICMP_CONVERSION_ERROR	31
+
+/** Mobile Host Redirect. */
+#define ICMP_REDIRECT_MOBILE	32
+
+/** IPv6 Where-Are-You. */
+#define ICMP_IPV6_WHERE_ARE_YOU	33
+
+/** IPv6 I-Am-Here. */
+#define ICMP_IPV6_I_AM_HERE	34
+
+/** Mobile Registration Request. */
+#define ICMP_MOBILE_REQUEST	35
+
+/** Mobile Registration Reply. */
+#define ICMP_MOBILE_REPLY	36
+
+/** Domain name request. */
+#define ICMP_DN_REQUEST		37
+
+/** Domain name reply. */
+#define ICMP_DN_REPLY		38
+
+/** SKIP. */
+#define ICMP_SKIP		39
+
+/** Photuris. */
+#define ICMP_PHOTURIS		40
+
+/*@}*/
+
+/** @name ICMP_DEST_UNREACH codes definitions
+ */
+/*@{*/
+
+/** Network Unreachable. */
+#define ICMP_NET_UNREACH	0
+
+/** Host Unreachable. */
+#define ICMP_HOST_UNREACH	1
+
+/** Protocol Unreachable. */
+#define ICMP_PROT_UNREACH	2
+
+/** Port Unreachable. */
+#define ICMP_PORT_UNREACH	3
+
+/** Fragmentation needed but the Do Not Fragment bit was set. */
+#define ICMP_FRAG_NEEDED	4
+
+/** Source Route failed. */
+#define ICMP_SR_FAILED		5
+
+/** Destination network unknown. */
+#define ICMP_NET_UNKNOWN	6
+
+/** Destination host unknown. */
+#define ICMP_HOST_UNKNOWN	7
+
+/** Source host isolated (obsolete). */
+#define ICMP_HOST_ISOLATED	8
+
+/** Destination network administratively prohibited. */
+#define ICMP_NET_ANO		9
+
+/** Destination host administratively prohibited. */
+#define ICMP_HOST_ANO		10
+
+/** Network unreachable for this type of service. */
+#define ICMP_NET_UNR_TOS	11
+
+/** Host unreachable for this type of service. */
+#define ICMP_HOST_UNR_TOS	12
+
+/** Communication administratively prohibited by filtering. */
+#define ICMP_PKT_FILTERED	13
+
+/** Host precedence violation. */
+#define ICMP_PREC_VIOLATION	14
+
+/** Precedence cutoff in effect. */
+#define ICMP_PREC_CUTOFF	15
+
+/*@}*/
+
+/** @name ICMP_REDIRECT codes definitions */
+/*@{*/
+
+/** Network redirect (or subnet). */
+#define ICMP_REDIR_NET		0
+
+/** Host redirect. */
+#define ICMP_REDIR_HOST		1
+
+/** Network redirect for this type of service. */
+#define ICMP_REDIR_NETTOS	2
+
+/** Host redirect for this type of service. */
+#define ICMP_REDIR_HOSTTOS	3
+
+/*@}*/
+
+/** @name ICMP_ALTERNATE_ADDRESS codes definitions */
+/*@{*/
+
+/** Alternate address for host. */
+#define ICMP_ALTERNATE_HOST	0
+
+/*@}*/
+
+/** @name ICMP_ROUTER_ADV codes definitions */
+/*@{*/
+
+/** Normal router advertisement. */
+#define ICMP_ROUTER_NORMAL	0
+
+/** Does not route common traffic. */
+#define ICMP_ROUTER_NO_NORMAL_TRAFFIC	16
+
+/*@}*/
+
+/** @name ICMP_TIME_EXCEEDED codes definitions */
+/*@{*/
+
+/** Transit TTL exceeded. */
+#define ICMP_EXC_TTL		0
+
+/** Reassembly TTL exceeded. */
+#define ICMP_EXC_FRAGTIME	1
+
+/*@}*/
+
+/** @name ICMP_PARAMETERPROB codes definitions */
+/*@{*/
+
+/** Pointer indicates the error. */
+#define ICMP_PARAM_POINTER	0
+
+/** Missing required option. */
+#define ICMP_PARAM_MISSING	1
+
+/** Bad length. */
+#define ICMP_PARAM_LENGTH	2
+
+/*@}*/
+
+/** @name ICMP_PHOTURIS codes definitions */
+/*@{*/
+
+/** Bad SPI. */
+#define ICMP_PHOTURIS_BAD_SPI			0
+
+/** Authentication failed. */
+#define ICMP_PHOTURIS_AUTHENTICATION		1
+
+/** Decompression failed. */
+#define ICMP_PHOTURIS_DECOMPRESSION		2
+
+/** Decryption failed. */
+#define ICMP_PHOTURIS_DECRYPTION		3
+
+/** Need authentication. */
+#define ICMP_PHOTURIS_NEED_AUTHENTICATION	4
+
+/** Need authorization. */
+#define ICMP_PHOTURIS_NEED_AUTHORIZATION	5
+
+/*@}*/
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/include/net/icmp_common.h
===================================================================
--- uspace/lib/c/include/net/icmp_common.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
+++ uspace/lib/c/include/net/icmp_common.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2009 Lukas Mejdrech
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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
+ * ICMP module common interface.
+ */
+
+#ifndef LIBC_ICMP_COMMON_H_
+#define LIBC_ICMP_COMMON_H_
+
+#include <ipc/services.h>
+#include <sys/time.h>
+
+/** Default timeout for incoming connections in microseconds. */
+#define ICMP_CONNECT_TIMEOUT	(1 * 1000 * 1000)
+
+extern int icmp_connect_module(services_t, suseconds_t);
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/include/net/in.h
===================================================================
--- uspace/lib/c/include/net/in.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
+++ uspace/lib/c/include/net/in.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2009 Lukas Mejdrech
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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
+ *  INET family common definitions.
+ */
+
+#ifndef LIBC_IN_H_
+#define LIBC_IN_H_
+
+#include <net/inet.h>
+#include <net/ip_protocols.h>
+#include <sys/types.h>
+
+/** INET string address maximum length. */
+#define INET_ADDRSTRLEN		(4 * 3 + 3 + 1)
+
+/** Type definition of the INET address.
+ * @see in_addr
+ */
+typedef struct in_addr		in_addr_t;
+
+/** Type definition of the INET socket address.
+ * @see sockaddr_in
+ */
+typedef struct sockaddr_in	sockaddr_in_t;
+
+/** INET address. */
+struct in_addr {
+	/** 4 byte IP address. */
+	uint32_t s_addr;
+};
+
+/** INET socket address.
+ * @see sockaddr
+ */
+struct sockaddr_in {
+	/** Address family. Should be AF_INET. */
+	uint16_t sin_family;
+	/** Port number. */
+	uint16_t sin_port;
+	/** Internet address. */
+	struct in_addr sin_addr;
+	/** Padding to meet the sockaddr size. */
+	uint8_t sin_zero[8];
+};
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/include/net/in6.h
===================================================================
--- uspace/lib/c/include/net/in6.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
+++ uspace/lib/c/include/net/in6.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2009 Lukas Mejdrech
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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
+ *  INET6 family common definitions.
+ */
+
+#ifndef LIBC_IN6_H_
+#define LIBC_IN6_H_
+
+#include <net/inet.h>
+#include <net/ip_protocols.h>
+#include <sys/types.h>
+
+/** INET6 string address maximum length. */
+#define INET6_ADDRSTRLEN	(8 * 4 + 7 + 1)
+
+/** Type definition of the INET6 address.
+ * @see in6_addr
+ */
+typedef struct in6_addr	in6_addr_t;
+
+/** Type definition of the INET6 socket address.
+ * @see sockaddr_in6
+ */
+typedef struct sockaddr_in6	sockaddr_in6_t;
+
+/** INET6 address. */
+struct in6_addr {
+	/** 16 byte IPv6 address. */
+	unsigned char s6_addr[16];
+};
+
+/** INET6 socket address.
+ * @see sockaddr
+ */
+struct sockaddr_in6 {
+	/** Address family. Should be AF_INET6. */
+	uint16_t sin6_family;
+	/** Port number. */
+	uint16_t sin6_port;
+	/** IPv6 flow information. */
+	uint32_t sin6_flowinfo;
+	/** IPv6 address. */
+	struct in6_addr sin6_addr;
+	/** Scope identifier. */
+	uint32_t sin6_scope_id;
+};
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/include/net/inet.h
===================================================================
--- uspace/lib/c/include/net/inet.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
+++ uspace/lib/c/include/net/inet.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2009 Lukas Mejdrech
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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
+ *  Internet common definitions.
+ */
+
+#ifndef LIBC_INET_H_
+#define LIBC_INET_H_
+
+#include <sys/types.h>
+#include <byteorder.h>
+
+/** Type definition of the socket address.
+ * @see sockaddr
+ */
+typedef struct sockaddr		sockaddr_t;
+
+/** Type definition of the address information.
+ * @see addrinfo
+ */
+typedef struct addrinfo		addrinfo_t;
+
+/** Socket address. */
+struct sockaddr {
+	/** Address family. @see socket.h */
+	uint16_t sa_family;
+	/** 14 byte protocol address. */
+	uint8_t sa_data[14];
+};
+
+extern int inet_ntop(uint16_t, const uint8_t *, char *, size_t);
+extern int inet_pton(uint16_t, const char *, uint8_t *);
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/include/net/ip_codes.h
===================================================================
--- uspace/lib/c/include/net/ip_codes.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
+++ uspace/lib/c/include/net/ip_codes.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2009 Lukas Mejdrech
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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
+ * IP codes and definitions.
+ */
+
+#ifndef LIBC_IP_CODES_H_
+#define LIBC_IP_CODES_H_
+
+#include <sys/types.h>
+
+/** IP time to live counter type definition. */
+typedef uint8_t ip_ttl_t;
+
+/** IP type of service type definition. */
+typedef uint8_t ip_tos_t;
+
+/** IP transport protocol type definition. */
+typedef uint8_t ip_protocol_t;
+
+/** Default IPVERSION. */
+#define IPVERSION	4
+
+/** Default time to live counter. */
+#define IPDEFTTL	64
+
+/** @name IP options definitions */
+/*@{*/
+
+/** Copy shift. */
+#define IPOPT_COPY_SHIFT	7
+
+/** Class shift. */
+#define IPOPT_CLASS_SHIFT	5
+
+/** Number shift. */
+#define IPOPT_NUMBER_SHIFT	0
+
+/** Class mask. */
+#define IPOPT_CLASS_MASK	0x60
+
+/** Number mask. */
+#define IPOPT_NUMBER_MASK	0x1f
+
+/** Copy flag. */
+#define IPOPT_COPY		(1 << IPOPT_COPY_SHIFT)
+
+/** Returns IP option type.
+ *
+ * @param[in] copy	The value indication whether the IP option should be
+ *			copied.
+ * @param[in] class	The IP option class.
+ * @param[in] number	The IP option number.
+ */
+#define IPOPT_TYPE(copy, class, number) \
+	(((copy) & IPOPT_COPY) | ((class) & IPOPT_CLASS_MASK) | \
+	(((number) << IPOPT_NUMBER_SHIFT) & IPOPT_NUMBER_MASK))
+
+/** Returns a value indicating whether the IP option should be copied.
+ * @param[in] o The IP option.
+ */
+#define IPOPT_COPIED(o)		((o) & IPOPT_COPY)
+
+/*@}*/
+
+/** @name IP option class definitions */
+/*@{*/
+
+/** Control class. */
+#define IPOPT_CONTROL		(0 << IPOPT_CLASS_SHIFT)
+
+/*@}*/
+
+/** @name IP option type definitions */
+/*@{*/
+
+/** End of list. */
+#define IPOPT_END		IPOPT_TYPE(0, IPOPT_CONTROL, 0)
+
+/** No operation. */
+#define IPOPT_NOOP		IPOPT_TYPE(0, IPOPT_CONTROL, 1)
+
+/*@}*/
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/include/net/ip_protocols.h
===================================================================
--- uspace/lib/c/include/net/ip_protocols.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
+++ uspace/lib/c/include/net/ip_protocols.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2009 Lukas Mejdrech
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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
+ * Internet protocol numbers according to the on-line IANA - Assigned Protocol
+ * numbers:
+ *
+ * http://www.iana.org/assignments/protocol-numbers/protocol-numbers.xml
+ */
+
+#ifndef LIBC_IP_PROTOCOLS_H_
+#define LIBC_IP_PROTOCOLS_H_
+
+/** @name IP protocols definitions */
+/*@{*/
+
+#define IPPROTO_ICMP	1
+#define IPPROTO_TCP	6
+#define IPPROTO_UDP	17
+
+/*@}*/
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/include/net/modules.h
===================================================================
--- uspace/lib/c/include/net/modules.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
+++ uspace/lib/c/include/net/modules.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2009 Lukas Mejdrech
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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
+ * Generic module functions.
+ *
+ * @todo MAKE IT POSSIBLE TO REMOVE THIS FILE VIA EITHER REPLACING PART OF ITS
+ * FUNCTIONALITY OR VIA INTEGRATING ITS FUNCTIONALITY MORE TIGHTLY WITH THE REST
+ * OF THE SYSTEM.
+ */
+
+#ifndef LIBC_MODULES_H_
+#define LIBC_MODULES_H_
+
+#include <async.h>
+
+#include <ipc/ipc.h>
+#include <ipc/services.h>
+
+#include <sys/time.h>
+
+/** Converts the data length between different types.
+ *
+ * @param[in] type_from	The source type.
+ * @param[in] type_to	The destination type.
+ * @param[in] count	The number units of the source type size.
+ */
+#define CONVERT_SIZE(type_from, type_to, count) \
+	((sizeof(type_from) / sizeof(type_to)) * (count))
+
+/** Registers the module service at the name server.
+ *
+ * @param[in] me	The module service.
+ * @param[out] phonehash The created phone hash.
+ */
+#define REGISTER_ME(me, phonehash) \
+	ipc_connect_to_me(PHONE_NS, (me), 0, 0, (phonehash))
+
+/** Connect to the needed module function type definition.
+ *
+ * @param[in] need	The needed module service.
+ * @returns		The phone of the needed service.
+ */
+typedef int connect_module_t(services_t need);
+
+extern void answer_call(ipc_callid_t, int, ipc_call_t *, int);
+extern int bind_service(services_t, ipcarg_t, ipcarg_t, ipcarg_t,
+    async_client_conn_t);
+extern int bind_service_timeout(services_t, ipcarg_t, ipcarg_t, ipcarg_t,
+    async_client_conn_t, suseconds_t);
+extern int connect_to_service(services_t);
+extern int connect_to_service_timeout(services_t, suseconds_t);
+extern int data_receive(void **, size_t *);
+extern int data_reply(void *, size_t);
+extern void refresh_answer(ipc_call_t *, int *);
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/include/net/packet.h
===================================================================
--- uspace/lib/c/include/net/packet.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
+++ uspace/lib/c/include/net/packet.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2009 Lukas Mejdrech
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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
+ *  Packet map and queue.
+ */
+
+#ifndef LIBC_PACKET_H_
+#define LIBC_PACKET_H_
+
+/** Packet identifier type.
+ * Value zero is used as an invalid identifier.
+ */
+typedef int packet_id_t;
+
+/** Type definition of the packet.
+ * @see packet
+ */
+typedef struct packet * packet_t;
+
+/** Type definition of the packet pointer.
+ * @see packet
+ */
+typedef packet_t * packet_ref;
+
+/** Type definition of the packet dimension.
+ * @see packet_dimension
+ */
+typedef struct packet_dimension	packet_dimension_t;
+
+/** Type definition of the packet dimension pointer.
+ * @see packet_dimension
+ */
+typedef packet_dimension_t * packet_dimension_ref;
+
+/** Packet dimension. */
+struct packet_dimension {
+	/** Reserved packet prefix length. */
+	size_t prefix;
+	/** Maximal packet content length. */
+	size_t content;
+	/** Reserved packet suffix length. */
+	size_t suffix;
+	/** Maximal packet address length. */
+	size_t addr_len;
+};
+
+/** @name Packet management system interface
+ */
+/*@{*/
+
+extern packet_t pm_find(packet_id_t);
+extern int pm_add(packet_t);
+extern int pm_init(void);
+extern void pm_destroy(void);
+
+extern int pq_add(packet_t *, packet_t, size_t, size_t);
+extern packet_t pq_find(packet_t, size_t);
+extern int pq_insert_after(packet_t, packet_t);
+extern packet_t pq_detach(packet_t);
+extern int pq_set_order(packet_t, size_t, size_t);
+extern int pq_get_order(packet_t, size_t *, size_t *);
+extern void pq_destroy(packet_t, void (*)(packet_t));
+extern packet_t pq_next(packet_t);
+extern packet_t pq_previous(packet_t);
+
+/*@}*/
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/include/net/packet_header.h
===================================================================
--- uspace/lib/c/include/net/packet_header.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
+++ uspace/lib/c/include/net/packet_header.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -0,0 +1,138 @@
+/*
+ * Copyright (c) 2009 Lukas Mejdrech
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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
+ * Packet header.
+ */
+
+#ifndef LIBC_PACKET_HEADER_H_
+#define LIBC_PACKET_HEADER_H_
+
+#include <net/packet.h>
+
+/** Returns the actual packet data length.
+ * @param[in] header	The packet header.
+ */
+#define PACKET_DATA_LENGTH(header) \
+	((header)->data_end - (header)->data_start)
+
+/** Returns the maximum packet address length.
+ * @param[in] header	The packet header.
+ */
+#define PACKET_MAX_ADDRESS_LENGTH(header) \
+	((header)->dest_addr - (header)->src_addr)
+
+/** Returns the minimum packet suffix.
+ *  @param[in] header	The packet header.
+ */
+#define PACKET_MIN_SUFFIX(header) \
+	((header)->length - (header)->data_start - (header)->max_content)
+
+/** Packet integrity check magic value. */
+#define PACKET_MAGIC_VALUE	0x11227788
+
+/** Packet header. */
+struct packet {
+	/** Packet identifier. */
+	packet_id_t packet_id;
+
+	/**
+	 * Packet queue sorting value.
+	 * The packet queue is sorted the ascending order.
+	 */
+	size_t order;
+
+	/** Packet metric. */
+	size_t metric;
+	/** Previous packet in the queue. */
+	packet_id_t previous;
+	/** Next packet in the queue. */
+	packet_id_t next;
+
+	/**
+	 * Total length of the packet.
+	 * Contains the header, the addresses and the data of the packet.
+	 * Corresponds to the mapped sharable memory block.
+	 */
+	size_t length;
+
+	/** Stored source and destination addresses length. */
+	size_t addr_len;
+
+	/**
+	 * Souce address offset in bytes from the beginning of the packet
+	 * header.
+	 */
+	size_t src_addr;
+
+	/**
+	 * Destination address offset in bytes from the beginning of the packet
+	 * header.
+	 */
+	size_t dest_addr;
+
+	/** Reserved data prefix length in bytes. */
+	size_t max_prefix;
+	/** Reserved content length in bytes. */
+	size_t max_content;
+
+	/**
+	 * Actual data start offset in bytes from the beginning of the packet
+	 * header.
+	 */
+	size_t data_start;
+
+	/**
+	 * Actual data end offset in bytes from the beginning of the packet
+	 * header.
+	 */
+	size_t data_end;
+
+	/** Integrity check magic value. */
+	int magic_value;
+};
+
+/** Returns whether the packet is valid.
+ * @param[in] packet	The packet to be checked.
+ * @returns		True if the packet is not NULL and the magic value is
+ *			correct.
+ * @returns		False otherwise.
+ */
+static inline int packet_is_valid(const packet_t packet)
+{
+	return packet && (packet->magic_value == PACKET_MAGIC_VALUE);
+}
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/include/net/socket.h
===================================================================
--- uspace/lib/c/include/net/socket.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
+++ uspace/lib/c/include/net/socket.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2009 Lukas Mejdrech
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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
+ *  Socket application program interface (API).
+ *  This is a part of the network application library.
+ *  Based on the BSD socket interface.
+ */
+
+#ifndef LIBC_SOCKET_H_
+#define LIBC_SOCKET_H_
+
+#include <net/socket_codes.h>
+#include <net/in.h>
+#include <net/in6.h>
+#include <net/inet.h>
+#include <errno.h>
+#include <byteorder.h>
+
+/** @name Socket application programming interface
+ */
+/*@{*/
+
+extern int socket(int, int, int);
+extern int bind(int, const struct sockaddr *, socklen_t);
+extern int listen(int, int);
+extern int accept(int, struct sockaddr *, socklen_t *);
+extern int connect(int, const struct sockaddr *, socklen_t);
+extern int closesocket(int);
+extern int send(int, void *, size_t, int);
+extern int sendto(int, const void *, size_t, int, const struct sockaddr *,
+    socklen_t);
+extern int recv(int, void *, size_t, int);
+extern int recvfrom(int, void *, size_t, int, struct sockaddr *, socklen_t *);
+extern int getsockopt(int, int, int, void *, size_t *);
+extern int setsockopt(int, int, int, const void *, size_t);
+
+/*@}*/
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/include/net/socket_codes.h
===================================================================
--- uspace/lib/c/include/net/socket_codes.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
+++ uspace/lib/c/include/net/socket_codes.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2009 Lukas Mejdrech
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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
+ *  Socket codes and definitions.
+ *  This is a part of the network application library.
+ */
+
+#ifndef LIBC_SOCKET_CODES_H_
+#define LIBC_SOCKET_CODES_H_
+
+#include <sys/types.h>
+
+/** @name Address families definitions */
+/*@{*/
+
+enum {
+	AF_UNKNOWN = 0,
+	AF_INET,	/* IPv4 address */
+	AF_INET6	/* IPv6 address */
+};
+
+/*@}*/
+
+/** @name Protocol families definitions
+ *  Same as address families.
+ */
+/*@{*/
+
+#define PF_INET		AF_INET
+#define PF_INET6	AF_INET6
+
+/*@}*/
+
+/** Socket types. */
+typedef enum sock_type {
+	/** Stream (connection oriented) socket. */
+	SOCK_STREAM = 1,
+	/** Datagram (connectionless oriented) socket. */
+	SOCK_DGRAM = 2,
+	/** Raw socket. */
+	SOCK_RAW = 3
+} sock_type_t;
+
+/** Type definition of the socket length. */
+typedef int32_t socklen_t;
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/include/net/socket_parse.h
===================================================================
--- uspace/lib/c/include/net/socket_parse.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
+++ uspace/lib/c/include/net/socket_parse.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2009 Lukas Mejdrech
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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 socket
+ * @{
+ */
+
+/** @file
+ * Command-line argument parsing functions related to networking.
+ */
+
+extern int socket_parse_address_family(const char *, int *);
+extern int socket_parse_protocol_family(const char *, int *);
+extern int socket_parse_socket_type(const char *, int *);
+
+/** @}
+ */
Index: uspace/lib/c/include/sort.h
===================================================================
--- uspace/lib/c/include/sort.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
+++ uspace/lib/c/include/sort.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -0,0 +1,49 @@
+/*
+ * 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 <sys/types.h>
+#include <bool.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/stats.h
===================================================================
--- uspace/lib/c/include/stats.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/lib/c/include/stats.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -53,4 +53,7 @@
 extern stats_thread_t *stats_get_thread(thread_id_t);
 
+extern stats_exc_t *stats_get_exceptions(size_t *);
+extern stats_exc_t *stats_get_exception(unsigned int);
+
 extern void stats_print_load_fragment(load_t, unsigned int);
 extern const char *thread_get_state(state_t);
Index: uspace/lib/c/include/stdint.h
===================================================================
--- uspace/lib/c/include/stdint.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/lib/c/include/stdint.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -36,26 +36,37 @@
 #define LIBC_STDINT_H_
 
-/* Definitions of types with fixed size */
+#define INT8_MIN  (0x80)
+#define INT8_MAX  (0x7F)
+
+#define UINT8_MIN  (0u)
+#define UINT8_MAX  (0xFFu)
+
+#define INT16_MIN  (0x8000)
+#define INT16_MAX  (0x7FFF)
+
+#define UINT16_MIN  (0u)
+#define UINT16_MAX  (0xFFFFu)
+
+#define INT32_MIN  (0x80000000l)
+#define INT32_MAX  (0x7FFFFFFFl)
+
+#define UINT32_MIN  (0ul)
+#define UINT32_MAX  (0xFFFFFFFFul)
+
+#define INT64_MIN  (0x8000000000000000ll)
+#define INT64_MAX  (0x7FFFFFFFFFFFFFFFll)
+
+#define UINT64_MIN  (0ull)
+#define UINT64_MAX  (0xFFFFFFFFFFFFFFFFull)
+
 #include <libarch/types.h>
 
-#define MAX_INT8 (0x7F)
-#define MIN_INT8 (0x80)
-#define MAX_UINT8 (0xFFu)
-#define MIN_UINT8 (0u)
+/* off64_t */
+#define OFF64_MIN  INT64_MIN
+#define OFF64_MAX  INT64_MAX
 
-#define MAX_INT16 (0x7FFF)
-#define MIN_INT16 (0x8000)
-#define MAX_UINT16 (0xFFFFu)
-#define MIN_UINT16 (0u)
-
-#define MAX_INT32 (0x7FFFFFFF)
-#define MIN_INT32 (0x80000000)
-#define MAX_UINT32 (0xFFFFFFFFu)
-#define MIN_UINT32 (0u)
-
-#define MAX_INT64 (0x7FFFFFFFFFFFFFFFll)
-#define MIN_INT64 (0x8000000000000000ll)
-#define MAX_UINT64 (0xFFFFFFFFFFFFFFFFull)
-#define MIN_UINT64 (0ull)
+/* 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 a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/lib/c/include/stdio.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -171,4 +171,5 @@
 extern off64_t ftell(FILE *);
 extern int feof(FILE *);
+extern int fileno(FILE *);
 
 extern int fflush(FILE *);
Index: uspace/lib/c/include/sys/time.h
===================================================================
--- uspace/lib/c/include/sys/time.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/lib/c/include/sys/time.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -43,4 +43,7 @@
 typedef long suseconds_t;
 
+typedef uint32_t useconds_t;
+typedef uint32_t mseconds_t;
+
 struct timeval {
 	time_t tv_sec;        /* seconds */
Index: uspace/lib/c/include/trace.h
===================================================================
--- uspace/lib/c/include/trace.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
+++ uspace/lib/c/include/trace.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2010 Martin Decky
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup libc
+ * @{
+ */
+/** @file
+ */
+
+#ifndef LIBC_TRACE_H_
+#define LIBC_TRACE_H_
+
+#define NO_TRACE  __attribute__((no_instrument_function))
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/include/unistd.h
===================================================================
--- uspace/lib/c/include/unistd.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/lib/c/include/unistd.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -37,4 +37,5 @@
 
 #include <sys/types.h>
+#include <time.h>
 #include <libarch/config.h>
 
@@ -56,6 +57,4 @@
 	#define SEEK_END  2
 #endif
-
-typedef uint32_t useconds_t;
 
 extern int dup2(int oldfd, int newfd);
Index: pace/lib/libpci/Makefile.build
===================================================================
--- uspace/lib/libpci/Makefile.build	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ 	(revision )
@@ -1,61 +1,0 @@
-#
-# Copyright (c) 2005 Martin Decky
-# Copyright (c) 2007 Jakub Jermar
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions
-# are met:
-#
-# - Redistributions of source code must retain the above copyright
-#   notice, this list of conditions and the following disclaimer.
-# - Redistributions in binary form must reproduce the above copyright
-#   notice, this list of conditions and the following disclaimer in the
-#   documentation and/or other materials provided with the distribution.
-# - The name of the author may not be used to endorse or promote products
-#   derived from this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
-# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
-# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
-# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
-# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
-# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-#
-
-## Setup toolchain
-#
-
-include Makefile.common
-include $(LIBC_PREFIX)/Makefile.toolchain
-
-## Sources
-#
-
-SOURCES = \
-	access.c \
-	generic.c \
-	names.c \
-	i386-ports.c
-
-OBJECTS := $(addsuffix .o,$(basename $(SOURCES)))
-
-.PHONY: all
-
-all: $(LIBPCI)
-
--include $(DEPEND)
-
-$(LIBPCI): $(OBJECTS)
-	$(AR) rc $@ $(OBJECTS)
-
-%.o: %.c $(DEPEND)
-	$(CC) $(DEFS) $(CFLAGS) -c $< -o $@
-
-$(DEPEND):
-	makedepend -f - -- $(DEPEND_DEFS) $(CFLAGS) -- $(SOURCES) > $@ 2> /dev/null
-	-[ -f $(DEPEND_PREV) ] && diff -q $(DEPEND_PREV) $@ && mv -f $(DEPEND_PREV) $@
Index: pace/lib/libpci/Makefile.common
===================================================================
--- uspace/lib/libpci/Makefile.common	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ 	(revision )
@@ -1,36 +1,0 @@
-#
-# Copyright (c) 2005 Martin Decky
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions
-# are met:
-#
-# - Redistributions of source code must retain the above copyright
-#   notice, this list of conditions and the following disclaimer.
-# - Redistributions in binary form must reproduce the above copyright
-#   notice, this list of conditions and the following disclaimer in the
-#   documentation and/or other materials provided with the distribution.
-# - The name of the author may not be used to endorse or promote products
-#   derived from this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
-# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
-# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
-# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
-# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
-# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-#
-
-
-## Common names
-#
-
-LIBC_PREFIX = ../../../lib/libc
-DEPEND = Makefile.depend
-DEPEND_PREV = $(DEPEND).prev
-LIBPCI = libpci.a
Index: uspace/lib/net/Makefile
===================================================================
--- uspace/lib/net/Makefile	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/lib/net/Makefile	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -29,15 +29,17 @@
 
 USPACE_PREFIX = ../..
-EXTRA_CFLAGS = -Iinclude -I$(LIBSOCKET_PREFIX)/include
+EXTRA_CFLAGS = -Iinclude
 LIBRARY = libnet
 
 SOURCES = \
+	generic/generic.c \
 	generic/net_remote.c \
 	generic/net_checksum.c \
+	generic/packet_client.c \
 	generic/packet_remote.c \
+	generic/socket_core.c \
 	adt/module_map.c \
 	netif/netif_local.c \
 	netif/netif_remote.c \
-	netif/netif_nil_bundle.c \
 	nil/nil_remote.c \
 	il/ip_remote.c \
Index: uspace/lib/net/adt/module_map.c
===================================================================
--- uspace/lib/net/adt/module_map.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/lib/net/adt/module_map.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -27,10 +27,10 @@
  */
 
-/** @addtogroup net
- *  @{
+/** @addtogroup libnet
+ * @{
  */
 
 /** @file
- *  Character string to module map implementation.
+ * Character string to module map implementation.
  */
 
@@ -38,9 +38,9 @@
 #include <task.h>
 #include <unistd.h>
+#include <err.h>
 
 #include <ipc/services.h>
 
-#include <net_err.h>
-#include <net_modules.h>
+#include <net/modules.h>
 
 #include <adt/generic_char_map.h>
@@ -49,5 +49,22 @@
 GENERIC_CHAR_MAP_IMPLEMENT(modules, module_t)
 
-int add_module(module_ref * module, modules_ref modules, const char * name, const char * filename, services_t service, task_id_t task_id, connect_module_t connect_module){
+/** Adds module to the module map.
+ *
+ * @param[out] module	The module structure added.
+ * @param[in] modules	The module map.
+ * @param[in] name	The module name.
+ * @param[in] filename	The full path filename.
+ * @param[in] service	The module service.
+ * @param[in] task_id	The module current task identifier. Zero means not
+ *			running.
+ * @param[in] connect_module The module connecting function.
+ * @returns		EOK on success.
+ * @returns		ENOMEM if there is not enough memory left.
+ */
+int
+add_module(module_ref *module, modules_ref modules, const char *name,
+    const char *filename, services_t service, task_id_t task_id,
+    connect_module_t connect_module)
+{
 	ERROR_DECLARE;
 
@@ -55,7 +72,7 @@
 
 	tmp_module = (module_ref) malloc(sizeof(module_t));
-	if(! tmp_module){
+	if (!tmp_module)
 		return ENOMEM;
-	}
+
 	tmp_module->task_id = task_id;
 	tmp_module->phone = 0;
@@ -65,33 +82,52 @@
 	tmp_module->service = service;
 	tmp_module->connect_module = connect_module;
-	if(ERROR_OCCURRED(modules_add(modules, tmp_module->name, 0, tmp_module))){
+
+	if (ERROR_OCCURRED(modules_add(modules, tmp_module->name, 0,
+	    tmp_module))) {
 		free(tmp_module);
 		return ERROR_CODE;
 	}
-	if(module){
+	if (module)
 		*module = tmp_module;
-	}
+
 	return EOK;
 }
 
-module_ref get_running_module(modules_ref modules, char * name){
+/** Searches and returns the specified module.
+ *
+ * If the module is not running, the module filaname is spawned.
+ * If the module is not connected, the connect_function is called.
+ *
+ * @param[in] modules	The module map.
+ * @param[in] name	The module name.
+ * @returns		The running module found. It does not have to be
+ *			connected.
+ * @returns		NULL if there is no such module.
+ */
+module_ref get_running_module(modules_ref modules, char *name)
+{
 	module_ref module;
 
 	module = modules_find(modules, name, 0);
-	if(! module){
+	if (!module)
 		return NULL;
+
+	if (!module->task_id) {
+		module->task_id = spawn(module->filename);
+		if (!module->task_id)
+			return NULL;
 	}
-	if(! module->task_id){
-		module->task_id = spawn(module->filename);
-		if(! module->task_id){
-			return NULL;
-		}
-	}
-	if(! module->phone){
+	if (!module->phone)
 		module->phone = module->connect_module(module->service);
-	}
+
 	return module;
 }
 
+/** Starts the given module.
+ *
+ * @param[in] fname	The module full or relative path filename.
+ * @returns		The new module task identifier on success.
+ * @returns		Zero if there is no such module.
+ */
 task_id_t spawn(const char *fname)
 {
Index: uspace/lib/net/generic/generic.c
===================================================================
--- uspace/lib/net/generic/generic.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
+++ uspace/lib/net/generic/generic.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -0,0 +1,265 @@
+/*
+ * Copyright (c) 2009 Lukas Mejdrech
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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 libnet
+ * @{
+ */
+
+/** @file
+ * Generic communication interfaces for networking.
+ */
+
+#include <generic.h>
+
+#include <async.h>
+#include <ipc/ipc.h>
+#include <ipc/services.h>
+
+#include <net/device.h>
+#include <adt/measured_strings.h>
+#include <net/packet.h>
+
+/** Notify the module about the device state change.
+ *
+ * @param[in] phone	The service module phone.
+ * @param[in] message	The service specific message.
+ * @param[in] device_id	The device identifier.
+ * @param[in] state	The new device state.
+ * @param[in] target	The target module service.
+ * @return		EOK on success.
+ *
+ */
+int
+generic_device_state_msg_remote(int phone, int message, device_id_t device_id,
+    int state, services_t target)
+{
+	async_msg_3(phone, (ipcarg_t) message, (ipcarg_t) device_id,
+	    (ipcarg_t) state, target);
+	
+	return EOK;
+}
+
+/** Notify a module about the device.
+ *
+ * @param[in] phone	The service module phone.
+ * @param[in] message	The service specific message.
+ * @param[in] device_id	The device identifier.
+ * @param[in] arg2	The second argument of the message.
+ * @param[in] service	The device module service.
+ * @return		EOK on success.
+ * @return		Other error codes as defined for the specific service
+ *			 message.
+ *
+ */
+int
+generic_device_req_remote(int phone, int message, device_id_t device_id,
+    int arg2, services_t service)
+{
+	return (int) async_req_3_0(phone, (ipcarg_t) message,
+	    (ipcarg_t) device_id, (ipcarg_t) arg2, (ipcarg_t) service);
+}
+
+/** Returns the address.
+ *
+ * @param[in] phone	The service module phone.
+ * @param[in] message	The service specific message.
+ * @param[in] device_id	The device identifier.
+ * @param[out] address	The desired address.
+ * @param[out] data	The address data container.
+ * @returns		EOK on success.
+ * @returns		EBADMEM if the address parameter and/or the data
+ *			parameter is NULL.
+ * @returns		Other error codes as defined for the specific service
+ *			message.
+ */
+int
+generic_get_addr_req(int phone, int message, device_id_t device_id,
+    measured_string_ref *address, char ** data)
+{
+	aid_t message_id;
+	ipcarg_t result;
+	int string;
+
+	if (!address || !data)
+		return EBADMEM;
+
+	// request the address
+	message_id = async_send_1(phone, (ipcarg_t) message,
+	    (ipcarg_t) device_id, NULL);
+	string = measured_strings_return(phone, address, data, 1);
+	async_wait_for(message_id, &result);
+
+	// if not successful
+	if ((string == EOK) && (result != EOK)) {
+		// clear the data
+		free(*address);
+		free(*data);
+	}
+	
+	return (int) result;
+}
+
+/** Return the device packet dimension for sending.
+ *
+ * @param[in] phone	The service module phone.
+ * @param[in] message	The service specific message.
+ * @param[in] device_id	The device identifier.
+ * @param[out] packet_dimension The packet dimension.
+ * @return		EOK on success.
+ * @return		EBADMEM if the packet_dimension parameter is NULL.
+ * @return		Other error codes as defined for the specific service
+ *			message.
+ */
+int
+generic_packet_size_req_remote(int phone, int message, device_id_t device_id,
+    packet_dimension_ref packet_dimension)
+{
+	if (!packet_dimension)
+		return EBADMEM;
+	
+	ipcarg_t addr_len;
+	ipcarg_t prefix;
+	ipcarg_t content;
+	ipcarg_t suffix;
+	
+	ipcarg_t result = async_req_1_4(phone, (ipcarg_t) message,
+	    (ipcarg_t) device_id, &addr_len, &prefix, &content, &suffix);
+	
+	packet_dimension->prefix = (size_t) prefix;
+	packet_dimension->content = (size_t) content;
+	packet_dimension->suffix = (size_t) suffix;
+	packet_dimension->addr_len = (size_t) addr_len;
+	
+	return (int) result;
+}
+
+/** Pass the packet queue to the module.
+ *
+ * @param[in] phone	The service module phone.
+ * @param[in] message	The service specific message.
+ * @param[in] device_id	The device identifier.
+ * @param[in] packet_id	The received packet or the received packet queue
+ *			identifier.
+ * @param[in] target	The target module service.
+ * @param[in] error	The error module service.
+ * @return		EOK on success.
+ */
+int
+generic_received_msg_remote(int phone, int message, device_id_t device_id,
+    packet_id_t packet_id, services_t target, services_t error)
+{
+	if (error) {
+		async_msg_4(phone, (ipcarg_t) message, (ipcarg_t) device_id,
+		    (ipcarg_t) packet_id, (ipcarg_t) target, (ipcarg_t) error);
+	} else {
+		async_msg_3(phone, (ipcarg_t) message, (ipcarg_t) device_id,
+		    (ipcarg_t) packet_id, (ipcarg_t) target);
+	}
+	
+	return EOK;
+}
+
+/** Send the packet queue.
+ *
+ * @param[in] phone	The service module phone.
+ * @param[in] message	The service specific message.
+ * @param[in] device_id	The device identifier.
+ * @param[in] packet_id	The packet or the packet queue identifier.
+ * @param[in] sender	The sending module service.
+ * @param[in] error	The error module service.
+ * @return		EOK on success.
+ *
+ */
+int
+generic_send_msg_remote(int phone, int message, device_id_t device_id,
+    packet_id_t packet_id, services_t sender, services_t error)
+{
+	if (error) {
+		async_msg_4(phone, (ipcarg_t) message, (ipcarg_t) device_id,
+		    (ipcarg_t) packet_id, (ipcarg_t) sender, (ipcarg_t) error);
+	} else {
+		async_msg_3(phone, (ipcarg_t) message, (ipcarg_t) device_id,
+		    (ipcarg_t) packet_id, (ipcarg_t) sender);
+	}
+	
+	return EOK;
+}
+
+/** Translates the given strings.
+ *
+ * Allocates and returns the needed memory block as the data parameter.
+ *
+ * @param[in] phone	The service module phone.
+ * @param[in] message	The service specific message.
+ * @param[in] device_id	The device identifier.
+ * @param[in] service	The module service.
+ * @param[in] configuration The key strings.
+ * @param[in] count	The number of configuration keys.
+ * @param[out] translation The translated values.
+ * @param[out] data	The translation data container.
+ * @returns		EOK on success.
+ * @returns		EINVAL if the configuration parameter is NULL.
+ * @returns		EINVAL if the count parameter is zero.
+ * @returns		EBADMEM if the translation or the data parameters are
+ *			NULL.
+ * @returns		Other error codes as defined for the specific service
+ *			message.
+ */
+int
+generic_translate_req(int phone, int message, device_id_t device_id,
+    services_t service, measured_string_ref configuration, size_t count,
+    measured_string_ref *translation, char **data)
+{
+	aid_t message_id;
+	ipcarg_t result;
+	int string;
+
+	if (!configuration || (count == 0))
+		return EINVAL;
+	if (!translation || !data)
+		return EBADMEM;
+
+	// request the translation
+	message_id = async_send_3(phone, (ipcarg_t) message,
+	    (ipcarg_t) device_id, (ipcarg_t) count, (ipcarg_t) service, NULL);
+	measured_strings_send(phone, configuration, count);
+	string = measured_strings_return(phone, translation, data, count);
+	async_wait_for(message_id, &result);
+
+	// if not successful
+	if ((string == EOK) && (result != EOK)) {
+		// clear the data
+		free(*translation);
+		free(*data);
+	}
+
+	return (int) result;
+}
+
+/** @}
+ */
Index: uspace/lib/net/generic/net_checksum.c
===================================================================
--- uspace/lib/net/generic/net_checksum.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/lib/net/generic/net_checksum.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -27,10 +27,10 @@
  */
 
-/** @addtogroup net
- *  @{
+/** @addtogroup libnet
+ * @{
  */
 
 /** @file
- *  General CRC and checksum computation implementation.
+ * General CRC and checksum computation implementation.
  */
 
@@ -39,71 +39,93 @@
 #include <net_checksum.h>
 
-/** Big-endian encoding CRC divider.
- */
-#define CRC_DIVIDER_BE	0x04C11DB7
-
-/** Little-endian encoding CRC divider.
- */
-#define CRC_DIVIDER_LE	0xEDB88320
-
-uint16_t compact_checksum(uint32_t sum){
+/** Big-endian encoding CRC divider. */
+#define CRC_DIVIDER_BE	0x04c11db7
+
+/** Little-endian encoding CRC divider. */
+#define CRC_DIVIDER_LE	0xedb88320
+
+/** Compacts the computed checksum to the 16 bit number adding the carries.
+ *
+ * @param[in] sum	Computed checksum.
+ * @returns		Compacted computed checksum to the 16 bits.
+ */
+uint16_t compact_checksum(uint32_t sum)
+{
 	// shorten to the 16 bits
-	while(sum >> 16){
-		sum = (sum &0xFFFF) + (sum >> 16);
-	}
+	while (sum >> 16)
+		sum = (sum & 0xffff) + (sum >> 16);
 
 	return (uint16_t) sum;
 }
 
-uint32_t compute_checksum(uint32_t seed, uint8_t * data, size_t length){
+/** Computes sum of the 2 byte fields.
+ *
+ * Padds one zero (0) byte if odd.
+ *
+ * @param[in] seed	Initial value. Often used as 0 or ~0.
+ * @param[in] data	Pointer to the beginning of data to process.
+ * @param[in] length	Length of the data in bytes.
+ * @returns		The computed checksum of the length bytes of the data.
+ */
+uint32_t compute_checksum(uint32_t seed, uint8_t *data, size_t length)
+{
 	size_t index;
 
 	// sum all the 16 bit fields
-	for(index = 0; index + 1 < length; index += 2){
+	for (index = 0; index + 1 < length; index += 2)
 		seed += (data[index] << 8) + data[index + 1];
-	}
 
 	// last odd byte with zero padding
-	if(index + 1 == length){
+	if (index + 1 == length)
 		seed += data[index] << 8;
-	}
 
 	return seed;
 }
 
-uint32_t compute_crc32_be(uint32_t seed, uint8_t * data, size_t length){
+/** Computes CRC32 value in the big-endian environment.
+ *
+ * @param[in] seed	Initial value. Often used as 0 or ~0.
+ * @param[in] data	Pointer to the beginning of data to process.
+ * @param[in] length	Length of the data in bits.
+ * @returns		The computed CRC32 of the length bits of the data.
+ */
+uint32_t compute_crc32_be(uint32_t seed, uint8_t * data, size_t length)
+{
 	size_t index;
 
 	// process full bytes
-	while(length >= 8){
+	while (length >= 8) {
 		// add the data
 		seed ^= (*data) << 24;
+		
 		// for each added bit
-		for(index = 0; index < 8; ++ index){
+		for (index = 0; index < 8; ++index) {
 			// if the first bit is set
-			if(seed &0x80000000){
+			if (seed & 0x80000000) {
 				// shift and divide the checksum
 				seed = (seed << 1) ^ ((uint32_t) CRC_DIVIDER_BE);
-			}else{
+			} else {
 				// shift otherwise
 				seed <<= 1;
 			}
 		}
+		
 		// move to the next byte
-		++ data;
+		++data;
 		length -= 8;
 	}
 
 	// process the odd bits
-	if(length > 0){
+	if (length > 0) {
 		// add the data with zero padding
-		seed ^= ((*data) &(0xFF << (8 - length))) << 24;
+		seed ^= ((*data) & (0xff << (8 - length))) << 24;
+		
 		// for each added bit
-		for(index = 0; index < length; ++ index){
+		for (index = 0; index < length; ++index) {
 			// if the first bit is set
-			if(seed &0x80000000){
+			if (seed & 0x80000000) {
 				// shift and divide the checksum
 				seed = (seed << 1) ^ ((uint32_t) CRC_DIVIDER_BE);
-			}else{
+			} else {
 				// shift otherwise
 				seed <<= 1;
@@ -115,37 +137,48 @@
 }
 
-uint32_t compute_crc32_le(uint32_t seed, uint8_t * data, size_t length){
+/** Computes CRC32 value in the little-endian environment.
+ *
+ * @param[in] seed	Initial value. Often used as 0 or ~0.
+ * @param[in] data	Pointer to the beginning of data to process.
+ * @param[in] length	Length of the data in bits.
+ * @returns		The computed CRC32 of the length bits of the data.
+ */
+uint32_t compute_crc32_le(uint32_t seed, uint8_t * data, size_t length)
+{
 	size_t index;
 
 	// process full bytes
-	while(length >= 8){
+	while (length >= 8) {
 		// add the data
 		seed ^= (*data);
+		
 		// for each added bit
-		for(index = 0; index < 8; ++ index){
+		for (index = 0; index < 8; ++index) {
 			// if the last bit is set
-			if(seed &1){
+			if (seed & 1) {
 				// shift and divide the checksum
 				seed = (seed >> 1) ^ ((uint32_t) CRC_DIVIDER_LE);
-			}else{
+			} else {
 				// shift otherwise
 				seed >>= 1;
 			}
 		}
+		
 		// move to the next byte
-		++ data;
+		++data;
 		length -= 8;
 	}
 
 	// process the odd bits
-	if(length > 0){
+	if (length > 0) {
 		// add the data with zero padding
 		seed ^= (*data) >> (8 - length);
-		for(index = 0; index < length; ++ index){
+		
+		for (index = 0; index < length; ++index) {
 			// if the last bit is set
-			if(seed &1){
+			if (seed & 1) {
 				// shift and divide the checksum
 				seed = (seed >> 1) ^ ((uint32_t) CRC_DIVIDER_LE);
-			}else{
+			} else {
 				// shift otherwise
 				seed >>= 1;
@@ -157,13 +190,33 @@
 }
 
-uint16_t flip_checksum(uint16_t checksum){
+/** Returns or flips the checksum if zero.
+ *
+ * @param[in] checksum	The computed checksum.
+ * @returns		The internet protocol header checksum.
+ * @returns		0xFFFF if the computed checksum is zero.
+ */
+uint16_t flip_checksum(uint16_t checksum)
+{
 	// flip, zero is returned as 0xFFFF (not flipped)
-	checksum = ~ checksum;
+	checksum = ~checksum;
 	return checksum ? checksum : IP_CHECKSUM_ZERO;
 }
 
-uint16_t ip_checksum(uint8_t * data, size_t length){
+/** Computes the ip header checksum.
+ *
+ * To compute the checksum of a new packet, the checksum header field must be
+ * zero. To check the checksum of a received packet, the checksum may be left
+ * set. Zero will be returned in this case if valid.
+ *
+ * @param[in] data	The header data.
+ * @param[in] length	The header length in bytes.
+ * @returns		The internet protocol header checksum.
+ * @returns		0xFFFF if the computed checksum is zero.
+ */
+uint16_t ip_checksum(uint8_t *data, size_t length)
+{
 	// compute, compact and flip the data checksum
-	return flip_checksum(compact_checksum(compute_checksum(0, data, length)));
+	return flip_checksum(compact_checksum(compute_checksum(0, data,
+	    length)));
 }
 
Index: uspace/lib/net/generic/net_remote.c
===================================================================
--- uspace/lib/net/generic/net_remote.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/lib/net/generic/net_remote.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -27,43 +27,99 @@
  */
 
-/** @addtogroup net
- *  @{
+/** @addtogroup libnet
+ * @{
  */
 
 /** @file
- *  Networking interface implementation for remote modules.
- *  @see net_interface.h
+ * Networking interface implementation for remote modules.
+ * @see net_interface.h
  */
 
 #include <ipc/services.h>
+#include <ipc/net_net.h>
 
 #include <malloc.h>
 
-#include <net_messages.h>
-#include <net_modules.h>
-#include <net_device.h>
+#include <generic.h>
+#include <net/modules.h>
+#include <net/device.h>
 #include <net_interface.h>
 #include <adt/measured_strings.h>
-#include <net_net_messages.h>
 
-int net_connect_module(services_t service){
+/** Connects to the networking module.
+ *
+ * @returns		The networking module phone on success.
+ */
+int net_connect_module(void)
+{
 	return connect_to_service(SERVICE_NETWORKING);
 }
 
-void net_free_settings(measured_string_ref settings, char * data){
-	if(settings){
+/** Frees the received settings.
+ *
+ * @param[in] settings	The received settings.
+ * @param[in] data	The received settings data.
+ * @see	net_get_device_conf_req()
+ * @see net_get_conf_req()
+ */
+void net_free_settings(measured_string_ref settings, char *data)
+{
+	if (settings)
 		free(settings);
-	}
-	if(data){
+	if (data)
 		free(data);
-	}
 }
 
-int net_get_conf_req(int net_phone, measured_string_ref * configuration, size_t count, char ** data){
-	return generic_translate_req(net_phone, NET_NET_GET_DEVICE_CONF, 0, 0, * configuration, count, configuration, data);
+/** Returns the global configuration.
+ *
+ * The configuration names are read and the appropriate settings are set
+ * instead. Call net_free_settings() function to release the returned
+ * configuration.
+ *
+ * @param[in] net_phone	The networking module phone.
+ * @param[in,out] configuration The requested configuration. The names are read
+ * and the appropriate settings are set instead.
+ *
+ * @param[in] count	The configuration entries count.
+ * @param[in,out] data	The configuration and settings data.
+ * @returns		EOK on success.
+ * @returns		EINVAL if the configuration is NULL.
+ * @returns		EINVAL if the count is zero.
+ * @returns		Other error codes as defined for the
+ *			generic_translate_req() function.
+ */
+int
+net_get_conf_req(int net_phone, measured_string_ref *configuration,
+    size_t count, char **data)
+{
+	return generic_translate_req(net_phone, NET_NET_GET_DEVICE_CONF, 0, 0,
+	    *configuration, count, configuration, data);
 }
 
-int net_get_device_conf_req(int net_phone, device_id_t device_id, measured_string_ref * configuration, size_t count, char ** data){
-	return generic_translate_req(net_phone, NET_NET_GET_DEVICE_CONF, device_id, 0, * configuration, count, configuration, data);
+/** Returns the device specific configuration.
+ *
+ * Returns the global configuration if the device specific is not found.
+ * The configuration names are read and the appropriate settings are set
+ * instead. Call net_free_settings() function to release the returned
+ * configuration.
+ *
+ * @param[in] net_phone	The networking module phone.
+ * @param[in] device_id	The device identifier.
+ * @param[in,out] configuration The requested device configuration. The names
+ *			are read and the appropriate settings are set instead.
+ * @param[in] count	The configuration entries count.
+ * @param[in,out] data	The configuration and settings data.
+ * @returns		EOK on success.
+ * @returns		EINVAL if the configuration is NULL.
+ * @returns		EINVAL if the count is zero.
+ * @returns		Other error codes as defined for the
+ *			generic_translate_req() function.
+ */
+int
+net_get_device_conf_req(int net_phone, device_id_t device_id,
+    measured_string_ref *configuration, size_t count, char **data)
+{
+	return generic_translate_req(net_phone, NET_NET_GET_DEVICE_CONF,
+	    device_id, 0, *configuration, count, configuration, data);
 }
 
Index: uspace/lib/net/generic/packet_client.c
===================================================================
--- uspace/lib/net/generic/packet_client.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
+++ uspace/lib/net/generic/packet_client.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -0,0 +1,294 @@
+/*
+ * Copyright (c) 2009 Lukas Mejdrech
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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 libnet
+ * @{
+ */
+
+/** @file
+ * Packet client implementation.
+ */
+
+#include <errno.h>
+#include <mem.h>
+#include <unistd.h>
+#include <sys/mman.h>
+
+#include <packet_client.h>
+#include <packet_remote.h>
+
+#include <net/packet.h>
+#include <net/packet_header.h>
+
+/** Copies the specified data to the beginning of the actual packet content.
+ *
+ * Pushes the content end if needed.
+ *
+ * @param[in] packet	The packet to be filled.
+ * @param[in] data	The data to be copied.
+ * @param[in] length	The length of the copied data.
+ * @returns		EOK on success.
+ * @returns		EINVAL if the packet is not valid.
+ * @returns		ENOMEM if there is not enough memory left.
+ */
+int packet_copy_data(packet_t packet, const void *data, size_t length)
+{
+	if (!packet_is_valid(packet))
+		return EINVAL;
+
+	if (packet->data_start + length >= packet->length)
+		return ENOMEM;
+
+	memcpy((void *) packet + packet->data_start, data, length);
+	if (packet->data_start + length > packet->data_end) 
+		packet->data_end = packet->data_start + length;
+
+	return EOK;
+}
+
+/** Allocates the specified space right before the actual packet content and
+ * returns its pointer.
+ *
+ * @param[in] packet	The packet to be used.
+ * @param[in] length	The space length to be allocated at the beginning of the
+ *			packet content.
+ * @returns		The pointer to the allocated memory.
+ * @returns		NULL if there is not enough memory left.
+ */
+void *packet_prefix(packet_t packet, size_t length)
+{
+	if ((!packet_is_valid(packet)) ||
+	    (packet->data_start - sizeof(struct packet) -
+	    2 * (packet->dest_addr - packet->src_addr) < length)) {
+		return NULL;
+	}
+
+	packet->data_start -= length;
+	return (void *) packet + packet->data_start;
+}
+
+/** Allocates the specified space right after the actual packet content and
+ * returns its pointer.
+ *
+ * @param[in] packet	The packet to be used.
+ * @param[in] length	The space length to be allocated at the end of the
+ *			 packet content.
+ * @returns		The pointer to the allocated memory.
+ * @returns		NULL if there is not enough memory left.
+ */
+void *packet_suffix(packet_t packet, size_t length)
+{
+	if ((!packet_is_valid(packet)) ||
+	    (packet->data_end + length >= packet->length)) {
+		return NULL;
+	}
+
+	packet->data_end += length;
+	return (void *) packet + packet->data_end - length;
+}
+
+/** Trims the actual packet content by the specified prefix and suffix lengths.
+ *
+ * @param[in] packet	The packet to be trimmed.
+ * @param[in] prefix	The prefix length to be removed from the beginning of
+ *			the packet content.
+ * @param[in] suffix	The suffix length to be removed from the end of the
+ *			packet content.
+ * @returns		EOK on success.
+ * @returns		EINVAL if the packet is not valid.
+ * @returns		ENOMEM if there is not enough memory left.
+ */
+int packet_trim(packet_t packet, size_t prefix, size_t suffix)
+{
+	if (!packet_is_valid(packet))
+		return EINVAL;
+
+	if (prefix + suffix > PACKET_DATA_LENGTH(packet))
+		return ENOMEM;
+
+	packet->data_start += prefix;
+	packet->data_end -= suffix;
+	return EOK;
+}
+
+/** Returns the packet identifier.
+ *
+ * @param[in] packet	The packet.
+ * @returns		The packet identifier.
+ * @returns		Zero if the packet is not valid.
+ */
+packet_id_t packet_get_id(const packet_t packet)
+{
+	return packet_is_valid(packet) ? packet->packet_id : 0;
+}
+
+/** Returns the stored packet addresses and their length.
+ *
+ * @param[in] packet	The packet.
+ * @param[out] src	The source address. May be NULL if not desired.
+ * @param[out] dest	The destination address. May be NULL if not desired.
+ * @returns		The stored addresses length.
+ * @returns		Zero if the addresses are not present.
+ * @returns		EINVAL if the packet is not valid.
+ */
+int packet_get_addr(const packet_t packet, uint8_t **src, uint8_t **dest)
+{
+	if (!packet_is_valid(packet))
+		return EINVAL;
+	if (!packet->addr_len)
+		return 0;
+	if (src)
+		*src = (void *) packet + packet->src_addr;
+	if (dest)
+		*dest = (void *) packet + packet->dest_addr;
+
+	return packet->addr_len;
+}
+
+/** Returns the packet content length.
+ *
+ * @param[in] packet	The packet.
+ * @returns		The packet content length in bytes.
+ * @returns		Zero if the packet is not valid.
+ */
+size_t packet_get_data_length(const packet_t packet)
+{
+	if (!packet_is_valid(packet))
+		return 0;
+
+	return PACKET_DATA_LENGTH(packet);
+}
+
+/** Returns the pointer to the beginning of the packet content.
+ *
+ * @param[in] packet	The packet.
+ * @returns		The pointer to the beginning of the packet content.
+ * @returns		NULL if the packet is not valid.
+ */
+void *packet_get_data(const packet_t packet)
+{
+	if (!packet_is_valid(packet))
+		return NULL;
+
+	return (void *) packet + packet->data_start;
+}
+
+/** Sets the packet addresses.
+ *
+ * @param[in] packet	The packet.
+ * @param[in] src	The new source address. May be NULL.
+ * @param[in] dest	The new destination address. May be NULL.
+ * @param[in] addr_len	The addresses length.
+ * @returns		EOK on success.
+ * @returns		EINVAL if the packet is not valid.
+ * @returns		ENOMEM if there is not enough memory left.
+ */
+int
+packet_set_addr(packet_t packet, const uint8_t *src, const uint8_t *dest,
+    size_t addr_len)
+{
+	size_t padding;
+	size_t allocated;
+
+	if (!packet_is_valid(packet))
+		return EINVAL;
+
+	allocated = PACKET_MAX_ADDRESS_LENGTH(packet);
+	if (allocated < addr_len)
+		return ENOMEM;
+
+	padding = allocated - addr_len;
+	packet->addr_len = addr_len;
+
+	if (src) {
+		memcpy((void *) packet + packet->src_addr, src, addr_len);
+		if (padding)
+			bzero((void *) packet + packet->src_addr + addr_len,
+			    padding);
+	} else {
+		bzero((void *) packet + packet->src_addr, allocated);
+	}
+
+	if (dest) {
+		memcpy((void *) packet + packet->dest_addr, dest, addr_len);
+		if (padding)
+			bzero((void *) packet + packet->dest_addr + addr_len,
+			    padding);
+	} else {
+		bzero((void *) packet + packet->dest_addr, allocated);
+	}
+
+	return EOK;
+}
+
+/** Returns the packet copy.
+ *
+ * Copies the addresses, data, order and metric values.
+ * Does not copy the queue placement.
+ *
+ * @param[in] phone	The packet server module phone.
+ * @param[in] packet	The original packet.
+ * @returns		The packet copy.
+ * @returns		NULL on error.
+ */
+packet_t packet_get_copy(int phone, packet_t packet)
+{
+	packet_t copy;
+	uint8_t * src = NULL;
+	uint8_t * dest = NULL;
+	size_t addrlen;
+
+	if (!packet_is_valid(packet))
+		return NULL;
+
+	// get a new packet
+	copy = packet_get_4_remote(phone, PACKET_DATA_LENGTH(packet),
+	    PACKET_MAX_ADDRESS_LENGTH(packet), packet->max_prefix,
+	    PACKET_MIN_SUFFIX(packet));
+	if (!copy)
+		return NULL;
+
+	// get addresses
+	addrlen = packet_get_addr(packet, &src, &dest);
+	// copy data
+	if ((packet_copy_data(copy, packet_get_data(packet),
+	    PACKET_DATA_LENGTH(packet)) == EOK) &&
+	    // copy addresses if present
+	    ((addrlen <= 0) ||
+	    (packet_set_addr(copy, src, dest, addrlen) == EOK))) {
+		copy->order = packet->order;
+		copy->metric = packet->metric;
+		return copy;
+	} else {
+		pq_release_remote(phone, copy->packet_id);
+		return NULL;
+	}
+}
+
+/** @}
+ */
Index: uspace/lib/net/generic/packet_remote.c
===================================================================
--- uspace/lib/net/generic/packet_remote.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/lib/net/generic/packet_remote.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -27,25 +27,25 @@
  */
 
-/** @addtogroup packet
- *  @{
+/** @addtogroup libnet
+ * @{
  */
 
 /** @file
- *  Packet client interface implementation for remote modules.
- *  @see packet_client.h
+ * Packet client interface implementation for remote modules.
+ * @see packet_client.h
  */
 
 #include <async.h>
 #include <errno.h>
+#include <err.h>
 #include <ipc/ipc.h>
+#include <ipc/packet.h>
 #include <sys/mman.h>
 
-#include <net_err.h>
-#include <net_messages.h>
-#include <packet/packet.h>
-#include <packet/packet_client.h>
-#include <packet/packet_header.h>
-#include <packet/packet_messages.h>
+#include <packet_client.h>
 #include <packet_remote.h>
+
+#include <net/packet.h>
+#include <net/packet_header.h>
 
 /** Obtain the packet from the packet server as the shared memory block.
@@ -64,12 +64,15 @@
  *
  */
-static int packet_return(int phone, packet_ref packet, packet_id_t packet_id, size_t size){
+static int
+packet_return(int phone, packet_ref packet, packet_id_t packet_id, size_t size)
+{
 	ERROR_DECLARE;
 	
 	ipc_call_t answer;
 	aid_t message = async_send_1(phone, NET_PACKET_GET, packet_id, &answer);
+
 	*packet = (packet_t) as_get_mappable_page(size);
-	if (ERROR_OCCURRED(async_share_in_start_0_0(phone, *packet, size))
-	    || ERROR_OCCURRED(pm_add(*packet))) {
+	if (ERROR_OCCURRED(async_share_in_start_0_0(phone, *packet, size)) ||
+	    ERROR_OCCURRED(pm_add(*packet))) {
 		munmap(*packet, size);
 		async_wait_for(message, NULL);
@@ -83,4 +86,19 @@
 }
 
+/** Translates the packet identifier to the packet reference.
+ *
+ * Tries to find mapping first.
+ * Contacts the packet server to share the packet if the mapping is not present.
+ *
+ * @param[in] phone	The packet server module phone.
+ * @param[out] packet	The packet reference.
+ * @param[in] packet_id	The packet identifier.
+ * @returns		EOK on success.
+ * @returns		EINVAL if the packet parameter is NULL.
+ * @returns		Other error codes as defined for the NET_PACKET_GET_SIZE
+ *			message.
+ * @returns		Other error codes as defined for the packet_return()
+ *			function.
+ */
 int packet_translate_remote(int phone, packet_ref packet, packet_id_t packet_id)
 {
@@ -91,14 +109,15 @@
 	
 	*packet = pm_find(packet_id);
-	if (!(*packet)) {
+	if (!*packet) {
 		ipcarg_t size;
 		
-		ERROR_PROPAGATE(async_req_1_1(phone, NET_PACKET_GET_SIZE, packet_id, &size));
+		ERROR_PROPAGATE(async_req_1_1(phone, NET_PACKET_GET_SIZE,
+		    packet_id, &size));
 		ERROR_PROPAGATE(packet_return(phone, packet, packet_id, size));
 	}
-	if ((** packet).next) {
+	if ((*packet)->next) {
 		packet_t next;
 		
-		return packet_translate_remote(phone, &next, (** packet).next);
+		return packet_translate_remote(phone, &next, (*packet)->next);
 	}
 	
@@ -106,4 +125,17 @@
 }
 
+/** Obtains the packet of the given dimensions.
+ *
+ * Contacts the packet server to return the appropriate packet.
+ *
+ * @param[in] phone	The packet server module phone.
+ * @param[in] addr_len	The source and destination addresses maximal length in
+ *			bytes.
+ * @param[in] max_prefix The maximal prefix length in bytes.
+ * @param[in] max_content The maximal content length in bytes.
+ * @param[in] max_suffix The maximal suffix length in bytes.
+ * @returns		The packet reference.
+ * @returns		NULL on error.
+ */
 packet_t packet_get_4_remote(int phone, size_t max_content, size_t addr_len,
     size_t max_prefix, size_t max_suffix)
@@ -114,6 +146,6 @@
 	ipcarg_t size;
 	
-	if (ERROR_OCCURRED(async_req_4_2(phone, NET_PACKET_CREATE_4, max_content,
-	    addr_len, max_prefix, max_suffix, &packet_id, &size)))
+	if (ERROR_OCCURRED(async_req_4_2(phone, NET_PACKET_CREATE_4,
+	    max_content, addr_len, max_prefix, max_suffix, &packet_id, &size)))
 		return NULL;
 	
@@ -121,5 +153,6 @@
 	packet_t packet = pm_find(packet_id);
 	if (!packet) {
-		if (ERROR_OCCURRED(packet_return(phone, &packet, packet_id, size)))
+		if (ERROR_OCCURRED(packet_return(phone, &packet, packet_id,
+		    size)))
 			return NULL;
 	}
@@ -128,4 +161,13 @@
 }
 
+/** Obtains the packet of the given content size.
+ *
+ * Contacts the packet server to return the appropriate packet.
+ *
+ * @param[in] phone	The packet server module phone.
+ * @param[in] content	The maximal content length in bytes.
+ * @returns		The packet reference.
+ * @returns		NULL on error.
+ */
 packet_t packet_get_1_remote(int phone, size_t content)
 {
@@ -141,5 +183,6 @@
 	packet_t packet = pm_find(packet_id);
 	if (!packet) {
-		if (ERROR_OCCURRED(packet_return(phone, &packet, packet_id, size)))
+		if (ERROR_OCCURRED(packet_return(phone, &packet, packet_id,
+		    size)))
 			return NULL;
 	}
@@ -148,4 +191,14 @@
 }
 
+/** Releases the packet queue.
+ *
+ * All packets in the queue are marked as free for use.
+ * The packet queue may be one packet only.
+ * The module should not use the packets after this point until they are
+ * received or obtained again.
+ *
+ * @param[in] phone	The packet server module phone.
+ * @param[in] packet_id	The packet identifier.
+ */
 void pq_release_remote(int phone, packet_id_t packet_id)
 {
Index: uspace/lib/net/generic/socket_core.c
===================================================================
--- uspace/lib/net/generic/socket_core.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
+++ uspace/lib/net/generic/socket_core.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -0,0 +1,700 @@
+/*
+ * Copyright (c) 2009 Lukas Mejdrech
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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 libnet
+ * @{
+ */
+
+/** @file
+ * Socket common core implementation.
+ */
+
+#include <socket_core.h>
+#include <packet_client.h>
+#include <packet_remote.h>
+
+#include <net/socket_codes.h>
+#include <net/in.h>
+#include <net/inet.h>
+#include <net/packet.h>
+#include <net/modules.h>
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <err.h>
+
+#include <adt/dynamic_fifo.h>
+#include <adt/int_map.h>
+
+/**
+ * Maximum number of random attempts to find a new socket identifier before
+ * switching to the sequence.
+ */
+#define SOCKET_ID_TRIES	100
+
+/** Bound port sockets.*/
+struct socket_port {
+	/** The bound sockets map. */
+	socket_port_map_t map;
+	/** The bound sockets count. */
+	int count;
+};
+
+INT_MAP_IMPLEMENT(socket_cores, socket_core_t);
+
+GENERIC_CHAR_MAP_IMPLEMENT(socket_port_map, socket_core_ref);
+
+INT_MAP_IMPLEMENT(socket_ports, socket_port_t);
+
+/** Destroys the socket.
+ *
+ * If the socket is bound, the port is released.
+ * Releases all buffered packets, calls the release function and removes the
+ * socket from the local sockets.
+ *
+ * @param[in] packet_phone The packet server phone to release buffered packets.
+ * @param[in] socket	The socket to be destroyed.
+ * @param[in,out] local_sockets The local sockets to be updated.
+ * @param[in,out] global_sockets The global sockets to be updated.
+ * @param[in] socket_release The client release callback function.
+ */
+static void
+socket_destroy_core(int packet_phone, socket_core_ref socket,
+    socket_cores_ref local_sockets, socket_ports_ref global_sockets,
+    void (* socket_release)(socket_core_ref socket))
+{
+	int packet_id;
+
+	// if bound
+	if (socket->port) {
+		// release the port
+		socket_port_release(global_sockets, socket);
+	}
+	
+	// release all received packets
+	while ((packet_id = dyn_fifo_pop(&socket->received)) >= 0)
+		pq_release_remote(packet_phone, packet_id);
+
+	dyn_fifo_destroy(&socket->received);
+	dyn_fifo_destroy(&socket->accepted);
+
+	if (socket_release)
+		socket_release(socket);
+
+	socket_cores_exclude(local_sockets, socket->socket_id);
+}
+
+/** Destroys local sockets.
+ *
+ * Releases all buffered packets and calls the release function for each of the
+ * sockets.
+ *
+ * @param[in] packet_phone The packet server phone to release buffered packets.
+ * @param[in] local_sockets The local sockets to be destroyed.
+ * @param[in,out] global_sockets The global sockets to be updated.
+ * @param[in] socket_release The client release callback function.
+ */
+void
+socket_cores_release(int packet_phone, socket_cores_ref local_sockets,
+    socket_ports_ref global_sockets,
+    void (* socket_release)(socket_core_ref socket))
+{
+	int index;
+
+	if (!socket_cores_is_valid(local_sockets))
+		return;
+
+	local_sockets->magic = 0;
+
+	for (index = 0; index < local_sockets->next; ++index) {
+		if (socket_cores_item_is_valid(&local_sockets->items[index])) {
+			local_sockets->items[index].magic = 0;
+
+			if (local_sockets->items[index].value) {
+				socket_destroy_core(packet_phone,
+				    local_sockets->items[index].value,
+				    local_sockets, global_sockets,
+				    socket_release);
+				free(local_sockets->items[index].value);
+				local_sockets->items[index].value = NULL;
+			}
+		}
+	}
+
+	free(local_sockets->items);
+}
+
+/** Adds the socket to a socket port.
+ *
+ * @param[in,out] socket_port The socket port structure.
+ * @param[in] socket	The socket to be added.
+ * @param[in] key	The socket key identifier.
+ * @param[in] key_length The socket key length.
+ * @returns		EOK on success.
+ * @returns		ENOMEM if there is not enough memory left.
+ */
+static int
+socket_port_add_core(socket_port_ref socket_port, socket_core_ref socket,
+    const char *key, size_t key_length)
+{
+	ERROR_DECLARE;
+
+	socket_core_ref *socket_ref;
+
+	// create a wrapper
+	socket_ref = malloc(sizeof(*socket_ref));
+	if (!socket_ref)
+		return ENOMEM;
+
+	*socket_ref = socket;
+	// add the wrapper
+	if (ERROR_OCCURRED(socket_port_map_add(&socket_port->map, key,
+	    key_length, socket_ref))) {
+		free(socket_ref);
+		return ERROR_CODE;
+	}
+	
+	++socket_port->count;
+	socket->key = key;
+	socket->key_length = key_length;
+	
+	return EOK;
+}
+
+/** Binds the socket to the port.
+ *
+ * The SOCKET_MAP_KEY_LISTENING key identifier is used.
+ *
+ * @param[in] global_sockets The global sockets to be updated.
+ * @param[in] socket	The socket to be added.
+ * @param[in] port	The port number to be bound to.
+ * @returns		EOK on success.
+ * @returns		ENOMEM if there is not enough memory left.
+ * @returns		Other error codes as defined for the
+ *			 socket_ports_add() function.
+ */
+static int
+socket_bind_insert(socket_ports_ref global_sockets, socket_core_ref socket,
+    int port)
+{
+	ERROR_DECLARE;
+
+	socket_port_ref socket_port;
+
+	// create a wrapper
+	socket_port = malloc(sizeof(*socket_port));
+	if (!socket_port)
+		return ENOMEM;
+
+	socket_port->count = 0;
+	if (ERROR_OCCURRED(socket_port_map_initialize(&socket_port->map)) ||
+	    ERROR_OCCURRED(socket_port_add_core(socket_port, socket,
+	    SOCKET_MAP_KEY_LISTENING, 0))) {
+		socket_port_map_destroy(&socket_port->map);
+		free(socket_port);
+		return ERROR_CODE;
+	}
+	
+	// register the incomming port
+	ERROR_CODE = socket_ports_add(global_sockets, port, socket_port);
+	if (ERROR_CODE < 0) {
+		socket_port_map_destroy(&socket_port->map);
+		free(socket_port);
+		return ERROR_CODE;
+	}
+	
+	socket->port = port;
+	return EOK;
+}
+
+/** Binds the socket to the port.
+ *
+ * The address port is used if set, a free port is used if not.
+ *
+ * @param[in] local_sockets The local sockets to be searched.
+ * @param[in,out] global_sockets The global sockets to be updated.
+ * @param[in] socket_id	The new socket identifier.
+ * @param[in] addr	The address to be bound to.
+ * @param[in] addrlen	The address length.
+ * @param[in] free_ports_start The minimum free port.
+ * @param[in] free_ports_end The maximum free port.
+ * @param[in] last_used_port The last used free port.
+ * @returns		EOK on success.
+ * @returns		ENOTSOCK if the socket was not found.
+ * @returns		EAFNOSUPPORT if the address family is not supported.
+ * @returns		EADDRINUSE if the port is already in use.
+ * @returns		Other error codes as defined for the
+ *			socket_bind_free_port() function.
+ * @returns		Other error codes as defined for the
+ *			socket_bind_insert() function.
+ */
+int
+socket_bind(socket_cores_ref local_sockets, socket_ports_ref global_sockets,
+    int socket_id, void *addr, size_t addrlen, int free_ports_start,
+    int free_ports_end, int last_used_port)
+{
+	socket_core_ref socket;
+	socket_port_ref socket_port;
+	struct sockaddr *address;
+	struct sockaddr_in *address_in;
+
+	if (addrlen < sizeof(struct sockaddr))
+		return EINVAL;
+
+	address = (struct sockaddr *) addr;
+	switch (address->sa_family) {
+	case AF_INET:
+		if (addrlen != sizeof(struct sockaddr_in))
+			return EINVAL;
+		
+		address_in = (struct sockaddr_in *) addr;
+		// find the socket
+		socket = socket_cores_find(local_sockets, socket_id);
+		if (!socket)
+			return ENOTSOCK;
+		
+		// bind a free port?
+		if (address_in->sin_port <= 0)
+			return socket_bind_free_port(global_sockets, socket,
+			     free_ports_start, free_ports_end, last_used_port);
+		
+		// try to find the port
+		socket_port = socket_ports_find(global_sockets,
+		    ntohs(address_in->sin_port));
+		if (socket_port) {
+			// already used
+			return EADDRINUSE;
+		}
+		
+		// if bound
+		if (socket->port) {
+			// release the port
+			socket_port_release(global_sockets, socket);
+		}
+		socket->port = -1;
+		
+		return socket_bind_insert(global_sockets, socket,
+		    ntohs(address_in->sin_port));
+		
+	case AF_INET6:
+		// TODO IPv6
+		break;
+	}
+	
+	return EAFNOSUPPORT;
+}
+
+/** Binds the socket to a free port.
+ *
+ * The first free port is used.
+ *
+ * @param[in,out] global_sockets The global sockets to be updated.
+ * @param[in,out] socket The socket to be bound.
+ * @param[in] free_ports_start The minimum free port.
+ * @param[in] free_ports_end The maximum free port.
+ * @param[in] last_used_port The last used free port.
+ * @returns		EOK on success.
+ * @returns		ENOTCONN if no free port was found.
+ * @returns		Other error codes as defined for the
+ *			socket_bind_insert() function.
+ */
+int
+socket_bind_free_port(socket_ports_ref global_sockets, socket_core_ref socket,
+    int free_ports_start, int free_ports_end, int last_used_port)
+{
+	int index;
+
+	// from the last used one
+	index = last_used_port;
+	
+	do {
+		++index;
+		
+		// til the range end
+		if (index >= free_ports_end) {
+			// start from the range beginning
+			index = free_ports_start - 1;
+			do {
+				++index;
+				// til the last used one
+				if (index >= last_used_port) {
+					// none found
+					return ENOTCONN;
+				}
+			} while (socket_ports_find(global_sockets, index));
+			
+			// found, break immediately
+			break;
+		}
+		
+	} while (socket_ports_find(global_sockets, index));
+	
+	return socket_bind_insert(global_sockets, socket, index);
+}
+
+/** Tries to find a new free socket identifier.
+ *
+ * @param[in] local_sockets The local sockets to be searched.
+ * @param[in] positive	A value indicating whether a positive identifier is
+ *			requested. A negative identifier is requested if set to
+ *			false.
+ * @returns		The new socket identifier.
+ * @returns		ELIMIT if there is no socket identifier available.
+ */
+static int socket_generate_new_id(socket_cores_ref local_sockets, int positive)
+{
+	int socket_id;
+	int count;
+
+	count = 0;
+//	socket_id = socket_globals.last_id;
+	do {
+		if (count < SOCKET_ID_TRIES) {
+			socket_id = rand() % INT_MAX;
+			++count;
+		} else if (count == SOCKET_ID_TRIES) {
+			socket_id = 1;
+			++count;
+		// only this branch for last_id
+		} else {
+			if (socket_id < INT_MAX) {
+				++ socket_id;
+/*			} else if(socket_globals.last_id) {
+*				socket_globals.last_id = 0;
+*				socket_id = 1;
+*/			} else {
+				return ELIMIT;
+			}
+		}
+	} while (socket_cores_find(local_sockets,
+	    ((positive ? 1 : -1) * socket_id)));
+	
+//	last_id = socket_id
+	return socket_id;
+}
+
+/** Creates a new socket.
+ *
+ * @param[in,out] local_sockets The local sockets to be updated.
+ * @param[in] app_phone	The application phone.
+ * @param[in] specific_data The socket specific data.
+ * @param[in,out] socket_id The new socket identifier. A new identifier is
+ *			chosen if set to zero or negative. A negative identifier
+ *			is chosen if set to negative.
+ * @returns		EOK on success.
+ * @returns		EINVAL if the socket_id parameter is NULL.
+ * @returns		ENOMEM if there is not enough memory left.
+ */
+int
+socket_create(socket_cores_ref local_sockets, int app_phone,
+    void *specific_data, int *socket_id)
+{
+	ERROR_DECLARE;
+
+	socket_core_ref socket;
+	int res;
+	int positive;
+
+	if (!socket_id)
+		return EINVAL;
+	
+	// store the socket
+	if (*socket_id <= 0) {
+		positive = (*socket_id == 0);
+		*socket_id = socket_generate_new_id(local_sockets, positive);
+		if (*socket_id <= 0)
+			return *socket_id;
+		if (!positive)
+			*socket_id *= -1;
+	} else if(socket_cores_find(local_sockets, *socket_id)) {
+		return EEXIST;
+	}
+	
+	socket = (socket_core_ref) malloc(sizeof(*socket));
+	if (!socket)
+		return ENOMEM;
+	
+	// initialize
+	socket->phone = app_phone;
+	socket->port = -1;
+	socket->key = NULL;
+	socket->key_length = 0;
+	socket->specific_data = specific_data;
+	if (ERROR_OCCURRED(dyn_fifo_initialize(&socket->received,
+	    SOCKET_INITIAL_RECEIVED_SIZE))) {
+		free(socket);
+		return ERROR_CODE;
+	}
+	if (ERROR_OCCURRED(dyn_fifo_initialize(&socket->accepted,
+	    SOCKET_INITIAL_ACCEPTED_SIZE))) {
+		dyn_fifo_destroy(&socket->received);
+		free(socket);
+		return ERROR_CODE;
+	}
+	socket->socket_id = *socket_id;
+	res = socket_cores_add(local_sockets, socket->socket_id, socket);
+	if (res < 0) {
+		dyn_fifo_destroy(&socket->received);
+		dyn_fifo_destroy(&socket->accepted);
+		free(socket);
+		return res;
+	}
+	
+	return EOK;
+}
+
+/** Destroys the socket.
+ *
+ * If the socket is bound, the port is released.
+ * Releases all buffered packets, calls the release function and removes the
+ * socket from the local sockets.
+ *
+ * @param[in] packet_phone The packet server phone to release buffered packets.
+ * @param[in] socket_id	The socket identifier.
+ * @param[in,out] local_sockets The local sockets to be updated.
+ * @param[in,out] global_sockets The global sockets to be updated.
+ * @param[in] socket_release The client release callback function.
+ * @returns		EOK on success.
+ * @returns		ENOTSOCK if the socket is not found.
+ */
+int
+socket_destroy(int packet_phone, int socket_id, socket_cores_ref local_sockets,
+    socket_ports_ref global_sockets,
+    void (*socket_release)(socket_core_ref socket))
+{
+	socket_core_ref socket;
+	int accepted_id;
+
+	// find the socket
+	socket = socket_cores_find(local_sockets, socket_id);
+	if (!socket)
+		return ENOTSOCK;
+	
+	// destroy all accepted sockets
+	while ((accepted_id = dyn_fifo_pop(&socket->accepted)) >= 0)
+		socket_destroy(packet_phone, accepted_id, local_sockets,
+		    global_sockets, socket_release);
+	
+	socket_destroy_core(packet_phone, socket, local_sockets, global_sockets,
+	    socket_release);
+	
+	return EOK;
+}
+
+/** Replies the packet or the packet queue data to the application via the
+ * socket.
+ *
+ * Uses the current message processing fibril.
+ *
+ * @param[in] packet	The packet to be transfered.
+ * @param[out] length	The total data length.
+ * @returns		EOK on success.
+ * @returns		EBADMEM if the length parameter is NULL.
+ * @returns		ENOMEM if there is not enough memory left.
+ * @returns		Other error codes as defined for the data_reply()
+ *			function.
+ */
+int socket_reply_packets(packet_t packet, size_t *length)
+{
+	ERROR_DECLARE;
+
+	packet_t next_packet;
+	size_t fragments;
+	size_t *lengths;
+	size_t index;
+
+	if (!length)
+		return EBADMEM;
+
+	next_packet = pq_next(packet);
+	if (!next_packet) {
+		// write all if only one fragment
+		ERROR_PROPAGATE(data_reply(packet_get_data(packet),
+		    packet_get_data_length(packet)));
+		// store the total length
+		*length = packet_get_data_length(packet);
+	} else {
+		// count the packet fragments
+		fragments = 1;
+		next_packet = pq_next(packet);
+		while ((next_packet = pq_next(next_packet)))
+			++fragments;
+		
+		// compute and store the fragment lengths
+		lengths = (size_t *) malloc(sizeof(size_t) * fragments +
+		    sizeof(size_t));
+		if (!lengths)
+			return ENOMEM;
+		
+		lengths[0] = packet_get_data_length(packet);
+		lengths[fragments] = lengths[0];
+		next_packet = pq_next(packet);
+		
+		for (index = 1; index < fragments; ++index) {
+			lengths[index] = packet_get_data_length(next_packet);
+			lengths[fragments] += lengths[index];
+			next_packet = pq_next(packet);
+		}
+		
+		// write the fragment lengths
+		if (ERROR_OCCURRED(data_reply(lengths,
+		    sizeof(int) * (fragments + 1)))) {
+			free(lengths);
+			return ERROR_CODE;
+		}
+		next_packet = packet;
+		
+		// write the fragments
+		for (index = 0; index < fragments; ++index) {
+			ERROR_CODE = data_reply(packet_get_data(next_packet),
+			    lengths[index]);
+			if (ERROR_OCCURRED(ERROR_CODE)) {
+				free(lengths);
+				return ERROR_CODE;
+			}
+			next_packet = pq_next(next_packet);
+		}
+		
+		// store the total length
+		*length = lengths[fragments];
+		free(lengths);
+	}
+	
+	return EOK;
+}
+
+/** Finds the bound port socket.
+ *
+ * @param[in] global_sockets The global sockets to be searched.
+ * @param[in] port	The port number.
+ * @param[in] key	The socket key identifier.
+ * @param[in] key_length The socket key length.
+ * @returns		The found socket.
+ * @returns		NULL if no socket was found.
+ */
+socket_core_ref
+socket_port_find(socket_ports_ref global_sockets, int port, const char *key,
+    size_t key_length)
+{
+	socket_port_ref socket_port;
+	socket_core_ref *socket_ref;
+
+	socket_port = socket_ports_find(global_sockets, port);
+	if (socket_port && (socket_port->count > 0)) {
+		socket_ref = socket_port_map_find(&socket_port->map, key,
+		    key_length);
+		if (socket_ref)
+			return *socket_ref;
+	}
+	
+	return NULL;
+}
+
+/** Releases the socket port.
+ *
+ * If the socket is bound the port entry is released.
+ * If there are no more port entries the port is release.
+ *
+ * @param[in] global_sockets The global sockets to be updated.
+ * @param[in] socket	The socket to be unbound.
+ */
+void
+socket_port_release(socket_ports_ref global_sockets, socket_core_ref socket)
+{
+	socket_port_ref socket_port;
+	socket_core_ref *socket_ref;
+
+	if (!socket->port)
+		return;
+	
+	// find ports
+	socket_port = socket_ports_find(global_sockets, socket->port);
+	if (socket_port) {
+		// find the socket
+		socket_ref = socket_port_map_find(&socket_port->map,
+		    socket->key, socket->key_length);
+		
+		if (socket_ref) {
+			--socket_port->count;
+			
+			// release if empty
+			if (socket_port->count <= 0) {
+				// destroy the map
+				socket_port_map_destroy(&socket_port->map);
+				// release the port
+				socket_ports_exclude(global_sockets,
+				    socket->port);
+			} else {
+				// remove
+				socket_port_map_exclude(&socket_port->map,
+				    socket->key, socket->key_length);
+			}
+		}
+	}
+	
+	socket->port = 0;
+	socket->key = NULL;
+	socket->key_length = 0;
+}
+
+/** Adds the socket to an already bound port.
+ *
+ * @param[in] global_sockets The global sockets to be updated.
+ * @param[in] port	The port number to be bound to.
+ * @param[in] socket	The socket to be added.
+ * @param[in] key	The socket key identifier.
+ * @param[in] key_length The socket key length.
+ * @returns		EOK on success.
+ * @returns		ENOENT if the port is not already used.
+ * @returns		Other error codes as defined for the
+ *			socket_port_add_core() function.
+ */
+int
+socket_port_add(socket_ports_ref global_sockets, int port,
+    socket_core_ref socket, const char *key, size_t key_length)
+{
+	ERROR_DECLARE;
+
+	socket_port_ref socket_port;
+
+	// find ports
+	socket_port = socket_ports_find(global_sockets, port);
+	if (!socket_port)
+		return ENOENT;
+	
+	// add the socket
+	ERROR_PROPAGATE(socket_port_add_core(socket_port, socket, key,
+	    key_length));
+	
+	socket->port = port;
+	return EOK;
+}
+
+/** @}
+ */
Index: uspace/lib/net/il/arp_remote.c
===================================================================
--- uspace/lib/net/il/arp_remote.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/lib/net/il/arp_remote.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -27,12 +27,15 @@
  */
 
-/** @addtogroup arp
- *  @{
+/** @addtogroup libnet
+ * @{
  */
 
 /** @file
- *  ARP interface implementation for remote modules.
- *  @see arp_interface.h
+ * ARP interface implementation for remote modules.
+ * @see arp_interface.h
  */
+
+#include <arp_interface.h>
+#include <generic.h>
 
 #include <async.h>
@@ -40,53 +43,130 @@
 #include <ipc/ipc.h>
 #include <ipc/services.h>
+#include <ipc/arp.h>
 
-#include <net_messages.h>
-#include <net_modules.h>
-#include <net_device.h>
-#include <arp_interface.h>
+#include <net/modules.h>
+#include <net/device.h>
 #include <adt/measured_strings.h>
-#include <arp_messages.h>
 
-int arp_connect_module(services_t service){
-	if(service != SERVICE_ARP){
+/** Connects to the ARP module.
+ *
+ * @param service	The ARP module service. Ignored parameter.
+ * @returns		The ARP module phone on success.
+ */
+int arp_connect_module(services_t service)
+{
+	if (service != SERVICE_ARP)
 		return EINVAL;
-	}
+
 	return connect_to_service(SERVICE_ARP);
 }
 
-int arp_clean_cache_req(int arp_phone){
+/** Cleans the cache.
+ *
+ * @param[in] arp_phone	The ARP module phone used for (semi)remote calls.
+ * @returns		EOK on success.
+ */
+int arp_clean_cache_req(int arp_phone)
+{
 	return (int) async_req_0_0(arp_phone, NET_ARP_CLEAN_CACHE);
 }
 
-int arp_clear_address_req(int arp_phone, device_id_t device_id, services_t protocol, measured_string_ref address){
+/** Clears the given protocol address from the cache.
+ *
+ * @param[in] arp_phone	The ARP module phone used for (semi)remote calls.
+ * @param[in] device_id	The device identifier.
+ * @param[in] protocol	The requesting protocol service.
+ * @param[in] address	The protocol address to be cleared.
+ * @returns		EOK on success.
+ * @returns		ENOENT if the mapping is not found.
+ */
+int
+arp_clear_address_req(int arp_phone, device_id_t device_id, services_t protocol,
+    measured_string_ref address)
+{
 	aid_t message_id;
 	ipcarg_t result;
 
-	message_id = async_send_2(arp_phone, NET_ARP_CLEAR_ADDRESS, (ipcarg_t) device_id, protocol, NULL);
+	message_id = async_send_2(arp_phone, NET_ARP_CLEAR_ADDRESS,
+	    (ipcarg_t) device_id, protocol, NULL);
 	measured_strings_send(arp_phone, address, 1);
 	async_wait_for(message_id, &result);
+
 	return (int) result;
 }
 
-int arp_clear_device_req(int arp_phone, device_id_t device_id){
-	return (int) async_req_1_0(arp_phone, NET_ARP_CLEAR_DEVICE, (ipcarg_t) device_id);
+/** Clears the device cache.
+ *
+ * @param[in] arp_phone	The ARP module phone used for (semi)remote calls.
+ * @param[in] device_id	The device identifier.
+ * @returns		EOK on success.
+ * @returns		ENOENT if the device is not found.
+ */
+int arp_clear_device_req(int arp_phone, device_id_t device_id)
+{
+	return (int) async_req_1_0(arp_phone, NET_ARP_CLEAR_DEVICE,
+	    (ipcarg_t) device_id);
 }
 
-int arp_device_req(int arp_phone, device_id_t device_id, services_t protocol, services_t netif, measured_string_ref address){
+/** Registers the new device and the requesting protocol service.
+ *
+ * Connects to the network interface layer service.
+ * Determines the device broadcast address, its address lengths and packet size.
+ *
+ * @param[in] arp_phone	The ARP module phone used for (semi)remote calls.
+ * @param[in] device_id	The new device identifier.
+ * @param[in] protocol	The requesting protocol service.
+ * @param[in] netif	The underlying device network interface layer service.
+ * @param[in] address	The local requesting protocol address of the device.
+ * @returns		EOK on success.
+ * @returns		EEXIST if the device is already used.
+ * @returns		ENOMEM if there is not enough memory left.
+ * @returns		ENOENT if the network interface service is not known.
+ * @returns		EREFUSED if the network interface service is not
+ *			responding.
+ * @returns		Other error codes as defined for the
+ *			nil_packet_get_size() function.
+ * @returns		Other error codes as defined for the nil_get_addr()
+ *			function.
+ * @returns		Other error codes as defined for the
+ *			nil_get_broadcast_addr() function.
+ */
+int arp_device_req(int arp_phone, device_id_t device_id, services_t protocol,
+    services_t netif, measured_string_ref address)
+{
 	aid_t message_id;
 	ipcarg_t result;
 
-	message_id = async_send_3(arp_phone, NET_ARP_DEVICE, (ipcarg_t) device_id, protocol, netif, NULL);
+	message_id = async_send_3(arp_phone, NET_ARP_DEVICE,
+	    (ipcarg_t) device_id, protocol, netif, NULL);
 	measured_strings_send(arp_phone, address, 1);
 	async_wait_for(message_id, &result);
+
 	return (int) result;
 }
 
-task_id_t arp_task_get_id(void){
-	return 0;
-}
-
-int arp_translate_req(int arp_phone, device_id_t device_id, services_t protocol, measured_string_ref address, measured_string_ref * translation, char ** data){
-	return generic_translate_req(arp_phone, NET_ARP_TRANSLATE, device_id, protocol, address, 1, translation, data);
+/** Translates the given protocol address to the network interface address.
+ *
+ * Broadcasts the ARP request if the mapping is not found.
+ * Allocates and returns the needed memory block as the data parameter.
+ *
+ * @param[in] arp_phone	The ARP module phone used for (semi)remote calls.
+ * @param[in] device_id	The device identifier.
+ * @param[in] protocol	The requesting protocol service.
+ * @param[in] address	The local requesting protocol address.
+ * @param[out] translation The translation of the local protocol address.
+ * @param[out] data	The allocated raw translation data container.
+ * @returns		EOK on success.
+ * @returns		EINVAL if the address parameter is NULL.
+ * @returns		EBADMEM if the translation or the data parameters are
+ *			NULL.
+ * @returns		ENOENT if the mapping is not found.
+ */
+int
+arp_translate_req(int arp_phone, device_id_t device_id, services_t protocol,
+    measured_string_ref address, measured_string_ref *translation, char **data)
+{
+	return generic_translate_req(arp_phone, NET_ARP_TRANSLATE, device_id,
+	    protocol, address, 1, translation, data);
 }
 
Index: uspace/lib/net/il/ip_client.c
===================================================================
--- uspace/lib/net/il/ip_client.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/lib/net/il/ip_client.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -27,11 +27,11 @@
  */
 
-/** @addtogroup ip
- *  @{
+/** @addtogroup libnet
+ * @{
  */
 
 /** @file
- *  IP client interface implementation.
- *  @see ip_client.h
+ * IP client interface implementation.
+ * @see ip_client.h
  */
 
@@ -40,65 +40,121 @@
 
 #include <ip_client.h>
-#include <socket_errno.h>
-#include <packet/packet.h>
-#include <packet/packet_client.h>
+#include <packet_client.h>
 #include <ip_header.h>
 
-size_t ip_client_header_length(packet_t packet){
+#include <net/packet.h>
+
+/** Returns the IP header length.
+ *
+ * @param[in] packet	The packet.
+ * @returns		The IP header length in bytes.
+ * @returns		Zero if there is no IP header.
+ */
+size_t ip_client_header_length(packet_t packet)
+{
 	ip_header_ref header;
 
 	header = (ip_header_ref) packet_get_data(packet);
-	if((! header)
-		|| (packet_get_data_length(packet) < sizeof(ip_header_t))){
+	if (!header || (packet_get_data_length(packet) < sizeof(ip_header_t)))
 		return 0;
-	}
+
 	return IP_HEADER_LENGTH(header);
 }
 
-int ip_client_get_pseudo_header(ip_protocol_t protocol, struct sockaddr * src, socklen_t srclen, struct sockaddr * dest, socklen_t destlen, size_t data_length, void **header, size_t * headerlen){
+/** Constructs the IPv4 pseudo header.
+ *
+ * @param[in] protocol	The transport protocol.
+ * @param[in] src	The source address.
+ * @param[in] srclen	The source address length.
+ * @param[in] dest	The destination address.
+ * @param[in] destlen	The destination address length.
+ * @param[in] data_length The data length to be set.
+ * @param[out] header	The constructed IPv4 pseudo header.
+ * @param[out] headerlen The length of the IP pseudo header in bytes.
+ * @returns		EOK on success.
+ * @returns		EBADMEM if the header and/or the headerlen parameter is
+ *			NULL.
+ * @returns		EINVAL if the source address and/or the destination
+ *			address parameter is NULL.
+ * @returns		EINVAL if the source address length is less than struct
+ *			sockaddr length.
+ * @returns		EINVAL if the source address length differs from the
+ *			destination address length.
+ * @returns		EINVAL if the source address family differs from the
+ *			destination family.
+ * @returns		EAFNOSUPPORT if the address family is not supported.
+ * @returns		ENOMEM if there is not enough memory left.
+ */
+int
+ip_client_get_pseudo_header(ip_protocol_t protocol, struct sockaddr *src,
+    socklen_t srclen, struct sockaddr *dest, socklen_t destlen,
+    size_t data_length, void **header, size_t *headerlen)
+{
 	ipv4_pseudo_header_ref header_in;
-	struct sockaddr_in * address_in;
-
-	if(!(header && headerlen)){
+	struct sockaddr_in *address_in;
+
+	if (!header || !headerlen)
 		return EBADMEM;
-	}
-	if(!(src && dest && (srclen > 0) && ((size_t) srclen >= sizeof(struct sockaddr)) && (srclen == destlen) && (src->sa_family == dest->sa_family))){
+
+	if (!src || !dest || srclen <= 0 ||
+	    (((size_t) srclen < sizeof(struct sockaddr))) ||
+	    (srclen != destlen) || (src->sa_family != dest->sa_family)) {
 		return EINVAL;
 	}
 
-	switch(src->sa_family){
-		case AF_INET:
-			if(srclen != sizeof(struct sockaddr_in)){
-				return EINVAL;
-			}
-			*headerlen = sizeof(*header_in);
-			header_in = (ipv4_pseudo_header_ref) malloc(*headerlen);
-			if(! header_in){
-				return ENOMEM;
-			}
-			bzero(header_in, * headerlen);
-			address_in = (struct sockaddr_in *) dest;
-			header_in->destination_address = address_in->sin_addr.s_addr;
-			address_in = (struct sockaddr_in *) src;
-			header_in->source_address = address_in->sin_addr.s_addr;
-			header_in->protocol = protocol;
-			header_in->data_length = htons(data_length);
-			*header = header_in;
-			return EOK;
-		// TODO IPv6
-/*		case AF_INET6:
-			if(addrlen != sizeof(struct sockaddr_in6)){
-				return EINVAL;
-			}
-			address_in6 = (struct sockaddr_in6 *) addr;
-			return EOK;
-*/		default:
-			return EAFNOSUPPORT;
-	}
-}
-
-int ip_client_prepare_packet(packet_t packet, ip_protocol_t protocol, ip_ttl_t ttl, ip_tos_t tos, int dont_fragment, size_t ipopt_length){
+	switch (src->sa_family) {
+	case AF_INET:
+		if (srclen != sizeof(struct sockaddr_in))
+			return EINVAL;
+		
+		*headerlen = sizeof(*header_in);
+		header_in = (ipv4_pseudo_header_ref) malloc(*headerlen);
+		if (!header_in)
+			return ENOMEM;
+
+		bzero(header_in, *headerlen);
+		address_in = (struct sockaddr_in *) dest;
+		header_in->destination_address = address_in->sin_addr.s_addr;
+		address_in = (struct sockaddr_in *) src;
+		header_in->source_address = address_in->sin_addr.s_addr;
+		header_in->protocol = protocol;
+		header_in->data_length = htons(data_length);
+		*header = header_in;
+		return EOK;
+
+	// TODO IPv6
+/*	case AF_INET6:
+		if (addrlen != sizeof(struct sockaddr_in6))
+			return EINVAL;
+
+		address_in6 = (struct sockaddr_in6 *) addr;
+		return EOK;
+*/
+
+	default:
+		return EAFNOSUPPORT;
+	}
+}
+
+/** Prepares the packet to be transfered via IP.
+ *
+ * The IP header is prefixed.
+ *
+ * @param[in,out] packet The packet to be prepared.
+ * @param[in] protocol	The transport protocol.
+ * @param[in] ttl	The time to live counter. The IPDEFTTL is set if zero.
+ * @param[in] tos	The type of service.
+ * @param[in] dont_fragment The value indicating whether fragmentation is
+ *			disabled.
+ * @param[in] ipopt_length The prefixed IP options length in bytes.
+ * @returns		EOK on success.
+ * @returns		ENOMEM if there is not enough memory left in the packet.
+ */
+int
+ip_client_prepare_packet(packet_t packet, ip_protocol_t protocol, ip_ttl_t ttl,
+    ip_tos_t tos, int dont_fragment, size_t ipopt_length)
+{
 	ip_header_ref header;
-	uint8_t * data;
+	uint8_t *data;
 	size_t padding;
 
@@ -106,5 +162,5 @@
 	// multiple of 4 bytes
 	padding =  ipopt_length % 4;
-	if(padding){
+	if (padding) {
 		padding = 4 - padding;
 		ipopt_length += padding;
@@ -113,68 +169,93 @@
 	// prefix the header
 	data = (uint8_t *) packet_prefix(packet, sizeof(ip_header_t) + padding);
-	if(! data){
+	if (!data)
 		return ENOMEM;
-	}
 
 	// add the padding
-	while(padding --){
+	while (padding--)
 		data[sizeof(ip_header_t) + padding] = IPOPT_NOOP;
-	}
 
 	// set the header
 	header = (ip_header_ref) data;
-	header->header_length = IP_COMPUTE_HEADER_LENGTH(sizeof(ip_header_t) + ipopt_length);
-	header->ttl = (ttl ? ttl : IPDEFTTL); //(((ttl) <= MAXTTL) ? ttl : MAXTTL) : IPDEFTTL;
+	header->header_length = IP_COMPUTE_HEADER_LENGTH(sizeof(ip_header_t) +
+	    ipopt_length);
+	header->ttl = (ttl ? ttl : IPDEFTTL);
 	header->tos = tos;
 	header->protocol = protocol;
 
-	if(dont_fragment){
+	if (dont_fragment)
 		header->flags = IPFLAG_DONT_FRAGMENT;
-	}
+
 	return EOK;
 }
 
-int ip_client_process_packet(packet_t packet, ip_protocol_t * protocol, ip_ttl_t * ttl, ip_tos_t * tos, int * dont_fragment, size_t * ipopt_length){
+/** Processes the received IP packet.
+ *
+ * Fills set header fields.
+ * Returns the prefixed IP header length.
+ *
+ * @param[in] packet	The received packet.
+ * @param[out] protocol	The transport protocol. May be NULL if not desired.
+ * @param[out] ttl	The time to live counter. May be NULL if not desired.
+ * @param[out] tos	The type of service. May be NULL if not desired.
+ * @param[out] dont_fragment The value indicating whether the fragmentation is
+ *			disabled. May be NULL if not desired.
+ * @param[out] ipopt_length The IP options length in bytes. May be NULL if not
+ *			desired.
+ * @returns		The prefixed IP header length in bytes on success.
+ * @returns		ENOMEM if the packet is too short to contain the IP
+ *			header.
+ */
+int
+ip_client_process_packet(packet_t packet, ip_protocol_t *protocol,
+    ip_ttl_t *ttl, ip_tos_t *tos, int *dont_fragment, size_t *ipopt_length)
+{
 	ip_header_ref header;
 
 	header = (ip_header_ref) packet_get_data(packet);
-	if((! header)
-		|| (packet_get_data_length(packet) < sizeof(ip_header_t))){
+	if (!header || (packet_get_data_length(packet) < sizeof(ip_header_t)))
 		return ENOMEM;
-	}
-
-	if(protocol){
+
+	if (protocol)
 		*protocol = header->protocol;
-	}
-	if(ttl){
+	if (ttl)
 		*ttl = header->ttl;
-	}
-	if(tos){
+	if (tos)
 		*tos = header->tos;
-	}
-	if(dont_fragment){
-		*dont_fragment = header->flags &IPFLAG_DONT_FRAGMENT;
-	}
-	if(ipopt_length){
+	if (dont_fragment)
+		*dont_fragment = header->flags & IPFLAG_DONT_FRAGMENT;
+	if (ipopt_length) {
 		*ipopt_length = IP_HEADER_LENGTH(header) - sizeof(ip_header_t);
 		return sizeof(ip_header_t);
-	}else{
+	} else {
 		return IP_HEADER_LENGTH(header);
 	}
 }
 
-int ip_client_set_pseudo_header_data_length(void *header, size_t headerlen, size_t data_length){
+/** Updates the IPv4 pseudo header data length field.
+ *
+ * @param[in,out] header The IPv4 pseudo header to be updated.
+ * @param[in] headerlen	The length of the IP pseudo header in bytes.
+ * @param[in] data_length The data length to be set.
+ * @returns		EOK on success.
+ * @returns		EBADMEM if the header parameter is NULL.
+ * @returns		EINVAL if the headerlen parameter is not IPv4 pseudo
+ *			header length.
+ */
+int
+ip_client_set_pseudo_header_data_length(void *header, size_t headerlen,
+    size_t data_length)
+{
 	ipv4_pseudo_header_ref header_in;
 
-	if(! header){
+	if (!header)
 		return EBADMEM;
-	}
-
-	if(headerlen == sizeof(ipv4_pseudo_header_t)){
+
+	if (headerlen == sizeof(ipv4_pseudo_header_t)) {
 		header_in = (ipv4_pseudo_header_ref) header;
 		header_in->data_length = htons(data_length);
 		return EOK;
 	// TODO IPv6
-	}else{
+	} else {
 		return EINVAL;
 	}
Index: uspace/lib/net/il/ip_remote.c
===================================================================
--- uspace/lib/net/il/ip_remote.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/lib/net/il/ip_remote.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -40,15 +40,16 @@
  */
 
+#include <ip_remote.h>
+#include <ip_interface.h>
+#include <packet_client.h>
+#include <generic.h>
+
 #include <ipc/services.h>
-
-#include <net_messages.h>
-#include <net_modules.h>
-#include <net_device.h>
-#include <inet.h>
-#include <ip_interface.h>
-#include <packet/packet_client.h>
-#include <il_messages.h>
-#include <ip_messages.h>
-#include <ip_remote.h>
+#include <ipc/il.h>
+#include <ipc/ip.h>
+
+#include <net/modules.h>
+#include <net/device.h>
+#include <net/inet.h>
 
 /** Add a route to the device routing table.
@@ -72,5 +73,5 @@
 
 int ip_bind_service(services_t service, int protocol, services_t me,
-    async_client_conn_t receiver, tl_received_msg_t tl_received_msg)
+    async_client_conn_t receiver)
 {
 	return (int) bind_service(service, (ipcarg_t) protocol, me, service,
@@ -127,5 +128,5 @@
 		return EINVAL;
 	
-	if ((!device_id) || (header) || (headerlen))
+	if ((!device_id) || (!header) || (!headerlen))
 		return EBADMEM;
 	
Index: uspace/lib/net/include/adt/module_map.h
===================================================================
--- uspace/lib/net/include/adt/module_map.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/lib/net/include/adt/module_map.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -27,94 +27,58 @@
  */
 
-/** @addtogroup net
- *  @{
+/** @addtogroup libnet
+ * @{
  */
 
 /** @file
- *  Character string to module map.
+ * Character string to module map.
  */
 
-#ifndef __NET_MODULES_MAP_H__
-#define __NET_MODULES_MAP_H__
+#ifndef LIBNET_MODULES_MAP_H_
+#define LIBNET_MODULES_MAP_H_
 
 #include <task.h>
-
 #include <ipc/services.h>
-
-#include <net_modules.h>
-
+#include <net/modules.h>
 #include <adt/generic_char_map.h>
 
 /** Type definition of the module structure.
- *  @see module_struct
+ * @see module_struct
  */
-typedef struct module_struct	module_t;
+typedef struct module_struct module_t;
 
 /** Type definition of the module structure pointer.
- *  @see module_struct
+ * @see module_struct
  */
-typedef module_t *				module_ref;
+typedef module_t *module_ref;
 
 /** Module map.
- *  Sorted by module names.
- *  @see generic_char_map.h
+ * Sorted by module names.
+ * @see generic_char_map.h
  */
 GENERIC_CHAR_MAP_DECLARE(modules, module_t)
 
-/** Module structure.
- */
-struct	module_struct{
-	/** Module task identifier if running.
-	 */
+/** Module structure. */
+struct module_struct {
+	/** Module task identifier if running. */
 	task_id_t task_id;
-	/** Module service identifier.
-	 */
+	/** Module service identifier. */
 	services_t service;
-	/** Module phone if running and connected.
-	 */
+	/** Module phone if running and connected. */
 	int phone;
-	/** Usage counter.
-	 */
+	/** Usage counter. */
 	int usage;
-	/** Module name.
-	 */
-	const char * name;
-	/** Module full path filename.
-	 */
-	const char * filename;
-	/** Connecting function.
-	 */
-	connect_module_t * connect_module;
+	/** Module name. */
+	const char *name;
+	/** Module full path filename. */
+	const char *filename;
+	/** Connecting function. */
+	connect_module_t *connect_module;
 };
 
-/** Adds module to the module map.
- *  @param[out] module The module structure added.
- *  @param[in] modules The module map.
- *  @param[in] name The module name.
- *  @param[in] filename The full path filename.
- *  @param[in] service The module service.
- *  @param[in] task_id The module current task identifier. Zero (0) means not running.
- *  @param[in] connect_module The module connecting function.
- *  @returns EOK on success.
- *  @returns ENOMEM if there is not enough memory left.
- */
-int add_module(module_ref * module, modules_ref modules, const char * name, const char * filename, services_t service, task_id_t task_id, connect_module_t * connect_module);
-
-/** Searches and returns the specified module.
- *  If the module is not running, the module filaname is spawned.
- *  If the module is not connected, the connect_function is called.
- *  @param[in] modules The module map.
- *  @param[in] name The module name.
- *  @returns The running module found. It does not have to be connected.
- *  @returns NULL if there is no such module.
- */
-module_ref get_running_module(modules_ref modules, char * name);
-
-/** Starts the given module.
- *  @param[in] fname The module full or relative path filename.
- *  @returns The new module task identifier on success.
- *  @returns 0 if there is no such module.
- */
-task_id_t spawn(const char * fname);
+extern int add_module(module_ref *, modules_ref, const char *, const char *,
+    services_t, task_id_t, connect_module_t *);
+extern module_ref get_running_module(modules_ref, char *);
+extern task_id_t spawn(const char *);
 
 #endif
Index: uspace/lib/net/include/arp_interface.h
===================================================================
--- uspace/lib/net/include/arp_interface.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/lib/net/include/arp_interface.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -27,90 +27,33 @@
  */
 
-/** @addtogroup arp
- *  @{
+/** @addtogroup libnet
+ * @{
  */
 
-#ifndef __NET_ARP_INTERFACE_H__
-#define __NET_ARP_INTERFACE_H__
+#ifndef LIBNET_ARP_INTERFACE_H_
+#define LIBNET_ARP_INTERFACE_H_
 
 #include <adt/measured_strings.h>
-#include <net_device.h>
+#include <task.h>
+
+#include <ipc/services.h>
+
+#include <net/device.h>
+#include <net/socket.h>
 
 /** @name ARP module interface
- *  This interface is used by other modules.
+ * This interface is used by other modules.
  */
 /*@{*/
 
-/** Registers the new device and the requesting protocol service.
- *  Connects to the network interface layer service.
- *  Determines the device broadcast address, its address lengths and packet size.
- *  @param[in] arp_phone The ARP module phone used for (semi)remote calls.
- *  @param[in] device_id The new device identifier.
- *  @param[in] protocol The requesting protocol service.
- *  @param[in] netif The underlying device network interface layer service.
- *  @param[in] address The local requesting protocol address of the device.
- *  @returns EOK on success.
- *  @returns EEXIST if the device is already used.
- *  @returns ENOMEM if there is not enough memory left.
- *  @returns ENOENT if the network interface service is not known.
- *  @returns EREFUSED if the network interface service is not responding.
- *  @returns Other error codes as defined for the nil_packet_get_size() function.
- *  @returns Other error codes as defined for the nil_get_addr() function.
- *  @returns Other error codes as defined for the nil_get_broadcast_addr() function.
- */
-extern int arp_device_req(int arp_phone, device_id_t device_id, services_t protocol, services_t netif, measured_string_ref address);
-
-/** Translates the given protocol address to the network interface address.
- *  Broadcasts the ARP request if the mapping is not found.
- *  Allocates and returns the needed memory block as the data parameter.
- *  @param[in] arp_phone The ARP module phone used for (semi)remote calls.
- *  @param[in] device_id The device identifier.
- *  @param[in] protocol The requesting protocol service.
- *  @param[in] address The local requesting protocol address.
- *  @param[out] translation The translation of the local protocol address.
- *  @param[out] data The allocated raw translation data container.
- *  @returns EOK on success.
- *  @returns EINVAL if the address parameter is NULL.
- *  @returns EBADMEM if the translation or the data parameters are NULL.
- *  @returns ENOENT if the mapping is not found.
- */
-extern int arp_translate_req(int arp_phone, device_id_t device_id, services_t protocol, measured_string_ref address, measured_string_ref * translation, char ** data);
-
-/** Clears the device cache.
- *  @param[in] arp_phone The ARP module phone used for (semi)remote calls.
- *  @param[in] device_id The device identifier.
- *  @returns EOK on success.
- *  @returns ENOENT if the device is not found.
- */
-extern int arp_clear_device_req(int arp_phone, device_id_t device_id);
-
-/** Clears the given protocol address from the cache.
- *  @param[in] arp_phone The ARP module phone used for (semi)remote calls.
- *  @param[in] device_id The device identifier.
- *  @param[in] protocol The requesting protocol service.
- *  @param[in] address The protocol address to be cleared.
- *  @returns EOK on success.
- *  @returns ENOENT if the mapping is not found.
- */
-extern int arp_clear_address_req(int arp_phone, device_id_t device_id, services_t protocol, measured_string_ref address);
-
-/** Cleans the cache.
- *  @param[in] arp_phone The ARP module phone used for (semi)remote calls.
- *  @returns EOK on success.
- */
-extern int arp_clean_cache_req(int arp_phone);
-
-/** Connects to the ARP module.
- *  @param service The ARP module service. Ignored parameter.
- *  @returns The ARP module phone on success.
- *  @returns 0 if called by the bundle module.
- */
-extern int arp_connect_module(services_t service);
-
-/** Returns the ARP task identifier.
- *  @returns The current task identifier if called by the bundle module.
- *  @returns 0 if called by the remote module.
- */
-extern task_id_t arp_task_get_id(void);
+extern int arp_device_req(int, device_id_t, services_t, services_t,
+    measured_string_ref);
+extern int arp_translate_req(int, device_id_t, services_t, measured_string_ref,
+    measured_string_ref *, char **);
+extern int arp_clear_device_req(int, device_id_t);
+extern int arp_clear_address_req(int, device_id_t, services_t,
+    measured_string_ref);
+extern int arp_clean_cache_req(int);
+extern int arp_connect_module(services_t);
 
 /*@}*/
Index: pace/lib/net/include/arp_messages.h
===================================================================
--- uspace/lib/net/include/arp_messages.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ 	(revision )
@@ -1,85 +1,0 @@
-/*
- * Copyright (c) 2009 Lukas Mejdrech
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (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 arp
- *  @{
- */
-
-/** @file
- *  ARP module messages.
- *  @see arp_interface.h
- */
-
-#ifndef __NET_ARP_MESSAGES__
-#define __NET_ARP_MESSAGES__
-
-#include <ipc/ipc.h>
-
-#include <net_messages.h>
-
-/** ARP module messages.
- */
-typedef enum{
-	/** Clean cache message.
-	 *  @see arp_clean_cache()
-	 */
-	NET_ARP_CLEAN_CACHE = NET_ARP_FIRST,
-	/** Clear address cache message.
-	 *  @see arp_clear_address_msg()
-	 */
-	NET_ARP_CLEAR_ADDRESS,
-	/** Clear device cache message.
-	 *  @see arp_clear_device_req()
-	 */
-	NET_ARP_CLEAR_DEVICE,
-	/** New device message.
-	 *  @see arp_device_req()
-	 */
-	NET_ARP_DEVICE,
-	/** Address translation message.
-	 *  @see arp_translate_req()
-	 */
-	NET_ARP_TRANSLATE
-} arp_messages;
-
-/** @name ARP specific message parameters definitions
- */
-/*@{*/
-
-/** Returns the protocol service message parameter.
- *  @param[in] call The message call structure.
- */
-#define ARP_GET_NETIF(call) \
-	({services_t service = (services_t) IPC_GET_ARG2(*call); service;})
-
-/*@}*/
-
-#endif
-
-/** @}
- */
Index: uspace/lib/net/include/generic.h
===================================================================
--- uspace/lib/net/include/generic.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
+++ uspace/lib/net/include/generic.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2009 Lukas Mejdrech
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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 libnet
+ * @{
+ */
+
+/** @file
+ * Generic communication interfaces for networking.
+ */
+
+#ifndef LIBNET_GENERIC_H_
+#define LIBNET_GENERIC_H_
+
+#include <async.h>
+#include <ipc/ipc.h>
+#include <ipc/services.h>
+
+#include <net/device.h>
+#include <adt/measured_strings.h>
+#include <net/packet.h>
+
+extern int generic_device_state_msg_remote(int, int, device_id_t, int,
+    services_t);
+extern int generic_device_req_remote(int, int, device_id_t, int, services_t);
+extern int generic_get_addr_req(int, int, device_id_t, measured_string_ref *,
+    char **);
+extern int generic_packet_size_req_remote(int, int, device_id_t,
+    packet_dimension_ref);
+extern int generic_received_msg_remote(int, int, device_id_t, packet_id_t,
+    services_t, services_t);
+extern int generic_send_msg_remote(int, int, device_id_t, packet_id_t,
+    services_t, services_t);
+extern int generic_translate_req(int, int, device_id_t, services_t,
+    measured_string_ref, size_t, measured_string_ref *, char **);
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/net/include/icmp_client.h
===================================================================
--- uspace/lib/net/include/icmp_client.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/lib/net/include/icmp_client.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -38,6 +38,6 @@
 #define __NET_ICMP_CLIENT_H__
 
-#include <icmp_codes.h>
-#include <packet/packet.h>
+#include <net/icmp_codes.h>
+#include <net/packet.h>
 
 /** Processes the received packet prefixed with an ICMP header.
Index: uspace/lib/net/include/icmp_header.h
===================================================================
--- uspace/lib/net/include/icmp_header.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/lib/net/include/icmp_header.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -41,6 +41,6 @@
 #include <sys/types.h>
 
-#include <in.h>
-#include <icmp_codes.h>
+#include <net/in.h>
+#include <net/icmp_codes.h>
 
 /** ICMP header size in bytes.
Index: uspace/lib/net/include/icmp_interface.h
===================================================================
--- uspace/lib/net/include/icmp_interface.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/lib/net/include/icmp_interface.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -34,14 +34,14 @@
 #define __NET_ICMP_INTERFACE_H__
 
+#include <net/socket_codes.h>
 #include <sys/types.h>
 
-#include <net_device.h>
+#include <net/device.h>
 #include <adt/measured_strings.h>
-#include <packet/packet.h>
-#include <inet.h>
-#include <ip_codes.h>
-#include <socket_codes.h>
-#include <icmp_codes.h>
-#include <icmp_common.h>
+#include <net/packet.h>
+#include <net/inet.h>
+#include <net/ip_codes.h>
+#include <net/icmp_codes.h>
+#include <net/icmp_common.h>
 
 /** @name ICMP module interface
Index: uspace/lib/net/include/il_interface.h
===================================================================
--- uspace/lib/net/include/il_interface.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/lib/net/include/il_interface.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -39,13 +39,13 @@
 #define __NET_IL_INTERFACE_H__
 
-#include <async.h>
+#include <generic.h>
 
 #include <ipc/services.h>
+#include <ipc/il.h>
 
-#include <net_messages.h>
-#include <net_device.h>
-#include <packet/packet.h>
-#include <packet/packet_client.h>
-#include <il_messages.h>
+#include <net/device.h>
+#include <net/packet.h>
+
+#include <packet_client.h>
 
 /** @name Internetwork layer module interface
Index: pace/lib/net/include/il_messages.h
===================================================================
--- uspace/lib/net/include/il_messages.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ 	(revision )
@@ -1,95 +1,0 @@
-/*
- * Copyright (c) 2009 Lukas Mejdrech
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (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 net_il
- * @{
- */
-
-/** @file
- * Internetwork layer modules messages.
- * @see il_interface.h
- * @see ip_interface.h
- */
-
-#ifndef __NET_IL_MESSAGES_H__
-#define __NET_IL_MESSAGES_H__
-
-#include <ipc/ipc.h>
-
-/** Internet layer modules messages.
- */
-typedef enum {
-	/** New device message.
-	 *  @see ip_device_req()
-	 */
-	NET_IL_DEVICE = NET_IL_FIRST,
-	/** Device state changed message.
-	 *  @see il_device_state_msg()
-	 */
-	NET_IL_DEVICE_STATE,
-	/** Device MTU changed message.
-	 *  @see il_mtu_changed_msg()
-	 */
-	NET_IL_MTU_CHANGED,
-	/** Packet size message.
-	 *  @see il_packet_size_req()
-	 */
-	NET_IL_PACKET_SPACE,
-	/** Packet received message.
-	 *  @see il_received_msg()
-	 */
-	NET_IL_RECEIVED,
-	/** Packet send message.
-	 *  @see il_send_msg()
-	 */
-	NET_IL_SEND
-} il_messages;
-
-/** @name Internetwork layer specific message parameters definitions
- *
- */
-/*@{*/
-
-/** Return the protocol number message parameter.
- * @param[in] call The message call structure.
- *
- */
-#define IL_GET_PROTO(call)  (int) IPC_GET_ARG1(*call)
-
-/** Return the registering service message parameter.
- * @param[in] call The message call structure.
- *
- */
-#define IL_GET_SERVICE(call)  (services_t) IPC_GET_ARG2(*call)
-
-/*@}*/
-
-#endif
-
-/** @}
- */
Index: uspace/lib/net/include/ip_client.h
===================================================================
--- uspace/lib/net/include/ip_client.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/lib/net/include/ip_client.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -27,85 +27,30 @@
  */
 
-/** @addtogroup ip
- *  @{
+/** @addtogroup libnet
+ * @{
  */
 
 /** @file
- *  IP client interface.
+ * IP client interface.
  */
 
-#ifndef __NET_IP_CLIENT_H__
-#define __NET_IP_CLIENT_H__
+#ifndef LIBNET_IP_CLIENT_H_
+#define LIBNET_IP_CLIENT_H_
 
+#include <net/socket_codes.h>
 #include <sys/types.h>
 
-#include <packet/packet.h>
-#include <ip_codes.h>
+#include <net/packet.h>
+#include <net/ip_codes.h>
 #include <ip_interface.h>
-#include <socket_codes.h>
 
-/** Prepares the packet to be transfered via IP.
- *  The IP header is prefixed.
- *  @param[in,out] packet The packet to be prepared.
- *  @param[in] protocol The transport protocol.
- *  @param[in] ttl The time to live counter. The IPDEFTTL is set if zero (0).
- *  @param[in] tos The type of service.
- *  @param[in] dont_fragment The value indicating whether fragmentation is disabled.
- *  @param[in] ipopt_length The prefixed IP options length in bytes.
- *  @returns EOK on success.
- *  @returns ENOMEM if there is not enough memory left in the packet.
- */
-extern int ip_client_prepare_packet(packet_t packet, ip_protocol_t protocol, ip_ttl_t ttl, ip_tos_t tos, int dont_fragment, size_t ipopt_length);
-
-/** Processes the received IP packet.
- *  Fills set header fields.
- *  Returns the prefixed IP header length.
- *  @param[in] packet The received packet.
- *  @param[out] protocol The transport protocol. May be NULL if not desired.
- *  @param[out] ttl The time to live counter. May be NULL if not desired.
- *  @param[out] tos The type of service. May be NULL if not desired.
- *  @param[out] dont_fragment The value indicating whether the fragmentation is disabled. May be NULL if not desired.
- *  @param[out] ipopt_length The IP options length in bytes. May be NULL if not desired.
- *  @returns The prefixed IP header length in bytes on success.
- *  @returns ENOMEM if the packet is too short to contain the IP header.
- */
-extern int ip_client_process_packet(packet_t packet, ip_protocol_t * protocol, ip_ttl_t * ttl, ip_tos_t * tos, int * dont_fragment, size_t * ipopt_length);
-
-/** Returns the IP header length.
- *  @param[in] packet The packet.
- *  @returns The IP header length in bytes.
- *  @returns Zero (0) if there is no IP header.
- */
-extern size_t ip_client_header_length(packet_t packet);
-
-/** Updates the IPv4 pseudo header data length field.
- *  @param[in,out] header The IPv4 pseudo header to be updated.
- *  @param[in] headerlen The length of the IP pseudo header in bytes.
- *  @param[in] data_length The data length to be set.
- *  @returns EOK on success.
- *  @returns EBADMEM if the header parameter is NULL.
- *  @returns EINVAL if the headerlen parameter is not IPv4 pseudo header length.
- */
-extern int ip_client_set_pseudo_header_data_length(void *header, size_t headerlen, size_t data_length);
-
-/** Constructs the IPv4 pseudo header.
- *  @param[in] protocol The transport protocol.
- *  @param[in] src The source address.
- *  @param[in] srclen The source address length.
- *  @param[in] dest The destination address.
- *  @param[in] destlen The destination address length.
- *  @param[in] data_length The data length to be set.
- *  @param[out] header The constructed IPv4 pseudo header.
- *  @param[out] headerlen The length of the IP pseudo header in bytes.
- *  @returns EOK on success.
- *  @returns EBADMEM if the header and/or the headerlen parameter is NULL.
- *  @returns EINVAL if the source address and/or the destination address parameter is NULL.
- *  @returns EINVAL if the source address length is less than struct sockaddr length.
- *  @returns EINVAL if the source address length differs from the destination address length.
- *  @returns EINVAL if the source address family differs from the destination family.
- *  @returns EAFNOSUPPORT if the address family is not supported.
- *  @returns ENOMEM if there is not enough memory left.
- */
-extern int ip_client_get_pseudo_header(ip_protocol_t protocol, struct sockaddr * src, socklen_t srclen, struct sockaddr * dest, socklen_t destlen, size_t data_length, void **header, size_t * headerlen);
+extern int ip_client_prepare_packet(packet_t, ip_protocol_t, ip_ttl_t, ip_tos_t,
+    int, size_t);
+extern int ip_client_process_packet(packet_t, ip_protocol_t *, ip_ttl_t *,
+    ip_tos_t *, int *, size_t *);
+extern size_t ip_client_header_length(packet_t);
+extern int ip_client_set_pseudo_header_data_length(void *, size_t, size_t);
+extern int ip_client_get_pseudo_header(ip_protocol_t, struct sockaddr *,
+    socklen_t, struct sockaddr *, socklen_t, size_t, void **, size_t *);
 
 // TODO ipopt manipulation
Index: uspace/lib/net/include/ip_interface.h
===================================================================
--- uspace/lib/net/include/ip_interface.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/lib/net/include/ip_interface.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -34,27 +34,13 @@
 #define __NET_IP_INTERFACE_H__
 
+#include <net/socket_codes.h>
 #include <async.h>
 #include <ipc/services.h>
 
-#include <net_device.h>
-#include <packet/packet.h>
+#include <net/device.h>
+#include <net/packet.h>
 
-#include <in.h>
-#include <ip_codes.h>
-#include <socket_codes.h>
-
-#ifdef CONFIG_IL_TL_BUNDLE
-
-#include <ip_local.h>
-
-#define ip_received_error_msg  ip_received_error_msg_local
-#define ip_set_gateway_req     ip_set_gateway_req_local
-#define ip_packet_size_req     ip_packet_size_req_local
-#define ip_device_req          ip_device_req_local
-#define ip_add_route_req       ip_add_route_req_local
-#define ip_send_msg            ip_send_msg_local
-#define ip_get_route_req       ip_get_route_req_local
-
-#else
+#include <net/in.h>
+#include <net/ip_codes.h>
 
 #include <ip_remote.h>
@@ -67,6 +53,4 @@
 #define ip_send_msg            ip_send_msg_remote
 #define ip_get_route_req       ip_get_route_req_remote
-
-#endif
 
 /** @name IP module interface
@@ -90,15 +74,13 @@
  *  @param[in] me The requesting module service.
  *  @param[in] receiver The message receiver. Used for remote connection.
- *  @param[in] tl_received_msg The message processing function. Used if bundled together.
  *  @returns The phone of the needed service.
  *  @returns EOK on success.
  *  @returns Other error codes as defined for the bind_service() function.
  */
-extern int ip_bind_service(services_t service, int protocol, services_t me, async_client_conn_t receiver, tl_received_msg_t tl_received_msg);
+extern int ip_bind_service(services_t service, int protocol, services_t me, async_client_conn_t receiver);
 
 /** Connects to the IP module.
  *  @param service The IP module service. Ignored parameter.
  *  @returns The IP module phone on success.
- *  @returns 0 if called by the bundle module.
  */
 extern int ip_connect_module(services_t service);
Index: pace/lib/net/include/ip_local.h
===================================================================
--- uspace/lib/net/include/ip_local.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ 	(revision )
@@ -1,61 +1,0 @@
-/*
- * Copyright (c) 2009 Lukas Mejdrech
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (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 ip
- * @{
- */
-
-#ifndef __NET_IP_LOCAL_H__
-#define __NET_IP_LOCAL_H__
-
-#include <async.h>
-#include <ipc/services.h>
-
-#include <ip_codes.h>
-#include <inet.h>
-#include <in.h>
-#include <socket.h>
-
-extern int ip_received_error_msg_local(int, device_id_t, packet_t, services_t,
-    services_t);
-extern int ip_set_gateway_req_local(int, device_id_t, in_addr_t);
-extern int ip_packet_size_req_local(int, device_id_t, packet_dimension_ref);
-extern int ip_received_error_msg_local(int, device_id_t, packet_t, services_t,
-    services_t);
-extern int ip_device_req_local(int, device_id_t, services_t);
-extern int ip_add_route_req_local(int, device_id_t, in_addr_t, in_addr_t,
-    in_addr_t);
-extern int ip_send_msg_local(int, device_id_t, packet_t, services_t,
-    services_t);
-extern int ip_get_route_req_local(int, ip_protocol_t, const struct sockaddr *,
-    socklen_t, device_id_t *, void **, size_t *);
-
-#endif
-
-/** @}
- */
Index: pace/lib/net/include/ip_messages.h
===================================================================
--- uspace/lib/net/include/ip_messages.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ 	(revision )
@@ -1,106 +1,0 @@
-/*
- * Copyright (c) 2009 Lukas Mejdrech
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (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 ip
- *  @{
- */
-
-/** @file
- *  IP module messages.
- *  @see ip_interface.h
- */
-
-#ifndef __NET_IP_MESSAGES_H__
-#define __NET_IP_MESSAGES_H__
-
-#include <ipc/ipc.h>
-
-#include <in.h>
-#include <ip_codes.h>
-
-/** IP module messages.
- */
-typedef enum{
-	/** Adds the routing entry.
-	 *  @see ip_add_route()
-	 */
-	NET_IP_ADD_ROUTE = NET_IP_FIRST,
-	/** Gets the actual route information.
-	 *  @see ip_get_route()
-	 */
-	NET_IP_GET_ROUTE,
-	/** Processes the received error notification.
-	 *  @see ip_received_error_msg()
-	 */
-	NET_IP_RECEIVED_ERROR,
-	/** Sets the default gateway.
-	 *  @see ip_set_default_gateway()
-	 */
-	NET_IP_SET_GATEWAY
-} ip_messages;
-
-/** @name IP specific message parameters definitions
- */
-/*@{*/
-
-/** Returns the address message parameter.
- *  @param[in] call The message call structure.
- */
-#define IP_GET_ADDRESS(call) \
-	({in_addr_t addr; addr.s_addr = IPC_GET_ARG3(*call); addr;})
-
-/** Returns the gateway message parameter.
- *  @param[in] call The message call structure.
- */
-#define IP_GET_GATEWAY(call) \
-	({in_addr_t addr; addr.s_addr = IPC_GET_ARG2(*call); addr;})
-
-/** Sets the header length in the message answer.
- *  @param[out] answer The message answer structure.
- */
-#define IP_SET_HEADERLEN(answer, value) \
-	{ipcarg_t argument = (ipcarg_t) (value); IPC_SET_ARG2(*answer, argument);}
-
-/** Returns the network mask message parameter.
- *  @param[in] call The message call structure.
- */
-#define IP_GET_NETMASK(call) \
-	({in_addr_t addr; addr.s_addr = IPC_GET_ARG4(*call); addr;})
-
-/** Returns the protocol message parameter.
- *  @param[in] call The message call structure.
- */
-#define IP_GET_PROTOCOL(call) \
-	({ip_protocol_t protocol = (ip_protocol_t) IPC_GET_ARG1(*call); protocol;})
-
-/*@}*/
-
-#endif
-
-/** @}
- */
Index: uspace/lib/net/include/ip_remote.h
===================================================================
--- uspace/lib/net/include/ip_remote.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/lib/net/include/ip_remote.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -34,11 +34,12 @@
 #define __NET_IP_REMOTE_H__
 
-#include <async.h>
 #include <ipc/services.h>
 
-#include <ip_codes.h>
-#include <inet.h>
-#include <in.h>
-#include <socket.h>
+#include <net/ip_codes.h>
+#include <net/inet.h>
+#include <net/in.h>
+#include <net/packet.h>
+#include <net/device.h>
+#include <net/socket.h>
 
 extern int ip_set_gateway_req_remote(int, device_id_t, in_addr_t);
Index: uspace/lib/net/include/net_checksum.h
===================================================================
--- uspace/lib/net/include/net_checksum.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/lib/net/include/net_checksum.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -27,84 +27,37 @@
  */
 
-/** @addtogroup net
- *  @{
+/** @addtogroup libnet
+ * @{
  */
 
 /** @file
- *  General CRC and checksum computation.
+ * General CRC and checksum computation.
  */
 
-#ifndef __NET_CHECKSUM_H__
-#define __NET_CHECKSUM_H__
+#ifndef LIBNET_CHECKSUM_H_
+#define LIBNET_CHECKSUM_H_
 
 #include <byteorder.h>
-
 #include <sys/types.h>
 
 /** IP checksum value for computed zero checksum.
- *  Zero is returned as 0xFFFF (not flipped)
+ * Zero is returned as 0xFFFF (not flipped)
  */
-#define IP_CHECKSUM_ZERO			0xFFFFu
+#define IP_CHECKSUM_ZERO	0xffffU
 
-/**	Computes CRC32 value.
- *  @param[in] seed Initial value. Often used as 0 or ~0.
- *  @param[in] data Pointer to the beginning of data to process.
- *  @param[in] length Length of the data in bits.
- *  @returns The computed CRC32 of the length bits of the data.
- */
 #ifdef ARCH_IS_BIG_ENDIAN
-	#define compute_crc32(seed, data, length)	compute_crc32_be(seed, (uint8_t *) data, length)
+#define compute_crc32(seed, data, length) \
+	compute_crc32_be(seed, (uint8_t *) data, length)
 #else
-	#define compute_crc32(seed, data, length)	compute_crc32_le(seed, (uint8_t *) data, length)
+#define compute_crc32(seed, data, length) \
+	compute_crc32_le(seed, (uint8_t *) data, length)
 #endif
 
-/**	Computes CRC32 value in the little-endian environment.
- *  @param[in] seed Initial value. Often used as 0 or ~0.
- *  @param[in] data Pointer to the beginning of data to process.
- *  @param[in] length Length of the data in bits.
- *  @returns The computed CRC32 of the length bits of the data.
- */
-extern uint32_t compute_crc32_le(uint32_t seed, uint8_t * data, size_t length);
-
-/**	Computes CRC32 value in the big-endian environment.
- *  @param[in] seed Initial value. Often used as 0 or ~0.
- *  @param[in] data Pointer to the beginning of data to process.
- *  @param[in] length Length of the data in bits.
- *  @returns The computed CRC32 of the length bits of the data.
- */
-extern uint32_t compute_crc32_be(uint32_t seed, uint8_t * data, size_t length);
-
-/** Computes sum of the 2 byte fields.
- *  Padds one zero (0) byte if odd.
- *  @param[in] seed Initial value. Often used as 0 or ~0.
- *  @param[in] data Pointer to the beginning of data to process.
- *  @param[in] length Length of the data in bytes.
- *  @returns The computed checksum of the length bytes of the data.
- */
-extern uint32_t compute_checksum(uint32_t seed, uint8_t * data, size_t length);
-
-/** Compacts the computed checksum to the 16 bit number adding the carries.
- *  @param[in] sum Computed checksum.
- *  @returns Compacted computed checksum to the 16 bits.
- */
-extern uint16_t compact_checksum(uint32_t sum);
-
-/** Returns or flips the checksum if zero.
- *  @param[in] checksum The computed checksum.
- *  @returns The internet protocol header checksum.
- *  @returns 0xFFFF if the computed checksum is zero.
- */
-extern uint16_t flip_checksum(uint16_t checksum);
-
-/** Computes the ip header checksum.
- *  To compute the checksum of a new packet, the checksum header field must be zero.
- *  To check the checksum of a received packet, the checksum may be left set.
- *  The zero (0) value will be returned in this case if valid.
- *  @param[in] data The header data.
- *  @param[in] length The header length in bytes.
- *  @returns The internet protocol header checksum.
- *  @returns 0xFFFF if the computed checksum is zero.
- */
-extern uint16_t ip_checksum(uint8_t * data, size_t length);
+extern uint32_t compute_crc32_le(uint32_t, uint8_t *, size_t);
+extern uint32_t compute_crc32_be(uint32_t, uint8_t *, size_t);
+extern uint32_t compute_checksum(uint32_t, uint8_t *, size_t);
+extern uint16_t compact_checksum(uint32_t);
+extern uint16_t flip_checksum(uint16_t);
+extern uint16_t ip_checksum(uint8_t *, size_t);
 
 #endif
Index: uspace/lib/net/include/net_interface.h
===================================================================
--- uspace/lib/net/include/net_interface.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/lib/net/include/net_interface.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -27,65 +27,26 @@
  */
 
-/** @addtogroup net
+/** @addtogroup libnet
  *  @{
  */
 
-#ifndef __NET_NET_INTERFACE_H__
-#define __NET_NET_INTERFACE_H__
+#ifndef LIBNET_NET_INTERFACE_H_
+#define LIBNET_NET_INTERFACE_H_
 
 #include <ipc/services.h>
 
-#include <net_device.h>
+#include <net/device.h>
 #include <adt/measured_strings.h>
 
 /** @name Networking module interface
- *  This interface is used by other modules.
+ * This interface is used by other modules.
  */
 /*@{*/
 
-/** Returns the device specific configuration.
- *  Returns the global configuration if the device specific is not found.
- *  The configuration names are read and the appropriate settings are set instead.
- *  Call net_free_settings() function to release the returned configuration.
- *  @param[in] net_phone The networking module phone.
- *  @param[in] device_id The device identifier.
- *  @param[in,out] configuration The requested device configuration. The names are read and the appropriate settings are set instead.
- *  @param[in] count The configuration entries count.
- *  @param[in,out] data The configuration and settings data.
- *  @returns EOK on success.
- *  @returns EINVAL if the configuration is NULL.
- *  @returns EINVAL if the count is zero (0).
- *  @returns Other error codes as defined for the generic_translate_req() function.
- */
-extern int net_get_device_conf_req(int net_phone, device_id_t device_id, measured_string_ref * configuration, size_t count, char ** data);
-
-/** Returns the global configuration.
- *  The configuration names are read and the appropriate settings are set instead.
- *  Call net_free_settings() function to release the returned configuration.
- *  @param[in] net_phone The networking module phone.
- *  @param[in,out] configuration The requested configuration. The names are read and the appropriate settings are set instead.
- *  @param[in] count The configuration entries count.
- *  @param[in,out] data The configuration and settings data.
- *  @returns EOK on success.
- *  @returns EINVAL if the configuration is NULL.
- *  @returns EINVAL if the count is zero (0).
- *  @returns Other error codes as defined for the generic_translate_req() function.
- */
-extern int net_get_conf_req(int net_phone, measured_string_ref * configuration, size_t count, char ** data);
-
-/** Frees the received settings.
- *  @param[in] settings The received settings.
- *  @param[in] data The received settings data.
- *  @see net_get_device_conf_req()
- *  @see net_get_conf_req()
- */
-extern void net_free_settings(measured_string_ref settings, char * data);
-
-/** Connects to the networking module.
- *  @param service The networking module service. Ignored parameter.
- *  @returns The networking module phone on success.
- *  @returns 0 if called by the bundle module.
- */
-extern int net_connect_module(services_t service);
+extern int net_get_device_conf_req(int, device_id_t, measured_string_ref *,
+    size_t, char **);
+extern int net_get_conf_req(int, measured_string_ref *, size_t, char **);
+extern void net_free_settings(measured_string_ref, char *);
+extern int net_connect_module(void);
 
 /*@}*/
Index: pace/lib/net/include/net_net_messages.h
===================================================================
--- uspace/lib/net/include/net_net_messages.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ 	(revision )
@@ -1,64 +1,0 @@
-/*
- * Copyright (c) 2009 Lukas Mejdrech
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (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 net
- *  @{
- */
-
-/** @file
- *  Networking subsystem central module messages.
- *  @see net_interface.h
- */
-
-#ifndef __NET_NET_MESSAGES_H__
-#define __NET_NET_MESSAGES_H__
-
-#include <ipc/ipc.h>
-
-#include <net_messages.h>
-
-/** Networking subsystem central module messages.
- */
-typedef enum{
-	/** Returns the general configuration
-	 *  @see net_get_conf_req()
-	 */
-	NET_NET_GET_CONF = NET_FIRST,
-	/** Returns the device specific configuration
-	 *  @see net_get_device_conf_req()
-	 */
-	NET_NET_GET_DEVICE_CONF,
-	/** Starts the networking stack.
-	 */
-	NET_NET_STARTUP,
-} net_messages;
-
-#endif
-
-/** @}
- */
Index: uspace/lib/net/include/netif_interface.h
===================================================================
--- uspace/lib/net/include/netif_interface.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/lib/net/include/netif_interface.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -34,24 +34,6 @@
 #define __NET_NETIF_INTERFACE_H__
 
-#ifdef CONFIG_NETIF_NIL_BUNDLE
-
-#include <netif_local.h>
-#include <netif_nil_bundle.h>
-#include <packet/packet_server.h>
-
-#define netif_module_message    netif_nil_module_message
-#define netif_module_start      netif_nil_module_start
-#define netif_get_addr_req      netif_get_addr_req_local
-#define netif_probe_req         netif_probe_req_local
-#define netif_send_msg          netif_send_msg_local
-#define netif_start_req         netif_start_req_local
-#define netif_stop_req          netif_stop_req_local
-#define netif_stats_req         netif_stats_req_local
-#define netif_bind_service      netif_bind_service_local
-
-#else /* CONFIG_NETIF_NIL_BUNDLE */
-
 #include <netif_remote.h>
-#include <packet/packet_client.h>
+#include <packet_client.h>
 
 #define netif_module_message    netif_module_message_standalone
@@ -65,6 +47,4 @@
 #define netif_bind_service      netif_bind_service_remote
 
-#endif /* CONFIG_NETIF_NIL_BUNDLE */
-
 #endif
 
Index: uspace/lib/net/include/netif_local.h
===================================================================
--- uspace/lib/net/include/netif_local.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/lib/net/include/netif_local.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -34,5 +34,4 @@
  * Network interface module skeleton.
  * The skeleton has to be part of each network interface module.
- * The skeleton can be also part of the module bundled with the network interface layer.
  */
 
@@ -44,9 +43,9 @@
 #include <ipc/ipc.h>
 #include <ipc/services.h>
+#include <err.h>
 
 #include <adt/measured_strings.h>
-#include <net_err.h>
-#include <net_device.h>
-#include <packet/packet.h>
+#include <net/device.h>
+#include <net/packet.h>
 
 /** Network interface device specific data.
Index: pace/lib/net/include/netif_messages.h
===================================================================
--- uspace/lib/net/include/netif_messages.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ 	(revision )
@@ -1,94 +1,0 @@
-/*
- * Copyright (c) 2009 Lukas Mejdrech
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (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 netif
- * @{
- */
-
-/** @file
- * Network interface common module messages.
- */
-
-#ifndef __NET_NETIF_MESSAGES_H__
-#define __NET_NETIF_MESSAGES_H__
-
-#include <ipc/ipc.h>
-
-#include <net_messages.h>
-
-/** Network interface common module messages.
- */
-typedef enum {
-	/** Probe device message.
-	 *  @see netif_probe_req()
-	 */
-	NET_NETIF_PROBE = NET_NETIF_FIRST,
-	/** Send packet message.
-	 *  @see netif_send_msg()
-	 */
-	NET_NETIF_SEND,
-	/** Start device message.
-	 *  @see netif_start_req()
-	 */
-	NET_NETIF_START,
-	/** Get device usage statistics message.
-	 *  @see netif_stats_req()
-	 */
-	NET_NETIF_STATS,
-	/** Stop device message.
-	 *  @see netif_stop_req()
-	 */
-	NET_NETIF_STOP,
-	/** Get device address message.
-	 *  @see netif_get_addr_req()
-	 */
-	NET_NETIF_GET_ADDR,
-} netif_messages;
-
-/** @name Network interface specific message parameters definitions
- */
-/*@{*/
-
-/** Return the interrupt number message parameter.
- * @param[in] call The message call structure.
- */
-#define NETIF_GET_IRQ(call) \
-	({int irq = (int) IPC_GET_ARG2(*call); irq;})
-
-/** Return the input/output address message parameter.
- * @param[in] call The message call structure.
- */
-#define NETIF_GET_IO(call) \
-	({int io = (int) IPC_GET_ARG3(*call); io;})
-
-/*@}*/
-
-#endif
-
-/** @}
- */
Index: pace/lib/net/include/netif_nil_bundle.h
===================================================================
--- uspace/lib/net/include/netif_nil_bundle.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ 	(revision )
@@ -1,46 +1,0 @@
-/*
- * Copyright (c) 2010 Martin Decky
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/** @addtogroup netif_standalone
- *  @{
- */
-
-#ifndef __NETIF_NIL_BUNDLE_H__
-#define __NETIF_NIL_BUNDLE_H__
-
-#include <ipc/ipc.h>
-#include <async.h>
-
-extern int netif_nil_module_message(const char *, ipc_callid_t, ipc_call_t *,
-    ipc_call_t *, int *);
-extern int netif_nil_module_start(async_client_conn_t);
-
-#endif
-
-/** @}
- */
Index: uspace/lib/net/include/netif_remote.h
===================================================================
--- uspace/lib/net/include/netif_remote.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/lib/net/include/netif_remote.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -34,7 +34,7 @@
 #define __NET_NETIF_REMOTE_H__
 
-#include <async.h>
-#include <fibril_synch.h>
-#include <ipc/ipc.h>
+#include <ipc/services.h>
+#include <adt/measured_strings.h>
+#include <net/device.h>
 
 extern int netif_get_addr_req_remote(int, device_id_t, measured_string_ref *,
Index: uspace/lib/net/include/nil_interface.h
===================================================================
--- uspace/lib/net/include/nil_interface.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/lib/net/include/nil_interface.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -38,10 +38,8 @@
 
 #include <ipc/ipc.h>
+#include <ipc/nil.h>
 
-#include <net_messages.h>
-#include <adt/measured_strings.h>
-#include <packet/packet.h>
-#include <nil_messages.h>
-#include <net_device.h>
+#include <generic.h>
+#include <nil_remote.h>
 
 #define nil_bind_service(service, device_id, me, receiver) \
@@ -67,22 +65,6 @@
 	    netif_service)
 
-
-#ifdef CONFIG_NETIF_NIL_BUNDLE
-
-#include <nil_local.h>
-#include <packet/packet_server.h>
-
-#define nil_device_state_msg  nil_device_state_msg_local
-#define nil_received_msg      nil_received_msg_local
-
-#else /* CONFIG_NETIF_NIL_BUNDLE */
-
-#include <nil_remote.h>
-#include <packet/packet_server.h>
-
 #define nil_device_state_msg  nil_device_state_msg_remote
 #define nil_received_msg      nil_received_msg_remote
-
-#endif /* CONFIG_NETIF_NIL_BUNDLE */
 
 #endif
Index: pace/lib/net/include/nil_messages.h
===================================================================
--- uspace/lib/net/include/nil_messages.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ 	(revision )
@@ -1,91 +1,0 @@
-/*
- * Copyright (c) 2009 Lukas Mejdrech
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (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 net_nil
- * @{
- */
-
-/** @file
- * Network interface layer module messages.
- */
-
-#ifndef __NET_NIL_MESSAGES_H__
-#define __NET_NIL_MESSAGES_H__
-
-#include <ipc/ipc.h>
-
-#include <net_messages.h>
-
-/** Network interface layer module messages.
- */
-typedef enum {
-	/** New device or update MTU message.
-	 *  @see nil_device_req()
-	 */
-	NET_NIL_DEVICE = NET_NIL_FIRST,
-	/** New device state message.
-	 *  @see nil_device_state_msg()
-	 */
-	NET_NIL_DEVICE_STATE,
-	/** Received packet queue message.
-	 *  @see nil_received_msg()
-	 */
-	NET_NIL_RECEIVED,
-	/** Send packet queue message.
-	 *  @see nil_send_msg()
-	 */
-	NET_NIL_SEND,
-	/** Packet size message.
-	 *  @see nil_packet_size_req()
-	 */
-	NET_NIL_PACKET_SPACE,
-	/** Device local hardware address message.
-	 *  @see nil_get_addr()
-	 */
-	NET_NIL_ADDR,
-	/** Device broadcast hardware address message.
-	 *  @see nil_get_broadcast_addr()
-	 */
-	NET_NIL_BROADCAST_ADDR,
-} nil_messages;
-
-/** @name Network interface layer specific message parameters definitions
- */
-/*@{*/
-
-/** Return the protocol service message parameter.
- */
-#define NIL_GET_PROTO(call) \
-	({services_t service = (services_t) IPC_GET_ARG2(*call); service;})
-
-/*@}*/
-
-#endif
-
-/** @}
- */
Index: uspace/lib/net/include/nil_remote.h
===================================================================
--- uspace/lib/net/include/nil_remote.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/lib/net/include/nil_remote.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -34,7 +34,7 @@
 #define __NET_NIL_REMOTE_H__
 
-#include <async.h>
-#include <fibril_synch.h>
-#include <ipc/ipc.h>
+#include <ipc/services.h>
+#include <net/device.h>
+#include <net/packet.h>
 
 extern int nil_device_state_msg_remote(int, device_id_t, int);
Index: uspace/lib/net/include/packet_client.h
===================================================================
--- uspace/lib/net/include/packet_client.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
+++ uspace/lib/net/include/packet_client.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -0,0 +1,117 @@
+/*
+ * Copyright (c) 2009 Lukas Mejdrech
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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 libnet
+ *  @{
+ */
+
+/** @file
+ * Packet client.
+ *
+ * To function correctly, initialization of the packet map by the pm_init()
+ * function has to happen at the first place. The module should not send the
+ * packet messages to the packet server but use the functions provided. The
+ * packet map should be released by the pm_destroy() function during the module
+ * termination. The packets and the packet queues can't be locked at all. The
+ * processing modules should process them sequentially - by passing the packets
+ * to the next module and stopping using the passed ones.
+ *
+ * @see packet.h
+ */
+
+#ifndef LIBNET_PACKET_CLIENT_H_
+#define LIBNET_PACKET_CLIENT_H_
+
+#include <net/packet.h>
+
+/** @name Packet client interface */
+/*@{*/
+
+/** Allocates the specified type right before the actual packet content and
+ * returns its pointer.
+ *
+ * The wrapper of the packet_prepend() function.
+ *
+ * @param[in] packet	The packet to be used.
+ * @param[in] type	The type to be allocated at the beginning of the packet
+ *			content.
+ * @returns		The typed pointer to the allocated memory.
+ * @returns		NULL if the packet is not valid.
+ * @returns		NULL if there is not enough memory left.
+ */
+#define PACKET_PREFIX(packet, type) \
+	(type *) packet_prefix((packet), sizeof(type))
+
+/** Allocates the specified type right after the actual packet content and
+ * returns its pointer.
+ *
+ * The wrapper of the packet_append() function.
+ *
+ * @param[in] packet	The packet to be used.
+ * @param[in] type	The type to be allocated at the end of the packet
+ *			content.
+ * @returns		The typed pointer to the allocated memory.
+ * @returns		NULL if the packet is not valid.
+ * @returns		NULL if there is not enough memory left.
+ */
+#define PACKET_SUFFIX(packet, type) \
+	(type *) packet_suffix((packet), sizeof(type))
+
+/** Trims the actual packet content by the specified prefix and suffix types.
+ *
+ * The wrapper of the packet_trim() function.
+ *
+ * @param[in] packet	The packet to be trimmed.
+ * @param[in] prefix	The type of the prefix to be removed from the beginning
+ *			of the packet content.
+ * @param[in] suffix	The type of the suffix to be removed from the end of
+ *			the packet content.
+ * @returns		EOK on success.
+ * @returns		EINVAL if the packet is not valid.
+ * @returns		ENOMEM if there is not enough memory left.
+ */
+#define PACKET_TRIM(packet, prefix, suffix) \
+	packet_trim((packet), sizeof(prefix), sizeof(suffix))
+
+extern void *packet_prefix(packet_t, size_t);
+extern void *packet_suffix(packet_t, size_t);
+extern int packet_trim(packet_t, size_t, size_t);
+extern int packet_copy_data(packet_t, const void *, size_t);
+extern packet_id_t packet_get_id(const packet_t);
+extern size_t packet_get_data_length(const packet_t);
+extern void *packet_get_data(const packet_t);
+extern int packet_get_addr(const packet_t, uint8_t **, uint8_t **);
+extern int packet_set_addr(packet_t, const uint8_t *, const uint8_t *, size_t);
+extern packet_t packet_get_copy(int phone, packet_t packet);
+
+/*@}*/
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/net/include/packet_remote.h
===================================================================
--- uspace/lib/net/include/packet_remote.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/lib/net/include/packet_remote.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -27,12 +27,13 @@
  */
 
-/** @addtogroup packet
+/** @addtogroup libnet
  * @{
  */
 
-#ifndef __NET_PACKET_REMOTE_H__
-#define __NET_PACKET_REMOTE_H__
+#ifndef LIBNET_PACKET_REMOTE_H_
+#define LIBNET_PACKET_REMOTE_H_
 
-#include <packet/packet.h>
+#include <net/packet.h>
+#include <sys/types.h>
 
 extern int packet_translate_remote(int, packet_ref, packet_id_t);
Index: uspace/lib/net/include/socket_core.h
===================================================================
--- uspace/lib/net/include/socket_core.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
+++ uspace/lib/net/include/socket_core.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -0,0 +1,139 @@
+/*
+ * Copyright (c) 2009 Lukas Mejdrech
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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 libnet 
+ *  @{
+ */
+
+/** @file
+ * Socket common core.
+ */
+
+#ifndef LIBNET_SOCKET_CORE_H_
+#define LIBNET_SOCKET_CORE_H_
+
+#include <sys/types.h>
+#include <adt/generic_char_map.h>
+#include <adt/dynamic_fifo.h>
+#include <adt/int_map.h>
+#include <net/in.h>
+#include <net/device.h>
+#include <net/packet.h>
+
+/** Initial size of the received packet queue. */
+#define SOCKET_INITIAL_RECEIVED_SIZE	4
+
+/** Maximum size of the received packet queue. */
+#define SOCKET_MAX_RECEIVED_SIZE	0
+
+/** Initial size of the sockets for acceptance queue. */
+#define SOCKET_INITIAL_ACCEPTED_SIZE	1
+
+/** Maximum size of the sockets for acceptance queue. */
+#define SOCKET_MAX_ACCEPTEDED_SIZE	0
+
+/** Listening sockets' port map key. */
+#define SOCKET_MAP_KEY_LISTENING	"L"
+
+/** Type definition of the socket core.
+ * @see socket_core
+ */
+typedef struct socket_core socket_core_t;
+
+/** Type definition of the socket core pointer.
+ * @see socket_core
+ */
+typedef socket_core_t *socket_core_ref;
+
+/** Type definition of the socket port.
+ * @see socket_port
+ */
+typedef struct socket_port socket_port_t;
+
+/** Type definition of the socket port pointer.
+ * @see socket_port
+ */
+typedef socket_port_t *socket_port_ref;
+
+/** Socket core. */
+struct socket_core {
+	/** Socket identifier. */
+	int socket_id;
+	/** Client application phone. */
+	int phone;
+	/** Bound port. */
+	int port;
+	/** Received packets queue. */
+	dyn_fifo_t received;
+	/** Sockets for acceptance queue. */
+	dyn_fifo_t accepted;
+	/** Protocol specific data. */
+	void *specific_data;
+	/** Socket ports map key. */
+	const char *key;
+	/** Length of the Socket ports map key. */
+	size_t key_length;
+};
+
+/** Sockets map.
+ * The key is the socket identifier.
+ */
+INT_MAP_DECLARE(socket_cores, socket_core_t);
+
+/** Bount port sockets map.
+ *
+ * The listening socket has the SOCKET_MAP_KEY_LISTENING key identifier whereas
+ * the other use the remote addresses.
+ */
+GENERIC_CHAR_MAP_DECLARE(socket_port_map, socket_core_ref);
+
+/** Ports map.
+ * The key is the port number.
+ */
+INT_MAP_DECLARE(socket_ports, socket_port_t);
+
+extern void socket_cores_release(int, socket_cores_ref, socket_ports_ref,
+    void (*)(socket_core_ref));
+extern int socket_bind(socket_cores_ref, socket_ports_ref, int, void *, size_t,
+    int, int, int);
+extern int socket_bind_free_port(socket_ports_ref, socket_core_ref, int, int,
+    int);
+extern int socket_create(socket_cores_ref, int, void *, int *);
+extern int socket_destroy(int, int, socket_cores_ref, socket_ports_ref,
+    void (*)(socket_core_ref));
+extern int socket_reply_packets(packet_t, size_t *);
+extern socket_core_ref socket_port_find(socket_ports_ref, int, const char *,
+    size_t);
+extern void socket_port_release(socket_ports_ref, socket_core_ref);
+extern int socket_port_add(socket_ports_ref, int, socket_core_ref,
+    const char *, size_t);
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/net/include/tl_common.h
===================================================================
--- uspace/lib/net/include/tl_common.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/lib/net/include/tl_common.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -38,8 +38,8 @@
 #define __NET_TL_COMMON_H__
 
-#include <packet/packet.h>
-#include <net_device.h>
-#include <inet.h>
-#include <socket_codes.h>
+#include <net/socket_codes.h>
+#include <net/packet.h>
+#include <net/device.h>
+#include <net/inet.h>
 
 /** Device packet dimensions.
Index: uspace/lib/net/include/tl_interface.h
===================================================================
--- uspace/lib/net/include/tl_interface.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/lib/net/include/tl_interface.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -40,10 +40,10 @@
 #include <async.h>
 #include <ipc/services.h>
+#include <ipc/tl.h>
 
-#include <net_messages.h>
-#include <net_device.h>
-#include <packet/packet.h>
-#include <packet/packet_client.h>
-#include <tl_messages.h>
+#include <generic.h>
+#include <net/device.h>
+#include <net/packet.h>
+#include <packet_client.h>
 
 /** @name Transport layer module interface
Index: pace/lib/net/include/tl_messages.h
===================================================================
--- uspace/lib/net/include/tl_messages.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ 	(revision )
@@ -1,57 +1,0 @@
-/*
- * Copyright (c) 2009 Lukas Mejdrech
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (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 net_tl
- *  @{
- */
-
-/** @file
- *  Transport layer modules messages.
- *  @see tl_interface.h
- */
-
-#ifndef __NET_TL_MESSAGES_H__
-#define __NET_TL_MESSAGES_H__
-
-#include <ipc/ipc.h>
-
-#include <net_messages.h>
-
-/** Transport layer modules messages.
- */
-typedef enum{
-	/** Packet received message.
-	 *  @see tl_received_msg()
-	 */
-	NET_TL_RECEIVED = NET_TL_FIRST
-} tl_messages;
-
-#endif
-
-/** @}
- */
Index: uspace/lib/net/netif/netif_local.c
===================================================================
--- uspace/lib/net/netif/netif_local.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/lib/net/netif/netif_local.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -42,17 +42,16 @@
 #include <ipc/ipc.h>
 #include <ipc/services.h>
-
-#include <net_err.h>
-#include <net_messages.h>
-#include <net_modules.h>
-#include <packet/packet.h>
-#include <packet/packet_client.h>
-#include <packet/packet_server.h>
+#include <ipc/netif.h>
+#include <err.h>
+
+#include <generic.h>
+#include <net/modules.h>
+#include <net/packet.h>
+#include <packet_client.h>
 #include <packet_remote.h>
 #include <adt/measured_strings.h>
-#include <net_device.h>
+#include <net/device.h>
 #include <nil_interface.h>
 #include <netif_local.h>
-#include <netif_messages.h>
 #include <netif_interface.h>
 
@@ -228,22 +227,4 @@
 	
 	return ERROR_CODE;
-}
-
-/** Create bidirectional connection with the network interface module and registers the message receiver.
- *
- * @param[in] service   The network interface module service.
- * @param[in] device_id The device identifier.
- * @param[in] me        The requesting module service.
- * @param[in] receiver  The message receiver.
- *
- * @return The phone of the needed service.
- * @return EOK on success.
- * @return Other error codes as defined for the bind_service() function.
- *
- */
-int netif_bind_service_local(services_t service, device_id_t device_id,
-    services_t me, async_client_conn_t receiver)
-{
-	return EOK;
 }
 
Index: pace/lib/net/netif/netif_nil_bundle.c
===================================================================
--- uspace/lib/net/netif/netif_nil_bundle.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ 	(revision )
@@ -1,105 +1,0 @@
-/*
- * Copyright (c) 2009 Lukas Mejdrech
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (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 netif
- *  @{
- */
-
-/** @file
- *  Wrapper for the bundled network interface and network interface layer module.
- *  Distributes messages and initializes both module parts.
- */
-
-#include <async.h>
-#include <ipc/ipc.h>
-
-#include <net_messages.h>
-#include <packet/packet.h>
-#include <netif_nil_bundle.h>
-#include <netif_local.h>
-#include <nil_local.h>
-
-/** Distribute the messages between the module parts.
- *
- * @param[in]  name         Module name.
- * @param[in]  callid       The message identifier.
- * @param[in]  call         The message parameters.
- * @param[out] answer       The message answer parameters.
- * @param[out] answer_count The last parameter for the actual
- *                          answer in the answer parameter.
- *
- * @return EOK on success.
- * @return ENOTSUP if the message is not known.
- * @return Other error codes as defined for each specific module message function.
- *
- */
-int netif_nil_module_message(const char *name, ipc_callid_t callid,
-    ipc_call_t *call, ipc_call_t *answer, int *answer_count)
-{
-	if ((IS_NET_NIL_MESSAGE(call))
-	    || (IPC_GET_METHOD(*call) == IPC_M_CONNECT_TO_ME))
-		return nil_message_standalone(name, callid, call, answer,
-		    answer_count);
-	else
-		return netif_module_message_standalone(name, callid, call, answer,
-		    answer_count);
-}
-
-/** Start the bundle network interface module.
- *
- * Initialize the client connection serving function, initialize
- * both module parts, register the module service and start the
- * async manager, processing IPC messages in an infinite loop.
- *
- * @param[in] client_connection The client connection processing
- *                              function. The module skeleton propagates
- *                              its own one.
- *
- * @return EOK on success.
- * @return Other error codes as defined for each specific module message
- *         function.
- *
- */
-int netif_nil_module_start(async_client_conn_t client_connection)
-{
-	ERROR_DECLARE;
-	
-	ERROR_PROPAGATE(netif_init_module(client_connection));
-	if (ERROR_OCCURRED(nil_initialize(netif_globals.net_phone))) {
-		pm_destroy();
-		return ERROR_CODE;
-	}
-	
-	async_manager();
-	
-	pm_destroy();
-	return EOK;
-}
-
-/** @}
- */
Index: uspace/lib/net/netif/netif_remote.c
===================================================================
--- uspace/lib/net/netif/netif_remote.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/lib/net/netif/netif_remote.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -36,12 +36,13 @@
 
 #include <ipc/services.h>
+#include <ipc/netif.h>
 
-#include <net_modules.h>
+#include <net/modules.h>
 #include <adt/measured_strings.h>
-#include <packet/packet.h>
-#include <packet/packet_client.h>
-#include <net_device.h>
+#include <net/packet.h>
+#include <packet_client.h>
+#include <net/device.h>
 #include <netif_remote.h>
-#include <netif_messages.h>
+#include <generic.h>
 
 int netif_get_addr_req_remote(int netif_phone, device_id_t device_id,
@@ -90,4 +91,17 @@
 }
 
+/** Create bidirectional connection with the network interface module and
+ * registers the message receiver.
+ *
+ * @param[in] service   The network interface module service.
+ * @param[in] device_id The device identifier.
+ * @param[in] me        The requesting module service.
+ * @param[in] receiver  The message receiver.
+ *
+ * @return The phone of the needed service.
+ * @return EOK on success.
+ * @return Other error codes as defined for the bind_service() function.
+ *
+ */
 int netif_bind_service_remote(services_t service, device_id_t device_id, services_t me,
     async_client_conn_t receiver)
Index: uspace/lib/net/nil/nil_remote.c
===================================================================
--- uspace/lib/net/nil/nil_remote.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/lib/net/nil/nil_remote.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -36,11 +36,12 @@
  */
 
-#include <net_messages.h>
-#include <net_device.h>
+#include <nil_remote.h>
 #include <nil_interface.h>
-#include <packet/packet.h>
-#include <packet/packet_client.h>
-#include <nil_messages.h>
-#include <nil_remote.h>
+#include <generic.h>
+#include <net/device.h>
+#include <net/packet.h>
+#include <packet_client.h>
+
+#include <ipc/nil.h>
 
 /** Notify the network interface layer about the device state change.
Index: uspace/lib/net/tl/icmp_client.c
===================================================================
--- uspace/lib/net/tl/icmp_client.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/lib/net/tl/icmp_client.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -43,8 +43,8 @@
 #include <sys/types.h>
 
-#include <icmp_codes.h>
+#include <net/icmp_codes.h>
 #include <icmp_client.h>
-#include <packet/packet.h>
-#include <packet/packet_client.h>
+#include <net/packet.h>
+#include <packet_client.h>
 #include <icmp_header.h>
 
Index: uspace/lib/net/tl/icmp_remote.c
===================================================================
--- uspace/lib/net/tl/icmp_remote.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/lib/net/tl/icmp_remote.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -40,11 +40,10 @@
 #include <ipc/ipc.h>
 #include <ipc/services.h>
+#include <ipc/icmp.h>
 #include <sys/types.h>
 
-#include <net_messages.h>
-#include <net_modules.h>
+#include <net/modules.h>
 #include <icmp_interface.h>
-#include <packet/packet_client.h>
-#include <icmp_messages.h>
+#include <packet_client.h>
 
 int icmp_destination_unreachable_msg(int icmp_phone, icmp_code_t code, icmp_param_t mtu, packet_t packet){
Index: uspace/lib/net/tl/tl_common.c
===================================================================
--- uspace/lib/net/tl/tl_common.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/lib/net/tl/tl_common.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -36,20 +36,19 @@
  */
 
+#include <net/socket_codes.h>
+#include <net/in.h>
+#include <net/in6.h>
+#include <net/inet.h>
 #include <async.h>
 #include <ipc/services.h>
-
-#include <net_err.h>
-#include <packet/packet.h>
-#include <packet/packet_client.h>
+#include <errno.h>
+#include <err.h>
+
+#include <net/packet.h>
+#include <packet_client.h>
 #include <packet_remote.h>
-#include <net_device.h>
+#include <net/device.h>
 #include <icmp_interface.h>
-#include <in.h>
-#include <in6.h>
-#include <inet.h>
-#include <ip_local.h>
 #include <ip_remote.h>
-#include <socket_codes.h>
-#include <socket_errno.h>
 #include <ip_interface.h>
 #include <tl_interface.h>
@@ -58,29 +57,32 @@
 DEVICE_MAP_IMPLEMENT(packet_dimensions, packet_dimension_t);
 
-int tl_get_address_port(const struct sockaddr * addr, int addrlen, uint16_t * port){
-	const struct sockaddr_in * address_in;
-	const struct sockaddr_in6 * address_in6;
-
-	if((addrlen <= 0) || ((size_t) addrlen < sizeof(struct sockaddr))){
-		return EINVAL;
-	}
-	switch(addr->sa_family){
-		case AF_INET:
-			if(addrlen != sizeof(struct sockaddr_in)){
+int
+tl_get_address_port(const struct sockaddr *addr, int addrlen, uint16_t *port)
+{
+	const struct sockaddr_in *address_in;
+	const struct sockaddr_in6 *address_in6;
+
+	if ((addrlen <= 0) || ((size_t) addrlen < sizeof(struct sockaddr)))
+		return EINVAL;
+
+	switch (addr->sa_family) {
+	case AF_INET:
+		if (addrlen != sizeof(struct sockaddr_in))
+			return EINVAL;
+
+		address_in = (struct sockaddr_in *) addr;
+		*port = ntohs(address_in->sin_port);
+		break;
+	case AF_INET6:
+		if (addrlen != sizeof(struct sockaddr_in6))
 				return EINVAL;
-			}
-			address_in = (struct sockaddr_in *) addr;
-			*port = ntohs(address_in->sin_port);
-			break;
-		case AF_INET6:
-			if(addrlen != sizeof(struct sockaddr_in6)){
-				return EINVAL;
-			}
-			address_in6 = (struct sockaddr_in6 *) addr;
-			*port = ntohs(address_in6->sin6_port);
-			break;
-		default:
-			return EAFNOSUPPORT;
-	}
+
+		address_in6 = (struct sockaddr_in6 *) addr;
+		*port = ntohs(address_in6->sin6_port);
+		break;
+	default:
+		return EAFNOSUPPORT;
+	}
+
 	return EOK;
 }
@@ -112,5 +114,6 @@
 		return EBADMEM;
 	
-	*packet_dimension = packet_dimensions_find(packet_dimensions, device_id);
+	*packet_dimension = packet_dimensions_find(packet_dimensions,
+	    device_id);
 	if (!*packet_dimension) {
 		/* Ask for and remember them if not found */
@@ -136,60 +139,69 @@
 }
 
-int tl_update_ip_packet_dimension(packet_dimensions_ref packet_dimensions, device_id_t device_id, size_t content){
+int
+tl_update_ip_packet_dimension(packet_dimensions_ref packet_dimensions,
+    device_id_t device_id, size_t content)
+{
 	packet_dimension_ref packet_dimension;
 
 	packet_dimension = packet_dimensions_find(packet_dimensions, device_id);
-	if(! packet_dimension){
+	if (!packet_dimension)
 		return ENOENT;
-	}
 	packet_dimension->content = content;
-	if(device_id != DEVICE_INVALID_ID){
-		packet_dimension = packet_dimensions_find(packet_dimensions, DEVICE_INVALID_ID);
-		if(packet_dimension){
-			if(packet_dimension->content >= content){
+
+	if (device_id != DEVICE_INVALID_ID) {
+		packet_dimension = packet_dimensions_find(packet_dimensions,
+		    DEVICE_INVALID_ID);
+
+		if (packet_dimension) {
+			if (packet_dimension->content >= content)
 				packet_dimension->content = content;
-			}else{
-				packet_dimensions_exclude(packet_dimensions, DEVICE_INVALID_ID);
-			}
+			else
+				packet_dimensions_exclude(packet_dimensions,
+				    DEVICE_INVALID_ID);
+
 		}
 	}
+
 	return EOK;
 }
 
-int tl_set_address_port(struct sockaddr * addr, int addrlen, uint16_t port){
-	struct sockaddr_in * address_in;
-	struct sockaddr_in6 * address_in6;
+int tl_set_address_port(struct sockaddr * addr, int addrlen, uint16_t port)
+{
+	struct sockaddr_in *address_in;
+	struct sockaddr_in6 *address_in6;
 	size_t length;
 
-	if(addrlen < 0){
-		return EINVAL;
-	}
+	if (addrlen < 0)
+		return EINVAL;
+	
 	length = (size_t) addrlen;
-	if(length < sizeof(struct sockaddr)){
-		return EINVAL;
-	}
-	switch(addr->sa_family){
-		case AF_INET:
-			if(length != sizeof(struct sockaddr_in)){
+	if (length < sizeof(struct sockaddr))
+		return EINVAL;
+
+	switch (addr->sa_family) {
+	case AF_INET:
+		if (length != sizeof(struct sockaddr_in))
+			return EINVAL;
+		address_in = (struct sockaddr_in *) addr;
+		address_in->sin_port = htons(port);
+		return EOK;
+	case AF_INET6:
+		if (length != sizeof(struct sockaddr_in6))
 				return EINVAL;
-			}
-			address_in = (struct sockaddr_in *) addr;
-			address_in->sin_port = htons(port);
-			return EOK;
-		case AF_INET6:
-			if(length != sizeof(struct sockaddr_in6)){
-				return EINVAL;
-			}
-			address_in6 = (struct sockaddr_in6 *) addr;
-			address_in6->sin6_port = htons(port);
-			return EOK;
-		default:
-			return EAFNOSUPPORT;
-	}
-}
-
-int tl_prepare_icmp_packet(int packet_phone, int icmp_phone, packet_t packet, services_t error){
+		address_in6 = (struct sockaddr_in6 *) addr;
+		address_in6->sin6_port = htons(port);
+		return EOK;
+	default:
+		return EAFNOSUPPORT;
+	}
+}
+
+int
+tl_prepare_icmp_packet(int packet_phone, int icmp_phone, packet_t packet,
+    services_t error)
+{
 	packet_t next;
-	uint8_t * src;
+	uint8_t *src;
 	int length;
 
@@ -200,17 +212,20 @@
 	
 	length = packet_get_addr(packet, &src, NULL);
-	if((length > 0)
-		&& (! error)
-		&& (icmp_phone >= 0)
-	// set both addresses to the source one (avoids the source address deletion before setting the destination one)
-		&& (packet_set_addr(packet, src, src, (size_t) length) == EOK)){
+	if ((length > 0) && (!error) && (icmp_phone >= 0) &&
+	    // set both addresses to the source one (avoids the source address
+	    // deletion before setting the destination one)
+	    (packet_set_addr(packet, src, src, (size_t) length) == EOK)) {
 		return EOK;
-	}else{
+	} else
 		pq_release_remote(packet_phone, packet_get_id(packet));
-	}
+
 	return ENOENT;
 }
 
-int tl_socket_read_packet_data(int packet_phone, packet_ref packet, size_t prefix, const packet_dimension_ref dimension, const struct sockaddr * addr, socklen_t addrlen){
+int
+tl_socket_read_packet_data(int packet_phone, packet_ref packet, size_t prefix,
+    const packet_dimension_ref dimension, const struct sockaddr *addr,
+    socklen_t addrlen)
+{
 	ERROR_DECLARE;
 
@@ -219,29 +234,33 @@
 	void * data;
 
-	if(! dimension){
-		return EINVAL;
-	}
+	if (!dimension)
+		return EINVAL;
+
 	// get the data length
-	if(! async_data_write_receive(&callid, &length)){
-		return EINVAL;
-	}
+	if (!async_data_write_receive(&callid, &length))
+		return EINVAL;
+
 	// get a new packet
-	*packet = packet_get_4_remote(packet_phone, length, dimension->addr_len, prefix + dimension->prefix, dimension->suffix);
-	if(! packet){
+	*packet = packet_get_4_remote(packet_phone, length, dimension->addr_len,
+	    prefix + dimension->prefix, dimension->suffix);
+	if (!packet)
 		return ENOMEM;
-	}
+
 	// allocate space in the packet
 	data = packet_suffix(*packet, length);
-	if(! data){
+	if (!data) {
 		pq_release_remote(packet_phone, packet_get_id(*packet));
 		return ENOMEM;
 	}
+
 	// read the data into the packet
-	if(ERROR_OCCURRED(async_data_write_finalize(callid, data, length))
-	// set the packet destination address
-		|| ERROR_OCCURRED(packet_set_addr(*packet, NULL, (uint8_t *) addr, addrlen))){
+	if (ERROR_OCCURRED(async_data_write_finalize(callid, data, length)) ||
+	    // set the packet destination address
+	    ERROR_OCCURRED(packet_set_addr(*packet, NULL, (uint8_t *) addr,
+	    addrlen))) {
 		pq_release_remote(packet_phone, packet_get_id(*packet));
 		return ERROR_CODE;
 	}
+
 	return (int) length;
 }
Index: uspace/lib/packet/Makefile
===================================================================
--- uspace/lib/packet/Makefile	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
+++ uspace/lib/packet/Makefile	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -0,0 +1,37 @@
+#
+# Copyright (c) 2005 Martin Decky
+# Copyright (c) 2007 Jakub Jermar
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# - Redistributions of source code must retain the above copyright
+#   notice, this list of conditions and the following disclaimer.
+# - Redistributions in binary form must reproduce the above copyright
+#   notice, this list of conditions and the following disclaimer in the
+#   documentation and/or other materials provided with the distribution.
+# - The name of the author may not be used to endorse or promote products
+#   derived from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+
+USPACE_PREFIX = ../..
+EXTRA_CFLAGS = -Iinclude
+LIBRARY = libpacket
+
+SOURCES = \
+	generic/packet_server.c
+
+include $(USPACE_PREFIX)/Makefile.common
Index: uspace/lib/packet/generic/packet_server.c
===================================================================
--- uspace/lib/packet/generic/packet_server.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
+++ uspace/lib/packet/generic/packet_server.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -0,0 +1,337 @@
+/*
+ * Copyright (c) 2009 Lukas Mejdrech
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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 packet
+ *  @{
+ */
+
+/** @file
+ *  Packet server implementation.
+ */
+
+#include <align.h>
+#include <assert.h>
+#include <async.h>
+#include <errno.h>
+#include <err.h>
+#include <fibril_synch.h>
+#include <unistd.h>
+#include <sys/mman.h>
+
+#include <ipc/ipc.h>
+#include <ipc/packet.h>
+#include <ipc/net.h>
+
+#include <net/packet.h>
+#include <net/packet_header.h>
+
+#include <packet_server.h>
+#include <packet_local.h>
+
+#define FREE_QUEUES_COUNT	7
+
+/** The default address length reserved for new packets.
+ */
+#define DEFAULT_ADDR_LEN	32
+
+/** The default prefix reserved for new packets.
+ */
+#define DEFAULT_PREFIX		64
+
+/** The default suffix reserved for new packets.
+ */
+#define DEFAULT_SUFFIX		64
+
+/** Packet server global data.
+ */
+static struct{
+	/** Safety lock.
+	 */
+	fibril_mutex_t lock;
+	/** Free packet queues.
+	 */
+	packet_t free[FREE_QUEUES_COUNT];
+	/** Packet length upper bounds of the free packet queues.
+	 *  The maximal lengths of packets in each queue in the ascending order.
+	 *  The last queue is not limited.
+	 */
+	size_t sizes[FREE_QUEUES_COUNT];
+	/** Total packets allocated.
+	 */
+	unsigned int count;
+} ps_globals = {
+	.lock = FIBRIL_MUTEX_INITIALIZER(ps_globals.lock),
+	.free = {NULL, NULL, NULL, NULL, NULL, NULL, NULL},
+	.sizes = {PAGE_SIZE, PAGE_SIZE * 2, PAGE_SIZE * 4, PAGE_SIZE * 8, PAGE_SIZE * 16, PAGE_SIZE * 32, PAGE_SIZE * 64},
+	.count = 0
+};
+
+int packet_translate_local(int phone, packet_ref packet, packet_id_t packet_id)
+{
+	if (!packet)
+		return EINVAL;
+	
+	*packet = pm_find(packet_id);
+	return (*packet) ? EOK : ENOENT;
+}
+
+/** Clears and initializes the packet according to the given dimensions.
+ *  @param[in] packet The packet to be initialized.
+ *  @param[in] addr_len The source and destination addresses maximal length in bytes.
+ *  @param[in] max_prefix The maximal prefix length in bytes.
+ *  @param[in] max_content The maximal content length in bytes.
+ *  @param[in] max_suffix The maximal suffix length in bytes.
+ */
+static void packet_init(packet_t packet, size_t addr_len, size_t max_prefix, size_t max_content, size_t max_suffix){
+	// clear the packet content
+	bzero(((void *) packet) + sizeof(struct packet), packet->length - sizeof(struct packet));
+	// clear the packet header
+	packet->order = 0;
+	packet->metric = 0;
+	packet->previous = 0;
+	packet->next = 0;
+	packet->addr_len = 0;
+	packet->src_addr = sizeof(struct packet);
+	packet->dest_addr = packet->src_addr + addr_len;
+	packet->max_prefix = max_prefix;
+	packet->max_content = max_content;
+	packet->data_start = packet->dest_addr + addr_len + packet->max_prefix;
+	packet->data_end = packet->data_start;
+}
+
+/** Creates a&nbsp;new packet of dimensions at least as given.
+ *  Should be used only when the global data are locked.
+ *  @param[in] length The total length of the packet, including the header, the addresses and the data of the packet.
+ *  @param[in] addr_len The source and destination addresses maximal length in bytes.
+ *  @param[in] max_prefix The maximal prefix length in bytes.
+ *  @param[in] max_content The maximal content length in bytes.
+ *  @param[in] max_suffix The maximal suffix length in bytes.
+ *  @returns The packet of dimensions at least as given.
+ *  @returns NULL if there is not enough memory left.
+ */
+static packet_t packet_create(size_t length, size_t addr_len, size_t max_prefix, size_t max_content, size_t max_suffix){
+	ERROR_DECLARE;
+
+	packet_t packet;
+
+	// already locked
+	packet = (packet_t) mmap(NULL, length, PROTO_READ | PROTO_WRITE, MAP_SHARED | MAP_ANONYMOUS, 0, 0);
+	if(packet == MAP_FAILED){
+		return NULL;
+	}
+	++ ps_globals.count;
+	packet->packet_id = ps_globals.count;
+	packet->length = length;
+	packet_init(packet, addr_len, max_prefix, max_content, max_suffix);
+	packet->magic_value = PACKET_MAGIC_VALUE;
+	if(ERROR_OCCURRED(pm_add(packet))){
+		munmap(packet, packet->length);
+		return NULL;
+	}
+	return packet;
+}
+
+/** Return the packet of dimensions at least as given.
+ *
+ * Try to reuse free packets first.
+ * Create a new packet aligned to the memory page size if none available.
+ * Lock the global data during its processing.
+ *
+ * @param[in] addr_len    The source and destination addresses
+ *                        maximal length in bytes.
+ * @param[in] max_prefix  The maximal prefix length in bytes.
+ * @param[in] max_content The maximal content length in bytes.
+ * @param[in] max_suffix  The maximal suffix length in bytes.
+ *
+ * @return The packet of dimensions at least as given.
+ * @return NULL if there is not enough memory left.
+ *
+ */
+static packet_t packet_get_local(size_t addr_len, size_t max_prefix,
+    size_t max_content, size_t max_suffix)
+{
+	size_t length = ALIGN_UP(sizeof(struct packet) + 2 * addr_len + max_prefix
+	    + max_content + max_suffix, PAGE_SIZE);
+	
+	fibril_mutex_lock(&ps_globals.lock);
+	
+	packet_t packet;
+	unsigned int index;
+	
+	for (index = 0; index < FREE_QUEUES_COUNT - 1; index++) {
+		if (length <= ps_globals.sizes[index]) {
+			packet = ps_globals.free[index];
+			
+			while (packet_is_valid(packet) && (packet->length < length))
+				packet = pm_find(packet->next);
+			
+			if (packet_is_valid(packet)) {
+				if (packet == ps_globals.free[index])
+					ps_globals.free[index] = pq_detach(packet);
+				else
+					pq_detach(packet);
+				
+				packet_init(packet, addr_len, max_prefix, max_content,
+				    max_suffix);
+				fibril_mutex_unlock(&ps_globals.lock);
+				
+				return packet;
+			}
+		}
+	}
+	
+	packet = packet_create(length, addr_len, max_prefix, max_content,
+	    max_suffix);
+	
+	fibril_mutex_unlock(&ps_globals.lock);
+	
+	return packet;
+}
+
+packet_t packet_get_4_local(int phone, size_t max_content, size_t addr_len,
+    size_t max_prefix, size_t max_suffix)
+{
+	return packet_get_local(addr_len, max_prefix, max_content, max_suffix);
+}
+
+packet_t packet_get_1_local(int phone, size_t content)
+{
+	return packet_get_local(DEFAULT_ADDR_LEN, DEFAULT_PREFIX, content,
+	    DEFAULT_SUFFIX);
+}
+
+/** Release the packet and returns it to the appropriate free packet queue.
+ *
+ *  Should be used only when the global data are locked.
+ *
+ *  @param[in] packet The packet to be released.
+ *
+ */
+static void packet_release(packet_t packet){
+	int index;
+	int result;
+
+	// remove debug dump
+//	printf("packet %d released\n", packet->packet_id);
+	for(index = 0; (index < FREE_QUEUES_COUNT - 1) && (packet->length > ps_globals.sizes[index]); ++ index);
+	result = pq_add(&ps_globals.free[index], packet, packet->length, packet->length);
+	assert(result == EOK);
+}
+
+/** Releases the packet queue.
+ *  @param[in] packet_id The first packet identifier.
+ *  @returns EOK on success.
+ *  @returns ENOENT if there is no such packet.
+ */
+static int packet_release_wrapper(packet_id_t packet_id){
+	packet_t packet;
+
+	packet = pm_find(packet_id);
+	if(! packet_is_valid(packet)){
+		return ENOENT;
+	}
+	fibril_mutex_lock(&ps_globals.lock);
+	pq_destroy(packet, packet_release);
+	fibril_mutex_unlock(&ps_globals.lock);
+	return EOK;
+}
+
+void pq_release_local(int phone, packet_id_t packet_id)
+{
+	(void) packet_release_wrapper(packet_id);
+}
+
+/** Shares the packet memory block.
+ *  @param[in] packet The packet to be shared.
+ *  @returns EOK on success.
+ *  @returns EINVAL if the packet is not valid.
+ *  @returns EINVAL if the calling module does not accept the memory.
+ *  @returns ENOMEM if the desired and actual sizes differ.
+ *  @returns Other error codes as defined for the async_share_in_finalize() function.
+ */
+static int packet_reply(const packet_t packet){
+	ipc_callid_t callid;
+	size_t size;
+
+	if(! packet_is_valid(packet)){
+		return EINVAL;
+	}
+	if(async_share_in_receive(&callid, &size) <= 0) return EINVAL;
+	if(size != packet->length){
+		return ENOMEM;
+	}
+	return async_share_in_finalize(callid, packet, PROTO_READ | PROTO_WRITE);
+}
+
+int packet_server_message(ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count){
+	packet_t packet;
+
+	*answer_count = 0;
+	switch(IPC_GET_METHOD(*call)){
+		case IPC_M_PHONE_HUNGUP:
+			return EOK;
+		case NET_PACKET_CREATE_1:
+			packet = packet_get_local(DEFAULT_ADDR_LEN, DEFAULT_PREFIX, IPC_GET_CONTENT(call), DEFAULT_SUFFIX);
+			if(! packet){
+				return ENOMEM;
+			}
+			*answer_count = 2;
+			IPC_SET_ARG1(*answer, (ipcarg_t) packet->packet_id);
+			IPC_SET_ARG2(*answer, (ipcarg_t) packet->length);
+			return EOK;
+		case NET_PACKET_CREATE_4:
+			packet = packet_get_local(((DEFAULT_ADDR_LEN < IPC_GET_ADDR_LEN(call)) ? IPC_GET_ADDR_LEN(call) : DEFAULT_ADDR_LEN), DEFAULT_PREFIX + IPC_GET_PREFIX(call), IPC_GET_CONTENT(call), DEFAULT_SUFFIX + IPC_GET_SUFFIX(call));
+			if(! packet){
+				return ENOMEM;
+			}
+			*answer_count = 2;
+			IPC_SET_ARG1(*answer, (ipcarg_t) packet->packet_id);
+			IPC_SET_ARG2(*answer, (ipcarg_t) packet->length);
+			return EOK;
+		case NET_PACKET_GET:
+			packet = pm_find(IPC_GET_ID(call));
+			if(! packet_is_valid(packet)){
+				return ENOENT;
+			}
+			return packet_reply(packet);
+		case NET_PACKET_GET_SIZE:
+			packet = pm_find(IPC_GET_ID(call));
+			if(! packet_is_valid(packet)){
+				return ENOENT;
+			}
+			IPC_SET_ARG1(*answer, (ipcarg_t) packet->length);
+			*answer_count = 1;
+			return EOK;
+		case NET_PACKET_RELEASE:
+			return packet_release_wrapper(IPC_GET_ID(call));
+	}
+	return ENOTSUP;
+}
+
+/** @}
+ */
Index: uspace/lib/packet/include/netdb.h
===================================================================
--- uspace/lib/packet/include/netdb.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
+++ uspace/lib/packet/include/netdb.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 2009 Lukas Mejdrech
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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 netdb
+ *  @{
+ */
+
+/** @file
+ *  Structures and interfaces according to the BSD netdb.h file.
+ */
+
+#ifndef __NET_NETDB_H__
+#define __NET_NETDB_H__
+
+#include <sys/types.h>
+
+/** Structure returned by network data base library.
+ *  All addresses are supplied in host order, and returned in network order (suitable for use in system calls).
+ */
+struct	hostent {
+	/** Official host name.
+	 */
+	char * h_name;
+	/** Alias list.
+	 */
+	char **	h_aliases;
+	/** Host address type.
+	 */
+	int h_addrtype;
+	/** Address length.
+	 */
+	int h_length;
+	/** List of addresses from name server.
+	 */
+	char **	h_addr_list;
+	/** Address, for backward compatiblity.
+	 */
+#define	h_addr	h_addr_list[0]
+};
+
+/** @name Host entry address types definitions.
+ */
+/*@{*/
+
+/** Authoritative Answer Host not found address type.
+ */
+#define	HOST_NOT_FOUND	1
+
+/** Non-Authoritive Host not found, or SERVERFAIL address type.
+ */
+#define	TRY_AGAIN	2
+
+/** Non recoverable errors, FORMERR, REFUSED, NOTIMP address type.
+ */
+#define	NO_RECOVERY	3
+
+/** Valid name, no data record of requested type address type.
+ */
+#define	NO_DATA		4
+
+/** No address, look for MX record address type.
+ */
+#define	NO_ADDRESS	NO_DATA
+
+/*@}*/
+
+/** Returns host entry by the host address.
+ *  @param[in] address The host address.
+ *  @param[in] len The address length.
+ *  @param[in] type The address type.
+ *  @returns Host entry information.
+ */
+//struct hostent *	gethostbyaddr(const void * address, int len, int type);
+
+/** Returns host entry by the host name.
+ *  @param[in] name The host name.
+ *  @returns Host entry information.
+ */
+//struct hostent *	gethostbyname(const char * name);
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/packet/include/packet_local.h
===================================================================
--- uspace/lib/packet/include/packet_local.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
+++ uspace/lib/packet/include/packet_local.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2009 Lukas Mejdrech
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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 packet
+ *  @{
+ */
+
+/** @file
+ */
+
+#ifndef __NET_PACKET_LOCAL_H__
+#define __NET_PACKET_LOCAL_H__
+
+#include <net/packet.h>
+
+/** @name Packet local interface
+ */
+/*@{*/
+
+extern int packet_translate_local(int, packet_ref, packet_id_t);
+extern packet_t packet_get_4_local(int, size_t, size_t, size_t, size_t);
+extern packet_t packet_get_1_local(int, size_t);
+extern void pq_release_local(int, packet_id_t);
+
+/*@}*/
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/packet/include/packet_server.h
===================================================================
--- uspace/lib/packet/include/packet_server.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
+++ uspace/lib/packet/include/packet_server.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2009 Lukas Mejdrech
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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 packet
+ *  @{
+ */
+
+/** @file
+ *  Packet server.
+ *  The hosting module has to be compiled with both the packet.c and the packet_server.c source files.
+ *  To function correctly, initialization of the packet map by the pm_init() function has to happen at the first place.
+ *  Then the packet messages have to be processed by the packet_server_message() function.
+ *  The packet map should be released by the pm_destroy() function during the module termination.
+ *  @see IS_NET_PACKET_MESSAGE()
+ */
+
+#ifndef __NET_PACKET_SERVER_H__
+#define __NET_PACKET_SERVER_H__
+
+#include <ipc/ipc.h>
+
+/** Processes the packet server message.
+ *  @param[in] callid The message identifier.
+ *  @param[in] call The message parameters.
+ *  @param[out] answer The message answer parameters.
+ *  @param[out] answer_count The last parameter for the actual answer in the answer parameter.
+ *  @returns EOK on success.
+ *  @returns ENOMEM if there is not enough memory left.
+ *  @returns ENOENT if there is no such packet as in the packet message parameter..
+ *  @returns ENOTSUP if the message is not known.
+ *  @returns Other error codes as defined for the packet_release_wrapper() function.
+ */
+extern int packet_server_message(ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count);
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/packet/include/tcp_codes.h
===================================================================
--- uspace/lib/packet/include/tcp_codes.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
+++ uspace/lib/packet/include/tcp_codes.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2009 Lukas Mejdrech
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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 options definitions.
+ */
+
+#ifndef __NET_TCP_CODES_H__
+#define __NET_TCP_CODES_H__
+
+/** End of list TCP option.
+ */
+#define TCPOPT_END_OF_LIST				0x0
+
+/** No operation TCP option.
+ */
+#define TCPOPT_NO_OPERATION				0x1
+
+/** Maximum segment size TCP option.
+ */
+#define TCPOPT_MAX_SEGMENT_SIZE			0x2
+
+/** Maximum segment size TCP option length.
+ */
+#define TCPOPT_MAX_SEGMENT_SIZE_LENGTH	4
+
+/** Window scale TCP option.
+ */
+#define TCPOPT_WINDOW_SCALE				0x3
+
+/** Window scale TCP option length.
+ */
+#define TCPOPT_WINDOW_SCALE_LENGTH		3
+
+/** Selective acknowledgement permitted TCP option.
+ */
+#define TCPOPT_SACK_PERMITTED			0x4
+
+/** Selective acknowledgement permitted TCP option length.
+ */
+#define TCPOPT_SACK_PERMITTED_LENGTH	2
+
+/** Selective acknowledgement TCP option.
+ *  Has variable length.
+ */
+#define TCPOPT_SACK						0x5
+
+/** Timestamp TCP option.
+ */
+#define TCPOPT_TIMESTAMP				0x8
+
+/** Timestamp TCP option length.
+ */
+#define TCPOPT_TIMESTAMP_LENGTH			10
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/pci/types.h
===================================================================
--- uspace/lib/pci/types.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/lib/pci/types.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -18,32 +18,45 @@
 
 #ifdef PCI_HAVE_64BIT_ADDRESS
-#include <limits.h>
+
+#include <stdint.h>
+
 #if ULONG_MAX > 0xffffffff
+
 typedef unsigned long u64;
 #define PCI_U64_FMT "l"
-#else
+
+#else /* ULONG_MAX > 0xffffffff */
+
 typedef unsigned long long u64;
 #define PCI_U64_FMT "ll"
-#endif
-#endif
 
-#endif				/* PCI_HAVE_Uxx_TYPES */
+#endif /* ULONG_MAX > 0xffffffff */
+#endif /* PCI_HAVE_64BIT_ADDRESS */
+#endif /* PCI_HAVE_Uxx_TYPES */
 
 #ifdef PCI_HAVE_64BIT_ADDRESS
+
 typedef u64 pciaddr_t;
 #define PCIADDR_T_FMT "%08" PCI_U64_FMT "x"
 #define PCIADDR_PORT_FMT "%04" PCI_U64_FMT "x"
-#else
+
+#else /* PCI_HAVE_64BIT_ADDRESS */
+
 typedef u32 pciaddr_t;
 #define PCIADDR_T_FMT "%08x"
 #define PCIADDR_PORT_FMT "%04x"
-#endif
+
+#endif /* PCI_HAVE_64BIT_ADDRESS */
 
 #ifdef PCI_ARCH_SPARC64
+
 /* On sparc64 Linux the kernel reports remapped port addresses and IRQ numbers */
 #undef PCIADDR_PORT_FMT
 #define PCIADDR_PORT_FMT PCIADDR_T_FMT
 #define PCIIRQ_FMT "%08x"
-#else
+
+#else /* PCI_ARCH_SPARC64 */
+
 #define PCIIRQ_FMT "%d"
-#endif
+
+#endif /* PCI_ARCH_SPARC64 */
Index: pace/lib/socket/Makefile
===================================================================
--- uspace/lib/socket/Makefile	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ 	(revision )
@@ -1,49 +1,0 @@
-#
-# Copyright (c) 2005 Martin Decky
-# Copyright (c) 2007 Jakub Jermar
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions
-# are met:
-#
-# - Redistributions of source code must retain the above copyright
-#   notice, this list of conditions and the following disclaimer.
-# - Redistributions in binary form must reproduce the above copyright
-#   notice, this list of conditions and the following disclaimer in the
-#   documentation and/or other materials provided with the distribution.
-# - The name of the author may not be used to endorse or promote products
-#   derived from this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
-# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
-# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
-# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
-# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
-# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-#
-
-USPACE_PREFIX = ../..
-EXTRA_CFLAGS = -Iinclude
-LIBRARY = libsocket
-
-SOURCES = \
-	generic/socket_client.c \
-	generic/socket_core.c \
-	generic/socket_parse.c \
-	generic/inet.c \
-	generic/net_modules.c \
-	generic/icmp_common.c \
-	generic/icmp_api.c \
-	packet/packet.c \
-	packet/packet_client.c \
-	packet/packet_server.c \
-	adt/dynamic_fifo.c \
-	adt/measured_strings.c \
-	adt/char_map.c
-
-include $(USPACE_PREFIX)/Makefile.common
Index: pace/lib/socket/adt/char_map.c
===================================================================
--- uspace/lib/socket/adt/char_map.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ 	(revision )
@@ -1,234 +1,0 @@
-/*
- * Copyright (c) 2009 Lukas Mejdrech
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (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 net
- *  @{
- */
-
-/** @file
- *  Character string to integer map implementation.
- *  @see char_map.h
- */
-
-#include <errno.h>
-#include <malloc.h>
-#include <mem.h>
-#include <unistd.h>
-
-#include <adt/char_map.h>
-
-/** Internal magic value for a&nbsp;consistency check.
- */
-#define CHAR_MAP_MAGIC_VALUE	0x12345611
-
-/** Adds the value with the key to the map.
- *  Creates new nodes to map the key.
- *  @param[in,out] map The character string to integer map.
- *  @param[in] identifier The key zero ('\\0') terminated character string. The key character string is processed until the first terminating zero ('\\0') character after the given length is found.
- *  @param[in] length The key character string length. The parameter may be zero (0) which means that the string is processed until the terminating zero ('\\0') character is found.
- *  @param[in] value The integral value to be stored for the key character string.
- *  @returns EOK on success.
- *  @returns ENOMEM if there is not enough memory left.
- *  @returns EEXIST if the key character string is already used.
- */
-int char_map_add_item(char_map_ref map, const char * identifier, size_t length, const int value);
-
-/** Returns the node assigned to the key from the map.
- *  @param[in] map The character string to integer map.
- *  @param[in] identifier The key zero ('\\0') terminated character string. The key character string is processed until the first terminating zero ('\\0') character after the given length is found.
- *  @param[in] length The key character string length. The parameter may be zero (0) which means that the string is processed until the terminating zero ('\\0') character is found.
- *  @returns The node holding the integral value assigned to the key character string.
- *  @returns NULL if the key is not assigned a&nbsp;node.
- */
-char_map_ref char_map_find_node(const char_map_ref map, const char * identifier, const size_t length);
-
-/** Returns the value assigned to the map.
- *  @param[in] map The character string to integer map.
- *  @returns The integral value assigned to the map.
- *  @returns CHAR_MAP_NULL if the map is not assigned a&nbsp;value.
- */
-int char_map_get_value(const char_map_ref map);
-
-/** Checks if the map is valid.
- *  @param[in] map The character string to integer map.
- *  @returns TRUE if the map is valid.
- *  @returns FALSE otherwise.
- */
-int char_map_is_valid(const char_map_ref map);
-
-int char_map_add(char_map_ref map, const char * identifier, size_t length, const int value){
-	if(char_map_is_valid(map) && (identifier) && ((length) || (*identifier))){
-		int index;
-
-		for(index = 0; index < map->next; ++ index){
-			if(map->items[index]->c == * identifier){
-				++ identifier;
-				if((length > 1) || ((length == 0) && (*identifier))){
-					return char_map_add(map->items[index], identifier, length ? length - 1 : 0, value);
-				}else{
-					if(map->items[index]->value != CHAR_MAP_NULL){
-						return EEXISTS;
-					}
-					map->items[index]->value = value;
-					return EOK;
-				}
-			}
-		}
-		return char_map_add_item(map, identifier, length, value);
-	}
-	return EINVAL;
-}
-
-int char_map_add_item(char_map_ref map, const char * identifier, size_t length, const int value){
-	if(map->next == (map->size - 1)){
-		char_map_ref *tmp;
-
-		tmp = (char_map_ref *) realloc(map->items, sizeof(char_map_ref) * 2 * map->size);
-		if(! tmp){
-			return ENOMEM;
-		}
-		map->size *= 2;
-		map->items = tmp;
-	}
-	map->items[map->next] = (char_map_ref) malloc(sizeof(char_map_t));
-	if(! map->items[map->next]){
-		return ENOMEM;
-	}
-	if(char_map_initialize(map->items[map->next]) != EOK){
-		free(map->items[map->next]);
-		map->items[map->next] = NULL;
-		return ENOMEM;
-	}
-	map->items[map->next]->c = * identifier;
-	++ identifier;
-	++ map->next;
-	if((length > 1) || ((length == 0) && (*identifier))){
-		map->items[map->next - 1]->value = CHAR_MAP_NULL;
-		return char_map_add_item(map->items[map->next - 1], identifier, length ? length - 1 : 0, value);
-	}else{
-		map->items[map->next - 1]->value = value;
-	}
-	return EOK;
-}
-
-void char_map_destroy(char_map_ref map){
-	if(char_map_is_valid(map)){
-		int index;
-
-		map->magic = 0;
-		for(index = 0; index < map->next; ++ index){
-			char_map_destroy(map->items[index]);
-		}
-		free(map->items);
-		map->items = NULL;
-	}
-}
-
-int char_map_exclude(char_map_ref map, const char * identifier, size_t length){
-	char_map_ref node;
-
-	node = char_map_find_node(map, identifier, length);
-	if(node){
-		int value;
-
-		value = node->value;
-		node->value = CHAR_MAP_NULL;
-		return value;
-	}
-	return CHAR_MAP_NULL;
-}
-
-int char_map_find(const char_map_ref map, const char * identifier, size_t length){
-	char_map_ref node;
-
-	node = char_map_find_node(map, identifier, length);
-	return node ? node->value : CHAR_MAP_NULL;
-}
-
-char_map_ref char_map_find_node(const char_map_ref map, const char * identifier, size_t length){
-	if(! char_map_is_valid(map)){
-		return NULL;
-	}
-	if(length || (*identifier)){
-		int index;
-
-		for(index = 0; index < map->next; ++ index){
-			if(map->items[index]->c == * identifier){
-				++ identifier;
-				if(length == 1){
-					return map->items[index];
-				}
-				return char_map_find_node(map->items[index], identifier, length ? length - 1 : 0);
-			}
-		}
-		return NULL;
-	}
-	return map;
-}
-
-int char_map_get_value(const char_map_ref map){
-	return char_map_is_valid(map) ? map->value : CHAR_MAP_NULL;
-}
-
-int char_map_initialize(char_map_ref map){
-	if(! map){
-		return EINVAL;
-	}
-	map->c = '\0';
-	map->value = CHAR_MAP_NULL;
-	map->size = 2;
-	map->next = 0;
-	map->items = malloc(sizeof(char_map_ref) * map->size);
-	if(! map->items){
-		map->magic = 0;
-		return ENOMEM;
-	}
-	map->items[map->next] = NULL;
-	map->magic = CHAR_MAP_MAGIC_VALUE;
-	return EOK;
-}
-
-int char_map_is_valid(const char_map_ref map){
-	return map && (map->magic == CHAR_MAP_MAGIC_VALUE);
-}
-
-int char_map_update(char_map_ref map, const char * identifier, const size_t length, const int value){
-	char_map_ref node;
-
-//	if(! char_map_is_valid(map)) return EINVAL;
-	node = char_map_find_node(map, identifier, length);
-	if(node){
-		node->value = value;
-		return EOK;
-	}else{
-		return char_map_add(map, identifier, length, value);
-	}
-}
-
-/** @}
- */
Index: pace/lib/socket/adt/dynamic_fifo.c
===================================================================
--- uspace/lib/socket/adt/dynamic_fifo.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ 	(revision )
@@ -1,151 +1,0 @@
-/*
- * Copyright (c) 2009 Lukas Mejdrech
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (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 net
- *  @{
- */
-
-/** @file
- *  Dynamic first in first out positive integer queue implementation.
- */
-
-#include <errno.h>
-#include <malloc.h>
-#include <mem.h>
-
-#include <adt/dynamic_fifo.h>
-
-/** Internal magic value for a&nbsp;consistency check.
- */
-#define DYN_FIFO_MAGIC_VALUE	0x58627659
-
-/** Returns the next queue index.
- *  The queue field is circular.
- *  @param[in] fifo The dynamic queue.
- *  @param[in] index The actual index to be shifted.
- */
-#define NEXT_INDEX(fifo, index)	(((index) + 1) % ((fifo)->size + 1))
-
-/** Checks if the queue is valid.
- *  @param[in] fifo The dynamic queue.
- *  @returns TRUE if the queue is valid.
- *  @returns FALSE otherwise.
- */
-static int dyn_fifo_is_valid(dyn_fifo_ref fifo){
-	return fifo && (fifo->magic_value == DYN_FIFO_MAGIC_VALUE);
-}
-
-int dyn_fifo_initialize(dyn_fifo_ref fifo, int size){
-	if(! fifo){
-		return EBADMEM;
-	}
-	if(size <= 0){
-		return EINVAL;
-	}
-	fifo->items = (int *) malloc(sizeof(int) * size + 1);
-	if(! fifo->items){
-		return ENOMEM;
-	}
-	fifo->size = size;
-	fifo->head = 0;
-	fifo->tail = 0;
-	fifo->magic_value = DYN_FIFO_MAGIC_VALUE;
-	return EOK;
-}
-
-int dyn_fifo_push(dyn_fifo_ref fifo, int value, int max_size){
-	int * new_items;
-
-	if(! dyn_fifo_is_valid(fifo)){
-		return EINVAL;
-	}
-	if(NEXT_INDEX(fifo, fifo->tail) == fifo->head){
-		if((max_size > 0) && ((fifo->size * 2) > max_size)){
-			if(fifo->size >= max_size){
-				return ENOMEM;
-			}
-		}else{
-			max_size = fifo->size * 2;
-		}
-		new_items = realloc(fifo->items, sizeof(int) * max_size + 1);
-		if(! new_items){
-			return ENOMEM;
-		}
-		fifo->items = new_items;
-		if(fifo->tail < fifo->head){
-			if(fifo->tail < max_size - fifo->size){
-				memcpy(fifo->items + fifo->size + 1, fifo->items, fifo->tail * sizeof(int));
-				fifo->tail += fifo->size + 1;
-			}else{
-				memcpy(fifo->items + fifo->size + 1, fifo->items, (max_size - fifo->size) * sizeof(int));
-				memcpy(fifo->items, fifo->items + max_size - fifo->size, fifo->tail - max_size + fifo->size);
-				fifo->tail -= max_size - fifo->size;
-			}
-		}
-		fifo->size = max_size;
-	}
-	fifo->items[fifo->tail] = value;
-	fifo->tail = NEXT_INDEX(fifo, fifo->tail);
-	return EOK;
-}
-
-int dyn_fifo_pop(dyn_fifo_ref fifo){
-	int value;
-
-	if(! dyn_fifo_is_valid(fifo)){
-		return EINVAL;
-	}
-	if(fifo->head == fifo->tail){
-		return ENOENT;
-	}
-	value = fifo->items[fifo->head];
-	fifo->head = NEXT_INDEX(fifo, fifo->head);
-	return value;
-}
-
-int dyn_fifo_value(dyn_fifo_ref fifo){
-	if(! dyn_fifo_is_valid(fifo)){
-		return EINVAL;
-	}
-	if(fifo->head == fifo->tail){
-		return ENOENT;
-	}
-	return fifo->items[fifo->head];
-}
-
-int dyn_fifo_destroy(dyn_fifo_ref fifo){
-	if(! dyn_fifo_is_valid(fifo)){
-		return EINVAL;
-	}
-	free(fifo->items);
-	fifo->magic_value = 0;
-	return EOK;
-}
-
-/** @}
- */
Index: pace/lib/socket/adt/measured_strings.c
===================================================================
--- uspace/lib/socket/adt/measured_strings.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ 	(revision )
@@ -1,284 +1,0 @@
-/*
- * Copyright (c) 2009 Lukas Mejdrech
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (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 net
- *  @{
- */
-
-/** @file
- *  Character string with measured length implementation.
- *  @see measured_strings.h
- */
-
-#include <errno.h>
-#include <malloc.h>
-#include <mem.h>
-#include <unistd.h>
-
-#include <ipc/ipc.h>
-
-#include <net_err.h>
-#include <net_modules.h>
-#include <adt/measured_strings.h>
-
-measured_string_ref measured_string_create_bulk(const char * string, size_t length){
-	measured_string_ref new;
-
-	if(length == 0){
-		while(string[length]){
-			++ length;
-		}
-	}
-	new = (measured_string_ref) malloc(sizeof(measured_string_t) + (sizeof(char) * (length + 1)));
-	if(! new){
-		return NULL;
-	}
-	new->length = length;
-	new->value = ((char *) new) + sizeof(measured_string_t);
-	// append terminating zero explicitly - to be safe
-	memcpy(new->value, string, new->length);
-	new->value[new->length] = '\0';
-	return new;
-}
-
-measured_string_ref measured_string_copy(measured_string_ref source){
-	measured_string_ref new;
-
-	if(! source){
-		return NULL;
-	}
-	new = (measured_string_ref) malloc(sizeof(measured_string_t));
-	if(new){
-		new->value = (char *) malloc(source->length + 1);
-		if(new->value){
-			new->length = source->length;
-			memcpy(new->value, source->value, new->length);
-			new->value[new->length] = '\0';
-			return new;
-		}else{
-			free(new);
-		}
-	}
-	return NULL;
-}
-
-int measured_strings_receive(measured_string_ref * strings, char ** data, size_t count){
-	ERROR_DECLARE;
-
-	size_t * lengths;
-	size_t index;
-	size_t length;
-	char * next;
-	ipc_callid_t callid;
-
-	if((! strings) || (! data) || (count <= 0)){
-		return EINVAL;
-	}
-	lengths = (size_t *) malloc(sizeof(size_t) * (count + 1));
-	if(! lengths){
-		return ENOMEM;
-	}
-	if((! async_data_write_receive(&callid, &length))
-		|| (length != sizeof(size_t) * (count + 1))){
-		free(lengths);
-		return EINVAL;
-	}
-	if(ERROR_OCCURRED(async_data_write_finalize(callid, lengths, sizeof(size_t) * (count + 1)))){
-		free(lengths);
-		return ERROR_CODE;
-	}
-	*data = malloc(lengths[count]);
-	if(!(*data)){
-		return ENOMEM;
-	}
-	(*data)[lengths[count] - 1] = '\0';
-	*strings = (measured_string_ref) malloc(sizeof(measured_string_t) * count);
-	if(!(*strings)){
-		free(lengths);
-		free(*data);
-		return ENOMEM;
-	}
-	next = * data;
-	for(index = 0; index < count; ++ index){
-		(*strings)[index].length = lengths[index];
-		if(lengths[index] > 0){
-			if((! async_data_write_receive(&callid, &length))
-				|| (length != lengths[index])){
-				free(*data);
-				free(*strings);
-				free(lengths);
-				return EINVAL;
-			}
-			ERROR_PROPAGATE(async_data_write_finalize(callid, next, lengths[index]));
-			(*strings)[index].value = next;
-			next += lengths[index];
-			*next = '\0';
-			++ next;
-		}else{
-			(*strings)[index].value = NULL;
-		}
-	}
-	free(lengths);
-	return EOK;
-}
-
-/** Computes the lengths of the measured strings in the given array.
- *  @param[in] strings The measured strings array to be processed.
- *  @param[in] count The measured strings array size.
- *  @returns The computed sizes array.
- *  @returns NULL if there is not enough memory left.
- */
-static size_t * prepare_lengths(const measured_string_ref strings, size_t count){
-	size_t * lengths;
-	size_t index;
-	size_t length;
-
-	lengths = (size_t *) malloc(sizeof(size_t) * (count + 1));
-	if(! lengths){
-		return NULL;
-	}
-	length = 0;
-	for(index = 0; index < count; ++ index){
-		lengths[index] = strings[index].length;
-		length += lengths[index] + 1;
-	}
-	lengths[count] = length;
-	return lengths;
-}
-
-int measured_strings_reply(const measured_string_ref strings, size_t count){
-	ERROR_DECLARE;
-
-	size_t * lengths;
-	size_t index;
-	size_t length;
-	ipc_callid_t callid;
-
-	if((! strings) || (count <= 0)){
-		return EINVAL;
-	}
-	lengths = prepare_lengths(strings, count);
-	if(! lengths){
-		return ENOMEM;
-	}
-	if((! async_data_read_receive(&callid, &length))
-		|| (length != sizeof(size_t) * (count + 1))){
-		free(lengths);
-		return EINVAL;
-	}
-	if(ERROR_OCCURRED(async_data_read_finalize(callid, lengths, sizeof(size_t) * (count + 1)))){
-		free(lengths);
-		return ERROR_CODE;
-	}
-	free(lengths);
-	for(index = 0; index < count; ++ index){
-		if(strings[index].length > 0){
-			if((! async_data_read_receive(&callid, &length))
-				|| (length != strings[index].length)){
-				return EINVAL;
-			}
-			ERROR_PROPAGATE(async_data_read_finalize(callid, strings[index].value, strings[index].length));
-		}
-	}
-	return EOK;
-}
-
-int measured_strings_return(int phone, measured_string_ref * strings, char ** data, size_t count){
-	ERROR_DECLARE;
-
-	size_t * lengths;
-	size_t index;
-	char * next;
-
-	if((phone <= 0) || (! strings) || (! data) || (count <= 0)){
-		return EINVAL;
-	}
-	lengths = (size_t *) malloc(sizeof(size_t) * (count + 1));
-	if(! lengths){
-		return ENOMEM;
-	}
-	if(ERROR_OCCURRED(async_data_read_start(phone, lengths, sizeof(size_t) * (count + 1)))){
-		free(lengths);
-		return ERROR_CODE;
-	}
-	*data = malloc(lengths[count]);
-	if(!(*data)){
-		return ENOMEM;
-	}
-	*strings = (measured_string_ref) malloc(sizeof(measured_string_t) * count);
-	if(!(*strings)){
-		free(lengths);
-		free(*data);
-		return ENOMEM;
-	}
-	next = * data;
-	for(index = 0; index < count; ++ index){
-		(*strings)[index].length = lengths[index];
-		if(lengths[index] > 0){
-			ERROR_PROPAGATE(async_data_read_start(phone, next, lengths[index]));
-			(*strings)[index].value = next;
-			next += lengths[index];
-			*next = '\0';
-			++ next;
-		}else{
-			(*strings)[index].value = NULL;
-		}
-	}
-	free(lengths);
-	return EOK;
-}
-
-int measured_strings_send(int phone, const measured_string_ref strings, size_t count){
-	ERROR_DECLARE;
-
-	size_t * lengths;
-	size_t index;
-
-	if((phone <= 0) || (! strings) || (count <= 0)){
-		return EINVAL;
-	}
-	lengths = prepare_lengths(strings, count);
-	if(! lengths){
-		return ENOMEM;
-	}
-	if(ERROR_OCCURRED(async_data_write_start(phone, lengths, sizeof(size_t) * (count + 1)))){
-		free(lengths);
-		return ERROR_CODE;
-	}
-	free(lengths);
-	for(index = 0; index < count; ++ index){
-		if(strings[index].length > 0){
-			ERROR_PROPAGATE(async_data_write_start(phone, strings[index].value, strings[index].length));
-		}
-	}
-	return EOK;
-}
-
-/** @}
- */
-
Index: pace/lib/socket/generic/icmp_api.c
===================================================================
--- uspace/lib/socket/generic/icmp_api.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ 	(revision )
@@ -1,69 +1,0 @@
-/*
- * Copyright (c) 2009 Lukas Mejdrech
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (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 icmp
- *  @{
- */
-
-/** @file
- *  ICMP application interface implementation.
- *  @see icmp_api.h
- */
-
-#include <async.h>
-
-#include <ipc/ipc.h>
-#include <ipc/services.h>
-
-#include <sys/types.h>
-
-#include <net_modules.h>
-#include <icmp_api.h>
-#include <inet.h>
-#include <ip_codes.h>
-#include <socket_codes.h>
-#include <icmp_messages.h>
-
-int icmp_echo_msg(int icmp_phone, size_t size, mseconds_t timeout, ip_ttl_t ttl, ip_tos_t tos, int dont_fragment, const struct sockaddr * addr, socklen_t addrlen){
-	aid_t message_id;
-	ipcarg_t result;
-
-	if(addrlen <= 0){
-		return EINVAL;
-	}
-	message_id = async_send_5(icmp_phone, NET_ICMP_ECHO, size, timeout, ttl, tos, (ipcarg_t) dont_fragment, NULL);
-	// send the address
-	async_data_write_start(icmp_phone, addr, (size_t) addrlen);
-	// timeout version may cause inconsistency - there is also an inner timer
-	// return async_wait_timeout(message_id, &result, timeout);
-	async_wait_for(message_id, &result);
-	return (int) result;
-}
-
-/** @}
- */
Index: pace/lib/socket/generic/icmp_common.c
===================================================================
--- uspace/lib/socket/generic/icmp_common.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ 	(revision )
@@ -1,56 +1,0 @@
-/*
- * Copyright (c) 2009 Lukas Mejdrech
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (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 icmp
- *  @{
- */
-
-/** @file
- *  ICMP common interface implementation.
- *  @see icmp_common.h
- */
-
-#include <async.h>
-#include <ipc/services.h>
-
-#include <net_modules.h>
-#include <icmp_common.h>
-#include <icmp_messages.h>
-
-int icmp_connect_module(services_t service, suseconds_t timeout){
-	int phone;
-
-	phone = connect_to_service_timeout(SERVICE_ICMP, timeout);
-	if(phone >= 0){
-		async_req_0_0(phone, NET_ICMP_INIT);
-	}
-	return phone;
-}
-
-/** @}
- */
Index: pace/lib/socket/generic/inet.c
===================================================================
--- uspace/lib/socket/generic/inet.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ 	(revision )
@@ -1,156 +1,0 @@
-/*
- * Copyright (c) 2009 Lukas Mejdrech
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (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 net
- *  @{
- */
-
-/** @file
- *  Internet protocol address conversion functions implementation.
- */
-
-#include <errno.h>
-#include <mem.h>
-#include <stdio.h>
-#include <str.h>
-
-#include <in.h>
-#include <in6.h>
-#include <inet.h>
-#include <socket_codes.h>
-
-int inet_ntop(uint16_t family, const uint8_t * data, char * address, size_t length){
-	if((! data) || (! address)){
-		return EINVAL;
-	}
-
-	switch(family){
-		case AF_INET:
-			// check the output buffer size
-			if(length < INET_ADDRSTRLEN){
-				return ENOMEM;
-			}
-			// fill the buffer with the IPv4 address
-			snprintf(address, length, "%hhu.%hhu.%hhu.%hhu", data[0], data[1], data[2], data[3]);
-			return EOK;
-		case AF_INET6:
-			// check the output buffer size
-			if(length < INET6_ADDRSTRLEN){
-				return ENOMEM;
-			}
-			// fill the buffer with the IPv6 address
-			snprintf(address, length, "%hhx%hhx:%hhx%hhx:%hhx%hhx:%hhx%hhx:%hhx%hhx:%hhx%hhx:%hhx%hhx:%hhx%hhx", data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7], data[8], data[9], data[10], data[11], data[12], data[13], data[14], data[15]);
-			return EOK;
-		default:
-			return ENOTSUP;
-	}
-}
-
-int inet_pton(uint16_t family, const char * address, uint8_t * data){
-	/** The base number of the values.
-	 */
-	int base;
-	/** The number of bytes per a section.
-	 */
-	size_t bytes;
-	/** The number of bytes of the address data.
-	 */
-	int count;
-
-	const char * next;
-	char * last;
-	int index;
-	size_t shift;
-	unsigned long value;
-
-	if(! data){
-		return EINVAL;
-	}
-
-	// set the processing parameters
-	switch(family){
-		case AF_INET:
-			count = 4;
-			base = 10;
-			bytes = 1;
-			break;
-		case AF_INET6:
-			count = 16;
-			base = 16;
-			bytes = 4;
-			break;
-		default:
-			return ENOTSUP;
-	}
-
-	// erase if no address
-	if(! address){
-		bzero(data, count);
-		return ENOENT;
-	}
-
-	// process the string from the beginning
-	next = address;
-	index = 0;
-	do{
-		// if the actual character is set
-		if(next && (*next)){
-
-			// if not on the first character
-			if(index){
-				// move to the next character
-				++ next;
-			}
-
-			// parse the actual integral value
-			value = strtoul(next, &last, base);
-			// remember the last problematic character
-			// should be either '.' or ':' but is ignored to be more generic
-			next = last;
-
-			// fill the address data byte by byte
-			shift = bytes - 1;
-			do{
-				// like little endian
-				data[index + shift] = value;
-				value >>= 8;
-			}while(shift --);
-
-			index += bytes;
-		}else{
-			// erase the rest of the address
-			bzero(data + index, count - index);
-			return EOK;
-		}
-	}while(index < count);
-
-	return EOK;
-}
-
-/** @}
- */
Index: pace/lib/socket/generic/net_modules.c
===================================================================
--- uspace/lib/socket/generic/net_modules.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ 	(revision )
@@ -1,228 +1,0 @@
-/*
- * Copyright (c) 2009 Lukas Mejdrech
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (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 net
- *  @{
- */
-
-/** @file
- *  Generic module functions implementation.
- */
-
-#include <async.h>
-#include <malloc.h>
-
-#include <ipc/ipc.h>
-#include <ipc/services.h>
-
-#include <sys/time.h>
-
-#include <net_err.h>
-#include <net_modules.h>
-
-/** The time between connect requests in microseconds.
- */
-#define MODULE_WAIT_TIME	(10 * 1000)
-
-void answer_call(ipc_callid_t callid, int result, ipc_call_t * answer, int answer_count){
-	// choose the most efficient answer function
-	if(answer || (! answer_count)){
-		switch(answer_count){
-			case 0:
-				ipc_answer_0(callid, (ipcarg_t) result);
-				break;
-			case 1:
-				ipc_answer_1(callid, (ipcarg_t) result, IPC_GET_ARG1(*answer));
-				break;
-			case 2:
-				ipc_answer_2(callid, (ipcarg_t) result, IPC_GET_ARG1(*answer), IPC_GET_ARG2(*answer));
-				break;
-			case 3:
-				ipc_answer_3(callid, (ipcarg_t) result, IPC_GET_ARG1(*answer), IPC_GET_ARG2(*answer), IPC_GET_ARG3(*answer));
-				break;
-			case 4:
-				ipc_answer_4(callid, (ipcarg_t) result, IPC_GET_ARG1(*answer), IPC_GET_ARG2(*answer), IPC_GET_ARG3(*answer), IPC_GET_ARG4(*answer));
-				break;
-			case 5:
-			default:
-				ipc_answer_5(callid, (ipcarg_t) result, IPC_GET_ARG1(*answer), IPC_GET_ARG2(*answer), IPC_GET_ARG3(*answer), IPC_GET_ARG4(*answer), IPC_GET_ARG5(*answer));
-				break;
-		}
-	}
-}
-
-/** Create bidirectional connection with the needed module service and registers the message receiver.
- *
- * @param[in] need            The needed module service.
- * @param[in] arg1            The first parameter.
- * @param[in] arg2            The second parameter.
- * @param[in] arg3            The third parameter.
- * @param[in] client_receiver The message receiver.
- *
- * @return The phone of the needed service.
- * @return Other error codes as defined for the ipc_connect_to_me() function.
- *
- */
-int bind_service(services_t need, ipcarg_t arg1, ipcarg_t arg2, ipcarg_t arg3,
-    async_client_conn_t client_receiver)
-{
-	return bind_service_timeout(need, arg1, arg2, arg3, client_receiver, 0);
-}
-
-/** Create bidirectional connection with the needed module service and registers the message receiver.
- *
- * @param[in] need            The needed module service.
- * @param[in] arg1            The first parameter.
- * @param[in] arg2            The second parameter.
- * @param[in] arg3            The third parameter.
- * @param[in] client_receiver The message receiver.
- * @param[in] timeout         The connection timeout in microseconds.
- *                            No timeout if set to zero (0).
- *
- * @return The phone of the needed service.
- * @return ETIMEOUT if the connection timeouted.
- * @return Other error codes as defined for the ipc_connect_to_me() function.
- *
- */
-int bind_service_timeout(services_t need, ipcarg_t arg1, ipcarg_t arg2,
-    ipcarg_t arg3, async_client_conn_t client_receiver, suseconds_t timeout)
-{
-	ERROR_DECLARE;
-	
-	/* Connect to the needed service */
-	int phone = connect_to_service_timeout(need, timeout);
-	if (phone >= 0) {
-		/* Request the bidirectional connection */
-		ipcarg_t phonehash;
-		if (ERROR_OCCURRED(ipc_connect_to_me(phone, arg1, arg2, arg3,
-		    &phonehash))) {
-			ipc_hangup(phone);
-			return ERROR_CODE;
-		}
-		async_new_connection(phonehash, 0, NULL, client_receiver);
-	}
-	
-	return phone;
-}
-
-int connect_to_service(services_t need){
-	return connect_to_service_timeout(need, 0);
-}
-
-int connect_to_service_timeout(services_t need, suseconds_t timeout){
-	int phone;
-
-	// if no timeout is set
-	if (timeout <= 0){
-		return async_connect_me_to_blocking(PHONE_NS, need, 0, 0);
-	}
-
-	while(true){
-		phone = async_connect_me_to(PHONE_NS, need, 0, 0);
-		if((phone >= 0) || (phone != ENOENT)){
-			return phone;
-		}
-
-		// end if no time is left
-		if(timeout <= 0){
-			return ETIMEOUT;
-		}
-
-		// wait the minimum of the module wait time and the timeout
-		usleep((timeout <= MODULE_WAIT_TIME) ? timeout : MODULE_WAIT_TIME);
-		timeout -= MODULE_WAIT_TIME;
-	}
-}
-
-int data_receive(void ** data, size_t * length){
-	ERROR_DECLARE;
-
-	ipc_callid_t callid;
-
-	if(!(data && length)){
-		return EBADMEM;
-	}
-
-	// fetch the request
-	if(! async_data_write_receive(&callid, length)){
-		return EINVAL;
-	}
-
-	// allocate the buffer
-	*data = malloc(*length);
-	if(!(*data)){
-		return ENOMEM;
-	}
-
-	// fetch the data
-	if(ERROR_OCCURRED(async_data_write_finalize(callid, * data, * length))){
-		free(data);
-		return ERROR_CODE;
-	}
-	return EOK;
-}
-
-int data_reply(void * data, size_t data_length){
-	size_t length;
-	ipc_callid_t callid;
-
-	// fetch the request
-	if(! async_data_read_receive(&callid, &length)){
-		return EINVAL;
-	}
-
-	// check the requested data size
-	if(length < data_length){
-		async_data_read_finalize(callid, data, length);
-		return EOVERFLOW;
-	}
-
-	// send the data
-	return async_data_read_finalize(callid, data, data_length);
-}
-
-void refresh_answer(ipc_call_t * answer, int * answer_count){
-
-	if(answer_count){
-		*answer_count = 0;
-	}
-
-	if(answer){
-		IPC_SET_RETVAL(*answer, 0);
-		// just to be precize
-		IPC_SET_METHOD(*answer, 0);
-		IPC_SET_ARG1(*answer, 0);
-		IPC_SET_ARG2(*answer, 0);
-		IPC_SET_ARG3(*answer, 0);
-		IPC_SET_ARG4(*answer, 0);
-		IPC_SET_ARG5(*answer, 0);
-	}
-}
-
-/** @}
- */
Index: pace/lib/socket/generic/socket_client.c
===================================================================
--- uspace/lib/socket/generic/socket_client.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ 	(revision )
@@ -1,882 +1,0 @@
-/*
- * Copyright (c) 2009 Lukas Mejdrech
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (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 socket
- *  @{
- */
-
-/** @file
- *  Socket application program interface (API) implementation.
- *  @see socket.h for more information.
- *  This is a part of the network application library.
- */
-
-#include <assert.h>
-#include <async.h>
-#include <fibril_synch.h>
-#include <limits.h>
-#include <stdlib.h>
-
-#include <ipc/services.h>
-
-#include <net_err.h>
-#include <net_modules.h>
-#include <in.h>
-#include <socket.h>
-#include <socket_errno.h>
-#include <adt/dynamic_fifo.h>
-#include <adt/int_map.h>
-#include <socket_messages.h>
-
-/** Initial received packet queue size.
- */
-#define SOCKET_INITIAL_RECEIVED_SIZE	4
-
-/** Maximum received packet queue size.
- */
-#define SOCKET_MAX_RECEIVED_SIZE		0
-
-/** Initial waiting sockets queue size.
- */
-#define SOCKET_INITIAL_ACCEPTED_SIZE	1
-
-/** Maximum waiting sockets queue size.
- */
-#define SOCKET_MAX_ACCEPTED_SIZE		0
-
-/** Default timeout for connections in microseconds.
- */
-#define SOCKET_CONNECT_TIMEOUT	(1 * 1000 * 1000)
-
-/** Maximum number of random attempts to find a new socket identifier before switching to the sequence.
- */
-#define SOCKET_ID_TRIES					100
-
-/** Type definition of the socket specific data.
- *  @see socket
- */
-typedef struct socket	socket_t;
-
-/** Type definition of the socket specific data pointer.
- *  @see socket
- */
-typedef socket_t *	socket_ref;
-
-/** Socket specific data.
- *  Each socket lock locks only its structure part and any number of them may be locked simultaneously.
- */
-struct socket{
-	/** Socket identifier.
-	 */
-	int socket_id;
-	/** Parent module phone.
-	 */
-	int phone;
-	/** Parent module service.
-	 */
-	services_t service;
-	/** Underlying protocol header size.
-	 *  Sending and receiving optimalization.
-	 */
-	size_t header_size;
-	/** Packet data fragment size.
-	 *  Sending optimalization.
-	 */
-	size_t data_fragment_size;
-	/** Sending safety lock.
-	 *  Locks the header_size and data_fragment_size attributes.
-	 */
-	fibril_rwlock_t sending_lock;
-	/** Received packets queue.
-	 */
-	dyn_fifo_t received;
-	/** Received packets safety lock.
-	 *  Used for receiving and receive notifications.
-	 *  Locks the received attribute.
-	 */
-	fibril_mutex_t receive_lock;
-	/** Received packets signaling.
-	 *  Signaled upon receive notification.
-	 */
-	fibril_condvar_t receive_signal;
-	/** Waiting sockets queue.
-	 */
-	dyn_fifo_t accepted;
-	/** Waiting sockets safety lock.
-	 *  Used for accepting and accept notifications.
-	 *  Locks the accepted attribute.
-	 */
-	fibril_mutex_t accept_lock;
-	/** Waiting sockets signaling.
-	 *  Signaled upon accept notification.
-	 */
-	fibril_condvar_t accept_signal;
-	/** The number of blocked functions called.
-	 *  Used while waiting for the received packets or accepted sockets.
-	 */
-	int blocked;
-};
-
-/** Sockets map.
- *  Maps socket identifiers to the socket specific data.
- *  @see int_map.h
- */
-INT_MAP_DECLARE(sockets, socket_t);
-
-/** Socket client library global data.
- */
-static struct socket_client_globals {
-	/** TCP module phone.
-	 */
-	int tcp_phone;
-	/** UDP module phone.
-	 */
-	int udp_phone;
-//	/** The last socket identifier.
-//	 */
-//	int last_id;
-	/** Active sockets.
-	 */
-	sockets_ref sockets;
-	/** Safety lock.
-	 *  Write lock is used only for adding or removing sockets.
-	 *  When locked for writing, no other socket locks need to be locked.
-	 *  When locked for reading, any other socket locks may be locked.
-	 *  No socket lock may be locked if this lock is unlocked.
-	 */
-	fibril_rwlock_t lock;
-} socket_globals = {
-	.tcp_phone = -1,
-	.udp_phone = -1,
-//	.last_id = 0,
-	.sockets = NULL,
-	.lock = {
-		.readers = 0,
-		.writers = 0,
-		.waiters = {
-			.prev = &socket_globals.lock.waiters,
-			.next = &socket_globals.lock.waiters
-		}
-	}
-};
-
-INT_MAP_IMPLEMENT(sockets, socket_t);
-
-/** Returns the active sockets.
- *  @returns The active sockets.
- */
-static sockets_ref socket_get_sockets(void){
-	if(! socket_globals.sockets){
-		socket_globals.sockets = (sockets_ref) malloc(sizeof(sockets_t));
-		if(! socket_globals.sockets){
-			return NULL;
-		}
-		if(sockets_initialize(socket_globals.sockets) != EOK){
-			free(socket_globals.sockets);
-			socket_globals.sockets = NULL;
-		}
-		srand(task_get_id());
-	}
-	return socket_globals.sockets;
-}
-
-/** Default thread for new connections.
- *  @param[in] iid The initial message identifier.
- *  @param[in] icall The initial message call structure.
- */
-static void socket_connection(ipc_callid_t iid, ipc_call_t * icall){
-	ERROR_DECLARE;
-
-	ipc_callid_t callid;
-	ipc_call_t call;
-	socket_ref socket;
-
-	while(true){
-
-		callid = async_get_call(&call);
-		switch(IPC_GET_METHOD(call)){
-			case NET_SOCKET_RECEIVED:
-			case NET_SOCKET_ACCEPTED:
-			case NET_SOCKET_DATA_FRAGMENT_SIZE:
-				fibril_rwlock_read_lock(&socket_globals.lock);
-				// find the socket
-				socket = sockets_find(socket_get_sockets(), SOCKET_GET_SOCKET_ID(call));
-				if(! socket){
-					ERROR_CODE = ENOTSOCK;
-				}else{
-					switch(IPC_GET_METHOD(call)){
-						case NET_SOCKET_RECEIVED:
-							fibril_mutex_lock(&socket->receive_lock);
-							// push the number of received packet fragments
-							if(! ERROR_OCCURRED(dyn_fifo_push(&socket->received, SOCKET_GET_DATA_FRAGMENTS(call), SOCKET_MAX_RECEIVED_SIZE))){
-								// signal the received packet
-								fibril_condvar_signal(&socket->receive_signal);
-							}
-							fibril_mutex_unlock(&socket->receive_lock);
-							break;
-						case NET_SOCKET_ACCEPTED:
-							// push the new socket identifier
-							fibril_mutex_lock(&socket->accept_lock);
-							if(! ERROR_OCCURRED(dyn_fifo_push(&socket->accepted, 1, SOCKET_MAX_ACCEPTED_SIZE))){
-								// signal the accepted socket
-								fibril_condvar_signal(&socket->accept_signal);
-							}
-							fibril_mutex_unlock(&socket->accept_lock);
-							break;
-						default:
-							ERROR_CODE = ENOTSUP;
-					}
-					if((SOCKET_GET_DATA_FRAGMENT_SIZE(call) > 0)
-						&& (SOCKET_GET_DATA_FRAGMENT_SIZE(call) != socket->data_fragment_size)){
-						fibril_rwlock_write_lock(&socket->sending_lock);
-						// set the data fragment size
-						socket->data_fragment_size = SOCKET_GET_DATA_FRAGMENT_SIZE(call);
-						fibril_rwlock_write_unlock(&socket->sending_lock);
-					}
-				}
-				fibril_rwlock_read_unlock(&socket_globals.lock);
-				break;
-			default:
-				ERROR_CODE = ENOTSUP;
-		}
-		ipc_answer_0(callid, (ipcarg_t) ERROR_CODE);
-	}
-}
-
-/** Returns the TCP module phone.
- *  Connects to the TCP module if necessary.
- *  @returns The TCP module phone.
- *  @returns Other error codes as defined for the bind_service_timeout() function.
- */
-static int socket_get_tcp_phone(void){
-	if(socket_globals.tcp_phone < 0){
-		socket_globals.tcp_phone = bind_service_timeout(SERVICE_TCP, 0, 0, SERVICE_TCP, socket_connection, SOCKET_CONNECT_TIMEOUT);
-	}
-	return socket_globals.tcp_phone;
-}
-
-/** Returns the UDP module phone.
- *  Connects to the UDP module if necessary.
- *  @returns The UDP module phone.
- *  @returns Other error codes as defined for the bind_service_timeout() function.
- */
-static int socket_get_udp_phone(void){
-	if(socket_globals.udp_phone < 0){
-		socket_globals.udp_phone = bind_service_timeout(SERVICE_UDP, 0, 0, SERVICE_UDP, socket_connection, SOCKET_CONNECT_TIMEOUT);
-	}
-	return socket_globals.udp_phone;
-}
-
-/** Tries to find a new free socket identifier.
- *	@returns The new socket identifier.
- *  @returns ELIMIT if there is no socket identifier available.
- */
-static int socket_generate_new_id(void){
-	sockets_ref sockets;
-	int socket_id = 0;
-	int count;
-
-	sockets = socket_get_sockets();
-	count = 0;
-//	socket_id = socket_globals.last_id;
-	do{
-		if(count < SOCKET_ID_TRIES){
-			socket_id = rand() % INT_MAX;
-			++ count;
-		}else if(count == SOCKET_ID_TRIES){
-			socket_id = 1;
-			++ count;
-		// only this branch for last_id
-		}else{
-			if(socket_id < INT_MAX){
-				++ socket_id;
-/*			}else if(socket_globals.last_id){
-*				socket_globals.last_id = 0;
-*				socket_id = 1;
-*/			}else{
-				return ELIMIT;
-			}
-		}
-	}while(sockets_find(sockets, socket_id));
-//	last_id = socket_id
-	return socket_id;
-}
-
-/** Initializes a new socket specific data.
- *  @param[in,out] socket The socket to be initialized.
- *  @param[in] socket_id The new socket identifier.
- *  @param[in] phone The parent module phone.
- *  @param[in] service The parent module service.
- */
-static void socket_initialize(socket_ref socket, int socket_id, int phone, services_t service){
-	socket->socket_id = socket_id;
-	socket->phone = phone;
-	socket->service = service;
-	dyn_fifo_initialize(&socket->received, SOCKET_INITIAL_RECEIVED_SIZE);
-	dyn_fifo_initialize(&socket->accepted, SOCKET_INITIAL_ACCEPTED_SIZE);
-	fibril_mutex_initialize(&socket->receive_lock);
-	fibril_condvar_initialize(&socket->receive_signal);
-	fibril_mutex_initialize(&socket->accept_lock);
-	fibril_condvar_initialize(&socket->accept_signal);
-	fibril_rwlock_initialize(&socket->sending_lock);
-}
-
-int socket(int domain, int type, int protocol){
-	ERROR_DECLARE;
-
-	socket_ref socket;
-	int phone;
-	int socket_id;
-	services_t service;
-	ipcarg_t fragment_size;
-	ipcarg_t header_size;
-
-	// find the appropriate service
-	switch(domain){
-		case PF_INET:
-			switch(type){
-				case SOCK_STREAM:
-					if(! protocol){
-						protocol = IPPROTO_TCP;
-					}
-					switch(protocol){
-						case IPPROTO_TCP:
-							phone = socket_get_tcp_phone();
-							service = SERVICE_TCP;
-							break;
-						default:
-							return EPROTONOSUPPORT;
-					}
-					break;
-				case SOCK_DGRAM:
-					if(! protocol){
-						protocol = IPPROTO_UDP;
-					}
-					switch(protocol){
-						case IPPROTO_UDP:
-							phone = socket_get_udp_phone();
-							service = SERVICE_UDP;
-							break;
-						default:
-							return EPROTONOSUPPORT;
-					}
-					break;
-				case SOCK_RAW:
-				default:
-					return ESOCKTNOSUPPORT;
-			}
-			break;
-		// TODO IPv6
-		default:
-			return EPFNOSUPPORT;
-	}
-	if(phone < 0){
-		return phone;
-	}
-	// create a new socket structure
-	socket = (socket_ref) malloc(sizeof(socket_t));
-	if(! socket){
-		return ENOMEM;
-	}
-	bzero(socket, sizeof(*socket));
-	fibril_rwlock_write_lock(&socket_globals.lock);
-	// request a new socket
-	socket_id = socket_generate_new_id();
-	if(socket_id <= 0){
-		fibril_rwlock_write_unlock(&socket_globals.lock);
-		free(socket);
-		return socket_id;
-	}
-	if(ERROR_OCCURRED((int) async_req_3_3(phone, NET_SOCKET, socket_id, 0, service, NULL, &fragment_size, &header_size))){
-		fibril_rwlock_write_unlock(&socket_globals.lock);
-		free(socket);
-		return ERROR_CODE;
-	}
-	socket->data_fragment_size = (size_t) fragment_size;
-	socket->header_size = (size_t) header_size;
-	// finish the new socket initialization
-	socket_initialize(socket, socket_id, phone, service);
-	// store the new socket
-	ERROR_CODE = sockets_add(socket_get_sockets(), socket_id, socket);
-	fibril_rwlock_write_unlock(&socket_globals.lock);
-	if(ERROR_CODE < 0){
-		dyn_fifo_destroy(&socket->received);
-		dyn_fifo_destroy(&socket->accepted);
-		free(socket);
-		async_msg_3(phone, NET_SOCKET_CLOSE, (ipcarg_t) socket_id, 0, service);
-		return ERROR_CODE;
-	}
-
-	return socket_id;
-}
-
-/** Sends message to the socket parent module with specified data.
- *  @param[in] socket_id Socket identifier.
- *  @param[in] message The action message.
- *  @param[in] arg2 The second message parameter.
- *  @param[in] data The data to be sent.
- *  @param[in] datalength The data length.
- *  @returns EOK on success.
- *  @returns ENOTSOCK if the socket is not found.
- *  @returns EBADMEM if the data parameter is NULL.
- *  @returns NO_DATA if the datalength parameter is zero (0).
- *  @returns Other error codes as defined for the spcific message.
- */
-static int socket_send_data(int socket_id, ipcarg_t message, ipcarg_t arg2, const void * data, size_t datalength){
-	socket_ref socket;
-	aid_t message_id;
-	ipcarg_t result;
-
-	if(! data){
-		return EBADMEM;
-	}
-	if(! datalength){
-		return NO_DATA;
-	}
-
-	fibril_rwlock_read_lock(&socket_globals.lock);
-	// find the socket
-	socket = sockets_find(socket_get_sockets(), socket_id);
-	if(! socket){
-		fibril_rwlock_read_unlock(&socket_globals.lock);
-		return ENOTSOCK;
-	}
-	// request the message
-	message_id = async_send_3(socket->phone, message, (ipcarg_t) socket->socket_id, arg2, socket->service, NULL);
-	// send the address
-	async_data_write_start(socket->phone, data, datalength);
-	fibril_rwlock_read_unlock(&socket_globals.lock);
-	async_wait_for(message_id, &result);
-	return (int) result;
-}
-
-int bind(int socket_id, const struct sockaddr * my_addr, socklen_t addrlen){
-	if(addrlen <= 0){
-		return EINVAL;
-	}
-	// send the address
-	return socket_send_data(socket_id, NET_SOCKET_BIND, 0, my_addr, (size_t) addrlen);
-}
-
-int listen(int socket_id, int backlog){
-	socket_ref socket;
-	int result;
-
-	if(backlog <= 0){
-		return EINVAL;
-	}
-	fibril_rwlock_read_lock(&socket_globals.lock);
-	// find the socket
-	socket = sockets_find(socket_get_sockets(), socket_id);
-	if(! socket){
-		fibril_rwlock_read_unlock(&socket_globals.lock);
-		return ENOTSOCK;
-	}
-	// request listen backlog change
-	result = (int) async_req_3_0(socket->phone, NET_SOCKET_LISTEN, (ipcarg_t) socket->socket_id, (ipcarg_t) backlog, socket->service);
-	fibril_rwlock_read_unlock(&socket_globals.lock);
-	return result;
-}
-
-int accept(int socket_id, struct sockaddr * cliaddr, socklen_t * addrlen){
-	socket_ref socket;
-	socket_ref new_socket;
-	aid_t message_id;
-	ipcarg_t ipc_result;
-	int result;
-	ipc_call_t answer;
-
-	if((! cliaddr) || (! addrlen)){
-		return EBADMEM;
-	}
-
-	fibril_rwlock_write_lock(&socket_globals.lock);
-	// find the socket
-	socket = sockets_find(socket_get_sockets(), socket_id);
-	if(! socket){
-		fibril_rwlock_write_unlock(&socket_globals.lock);
-		return ENOTSOCK;
-	}
-	fibril_mutex_lock(&socket->accept_lock);
-	// wait for an accepted socket
-	++ socket->blocked;
-	while(dyn_fifo_value(&socket->accepted) <= 0){
-		fibril_rwlock_write_unlock(&socket_globals.lock);
-		fibril_condvar_wait(&socket->accept_signal, &socket->accept_lock);
-		// drop the accept lock to avoid deadlock
-		fibril_mutex_unlock(&socket->accept_lock);
-		fibril_rwlock_write_lock(&socket_globals.lock);
-		fibril_mutex_lock(&socket->accept_lock);
-	}
-	-- socket->blocked;
-
-	// create a new scoket
-	new_socket = (socket_ref) malloc(sizeof(socket_t));
-	if(! new_socket){
-		fibril_mutex_unlock(&socket->accept_lock);
-		fibril_rwlock_write_unlock(&socket_globals.lock);
-		return ENOMEM;
-	}
-	bzero(new_socket, sizeof(*new_socket));
-	socket_id = socket_generate_new_id();
-	if(socket_id <= 0){
-		fibril_mutex_unlock(&socket->accept_lock);
-		fibril_rwlock_write_unlock(&socket_globals.lock);
-		free(new_socket);
-		return socket_id;
-	}
-	socket_initialize(new_socket, socket_id, socket->phone, socket->service);
-	result = sockets_add(socket_get_sockets(), new_socket->socket_id, new_socket);
-	if(result < 0){
-		fibril_mutex_unlock(&socket->accept_lock);
-		fibril_rwlock_write_unlock(&socket_globals.lock);
-		free(new_socket);
-		return result;
-	}
-
-	// request accept
-	message_id = async_send_5(socket->phone, NET_SOCKET_ACCEPT, (ipcarg_t) socket->socket_id, 0, socket->service, 0, new_socket->socket_id, &answer);
-	// read address
-	ipc_data_read_start(socket->phone, cliaddr, * addrlen);
-	fibril_rwlock_write_unlock(&socket_globals.lock);
-	async_wait_for(message_id, &ipc_result);
-	result = (int) ipc_result;
-	if(result > 0){
-		if(result != socket_id){
-			result = EINVAL;
-		}
-		// dequeue the accepted socket if successful
-		dyn_fifo_pop(&socket->accepted);
-		// set address length
-		*addrlen = SOCKET_GET_ADDRESS_LENGTH(answer);
-		new_socket->data_fragment_size = SOCKET_GET_DATA_FRAGMENT_SIZE(answer);
-	}else if(result == ENOTSOCK){
-		// empty the queue if no accepted sockets
-		while(dyn_fifo_pop(&socket->accepted) > 0);
-	}
-	fibril_mutex_unlock(&socket->accept_lock);
-	return result;
-}
-
-int connect(int socket_id, const struct sockaddr * serv_addr, socklen_t addrlen){
-	if(! serv_addr){
-		return EDESTADDRREQ;
-	}
-	if(! addrlen){
-		return EDESTADDRREQ;
-	}
-	// send the address
-	return socket_send_data(socket_id, NET_SOCKET_CONNECT, 0, serv_addr, addrlen);
-}
-
-/** Clears and destroys the socket.
- *  @param[in] socket The socket to be destroyed.
- */
-static void socket_destroy(socket_ref socket){
-	int accepted_id;
-
-	// destroy all accepted sockets
-	while((accepted_id = dyn_fifo_pop(&socket->accepted)) >= 0){
-		socket_destroy(sockets_find(socket_get_sockets(), accepted_id));
-	}
-	dyn_fifo_destroy(&socket->received);
-	dyn_fifo_destroy(&socket->accepted);
-	sockets_exclude(socket_get_sockets(), socket->socket_id);
-}
-
-int closesocket(int socket_id){
-	ERROR_DECLARE;
-
-	socket_ref socket;
-
-	fibril_rwlock_write_lock(&socket_globals.lock);
-	socket = sockets_find(socket_get_sockets(), socket_id);
-	if(! socket){
-		fibril_rwlock_write_unlock(&socket_globals.lock);
-		return ENOTSOCK;
-	}
-	if(socket->blocked){
-		fibril_rwlock_write_unlock(&socket_globals.lock);
-		return EINPROGRESS;
-	}
-	// request close
-	ERROR_PROPAGATE((int) async_req_3_0(socket->phone, NET_SOCKET_CLOSE, (ipcarg_t) socket->socket_id, 0, socket->service));
-	// free the socket structure
-	socket_destroy(socket);
-	fibril_rwlock_write_unlock(&socket_globals.lock);
-	return EOK;
-}
-
-/** Sends data via the socket to the remote address.
- *  Binds the socket to a free port if not already connected/bound.
- *  @param[in] message The action message.
- *  @param[in] socket_id Socket identifier.
- *  @param[in] data The data to be sent.
- *  @param[in] datalength The data length.
- *  @param[in] flags Various send flags.
- *  @param[in] toaddr The destination address. May be NULL for connected sockets.
- *  @param[in] addrlen The address length. Used only if toaddr is not NULL.
- *  @returns EOK on success.
- *  @returns ENOTSOCK if the socket is not found.
- *  @returns EBADMEM if the data or toaddr parameter is NULL.
- *  @returns NO_DATA if the datalength or the addrlen parameter is zero (0).
- *  @returns Other error codes as defined for the NET_SOCKET_SENDTO message.
- */
-static int sendto_core(ipcarg_t message, int socket_id, const void * data, size_t datalength, int flags, const struct sockaddr * toaddr, socklen_t addrlen){
-	socket_ref socket;
-	aid_t message_id;
-	ipcarg_t result;
-	size_t fragments;
-	ipc_call_t answer;
-
-	if(! data){
-		return EBADMEM;
-	}
-	if(! datalength){
-		return NO_DATA;
-	}
-	fibril_rwlock_read_lock(&socket_globals.lock);
-	// find socket
-	socket = sockets_find(socket_get_sockets(), socket_id);
-	if(! socket){
-		fibril_rwlock_read_unlock(&socket_globals.lock);
-		return ENOTSOCK;
-	}
-	fibril_rwlock_read_lock(&socket->sending_lock);
-	// compute data fragment count
-	if(socket->data_fragment_size > 0){
-		fragments = (datalength + socket->header_size) / socket->data_fragment_size;
-		if((datalength + socket->header_size) % socket->data_fragment_size) ++ fragments;
-	}else{
-		fragments = 1;
-	}
-	// request send
-	message_id = async_send_5(socket->phone, message, (ipcarg_t) socket->socket_id, (fragments == 1 ? datalength : socket->data_fragment_size), socket->service, (ipcarg_t) flags, fragments, &answer);
-	// send the address if given
-	if((! toaddr) || (async_data_write_start(socket->phone, toaddr, addrlen) == EOK)){
-		if(fragments == 1){
-			// send all if only one fragment
-			async_data_write_start(socket->phone, data, datalength);
-		}else{
-			// send the first fragment
-			async_data_write_start(socket->phone, data, socket->data_fragment_size - socket->header_size);
-			data = ((const uint8_t *) data) + socket->data_fragment_size - socket->header_size;
-			// send the middle fragments
-			while((-- fragments) > 1){
-				async_data_write_start(socket->phone, data, socket->data_fragment_size);
-				data = ((const uint8_t *) data) + socket->data_fragment_size;
-			}
-			// send the last fragment
-			async_data_write_start(socket->phone, data, (datalength + socket->header_size) % socket->data_fragment_size);
-		}
-	}
-	async_wait_for(message_id, &result);
-	if((SOCKET_GET_DATA_FRAGMENT_SIZE(answer) > 0)
-		&& (SOCKET_GET_DATA_FRAGMENT_SIZE(answer) != socket->data_fragment_size)){
-		// set the data fragment size
-		socket->data_fragment_size = SOCKET_GET_DATA_FRAGMENT_SIZE(answer);
-	}
-	fibril_rwlock_read_unlock(&socket->sending_lock);
-	fibril_rwlock_read_unlock(&socket_globals.lock);
-	return (int) result;
-}
-
-int send(int socket_id, void * data, size_t datalength, int flags){
-	// without the address
-	return sendto_core(NET_SOCKET_SEND, socket_id, data, datalength, flags, NULL, 0);
-}
-
-int sendto(int socket_id, const void * data, size_t datalength, int flags, const struct sockaddr * toaddr, socklen_t addrlen){
-	if(! toaddr){
-		return EDESTADDRREQ;
-	}
-	if(! addrlen){
-		return EDESTADDRREQ;
-	}
-	// with the address
-	return sendto_core(NET_SOCKET_SENDTO, socket_id, data, datalength, flags, toaddr, addrlen);
-}
-
-/** Receives data via the socket.
- *  @param[in] message The action message.
- *  @param[in] socket_id Socket identifier.
- *  @param[out] data The data buffer to be filled.
- *  @param[in] datalength The data length.
- *  @param[in] flags Various receive flags.
- *  @param[out] fromaddr The source address. May be NULL for connected sockets.
- *  @param[in,out] addrlen The address length. The maximum address length is read. The actual address length is set. Used only if fromaddr is not NULL.
- *  @returns EOK on success.
- *  @returns ENOTSOCK if the socket is not found.
- *  @returns EBADMEM if the data parameter is NULL.
- *  @returns NO_DATA if the datalength or addrlen parameter is zero (0).
- *  @returns Other error codes as defined for the spcific message.
- */
-static int recvfrom_core(ipcarg_t message, int socket_id, void * data, size_t datalength, int flags, struct sockaddr * fromaddr, socklen_t * addrlen){
-	socket_ref socket;
-	aid_t message_id;
-	ipcarg_t ipc_result;
-	int result;
-	size_t fragments;
-	size_t * lengths;
-	size_t index;
-	ipc_call_t answer;
-
-	if(! data){
-		return EBADMEM;
-	}
-	if(! datalength){
-		return NO_DATA;
-	}
-	if(fromaddr && (! addrlen)){
-		return EINVAL;
-	}
-	fibril_rwlock_read_lock(&socket_globals.lock);
-	// find the socket
-	socket = sockets_find(socket_get_sockets(), socket_id);
-	if(! socket){
-		fibril_rwlock_read_unlock(&socket_globals.lock);
-		return ENOTSOCK;
-	}
-	fibril_mutex_lock(&socket->receive_lock);
-	// wait for a received packet
-	++ socket->blocked;
-	while((result = dyn_fifo_value(&socket->received)) <= 0){
-		fibril_rwlock_read_unlock(&socket_globals.lock);
-		fibril_condvar_wait(&socket->receive_signal, &socket->receive_lock);
-		// drop the receive lock to avoid deadlock
-		fibril_mutex_unlock(&socket->receive_lock);
-		fibril_rwlock_read_lock(&socket_globals.lock);
-		fibril_mutex_lock(&socket->receive_lock);
-	}
-	-- socket->blocked;
-	fragments = (size_t) result;
-	// prepare lengths if more fragments
-	if(fragments > 1){
-		lengths = (size_t *) malloc(sizeof(size_t) * fragments + sizeof(size_t));
-		if(! lengths){
-			fibril_mutex_unlock(&socket->receive_lock);
-			fibril_rwlock_read_unlock(&socket_globals.lock);
-			return ENOMEM;
-		}
-		// request packet data
-		message_id = async_send_4(socket->phone, message, (ipcarg_t) socket->socket_id, 0, socket->service, (ipcarg_t) flags, &answer);
-		// read the address if desired
-		if((! fromaddr) || (async_data_read_start(socket->phone, fromaddr, * addrlen) == EOK)){
-		// read the fragment lengths
-			if(async_data_read_start(socket->phone, lengths, sizeof(int) * (fragments + 1)) == EOK){
-				if(lengths[fragments] <= datalength){
-					// read all fragments if long enough
-					for(index = 0; index < fragments; ++ index){
-						async_data_read_start(socket->phone, data, lengths[index]);
-						data = ((uint8_t *) data) + lengths[index];
-					}
-				}
-			}
-		}
-		free(lengths);
-	}else{
-		// request packet data
-		message_id = async_send_4(socket->phone, message, (ipcarg_t) socket->socket_id, 0, socket->service, (ipcarg_t) flags, &answer);
-		// read the address if desired
-		if((! fromaddr) || (async_data_read_start(socket->phone, fromaddr, * addrlen) == EOK)){
-			// read all if only one fragment
-			async_data_read_start(socket->phone, data, datalength);
-		}
-	}
-	async_wait_for(message_id, &ipc_result);
-	result = (int) ipc_result;
-	// if successful
-	if(result == EOK){
-		// dequeue the received packet
-		dyn_fifo_pop(&socket->received);
-		// return read data length
-		result = SOCKET_GET_READ_DATA_LENGTH(answer);
-		// set address length
-		if(fromaddr && addrlen){
-			*addrlen = SOCKET_GET_ADDRESS_LENGTH(answer);
-		}
-	}
-	fibril_mutex_unlock(&socket->receive_lock);
-	fibril_rwlock_read_unlock(&socket_globals.lock);
-	return result;
-}
-
-int recv(int socket_id, void * data, size_t datalength, int flags){
-	// without the address
-	return recvfrom_core(NET_SOCKET_RECV, socket_id, data, datalength, flags, NULL, NULL);
-}
-
-int recvfrom(int socket_id, void * data, size_t datalength, int flags, struct sockaddr * fromaddr, socklen_t * addrlen){
-	if(! fromaddr){
-		return EBADMEM;
-	}
-	if(! addrlen){
-		return NO_DATA;
-	}
-	// with the address
-	return recvfrom_core(NET_SOCKET_RECVFROM, socket_id, data, datalength, flags, fromaddr, addrlen);
-}
-
-int getsockopt(int socket_id, int level, int optname, void * value, size_t * optlen){
-	socket_ref socket;
-	aid_t message_id;
-	ipcarg_t result;
-
-	if(!(value && optlen)){
-		return EBADMEM;
-	}
-	if(!(*optlen)){
-		return NO_DATA;
-	}
-	fibril_rwlock_read_lock(&socket_globals.lock);
-	// find the socket
-	socket = sockets_find(socket_get_sockets(), socket_id);
-	if(! socket){
-		fibril_rwlock_read_unlock(&socket_globals.lock);
-		return ENOTSOCK;
-	}
-	// request option value
-	message_id = async_send_3(socket->phone, NET_SOCKET_GETSOCKOPT, (ipcarg_t) socket->socket_id, (ipcarg_t) optname, socket->service, NULL);
-	// read the length
-	if(async_data_read_start(socket->phone, optlen, sizeof(*optlen)) == EOK){
-		// read the value
-		async_data_read_start(socket->phone, value, * optlen);
-	}
-	fibril_rwlock_read_unlock(&socket_globals.lock);
-	async_wait_for(message_id, &result);
-	return (int) result;
-}
-
-int setsockopt(int socket_id, int level, int optname, const void * value, size_t optlen){
-	// send the value
-	return socket_send_data(socket_id, NET_SOCKET_SETSOCKOPT, (ipcarg_t) optname, value, optlen);
-
-}
-
-/** @}
- */
Index: pace/lib/socket/generic/socket_core.c
===================================================================
--- uspace/lib/socket/generic/socket_core.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ 	(revision )
@@ -1,476 +1,0 @@
-/*
- * Copyright (c) 2009 Lukas Mejdrech
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (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 socket
- *  @{
- */
-
-/** @file
- *  Socket common core implementation.
- */
-
-#include <limits.h>
-#include <stdlib.h>
-
-#include <net_err.h>
-#include <in.h>
-#include <inet.h>
-#include <socket_codes.h>
-#include <socket_errno.h>
-#include <adt/dynamic_fifo.h>
-#include <adt/int_map.h>
-#include <packet/packet.h>
-#include <packet/packet_client.h>
-#include <net_modules.h>
-#include <socket_core.h>
-
-/** Maximum number of random attempts to find a new socket identifier before switching to the sequence.
- */
-#define SOCKET_ID_TRIES					100
-
-/** Bound port sockets.
- */
-struct socket_port{
-	/** The bound sockets map.
-	 */
-	socket_port_map_t map;
-	/** The bound sockets count.
-	 */
-	int count;
-};
-
-INT_MAP_IMPLEMENT(socket_cores, socket_core_t);
-
-GENERIC_CHAR_MAP_IMPLEMENT(socket_port_map, socket_core_ref);
-
-INT_MAP_IMPLEMENT(socket_ports, socket_port_t);
-
-/** Destroys the socket.
- *  If the socket is bound, the port is released.
- *  Releases all buffered packets, calls the release function and removes the socket from the local sockets.
- *  @param[in] packet_phone The packet server phone to release buffered packets.
- *  @param[in] socket The socket to be destroyed.
- *  @param[in,out] local_sockets The local sockets to be updated.
- *  @param[in,out] global_sockets The global sockets to be updated.
- *  @param[in] socket_release The client release callback function.
- */
-static void socket_destroy_core(int packet_phone, socket_core_ref socket, socket_cores_ref local_sockets, socket_ports_ref global_sockets, void (*socket_release)(socket_core_ref socket)){
-	int packet_id;
-
-	// if bound
-	if(socket->port){
-		// release the port
-		socket_port_release(global_sockets, socket);
-	}
-	// release all received packets
-	while((packet_id = dyn_fifo_pop(&socket->received)) >= 0){
-		pq_release_local(packet_phone, packet_id);
-	}
-	dyn_fifo_destroy(&socket->received);
-	dyn_fifo_destroy(&socket->accepted);
-	if(socket_release){
-		socket_release(socket);
-	}
-	socket_cores_exclude(local_sockets, socket->socket_id);
-}
-
-void socket_cores_release(int packet_phone, socket_cores_ref local_sockets, socket_ports_ref global_sockets, void (*socket_release)(socket_core_ref socket)){
-	if(socket_cores_is_valid(local_sockets)){
-		int index;
-
-		local_sockets->magic = 0;
-		for(index = 0; index < local_sockets->next; ++ index){
-			if(socket_cores_item_is_valid(&(local_sockets->items[index]))){
-				local_sockets->items[index].magic = 0;
-				if(local_sockets->items[index].value){
-					socket_destroy_core(packet_phone, local_sockets->items[index].value, local_sockets, global_sockets, socket_release);
-					free(local_sockets->items[index].value);
-					local_sockets->items[index].value = NULL;
-				}
-			}
-		}
-		free(local_sockets->items);
-	}
-}
-
-/** Adds the socket to a socket port.
- *  @param[in,out] socket_port The socket port structure.
- *  @param[in] socket The socket to be added.
- *  @param[in] key The socket key identifier.
- *  @param[in] key_length The socket key length.
- *  @returns EOK on success.
- *  @returns ENOMEM if there is not enough memory left.
- */
-static int socket_port_add_core(socket_port_ref socket_port, socket_core_ref socket, const char * key, size_t key_length){
-	ERROR_DECLARE;
-
-	socket_core_ref * socket_ref;
-
-	// create a wrapper
-	socket_ref = malloc(sizeof(*socket_ref));
-	if(! socket_ref){
-		return ENOMEM;
-	}
-	*socket_ref = socket;
-	// add the wrapper
-	if(ERROR_OCCURRED(socket_port_map_add(&socket_port->map, key, key_length, socket_ref))){
-		free(socket_ref);
-		return ERROR_CODE;
-	}
-	++ socket_port->count;
-	socket->key = key;
-	socket->key_length = key_length;
-	return EOK;
-}
-
-/** Binds the socket to the port.
- *  The SOCKET_MAP_KEY_LISTENING key identifier is used.
- *  @param[in] global_sockets The global sockets to be updated.
- *  @param[in] socket The socket to be added.
- *  @param[in] port The port number to be bound to.
- *  @returns EOK on success.
- *  @returns ENOMEM if there is not enough memory left.
- *  @returns Other error codes as defined for the socket_ports_add() function.
- */
-static int socket_bind_insert(socket_ports_ref global_sockets, socket_core_ref socket, int port){
-	ERROR_DECLARE;
-
-	socket_port_ref socket_port;
-
-	// create a wrapper
-	socket_port = malloc(sizeof(*socket_port));
-	if(! socket_port){
-		return ENOMEM;
-	}
-	socket_port->count = 0;
-	if(ERROR_OCCURRED(socket_port_map_initialize(&socket_port->map))
-		|| ERROR_OCCURRED(socket_port_add_core(socket_port, socket, SOCKET_MAP_KEY_LISTENING, 0))){
-		socket_port_map_destroy(&socket_port->map);
-		free(socket_port);
-		return ERROR_CODE;
-	}
-	// register the incomming port
-	ERROR_CODE = socket_ports_add(global_sockets, port, socket_port);
-	if(ERROR_CODE < 0){
-		socket_port_map_destroy(&socket_port->map);
-		free(socket_port);
-		return ERROR_CODE;
-	}
-	socket->port = port;
-	return EOK;
-}
-
-int socket_bind(socket_cores_ref local_sockets, socket_ports_ref global_sockets, int socket_id, void * addr, size_t addrlen, int free_ports_start, int free_ports_end, int last_used_port){
-	socket_core_ref socket;
-	socket_port_ref socket_port;
-	struct sockaddr * address;
-	struct sockaddr_in * address_in;
-
-	if(addrlen < sizeof(struct sockaddr)){
-		return EINVAL;
-	}
-	address = (struct sockaddr *) addr;
-	switch(address->sa_family){
-		case AF_INET:
-			if(addrlen != sizeof(struct sockaddr_in)){
-				return EINVAL;
-			}
-			address_in = (struct sockaddr_in *) addr;
-			// find the socket
-			socket = socket_cores_find(local_sockets, socket_id);
-			if(! socket){
-				return ENOTSOCK;
-			}
-			// bind a free port?
-			if(address_in->sin_port <= 0){
-				return socket_bind_free_port(global_sockets, socket, free_ports_start, free_ports_end, last_used_port);
-			}
-			// try to find the port
-			socket_port = socket_ports_find(global_sockets, ntohs(address_in->sin_port));
-			if(socket_port){
-				// already used
-				return EADDRINUSE;
-			}
-			// if bound
-			if(socket->port){
-				// release the port
-				socket_port_release(global_sockets, socket);
-			}
-			socket->port = -1;
-			return socket_bind_insert(global_sockets, socket, ntohs(address_in->sin_port));
-			break;
-		// TODO IPv6
-	}
-	return EAFNOSUPPORT;
-}
-
-int socket_bind_free_port(socket_ports_ref global_sockets, socket_core_ref socket, int free_ports_start, int free_ports_end, int last_used_port){
-	int index;
-
-	// from the last used one
-	index = last_used_port;
-	do{
-		++ index;
-		// til the range end
-		if(index >= free_ports_end){
-			// start from the range beginning
-			index = free_ports_start - 1;
-			do{
-				++ index;
-				// til the last used one
-				if(index >= last_used_port){
-					// none found
-					return ENOTCONN;
-				}
-			}while(socket_ports_find(global_sockets, index) != NULL);
-			// found, break immediately
-			break;
-		}
-	}while(socket_ports_find(global_sockets, index) != NULL);
-	return socket_bind_insert(global_sockets, socket, index);
-}
-
-/** Tries to find a new free socket identifier.
- *  @param[in] local_sockets The local sockets to be searched.
- *  @param[in] positive A value indicating whether a positive identifier is requested. A negative identifier is requested if set to false.
- *	@returns The new socket identifier.
- *  @returns ELIMIT if there is no socket identifier available.
- */
-static int socket_generate_new_id(socket_cores_ref local_sockets, int positive){
-	int socket_id;
-	int count;
-
-	count = 0;
-//	socket_id = socket_globals.last_id;
-	do{
-		if(count < SOCKET_ID_TRIES){
-			socket_id = rand() % INT_MAX;
-			++ count;
-		}else if(count == SOCKET_ID_TRIES){
-			socket_id = 1;
-			++ count;
-		// only this branch for last_id
-		}else{
-			if(socket_id < INT_MAX){
-				++ socket_id;
-/*			}else if(socket_globals.last_id){
-*				socket_globals.last_id = 0;
-*				socket_id = 1;
-*/			}else{
-				return ELIMIT;
-			}
-		}
-	}while(socket_cores_find(local_sockets, ((positive ? 1 : -1) * socket_id)));
-//	last_id = socket_id
-	return socket_id;
-}
-
-int socket_create(socket_cores_ref local_sockets, int app_phone, void * specific_data, int * socket_id){
-	ERROR_DECLARE;
-
-	socket_core_ref socket;
-	int res;
-	int positive;
-
-	if(! socket_id){
-		return EINVAL;
-	}
-	// store the socket
-	if(*socket_id <= 0){
-		positive = (*socket_id == 0);
-		*socket_id = socket_generate_new_id(local_sockets, positive);
-		if(*socket_id <= 0){
-			return * socket_id;
-		}
-		if(! positive){
-			*socket_id *= -1;
-		}
-	}else if(socket_cores_find(local_sockets, * socket_id)){
-		return EEXIST;
-	}
-	socket = (socket_core_ref) malloc(sizeof(*socket));
-	if(! socket){
-		return ENOMEM;
-	}
-	// initialize
-	socket->phone = app_phone;
-	socket->port = -1;
-	socket->key = NULL;
-	socket->key_length = 0;
-	socket->specific_data = specific_data;
-	if(ERROR_OCCURRED(dyn_fifo_initialize(&socket->received, SOCKET_INITIAL_RECEIVED_SIZE))){
-		free(socket);
-		return ERROR_CODE;
-	}
-	if(ERROR_OCCURRED(dyn_fifo_initialize(&socket->accepted, SOCKET_INITIAL_ACCEPTED_SIZE))){
-		dyn_fifo_destroy(&socket->received);
-		free(socket);
-		return ERROR_CODE;
-	}
-	socket->socket_id = * socket_id;
-	res = socket_cores_add(local_sockets, socket->socket_id, socket);
-	if(res < 0){
-		dyn_fifo_destroy(&socket->received);
-		dyn_fifo_destroy(&socket->accepted);
-		free(socket);
-		return res;
-	}
-	return EOK;
-}
-
-int socket_destroy(int packet_phone, int socket_id, socket_cores_ref local_sockets, socket_ports_ref global_sockets, void (*socket_release)(socket_core_ref socket)){
-	socket_core_ref socket;
-	int accepted_id;
-
-	// find the socket
-	socket = socket_cores_find(local_sockets, socket_id);
-	if(! socket){
-		return ENOTSOCK;
-	}
-	// destroy all accepted sockets
-	while((accepted_id = dyn_fifo_pop(&socket->accepted)) >= 0){
-		socket_destroy(packet_phone, accepted_id, local_sockets, global_sockets, socket_release);
-	}
-	socket_destroy_core(packet_phone, socket, local_sockets, global_sockets, socket_release);
-	return EOK;
-}
-
-int socket_reply_packets(packet_t packet, size_t * length){
-	ERROR_DECLARE;
-
-	packet_t next_packet;
-	size_t fragments;
-	size_t * lengths;
-	size_t index;
-
-	if(! length){
-		return EBADMEM;
-	}
-	next_packet = pq_next(packet);
-	if(! next_packet){
-		// write all if only one fragment
-		ERROR_PROPAGATE(data_reply(packet_get_data(packet), packet_get_data_length(packet)));
-		// store the total length
-		*length = packet_get_data_length(packet);
-	}else{
-		// count the packet fragments
-		fragments = 1;
-		next_packet = pq_next(packet);
-		while((next_packet = pq_next(next_packet))){
-			++ fragments;
-		}
-		// compute and store the fragment lengths
-		lengths = (size_t *) malloc(sizeof(size_t) * fragments + sizeof(size_t));
-		if(! lengths){
-			return ENOMEM;
-		}
-		lengths[0] = packet_get_data_length(packet);
-		lengths[fragments] = lengths[0];
-		next_packet = pq_next(packet);
-		for(index = 1; index < fragments; ++ index){
-			lengths[index] = packet_get_data_length(next_packet);
-			lengths[fragments] += lengths[index];
-			next_packet = pq_next(packet);
-		}while(next_packet);
-		// write the fragment lengths
-		ERROR_PROPAGATE(data_reply(lengths, sizeof(int) * (fragments + 1)));
-		next_packet = packet;
-		// write the fragments
-		for(index = 0; index < fragments; ++ index){
-			ERROR_PROPAGATE(data_reply(packet_get_data(next_packet), lengths[index]));
-			next_packet = pq_next(next_packet);
-		}while(next_packet);
-		// store the total length
-		*length = lengths[fragments];
-		free(lengths);
-	}
-	return EOK;
-}
-
-socket_core_ref socket_port_find(socket_ports_ref global_sockets, int port, const char * key, size_t key_length){
-	socket_port_ref socket_port;
-	socket_core_ref * socket_ref;
-
-	socket_port = socket_ports_find(global_sockets, port);
-	if(socket_port && (socket_port->count > 0)){
-		socket_ref = socket_port_map_find(&socket_port->map, key, key_length);
-		if(socket_ref){
-			return * socket_ref;
-		}
-	}
-	return NULL;
-}
-
-void socket_port_release(socket_ports_ref global_sockets, socket_core_ref socket){
-	socket_port_ref socket_port;
-	socket_core_ref * socket_ref;
-
-	if(socket->port){
-		// find ports
-		socket_port = socket_ports_find(global_sockets, socket->port);
-		if(socket_port){
-			// find the socket
-			socket_ref = socket_port_map_find(&socket_port->map, socket->key, socket->key_length);
-			if(socket_ref){
-				-- socket_port->count;
-				// release if empty
-				if(socket_port->count <= 0){
-					// destroy the map
-					socket_port_map_destroy(&socket_port->map);
-					// release the port
-					socket_ports_exclude(global_sockets, socket->port);
-				}else{
-					// remove
-					socket_port_map_exclude(&socket_port->map, socket->key, socket->key_length);
-				}
-			}
-		}
-		socket->port = 0;
-		socket->key = NULL;
-		socket->key_length = 0;
-	}
-}
-
-int socket_port_add(socket_ports_ref global_sockets, int port, socket_core_ref socket, const char * key, size_t key_length){
-	ERROR_DECLARE;
-
-	socket_port_ref socket_port;
-
-	// find ports
-	socket_port = socket_ports_find(global_sockets, port);
-	if(! socket_port){
-		return ENOENT;
-	}
-	// add the socket
-	ERROR_PROPAGATE(socket_port_add_core(socket_port, socket, key, key_length));
-	socket->port = port;
-	return EOK;
-}
-
-/** @}
- */
Index: pace/lib/socket/generic/socket_parse.c
===================================================================
--- uspace/lib/socket/generic/socket_parse.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ 	(revision )
@@ -1,122 +1,0 @@
-/*
- * Copyright (c) 2009 Lukas Mejdrech
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (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 socket
- * @{
- */
-
-/** @file
- * Command-line argument parsing functions related to networking.
- */
-
-#include <socket_parse.h>
-#include <arg_parse.h>
-#include <errno.h>
-#include <str.h>
-#include <socket.h>
-
-/** Translate the character string to the address family number.
- *
- * @param[in]  name The address family name.
- * @param[out] af   The corresponding address family number
- *                  or EAFNOSUPPORTED.
- *
- * @return EOK on success.
- * @return ENOTSUP on unsupported address family.
- *
- */
-int socket_parse_address_family(const char *name, int *af)
-{
-	if (str_lcmp(name, "AF_INET", 7) == 0) {
-		*af = AF_INET;
-		return EOK;
-	}
-	
-	if (str_lcmp(name, "AF_INET6", 8) == 0) {
-		*af = AF_INET6;
-		return EOK;
-	}
-	
-	*af = EAFNOSUPPORT;
-	return ENOTSUP;
-}
-
-/** Translate the character string to the protocol family number.
- *
- * @param[in]  name The protocol family name.
- * @param[out] pf   The corresponding protocol family number
- *                  or EPFNOSUPPORTED.
- *
- * @return EOK on success.
- * @return ENOTSUP on unsupported protocol family.
- *
- */
-int socket_parse_protocol_family(const char *name, int *pf)
-{
-	if (str_lcmp(name, "PF_INET", 7) == 0) {
-		*pf = PF_INET;
-		return EOK;
-	}
-	
-	if (str_lcmp(name, "PF_INET6", 8) == 0) {
-		*pf = PF_INET6;
-		return EOK;
-	}
-	
-	*pf = EPFNOSUPPORT;
-	return ENOTSUP;
-}
-
-/** Translate the character string to the socket type number.
- *
- * @param[in]  name  The socket type name.
- * @param[out] sockt The corresponding socket type number
- *                   or ESOCKTNOSUPPORT.
- *
- * @return EOK on success.
- * @return ENOTSUP on unsupported socket type.
- *
- */
-int socket_parse_socket_type(const char *name, int *sockt)
-{
-	if (str_lcmp(name, "SOCK_DGRAM", 11) == 0) {
-		*sockt = SOCK_DGRAM;
-		return EOK;
-	}
-	
-	if (str_lcmp(name, "SOCK_STREAM", 12) == 0) {
-		*sockt = SOCK_STREAM;
-		return EOK;
-	}
-	
-	*sockt = ESOCKTNOSUPPORT;
-	return ENOTSUP;
-}
-
-/** @}
- */
Index: pace/lib/socket/include/adt/char_map.h
===================================================================
--- uspace/lib/socket/include/adt/char_map.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ 	(revision )
@@ -1,142 +1,0 @@
-/*
- * Copyright (c) 2009 Lukas Mejdrech
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (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 net
- *  @{
- */
-
-/** @file
- *  Character string to integer map.
- */
-
-#ifndef __CHAR_MAP_H__
-#define __CHAR_MAP_H__
-
-/** Invalid assigned value used also if an&nbsp;entry does not exist.
- */
-#define CHAR_MAP_NULL	(-1)
-
-/** Type definition of the character string to integer map.
- *  @see char_map
- */
-typedef struct char_map	char_map_t;
-
-/** Type definition of the character string to integer map pointer.
- *  @see char_map
- */
-typedef char_map_t *	char_map_ref;
-
-/** Character string to integer map item.
- *  This structure recursivelly contains itself as a&nbsp;character by character tree.
- *  The actually mapped character string consists o fall the parent characters and the actual one.
- */
-struct	char_map{
-	/** Actually mapped character.
-	 */
-	char c;
-	/** Stored integral value.
-	 */
-	int value;
-	/** Next character array size.
-	 */
-	int size;
-	/** First free position in the next character array.
-	 */
-	int next;
-	/** Next character array.
-	 */
-	char_map_ref * items;
-	/** Consistency check magic value.
-	 */
-	int magic;
-};
-
-/** Adds the value with the key to the map.
- *  @param[in,out] map The character string to integer map.
- *  @param[in] identifier The key zero ('\\0') terminated character string. The key character string is processed until the first terminating zero ('\\0') character after the given length is found.
- *  @param[in] length The key character string length. The parameter may be zero (0) which means that the string is processed until the terminating zero ('\\0') character is found.
- *  @param[in] value The integral value to be stored for the key character string.
- *  @returns EOK on success.
- *  @returns EINVAL if the map is not valid.
- *  @returns EINVAL if the identifier parameter is NULL.
- *  @returns EINVAL if the length parameter zero (0) and the identifier parameter is an empty character string (the first character is the terminating zero ('\\0') character.
- *  @returns EEXIST if the key character string is already used.
- *  @returns Other error codes as defined for the char_map_add_item() function.
- */
-extern int char_map_add(char_map_ref map, const char * identifier, size_t length, const int value);
-
-/** Clears and destroys the map.
- *  @param[in,out] map The character string to integer map.
- */
-extern void char_map_destroy(char_map_ref map);
-
-/** Excludes the value assigned to the key from the map.
- *  The entry is cleared from the map.
- *  @param[in,out] map The character string to integer map.
- *  @param[in] identifier The key zero ('\\0') terminated character string. The key character string is processed until the first terminating zero ('\\0') character after the given length is found.
- *  @param[in] length The key character string length. The parameter may be zero (0) which means that the string is processed until the terminating zero ('\\0') character is found.
- *  @returns The integral value assigned to the key character string.
- *  @returns CHAR_MAP_NULL if the key is not assigned a&nbsp;value.
- */
-extern int char_map_exclude(char_map_ref map, const char * identifier, size_t length);
-
-/** Returns the value assigned to the key from the map.
- *  @param[in] map The character string to integer map.
- *  @param[in] identifier The key zero ('\\0') terminated character string. The key character string is processed until the first terminating zero ('\\0') character after the given length is found.
- *  @param[in] length The key character string length. The parameter may be zero (0) which means that the string is processed until the terminating zero ('\\0') character is found.
- *  @returns The integral value assigned to the key character string.
- *  @returns CHAR_MAP_NULL if the key is not assigned a&nbsp;value.
- */
-extern int char_map_find(const char_map_ref map, const char * identifier, size_t length);
-
-/** Initializes the map.
- *  @param[in,out] map The character string to integer map.
- *  @returns EOK on success.
- *  @returns EINVAL if the map parameter is NULL.
- *  @returns ENOMEM if there is not enough memory left.
- */
-extern int char_map_initialize(char_map_ref map);
-
-/** Adds or updates the value with the key to the map.
- *  @param[in,out] map The character string to integer map.
- *  @param[in] identifier The key zero ('\\0') terminated character string. The key character string is processed until the first terminating zero ('\\0') character after the given length is found.
- *  @param[in] length The key character string length. The parameter may be zero (0) which means that the string is processed until the terminating zero ('\\0') character is found.
- *  @param[in] value The integral value to be stored for the key character string.
- *  @returns EOK on success.
- *  @returns EINVAL if the map is not valid.
- *  @returns EINVAL if the identifier parameter is NULL.
- *  @returns EINVAL if the length parameter zero (0) and the identifier parameter is an empty character string (the first character is the terminating zero ('\\0) character.
- *  @returns EEXIST if the key character string is already used.
- *  @returns Other error codes as defined for the char_map_add_item() function.
- */
-extern int char_map_update(char_map_ref map, const char * identifier, size_t length, const int value);
-
-#endif
-
-/** @}
- */
Index: pace/lib/socket/include/adt/dynamic_fifo.h
===================================================================
--- uspace/lib/socket/include/adt/dynamic_fifo.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ 	(revision )
@@ -1,119 +1,0 @@
-/*
- * Copyright (c) 2009 Lukas Mejdrech
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (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 net
- *  @{
- */
-
-/** @file
- *  Dynamic first in first out positive integer queue.
- *  Possitive integer values only.
- */
-
-#ifndef __NET_DYNAMIC_FIFO_H__
-#define __NET_DYNAMIC_FIFO_H__
-
-/** Type definition of the dynamic fifo queue.
- *  @see dyn_fifo
- */
-typedef struct dyn_fifo	dyn_fifo_t;
-
-/** Type definition of the dynamic fifo queue pointer.
- *  @see dyn_fifo
- */
-typedef dyn_fifo_t *	dyn_fifo_ref;
-
-/** Dynamic first in first out positive integer queue.
- *  Possitive integer values only.
- *  The queue automatically resizes if needed.
- */
-struct dyn_fifo{
-	/** Stored item field.
-	 */
-	int *	items;
-	/** Actual field size.
-	 */
-	int size;
-	/** First item in the queue index.
-	 */
-	int head;
-	/** Last item in the queue index.
-	 */
-	int tail;
-	/** Consistency check magic value.
-	 */
-	int magic_value;
-};
-
-/** Initializes the dynamic queue.
- *  @param[in,out] fifo The dynamic queue.
- *  @param[in] size The initial queue size.
- *  @returns EOK on success.
- *  @returns EINVAL if the queue is not valid.
- *  @returns EBADMEM if the fifo parameter is NULL.
- *  @returns ENOMEM if there is not enough memory left.
- */
-extern int dyn_fifo_initialize(dyn_fifo_ref fifo, int size);
-
-/** Appends a new item to the queue end.
- *  @param[in,out] fifo The dynamic queue.
- *  @param[in] value The new item value. Should be positive.
- *  @param[in] max_size The maximum queue size. The queue is not resized beyound this limit. May be zero or negative (<=0) to indicate no limit.
- *  @returns EOK on success.
- *  @returns EINVAL if the queue is not valid.
- *  @returns ENOMEM if there is not enough memory left.
- */
-extern int dyn_fifo_push(dyn_fifo_ref fifo, int value, int max_size);
-
-/** Returns and excludes the first item in the queue.
- *  @param[in,out] fifo The dynamic queue.
- *  @returns Value of the first item in the queue.
- *  @returns EINVAL if the queue is not valid.
- *  @returns ENOENT if the queue is empty.
- */
-extern int dyn_fifo_pop(dyn_fifo_ref fifo);
-
-/** Returns and keeps the first item in the queue.
- *  @param[in,out] fifo The dynamic queue.
- *  @returns Value of the first item in the queue.
- *  @returns EINVAL if the queue is not valid.
- *  @returns ENOENT if the queue is empty.
- */
-extern int dyn_fifo_value(dyn_fifo_ref fifo);
-
-/** Clears and destroys the queue.
- *  @param[in,out] fifo The dynamic queue.
- *  @returns EOK on success.
- *  @returns EINVAL if the queue is not valid.
- */
-extern int dyn_fifo_destroy(dyn_fifo_ref fifo);
-
-#endif
-
-/** @}
- */
Index: pace/lib/socket/include/adt/generic_char_map.h
===================================================================
--- uspace/lib/socket/include/adt/generic_char_map.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ 	(revision )
@@ -1,161 +1,0 @@
-/*
- * Copyright (c) 2009 Lukas Mejdrech
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (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 net
- *  @{
- */
-
-/** @file
- *  Character string to generic type map.
- */
-
-#ifndef __GENERIC_CHAR_MAP_H__
-#define __GENERIC_CHAR_MAP_H__
-
-#include <errno.h>
-#include <unistd.h>
-
-#include <net_err.h>
-
-#include <adt/char_map.h>
-#include <adt/generic_field.h>
-
-/** Internal magic value for a&nbsp;map consistency check.
- */
-#define GENERIC_CHAR_MAP_MAGIC_VALUE	0x12345622
-
-/** Character string to generic type map declaration.
- *  @param[in] name Name of the map.
- *  @param[in] type Inner object type.
- */
-#define GENERIC_CHAR_MAP_DECLARE(name, type)									\
-																				\
-GENERIC_FIELD_DECLARE(name##_items, type)										\
-																				\
-typedef	struct name		name##_t;												\
-typedef	name##_t *		name##_ref;												\
-																				\
-struct	name{																	\
-	char_map_t names;														\
-	name##_items_t values;														\
-	int magic;														\
-};																				\
-																				\
-int name##_add(name##_ref map, const char * name, const size_t length, type * value);	\
-int name##_count(name##_ref map);												\
-void name##_destroy(name##_ref map);											\
-void name##_exclude(name##_ref map, const char * name, const size_t length);	\
-type * name##_find(name##_ref map, const char * name, const size_t length);		\
-int name##_initialize(name##_ref map);											\
-int name##_is_valid(name##_ref map);
-
-/** Character string to generic type map implementation.
- *  Should follow declaration with the same parameters.
- *  @param[in] name Name of the map.
- *  @param[in] type Inner object type.
- */
-#define GENERIC_CHAR_MAP_IMPLEMENT(name, type)									\
-																				\
-GENERIC_FIELD_IMPLEMENT(name##_items, type)										\
-																				\
-int name##_add(name##_ref map, const char * name, const size_t length, type * value){	\
-	ERROR_DECLARE;																\
-																				\
-	int index;																	\
-																				\
-	if(! name##_is_valid(map)){													\
-		return EINVAL;															\
-	}																			\
-	index = name##_items_add(&map->values, value);								\
-	if(index < 0){																\
-		return index;															\
-	}																			\
-	if(ERROR_OCCURRED(char_map_add(&map->names, name, length, index))){			\
-		name##_items_exclude_index(&map->values, index);						\
-		return ERROR_CODE;														\
-	}																			\
-	return EOK;																	\
-}																				\
-																				\
-int name##_count(name##_ref map){												\
-	return name##_is_valid(map) ? name##_items_count(&map->values) : -1;		\
-}																				\
-																				\
-void name##_destroy(name##_ref map){											\
-	if(name##_is_valid(map)){													\
-		char_map_destroy(&map->names);											\
-		name##_items_destroy(&map->values);										\
-	}																			\
-}																				\
-																				\
-void name##_exclude(name##_ref map, const char * name, const size_t length){	\
-	if(name##_is_valid(map)){													\
-		int index;																\
-																				\
-		index = char_map_exclude(&map->names, name, length);					\
-		if(index != CHAR_MAP_NULL){												\
-			name##_items_exclude_index(&map->values, index);					\
-		}																		\
-	}																			\
-}																				\
-																				\
-type * name##_find(name##_ref map, const char * name, const size_t length){		\
-	if(name##_is_valid(map)){													\
-		int index;																\
-																				\
-		index = char_map_find(&map->names, name, length);						\
-		if(index != CHAR_MAP_NULL){												\
-			return name##_items_get_index(&map->values, index);					\
-		}																		\
-	}																			\
-	return NULL;																\
-}																				\
-																				\
-int name##_initialize(name##_ref map){											\
-	ERROR_DECLARE;																\
-																				\
-	if(! map){																	\
-		return EINVAL;															\
-	}																			\
-	ERROR_PROPAGATE(char_map_initialize(&map->names));							\
-	if(ERROR_OCCURRED(name##_items_initialize(&map->values))){					\
-		char_map_destroy(&map->names);											\
-		return ERROR_CODE;														\
-	}																			\
-	map->magic = GENERIC_CHAR_MAP_MAGIC_VALUE;									\
-	return EOK;																	\
-}																				\
-																				\
-int name##_is_valid(name##_ref map){											\
-	return map && (map->magic == GENERIC_CHAR_MAP_MAGIC_VALUE);					\
-}
-
-#endif
-
-/** @}
- */
Index: pace/lib/socket/include/adt/generic_field.h
===================================================================
--- uspace/lib/socket/include/adt/generic_field.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ 	(revision )
@@ -1,160 +1,0 @@
-/*
- * Copyright (c) 2009 Lukas Mejdrech
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (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 net
- *  @{
- */
-
-/** @file
- *  Generic type field.
- */
-
-#ifndef __GENERIC_FIELD_H__
-#define __GENERIC_FIELD_H__
-
-#include <errno.h>
-#include <malloc.h>
-#include <mem.h>
-#include <unistd.h>
-
-/** Internal magic value for a&nbsp;field consistency check.
- */
-#define GENERIC_FIELD_MAGIC_VALUE		0x55667788
-
-/** Generic type field declaration.
- *  @param[in] name Name of the field.
- *  @param[in] type Inner object type.
- */
-#define GENERIC_FIELD_DECLARE(name, type)										\
-																				\
-typedef	struct name		name##_t;												\
-typedef	name##_t *		name##_ref;												\
-																				\
-struct	name{																	\
-	int size;																	\
-	int next;																	\
-	type **	items;																\
-	int magic;																	\
-};																				\
-																				\
-int name##_add(name##_ref field, type * value);									\
-int name##_count(name##_ref field);												\
-void name##_destroy(name##_ref field);											\
-void name##_exclude_index(name##_ref field, int index);							\
-type ** name##_get_field(name##_ref field);										\
-type * name##_get_index(name##_ref field, int index);							\
-int name##_initialize(name##_ref field);										\
-int name##_is_valid(name##_ref field);
-
-/** Generic type field implementation.
- *  Should follow declaration with the same parameters.
- *  @param[in] name Name of the field.
- *  @param[in] type Inner object type.
- */
-#define GENERIC_FIELD_IMPLEMENT(name, type)										\
-																				\
-int name##_add(name##_ref field, type * value){									\
-	if(name##_is_valid(field)){													\
-		if(field->next == (field->size - 1)){									\
-			type **	tmp;														\
-																				\
-			tmp = (type **) realloc(field->items, sizeof(type *) * 2 * field->size);	\
-			if(! tmp){															\
-				return ENOMEM;													\
-			}																	\
-			field->size *= 2;													\
-			field->items = tmp;													\
-		}																		\
-		field->items[field->next] = value;										\
-		++ field->next;															\
-		field->items[field->next] = NULL;										\
-		return field->next - 1;													\
-	}																			\
-	return EINVAL;																\
-}																				\
-																				\
-int name##_count(name##_ref field){												\
-	return name##_is_valid(field) ? field->next : -1;							\
-}																				\
-																				\
-void name##_destroy(name##_ref field){											\
-	if(name##_is_valid(field)){													\
-		int index;																\
-																				\
-		field->magic = 0;														\
-		for(index = 0; index < field->next; ++ index){							\
-			if(field->items[index]){											\
-				free(field->items[index]);										\
-			}																	\
-		}																		\
-		free(field->items);														\
-	}																			\
-}																				\
-																				\
-void name##_exclude_index(name##_ref field, int index){							\
-	if(name##_is_valid(field) && (index >= 0) && (index < field->next) && (field->items[index])){	\
-		free(field->items[index]);												\
-		field->items[index] = NULL;												\
-	}																			\
-}																				\
-																				\
-type * name##_get_index(name##_ref field, int index){							\
-	if(name##_is_valid(field) && (index >= 0) && (index < field->next) && (field->items[index])){	\
-		return field->items[index];												\
-	}																			\
-	return NULL;																\
-}																				\
-																				\
-type ** name##_get_field(name##_ref field){										\
-	return name##_is_valid(field) ? field->items : NULL;						\
-}																				\
-																				\
-int name##_initialize(name##_ref field){										\
-	if(! field){																\
-		return EINVAL;															\
-	}																			\
-	field->size = 2;															\
-	field->next = 0;															\
-	field->items = (type **) malloc(sizeof(type *) * field->size);				\
-	if(! field->items){															\
-		return ENOMEM;															\
-	}																			\
-	field->items[field->next] = NULL;											\
-	field->magic = GENERIC_FIELD_MAGIC_VALUE;									\
-	return EOK;																	\
-}																				\
-																				\
-int name##_is_valid(name##_ref field){											\
-	return field && (field->magic == GENERIC_FIELD_MAGIC_VALUE);				\
-}
-
-#endif
-
-/** @}
- */
-
Index: pace/lib/socket/include/adt/int_map.h
===================================================================
--- uspace/lib/socket/include/adt/int_map.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ 	(revision )
@@ -1,247 +1,0 @@
-/*
- * Copyright (c) 2009 Lukas Mejdrech
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (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 net
- *  @{
- */
-
-/** @file
- *  Integer to generic type map.
- */
-
-#ifndef __NET_INT_MAP_H__
-#define __NET_INT_MAP_H__
-
-#include <errno.h>
-#include <malloc.h>
-#include <mem.h>
-#include <unistd.h>
-
-/** Internal magic value for a&nbsp;map consistency check.
- */
-#define INT_MAP_MAGIC_VALUE			0x11223344
-
-/** Internal magic value for an item consistency check.
- */
-#define INT_MAP_ITEM_MAGIC_VALUE	0x55667788
-
-/** Integer to generic type map declaration.
- *  @param[in] name Name of the map.
- *  @param[in] type Inner object type.
- */
-#define INT_MAP_DECLARE(name, type)												\
-																				\
-typedef	struct name			name##_t;											\
-typedef	name##_t *			name##_ref;											\
-typedef	struct name##_item	name##_item_t;										\
-typedef	name##_item_t *		name##_item_ref;									\
-																				\
-struct	name##_item{															\
-	int key;																\
-	type * value;																\
-	int magic;																\
-};																				\
-																				\
-struct	name{																	\
-	int size;														\
-	int next;														\
-	name##_item_ref items;														\
-	int magic;														\
-};																				\
-																				\
-int name##_add(name##_ref map, int key, type * value);							\
-void name##_clear(name##_ref map);												\
-int name##_count(name##_ref map);												\
-void name##_destroy(name##_ref map);											\
-void name##_exclude(name##_ref map, int key);									\
-void name##_exclude_index(name##_ref map, int index);							\
-type * name##_find(name##_ref map, int key);									\
-int name##_update(name##_ref map, int key, int new_key);						\
-type * name##_get_index(name##_ref map, int index);								\
-int name##_initialize(name##_ref map);											\
-int name##_is_valid(name##_ref map);											\
-void name##_item_destroy(name##_item_ref item);									\
-int name##_item_is_valid(name##_item_ref item);
-
-/** Integer to generic type map implementation.
- *  Should follow declaration with the same parameters.
- *  @param[in] name Name of the map.
- *  @param[in] type Inner object type.
- */
-#define INT_MAP_IMPLEMENT(name, type)											\
-																				\
-int name##_add(name##_ref map, int key, type * value){							\
-	if(name##_is_valid(map)){													\
-		if(map->next == (map->size - 1)){										\
-			name##_item_ref tmp;												\
-																				\
-			tmp = (name##_item_ref) realloc(map->items, sizeof(name##_item_t) * 2 * map->size);	\
-			if(! tmp){															\
-				return ENOMEM;													\
-			}																	\
-			map->size *= 2;														\
-			map->items = tmp;													\
-		}																		\
-		map->items[map->next].key = key;										\
-		map->items[map->next].value = value;									\
-		map->items[map->next].magic = INT_MAP_ITEM_MAGIC_VALUE;					\
-		++ map->next;															\
-		map->items[map->next].magic = 0;										\
-		return map->next - 1;													\
-	}																			\
-	return EINVAL;																\
-}																				\
-																				\
-void name##_clear(name##_ref map){												\
-	if(name##_is_valid(map)){													\
-		int index;																\
-																				\
-/*		map->magic = 0;*/														\
-		for(index = 0; index < map->next; ++ index){							\
-			if(name##_item_is_valid(&(map->items[index]))){						\
-				name##_item_destroy(&(map->items[index]));						\
-			}																	\
-		}																		\
-		map->next = 0;															\
-		map->items[map->next].magic = 0;										\
-/*		map->magic = INT_MAP_MAGIC_VALUE;*/										\
-	}																			\
-}																				\
-																				\
-int name##_count(name##_ref map){												\
-	return name##_is_valid(map) ? map->next : -1;								\
-}																				\
-																				\
-void name##_destroy(name##_ref map){											\
-	if(name##_is_valid(map)){													\
-		int index;																\
-																				\
-		map->magic = 0;															\
-		for(index = 0; index < map->next; ++ index){							\
-			if(name##_item_is_valid(&(map->items[index]))){						\
-				name##_item_destroy(&(map->items[index]));						\
-			}																	\
-		}																		\
-		free(map->items);														\
-	}																			\
-}																				\
-																				\
-void name##_exclude(name##_ref map, int key){									\
-	if(name##_is_valid(map)){													\
-		int index;																\
-																				\
-		for(index = 0; index < map->next; ++ index){							\
-			if(name##_item_is_valid(&(map->items[index])) && (map->items[index].key == key)){	\
-				name##_item_destroy(&(map->items[index]));						\
-			}																	\
-		}																		\
-	}																			\
-}																				\
-																				\
-void name##_exclude_index(name##_ref map, int index){							\
-	if(name##_is_valid(map) && (index >= 0) && (index < map->next) && name##_item_is_valid(&(map->items[index]))){	\
-		name##_item_destroy(&(map->items[index]));								\
-	}																			\
-}																				\
-																				\
-type * name##_find(name##_ref map, int key){									\
-	if(name##_is_valid(map)){													\
-		int index;																\
-																				\
-		for(index = 0; index < map->next; ++ index){							\
-			if(name##_item_is_valid(&(map->items[index])) && (map->items[index].key == key)){	\
-				return map->items[index].value;									\
-			}																	\
-		}																		\
-	}																			\
-	return NULL;																\
-}																				\
-																				\
-int name##_update(name##_ref map, int key, int new_key){						\
-	if(name##_is_valid(map)){													\
-		int index;																\
-																				\
-		for(index = 0; index < map->next; ++ index){							\
-			if(name##_item_is_valid(&(map->items[index]))){						\
-				if(map->items[index].key == new_key){							\
-					return EEXIST;												\
-				}else if(map->items[index].key == key){							\
-					map->items[index].key = new_key;							\
-					return EOK;													\
-				}																\
-			}																	\
-		}																		\
-	}																			\
-	return ENOENT;																\
-}																				\
-																				\
-type * name##_get_index(name##_ref map, int index){								\
-	if(name##_is_valid(map) && (index >= 0) && (index < map->next) && name##_item_is_valid(&(map->items[index]))){	\
-		return map->items[index].value;											\
-	}																			\
-	return NULL;																\
-}																				\
-																				\
-int name##_initialize(name##_ref map){											\
-	if(! map){																	\
-		return EINVAL;															\
-	}																			\
-	map->size = 2;																\
-	map->next = 0;																\
-	map->items = (name##_item_ref) malloc(sizeof(name##_item_t) * map->size);	\
-	if(! map->items){															\
-		return ENOMEM;															\
-	}																			\
-	map->items[map->next].magic = 0;											\
-	map->magic = INT_MAP_MAGIC_VALUE;											\
-	return EOK;																	\
-}																				\
-																				\
-int name##_is_valid(name##_ref map){											\
-	return map && (map->magic == INT_MAP_MAGIC_VALUE);							\
-}																				\
-																				\
-void name##_item_destroy(name##_item_ref item){									\
-	if(name##_item_is_valid(item)){												\
-		item->magic = 0;														\
-		if(item->value){														\
-			free(item->value);													\
-			item->value = NULL;													\
-		}																		\
-	}																			\
-}																				\
-																				\
-int name##_item_is_valid(name##_item_ref item){									\
-	return item && (item->magic == INT_MAP_ITEM_MAGIC_VALUE);					\
-}
-
-#endif
-
-/** @}
- */
-
Index: pace/lib/socket/include/adt/measured_strings.h
===================================================================
--- uspace/lib/socket/include/adt/measured_strings.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ 	(revision )
@@ -1,144 +1,0 @@
-/*
- * Copyright (c) 2009 Lukas Mejdrech
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (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 net
- *  @{
- */
-
-/** @file
- *  Character string with measured length.
- *  The structure has been designed for serialization of character strings between modules.
- */
-
-#ifndef __MEASURED_STRINGS_H__
-#define __MEASURED_STRINGS_H__
-
-#include <sys/types.h>
-
-/** Type definition of the character string with measured length.
- *  @see measured_string
- */
-typedef struct measured_string	measured_string_t;
-
-/** Type definition of the character string with measured length pointer.
- *  @see measured_string
- */
-typedef measured_string_t *		measured_string_ref;
-
-/** Character string with measured length.
- *  This structure has been designed for serialization of character strings between modules.
- */
-struct	measured_string{
-	/** Character string data.
-	 */
-	char * value;
-	/** Character string length.
-	 */
-	size_t length;
-};
-
-/** Creates a&nbsp;new measured string bundled with a&nbsp;copy of the given string itself as one memory block.
- *  If the measured string is being freed, whole memory block is freed.
- *  The measured string should be used only as a&nbsp;constant.
- *  @param[in] string The initial character string to be stored.
- *  @param[in] length The length of the given string without the terminating zero ('/0') character. If the length is zero (0), the actual length is computed. The given length is used and appended with the terminating zero ('\\0') character otherwise.
- *  @returns The new bundled character string with measured length.
- *  @returns NULL if there is not enough memory left.
- */
-extern measured_string_ref measured_string_create_bulk(const char * string, size_t length);
-
-/** Copies the given measured string with separated header and data parts.
- *  @param[in] source The source measured string to be copied.
- *  @returns The copy of the given measured string.
- *  @returns NULL if the source parameter is NULL.
- *  @returns NULL if there is not enough memory left.
- */
-extern measured_string_ref measured_string_copy(measured_string_ref source);
-
-/** Receives a&nbsp;measured strings array from a&nbsp;calling module.
- *  Creates the array and the data memory blocks.
- *  This method should be used only while processing IPC messages as the array size has to be negotiated in advance.
- *  @param[out] strings The received measured strings array.
- *  @param[out] data The measured strings data. This memory block stores the actual character strings.
- *  @param[in] count The size of the measured strings array.
- *  @returns EOK on success.
- *  @returns EINVAL if the strings or data parameter is NULL.
- *  @returns EINVAL if the count parameter is zero (0).
- *  @returns EINVAL if the sent array differs in size.
- *  @returns EINVAL if there is inconsistency in sent measured strings' lengths (should not occur).
- *  @returns ENOMEM if there is not enough memory left.
- *  @returns Other error codes as defined for the async_data_write_finalize() function.
- */
-extern int measured_strings_receive(measured_string_ref * strings, char ** data, size_t count);
-
-/** Replies the given measured strings array to a&nbsp;calling module.
- *  This method should be used only while processing IPC messages as the array size has to be negotiated in advance.
- *  @param[in] strings The measured strings array to be transferred.
- *  @param[in] count The measured strings array size.
- *  @returns EOK on success.
- *  @returns EINVAL if the strings parameter is NULL.
- *  @returns EINVAL if the count parameter is zero (0).
- *  @returns EINVAL if the calling module does not accept the given array size.
- *  @returns EINVAL if there is inconsistency in sent measured strings' lengths (should not occur).
- *  @returns Other error codes as defined for the async_data_read_finalize() function.
- */
-extern int measured_strings_reply(const measured_string_ref strings, size_t count);
-
-/** Receives a&nbsp;measured strings array from another module.
- *  Creates the array and the data memory blocks.
- *  This method should be used only following other IPC messages as the array size has to be negotiated in advance.
- *  @param[in] phone The other module phone.
- *  @param[out] strings The returned measured strings array.
- *  @param[out] data The measured strings data. This memory block stores the actual character strings.
- *  @param[in] count The size of the measured strings array.
- *  @returns EOK on success.
- *  @returns EINVAL if the strings or data parameter is NULL.
- *  @returns EINVAL if the phone or count parameter is not positive (<=0).
- *  @returns EINVAL if the sent array differs in size.
- *  @returns ENOMEM if there is not enough memory left.
- *  @returns Other error codes as defined for the async_data_read_start() function.
- */
-extern int measured_strings_return(int phone, measured_string_ref * strings, char ** data, size_t count);
-
-/** Sends the given measured strings array to another module.
- *  This method should be used only following other IPC messages as the array size has to be negotiated in advance.
- *  @param[in] phone The other module phone.
- *  @param[in] strings The measured strings array to be transferred.
- *  @param[in] count The measured strings array size.
- *  @returns EOK on success.
- *  @returns EINVAL if the strings parameter is NULL.
- *  @returns EINVAL if the phone or count parameter is not positive (<=0).
- *  @returns Other error codes as defined for the async_data_write_start() function.
- */
-extern int measured_strings_send(int phone, const measured_string_ref strings, size_t count);
-
-#endif
-
-/** @}
- */
-
Index: pace/lib/socket/include/icmp_api.h
===================================================================
--- uspace/lib/socket/include/icmp_api.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ 	(revision )
@@ -1,85 +1,0 @@
-/*
- * Copyright (c) 2009 Lukas Mejdrech
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (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 icmp
- *  @{
- */
-
-/** @file
- *  ICMP module application interface.
- */
-
-#ifndef __NET_ICMP_API_H__
-#define __NET_ICMP_API_H__
-
-#include <sys/types.h>
-
-#include <net_device.h>
-#include <adt/measured_strings.h>
-#include <packet/packet.h>
-#include <inet.h>
-#include <ip_codes.h>
-#include <socket_codes.h>
-#include <icmp_codes.h>
-#include <icmp_common.h>
-
-/** Miliseconds type definition.
- */
-typedef size_t	mseconds_t;
-
-/** @name ICMP module application interface
- *  This interface is used by other application modules.
- */
-/*@{*/
-
-/** Requests an echo message.
- *  Sends a packet with specified parameters to the target host and waits for the reply upto the given timeout.
- *  Blocks the caller until the reply or the timeout occurres.
- *  @param[in] icmp_phone The ICMP module phone used for (semi)remote calls.
- *  @param[in] size The message data length in bytes.
- *  @param[in] timeout The timeout in miliseconds.
- *  @param[in] ttl The time to live.
- *  @param[in] tos The type of service.
- *  @param[in] dont_fragment The value indicating whether the datagram must not be fragmented. Is used as a MTU discovery.
- *  @param[in] addr The target host address.
- *  @param[in] addrlen The torget host address length.
- *  @returns ICMP_ECHO on success.
- *  @returns ETIMEOUT if the reply has not arrived before the timeout.
- *  @returns ICMP type of the received error notification. 
- *  @returns EINVAL if the addrlen parameter is less or equal to zero (<=0).
- *  @returns ENOMEM if there is not enough memory left.
- *  @returns EPARTY if there was an internal error.
- */
-extern int icmp_echo_msg(int icmp_phone, size_t size, mseconds_t timeout, ip_ttl_t ttl, ip_tos_t tos, int dont_fragment, const struct sockaddr * addr, socklen_t addrlen);
-
-/*@}*/
-
-#endif
-
-/** @}
- */
Index: pace/lib/socket/include/icmp_codes.h
===================================================================
--- uspace/lib/socket/include/icmp_codes.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ 	(revision )
@@ -1,347 +1,0 @@
-/*
- * Copyright (c) 2009 Lukas Mejdrech
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (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 icmp
- *  @{
- */
-
-/** @file
- *  ICMP types and codes according to the on-line IANA - ICMP Type Numbers - <http://http://www.iana.org/assignments/icmp-parameters>, cited September 14 2009.
- */
-
-#ifndef __NET_ICMP_CODES_H__
-#define __NET_ICMP_CODES_H__
-
-/** ICMP type type definition.
- */
-typedef uint8_t	icmp_type_t;
-
-/** ICMP code type definition.
- */
-typedef uint8_t	icmp_code_t;
-
-/** ICMP parameter type definition.
- */
-typedef uint16_t	icmp_param_t;
-
-/** @name ICMP types definitions
- */
-/*@{*/
-
-/** Echo Reply.
- */
-#define ICMP_ECHOREPLY		0
-
-/** Destination Unreachable.
- */
-#define ICMP_DEST_UNREACH	3
-
-/** Source Quench.
- */
-#define ICMP_SOURCE_QUENCH	4
-
-/** Redirect.
- */
-#define ICMP_REDIRECT		5
-
-/** Alternate Host Address.
- */
-#define ICMP_ALTERNATE_ADDR	6
-
-/** Echo Request.
- */
-#define ICMP_ECHO			8
-
-/** Router Advertisement.
- */
-#define ICMP_ROUTER_ADV		9
-
-/** Router solicitation.
- */
-#define ICMP_ROUTER_SOL		10
-
-/** Time Exceeded.
- */
-#define ICMP_TIME_EXCEEDED	11
-
-/** Parameter Problem.
- */
-#define ICMP_PARAMETERPROB	12
-
-/** Timestamp Request.
- */
-#define ICMP_TIMESTAMP		13
-
-/** Timestamp Reply.
- */
-#define ICMP_TIMESTAMPREPLY	14
-
-/** Information Request.
- */
-#define ICMP_INFO_REQUEST	15
-
-/** Information Reply.
- */
-#define ICMP_INFO_REPLY		16
-
-/** Address Mask Request.
- */
-#define ICMP_ADDRESS		17
-
-/** Address Mask Reply.
- */
-#define ICMP_ADDRESSREPLY	18
-
-/** Traceroute.
- */
-#define ICMP_TRACEROUTE		30
-
-/** Datagram Conversion Error.
- */
-#define ICMP_CONVERSION_ERROR	31
-
-/** Mobile Host Redirect.
- */
-#define ICMP_REDIRECT_MOBILE	32
-
-/** IPv6 Where-Are-You.
- */
-#define ICMP_IPV6_WHERE_ARE_YOU	33
-
-/** IPv6 I-Am-Here.
- */
-#define ICMP_IPV6_I_AM_HERE	34
-
-/** Mobile Registration Request.
- */
-#define ICMP_MOBILE_REQUEST	35
-
-/** Mobile Registration Reply.
- */
-#define ICMP_MOBILE_REPLY	36
-
-/** Domain name request.
- */
-#define ICMP_DN_REQUEST		37
-
-/** Domain name reply.
- */
-#define ICMP_DN_REPLY		38
-
-/** SKIP.
- */
-#define ICMP_SKIP			39
-
-/** Photuris.
- */
-#define ICMP_PHOTURIS		40
-
-/*@}*/
-
-/** @name ICMP_DEST_UNREACH codes definitions
- */
-/*@{*/
-
-/** Network Unreachable.
- */
-#define ICMP_NET_UNREACH	0
-
-/** Host Unreachable.
- */
-#define ICMP_HOST_UNREACH	1
-
-/** Protocol Unreachable.
- */
-#define ICMP_PROT_UNREACH	2
-
-/** Port Unreachable.
- */
-#define ICMP_PORT_UNREACH	3
-
-/** Fragmentation needed but the Do Not Fragment bit was set.
- */
-#define ICMP_FRAG_NEEDED	4
-
-/** Source Route failed.
- */
-#define ICMP_SR_FAILED		5
-
-/** Destination network unknown.
- */
-#define ICMP_NET_UNKNOWN	6
-
-/** Destination host unknown.
- */
-#define ICMP_HOST_UNKNOWN	7
-
-/** Source host isolated (obsolete).
- */
-#define ICMP_HOST_ISOLATED	8
-
-/** Destination network administratively prohibited.
- */
-#define ICMP_NET_ANO		9
-
-/** Destination host administratively prohibited.
- */
-#define ICMP_HOST_ANO		10
-
-/** Network unreachable for this type of service.
- */
-#define ICMP_NET_UNR_TOS	11
-
-/** Host unreachable for this type of service.
- */
-#define ICMP_HOST_UNR_TOS	12
-
-/** Communication administratively prohibited by filtering.
- */
-#define ICMP_PKT_FILTERED	13
-
-/** Host precedence violation.
- */
-#define ICMP_PREC_VIOLATION	14
-
-/** Precedence cutoff in effect.
- */
-#define ICMP_PREC_CUTOFF	15
-
-/*@}*/
-
-/** @name ICMP_REDIRECT codes definitions
- */
-/*@{*/
-
-/** Network redirect (or subnet).
- */
-#define ICMP_REDIR_NET		0
-
-/** Host redirect.
- */
-#define ICMP_REDIR_HOST		1
-
-/** Network redirect for this type of service.
- */
-#define ICMP_REDIR_NETTOS	2
-
-/** Host redirect for this type of service.
- */
-#define ICMP_REDIR_HOSTTOS	3
-
-/*@}*/
-
-/** @name ICMP_ALTERNATE_ADDRESS codes definitions
- */
-/*@{*/
-
-/** Alternate address for host.
- */
-#define ICMP_ALTERNATE_HOST	0
-
-/*@}*/
-
-/** @name ICMP_ROUTER_ADV codes definitions
- */
-/*@{*/
-
-/** Normal router advertisement.
- */
-#define ICMP_ROUTER_NORMAL	0
-
-/** Does not route common traffic.
- */
-#define ICMP_ROUTER_NO_NORMAL_TRAFFIC	16
-
-/*@}*/
-
-/** @name ICMP_TIME_EXCEEDED codes definitions
- */
-/*@{*/
-
-/** Transit TTL exceeded.
- */
-#define ICMP_EXC_TTL		0
-
-/** Reassembly TTL exceeded.
- */
-#define ICMP_EXC_FRAGTIME	1
-
-/*@}*/
-
-/** @name ICMP_PARAMETERPROB codes definitions
- */
-/*@{*/
-
-/** Pointer indicates the error.
- */
-#define ICMP_PARAM_POINTER	0
-
-/** Missing required option.
- */
-#define ICMP_PARAM_MISSING	1
-
-/** Bad length.
- */
-#define ICMP_PARAM_LENGTH	2
-
-/*@}*/
-
-/** @name ICMP_PHOTURIS codes definitions
- */
-/*@{*/
-
-/** Bad SPI.
- */
-#define ICMP_PHOTURIS_BAD_SPI	0
-
-/** Authentication failed.
- */
-#define ICMP_PHOTURIS_AUTHENTICATION	1
-
-/** Decompression failed.
- */
-#define ICMP_PHOTURIS_DECOMPRESSION		2
-
-/** Decryption failed.
- */
-#define ICMP_PHOTURIS_DECRYPTION	3
-
-/** Need authentication.
- */
-#define ICMP_PHOTURIS_NEED_AUTHENTICATION	4
-
-/** Need authorization.
- */
-#define ICMP_PHOTURIS_NEED_AUTHORIZATION	5
-
-/*@}*/
-
-#endif
-
-/** @}
- */
Index: pace/lib/socket/include/icmp_common.h
===================================================================
--- uspace/lib/socket/include/icmp_common.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ 	(revision )
@@ -1,60 +1,0 @@
-/*
- * Copyright (c) 2009 Lukas Mejdrech
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (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 icmp
- *  @{
- */
-
-/** @file
- *  ICMP module common interface.
- */
-
-#ifndef __NET_ICMP_COMMON_H__
-#define __NET_ICMP_COMMON_H__
-
-#include <ipc/services.h>
-
-#include <sys/time.h>
-
-/** Default timeout for incoming connections in microseconds.
- */
-#define ICMP_CONNECT_TIMEOUT	(1 * 1000 * 1000)
-
-/** Connects to the ICMP module.
- *  @param service The ICMP module service. Ignored parameter.
- *  @param[in] timeout The connection timeout in microseconds. No timeout if set to zero (0).
- *  @returns The ICMP module phone on success.
- *  @returns The ICMP socket identifier if called by the bundle module.
- *  @returns ETIMEOUT if the connection timeouted.
- */
-extern int icmp_connect_module(services_t service, suseconds_t timeout);
-
-#endif
-
-/** @}
- */
Index: pace/lib/socket/include/icmp_messages.h
===================================================================
--- uspace/lib/socket/include/icmp_messages.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ 	(revision )
@@ -1,132 +1,0 @@
-/*
- * Copyright (c) 2009 Lukas Mejdrech
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (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 icmp
- *  @{
- */
-
-/** @file
- *  ICMP module messages.
- *  @see icmp_interface.h
- */
-
-#ifndef __NET_ICMP_MESSAGES__
-#define __NET_ICMP_MESSAGES__
-
-#include <ipc/ipc.h>
-#include <sys/types.h>
-
-#include <icmp_codes.h>
-#include <net_messages.h>
-
-/** ICMP module messages.
- */
-typedef enum{
-	/** Sends echo request.
-	 *  @see icmp_echo()
-	 */
-	NET_ICMP_ECHO = NET_ICMP_FIRST,
-	/** Sends destination unreachable error message.
-	 *  @see icmp_destination_unreachable_msg()
-	 */
-	NET_ICMP_DEST_UNREACH,
-	/** Sends source quench error message.
-	 *  @see icmp_source_quench_msg()
-	 */
-	NET_ICMP_SOURCE_QUENCH,
-	/** Sends time exceeded error message.
-	 *  @see icmp_time_exceeded_msg()
-	 */
-	NET_ICMP_TIME_EXCEEDED,
-	/** Sends parameter problem error message.
-	 *  @see icmp_parameter_problem_msg()
-	 */
-	NET_ICMP_PARAMETERPROB,
-	/** Initializes new connection.
-	 */
-	NET_ICMP_INIT
-} icmp_messages;
-
-/** @name ICMP specific message parameters definitions
- */
-/*@{*/
-
-/** Returns the ICMP code message parameter.
- *  @param[in] call The message call structure.
- */
-#define ICMP_GET_CODE(call) \
-	({icmp_code_t code = (icmp_code_t) IPC_GET_ARG1(*call); code;})
-
-/** Returns the ICMP link MTU message parameter.
- *  @param[in] call The message call structure.
- */
-#define ICMP_GET_MTU(call) \
-	({icmp_param_t mtu = (icmp_param_t) IPC_GET_ARG3(*call); mtu;})
-
-/** Returns the pointer message parameter.
- *  @param[in] call The message call structure.
- */
-#define ICMP_GET_POINTER(call) \
-	({icmp_param_t pointer = (icmp_param_t) IPC_GET_ARG3(*call); pointer;})
-
-/** Returns the size message parameter.
- *  @param[in] call The message call structure.
- */
-#define ICMP_GET_SIZE(call) \
-	({size_t size = (size_t) IPC_GET_ARG1(call); size;})
-
-/** Returns the timeout message parameter.
- *  @param[in] call The message call structure.
- */
-#define ICMP_GET_TIMEOUT(call) \
-	(({suseconds_t timeout = (suseconds_t) IPC_GET_ARG2(call); timeout;}))
-
-/** Returns the time to live message parameter.
- *  @param[in] call The message call structure.
- */
-#define ICMP_GET_TTL(call) \
-	({ip_ttl_t ttl = (ip_ttl_t) IPC_GET_ARG3(call); ttl;})
-
-/** Returns the type of service message parameter.
- *  @param[in] call The message call structure.
- */
-#define ICMP_GET_TOS(call) \
-	({ip_tos_t tos = (ip_tos_t) IPC_GET_ARG4(call); tos;})
-
-/** Returns the dont fragment message parameter.
- *  @param[in] call The message call structure.
- */
-#define ICMP_GET_DONT_FRAGMENT(call) \
-	({int dont_fragment = (int) IPC_GET_ARG5(call); dont_fragment;})
-
-/*@}*/
-
-#endif
-
-/** @}
- */
Index: pace/lib/socket/include/in.h
===================================================================
--- uspace/lib/socket/include/in.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ 	(revision )
@@ -1,89 +1,0 @@
-/*
- * Copyright (c) 2009 Lukas Mejdrech
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (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 net
- *  @{
- */
-
-/** @file
- *  INET family common definitions.
- */
-
-#ifndef __NET_IN_H__
-#define __NET_IN_H__
-
-#include <sys/types.h>
-
-#include <ip_protocols.h>
-#include <inet.h>
-
-/** INET string address maximum length.
- */
-#define INET_ADDRSTRLEN		(4 * 3 + 3 + 1)
-
-/** Type definition of the INET address.
- *  @see in_addr
- */
-typedef struct in_addr		in_addr_t;
-
-/** Type definition of the INET socket address.
- *  @see sockaddr_in
- */
-typedef struct sockaddr_in	sockaddr_in_t;
-
-/** INET address.
- */
-struct in_addr{
-	/** 4 byte IP address.
-	 */
-	uint32_t s_addr;
-};
-
-/** INET socket address.
- *  @see sockaddr
- */
-struct sockaddr_in{
-	/** Address family.
-	 *  Should be AF_INET.
-	 */
-	uint16_t sin_family;
-	/** Port number.
-	 */
-	uint16_t sin_port;
-	/** Internet address.
-	 */
-	struct in_addr sin_addr;
-	/** Padding to meet the sockaddr size.
-	 */
-	uint8_t sin_zero[8];
-};
-
-#endif
-
-/** @}
- */
Index: pace/lib/socket/include/in6.h
===================================================================
--- uspace/lib/socket/include/in6.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ 	(revision )
@@ -1,92 +1,0 @@
-/*
- * Copyright (c) 2009 Lukas Mejdrech
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (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 net
- *  @{
- */
-
-/** @file
- *  INET6 family common definitions.
- */
-
-#ifndef __NET_IN6_H__
-#define __NET_IN6_H__
-
-#include <sys/types.h>
-
-#include <ip_protocols.h>
-#include <inet.h>
-
-/** INET6 string address maximum length.
- */
-#define INET6_ADDRSTRLEN	(8 * 4 + 7 + 1)
-
-/** Type definition of the INET6 address.
- *  @see in6_addr
- */
-typedef struct in6_addr	in6_addr_t;
-
-/** Type definition of the INET6 socket address.
- *  @see sockaddr_in6
- */
-typedef struct sockaddr_in6	sockaddr_in6_t;
-
-/** INET6 address.
- */
-struct in6_addr{
-	/** 16 byte IPv6 address.
-	 */
-	unsigned char s6_addr[16];
-};
-
-/** INET6 socket address.
- *  @see sockaddr
- */
-struct sockaddr_in6{
-	/** Address family.
-	 *  Should be AF_INET6.
-	 */
-	uint16_t sin6_family;
-	/** Port number.
-	 */
-	uint16_t sin6_port;
-	/** IPv6 flow information.
-	 */
-	uint32_t sin6_flowinfo;
-	/** IPv6 address.
-	 */
-	struct in6_addr sin6_addr;
-	/** Scope identifier.
-	 */
-	uint32_t sin6_scope_id;
-};
-
-#endif
-
-/** @}
- */
Index: pace/lib/socket/include/inet.h
===================================================================
--- uspace/lib/socket/include/inet.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ 	(revision )
@@ -1,115 +1,0 @@
-/*
- * Copyright (c) 2009 Lukas Mejdrech
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (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 net
- *  @{
- */
-
-/** @file
- *  Internet common definitions.
- */
-
-#ifndef __NET_INET_H__
-#define __NET_INET_H__
-
-#include <sys/types.h>
-
-#include <net_byteorder.h>
-
-/** Type definition of the socket address.
- *  @see sockaddr
- */
-typedef struct sockaddr		sockaddr_t;
-
-/** Type definition of the address information.
- *  @see addrinfo
- */
-typedef struct addrinfo		addrinfo_t;
-
-/** Prints the address into the character buffer.
- *  @param[in] family The address family.
- *  @param[in] data The address data.
- *  @param[out] address The character buffer to be filled.
- *  @param[in] length The buffer length.
- *  @returns EOK on success.
- *  @returns EINVAL if the data or address parameter is NULL.
- *  @returns ENOMEM if the character buffer is not long enough.
- *  @returns ENOTSUP if the address family is not supported.
- */
-extern int inet_ntop(uint16_t family, const uint8_t * data, char * address, size_t length);
-
-/** Parses the character string into the address.
- *  If the string is shorter than the full address, zero bytes are added.
- *  @param[in] family The address family.
- *  @param[in] address The character buffer to be parsed.
- *  @param[out] data The address data to be filled.
- *  @returns EOK on success.
- *  @returns EINVAL if the data parameter is NULL.
- *  @returns ENOENT if the address parameter is NULL.
- *  @returns ENOTSUP if the address family is not supported.
- */
-extern int inet_pton(uint16_t family, const char * address, uint8_t * data);
-
-/** Socket address.
- */
-struct sockaddr{
-	/** Address family.
-	 *  @see socket.h
-	 */
-	uint16_t sa_family;
-	/** 14 byte protocol address.
-	 */
-	uint8_t sa_data[14];
-};
-
-// TODO define address information
-// /** Address information.
-// * \todo
-// */
-//struct addrinfo{
-//	int				ai_flags;		// AI_PASSIVE, AI_CANONNAME, etc.
-//	uint16_t		ai_family;		// AF_INET, AF_INET6, AF_UNSPEC
-//	int				ai_socktype;	// SOCK_STREAM, SOCK_DGRAM
-//	int				ai_protocol;	// use 0 for "any"
-//	size_t			ai_addrlen;		// size of ai_addr in bytes
-//	struct sockaddr *	ai_addr;	// struct sockaddr_in or _in6
-//	char *			ai_canonname;	// full canonical hostname
-//	struct addrinfo *	ai_next;	// linked list, next node
-//};
-
-/*int getaddrinfo(const char *node, // e.g. "www.example.com" or IP
-const char *service, // e.g. "http" or port number
-const struct addrinfo *hints,
-struct addrinfo **res);
-getnameinfo
-*/
-
-#endif
-
-/** @}
- */
Index: pace/lib/socket/include/ip_codes.h
===================================================================
--- uspace/lib/socket/include/ip_codes.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ 	(revision )
@@ -1,374 +1,0 @@
-/*
- * Copyright (c) 2009 Lukas Mejdrech
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (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 ip
- *  @{
- */
-
-/** @file
- *  IP codes and definitions.
- */
-
-#ifndef __NET_IP_CODES_H__
-#define __NET_IP_CODES_H__
-
-#include <sys/types.h>
-
-/** IP time to live counter type definition.
- */
-typedef uint8_t	ip_ttl_t;
-
-/** IP type of service type definition.
- */
-typedef uint8_t	ip_tos_t;
-
-/** IP transport protocol type definition.
- */
-typedef uint8_t	ip_protocol_t;
-
-/** Default IPVERSION.
- */
-#define IPVERSION	4
-
-/** Maximum time to live counter.
- */
-#define MAXTTL		255
-
-/** Default time to live counter.
- */
-#define IPDEFTTL	64
-
-/** @name IP type of service definitions
- */
-/*@{*/
-
-/** IP TOS mask.
- */
-#define IPTOS_TOS_MASK				0x1E
-
-/** Precedence shift.
- */
-#define IPTOS_PRECEDENCE_SHIFT		5
-
-/** Delay shift.
- */
-#define IPTOS_DELAY_SHIFT			4
-
-/** Throughput shift.
- */
-#define IPTOS_THROUGHPUT_SHIFT		3
-
-/** Reliability shift.
- */
-#define IPTOS_RELIABILITY_SHIFT		2
-
-/** Cost shift.
- */
-#define IPTOS_COST_SHIFT			1
-
-/** Normal delay.
- */
-#define IPTOS_NORMALDELAY			(0x0 << IPTOS_DELAY_SHIFT)
-
-/** Low delay.
- */
-#define IPTOS_LOWDELAY				(0x1 << IPTOS_DELAY_SHIFT)
-
-/** Normal throughput.
- */
-#define IPTOS_NORMALTHROUGHPUT		(0x0 << IPTOS_THROUGHPUT_SHIFT)
-
-/** Throughput.
- */
-#define IPTOS_THROUGHPUT			(0x1 << IPTOS_THROUGHPUT_SHIFT)
-
-/** Normal reliability.
- */
-#define IPTOS_NORMALRELIABILITY		(0x0 << IPTOS_RELIABILITY_SHIFT)
-
-/** Reliability.
- */
-#define IPTOS_RELIABILITY			(0x1 << IPTOS_RELIABILITY_SHIFT)
-
-/** Normal cost.
- */
-#define IPTOS_NORMALCOST			(0x0 << IPTOS_COST_SHIFT)
-
-/** Minimum cost.
- */
-#define IPTOS_MICNCOST				(0x1 << IPTOS_COST_SHIFT)
-
-/*@}*/
-
-/** @name IP TOS precedence definitions
- */
-/*@{*/
-
-
-/** Precedence mask.
- */
-#define IPTOS_PREC_MASK				0xE0
-
-/** Routine precedence.
- */
-#define IPTOS_PREC_ROUTINE			(0x0 << IPTOS_PRECEDENCE_SHIFT)
-
-/** Priority precedence.
- */
-#define IPTOS_PREC_PRIORITY			(0x1 << IPTOS_PRECEDENCE_SHIFT)
-
-/** Immediate precedence.
- */
-#define IPTOS_PREC_IMMEDIATE		(0x2 << IPTOS_PRECEDENCE_SHIFT)
-
-/** Flash precedence.
- */
-#define IPTOS_PREC_FLASH			(0x3 << IPTOS_PRECEDENCE_SHIFT)
-
-/** Flash override precedence.
- */
-#define IPTOS_PREC_FLASHOVERRIDE	(0x4 << IPTOS_PRECEDENCE_SHIFT)
-
-/** Critical precedence.
- */
-#define IPTOS_PREC_CRITIC_ECP		(0x5 << IPTOS_PRECEDENCE_SHIFT)
-
-/** Inter-network control precedence.
- */
-#define IPTOS_PREC_INTERNETCONTROL	(0x6 << IPTOS_PRECEDENCE_SHIFT)
-
-/** Network control precedence.
- */
-#define IPTOS_PREC_NETCONTROL		(0x7 << IPTOS_PRECEDENCE_SHIFT)
-
-/*@}*/
-
-/** @name IP options definitions
- */
-/*@{*/
-
-/** Copy shift.
- */
-#define IPOPT_COPY_SHIFT			7
-
-/** Class shift.
- */
-#define IPOPT_CLASS_SHIFT			5
-
-/** Number shift.
- */
-#define IPOPT_NUMBER_SHIFT			0
-
-/** Class mask.
- */
-#define IPOPT_CLASS_MASK			0x60
-
-/** Number mask.
- */
-#define IPOPT_NUMBER_MASK			0x1F
-
-/** Copy flag.
- */
-#define IPOPT_COPY					(1 << IPOPT_COPY_SHIFT)
-
-/** Returns IP option type.
- *  @param[in] copy The value indication whether the IP option should be copied.
- *  @param[in] class The IP option class.
- *  @param[in] number The IP option number.
- */
-#define IPOPT_TYPE(copy, class, number)	(((copy) &IPOPT_COPY) | ((class) &IPOPT_CLASS_MASK) | ((number << IPOPT_NUMBER_SHIFT) &IPOPT_NUMBER_MASK))
-
-/** Returns a value indicating whether the IP option should be copied.
- *  @param[in] o The IP option.
- */
-#define	IPOPT_COPIED(o)			((o) &IPOPT_COPY)
-
-/** Returns an IP option class.
- *  @param[in] o The IP option.
- */
-#define	IPOPT_CLASS(o)			((o) &IPOPT_CLASS_MASK)
-
-/** Returns an IP option number.
- *  @param[in] o The IP option.
- */
-#define	IPOPT_NUMBER(o)			((o) &IPOPT_NUMBER_MASK)
-
-/*@}*/
-
-/** @name IP option class definitions
- */
-/*@{*/
-
-/** Control class.
- */
-#define	IPOPT_CONTROL				(0 << IPOPT_CLASS_SHIFT)
-
-/** Reserved class 1.
- */
-#define	IPOPT_RESERVED1				(1 << IPOPT_CLASS_SHIFT)
-
-/** Measurement class.
- */
-#define	IPOPT_MEASUREMENT			(2 << IPOPT_CLASS_SHIFT)
-
-/** Reserved class 2.
- */
-#define	IPOPT_RESERVED2				(3 << IPOPT_CLASS_SHIFT)
-
-/*@}*/
-
-/** @name IP option type definitions
- */
-/*@{*/
-
-/** End of list.
- */
-//#define IPOPT_END_OF_LIST			0x0
-#define IPOPT_END					IPOPT_TYPE(0, IPOPT_CONTROL, 0)
-
-/** No operation.
- */
-//#define IPOPT_NO_OPERATION		0x1
-#define IPOPT_NOOP					IPOPT_TYPE(0, IPOPT_CONTROL, 1)
-
-/** Security.
- */
-//#define IPOPT_SECURITY			0x82
-#define IPOPT_SEC					IPOPT_TYPE(IPOPT_COPY, IPOPT_CONTROL, 2)
-
-/** Loose source.
- */
-//#define IPOPT_LOOSE_SOURCE		0x83
-#define IPOPT_LSRR					IPOPT_TYPE(IPOPT_COPY, IPOPT_CONTROL, 3)
-
-/** Strict route.
- */
-//#define IPOPT_STRICT_SOURCE		0x89
-#define IPOPT_SSRR					IPOPT_TYPE(IPOPT_COPY, IPOPT_CONTROL, 9)
-
-/** Record route.
- */
-//#define IPOPT_RECORD_ROUTE		0x07
-#define IPOPT_RR					IPOPT_TYPE(IPOPT_COPY, IPOPT_CONTROL, 7)
-
-/** Stream identifier.
- */
-//#define IPOPT_STREAM_IDENTIFIER	0x88
-#define IPOPT_SID					IPOPT_TYPE(IPOPT_COPY, IPOPT_CONTROL, 8)
-
-/** Stream identifier length.
- */
-#define IPOPT_SID_LENGTH			4
-
-/** Internet timestamp.
- */
-//#define IPOPT_INTERNET_TIMESTAMP	0x44
-#define IPOPT_TIMESTAMP				IPOPT_TYPE(IPOPT_COPY, IPOPT_MEASUREMENT, 4)
-
-/** Commercial IP security option.
- */
-#define IPOPT_CIPSO					IPOPT_TYPE(IPOPT_COPY, IPOPT_CONTROL, 5)
-
-/** No operation variant.
- */
-#define IPOPT_NOP IPOPT_NOOP
-
-/** End of list variant.
- */
-#define IPOPT_EOL IPOPT_END
-
-/** Timestamp variant.
- */
-#define IPOPT_TS  IPOPT_TIMESTAMP
-
-/*@}*/
-
-/** @name IP security option definitions
- */
-/*@{*/
-
-/** Security length.
- */
-#define IPOPT_SEC_LENGTH			11
-
-/** Unclasified.
- */
-#define IPOPT_SEC_UNCLASIFIED		0x0
-
-/** Confidential.
- */
-#define IPOPT_SEC_CONFIDENTIAL		0xF035
-
-/** EFTO.
- */
-#define IPOPT_SEC_EFTO				0x789A
-
-/** MMMM.
- */
-#define IPOPT_SEC_MMMM				0xBC4D
-
-/** PROG.
- */
-#define IPOPT_SEC_PROG				0x5E26
-
-/** Restricted.
- */
-#define IPOPT_SEC_RESTRICTED		0xAF13
-
-/** Secret.
- */
-#define IPOPT_SEC_SECRET			0xD788
-
-/** Top secret.
- */
-#define IPOPT_SEC_TOP_SECRET		0x6BC5
-
-/*@}*/
-
-/** @name IP timestamp option definitions
- */
-/*@{*/
-
-/** Tiemstamp only.
- */
-#define	IPOPT_TS_TSONLY		0
-
-/** Timestamps and addresses.
- */
-#define	IPOPT_TS_TSANDADDR	1
-
-/** Specified modules only.
- */
-#define	IPOPT_TS_PRESPEC	3
-
-/*@}*/
-
-#endif
-
-/** @}
- */
Index: pace/lib/socket/include/ip_protocols.h
===================================================================
--- uspace/lib/socket/include/ip_protocols.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ 	(revision )
@@ -1,619 +1,0 @@
-/*
- * Copyright (c) 2009 Lukas Mejdrech
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (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 ip
- *  @{
- */
-
-/** @file
- *  Internet protocol numbers according to the on-line IANA - Assigned Protocol numbers - <http://www.iana.org/assignments/protocol-numbers/protocol-numbers.xml>, cited January 14 2009.
- */
-
-#ifndef __NET_IPPROTOCOLS_H__
-#define __NET_IPPROTOCOLS_H__
-
-/** @name IP protocols definitions
- */
-/*@{*/
-
-/** IPv6 Hop-by-Hop Option internet protocol number.
- */
-#define IPPROTO_HOPOPT		0
-
-/** Internet Control Message internet protocol number.
- */
-#define IPPROTO_ICMP		1
-
-/** Internet Group Management internet protocol number.
- */
-#define IPPROTO_IGMP		2
-
-/** Gateway-to-Gateway internet protocol number.
- */
-#define IPPROTO_GGP		3
-
-/** IP in IP (encapsulation) internet protocol number.
- */
-#define IPPROTO_IP		4
-
-/** Stream internet protocol number.
- */
-#define IPPROTO_ST		5
-
-/** Transmission Control internet protocol number.
- */
-#define IPPROTO_TCP		6
-
-/** CBT internet protocol number.
- */
-#define IPPROTO_CBT		7
-
-/** Exterior Gateway Protocol internet protocol number.
- */
-#define IPPROTO_EGP		8
-
-/** any private interior gateway             
-(used by Cisco for their IGRP) internet protocol number.
- */
-#define IPPROTO_IGP		9
-
-/** BBN RCC Monitoring internet protocol number.
- */
-#define IPPROTO_BBN_RCC_MON		10
-
-/** Network Voice Protocol internet protocol number.
- */
-#define IPPROTO_NVP_II		11
-
-/** PUP internet protocol number.
- */
-#define IPPROTO_PUP		12
-
-/** ARGUS internet protocol number.
- */
-#define IPPROTO_ARGUS		13
-
-/** EMCON internet protocol number.
- */
-#define IPPROTO_EMCON		14
-
-/** Cross Net Debugger internet protocol number.
- */
-#define IPPROTO_XNET		15
-
-/** Chaos internet protocol number.
- */
-#define IPPROTO_CHAOS		16
-
-/** User Datagram internet protocol number.
- */
-#define IPPROTO_UDP		17
-
-/** Multiplexing internet protocol number.
- */
-#define IPPROTO_MUX		18
-
-/** DCN Measurement Subsystems internet protocol number.
- */
-#define IPPROTO_DCN_MEAS		19
-
-/** Host Monitoring internet protocol number.
- */
-#define IPPROTO_HMP		20
-
-/** Packet Radio Measurement internet protocol number.
- */
-#define IPPROTO_PRM		21
-
-/** XEROX NS IDP internet protocol number.
- */
-#define IPPROTO_XNS_IDP		22
-
-/** Trunk-1 internet protocol number.
- */
-#define IPPROTO_TRUNK_1		23
-
-/** Trunk-2 internet protocol number.
- */
-#define IPPROTO_TRUNK_2		24
-
-/** Leaf-1 internet protocol number.
- */
-#define IPPROTO_LEAF_1		25
-
-/** Leaf-2 internet protocol number.
- */
-#define IPPROTO_LEAF_2		26
-
-/** Reliable Data Protocol internet protocol number.
- */
-#define IPPROTO_RDP		27
-
-/** Internet Reliable Transaction internet protocol number.
- */
-#define IPPROTO_IRTP		28
-
-/** ISO Transport Protocol Class 4 internet protocol number.
- */
-#define IPPROTO_ISO_TP4		29
-
-/** Bulk Data Transfer Protocol internet protocol number.
- */
-#define IPPROTO_NETBLT		30
-
-/** MFE Network Services Protocol internet protocol number.
- */
-#define IPPROTO_MFE_NSP		31
-
-/** MERIT Internodal Protocol internet protocol number.
- */
-#define IPPROTO_MERIT_INP		32
-
-/** Datagram Congestion Control Protocol internet protocol number.
- */
-#define IPPROTO_DCCP		33
-
-/** Third Party Connect Protocol internet protocol number.
- */
-#define IPPROTO_3PC		34
-
-/** Inter-Domain Policy Routing Protocol internet protocol number.
- */
-#define IPPROTO_IDPR		35
-
-/** XTP internet protocol number.
- */
-#define IPPROTO_XTP		36
-
-/** Datagram Delivery Protocol internet protocol number.
- */
-#define IPPROTO_DDP		37
-
-/** IDPR Control Message Transport Proto internet protocol number.
- */
-#define IPPROTO_IDPR_CMTP		38
-
-/** TP++ Transport Protocol internet protocol number.
- */
-#define IPPROTO_TP		39
-
-/** IL Transport Protocol internet protocol number.
- */
-#define IPPROTO_IL		40
-
-/** Ipv6 internet protocol number.
- */
-#define IPPROTO_IPV6		41
-
-/** Source Demand Routing Protocol internet protocol number.
- */
-#define IPPROTO_SDRP		42
-
-/** Routing Header for IPv6 internet protocol number.
- */
-#define IPPROTO_IPv6_Route		43
-
-/** Fragment Header for IPv6 internet protocol number.
- */
-#define IPPROTO_IPv6_Frag		44
-
-/** Inter-Domain Routing Protocol internet protocol number.
- */
-#define IPPROTO_IDRP		45
-
-/** Reservation Protocol internet protocol number.
- */
-#define IPPROTO_RSVP		46
-
-/** General Routing Encapsulation internet protocol number.
- */
-#define IPPROTO_GRE		47
-
-/** Dynamic Source Routing Protocol internet protocol number.
- */
-#define IPPROTO_DSR		48
-
-/** BNA internet protocol number.
- */
-#define IPPROTO_BNA		49
-
-/** Encap Security Payload internet protocol number.
- */
-#define IPPROTO_ESP		50
-
-/** Authentication Header internet protocol number.
- */
-#define IPPROTO_AH		51
-
-/** Integrated Net Layer Security  TUBA internet protocol number.
- */
-#define IPPROTO_I_NLSP		52
-
-/** IP with Encryption internet protocol number.
- */
-#define IPPROTO_SWIPE		53
-
-/** NBMA Address Resolution Protocol internet protocol number.
- */
-#define IPPROTO_NARP		54
-
-/** IP Mobility internet protocol number.
- */
-#define IPPROTO_MOBILE		55
-
-/** Transport Layer Security Protocol        
-using Kryptonet key management internet protocol number.
- */
-#define IPPROTO_TLSP		56
-
-/** SKIP internet protocol number.
- */
-#define IPPROTO_SKIP		57
-
-/** ICMP for IPv6 internet protocol number.
- */
-#define IPPROTO_IPv6_ICMP		58
-
-/** No Next Header for IPv6 internet protocol number.
- */
-#define IPPROTO_IPv6_NoNxt		59
-
-/** Destination Options for IPv6 internet protocol number.
- */
-#define IPPROTO_IPv6_Opts		60
-
-/** Any host internal protocol internet protocol number.
- */
-#define IPPROTO_AHIP		61
-
-/** CFTP internet protocol number.
- */
-#define IPPROTO_CFTP		62
-
-/** Any local network internet protocol number.
- */
-#define IPPROTO_ALN		63
-
-/** SATNET and Backroom EXPAK internet protocol number.
- */
-#define IPPROTO_SAT_EXPAK		64
-
-/** Kryptolan internet protocol number.
- */
-#define IPPROTO_KRYPTOLAN		65
-
-/** MIT Remote Virtual Disk Protocol internet protocol number.
- */
-#define IPPROTO_RVD		66
-
-/** Internet Pluribus Packet Core internet protocol number.
- */
-#define IPPROTO_IPPC		67
-
-/** Any distributed file system internet protocol number.
- */
-#define IPPROTO_ADFS		68
-
-/** SATNET Monitoring internet protocol number.
- */
-#define IPPROTO_SAT_MON		69
-
-/** VISA Protocol internet protocol number.
- */
-#define IPPROTO_VISA		70
-
-/** Internet Packet Core Utility internet protocol number.
- */
-#define IPPROTO_IPCV		71
-
-/** Computer Protocol Network Executive internet protocol number.
- */
-#define IPPROTO_CPNX		72
-
-/** Computer Protocol Heart Beat internet protocol number.
- */
-#define IPPROTO_CPHB		73
-
-/** Wang Span Network internet protocol number.
- */
-#define IPPROTO_WSN		74
-
-/** Packet Video Protocol internet protocol number.
- */
-#define IPPROTO_PVP		75
-
-/** Backroom SATNET Monitoring internet protocol number.
- */
-#define IPPROTO_BR_SAT_MON		76
-
-/** SUN ND IPPROTOCOL_Temporary internet protocol number.
- */
-#define IPPROTO_SUN_ND		77
-
-/** WIDEBAND Monitoring internet protocol number.
- */
-#define IPPROTO_WB_MON		78
-
-/** WIDEBAND EXPAK internet protocol number.
- */
-#define IPPROTO_WB_EXPAK		79
-
-/** ISO Internet Protocol internet protocol number.
- */
-#define IPPROTO_ISO_IP		80
-
-/** VMTP internet protocol number.
- */
-#define IPPROTO_VMTP		81
-
-/** SECURE-VMTP internet protocol number.
- */
-#define IPPROTO_SECURE_VMTP		82
-
-/** VINES internet protocol number.
- */
-#define IPPROTO_VINES		83
-
-/** TTP internet protocol number.
- */
-#define IPPROTO_TTP		84
-
-/** NSFNET-IGP internet protocol number.
- */
-#define IPPROTO_NSFNET_IGP		85
-
-/** Dissimilar Gateway Protocol internet protocol number.
- */
-#define IPPROTO_DGP		86
-
-/** TCF internet protocol number.
- */
-#define IPPROTO_TCF		87
-
-/** EIGRP internet protocol number.
- */
-#define IPPROTO_EIGRP		88
-
-/** OSPFIGP internet protocol number.
- */
-#define IPPROTO_OSPFIGP		89
-
-/** Sprite RPC Protocol internet protocol number.
- */
-#define IPPROTO_Sprite_RPC		90
-
-/** Locus Address Resolution Protocol internet protocol number.
- */
-#define IPPROTO_LARP		91
-
-/** Multicast Transport Protocol internet protocol number.
- */
-#define IPPROTO_MTP		92
-
-/** AX.25 Frames internet protocol number.
- */
-#define IPPROTO_AX25		93
-
-/** IP-within-IP Encapsulation Protocol internet protocol number.
- */
-#define IPPROTO_IPIP		94
-
-/** Mobile Internetworking Control Pro. internet protocol number.
- */
-#define IPPROTO_MICP		95
-
-/** Semaphore Communications Sec. Pro. internet protocol number.
- */
-#define IPPROTO_SCC_SP		96
-
-/** Ethernet-within-IP Encapsulation internet protocol number.
- */
-#define IPPROTO_ETHERIP		97
-
-/** Encapsulation Header internet protocol number.
- */
-#define IPPROTO_ENCAP		98
-
-/** Any private encryption scheme internet protocol number.
- */
-#define IPPROTO_APES		99
-
-/** GMTP internet protocol number.
- */
-#define IPPROTO_GMTP		100
-
-/** Ipsilon Flow Management Protocol internet protocol number.
- */
-#define IPPROTO_IFMP		101
-
-/** PNNI over IP internet protocol number.
- */
-#define IPPROTO_PNNI		102
-
-/** Protocol Independent Multicast internet protocol number.
- */
-#define IPPROTO_PIM		103
-
-/** ARIS internet protocol number.
- */
-#define IPPROTO_ARIS		104
-
-/** SCPS internet protocol number.
- */
-#define IPPROTO_SCPS		105
-
-/** QNX internet protocol number.
- */
-#define IPPROTO_QNX		106
-
-/** Active Networks internet protocol number.
- */
-#define IPPROTO_AN		107
-
-/** IP Payload Compression Protocol internet protocol number.
- */
-#define IPPROTO_IPComp		108
-
-/** Sitara Networks Protocol internet protocol number.
- */
-#define IPPROTO_SNP		109
-
-/** Compaq Peer Protocol internet protocol number.
- */
-#define IPPROTO_Compaq_Peer		110
-
-/** IPX in IP internet protocol number.
- */
-#define IPPROTO_IPX_in_IP		111
-
-/** Virtual Router Redundancy Protocol internet protocol number.
- */
-#define IPPROTO_VRRP		112
-
-/** PGM Reliable Transport Protocol internet protocol number.
- */
-#define IPPROTO_PGM		113
-
-/** Any 0-hop protocol internet protocol number.
- */
-#define IPPROTO_A0HP		114
-
-/** Layer Two Tunneling Protocol internet protocol number.
- */
-#define IPPROTO_L2TP		115
-
-/** D-II Data Exchange (DDX) internet protocol number.
- */
-#define IPPROTO_DDX		116
-
-/** Interactive Agent Transfer Protocol internet protocol number.
- */
-#define IPPROTO_IATP		117
-
-/** Schedule Transfer Protocol internet protocol number.
- */
-#define IPPROTO_STP		118
-
-/** SpectraLink Radio Protocol internet protocol number.
- */
-#define IPPROTO_SRP		119
-
-/** UTI internet protocol number.
- */
-#define IPPROTO_UTI		120
-
-/** Simple Message Protocol internet protocol number.
- */
-#define IPPROTO_SMP		121
-
-/** SM internet protocol number.
- */
-#define IPPROTO_SM		122
-
-/** Performance Transparency Protocol internet protocol number.
- */
-#define IPPROTO_PTP		123
-
-/** ISIS over IPv4 internet protocol number.
- */
-#define IPPROTO_ISIS		124
-
-/** FIRE internet protocol number.
- */
-#define IPPROTO_FIRE		125
-
-/** Combat Radio Transport Protocol internet protocol number.
- */
-#define IPPROTO_CRTP		126
-
-/** Combat Radio User Datagram internet protocol number.
- */
-#define IPPROTO_CRUDP		127
-
-/** SSCOPMCE internet protocol number.
- */
-#define IPPROTO_SSCOPMCE		128
-
-/** IPLT internet protocol number.
- */
-#define IPPROTO_IPLT		129
-
-/** Secure Packet Shield internet protocol number.
- */
-#define IPPROTO_SPS		130
-
-/** Private IP Encapsulation within IP internet protocol number.
- */
-#define IPPROTO_PIPE		131
-
-/** Stream Control Transmission Protocol internet protocol number.
- */
-#define IPPROTO_SCTP		132
-
-/** Fibre Channel internet protocol number.
- */
-#define IPPROTO_FC		133
-
-/** RSVP-E2E-IGNORE internet protocol number.
- */
-#define IPPROTO_RSVP_E2E_IGNORE		134
-
-/** Mobility Header internet protocol number.
- */
-#define IPPROTO_MH		135
-
-/** UDPLite internet protocol number.
- */
-#define IPPROTO_UDPLITE		136
-
-/** MPLS-in-IP internet protocol number.
- */
-#define IPPROTO_MPLS_in_IP		137
-
-/** MANET Protocols internet protocol number.
- */
-#define IPPROTO_manet		138
-
-/** Host Identity Protocol internet protocol number.
- */
-#define IPPROTO_HIP		139
-
-/** Raw internet protocol number.
- */
-#define IPPROTO_RAW		255
-
-/** Maximum internet protocol number.
- */
-#define IPPROTO_MAX		(IPPROTO_RAW + 1)
-
-/*@}*/
-
-#endif
-
-/** @}
- */
Index: pace/lib/socket/include/net_byteorder.h
===================================================================
--- uspace/lib/socket/include/net_byteorder.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ 	(revision )
@@ -1,71 +1,0 @@
-/*
- * Copyright (c) 2009 Lukas Mejdrech
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (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 net
- *  @{
- */
-
-/** @file
- *  Host - network byte order manipulation functions.
- */
-
-#ifndef __NET_BYTEORDER_H__
-#define __NET_BYTEORDER_H__
-
-#include <byteorder.h>
-#include <sys/types.h>
-
-
-/** Converts the given short number (16 bit) from the host byte order to the network byte order (big endian).
- *  @param[in] number The number in the host byte order to be converted.
- *  @returns The number in the network byte order.
- */
-#define htons(number)		host2uint16_t_be(number)
-
-/** Converts the given long number (32 bit) from the host byte order to the network byte order (big endian).
- *  @param[in] number The number in the host byte order to be converted.
- *  @returns The number in the network byte order.
- */
-#define htonl(number)		host2uint32_t_be(number)
-
-/** Converts the given short number (16 bit) from the network byte order (big endian) to the host byte order.
- *  @param[in] number The number in the network byte order to be converted.
- *  @returns The number in the host byte order.
- */
-#define ntohs(number) 	uint16_t_be2host(number)
-
-/** Converts the given long number (32 bit) from the network byte order (big endian) to the host byte order.
- *  @param[in] number The number in the network byte order to be converted.
- *  @returns The number in the host byte order.
- */
-#define ntohl(number)		uint32_t_be2host(number)
-
-#endif
-
-/** @}
- */
Index: pace/lib/socket/include/net_device.h
===================================================================
--- uspace/lib/socket/include/net_device.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ 	(revision )
@@ -1,173 +1,0 @@
-/*
- * Copyright (c) 2009 Lukas Mejdrech
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (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 netif
- *  @{
- */
-
-/** @file
- *  Device identifier, state and usage statistics.
- */
-
-#ifndef __NET_DEVICE_ID_TYPE_H__
-#define __NET_DEVICE_ID_TYPE_H__
-
-#include <adt/int_map.h>
-
-/** Device identifier to generic type map declaration.
- */
-#define DEVICE_MAP_DECLARE		INT_MAP_DECLARE
-
-/** Device identifier to generic type map implementation.
- */
-#define DEVICE_MAP_IMPLEMENT	INT_MAP_IMPLEMENT
-
-/** Invalid device identifier.
- */
-#define DEVICE_INVALID_ID		(-1)
-
-/** Device identifier type.
- */
-typedef int	device_id_t;
-
-/** Device state type.
- */
-typedef enum device_state	device_state_t;
-
-/** Type definition of the device usage statistics.
- *  @see device_stats
- */
-typedef struct device_stats	device_stats_t;
-
-/** Type definition of the device usage statistics pointer.
- *  @see device_stats
- */
-typedef device_stats_t *	device_stats_ref;
-
-/** Device state.
- */
-enum	device_state{
-	/** Device not present or not initialized.
-	 */
-	NETIF_NULL = 0,
-	/** Device present and stopped.
-	 */
-	NETIF_STOPPED,
-	/** Device present and active.
-	 */
-	NETIF_ACTIVE,
-	/** Device present but unable to transmit.
-	 */
-	NETIF_CARRIER_LOST
-};
-
-/** Device usage statistics.
- */
-struct	device_stats{
-	/** Total packets received.
-	 */
-	unsigned long receive_packets;
-	/** Total packets transmitted.
-	 */
-	unsigned long send_packets;
-	/** Total bytes received.
-	 */
-	unsigned long receive_bytes;
-	/** Total bytes transmitted.
-	 */
-	unsigned long send_bytes;
-	/** Bad packets received counter.
-	 */
-	unsigned long receive_errors;
-	/** Packet transmition problems counter.
-	 */
-	unsigned long send_errors;
-	/** No space in buffers counter.
-	 */
-	unsigned long receive_dropped;
-	/** No space available counter.
-	 */
-	unsigned long send_dropped;
-	/** Total multicast packets received.
-	 */
-	unsigned long multicast;
-	/** The number of collisions due to congestion on the medium.
-	 */
-	unsigned long collisions;
-
-	/* detailed receive_errors: */
-	/** Received packet length error counter.
-	 */
-	unsigned long receive_length_errors;
-	/** Receiver buffer overflow counter.
-	 */
-	unsigned long receive_over_errors;
-	/** Received packet with crc error counter.
-	 */
-	unsigned long receive_crc_errors;
-	/** Received frame alignment error counter.
-	 */
-	unsigned long receive_frame_errors;
-	/** Receiver fifo overrun counter.
-	 */
-	unsigned long receive_fifo_errors;
-	/** Receiver missed packet counter.
-	 */
-	unsigned long receive_missed_errors;
-
-	/* detailed send_errors */
-	/** Transmitter aborted counter.
-	 */
-	unsigned long send_aborted_errors;
-	/** Transmitter carrier errors counter.
-	 */
-	unsigned long send_carrier_errors;
-	/** Transmitter fifo overrun counter.
-	 */
-	unsigned long send_fifo_errors;
-	/** Transmitter carrier errors counter.
-	 */
-	unsigned long send_heartbeat_errors;
-	/** Transmitter window errors counter.
-	 */
-	unsigned long send_window_errors;
-
-	/* for cslip etc */
-	/** Total compressed packets received.
-	 */
-	unsigned long receive_compressed;
-	/** Total compressed packet transmitted.
-	 */
-	unsigned long send_compressed;
-};
-
-#endif
-
-/** @}
- */
-
Index: pace/lib/socket/include/net_err.h
===================================================================
--- uspace/lib/socket/include/net_err.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ 	(revision )
@@ -1,99 +1,0 @@
-/*
- * Copyright (c) 2009 Lukas Mejdrech
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (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 net
- * @{
- */
-
-/** @file
- * Common error processing codes and routines.
- */
-
-#ifndef __NET_ERR_H__
-#define __NET_ERR_H__
-
-#include <errno.h>
-
-#ifdef CONFIG_DEBUG
-	#include <stdio.h>
-	#include <str_error.h>
-#endif
-
-/** An actual stored error code.
- *
- */
-#define ERROR_CODE  error_check_return_value
-
-/** An error processing routines declaration.
- *
- * This has to be declared in the block where the error processing
- * is desired.
- *
- */
-#define ERROR_DECLARE  int ERROR_CODE
-
-/** Store the value as an error code and checks if an error occurred.
- *
- * @param[in] value The value to be checked. May be a function call.
- * @return False if the value indicates success (EOK).
- * @return True otherwise.
- *
- */
-#ifdef CONFIG_DEBUG
-
-#define ERROR_OCCURRED(value) \
-	(((ERROR_CODE = (value)) != EOK) \
-	&& ({ \
-		fprintf(stderr, "libsocket error at %s:%d (%s)\n", \
-		__FILE__, __LINE__, str_error(ERROR_CODE)); \
-		1; \
-	}))
-
-#else
-
-#define ERROR_OCCURRED(value)  ((ERROR_CODE = (value)) != EOK)
-
-#endif
-
-/** Error propagation
- *
- * Check if an error occurred and immediately exit the actual
- * function returning the error code.
- *
- * @param[in] value The value to be checked. May be a function call.
- *
- */
-
-#define ERROR_PROPAGATE(value) \
-	if (ERROR_OCCURRED(value)) \
-		return ERROR_CODE
-
-#endif
-
-/** @}
- */
Index: pace/lib/socket/include/net_messages.h
===================================================================
--- uspace/lib/socket/include/net_messages.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ 	(revision )
@@ -1,670 +1,0 @@
-/*
- * Copyright (c) 2009 Lukas Mejdrech
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (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 net
- *  @{
- */
-
-/** @file
- *  Networking common message definitions.
- */
-
-#ifndef __NET_MESSAGES_H__
-#define __NET_MESSAGES_H__
-
-#include <async.h>
-
-#include <ipc/ipc.h>
-#include <ipc/services.h>
-
-#include <net_device.h>
-#include <adt/measured_strings.h>
-#include <packet/packet.h>
-
-/** Returns a value indicating whether the value is in the interval.
- *  @param[in] item The value to be checked.
- *  @param[in] first_inclusive The first value in the interval inclusive.
- *  @param[in] last_exclusive The first value after the interval.
- */
-#define IS_IN_INTERVAL(item, first_inclusive, last_exclusive)	(((item) >= (first_inclusive)) && ((item) < (last_exclusive)))
-
-/** @name Networking message counts
- */
-/*@{*/
-
-/** The number of ARP messages.
- */
-#define NET_ARP_COUNT		5
-
-/** The number of Ethernet messages.
- */
-#define NET_ETH_COUNT		0
-
-/** The number of ICMP messages.
- */
-#define NET_ICMP_COUNT		6
-
-/** The number of inter-network messages.
- */
-#define NET_IL_COUNT		6
-
-/** The number of IP messages.
- */
-#define NET_IP_COUNT		4
-
-/** The number of general networking messages.
- */
-#define NET_NET_COUNT		3
-
-/** The number of network interface driver messages.
- */
-#define NET_NETIF_COUNT		6
-
-/** The number of network interface layer messages.
- */
-#define NET_NIL_COUNT		7
-
-/** The number of packet management system messages.
- */
-#define NET_PACKET_COUNT	5
-
-/** The number of socket messages.
- */
-#define NET_SOCKET_COUNT	14
-
-/** The number of TCP messages.
- */
-#define NET_TCP_COUNT		0
-
-/** The number of transport layer messages.
- */
-#define NET_TL_COUNT		1
-
-/** The number of UDP messages.
- */
-#define NET_UDP_COUNT		0
-
-/*@}*/
-
-/** @name Networking message intervals
- */
-/*@{*/
-
-/** The first networking message.
- */
-#define NET_FIRST			2000
-
-/** The first network interface layer message.
- */
-#define NET_NETIF_FIRST		NET_FIRST
-
-/** The last network interface layer message.
- */
-#define NET_NETIF_LAST		(NET_NETIF_FIRST + NET_NETIF_COUNT)
-
-/** The first general networking message.
- */
-#define NET_NET_FIRST		(NET_NETIF_LAST + 0)
-
-/** The last general networking message.
- */
-#define NET_NET_LAST		(NET_NET_FIRST + NET_NET_COUNT)
-
-/** The first network interface layer message.
- */
-#define NET_NIL_FIRST		(NET_NET_LAST + 0)
-
-/** The last network interface layer message.
- */
-#define NET_NIL_LAST		(NET_NIL_FIRST + NET_NIL_COUNT)
-
-/** The first Ethernet message.
- */
-#define NET_ETH_FIRST		(NET_NIL_LAST + 0)
-
-/** The last Ethernet message.
- */
-#define NET_ETH_LAST		(NET_ETH_FIRST + NET_ETH_COUNT)
-
-/** The first inter-network message.
- */
-#define NET_IL_FIRST		(NET_ETH_LAST + 0)
-
-/** The last inter-network message.
- */
-#define NET_IL_LAST			(NET_IL_FIRST + NET_IL_COUNT)
-
-/** The first IP message.
- */
-#define NET_IP_FIRST		(NET_IL_LAST + 0)
-
-/** The last IP message.
- */
-#define NET_IP_LAST			(NET_IP_FIRST + NET_IP_COUNT)
-
-/** The first ARP message.
- */
-#define NET_ARP_FIRST		(NET_IP_LAST + 0)
-
-/** The last ARP message.
- */
-#define NET_ARP_LAST		(NET_ARP_FIRST + NET_ARP_COUNT)
-
-/** The first ICMP message.
- */
-#define NET_ICMP_FIRST		(NET_ARP_LAST + 0)
-
-/** The last ICMP message.
- */
-#define NET_ICMP_LAST		(NET_ICMP_FIRST + NET_ICMP_COUNT)
-
-/** The first ICMP message.
- */
-#define NET_TL_FIRST		(NET_ICMP_LAST + 0)
-
-/** The last ICMP message.
- */
-#define NET_TL_LAST			(NET_TL_FIRST + NET_TL_COUNT)
-
-/** The first UDP message.
- */
-#define NET_UDP_FIRST		(NET_TL_LAST + 0)
-
-/** The last UDP message.
- */
-#define NET_UDP_LAST		(NET_UDP_FIRST + NET_UDP_COUNT)
-
-/** The first TCP message.
- */
-#define NET_TCP_FIRST		(NET_UDP_LAST + 0)
-
-/** The last TCP message.
- */
-#define NET_TCP_LAST		(NET_TCP_FIRST + NET_TCP_COUNT)
-
-/** The first socket message.
- */
-#define NET_SOCKET_FIRST	(NET_TCP_LAST + 0)
-
-/** The last socket message.
- */
-#define NET_SOCKET_LAST		(NET_SOCKET_FIRST + NET_SOCKET_COUNT)
-
-/** The first packet management system message.
- */
-#define NET_PACKET_FIRST	(NET_SOCKET_LAST + 0)
-
-/** The last packet management system message.
- */
-#define NET_PACKET_LAST		(NET_PACKET_FIRST + NET_PACKET_COUNT)
-
-/** The last networking message.
- */
-#define NET_LAST			NET_PACKET_LAST
-
-/** The number of networking messages.
- */
-#define NET_COUNT			(NET_LAST - NET_FIRST)
-
-/** Returns a value indicating whether the IPC call is a generic networking message.
- *  @param[in] call The IPC call to be checked.
- */
-#define IS_NET_MESSAGE(call) \
-	IS_IN_INTERVAL(IPC_GET_METHOD(*call), NET_FIRST, NET_LAST)
-
-/** Returns a value indicating whether the IPC call is an ARP message.
- *  @param[in] call The IPC call to be checked.
- */
-#define IS_NET_ARP_MESSAGE(call) \
-	IS_IN_INTERVAL(IPC_GET_METHOD(*call), NET_ARP_FIRST, NET_ARP_LAST)
-
-/** Returns a value indicating whether the IPC call is an Ethernet message.
- *  @param[in] call The IPC call to be checked.
- */
-#define IS_NET_ETH_MESSAGE(call) \
-	IS_IN_INTERVAL(IPC_GET_METHOD(*call), NET_ETH_FIRST, NET_ETH_LAST)
-
-/** Returns a value indicating whether the IPC call is an ICMP message.
- *  @param[in] call The IPC call to be checked.
- */
-#define IS_NET_ICMP_MESSAGE(call) \
-	IS_IN_INTERVAL(IPC_GET_METHOD(*call), NET_ICMP_FIRST, NET_ICMP_LAST)
-
-/** Returns a value indicating whether the IPC call is an inter-network layer message.
- *  @param[in] call The IPC call to be checked.
- */
-#define IS_NET_IL_MESSAGE(call) \
-	IS_IN_INTERVAL(IPC_GET_METHOD(*call), NET_IL_FIRST, NET_IL_LAST)
-
-/** Returns a value indicating whether the IPC call is an IP message.
- *  @param[in] call The IPC call to be checked.
- */
-#define IS_NET_IP_MESSAGE(call) \
-	IS_IN_INTERVAL(IPC_GET_METHOD(*call), NET_IP_FIRST, NET_IP_LAST)
-
-/** Returns a value indicating whether the IPC call is a generic networking message.
- *  @param[in] call The IPC call to be checked.
- */
-#define IS_NET_NET_MESSAGE(call) \
-	IS_IN_INTERVAL(IPC_GET_METHOD(*call), NET_NET_FIRST, NET_NET_LAST)
-
-/** Returns a value indicating whether the IPC call is a network interface layer message.
- *  @param[in] call The IPC call to be checked.
- */
-#define IS_NET_NIL_MESSAGE(call) \
-	IS_IN_INTERVAL(IPC_GET_METHOD(*call), NET_NIL_FIRST, NET_NIL_LAST)
-
-/** Returns a value indicating whether the IPC call is a packet manaagement system message.
- *  @param[in] call The IPC call to be checked.
- */
-#define IS_NET_PACKET_MESSAGE(call) \
-	IS_IN_INTERVAL(IPC_GET_METHOD(*call), NET_PACKET_FIRST, NET_PACKET_LAST)
-
-/** Returns a value indicating whether the IPC call is a socket message.
- *  @param[in] call The IPC call to be checked.
- */
-#define IS_NET_SOCKET_MESSAGE(call) \
-	IS_IN_INTERVAL(IPC_GET_METHOD(*call), NET_SOCKET_FIRST, NET_SOCKET_LAST)
-
-/** Returns a value indicating whether the IPC call is a TCP message.
- *  @param[in] call The IPC call to be checked.
- */
-#define IS_NET_TCP_MESSAGE(call) \
-	IS_IN_INTERVAL(IPC_GET_METHOD(*call), NET_TCP_FIRST, NET_TCP_LAST)
-
-/** Returns a value indicating whether the IPC call is a transport layer message.
- *  @param[in] call The IPC call to be checked.
- */
-#define IS_NET_TL_MESSAGE(call) \
-	IS_IN_INTERVAL(IPC_GET_METHOD(*call), NET_TL_FIRST, NET_TL_LAST)
-
-/** Returns a value indicating whether the IPC call is a UDP message.
- *  @param[in] call The IPC call to be checked.
- */
-#define IS_NET_UDP_MESSAGE(call) \
-	IS_IN_INTERVAL(IPC_GET_METHOD(*call), NET_UDP_FIRST, NET_UDP_LAST)
-
-/*@}*/
-
-/** @name Networking specific message arguments definitions
- */
-/*@{*/
-
-/** @name First arguments
- */
-/*@{*/
-
-/** Returns the device identifier message argument.
- *  @param[in] call The message call structure.
- */
-#define IPC_GET_DEVICE(call) \
-	({device_id_t device_id = (device_id_t) IPC_GET_ARG1(*call); device_id;})
-
-/*@;})*/
-
-/** @name Second arguments
- */
-/*@({*/
-
-/** Returns the packet identifier message argument.
- *  @param[in] call The message call structure.
- */
-#define IPC_GET_PACKET(call) \
-	({packet_id_t packet_id = (packet_id_t) IPC_GET_ARG2(*call); packet_id;})
-
-/** Returns the count message argument.
- *  @param[in] call The message call structure.
- */
-#define IPC_GET_COUNT(call) \
-	({size_t size = (size_t) IPC_GET_ARG2(*call); size;})
-
-/** Returns the device state message argument.
- *  @param[in] call The message call structure.
- */
-#define IPC_GET_STATE(call) \
-	({device_state_t device_state = (device_state_t) IPC_GET_ARG2(*call); device_state;})
-
-/** Returns the maximum transmission unit message argument.
- *  @param[in] call The message call structure.
- */
-#define IPC_GET_MTU(call) \
-	({size_t size = (size_t) IPC_GET_ARG2(*call); size;})
-
-/*@;})*/
-
-/** @name Third arguments
- */
-/*@({*/
-
-/** Returns the device driver service message argument.
- *  @param[in] call The message call structure.
- */
- #define IPC_GET_SERVICE(call) \
-	({services_t service = (services_t) IPC_GET_ARG3(*call); service;})
-
-/** Returns the target service message argument.
- *  @param[in] call The message call structure.
- */
-#define IPC_GET_TARGET(call) \
-	({services_t service = (services_t) IPC_GET_ARG3(*call); service;})
-
-/** Returns the sender service message argument.
- *  @param[in] call The message call structure.
- */
-#define IPC_GET_SENDER(call) \
-	({services_t service = (services_t) IPC_GET_ARG3(*call); service;})
-
-/*@;})*/
-
-/** @name Fourth arguments
- */
-/*@({*/
-
-/** Returns the error service message argument.
- *  @param[in] call The message call structure.
- */
-#define IPC_GET_ERROR(call) \
-	({services_t service = (services_t) IPC_GET_ARG4(*call); service;})
-
-/*@;})*/
-
-/** @name Fifth arguments
- */
-/*@({*/
-
-/** Returns the phone message argument.
- *  @param[in] call The message call structure.
- */
-#define IPC_GET_PHONE(call) \
-	({int phone = (int) IPC_GET_ARG5(*call); phone;})
-
-/*@}*/
-
-/** @name First answers
- */
-/*@{*/
-
-/** Sets the device identifier in the message answer.
- *  @param[out] answer The message answer structure.
- */
-#define IPC_SET_DEVICE(answer, value) \
-	{ipcarg_t argument = (ipcarg_t) (value); IPC_SET_ARG1(*answer, argument);}
-
-/** Sets the minimum address length in the message answer.
- *  @param[out] answer The message answer structure.
- */
-#define IPC_SET_ADDR(answer, value) \
-	{ipcarg_t argument = (ipcarg_t) (value); IPC_SET_ARG1(*answer, argument);}
-
-/*@}*/
-
-/** @name Second answers
- */
-/*@{*/
-
-/** Sets the minimum prefix size in the message answer.
- *  @param[out] answer The message answer structure.
- */
-#define IPC_SET_PREFIX(answer, value) \
-	{ipcarg_t argument = (ipcarg_t) (value); IPC_SET_ARG2(*answer, argument);}
-
-/*@}*/
-
-/** @name Third answers
- */
-/*@{*/
-
-/** Sets the maximum content size in the message answer.
- *  @param[out] answer The message answer structure.
- */
-#define IPC_SET_CONTENT(answer, value) \
-	{ipcarg_t argument = (ipcarg_t) (value); IPC_SET_ARG3(*answer, argument);}
-
-/*@}*/
-
-/** @name Fourth answers
- */
-/*@{*/
-
-/** Sets the minimum suffix size in the message answer.
- *  @param[out] answer The message answer structure.
- */
-#define IPC_SET_SUFFIX(answer, value) \
-	{ipcarg_t argument = (ipcarg_t) (value); IPC_SET_ARG4(*answer, argument);}
-
-/*@}*/
-
-/*@}*/
-
-/** Notify the module about the device state change.
- *
- * @param[in] phone     The service module phone.
- * @param[in] message   The service specific message.
- * @param[in] device_id The device identifier.
- * @param[in] state     The new device state.
- * @param[in] target    The target module service.
- *
- * @return EOK on success.
- *
- */
-static inline int generic_device_state_msg_remote(int phone, int message,
-    device_id_t device_id, int state, services_t target)
-{
-	async_msg_3(phone, (ipcarg_t) message, (ipcarg_t) device_id,
-	    (ipcarg_t) state, target);
-	
-	return EOK;
-}
-
-/** Notify a module about the device.
- *
- * @param[in] phone     The service module phone.
- * @param[in] message   The service specific message.
- * @param[in] device_id The device identifier.
- * @param[in] arg2      The second argument of the message.
- * @param[in] service   The device module service.
- *
- * @return EOK on success.
- * @return Other error codes as defined for the specific service message.
- *
- */
-static inline int generic_device_req_remote(int phone, int message,
-    device_id_t device_id, int arg2, services_t service)
-{
-	return (int) async_req_3_0(phone, (ipcarg_t) message, (ipcarg_t) device_id,
-	    (ipcarg_t) arg2, (ipcarg_t) service);
-}
-
-/** Returns the address.
- *  @param[in] phone The service module phone.
- *  @param[in] message The service specific message.
- *  @param[in] device_id The device identifier.
- *  @param[out] address The desired address.
- *  @param[out] data The address data container.
- *  @returns EOK on success.
- *  @returns EBADMEM if the address parameter and/or the data parameter is NULL.
- *  @returns Other error codes as defined for the specific service message.
- */
-static inline int generic_get_addr_req(int phone, int message, device_id_t device_id, measured_string_ref * address, char ** data){
-	aid_t message_id;
-	ipcarg_t result;
-	int string;
-
-	if(!(address && data)){
-		return EBADMEM;
-	}
-
-	// request the address
-	message_id = async_send_1(phone, (ipcarg_t) message, (ipcarg_t) device_id, NULL);
-	string = measured_strings_return(phone, address, data, 1);
-	async_wait_for(message_id, &result);
-
-	// if not successful
-	if((string == EOK) && (result != EOK)){
-		// clear the data
-		free(*address);
-		free(*data);
-	}
-	return (int) result;
-}
-
-/** Return the device packet dimension for sending.
- *
- * @param[in]  phone            The service module phone.
- * @param[in]  message          The service specific message.
- * @param[in]  device_id        The device identifier.
- * @param[out] packet_dimension The packet dimension.
- *
- * @return EOK on success.
- * @return EBADMEM if the packet_dimension parameter is NULL.
- * @return Other error codes as defined for the specific service message.
- *
- */
-static inline int generic_packet_size_req_remote(int phone, int message,
-    device_id_t device_id, packet_dimension_ref packet_dimension)
-{
-	if (!packet_dimension)
-		return EBADMEM;
-	
-	ipcarg_t addr_len;
-	ipcarg_t prefix;
-	ipcarg_t content;
-	ipcarg_t suffix;
-	
-	ipcarg_t result = async_req_1_4(phone, (ipcarg_t) message,
-	    (ipcarg_t) device_id, &addr_len, &prefix, &content, &suffix);
-	
-	packet_dimension->prefix = (size_t) prefix;
-	packet_dimension->content = (size_t) content;
-	packet_dimension->suffix = (size_t) suffix;
-	packet_dimension->addr_len = (size_t) addr_len;
-	
-	return (int) result;
-}
-
-/** Pass the packet queue to the module.
- *
- * @param[in] phone     The service module phone.
- * @param[in] message   The service specific message.
- * @param[in] device_id The device identifier.
- * @param[in] packet_id The received packet or the received packet queue
- *                      identifier.
- * @param[in] target    The target module service.
- * @param[in] error     The error module service.
- *
- * @return EOK on success.
- *
- */
-static inline int generic_received_msg_remote(int phone, int message,
-    device_id_t device_id, packet_id_t packet_id, services_t target,
-    services_t error)
-{
-	if (error)
-		async_msg_4(phone, (ipcarg_t) message, (ipcarg_t) device_id,
-		    (ipcarg_t) packet_id, (ipcarg_t) target, (ipcarg_t) error);
-	else
-		async_msg_3(phone, (ipcarg_t) message, (ipcarg_t) device_id,
-		    (ipcarg_t) packet_id, (ipcarg_t) target);
-	
-	return EOK;
-}
-
-/** Send the packet queue.
- *
- * @param[in] phone     The service module phone.
- * @param[in] message   The service specific message.
- * @param[in] device_id The device identifier.
- * @param[in] packet_id The packet or the packet queue identifier.
- * @param[in] sender    The sending module service.
- * @param[in] error     The error module service.
- *
- * @return EOK on success.
- *
- */
-static inline int generic_send_msg_remote(int phone, int message,
-    device_id_t device_id, packet_id_t packet_id, services_t sender,
-    services_t error)
-{
-	if (error)
-		async_msg_4(phone, (ipcarg_t) message, (ipcarg_t) device_id,
-		    (ipcarg_t) packet_id, (ipcarg_t) sender, (ipcarg_t) error);
-	else
-		async_msg_3(phone, (ipcarg_t) message, (ipcarg_t) device_id,
-		    (ipcarg_t) packet_id, (ipcarg_t) sender);
-	
-	return EOK;
-}
-
-/** Translates the given strings.
- *  Allocates and returns the needed memory block as the data parameter.
- *  @param[in] phone The service module phone.
- *  @param[in] message The service specific message.
- *  @param[in] device_id The device identifier.
- *  @param[in] service The module service.
- *  @param[in] configuration The key strings.
- *  @param[in] count The number of configuration keys.
- *  @param[out] translation The translated values.
- *  @param[out] data The translation data container.
- *  @returns EOK on success.
- *  @returns EINVAL if the configuration parameter is NULL.
- *  @returns EINVAL if the count parameter is zero (0).
- *  @returns EBADMEM if the translation or the data parameters are NULL.
- *  @returns Other error codes as defined for the specific service message.
- */
-static inline int generic_translate_req(int phone, int message, device_id_t device_id, services_t service, measured_string_ref configuration, size_t count, measured_string_ref * translation, char ** data){
-	aid_t message_id;
-	ipcarg_t result;
-	int string;
-
-	if(!(configuration && (count > 0))){
-		return EINVAL;
-	}
-	if(!(translation && data)){
-		return EBADMEM;
-	}
-
-	// request the translation
-	message_id = async_send_3(phone, (ipcarg_t) message, (ipcarg_t) device_id, (ipcarg_t) count, (ipcarg_t) service, NULL);
-	measured_strings_send(phone, configuration, count);
-	string = measured_strings_return(phone, translation, data, count);
-	async_wait_for(message_id, &result);
-
-	// if not successful
-	if((string == EOK) && (result != EOK)){
-		// clear the data
-		free(*translation);
-		free(*data);
-	}
-
-	return (int) result;
-}
-
-#endif
-
-/** @}
- */
Index: pace/lib/socket/include/net_modules.h
===================================================================
--- uspace/lib/socket/include/net_modules.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ 	(revision )
@@ -1,125 +1,0 @@
-/*
- * Copyright (c) 2009 Lukas Mejdrech
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (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 net
- *  @{
- */
-
-/** @file
- *  Generic module functions.
- */
-
-#ifndef __NET_MODULES_H__
-#define __NET_MODULES_H__
- 
-#include <async.h>
-
-#include <ipc/ipc.h>
-#include <ipc/services.h>
-
-#include <sys/time.h>
-
-/** Converts the data length between different types.
- *	@param[in] type_from The source type.
- *  @param[in] type_to The destination type.
- *  @param[in] count The number units of the source type size.
- */
-#define CONVERT_SIZE(type_from, type_to, count)	((sizeof(type_from) / sizeof(type_to)) * (count))
-
-/** Registers the module service at the name server.
- *  @param[in] me The module service.
- *  @param[out] phonehash The created phone hash.
- */
-#define REGISTER_ME(me, phonehash)	ipc_connect_to_me(PHONE_NS, (me), 0, 0, (phonehash))
-
-/** Connect to the needed module function type definition.
- *  @param[in] need The needed module service.
- *  @returns The phone of the needed service.
- */
-typedef int connect_module_t(services_t need);
-
-/** Answers the call.
- *  @param[in] callid The call identifier.
- *  @param[in] result The message processing result.
- *  @param[in] answer The message processing answer.
- *  @param[in] answer_count The number of answer parameters.
- */
-extern void answer_call(ipc_callid_t callid, int result, ipc_call_t * answer, int answer_count);
-
-extern int bind_service(services_t, ipcarg_t, ipcarg_t, ipcarg_t,
-    async_client_conn_t);
-extern int bind_service_timeout(services_t, ipcarg_t, ipcarg_t, ipcarg_t,
-    async_client_conn_t, suseconds_t);
-
-/** Connects to the needed module.
- *  @param[in] need The needed module service.
- *  @returns The phone of the needed service.
- */
-extern int connect_to_service(services_t need);
-
-/** Connects to the needed module.
- *  @param[in] need The needed module service.
- *  @param[in] timeout The connection timeout in microseconds. No timeout if set to zero (0).
- *  @returns The phone of the needed service.
- *  @returns ETIMEOUT if the connection timeouted.
- */
-extern int connect_to_service_timeout(services_t need, suseconds_t timeout);
-
-/** Receives data from the other party.
- *  The received data buffer is allocated and returned.
- *  @param[out] data The data buffer to be filled.
- *  @param[out] length The buffer length.
- *  @returns EOK on success.
- *  @returns EBADMEM if the data or the length parameter is NULL.
- *  @returns EINVAL if the client does not send data.
- *  @returns ENOMEM if there is not enough memory left.
- *  @returns Other error codes as defined for the async_data_write_finalize() function.
- */
-extern int data_receive(void ** data, size_t * length);
-
-/** Replies the data to the other party.
- *  @param[in] data The data buffer to be sent.
- *  @param[in] data_length The buffer length.
- *  @returns EOK on success.
- *  @returns EINVAL if the client does not expect the data.
- *  @returns EOVERFLOW if the client does not expect all the data. Only partial data are transfered.
- *  @returns Other error codes as defined for the async_data_read_finalize() function.
- */
-extern int data_reply(void * data, size_t data_length);
-
-/** Refreshes answer structure and parameters count.
- *  Erases all attributes.
- *  @param[in,out] answer The message processing answer structure.
- *  @param[in,out] answer_count The number of answer parameters.
- */
-extern void refresh_answer(ipc_call_t * answer, int * answer_count);
-
-#endif
-
-/** @}
- */
Index: pace/lib/socket/include/netdb.h
===================================================================
--- uspace/lib/socket/include/netdb.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ 	(revision )
@@ -1,109 +1,0 @@
-/*
- * Copyright (c) 2009 Lukas Mejdrech
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (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 netdb
- *  @{
- */
-
-/** @file
- *  Structures and interfaces according to the BSD netdb.h file.
- */
-
-#ifndef __NET_NETDB_H__
-#define __NET_NETDB_H__
-
-#include <sys/types.h>
-
-/** Structure returned by network data base library.
- *  All addresses are supplied in host order, and returned in network order (suitable for use in system calls).
- */
-struct	hostent {
-	/** Official host name.
-	 */
-	char * h_name;
-	/** Alias list.
-	 */
-	char **	h_aliases;
-	/** Host address type.
-	 */
-	int h_addrtype;
-	/** Address length.
-	 */
-	int h_length;
-	/** List of addresses from name server.
-	 */
-	char **	h_addr_list;
-	/** Address, for backward compatiblity.
-	 */
-#define	h_addr	h_addr_list[0]
-};
-
-/** @name Host entry address types definitions.
- */
-/*@{*/
-
-/** Authoritative Answer Host not found address type.
- */
-#define	HOST_NOT_FOUND	1
-
-/** Non-Authoritive Host not found, or SERVERFAIL address type.
- */
-#define	TRY_AGAIN	2
-
-/** Non recoverable errors, FORMERR, REFUSED, NOTIMP address type.
- */
-#define	NO_RECOVERY	3
-
-/** Valid name, no data record of requested type address type.
- */
-#define	NO_DATA		4
-
-/** No address, look for MX record address type.
- */
-#define	NO_ADDRESS	NO_DATA
-
-/*@}*/
-
-/** Returns host entry by the host address.
- *  @param[in] address The host address.
- *  @param[in] len The address length.
- *  @param[in] type The address type.
- *  @returns Host entry information.
- */
-//struct hostent *	gethostbyaddr(const void * address, int len, int type);
-
-/** Returns host entry by the host name.
- *  @param[in] name The host name.
- *  @returns Host entry information.
- */
-//struct hostent *	gethostbyname(const char * name);
-
-#endif
-
-/** @}
- */
Index: pace/lib/socket/include/packet/packet.h
===================================================================
--- uspace/lib/socket/include/packet/packet.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ 	(revision )
@@ -1,196 +1,0 @@
-/*
- * Copyright (c) 2009 Lukas Mejdrech
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (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 packet
- *  @{
- */
-
-/** @file
- *  Packet map and queue.
- */
-
-#ifndef __NET_PACKET_H__
-#define __NET_PACKET_H__
-
-/** Packet identifier type.
- *  Value zero (0) is used as an invalid identifier.
- */
-typedef int	packet_id_t;
-
-/** Type definition of the packet.
- *  @see packet
- */
-typedef struct packet *	packet_t;
-
-/** Type definition of the packet pointer.
- *  @see packet
- */
-typedef packet_t *		packet_ref;
-
-/** Type definition of the packet dimension.
- *  @see packet_dimension
- */
-typedef struct packet_dimension	packet_dimension_t;
-
-/** Type definition of the packet dimension pointer.
- *  @see packet_dimension
- */
-typedef packet_dimension_t *	packet_dimension_ref;
-
-/** Packet dimension.
- */
-struct packet_dimension{
-	/** Reserved packet prefix length.
-	 */
-	size_t prefix;
-	/** Maximal packet content length.
-	 */
-	size_t content;
-	/** Reserved packet suffix length.
-	 */
-	size_t suffix;
-	/** Maximal packet address length.
-	 */
-	size_t addr_len;
-};
-
-/** @name Packet management system interface
- */
-/*@{*/
-
-/** Finds the packet mapping.
- *  @param[in] packet_id The packet identifier to be found.
- *  @returns The found packet reference.
- *  @returns NULL if the mapping does not exist.
- */
-extern packet_t pm_find(packet_id_t packet_id);
-
-/** Adds the packet mapping.
- *  @param[in] packet The packet to be remembered.
- *  @returns EOK on success.
- *  @returns EINVAL if the packet is not valid.
- *  @returns EINVAL if the packet map is not initialized.
- *  @returns ENOMEM if there is not enough memory left.
- */
-extern int pm_add(packet_t packet);
-
-/** Initializes the packet map.
- *  @returns EOK on success.
- *  @returns ENOMEM if there is not enough memory left.
- */
-extern int pm_init(void);
-
-/** Releases the packet map.
- */
-extern void pm_destroy(void);
-
-/** Add packet to the sorted queue.
- *  The queue is sorted in the ascending order.
- *  The packet is inserted right before the packets of the same order value.
- *  @param[in,out] first The first packet of the queue. Sets the first packet of the queue. The original first packet may be shifted by the new packet.
- *  @param[in] packet The packet to be added.
- *  @param[in] order The packet order value.
- *  @param[in] metric The metric value of the packet.
- *  @returns EOK on success.
- *  @returns EINVAL if the first parameter is NULL.
- *  @returns EINVAL if the packet is not valid.
- */
-extern int pq_add(packet_t * first, packet_t packet, size_t order, size_t metric);
-
-/** Finds the packet with the given order.
- *  @param[in] first The first packet of the queue.
- *  @param[in] order The packet order value.
- *  @returns The packet with the given order.
- *  @returns NULL if the first packet is not valid.
- *  @returns NULL if the packet is not found.
- */
-extern packet_t pq_find(packet_t first, size_t order);
-
-/** Inserts packet after the given one.
- *  @param[in] packet The packet in the queue.
- *  @param[in] new_packet The new packet to be inserted.
- *  @returns EOK on success.
- *  @returns EINVAL if etiher of the packets is invalid.
- */
-extern int pq_insert_after(packet_t packet, packet_t new_packet);
-
-/** Detach the packet from the queue.
- *  @param[in] packet The packet to be detached.
- *  @returns The next packet in the queue. If the packet is the first one of the queue, this becomes the new first one.
- *  @returns NULL if there is no packet left.
- *  @returns NULL if the packet is not valid.
- */
-extern packet_t pq_detach(packet_t packet);
-
-/** Sets the packet order and metric attributes.
- *  @param[in] packet The packet to be set.
- *  @param[in] order The packet order value.
- *  @param[in] metric The metric value of the packet.
- *  @returns EOK on success.
- *  @returns EINVAL if the packet is invalid..
- */
-extern int pq_set_order(packet_t packet, size_t order, size_t metric);
-
-/** Sets the packet order and metric attributes.
- *  @param[in] packet The packet to be set.
- *  @param[out] order The packet order value.
- *  @param[out] metric The metric value of the packet.
- *  @returns EOK on success.
- *  @returns EINVAL if the packet is invalid..
- */
-extern int pq_get_order(packet_t packet, size_t * order, size_t * metric);
-
-/** Releases the whole queue.
- *  Detaches all packets of the queue and calls the packet_release() for each of them.
- *  @param[in] first The first packet of the queue.
- *  @param[in] packet_release The releasing function called for each of the packets after its detachment.
- */
-extern void pq_destroy(packet_t first, void (*packet_release)(packet_t packet));
-
-/** Returns the next packet in the queue.
- *  @param[in] packet The packet queue member.
- *  @returns The next packet in the queue.
- *  @returns NULL if there is no next packet.
- *  @returns NULL if the packet is not valid.
- */
-extern packet_t pq_next(packet_t packet);
-
-/** Returns the previous packet in the queue.
- *  @param[in] packet The packet queue member.
- *  @returns The previous packet in the queue.
- *  @returns NULL if there is no previous packet.
- *  @returns NULL if the packet is not valid.
- */
-extern packet_t pq_previous(packet_t packet);
-
-/*@}*/
-
-#endif
-
-/** @}
- */
Index: pace/lib/socket/include/packet/packet_client.h
===================================================================
--- uspace/lib/socket/include/packet/packet_client.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ 	(revision )
@@ -1,221 +1,0 @@
-/*
- * Copyright (c) 2009 Lukas Mejdrech
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (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 packet
- *  @{
- */
-
-/** @file
- *  Packet client.
- *  The hosting module has to be compiled with both the packet.c and the packet_client.c source files.
- *  To function correctly, initialization of the packet map by the pm_init() function has to happen at the first place.
- *  The module should not send the packet messages to the packet server but use the functions provided.
- *  The packet map should be released by the pm_destroy() function during the module termination.
- *  The packets and the packet queues can't be locked at all.
- *  The processing modules should process them sequentially -&nbsp;by passing the packets to the next module and stopping using the passed ones.
- *  @see packet.h
- */
-
-#ifndef __NET_PACKET_CLIENT_H__
-#define __NET_PACKET_CLIENT_H__
-
-#include <packet/packet.h>
-
-/** @name Packet client interface
- */
-/*@{*/
-
-/** Allocates the specified type right before the actual packet content and returns its pointer.
- *  The wrapper of the packet_prepend() function.
- *  @param[in] packet The packet to be used.
- *  @param[in] type The type to be allocated at the beginning of the packet content.
- *  @returns The typed pointer to the allocated memory.
- *  @returns NULL if the packet is not valid.
- *  @returns NULL if there is not enough memory left.
- */
-#define PACKET_PREFIX(packet, type)	(type *) packet_prefix((packet), sizeof(type))
-
-/** Allocates the specified type right after the actual packet content and returns its pointer.
- *  The wrapper of the packet_append() function.
- *  @param[in] packet The packet to be used.
- *  @param[in] type The type to be allocated at the end of the packet content.
- *  @returns The typed pointer to the allocated memory.
- *  @returns NULL if the packet is not valid.
- *  @returns NULL if there is not enough memory left.
- */
-#define PACKET_SUFFIX(packet, type)	(type *) packet_suffix((packet), sizeof(type))
-
-/** Trims the actual packet content by the specified prefix and suffix types.
- *  The wrapper of the packet_trim() function.
- *  @param[in] packet The packet to be trimmed.
- *  @param[in] prefix The type of the prefix to be removed from the beginning of the packet content.
- *  @param[in] suffix The type of the suffix to be removed from the end of the packet content.
- *  @returns EOK on success.
- *  @returns EINVAL if the packet is not valid.
- *  @returns ENOMEM if there is not enough memory left.
- */
-#define PACKET_TRIM(packet, prefix, suffix)	packet_trim((packet), sizeof(prefix), sizeof(suffix))
-
-/** Allocates the specified space right before the actual packet content and returns its pointer.
- *  @param[in] packet The packet to be used.
- *  @param[in] length The space length to be allocated at the beginning of the packet content.
- *  @returns The pointer to the allocated memory.
- *  @returns NULL if there is not enough memory left.
- */
-extern void * packet_prefix(packet_t packet, size_t length);
-
-/** Allocates the specified space right after the actual packet content and returns its pointer.
- *  @param[in] packet The packet to be used.
- *  @param[in] length The space length to be allocated at the end of the packet content.
- *  @returns The pointer to the allocated memory.
- *  @returns NULL if there is not enough memory left.
- */
-extern void * packet_suffix(packet_t packet, size_t length);
-
-/** Trims the actual packet content by the specified prefix and suffix lengths.
- *  @param[in] packet The packet to be trimmed.
- *  @param[in] prefix The prefix length to be removed from the beginning of the packet content.
- *  @param[in] suffix The suffix length to be removed from the end of the packet content.
- *  @returns EOK on success.
- *  @returns EINVAL if the packet is not valid.
- *  @returns ENOMEM if there is not enough memory left.
- */
-extern int packet_trim(packet_t packet, size_t prefix, size_t suffix);
-
-/** Copies the specified data to the beginning of the actual packet content.
- *  Pushes the content end if needed.
- *  @param[in] packet The packet to be filled.
- *  @param[in] data The data to be copied.
- *  @param[in] length The length of the copied data.
- *  @returns EOK on success.
- *  @returns EINVAL if the packet is not valid.
- *  @returns ENOMEM if there is not enough memory left.
- */
-extern int packet_copy_data(packet_t packet, const void * data, size_t length);
-
-/** Returns the packet identifier.
- *  @param[in] packet The packet.
- *  @returns The packet identifier.
- *  @returns Zero (0) if the packet is not valid.
- */
-extern packet_id_t packet_get_id(const packet_t packet);
-
-/** Returns the packet content length.
- *  @param[in] packet The packet.
- *  @returns The packet content length in bytes.
- *  @returns Zero (0) if the packet is not valid.
- */
-extern size_t packet_get_data_length(const packet_t packet);
-
-/** Returns the pointer to the beginning of the packet content.
- *  @param[in] packet The packet.
- *  @returns The pointer to the beginning of the packet content.
- *  @returns NULL if the packet is not valid.
- */
-extern void * packet_get_data(const packet_t packet);
-
-/** Returns the stored packet addresses and their length.
- *  @param[in] packet The packet.
- *  @param[out] src The source address. May be NULL if not desired.
- *  @param[out] dest The destination address. May be NULL if not desired.
- *  @returns The stored addresses length.
- *  @returns Zero (0) if the addresses are not present.
- *  @returns EINVAL if the packet is not valid.
- */
-extern int packet_get_addr(const packet_t packet, uint8_t ** src, uint8_t ** dest);
-
-/** Sets the packet addresses.
- *  @param[in] packet The packet.
- *  @param[in] src The new source address. May be NULL.
- *  @param[in] dest The new destination address. May be NULL.
- *  @param[in] addr_len The addresses length.
- *  @returns EOK on success.
- *  @returns EINVAL if the packet is not valid.
- *  @returns ENOMEM if there is not enough memory left.
- */
-extern int packet_set_addr(packet_t packet, const uint8_t * src, const uint8_t * dest, size_t addr_len);
-
-/** Translates the packet identifier to the packet reference.
- *  Tries to find mapping first.
- *  Contacts the packet server to share the packet if the mapping is not present.
- *  @param[in] phone The packet server module phone.
- *  @param[out] packet The packet reference.
- *  @param[in] packet_id The packet identifier.
- *  @returns EOK on success.
- *  @returns EINVAL if the packet parameter is NULL.
- *  @returns Other error codes as defined for the NET_PACKET_GET_SIZE message.
- *  @returns Other error codes as defined for the packet_return() function.
- */
-extern int packet_translate_local(int phone, packet_ref packet, packet_id_t packet_id);
-
-/** Obtains the packet of the given dimensions.
- *  Contacts the packet server to return the appropriate packet.
- *  @param[in] phone The packet server module phone.
- *  @param[in] addr_len The source and destination addresses maximal length in bytes.
- *  @param[in] max_prefix The maximal prefix length in bytes.
- *  @param[in] max_content The maximal content length in bytes.
- *  @param[in] max_suffix The maximal suffix length in bytes.
- *  @returns The packet reference.
- *  @returns NULL on error.
- */
-extern packet_t packet_get_4_local(int phone, size_t max_content, size_t addr_len, size_t max_prefix, size_t max_suffix);
-
-/** Obtains the packet of the given content size.
- *  Contacts the packet server to return the appropriate packet.
- *  @param[in] phone The packet server module phone.
- *  @param[in] content The maximal content length in bytes.
- *  @returns The packet reference.
- *  @returns NULL on error.
- */
-extern packet_t packet_get_1_local(int phone, size_t content);
-
-/** Releases the packet queue.
- *  All packets in the queue are marked as free for use.
- *  The packet queue may be one packet only.
- *  The module should not use the packets after this point until they are received or obtained again.
- *  @param[in] phone The packet server module phone.
- *  @param[in] packet_id The packet identifier.
- */
-extern void pq_release_local(int phone, packet_id_t packet_id);
-
-/** Returns the packet copy.
- *  Copies the addresses, data, order and metric values.
- *  Does not copy the queue placement.
- *  @param[in] phone The packet server module phone.
- *  @param[in] packet The original packet.
- *  @returns The packet copy.
- *  @returns NULL on error.
- */
-extern packet_t packet_get_copy(int phone, packet_t packet);
-
-/*@}*/
-
-#endif
-
-/** @}
- */
Index: pace/lib/socket/include/packet/packet_header.h
===================================================================
--- uspace/lib/socket/include/packet/packet_header.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ 	(revision )
@@ -1,123 +1,0 @@
-/*
- * Copyright (c) 2009 Lukas Mejdrech
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (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 packet
- *  @{
- */
-
-/** @file
- *  Packet header.
- */
-
-#ifndef __NET_PACKET_HEADER_H__
-#define __NET_PACKET_HEADER_H__
-
-#include <packet/packet.h>
-
-/** Returns the actual packet data length.
- *  @param[in] header The packet header.
- */
-#define PACKET_DATA_LENGTH(header)		((header)->data_end - (header)->data_start)
-
-/** Returns the maximum packet address length.
- *  @param[in] header The packet header.
- */
-#define PACKET_MAX_ADDRESS_LENGTH(header)		((header)->dest_addr - (header)->src_addr)
-
-/** Returns the minimum packet suffix.
- *  @param[in] header The packet header.
- */
-#define PACKET_MIN_SUFFIX(header)		((header)->length - (header)->data_start - (header)->max_content)
-
-/** Packet integrity check magic value.
- */
-#define PACKET_MAGIC_VALUE	0x11227788
-
-/** Packet header.
- */
-struct packet{
-	/** Packet identifier.
-	 */
-	packet_id_t packet_id;
-	/** Packet queue sorting value.
-	 *  The packet queue is sorted the ascending order.
-	 */
-	size_t order;
-	/** Packet metric.
-	 */
-	size_t metric;
-	/** Previous packet in the queue.
-	 */
-	packet_id_t previous;
-	/** Next packet in the queue.
-	 */
-	packet_id_t next;
-	/** Total length of the packet.
-	 *  Contains the header, the addresses and the data of the packet.
-	 *  Corresponds to the mapped sharable memory block.
-	 */
-	size_t length;
-	/** Stored source and destination addresses length.
-	 */
-	size_t addr_len;
-	/** Souce address offset in bytes from the beginning of the packet header.
-	 */
-	size_t src_addr;
-	/** Destination address offset in bytes from the beginning of the packet header.
-	 */
-	size_t dest_addr;
-	/** Reserved data prefix length in bytes.
-	 */
-	size_t max_prefix;
-	/** Reserved content length in bytes.
-	 */
-	size_t max_content;
-	/** Actual data start offset in bytes from the beginning of the packet header.
-	 */
-	size_t data_start;
-	/** Actual data end offset in bytes from the beginning of the packet header.
-	 */
-	size_t data_end;
-	/** Integrity check magic value.
-	 */
-	int magic_value;
-};
-
-/** Returns whether the packet is valid.
- *  @param[in] packet The packet to be checked.
- *  @returns true if the packet is not NULL and the magic value is correct.
- *  @returns false otherwise.
- */
-static inline int packet_is_valid(const packet_t packet){
-	return packet && (packet->magic_value == PACKET_MAGIC_VALUE);
-}
-
-#endif
-
-/** @}
- */
Index: pace/lib/socket/include/packet/packet_messages.h
===================================================================
--- uspace/lib/socket/include/packet/packet_messages.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ 	(revision )
@@ -1,96 +1,0 @@
-/*
- * Copyright (c) 2009 Lukas Mejdrech
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (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 packet
- *  @{
- */
-
-/** @file
- *  Packet server module messages.
- */
-
-#ifndef __NET_PACKET_MESSAGES__
-#define __NET_PACKET_MESSAGES__
-
-#include <ipc/ipc.h>
-
-#include <net_messages.h>
-
-/** Packet server module messages.
- */
-typedef enum {
-	/** Create packet message with specified content length.
-	 *  @see packet_get_1()
-	 */
-	NET_PACKET_CREATE_1 = NET_PACKET_FIRST,
-	/** Create packet message with specified address length, prefix, content and suffix.
-	 *  @see packet_get_4()
-	 */
-	NET_PACKET_CREATE_4,
-	/** Get packet message.
-	 *  @see packet_return()
-	 */
-	NET_PACKET_GET,
-	/** Get packet size message.
-	 *  @see packet_translate()
-	 */
-	NET_PACKET_GET_SIZE,
-	/** Release packet message.
-	 *  @see pq_release()
-	 */
-	NET_PACKET_RELEASE
-} packet_messages;
-
-/** Returns the protocol service message parameter.
- */
-#define ARP_GET_PROTO(call)		(services_t) IPC_GET_ARG2(*call)
-
-/** Returns the packet identifier message parameter.
- */
-#define IPC_GET_ID(call)			(packet_id_t) IPC_GET_ARG1(*call)
-
-/** Returns the maximal content length message parameter.
- */
-#define IPC_GET_CONTENT(call)		(size_t) IPC_GET_ARG1(*call)
-
-/** Returns the maximal address length message parameter.
- */
-#define IPC_GET_ADDR_LEN(call)	(size_t) IPC_GET_ARG2(*call)
-
-/** Returns the maximal prefix length message parameter.
- */
-#define IPC_GET_PREFIX(call)		(size_t) IPC_GET_ARG3(*call)
-
-/** Returns the maximal suffix length message parameter.
- */
-#define IPC_GET_SUFFIX(call)		(size_t) IPC_GET_ARG4(*call)
-
-#endif
-
-/** @}
- */
Index: pace/lib/socket/include/packet/packet_server.h
===================================================================
--- uspace/lib/socket/include/packet/packet_server.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ 	(revision )
@@ -1,63 +1,0 @@
-/*
- * Copyright (c) 2009 Lukas Mejdrech
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (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 packet
- *  @{
- */
-
-/** @file
- *  Packet server.
- *  The hosting module has to be compiled with both the packet.c and the packet_server.c source files.
- *  To function correctly, initialization of the packet map by the pm_init() function has to happen at the first place.
- *  Then the packet messages have to be processed by the packet_server_message() function.
- *  The packet map should be released by the pm_destroy() function during the module termination.
- *  @see IS_NET_PACKET_MESSAGE()
- */
-
-#ifndef __NET_PACKET_SERVER_H__
-#define __NET_PACKET_SERVER_H__
-
-#include <ipc/ipc.h>
-
-/** Processes the packet server message.
- *  @param[in] callid The message identifier.
- *  @param[in] call The message parameters.
- *  @param[out] answer The message answer parameters.
- *  @param[out] answer_count The last parameter for the actual answer in the answer parameter.
- *  @returns EOK on success.
- *  @returns ENOMEM if there is not enough memory left.
- *  @returns ENOENT if there is no such packet as in the packet message parameter..
- *  @returns ENOTSUP if the message is not known.
- *  @returns Other error codes as defined for the packet_release_wrapper() function.
- */
-extern int packet_server_message(ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count);
-
-#endif
-
-/** @}
- */
Index: pace/lib/socket/include/socket.h
===================================================================
--- uspace/lib/socket/include/socket.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ 	(revision )
@@ -1,214 +1,0 @@
-/*
- * Copyright (c) 2009 Lukas Mejdrech
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (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 socket
- *  @{
- */
-
-/** @file
- *  Socket application program interface (API).
- *  This is a part of the network application library.
- *  Based on the BSD socket interface.
- */
-
-#ifndef __NET_SOCKET_H__
-#define __NET_SOCKET_H__
-
-#include <net_byteorder.h>
-#include <in.h>
-#include <in6.h>
-#include <inet.h>
-#include <socket_codes.h>
-#include <socket_errno.h>
-
-/** @name Socket application programming interface
- */
-/*@{*/
-
-/** Creates a new socket.
- *  @param[in] domain The socket protocol family.
- *  @param[in] type Socket type.
- *  @param[in] protocol Socket protocol.
- *  @returns The socket identifier on success.
- *  @returns EPFNOTSUPPORT if the protocol family is not supported.
- *  @returns ESOCKNOTSUPPORT if the socket type is not supported.
- *  @returns EPROTONOSUPPORT if the protocol is not supported.
- *  @returns ENOMEM if there is not enough memory left.
- *  @returns ELIMIT if there was not a free socket identifier found this time.
- *  @returns Other error codes as defined for the NET_SOCKET message.
- *  @returns Other error codes as defined for the bind_service_timeout() function.
- */
-extern int socket(int domain, int type, int protocol);
-
-/** Binds the socket to a port address.
- *  @param[in] socket_id Socket identifier.
- *  @param[in] my_addr The port address.
- *  @param[in] addrlen The address length.
- *  @returns EOK on success.
- *  @returns ENOTSOCK if the socket is not found.
- *  @returns EBADMEM if the my_addr parameter is NULL.
- *  @returns NO_DATA if the addlen parameter is zero (0).
- *  @returns Other error codes as defined for the NET_SOCKET_BIND message.
- */
-extern int bind(int socket_id, const struct sockaddr * my_addr, socklen_t addrlen);
-
-/** Sets the number of connections waiting to be accepted.
- *  @param[in] socket_id Socket identifier.
- *  @param[in] backlog The maximum number of waiting sockets to be accepted.
- *  @returns EOK on success.
- *  @returns EINVAL if the backlog parameter is not positive (<=0).
- *  @returns ENOTSOCK if the socket is not found.
- *  @returns Other error codes as defined for the NET_SOCKET_LISTEN message.
- */
-extern int listen(int socket_id, int backlog);
-
-/** Accepts waiting socket.
- *  Blocks until such a socket exists.
- *  @param[in] socket_id Socket identifier.
- *  @param[out] cliaddr The remote client address.
- *  @param[in] addrlen The address length.
- *  @returns EOK on success.
- *  @returns EBADMEM if the cliaddr or addrlen parameter is NULL.
- *  @returns EINVAL if the backlog parameter is not positive (<=0).
- *  @returns ENOTSOCK if the socket is not found.
- *  @returns Other error codes as defined for the NET_SOCKET_ACCEPT message.
- */
-extern int accept(int socket_id, struct sockaddr * cliaddr, socklen_t * addrlen);
-
-/** Connects socket to the remote server.
- *  @param[in] socket_id Socket identifier.
- *  @param[in] serv_addr The remote server address.
- *  @param[in] addrlen The address length.
- *  @returns EOK on success.
- *  @returns EBADMEM if the serv_addr parameter is NULL.
- *  @returns NO_DATA if the addlen parameter is zero (0).
- *  @returns ENOTSOCK if the socket is not found.
- *  @returns Other error codes as defined for the NET_SOCKET_CONNECT message.
- */
-extern int connect(int socket_id, const struct sockaddr * serv_addr, socklen_t addrlen);
-
-/** Closes the socket.
- *  @param[in] socket_id Socket identifier.
- *  @returns EOK on success.
- *  @returns ENOTSOCK if the socket is not found.
- *  @returns EINPROGRESS if there is another blocking function in progress.
- *  @returns Other error codes as defined for the NET_SOCKET_CLOSE message.
- */
-extern int closesocket(int socket_id);
-
-/** Sends data via the socket.
- *  @param[in] socket_id Socket identifier.
- *  @param[in] data The data to be sent.
- *  @param[in] datalength The data length.
- *  @param[in] flags Various send flags.
- *  @returns EOK on success.
- *  @returns ENOTSOCK if the socket is not found.
- *  @returns EBADMEM if the data parameter is NULL.
- *  @returns NO_DATA if the datalength parameter is zero (0).
- *  @returns Other error codes as defined for the NET_SOCKET_SEND message.
- */
-extern int send(int socket_id, void * data, size_t datalength, int flags);
-
-/** Sends data via the socket to the remote address.
- *  Binds the socket to a free port if not already connected/bound.
- *  @param[in] socket_id Socket identifier.
- *  @param[in] data The data to be sent.
- *  @param[in] datalength The data length.
- *  @param[in] flags Various send flags.
- *  @param[in] toaddr The destination address.
- *  @param[in] addrlen The address length.
- *  @returns EOK on success.
- *  @returns ENOTSOCK if the socket is not found.
- *  @returns EBADMEM if the data or toaddr parameter is NULL.
- *  @returns NO_DATA if the datalength or the addrlen parameter is zero (0).
- *  @returns Other error codes as defined for the NET_SOCKET_SENDTO message.
- */
-extern int sendto(int socket_id, const void * data, size_t datalength, int flags, const struct sockaddr * toaddr, socklen_t addrlen);
-
-/** Receives data via the socket.
- *  @param[in] socket_id Socket identifier.
- *  @param[out] data The data buffer to be filled.
- *  @param[in] datalength The data length.
- *  @param[in] flags Various receive flags.
- *  @returns EOK on success.
- *  @returns ENOTSOCK if the socket is not found.
- *  @returns EBADMEM if the data parameter is NULL.
- *  @returns NO_DATA if the datalength parameter is zero (0).
- *  @returns Other error codes as defined for the NET_SOCKET_RECV message.
- */
-extern int recv(int socket_id, void * data, size_t datalength, int flags);
-
-/** Receives data via the socket.
- *  @param[in] socket_id Socket identifier.
- *  @param[out] data The data buffer to be filled.
- *  @param[in] datalength The data length.
- *  @param[in] flags Various receive flags.
- *  @param[out] fromaddr The source address.
- *  @param[in,out] addrlen The address length. The maximum address length is read. The actual address length is set.
- *  @returns EOK on success.
- *  @returns ENOTSOCK if the socket is not found.
- *  @returns EBADMEM if the data or fromaddr parameter is NULL.
- *  @returns NO_DATA if the datalength or addrlen parameter is zero (0).
- *  @returns Other error codes as defined for the NET_SOCKET_RECVFROM message.
- */
-extern int recvfrom(int socket_id, void * data, size_t datalength, int flags, struct sockaddr * fromaddr, socklen_t * addrlen);
-
-/** Gets socket option.
- *  @param[in] socket_id Socket identifier.
- *  @param[in] level The socket options level.
- *  @param[in] optname The socket option to be get.
- *  @param[out] value The value buffer to be filled.
- *  @param[in,out] optlen The value buffer length. The maximum length is read. The actual length is set.
- *  @returns EOK on success.
- *  @returns ENOTSOCK if the socket is not found.
- *  @returns EBADMEM if the value or optlen parameter is NULL.
- *  @returns NO_DATA if the optlen parameter is zero (0).
- *  @returns Other error codes as defined for the NET_SOCKET_GETSOCKOPT message.
- */
-extern int getsockopt(int socket_id, int level, int optname, void * value, size_t * optlen);
-
-/** Sets socket option.
- *  @param[in] socket_id Socket identifier.
- *  @param[in] level The socket options level.
- *  @param[in] optname The socket option to be set.
- *  @param[in] value The value to be set.
- *  @param[in] optlen The value length.
- *  @returns EOK on success.
- *  @returns ENOTSOCK if the socket is not found.
- *  @returns EBADMEM if the value parameter is NULL.
- *  @returns NO_DATA if the optlen parameter is zero (0).
- *  @returns Other error codes as defined for the NET_SOCKET_SETSOCKOPT message.
- */
-extern int setsockopt(int socket_id, int level, int optname, const void * value, size_t optlen);
-
-/*@}*/
-
-#endif
-
-/** @}
- */
Index: pace/lib/socket/include/socket_codes.h
===================================================================
--- uspace/lib/socket/include/socket_codes.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ 	(revision )
@@ -1,460 +1,0 @@
-/*
- * Copyright (c) 2009 Lukas Mejdrech
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (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 socket
- *  @{
- */
-
-/** @file
- *  Socket codes and definitions.
- *  This is a part of the network application library.
- */
-
-#ifndef __NET_SOCKET_CODES_H__
-#define __NET_SOCKET_CODES_H__
-
-#include <sys/types.h>
-
-/** @name Address families definitions
- */
-/*@{*/
-
-/** Unspecified address family.
- */
-#define AF_UNSPEC	0
-
-/** Unix domain sockets address family.
- */
-#define AF_UNIXL	1
-
-/** POSIX name for AF_UNIX address family.
- */
-#define AF_LOCAL	1
-
-/** Internet IP Protocol address family.
- */
-#define AF_INET		2
-
-/** Amateur Radio AX.25 address family.
- */
-#define AF_AX25		3
-
-/** Novell IPX address family.
- */
-#define AF_IPX		4
-
-/** AppleTalk DDP address family.
- */
-#define AF_APPLETALK	5
-
-/** Amateur Radio NET/ROM address family.
- */
-#define AF_NETROM	6
-
-/** Multiprotocol bridge address family.
- */
-#define AF_BRIDGE	7
-
-/** ATM PVCs address family.
- */
-#define AF_ATMPVC	8
-
-/** Reserved for X.25 project address family.
- */
-#define AF_X25		9
-
-/** IP version 6 address family.
- */
-#define AF_INET6	10
-
-/** Amateur Radio X.25 PLP address family.
- */
-#define AF_ROSE		11
-
-/** Reserved for DECnet project address family.
- */
-#define AF_DECnet	12
-
-/** Reserved for 802.2LLC project address family.
- */
-#define AF_NETBEUI	13
-
-/** Security callback pseudo AF address family.
- */
-#define AF_SECURITY	14
-
-/** PF_KEY key management API address family.
- */
-#define AF_KEY		15
-
-/** Alias to emulate 4.4BSD address family.
- */
-#define AF_NETLINK	16
-
-/** Packet family address family.
- */
-#define AF_PACKET	17
-
-/** Ash address family.
- */
-#define AF_ASH		18
-
-/** Acorn Econet address family.
- */
-#define AF_ECONET	19
-
-/** ATM SVCs address family.
- */
-#define AF_ATMSVC	20
-
-/** Linux SNA Project (nutters!) address family.
- */
-#define AF_SNA		22
-
-/** IRDA sockets address family.
- */
-#define AF_IRDA		23
-
-/** PPPoX sockets address family.
- */
-#define AF_PPPOX	24
-
-/** Wanpipe API Sockets address family.
- */
-#define AF_WANPIPE	25
-
-/** Linux LLC address family.
- */
-#define AF_LLC		26
-
-/** Controller Area Network address family.
- */
-#define AF_CAN		29
-
-/** TIPC sockets address family.
- */
-#define AF_TIPC		30
-
-/** Bluetooth sockets address family.
- */
-#define AF_BLUETOOTH	31
-
-/** IUCV sockets address family.
- */
-#define AF_IUCV		32
-
-/** RxRPC sockets address family.
- */
-#define AF_RXRPC	33
-
-/** Maximum address family.
- */
-#define AF_MAX		34
-
-/*@}*/
-
-/** @name Protocol families definitions
- *  Same as address families.
- */
-/*@{*/
-
-/** Unspecified protocol family.
- */
-#define PF_UNSPEC	AF_UNSPEC
-
-/** Unix domain sockets protocol family.
- */
-#define PF_UNIXL	AF_UNIXL
-
-/** POSIX name for AF_UNIX protocol family.
- */
-#define PF_LOCAL	AF_LOCAL
-
-/** Internet IP Protocol protocol family.
- */
-#define PF_INET		AF_INET
-
-/** Amateur Radio AX.25 protocol family.
- */
-#define PF_AX25		AF_AX25
-
-/** Novell IPX protocol family.
- */
-#define PF_IPX		AF_IPX
-
-/** AppleTalk DDP protocol family.
- */
-#define PF_APPLETALK	AF_APPLETALK
-
-/** Amateur Radio NET/ROM protocol family.
- */
-#define PF_NETROM	AF_NETROM
-
-/** Multiprotocol bridge protocol family.
- */
-#define PF_BRIDGE	AF_BRIDGE
-
-/** ATM PVCs protocol family.
- */
-#define PF_ATMPVC	AF_ATMPVC
-
-/** Reserved for X.25 project protocol family.
- */
-#define PF_X25		AF_X25
-
-/** IP version 6 protocol family.
- */
-#define PF_INET6	AF_INET6
-
-/** Amateur Radio X.25 PLP protocol family.
- */
-#define PF_ROSE		AF_ROSE
-
-/** Reserved for DECnet project protocol family.
- */
-#define PF_DECnet	AF_DECnet
-
-/** Reserved for 802.2LLC project protocol family.
- */
-#define PF_NETBEUI	AF_NETBEUI
-
-/** Security callback pseudo AF protocol family.
- */
-#define PF_SECURITY	AF_SECURITY
-
-/** PF_KEY key management API protocol family.
- */
-#define PF_KEY		AF_KEY
-
-/** Alias to emulate 4.4BSD protocol family.
- */
-#define PF_NETLINK	AF_NETLINK
-
-/** Packet family protocol family.
- */
-#define PF_PACKET	AF_PACKET
-
-/** Ash protocol family.
- */
-#define PF_ASH		AF_ASH
-
-/** Acorn Econet protocol family.
- */
-#define PF_ECONET	AF_ECONET
-
-/** ATM SVCs protocol family.
- */
-#define PF_ATMSVC	AF_ATMSVC
-
-/** Linux SNA Project (nutters!) protocol family.
- */
-#define PF_SNA		AF_SNA
-
-/** IRDA sockets protocol family.
- */
-#define PF_IRDA		AF_IRDA
-
-/** PPPoX sockets protocol family.
- */
-#define PF_PPPOX	AF_PPPOX
-
-/** Wanpipe API Sockets protocol family.
- */
-#define PF_WANPIPE	AF_WANPIPE
-
-/** Linux LLC protocol family.
- */
-#define PF_LLC		AF_LLC
-
-/** Controller Area Network protocol family.
- */
-#define PF_CAN		AF_CAN
-
-/** TIPC sockets protocol family.
- */
-#define PF_TIPC		AF_TIPC
-
-/** Bluetooth sockets protocol family.
- */
-#define PF_BLUETOOTH	AF_BLUETOOTH
-
-/** IUCV sockets protocol family.
- */
-#define PF_IUCV		AF_IUCV
-
-/** RxRPC sockets protocol family.
- */
-#define PF_RXRPC	AF_RXRPC
-
-/** Maximum protocol family.
- */
-#define PF_MAX		AF_MAX
-
-/*@}*/
-
-/** @name Socket option levels definitions
- *  Thanks to BSD these must match IPPROTO_xxx
- */
-/*@{*/
-
-/** IP socket option level.
- */
-#define SOL_IP		0
-
-/** ICMP socket option level.
- */
-#define SOL_ICMP	1
-
-/** TCP socket option level.
- */
-#define SOL_TCP		6
-
-/** UDP socket option level.
- */
-#define SOL_UDP		17
-
-/** IPV socket option level.
- */
-#define SOL_IPV6	41
-
-/** ICMPV socket option level.
- */
-#define SOL_ICMPV6	58
-
-/** SCTP socket option level.
- */
-#define SOL_SCTP	132
-
-/** UDP-Lite (RFC 3828) socket option level.
- */
-#define SOL_UDPLITE	136
-
-/** RAW socket option level.
- */
-#define SOL_RAW		255
-
-/** IPX socket option level.
- */
-#define SOL_IPX		256
-
-/** AX socket option level.
- */
-#define SOL_AX25	257
-
-/** ATALK socket option level.
- */
-#define SOL_ATALK	258
-
-/** NETROM socket option level.
- */
-#define SOL_NETROM	259
-
-/** ROSE socket option level.
- */
-#define SOL_ROSE	260
-
-/** DECNET socket option level.
- */
-#define SOL_DECNET	261
-
-/** X25 socket option level.
- */
-#define	SOL_X25		262
-
-/** PACKET socket option level.
- */
-#define SOL_PACKET	263
-
-/** ATM layer (cell level) socket option level.
- */
-#define SOL_ATM		264
-
-/** ATM Adaption Layer (packet level) socket option level.
- */
-#define SOL_AAL		265
-
-/** IRDA socket option level.
- */
-#define SOL_IRDA	266
-
-/** NETBEUI socket option level.
- */
-#define SOL_NETBEUI	267
-
-/** LLC socket option level.
- */
-#define SOL_LLC		268
-
-/** DCCP socket option level.
- */
-#define SOL_DCCP	269
-
-/** NETLINK socket option level.
- */
-#define SOL_NETLINK	270
-
-/** TIPC socket option level.
- */
-#define SOL_TIPC	271
-
-/** RXRPC socket option level.
- */
-#define SOL_RXRPC	272
-
-/** PPPOL socket option level.
- */
-#define SOL_PPPOL2TP	273
-
-/** BLUETOOTH socket option level.
- */
-#define SOL_BLUETOOTH	274
-
-/*@}*/
-
-/** Socket types.
- */
-typedef enum sock_type{
-	/** Stream (connection oriented) socket.
-	 */
-	SOCK_STREAM = 1,
-	/** Datagram (connectionless oriented) socket.
-	 */
-	SOCK_DGRAM = 2,
-	/** Raw socket.
-	 */
-	SOCK_RAW = 3
-} sock_type_t;
-
-/** Type definition of the socket length.
- */
-typedef int32_t	socklen_t;
-
-#endif
-
-/** @}
- */
Index: pace/lib/socket/include/socket_core.h
===================================================================
--- uspace/lib/socket/include/socket_core.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ 	(revision )
@@ -1,242 +1,0 @@
-/*
- * Copyright (c) 2009 Lukas Mejdrech
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (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 socket
- *  @{
- */
-
-/** @file
- *  Socket common core.
- */
-
-#ifndef __NET_SOCKET_CORE_H__
-#define __NET_SOCKET_CORE_H__
-
-#include <sys/types.h>
-
-#include <in.h>
-#include <net_device.h>
-#include <adt/generic_char_map.h>
-#include <adt/dynamic_fifo.h>
-#include <adt/int_map.h>
-#include <packet/packet.h>
-
-/** Initial size of the received packet queue.
- */
-#define SOCKET_INITIAL_RECEIVED_SIZE	4
-
-/** Maximum size of the received packet queue.
- */
-#define SOCKET_MAX_RECEIVED_SIZE		0
-
-/** Initial size of the sockets for acceptance queue.
- */
-#define SOCKET_INITIAL_ACCEPTED_SIZE	1
-
-/** Maximum size of the sockets for acceptance queue.
- */
-#define SOCKET_MAX_ACCEPTEDED_SIZE		0
-
-/** Listening sockets' port map key.
- */
-#define SOCKET_MAP_KEY_LISTENING	"L"
-
-/** Type definition of the socket core.
- *  @see socket_core
- */
-typedef struct socket_core	socket_core_t;
-
-/** Type definition of the socket core pointer.
- *  @see socket_core
- */
-typedef socket_core_t *	socket_core_ref;
-
-/** Type definition of the socket port.
- *  @see socket_port
- */
-typedef struct socket_port	socket_port_t;
-
-/** Type definition of the socket port pointer.
- *  @see socket_port
- */
-typedef socket_port_t *	socket_port_ref;
-
-/** Socket core.
- */
-struct socket_core{
-	/** Socket identifier.
-	 */
-	int socket_id;
-	/** Client application phone.
-	 */
-	int phone;
-	/** Bound port.
-	 */
-	int port;
-	/** Received packets queue.
-	 */
-	dyn_fifo_t received;
-	/** Sockets for acceptance queue.
-	 */
-	dyn_fifo_t accepted;
-	/** Protocol specific data.
-	 */
-	void * specific_data;
-	/** Socket ports map key.
-	 */
-	const char * key;
-	/** Length of the Socket ports map key.
-	 */
-	size_t key_length;
-};
-
-/** Sockets map.
- *  The key is the socket identifier.
- */
-INT_MAP_DECLARE(socket_cores, socket_core_t);
-
-/** Bount port sockets map.
- *  The listening socket has the SOCKET_MAP_KEY_LISTENING key identifier whereas the other use the remote addresses.
- */
-GENERIC_CHAR_MAP_DECLARE(socket_port_map, socket_core_ref);
-
-/** Ports map.
- *  The key is the port number.
- */
-INT_MAP_DECLARE(socket_ports, socket_port_t);
-
-/** Destroys local sockets.
- *  Releases all buffered packets and calls the release function for each of the sockets.
- *  @param[in] packet_phone The packet server phone to release buffered packets.
- *  @param[in] local_sockets The local sockets to be destroyed.
- *  @param[in,out] global_sockets The global sockets to be updated.
- *  @param[in] socket_release The client release callback function.
- */
-extern void socket_cores_release(int packet_phone, socket_cores_ref local_sockets, socket_ports_ref global_sockets, void (*socket_release)(socket_core_ref socket));
-
-/** Binds the socket to the port.
- *  The address port is used if set, a free port is used if not.
- *  @param[in] local_sockets The local sockets to be searched.
- *  @param[in,out] global_sockets The global sockets to be updated.
- *  @param[in] socket_id The new socket identifier.
- *  @param[in] addr The address to be bound to.
- *  @param[in] addrlen The address length.
- *  @param[in] free_ports_start The minimum free port.
- *  @param[in] free_ports_end The maximum free port.
- *  @param[in] last_used_port The last used free port.
- *  @returns EOK on success.
- *  @returns ENOTSOCK if the socket was not found.
- *  @returns EAFNOSUPPORT if the address family is not supported.
- *  @returns EADDRINUSE if the port is already in use.
- *  @returns Other error codes as defined for the socket_bind_free_port() function.
- *  @returns Other error codes as defined for the socket_bind_insert() function.
- */
-extern int socket_bind(socket_cores_ref local_sockets, socket_ports_ref global_sockets, int socket_id, void * addr, size_t addrlen, int free_ports_start, int free_ports_end, int last_used_port);
-
-/** Binds the socket to a free port.
- *  The first free port is used.
- *  @param[in,out] global_sockets The global sockets to be updated.
- *  @param[in,out] socket The socket to be bound.
- *  @param[in] free_ports_start The minimum free port.
- *  @param[in] free_ports_end The maximum free port.
- *  @param[in] last_used_port The last used free port.
- *  @returns EOK on success.
- *  @returns ENOTCONN if no free port was found.
- *  @returns Other error codes as defined for the socket_bind_insert() function.
- */
-extern int socket_bind_free_port(socket_ports_ref global_sockets, socket_core_ref socket, int free_ports_start, int free_ports_end, int last_used_port);
-
-/** Creates a new socket.
- *  @param[in,out] local_sockets The local sockets to be updated.
- *  @param[in] app_phone The application phone.
- *  @param[in] specific_data The socket specific data.
- *  @param[in,out] socket_id The new socket identifier. A new identifier is chosen if set to zero (0) or negative. A negative identifier is chosen if set to negative.
- *  @returns EOK on success.
- *  @returns EINVAL if the socket_id parameter is NULL.
- *  @returns ENOMEM if there is not enough memory left.
- */
-extern int socket_create(socket_cores_ref local_sockets, int app_phone, void * specific_data, int * socket_id);
-
-/** Destroys the socket.
- *  If the socket is bound, the port is released.
- *  Releases all buffered packets, calls the release function and removes the socket from the local sockets.
- *  @param[in] packet_phone The packet server phone to release buffered packets.
- *  @param[in] socket_id The socket identifier.
- *  @param[in,out] local_sockets The local sockets to be updated.
- *  @param[in,out] global_sockets The global sockets to be updated.
- *  @param[in] socket_release The client release callback function.
- *  @returns EOK on success.
- *  @returns ENOTSOCK if the socket is not found.
- */
-extern int socket_destroy(int packet_phone, int socket_id, socket_cores_ref local_sockets, socket_ports_ref global_sockets, void (*socket_release)(socket_core_ref socket));
-
-/** Replies the packet or the packet queue data to the application via the socket.
- *  Uses the current message processing fibril.
- *  @param[in] packet The packet to be transfered.
- *  @param[out] length The total data length.
- *  @returns EOK on success.
- *  @returns EBADMEM if the length parameter is NULL.
- *  @returns ENOMEM if there is not enough memory left.
- *  @returns Other error codes as defined for the data_reply() function.
- */
-extern int socket_reply_packets(packet_t packet, size_t * length);
-
-/** Finds the bound port socket.
- *  @param[in] global_sockets The global sockets to be searched.
- *  @param[in] port The port number.
- *  @param[in] key The socket key identifier.
- *  @param[in] key_length The socket key length.
- *  @returns The found socket.
- *  @returns NULL if no socket was found.
- */
-extern socket_core_ref socket_port_find(socket_ports_ref global_sockets, int port, const char * key, size_t key_length);
-
-/** Releases the socket port.
- *  If the socket is bound the port entry is released.
- *  If there are no more port entries the port is release.
- *  @param[in] global_sockets The global sockets to be updated.
- *  @param[in] socket The socket to be unbound.
- */
-extern void socket_port_release(socket_ports_ref global_sockets, socket_core_ref socket);
-
-/** Adds the socket to an already bound port.
- *  @param[in] global_sockets The global sockets to be updated.
- *  @param[in] port The port number to be bound to.
- *  @param[in] socket The socket to be added.
- *  @param[in] key The socket key identifier.
- *  @param[in] key_length The socket key length.
- *  @returns EOK on success.
- *  @returns ENOENT if the port is not already used.
- *  @returns Other error codes as defined for the socket_port_add_core() function.
- */
-extern int socket_port_add(socket_ports_ref global_sockets, int port, socket_core_ref socket, const char * key, size_t key_length);
-
-#endif
-
-/** @}
- */
Index: pace/lib/socket/include/socket_errno.h
===================================================================
--- uspace/lib/socket/include/socket_errno.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ 	(revision )
@@ -1,136 +1,0 @@
-/*
- * Copyright (c) 2009 Lukas Mejdrech
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (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 net
- *  @{
- */
-
-/** @file
- *  Socket error codes.
- *  Based on BSD.
- */
-
-#ifndef __NET_SOCKET_ERR_H__
-#define __NET_SOCKET_ERR_H__
-
-#include <errno.h>
-
-/** @name Socket error codes definitions
- */
-/*@{*/
-
-////#define EINTR			(-10004)
-////#define EBADF			(-10009)
-//#define EACCES			(-10013)
-//#define EFAULT			(-10014)
-////#define EINVAL			(-10022)
-////#define EMFILE			(-10024)
-//#define EWOULDBLOCK		(-10035)
-
-/** An API function is called while another blocking function is in progress.
- */
-#define EINPROGRESS		(-10036)
-
-//#define EALREADY		(-10037)
-
-/** The socket identifier is not valid.
- */
-#define ENOTSOCK		(-10038)
-
-/** The destination address required.
- */
-#define EDESTADDRREQ	(-10039)
-
-//#define EMSGSIZE		(-10040)
-//#define EPROTOTYPE		(-10041)
-//#define ENOPROTOOPT		(-10042)
-
-/** Protocol is not supported.
- */
-#define EPROTONOSUPPORT	(-10043)
-
-/** Socket type is not supported.
- */
-#define ESOCKTNOSUPPORT	(-10044)
-
-//#define EOPNOTSUPP		(-10045)
-
-/** Protocol family is not supported.
- */
-#define EPFNOSUPPORT	(-10046)
-
-/** Address family is not supported.
- */
-#define EAFNOSUPPORT	(-10047)
-
-/** Address is already in use.
- */
-#define EADDRINUSE		(-10048)
-
-//#define EADDRNOTAVAIL	(-10049)
-/* May be reported at any time if the implementation detects an underlying failure.
- */
-//#define ENETDOWN		(-10050)
-//#define ENETUNREACH		(-10051)
-//#define ENETRESET		(-10052)
-//#define ECONNABORTED	(-10053)
-//#define ECONNRESET		(-10054)
-//#define ENOBUFS			(-10055)
-//#define EISCONN			(-10056)
-
-/** The socket is not connected or bound.
- */
-#define ENOTCONN		(-10057)
-
-//#define ESHUTDOWN		(-10058)
-//#define ETOOMANYREFS	(-10059)
-//#define ETIMEDOUT		(-10060)
-//#define ECONNREFUSED	(-10061)
-//#define ELOOP			(-10062)
-////#define ENAMETOOLONG	(-10063)
-//#define EHOSTDOWN		(-10064)
-//#define EHOSTUNREACH	(-10065)
-//#define HOST_NOT_FOUND	(-11001)
-
-/** The requested operation was not performed.
- *  Try again later.
- */
-#define TRY_AGAIN		(-11002)
-
-//#define NO_RECOVERY		(-11003)
-
-/** No data.
- */
-#define NO_DATA			(-11004)
-
-/*@}*/
-
-#endif
-
-/** @}
- */
Index: pace/lib/socket/include/socket_messages.h
===================================================================
--- uspace/lib/socket/include/socket_messages.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ 	(revision )
@@ -1,215 +1,0 @@
-/*
- * Copyright (c) 2009 Lukas Mejdrech
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (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 socket
- *  @{
- */
-
-/** @file
- *  Socket messages.
- *  @see socket.h
- */
-
-
-#ifndef __NET_SOCKET_MESSAGES_H__
-#define __NET_SOCKET_MESSAGES_H__
-
-#include <ipc/ipc.h>
-
-#include <net_messages.h>
-#include <socket_codes.h>
-
-/** Socket client messages.
- */
-typedef enum{
-	/** Creates a new socket.
-	 *  @see socket()
-	 */
-	NET_SOCKET = NET_SOCKET_FIRST,
-	/** Binds the socket.
-	 *  @see bind()
-	 */
-	NET_SOCKET_BIND,
-	/** Creates a new socket.
-	 *  @see socket()
-	 */
-	NET_SOCKET_LISTEN,
-	/** Accepts an incomming connection.
-	 *  @see accept()
-	 */
-	NET_SOCKET_ACCEPT,
-	/** Connects the socket.
-	 *  @see connect()
-	 */
-	NET_SOCKET_CONNECT,
-	/** Closes the socket.
-	 *  @see closesocket()
-	 */
-	NET_SOCKET_CLOSE,
-	/** Sends data via the stream socket.
-	 *  @see send()
-	 */
-	NET_SOCKET_SEND,
-	/** Sends data via the datagram socket.
-	 *  @see sendto()
-	 */
-	NET_SOCKET_SENDTO,
-	/** Receives data from the stream socket.
-	 *  @see socket()
-	 */
-	NET_SOCKET_RECV,
-	/** Receives data from the datagram socket.
-	 *  @see socket()
-	 */
-	NET_SOCKET_RECVFROM,
-	/** Gets the socket option.
-	 *  @see getsockopt()
-	 */
-	NET_SOCKET_GETSOCKOPT,
-	/** Sets the socket option.
-	 *  @see setsockopt()
-	 */
-	NET_SOCKET_SETSOCKOPT,
-	/** New socket for acceptence notification message.
-	 */
-	NET_SOCKET_ACCEPTED,
-	/** New data received notification message.
-	 */
-	NET_SOCKET_RECEIVED,
-	/** New socket data fragment size notification message.
-	 */
-	NET_SOCKET_DATA_FRAGMENT_SIZE
-} socket_messages;
-
-/** @name Socket specific message parameters definitions
- */
-/*@{*/
-
-/** Sets the socket identifier in the message answer.
- *  @param[out] answer The message answer structure.
- */
-#define SOCKET_SET_SOCKET_ID(answer, value) \
-	{ipcarg_t argument = (ipcarg_t) (value); IPC_SET_ARG1(answer, argument);}
-
-/** Returns the socket identifier message parameter.
- *  @param[in] call The message call structure.
- */
-#define SOCKET_GET_SOCKET_ID(call) \
-	({int socket_id = (int) IPC_GET_ARG1(call); socket_id;})
-
-/** Sets the read data length in the message answer.
- *  @param[out] answer The message answer structure.
- */
-#define SOCKET_SET_READ_DATA_LENGTH(answer, value) \
-	{ipcarg_t argument = (ipcarg_t) (value); IPC_SET_ARG1(answer, argument);}
-
-/** Returns the read data length message parameter.
- *  @param[in] call The message call structure.
- */
-#define SOCKET_GET_READ_DATA_LENGTH(call) \
-	({int data_length = (int) IPC_GET_ARG1(call); data_length;})
-
-/** Returns the backlog message parameter.
- *  @param[in] call The message call structure.
- */
-#define SOCKET_GET_BACKLOG(call) \
-	({int backlog = (int) IPC_GET_ARG2(call); backlog;})
-
-/** Returns the option level message parameter.
- *  @param[in] call The message call structure.
- */
-#define SOCKET_GET_OPT_LEVEL(call) \
-	({int opt_level = (int) IPC_GET_ARG2(call); opt_level;})
-
-/** Returns the data fragment size message parameter.
- *  @param[in] call The message call structure.
- */
-#define SOCKET_GET_DATA_FRAGMENT_SIZE(call) \
-	({size_t size = (size_t) IPC_GET_ARG2(call); size;})
-
-/** Sets the data fragment size in the message answer.
- *  @param[out] answer The message answer structure.
- */
-#define SOCKET_SET_DATA_FRAGMENT_SIZE(answer, value) \
-	{ipcarg_t argument = (ipcarg_t) (value); IPC_SET_ARG2(answer, argument);}
-
-/** Sets the address length in the message answer.
- *  @param[out] answer The message answer structure.
- */
-#define SOCKET_SET_ADDRESS_LENGTH(answer, value) \
-	{ipcarg_t argument = (ipcarg_t) (value); IPC_SET_ARG3(answer, argument);}
-
-/** Returns the address length message parameter.
- *  @param[in] call The message call structure.
- */
-#define SOCKET_GET_ADDRESS_LENGTH(call) \
-	({socklen_t address_length = (socklen_t) IPC_GET_ARG3(call); address_length;})
-
-/** Sets the header size in the message answer.
- *  @param[out] answer The message answer structure.
- */
-#define SOCKET_SET_HEADER_SIZE(answer, value) \
-	\
-	{ipcarg_t argument = (ipcarg_t) (value); IPC_SET_ARG3(answer, argument);}
-
-/** Returns the header size message parameter.
- *  @param[in] call The message call structure.
- */
-#define SOCKET_GET_HEADER_SIZE(call) \
-	({size_t size = (size_t) IPC_GET_ARG3(call); size;})
-
-/** Returns the flags message parameter.
- *  @param[in] call The message call structure.
- */
-#define SOCKET_GET_FLAGS(call) \
-	({int flags = (int) IPC_GET_ARG4(call); flags;})
-
-/** Returns the option name message parameter.
- *  @param[in] call The message call structure.
- */
-#define SOCKET_GET_OPT_NAME(call) \
-	({int opt_name = (int) IPC_GET_ARG4(call); opt_name;})
-
-/** Returns the data fragments message parameter.
- *  @param[in] call The message call structure.
- */
-#define SOCKET_GET_DATA_FRAGMENTS(call) \
-	({int fragments = (int) IPC_GET_ARG5(call); fragments;})
-
-/** Returns the new socket identifier message parameter.
- *  @param[in] call The message call structure.
- */
-#define SOCKET_GET_NEW_SOCKET_ID(call) \
-	({int socket_id = (int) IPC_GET_ARG5(call); socket_id;})
-
-/*@}*/
-
-#endif
-
-/** @}
- */
Index: pace/lib/socket/include/socket_parse.h
===================================================================
--- uspace/lib/socket/include/socket_parse.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ 	(revision )
@@ -1,42 +1,0 @@
-/*
- * Copyright (c) 2009 Lukas Mejdrech
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (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 socket
- * @{
- */
-
-/** @file
- * Command-line argument parsing functions related to networking.
- */
-
-extern int socket_parse_address_family(const char *, int *);
-extern int socket_parse_protocol_family(const char *, int *);
-extern int socket_parse_socket_type(const char *, int *);
-
-/** @}
- */
Index: pace/lib/socket/include/tcp_codes.h
===================================================================
--- uspace/lib/socket/include/tcp_codes.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ 	(revision )
@@ -1,88 +1,0 @@
-/*
- * Copyright (c) 2009 Lukas Mejdrech
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (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 options definitions.
- */
-
-#ifndef __NET_TCP_CODES_H__
-#define __NET_TCP_CODES_H__
-
-/** End of list TCP option.
- */
-#define TCPOPT_END_OF_LIST				0x0
-
-/** No operation TCP option.
- */
-#define TCPOPT_NO_OPERATION				0x1
-
-/** Maximum segment size TCP option.
- */
-#define TCPOPT_MAX_SEGMENT_SIZE			0x2
-
-/** Maximum segment size TCP option length.
- */
-#define TCPOPT_MAX_SEGMENT_SIZE_LENGTH	4
-
-/** Window scale TCP option.
- */
-#define TCPOPT_WINDOW_SCALE				0x3
-
-/** Window scale TCP option length.
- */
-#define TCPOPT_WINDOW_SCALE_LENGTH		3
-
-/** Selective acknowledgement permitted TCP option.
- */
-#define TCPOPT_SACK_PERMITTED			0x4
-
-/** Selective acknowledgement permitted TCP option length.
- */
-#define TCPOPT_SACK_PERMITTED_LENGTH	2
-
-/** Selective acknowledgement TCP option.
- *  Has variable length.
- */
-#define TCPOPT_SACK						0x5
-
-/** Timestamp TCP option.
- */
-#define TCPOPT_TIMESTAMP				0x8
-
-/** Timestamp TCP option length.
- */
-#define TCPOPT_TIMESTAMP_LENGTH			10
-
-#endif
-
-/** @}
- */
Index: pace/lib/socket/packet/packet.c
===================================================================
--- uspace/lib/socket/packet/packet.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ 	(revision )
@@ -1,330 +1,0 @@
-/*
- * Copyright (c) 2009 Lukas Mejdrech
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (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 packet
- *  @{
- */
-
-/** @file
- *  Packet map and queue implementation.
- *  This file has to be compiled with both the packet server and the client.
- */
-
-#include <errno.h>
-#include <malloc.h>
-#include <mem.h>
-#include <fibril_synch.h>
-#include <unistd.h>
-
-#include <sys/mman.h>
-
-#include <net_err.h>
-#include <adt/generic_field.h>
-#include <packet/packet.h>
-#include <packet/packet_header.h>
-
-/** Packet map page size.
- */
-#define PACKET_MAP_SIZE	100
-
-/** Returns the packet map page index.
- *  @param[in] packet_id The packet identifier.
- */
-#define PACKET_MAP_PAGE(packet_id)	(((packet_id) - 1) / PACKET_MAP_SIZE)
-
-/** Returns the packet index in the corresponding packet map page.
- *  @param[in] packet_id The packet identifier.
- */
-#define PACKET_MAP_INDEX(packet_id)	(((packet_id) - 1) % PACKET_MAP_SIZE)
-
-/** Type definition of the packet map page.
- */
-typedef packet_t packet_map_t[PACKET_MAP_SIZE];
-/** Type definition of the packet map page pointer.
- */
-typedef packet_map_t * packet_map_ref;
-
-/** Packet map.
- *  Maps packet identifiers to the packet references.
- *  @see generic_field.h
- */
-GENERIC_FIELD_DECLARE(gpm, packet_map_t);
-
-/** Releases the packet.
- *  @param[in] packet The packet to be released.
- *  @returns EOK on success.
- *  @returns EINVAL if the packet is not valid.
- */
-int packet_destroy(packet_t packet);
-
-/** Packet map global data.
- */
-static struct{
-	/** Safety lock.
-	 */
-	fibril_rwlock_t lock;
-	/** Packet map.
-	 */
-	gpm_t packet_map;
-} pm_globals;
-
-GENERIC_FIELD_IMPLEMENT(gpm, packet_map_t);
-
-int packet_destroy(packet_t packet){
-	if(! packet_is_valid(packet)){
-		return EINVAL;
-	}
-	return munmap(packet, packet->length);
-}
-
-int pm_init(void){
-	ERROR_DECLARE;
-
-	fibril_rwlock_initialize(&pm_globals.lock);
-	fibril_rwlock_write_lock(&pm_globals.lock);
-	ERROR_PROPAGATE(gpm_initialize(&pm_globals.packet_map));
-	fibril_rwlock_write_unlock(&pm_globals.lock);
-	return EOK;
-}
-
-packet_t pm_find(packet_id_t packet_id){
-	packet_map_ref map;
-	packet_t packet;
-
-	if(! packet_id){
-		return NULL;
-	}
-	fibril_rwlock_read_lock(&pm_globals.lock);
-	if(packet_id > PACKET_MAP_SIZE * gpm_count(&pm_globals.packet_map)){
-		fibril_rwlock_read_unlock(&pm_globals.lock);
-		return NULL;
-	}
-	map = gpm_get_index(&pm_globals.packet_map, PACKET_MAP_PAGE(packet_id));
-	if(! map){
-		fibril_rwlock_read_unlock(&pm_globals.lock);
-		return NULL;
-	}
-	packet = (*map)[PACKET_MAP_INDEX(packet_id)];
-	fibril_rwlock_read_unlock(&pm_globals.lock);
-	return packet;
-}
-
-int pm_add(packet_t packet){
-	ERROR_DECLARE;
-
-	packet_map_ref map;
-
-	if(! packet_is_valid(packet)){
-		return EINVAL;
-	}
-	fibril_rwlock_write_lock(&pm_globals.lock);
-	if(PACKET_MAP_PAGE(packet->packet_id) < gpm_count(&pm_globals.packet_map)){
-		map = gpm_get_index(&pm_globals.packet_map, PACKET_MAP_PAGE(packet->packet_id));
-	}else{
-		do{
-			map = (packet_map_ref) malloc(sizeof(packet_map_t));
-			if(! map){
-				fibril_rwlock_write_unlock(&pm_globals.lock);
-				return ENOMEM;
-			}
-			bzero(map, sizeof(packet_map_t));
-			if((ERROR_CODE = gpm_add(&pm_globals.packet_map, map)) < 0){
-				fibril_rwlock_write_unlock(&pm_globals.lock);
-				free(map);
-				return ERROR_CODE;
-			}
-		}while(PACKET_MAP_PAGE(packet->packet_id) >= gpm_count(&pm_globals.packet_map));
-	}
-	(*map)[PACKET_MAP_INDEX(packet->packet_id)] = packet;
-	fibril_rwlock_write_unlock(&pm_globals.lock);
-	return EOK;
-}
-
-void pm_destroy(void){
-	int count;
-	int index;
-	packet_map_ref map;
-	packet_t packet;
-
-	fibril_rwlock_write_lock(&pm_globals.lock);
-	count = gpm_count(&pm_globals.packet_map);
-	while(count > 0){
-		map = gpm_get_index(&pm_globals.packet_map, count - 1);
-		for(index = PACKET_MAP_SIZE - 1; index >= 0; -- index){
-			packet = (*map)[index];
-			if(packet_is_valid(packet)){
-				munmap(packet, packet->length);
-			}
-		}
-	}
-	gpm_destroy(&pm_globals.packet_map);
-	// leave locked
-}
-
-int pq_add(packet_t * first, packet_t packet, size_t order, size_t metric){
-	packet_t item;
-
-	if((! first) || (! packet_is_valid(packet))){
-		return EINVAL;
-	}
-	pq_set_order(packet, order, metric);
-	if(packet_is_valid(*first)){
-		item = * first;
-		do{
-			if(item->order < order){
-				if(item->next){
-					item = pm_find(item->next);
-				}else{
-					item->next = packet->packet_id;
-					packet->previous = item->packet_id;
-					return EOK;
-				}
-			}else{
-				packet->previous = item->previous;
-				packet->next = item->packet_id;
-				item->previous = packet->packet_id;
-				item = pm_find(packet->previous);
-				if(item){
-					item->next = packet->packet_id;
-				}else{
-					*first = packet;
-				}
-				return EOK;
-			}
-		}while(packet_is_valid(item));
-	}
-	*first = packet;
-	return EOK;
-}
-
-packet_t pq_find(packet_t packet, size_t order){
-	packet_t item;
-
-	if(! packet_is_valid(packet)){
-		return NULL;
-	}
-	item = packet;
-	do{
-		if(item->order == order){
-			return item;
-		}
-		item = pm_find(item->next);
-	}while(item && (item != packet) && packet_is_valid(item));
-	return NULL;
-}
-
-int pq_insert_after(packet_t packet, packet_t new_packet){
-	packet_t item;
-
-	if(!(packet_is_valid(packet) && packet_is_valid(new_packet))){
-		return EINVAL;
-	}
-	new_packet->previous = packet->packet_id;
-	new_packet->next = packet->next;
-	item = pm_find(packet->next);
-	if(item){
-		item->previous = new_packet->packet_id;
-	}
-	packet->next = new_packet->packet_id;
-	return EOK;
-}
-
-packet_t pq_detach(packet_t packet){
-	packet_t next;
-	packet_t previous;
-
-	if(! packet_is_valid(packet)){
-		return NULL;
-	}
-	next = pm_find(packet->next);
-	if(next){
-		next->previous = packet->previous;
-		previous = pm_find(next->previous);
-		if(previous){
-			previous->next = next->packet_id;
-		}
-	}
-	packet->previous = 0;
-	packet->next = 0;
-	return next;
-}
-
-int pq_set_order(packet_t packet, size_t order, size_t metric){
-	if(! packet_is_valid(packet)){
-		return EINVAL;
-	}
-	packet->order = order;
-	packet->metric = metric;
-	return EOK;
-}
-
-int pq_get_order(packet_t packet, size_t * order, size_t * metric){
-	if(! packet_is_valid(packet)){
-		return EINVAL;
-	}
-	if(order){
-		*order = packet->order;
-	}
-	if(metric){
-		*metric = packet->metric;
-	}
-	return EOK;
-}
-
-void pq_destroy(packet_t first, void (*packet_release)(packet_t packet)){
-	packet_t actual;
-	packet_t next;
-
-	actual = first;
-	while(packet_is_valid(actual)){
-		next = pm_find(actual->next);
-		actual->next = 0;
-		actual->previous = 0;
-		if(packet_release){
-			packet_release(actual);
-		}
-		actual = next;
-	}
-}
-
-packet_t pq_next(packet_t packet){
-	if(! packet_is_valid(packet)){
-		return NULL;
-	}
-	return pm_find(packet->next);
-}
-
-packet_t pq_previous(packet_t packet){
-	if(! packet_is_valid(packet)){
-		return NULL;
-	}
-	return pm_find(packet->previous);
-}
-
-/** @}
- */
Index: pace/lib/socket/packet/packet_client.c
===================================================================
--- uspace/lib/socket/packet/packet_client.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ 	(revision )
@@ -1,186 +1,0 @@
-/*
- * Copyright (c) 2009 Lukas Mejdrech
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (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 packet
- *  @{
- */
-
-/** @file
- *  Packet client implementation.
- */
-
-#include <errno.h>
-#include <mem.h>
-#include <unistd.h>
-
-#include <sys/mman.h>
-
-#include <net_messages.h>
-#include <packet/packet.h>
-#include <packet/packet_header.h>
-#include <packet/packet_client.h>
-
-int packet_copy_data(packet_t packet, const void * data, size_t length){
-	if(! packet_is_valid(packet)){
-		return EINVAL;
-	}
-	if(packet->data_start + length >= packet->length){
-		return ENOMEM;
-	}
-	memcpy((void *) packet + packet->data_start, data, length);
-	if(packet->data_start + length > packet->data_end){
-		packet->data_end = packet->data_start + length;
-	}
-	return EOK;
-}
-
-void * packet_prefix(packet_t packet, size_t length){
-	if((! packet_is_valid(packet)) || (packet->data_start - sizeof(struct packet) - 2 * (packet->dest_addr - packet->src_addr) < length)){
-		return NULL;
-	}
-	packet->data_start -= length;
-	return (void *) packet + packet->data_start;
-}
-
-void * packet_suffix(packet_t packet, size_t length){
-	if((! packet_is_valid(packet)) || (packet->data_end + length >= packet->length)){
-		return NULL;
-	}
-	packet->data_end += length;
-	return (void *) packet + packet->data_end - length;
-}
-
-int packet_trim(packet_t packet, size_t prefix, size_t suffix){
-	if(! packet_is_valid(packet)){
-		return EINVAL;
-	}
-	if(prefix + suffix > PACKET_DATA_LENGTH(packet)){
-		return ENOMEM;
-	}
-	packet->data_start += prefix;
-	packet->data_end -= suffix;
-	return EOK;
-}
-
-packet_id_t packet_get_id(const packet_t packet){
-	return packet_is_valid(packet) ? packet->packet_id : 0;
-}
-
-int packet_get_addr(const packet_t packet, uint8_t ** src, uint8_t ** dest){
-	if(! packet_is_valid(packet)){
-		return EINVAL;
-	}
-	if(! packet->addr_len){
-		return 0;
-	}
-	if(src){
-		*src = (void *) packet + packet->src_addr;
-	}
-	if(dest){
-		*dest = (void *) packet + packet->dest_addr;
-	}
-	return packet->addr_len;
-}
-
-size_t packet_get_data_length(const packet_t packet){
-	if(! packet_is_valid(packet)){
-		return 0;
-	}
-	return PACKET_DATA_LENGTH(packet);
-}
-
-void * packet_get_data(const packet_t packet){
-	if(! packet_is_valid(packet)){
-		return NULL;
-	}
-	return (void *) packet + packet->data_start;
-}
-
-int packet_set_addr(packet_t packet, const uint8_t * src, const uint8_t * dest, size_t addr_len){
-	size_t padding;
-	size_t allocated;
-
-	if(! packet_is_valid(packet)){
-		return EINVAL;
-	}
-	allocated = PACKET_MAX_ADDRESS_LENGTH(packet);
-	if(allocated < addr_len){
-		return ENOMEM;
-	}
-	padding = allocated - addr_len;
-	packet->addr_len = addr_len;
-	if(src){
-		memcpy((void *) packet + packet->src_addr, src, addr_len);
-		if(padding){
-			bzero((void *) packet + packet->src_addr + addr_len, padding);
-		}
-	}else{
-		bzero((void *) packet + packet->src_addr, allocated);
-	}
-	if(dest){
-		memcpy((void *) packet + packet->dest_addr, dest, addr_len);
-		if(padding){
-			bzero((void *) packet + packet->dest_addr + addr_len, padding);
-		}
-	}else{
-		bzero((void *) packet + packet->dest_addr, allocated);
-	}
-	return EOK;
-}
-
-packet_t packet_get_copy(int phone, packet_t packet){
-	packet_t copy;
-	uint8_t * src = NULL;
-	uint8_t * dest = NULL;
-	size_t addrlen;
-
-	if(! packet_is_valid(packet)){
-		return NULL;
-	}
-	// get a new packet
-	copy = packet_get_4_local(phone, PACKET_DATA_LENGTH(packet), PACKET_MAX_ADDRESS_LENGTH(packet), packet->max_prefix, PACKET_MIN_SUFFIX(packet));
-	if(! copy){
-		return NULL;
-	}
-	// get addresses
-	addrlen = packet_get_addr(packet, &src, &dest);
-	// copy data
-	if((packet_copy_data(copy, packet_get_data(packet), PACKET_DATA_LENGTH(packet)) == EOK)
-	// copy addresses if present
-		&& ((addrlen <= 0) || (packet_set_addr(copy, src, dest, addrlen) == EOK))){
-		copy->order = packet->order;
-		copy->metric = packet->metric;
-		return copy;
-	}else{
-		pq_release_local(phone, copy->packet_id);
-		return NULL;
-	}
-}
-
-/** @}
- */
Index: pace/lib/socket/packet/packet_server.c
===================================================================
--- uspace/lib/socket/packet/packet_server.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ 	(revision )
@@ -1,342 +1,0 @@
-/*
- * Copyright (c) 2009 Lukas Mejdrech
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (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 packet
- *  @{
- */
-
-/** @file
- *  Packet server implementation.
- */
-
-#include <align.h>
-#include <assert.h>
-#include <async.h>
-#include <errno.h>
-#include <fibril_synch.h>
-#include <unistd.h>
-
-#include <ipc/ipc.h>
-#include <sys/mman.h>
-
-#include <net_err.h>
-#include <net_messages.h>
-#include <packet/packet.h>
-#include <packet/packet_client.h>
-#include <packet/packet_header.h>
-#include <packet/packet_messages.h>
-#include <packet/packet_server.h>
-
-#define FREE_QUEUES_COUNT	7
-
-/** The default address length reserved for new packets.
- */
-#define DEFAULT_ADDR_LEN	32
-
-/** The default prefix reserved for new packets.
- */
-#define DEFAULT_PREFIX		64
-
-/** The default suffix reserved for new packets.
- */
-#define DEFAULT_SUFFIX		64
-
-/** Packet server global data.
- */
-static struct{
-	/** Safety lock.
-	 */
-	fibril_mutex_t lock;
-	/** Free packet queues.
-	 */
-	packet_t free[FREE_QUEUES_COUNT];
-	/** Packet length upper bounds of the free packet queues.
-	 *  The maximal lengths of packets in each queue in the ascending order.
-	 *  The last queue is not limited.
-	 */
-	size_t sizes[FREE_QUEUES_COUNT];
-	/** Total packets allocated.
-	 */
-	unsigned int count;
-} ps_globals = {
-	.lock = {
-		.counter = 1,
-		.waiters = {
-			.prev = &ps_globals.lock.waiters,
-			.next = &ps_globals.lock.waiters,
-		}
-	},
-	.free = {NULL, NULL, NULL, NULL, NULL, NULL, NULL},
-	.sizes = {PAGE_SIZE, PAGE_SIZE * 2, PAGE_SIZE * 4, PAGE_SIZE * 8, PAGE_SIZE * 16, PAGE_SIZE * 32, PAGE_SIZE * 64},
-	.count = 0
-};
-
-int packet_translate_local(int phone, packet_ref packet, packet_id_t packet_id)
-{
-	if (!packet)
-		return EINVAL;
-	
-	*packet = pm_find(packet_id);
-	return (*packet) ? EOK : ENOENT;
-}
-
-/** Clears and initializes the packet according to the given dimensions.
- *  @param[in] packet The packet to be initialized.
- *  @param[in] addr_len The source and destination addresses maximal length in bytes.
- *  @param[in] max_prefix The maximal prefix length in bytes.
- *  @param[in] max_content The maximal content length in bytes.
- *  @param[in] max_suffix The maximal suffix length in bytes.
- */
-static void packet_init(packet_t packet, size_t addr_len, size_t max_prefix, size_t max_content, size_t max_suffix){
-	// clear the packet content
-	bzero(((void *) packet) + sizeof(struct packet), packet->length - sizeof(struct packet));
-	// clear the packet header
-	packet->order = 0;
-	packet->metric = 0;
-	packet->previous = 0;
-	packet->next = 0;
-	packet->addr_len = 0;
-	packet->src_addr = sizeof(struct packet);
-	packet->dest_addr = packet->src_addr + addr_len;
-	packet->max_prefix = max_prefix;
-	packet->max_content = max_content;
-	packet->data_start = packet->dest_addr + addr_len + packet->max_prefix;
-	packet->data_end = packet->data_start;
-}
-
-/** Creates a&nbsp;new packet of dimensions at least as given.
- *  Should be used only when the global data are locked.
- *  @param[in] length The total length of the packet, including the header, the addresses and the data of the packet.
- *  @param[in] addr_len The source and destination addresses maximal length in bytes.
- *  @param[in] max_prefix The maximal prefix length in bytes.
- *  @param[in] max_content The maximal content length in bytes.
- *  @param[in] max_suffix The maximal suffix length in bytes.
- *  @returns The packet of dimensions at least as given.
- *  @returns NULL if there is not enough memory left.
- */
-static packet_t packet_create(size_t length, size_t addr_len, size_t max_prefix, size_t max_content, size_t max_suffix){
-	ERROR_DECLARE;
-
-	packet_t packet;
-
-	// already locked
-	packet = (packet_t) mmap(NULL, length, PROTO_READ | PROTO_WRITE, MAP_SHARED | MAP_ANONYMOUS, 0, 0);
-	if(packet == MAP_FAILED){
-		return NULL;
-	}
-	++ ps_globals.count;
-	packet->packet_id = ps_globals.count;
-	packet->length = length;
-	packet_init(packet, addr_len, max_prefix, max_content, max_suffix);
-	packet->magic_value = PACKET_MAGIC_VALUE;
-	if(ERROR_OCCURRED(pm_add(packet))){
-		munmap(packet, packet->length);
-		return NULL;
-	}
-	return packet;
-}
-
-/** Return the packet of dimensions at least as given.
- *
- * Try to reuse free packets first.
- * Create a new packet aligned to the memory page size if none available.
- * Lock the global data during its processing.
- *
- * @param[in] addr_len    The source and destination addresses
- *                        maximal length in bytes.
- * @param[in] max_prefix  The maximal prefix length in bytes.
- * @param[in] max_content The maximal content length in bytes.
- * @param[in] max_suffix  The maximal suffix length in bytes.
- *
- * @return The packet of dimensions at least as given.
- * @return NULL if there is not enough memory left.
- *
- */
-static packet_t packet_get_local(size_t addr_len, size_t max_prefix,
-    size_t max_content, size_t max_suffix)
-{
-	size_t length = ALIGN_UP(sizeof(struct packet) + 2 * addr_len + max_prefix
-	    + max_content + max_suffix, PAGE_SIZE);
-	
-	fibril_mutex_lock(&ps_globals.lock);
-	
-	packet_t packet;
-	unsigned int index;
-	
-	for (index = 0; index < FREE_QUEUES_COUNT - 1; index++) {
-		if (length <= ps_globals.sizes[index]) {
-			packet = ps_globals.free[index];
-			
-			while (packet_is_valid(packet) && (packet->length < length))
-				packet = pm_find(packet->next);
-			
-			if (packet_is_valid(packet)) {
-				if (packet == ps_globals.free[index])
-					ps_globals.free[index] = pq_detach(packet);
-				else
-					pq_detach(packet);
-				
-				packet_init(packet, addr_len, max_prefix, max_content,
-				    max_suffix);
-				fibril_mutex_unlock(&ps_globals.lock);
-				
-				return packet;
-			}
-		}
-	}
-	
-	packet = packet_create(length, addr_len, max_prefix, max_content,
-	    max_suffix);
-	
-	fibril_mutex_unlock(&ps_globals.lock);
-	
-	return packet;
-}
-
-packet_t packet_get_4_local(int phone, size_t max_content, size_t addr_len,
-    size_t max_prefix, size_t max_suffix)
-{
-	return packet_get_local(addr_len, max_prefix, max_content, max_suffix);
-}
-
-packet_t packet_get_1_local(int phone, size_t content)
-{
-	return packet_get_local(DEFAULT_ADDR_LEN, DEFAULT_PREFIX, content,
-	    DEFAULT_SUFFIX);
-}
-
-/** Release the packet and returns it to the appropriate free packet queue.
- *
- *  Should be used only when the global data are locked.
- *
- *  @param[in] packet The packet to be released.
- *
- */
-static void packet_release(packet_t packet){
-	int index;
-	int result;
-
-	// remove debug dump
-//	printf("packet %d released\n", packet->packet_id);
-	for(index = 0; (index < FREE_QUEUES_COUNT - 1) && (packet->length > ps_globals.sizes[index]); ++ index);
-	result = pq_add(&ps_globals.free[index], packet, packet->length, packet->length);
-	assert(result == EOK);
-}
-
-/** Releases the packet queue.
- *  @param[in] packet_id The first packet identifier.
- *  @returns EOK on success.
- *  @returns ENOENT if there is no such packet.
- */
-static int packet_release_wrapper(packet_id_t packet_id){
-	packet_t packet;
-
-	packet = pm_find(packet_id);
-	if(! packet_is_valid(packet)){
-		return ENOENT;
-	}
-	fibril_mutex_lock(&ps_globals.lock);
-	pq_destroy(packet, packet_release);
-	fibril_mutex_unlock(&ps_globals.lock);
-	return EOK;
-}
-
-void pq_release_local(int phone, packet_id_t packet_id)
-{
-	(void) packet_release_wrapper(packet_id);
-}
-
-/** Shares the packet memory block.
- *  @param[in] packet The packet to be shared.
- *  @returns EOK on success.
- *  @returns EINVAL if the packet is not valid.
- *  @returns EINVAL if the calling module does not accept the memory.
- *  @returns ENOMEM if the desired and actual sizes differ.
- *  @returns Other error codes as defined for the async_share_in_finalize() function.
- */
-static int packet_reply(const packet_t packet){
-	ipc_callid_t callid;
-	size_t size;
-
-	if(! packet_is_valid(packet)){
-		return EINVAL;
-	}
-	if(async_share_in_receive(&callid, &size) <= 0) return EINVAL;
-	if(size != packet->length){
-		return ENOMEM;
-	}
-	return async_share_in_finalize(callid, packet, PROTO_READ | PROTO_WRITE);
-}
-
-int packet_server_message(ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count){
-	packet_t packet;
-
-	*answer_count = 0;
-	switch(IPC_GET_METHOD(*call)){
-		case IPC_M_PHONE_HUNGUP:
-			return EOK;
-		case NET_PACKET_CREATE_1:
-			packet = packet_get_local(DEFAULT_ADDR_LEN, DEFAULT_PREFIX, IPC_GET_CONTENT(call), DEFAULT_SUFFIX);
-			if(! packet){
-				return ENOMEM;
-			}
-			*answer_count = 2;
-			IPC_SET_ARG1(*answer, (ipcarg_t) packet->packet_id);
-			IPC_SET_ARG2(*answer, (ipcarg_t) packet->length);
-			return EOK;
-		case NET_PACKET_CREATE_4:
-			packet = packet_get_local(((DEFAULT_ADDR_LEN < IPC_GET_ADDR_LEN(call)) ? IPC_GET_ADDR_LEN(call) : DEFAULT_ADDR_LEN), DEFAULT_PREFIX + IPC_GET_PREFIX(call), IPC_GET_CONTENT(call), DEFAULT_SUFFIX + IPC_GET_SUFFIX(call));
-			if(! packet){
-				return ENOMEM;
-			}
-			*answer_count = 2;
-			IPC_SET_ARG1(*answer, (ipcarg_t) packet->packet_id);
-			IPC_SET_ARG2(*answer, (ipcarg_t) packet->length);
-			return EOK;
-		case NET_PACKET_GET:
-			packet = pm_find(IPC_GET_ID(call));
-			if(! packet_is_valid(packet)){
-				return ENOENT;
-			}
-			return packet_reply(packet);
-		case NET_PACKET_GET_SIZE:
-			packet = pm_find(IPC_GET_ID(call));
-			if(! packet_is_valid(packet)){
-				return ENOENT;
-			}
-			IPC_SET_ARG1(*answer, (ipcarg_t) packet->length);
-			*answer_count = 1;
-			return EOK;
-		case NET_PACKET_RELEASE:
-			return packet_release_wrapper(IPC_GET_ID(call));
-	}
-	return ENOTSUP;
-}
-
-/** @}
- */
Index: uspace/lib/softfloat/generic/conversion.c
===================================================================
--- uspace/lib/softfloat/generic/conversion.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/lib/softfloat/generic/conversion.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -27,5 +27,5 @@
  */
 
-/** @addtogroup softfloat	
+/** @addtogroup softfloat
  * @{
  */
@@ -45,7 +45,7 @@
 	result.parts.sign = a.parts.sign;
 	result.parts.fraction = a.parts.fraction;
-	result.parts.fraction <<= (FLOAT64_FRACTION_SIZE - FLOAT32_FRACTION_SIZE );
-	
-	if ((isFloat32Infinity(a))||(isFloat32NaN(a))) {
+	result.parts.fraction <<= (FLOAT64_FRACTION_SIZE - FLOAT32_FRACTION_SIZE);
+	
+	if ((isFloat32Infinity(a)) || (isFloat32NaN(a))) {
 		result.parts.exp = 0x7FF;
 		/* TODO; check if its correct for SigNaNs*/
@@ -53,5 +53,5 @@
 	};
 	
-	result.parts.exp = a.parts.exp + ( (int)FLOAT64_BIAS - FLOAT32_BIAS );
+	result.parts.exp = a.parts.exp + ((int) FLOAT64_BIAS - FLOAT32_BIAS);
 	if (a.parts.exp == 0) {
 		/* normalize denormalized numbers */
@@ -181,16 +181,15 @@
 uint32_t float32_to_uint32(float32 a)
 {
-	if (isFloat32NaN(a)) {
-		return MAX_UINT32;
-	}
-	
-	if (isFloat32Infinity(a) || (a.parts.exp >= (32 + FLOAT32_BIAS)))  {
-		if (a.parts.sign) {
-			return MIN_UINT32;
-		}
-		return MAX_UINT32;
-	}
-	
-	return _float32_to_uint32_helper(a);	
+	if (isFloat32NaN(a))
+		return UINT32_MAX;
+	
+	if (isFloat32Infinity(a) || (a.parts.exp >= (32 + FLOAT32_BIAS))) {
+		if (a.parts.sign)
+			return UINT32_MIN;
+		
+		return UINT32_MAX;
+	}
+	
+	return _float32_to_uint32_helper(a);
 }
 
@@ -201,16 +200,16 @@
 int32_t float32_to_int32(float32 a)
 {
-	if (isFloat32NaN(a)) {
-		return MAX_INT32;
-	}
-	
-	if (isFloat32Infinity(a) || (a.parts.exp >= (32 + FLOAT32_BIAS)))  {
-		if (a.parts.sign) {
-			return MIN_INT32;
-		}
-		return MAX_INT32;
-	}
+	if (isFloat32NaN(a))
+		return INT32_MAX;
+	
+	if (isFloat32Infinity(a) || (a.parts.exp >= (32 + FLOAT32_BIAS))) {
+		if (a.parts.sign)
+			return INT32_MIN;
+		
+		return INT32_MAX;
+	}
+	
 	return _float32_to_uint32_helper(a);
-}	
+}
 
 
@@ -249,16 +248,16 @@
 uint64_t float64_to_uint64(float64 a)
 {
-	if (isFloat64NaN(a)) {
-		return MAX_UINT64;
-	}
-	
-	if (isFloat64Infinity(a) || (a.parts.exp >= (64 + FLOAT64_BIAS)))  {
-		if (a.parts.sign) {
-			return MIN_UINT64;
-		}
-		return MAX_UINT64;
-	}
-	
-	return _float64_to_uint64_helper(a);	
+	if (isFloat64NaN(a))
+		return UINT64_MAX;
+	
+	
+	if (isFloat64Infinity(a) || (a.parts.exp >= (64 + FLOAT64_BIAS))) {
+		if (a.parts.sign)
+			return UINT64_MIN;
+		
+		return UINT64_MAX;
+	}
+	
+	return _float64_to_uint64_helper(a);
 }
 
@@ -269,16 +268,17 @@
 int64_t float64_to_int64(float64 a)
 {
-	if (isFloat64NaN(a)) {
-		return MAX_INT64;
-	}
-	
-	if (isFloat64Infinity(a) || (a.parts.exp >= (64 + FLOAT64_BIAS)))  {
-		if (a.parts.sign) {
-			return MIN_INT64;
-		}
-		return MAX_INT64;
-	}
+	if (isFloat64NaN(a))
+		return INT64_MAX;
+	
+	
+	if (isFloat64Infinity(a) || (a.parts.exp >= (64 + FLOAT64_BIAS))) {
+		if (a.parts.sign)
+			return INT64_MIN;
+		
+		return INT64_MAX;
+	}
+	
 	return _float64_to_uint64_helper(a);
-}	
+}
 
 
@@ -320,16 +320,16 @@
 uint64_t float32_to_uint64(float32 a)
 {
-	if (isFloat32NaN(a)) {
-		return MAX_UINT64;
-	}
-	
-	if (isFloat32Infinity(a) || (a.parts.exp >= (64 + FLOAT32_BIAS)))  {
-		if (a.parts.sign) {
-			return MIN_UINT64;
-		}
-		return MAX_UINT64;
-	}
-	
-	return _float32_to_uint64_helper(a);	
+	if (isFloat32NaN(a))
+		return UINT64_MAX;
+	
+	
+	if (isFloat32Infinity(a) || (a.parts.exp >= (64 + FLOAT32_BIAS))) {
+		if (a.parts.sign)
+			return UINT64_MIN;
+		
+		return UINT64_MAX;
+	}
+	
+	return _float32_to_uint64_helper(a);
 }
 
@@ -340,16 +340,16 @@
 int64_t float32_to_int64(float32 a)
 {
-	if (isFloat32NaN(a)) {
-		return MAX_INT64;
-	}
-	
-	if (isFloat32Infinity(a) || (a.parts.exp >= (64 + FLOAT32_BIAS)))  {
-		if (a.parts.sign) {
-			return (MIN_INT64);
-		}
-		return MAX_INT64;
-	}
+	if (isFloat32NaN(a))
+		return INT64_MAX;
+	
+	if (isFloat32Infinity(a) || (a.parts.exp >= (64 + FLOAT32_BIAS))) {
+		if (a.parts.sign)
+			return INT64_MIN;
+		
+		return INT64_MAX;
+	}
+	
 	return _float32_to_uint64_helper(a);
-}	
+}
 
 
@@ -360,16 +360,16 @@
 uint32_t float64_to_uint32(float64 a)
 {
-	if (isFloat64NaN(a)) {
-		return MAX_UINT32;
-	}
-	
-	if (isFloat64Infinity(a) || (a.parts.exp >= (32 + FLOAT64_BIAS)))  {
-		if (a.parts.sign) {
-			return MIN_UINT32;
-		}
-		return MAX_UINT32;
-	}
-	
-	return (uint32_t)_float64_to_uint64_helper(a);	
+	if (isFloat64NaN(a))
+		return UINT32_MAX;
+	
+	
+	if (isFloat64Infinity(a) || (a.parts.exp >= (32 + FLOAT64_BIAS))) {
+		if (a.parts.sign)
+			return UINT32_MIN;
+		
+		return UINT32_MAX;
+	}
+	
+	return (uint32_t) _float64_to_uint64_helper(a);
 }
 
@@ -380,16 +380,17 @@
 int32_t float64_to_int32(float64 a)
 {
-	if (isFloat64NaN(a)) {
-		return MAX_INT32;
-	}
-	
-	if (isFloat64Infinity(a) || (a.parts.exp >= (32 + FLOAT64_BIAS)))  {
-		if (a.parts.sign) {
-			return MIN_INT32;
-		}
-		return MAX_INT32;
-	}
-	return (int32_t)_float64_to_uint64_helper(a);
-}	
+	if (isFloat64NaN(a))
+		return INT32_MAX;
+	
+	
+	if (isFloat64Infinity(a) || (a.parts.exp >= (32 + FLOAT64_BIAS))) {
+		if (a.parts.sign)
+			return INT32_MIN;
+		
+		return INT32_MAX;
+	}
+	
+	return (int32_t) _float64_to_uint64_helper(a);
+}
 
 /** Convert unsigned integer to float32
Index: uspace/lib/softint/generic/multiplication.c
===================================================================
--- uspace/lib/softint/generic/multiplication.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/lib/softint/generic/multiplication.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -29,5 +29,5 @@
 /** @addtogroup softint
  * @{
- */ 
+ */
 /**
  * @file
@@ -36,34 +36,29 @@
 
 #include <multiplication.h>
-#include <stdint.h> 
+#include <stdint.h>
 
-/** Set 1 to return MAX_INT64 or MIN_INT64 on overflow */
+/** Set 1 to return INT64_MAX or INT64_MIN on overflow */
 #ifndef SOFTINT_CHECK_OF
-# define SOFTINT_CHECK_OF 0
+	#define SOFTINT_CHECK_OF  0
 #endif
 
-/**
- * Multiply two integers and return long long as result. 
+/** Multiply two integers and return long long as result.
+ *
  * This function is overflow safe.
- * @param a
- * @param b
- * @result
+ *
  */
 static unsigned long long mul(unsigned int a, unsigned int b) {
-	unsigned int a1, a2, b1, b2;
-	unsigned long long t1, t2, t3;	
-
-	a1 = a >> 16;
-	a2 = a & MAX_UINT16;
-	b1 = b >> 16;
-	b2 = b & MAX_UINT16;
-
-	t1 = a1 * b1;
-	t2 = a1*b2;
-	t2 += a2*b1;
-	t3 = a2*b2;
-
-	t3 = (((t1 << 16) + t2) << 16) + t3; 
-
+	unsigned int a1 = a >> 16;
+	unsigned int a2 = a & UINT16_MAX;
+	unsigned int b1 = b >> 16;
+	unsigned int b2 = b & UINT16_MAX;
+	
+	unsigned long long t1 = a1 * b1;
+	unsigned long long t2 = a1 * b2;
+	t2 += a2 * b1;
+	unsigned long long t3 = a2 * b2;
+	
+	t3 = (((t1 << 16) + t2) << 16) + t3;
+	
 	return t3;
 }
@@ -74,57 +69,54 @@
 long long __muldi3 (long long a, long long b)
 {
-	long long result;
-	unsigned long long t1,t2;
-	unsigned long long a1, a2, b1, b2;
 	char neg = 0;
-
+	
 	if (a < 0) {
 		neg = !neg;
 		a = -a;
 	}
-
+	
 	if (b < 0) {
 		neg = !neg;
 		b = -b;
 	}
-
-	a1 = a >> 32;
-	b1 = b >> 32;
-
-	a2 = a & (MAX_UINT32);
-	b2 = b & (MAX_UINT32);
-
+	
+	unsigned long long a1 = a >> 32;
+	unsigned long long b1 = b >> 32;
+	
+	unsigned long long a2 = a & (UINT32_MAX);
+	unsigned long long b2 = b & (UINT32_MAX);
+	
 	if (SOFTINT_CHECK_OF && (a1 != 0) && (b1 != 0)) {
-		// error, overflow
-		return (neg?MIN_INT64:MAX_INT64);
+		/* Error (overflow) */
+		return (neg ? INT64_MIN : INT64_MAX);
 	}
-
-	// (if OF checked) a1 or b1 is zero => result fits in 64 bits, no need to another overflow check
-	t1 = mul(a1,b2) + mul(b1,a2);	
-
-	if (SOFTINT_CHECK_OF && t1 > MAX_UINT32) {
-		// error, overflow
-		return (neg?MIN_INT64:MAX_INT64);
+	
+	/* (if OF checked) a1 or b1 is zero => result fits in 64 bits,
+	 * no need to another overflow check
+	 */
+	unsigned long long t1 = mul(a1, b2) + mul(b1, a2);
+	
+	if ((SOFTINT_CHECK_OF) && (t1 > UINT32_MAX)) {
+		/* Error (overflow) */
+		return (neg ? INT64_MIN : INT64_MAX);
 	}
-
+	
 	t1 = t1 << 32;
-	t2 = mul(a2,b2);
+	unsigned long long t2 = mul(a2, b2);
 	t2 += t1;
-
+	
 	/* t2 & (1ull << 63) - if this bit is set in unsigned long long,
 	 * result does not fit in signed one */
 	if (SOFTINT_CHECK_OF && ((t2 < t1) || (t2 & (1ull << 63)))) {
 		// error, overflow
-		return (neg?MIN_INT64:MAX_INT64);
+		return (neg ? INT64_MIN : INT64_MAX);
 	}
-
-	result = t2;
-
-	if (neg) {
+	
+	long long result = t2;
+	if (neg)
 		result = -result;
-	}
-
+	
 	return result;
-}	
+}
 
 /** @}
Index: pace/srv/bd/part/mbr_part/Makefile.build
===================================================================
--- uspace/srv/bd/part/mbr_part/Makefile.build	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ 	(revision )
@@ -1,63 +1,0 @@
-#
-# Copyright (c) 2005 Martin Decky
-# Copyright (c) 2007 Jakub Jermar
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions
-# are met:
-#
-# - Redistributions of source code must retain the above copyright
-#   notice, this list of conditions and the following disclaimer.
-# - Redistributions in binary form must reproduce the above copyright
-#   notice, this list of conditions and the following disclaimer in the
-#   documentation and/or other materials provided with the distribution.
-# - The name of the author may not be used to endorse or promote products
-#   derived from this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
-# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
-# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
-# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
-# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
-# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-#
-
-## Setup toolchain
-#
-
-include Makefile.common
-include $(LIBC_PREFIX)/Makefile.toolchain
-
-CFLAGS += -I$(LIBBLOCK_PREFIX)
-
-## Sources
-#
-
-SOURCES = \
-	mbr_part.c
-
-OBJECTS := $(addsuffix .o,$(basename $(SOURCES)))
-
-.PHONY: all
-
-all: $(OUTPUT) $(OUTPUT).disasm
-
--include $(DEPEND)
-
-$(OUTPUT).disasm: $(OUTPUT)
-	$(OBJDUMP) -d $< > $@
-
-$(OUTPUT): $(OBJECTS) $(LIBS)
-	$(LD) -T $(LIBC_PREFIX)/arch/$(UARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map
-
-%.o: %.c $(DEPEND)
-	$(CC) $(DEFS) $(CFLAGS) -c $< -o $@
-
-$(DEPEND):
-	makedepend -f - -- $(DEPEND_DEFS) $(CFLAGS) -- $(SOURCES) > $@ 2> /dev/null
-	-[ -f $(DEPEND_PREV) ] && diff -q $(DEPEND_PREV) $@ && mv -f $(DEPEND_PREV) $@
Index: pace/srv/bd/part/mbr_part/Makefile.common
===================================================================
--- uspace/srv/bd/part/mbr_part/Makefile.common	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ 	(revision )
@@ -1,40 +1,0 @@
-#
-# Copyright (c) 2005 Martin Decky
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions
-# are met:
-#
-# - Redistributions of source code must retain the above copyright
-#   notice, this list of conditions and the following disclaimer.
-# - Redistributions in binary form must reproduce the above copyright
-#   notice, this list of conditions and the following disclaimer in the
-#   documentation and/or other materials provided with the distribution.
-# - The name of the author may not be used to endorse or promote products
-#   derived from this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
-# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
-# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
-# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
-# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
-# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-#
-
-
-## Common names
-#
-
-LIBC_PREFIX = ../../../lib/libc
-SOFTINT_PREFIX = ../../../lib/softint
-LIBBLOCK_PREFIX = ../../../lib/libblock
-LIBS = $(LIBBLOCK_PREFIX)/libblock.a $(LIBC_PREFIX)/libc.a
-
-DEPEND = Makefile.depend
-DEPEND_PREV = $(DEPEND).prev
-OUTPUT = mbr_part
Index: uspace/srv/fs/fat/fat.h
===================================================================
--- uspace/srv/fs/fat/fat.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/srv/fs/fat/fat.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -48,4 +48,17 @@
 
 #define min(a, b)		((a) < (b) ? (a) : (b))
+
+/*
+ * Convenience macros for accessing some frequently used boot sector members.
+ */
+#define BPS(bs)		uint16_t_le2host((bs)->bps)
+#define SPC(bs)		(bs)->spc
+#define RSCNT(bs)	uint16_t_le2host((bs)->rscnt)
+#define FATCNT(bs)	(bs)->fatcnt
+#define SF(bs)		uint16_t_le2host((bs)->sec_per_fat)
+#define RDE(bs)		uint16_t_le2host((bs)->root_ent_max)
+#define TS(bs)		(uint16_t_le2host((bs)->totsec16) != 0 ? \
+			uint16_t_le2host((bs)->totsec16) : \
+			uint32_t_le2host(bs->totsec32))
 
 #define BS_BLOCK		0
@@ -198,4 +211,16 @@
 	unsigned		refcnt;
 	bool			dirty;
+
+	/*
+	 * Cache of the node's last and "current" cluster to avoid some
+	 * unnecessary FAT walks.
+	 */
+	/* Node's last cluster in FAT. */
+	bool		lastc_cached_valid;
+	fat_cluster_t	lastc_cached_value;
+	/* Node's "current" cluster, i.e. where the last I/O took place. */
+	bool		currc_cached_valid;
+	aoff64_t	currc_cached_bn;
+	fat_cluster_t	currc_cached_value;
 } fat_node_t;
 
Index: uspace/srv/fs/fat/fat_fat.c
===================================================================
--- uspace/srv/fs/fat/fat_fat.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/srv/fs/fat/fat_fat.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -49,4 +49,15 @@
 #include <mem.h>
 
+/*
+ * Convenience macros for computing some frequently used values from the
+ * primitive boot sector members.
+ */
+#define RDS(bs)		((sizeof(fat_dentry_t) * RDE((bs))) / BPS((bs))) + \
+			(((sizeof(fat_dentry_t) * RDE((bs))) % BPS((bs))) != 0)
+#define SSA(bs)		(RSCNT((bs)) + FATCNT((bs)) * SF((bs)) + RDS(bs))
+
+#define CLBN2PBN(bs, cl, bn) \
+	(SSA((bs)) + ((cl) - FAT_CLST_FIRST) * SPC((bs)) + (bn) % SPC((bs)))
+
 /**
  * The fat_alloc_lock mutex protects all copies of the File Allocation Table
@@ -74,12 +85,7 @@
 {
 	block_t *b;
-	unsigned bps;
-	unsigned rscnt;		/* block address of the first FAT */
 	uint16_t clusters = 0;
 	fat_cluster_t clst = firstc;
 	int rc;
-
-	bps = uint16_t_le2host(bs->bps);
-	rscnt = uint16_t_le2host(bs->rscnt);
 
 	if (firstc == FAT_CLST_RES0) {
@@ -99,8 +105,9 @@
 		if (lastc)
 			*lastc = clst;	/* remember the last cluster number */
-		fsec = (clst * sizeof(fat_cluster_t)) / bps;
-		fidx = clst % (bps / sizeof(fat_cluster_t));
+		fsec = (clst * sizeof(fat_cluster_t)) / BPS(bs);
+		fidx = clst % (BPS(bs) / sizeof(fat_cluster_t));
 		/* read FAT1 */
-		rc = block_get(&b, dev_handle, rscnt + fsec, BLOCK_FLAGS_NONE);
+		rc = block_get(&b, dev_handle, RSCNT(bs) + fsec,
+		    BLOCK_FLAGS_NONE);
 		if (rc != EOK)
 			return rc;
@@ -125,7 +132,5 @@
  * @param block		Pointer to a block pointer for storing result.
  * @param bs		Buffer holding the boot sector of the file system.
- * @param dev_handle	Device handle of the file system.
- * @param firstc	First cluster used by the file. Can be zero if the file
- *			is empty.
+ * @param nodep		FAT node.
  * @param bn		Block number.
  * @param flags		Flags passed to libblock.
@@ -134,16 +139,75 @@
  */
 int
+fat_block_get(block_t **block, struct fat_bs *bs, fat_node_t *nodep,
+    aoff64_t bn, int flags)
+{
+	fat_cluster_t firstc = nodep->firstc;
+	fat_cluster_t currc;
+	aoff64_t relbn = bn;
+	int rc;
+
+	if (!nodep->size)
+		return ELIMIT;
+
+	if (nodep->firstc == FAT_CLST_ROOT) 
+		goto fall_through;
+
+	if (((((nodep->size - 1) / BPS(bs)) / SPC(bs)) == bn / SPC(bs)) &&
+	    nodep->lastc_cached_valid) {
+	    	/*
+		 * This is a request to read a block within the last cluster
+		 * when fortunately we have the last cluster number cached.
+		 */
+		return block_get(block, nodep->idx->dev_handle,
+		    CLBN2PBN(bs, nodep->lastc_cached_value, bn), flags);
+	}
+
+	if (nodep->currc_cached_valid && bn >= nodep->currc_cached_bn) {
+		/*
+		 * We can start with the cluster cached by the previous call to
+		 * fat_block_get().
+		 */
+		firstc = nodep->currc_cached_value;
+		relbn -= (nodep->currc_cached_bn / SPC(bs)) * SPC(bs);
+	}
+
+fall_through:
+	rc = _fat_block_get(block, bs, nodep->idx->dev_handle, firstc,
+	    &currc, relbn, flags);
+	if (rc != EOK)
+		return rc;
+	
+	/*
+	 * Update the "current" cluster cache.
+	 */
+	nodep->currc_cached_valid = true;
+	nodep->currc_cached_bn = bn;
+	nodep->currc_cached_value = currc;
+
+	return rc;
+}
+
+/** Read block from file located on a FAT file system.
+ *
+ * @param block		Pointer to a block pointer for storing result.
+ * @param bs		Buffer holding the boot sector of the file system.
+ * @param dev_handle	Device handle of the file system.
+ * @param fcl		First cluster used by the file. Can be zero if the file
+ *			is empty.
+ * @param clp		If not NULL, address where the cluster containing bn
+ *			will be stored.
+ *			stored 
+ * @param bn		Block number.
+ * @param flags		Flags passed to libblock.
+ *
+ * @return		EOK on success or a negative error code.
+ */
+int
 _fat_block_get(block_t **block, fat_bs_t *bs, dev_handle_t dev_handle,
-    fat_cluster_t firstc, aoff64_t bn, int flags)
-{
-	unsigned bps;
-	unsigned rscnt;		/* block address of the first FAT */
-	unsigned rde;
-	unsigned rds;		/* root directory size */
-	unsigned sf;
-	unsigned ssa;		/* size of the system area */
+    fat_cluster_t fcl, fat_cluster_t *clp, aoff64_t bn, int flags)
+{
 	uint16_t clusters;
 	unsigned max_clusters;
-	fat_cluster_t lastc;
+	fat_cluster_t c;
 	int rc;
 
@@ -151,33 +215,25 @@
 	 * This function can only operate on non-zero length files.
 	 */
-	if (firstc == FAT_CLST_RES0)
+	if (fcl == FAT_CLST_RES0)
 		return ELIMIT;
 
-	bps = uint16_t_le2host(bs->bps);
-	rscnt = uint16_t_le2host(bs->rscnt);
-	rde = uint16_t_le2host(bs->root_ent_max);
-	sf = uint16_t_le2host(bs->sec_per_fat);
-
-	rds = (sizeof(fat_dentry_t) * rde) / bps;
-	rds += ((sizeof(fat_dentry_t) * rde) % bps != 0);
-	ssa = rscnt + bs->fatcnt * sf + rds;
-
-	if (firstc == FAT_CLST_ROOT) {
+	if (fcl == FAT_CLST_ROOT) {
 		/* root directory special case */
-		assert(bn < rds);
-		rc = block_get(block, dev_handle, rscnt + bs->fatcnt * sf + bn,
-		    flags);
+		assert(bn < RDS(bs));
+		rc = block_get(block, dev_handle,
+		    RSCNT(bs) + FATCNT(bs) * SF(bs) + bn, flags);
 		return rc;
 	}
 
-	max_clusters = bn / bs->spc;
-	rc = fat_cluster_walk(bs, dev_handle, firstc, &lastc, &clusters,
-	    max_clusters);
+	max_clusters = bn / SPC(bs);
+	rc = fat_cluster_walk(bs, dev_handle, fcl, &c, &clusters, max_clusters);
 	if (rc != EOK)
 		return rc;
 	assert(clusters == max_clusters);
 
-	rc = block_get(block, dev_handle,
-	    ssa + (lastc - FAT_CLST_FIRST) * bs->spc + bn % bs->spc, flags);
+	rc = block_get(block, dev_handle, CLBN2PBN(bs, c, bn), flags);
+
+	if (clp)
+		*clp = c;
 
 	return rc;
@@ -198,24 +254,19 @@
 int fat_fill_gap(fat_bs_t *bs, fat_node_t *nodep, fat_cluster_t mcl, aoff64_t pos)
 {
-	uint16_t bps;
-	unsigned spc;
 	block_t *b;
 	aoff64_t o, boundary;
 	int rc;
 
-	bps = uint16_t_le2host(bs->bps);
-	spc = bs->spc;
-	
-	boundary = ROUND_UP(nodep->size, bps * spc);
+	boundary = ROUND_UP(nodep->size, BPS(bs) * SPC(bs));
 
 	/* zero out already allocated space */
 	for (o = nodep->size; o < pos && o < boundary;
-	    o = ALIGN_DOWN(o + bps, bps)) {
-	    	int flags = (o % bps == 0) ?
+	    o = ALIGN_DOWN(o + BPS(bs), BPS(bs))) {
+	    	int flags = (o % BPS(bs) == 0) ?
 		    BLOCK_FLAGS_NOREAD : BLOCK_FLAGS_NONE;
-		rc = fat_block_get(&b, bs, nodep, o / bps, flags);
-		if (rc != EOK)
-			return rc;
-		memset(b->data + o % bps, 0, bps - o % bps);
+		rc = fat_block_get(&b, bs, nodep, o / BPS(bs), flags);
+		if (rc != EOK)
+			return rc;
+		memset(b->data + o % BPS(bs), 0, BPS(bs) - o % BPS(bs));
 		b->dirty = true;		/* need to sync node */
 		rc = block_put(b);
@@ -228,10 +279,10 @@
 	
 	/* zero out the initial part of the new cluster chain */
-	for (o = boundary; o < pos; o += bps) {
+	for (o = boundary; o < pos; o += BPS(bs)) {
 		rc = _fat_block_get(&b, bs, nodep->idx->dev_handle, mcl,
-		    (o - boundary) / bps, BLOCK_FLAGS_NOREAD);
-		if (rc != EOK)
-			return rc;
-		memset(b->data, 0, min(bps, pos - o));
+		    NULL, (o - boundary) / BPS(bs), BLOCK_FLAGS_NOREAD);
+		if (rc != EOK)
+			return rc;
+		memset(b->data, 0, min(BPS(bs), pos - o));
 		b->dirty = true;		/* need to sync node */
 		rc = block_put(b);
@@ -257,19 +308,13 @@
 {
 	block_t *b;
-	uint16_t bps;
-	uint16_t rscnt;
-	uint16_t sf;
 	fat_cluster_t *cp;
 	int rc;
 
-	bps = uint16_t_le2host(bs->bps);
-	rscnt = uint16_t_le2host(bs->rscnt);
-	sf = uint16_t_le2host(bs->sec_per_fat);
-
-	rc = block_get(&b, dev_handle, rscnt + sf * fatno +
-	    (clst * sizeof(fat_cluster_t)) / bps, BLOCK_FLAGS_NONE);
+	rc = block_get(&b, dev_handle, RSCNT(bs) + SF(bs) * fatno +
+	    (clst * sizeof(fat_cluster_t)) / BPS(bs), BLOCK_FLAGS_NONE);
 	if (rc != EOK)
 		return rc;
-	cp = (fat_cluster_t *)b->data + clst % (bps / sizeof(fat_cluster_t));
+	cp = (fat_cluster_t *)b->data +
+	    clst % (BPS(bs) / sizeof(fat_cluster_t));
 	*value = uint16_t_le2host(*cp);
 	rc = block_put(b);
@@ -293,20 +338,14 @@
 {
 	block_t *b;
-	uint16_t bps;
-	uint16_t rscnt;
-	uint16_t sf;
 	fat_cluster_t *cp;
 	int rc;
 
-	bps = uint16_t_le2host(bs->bps);
-	rscnt = uint16_t_le2host(bs->rscnt);
-	sf = uint16_t_le2host(bs->sec_per_fat);
-
-	assert(fatno < bs->fatcnt);
-	rc = block_get(&b, dev_handle, rscnt + sf * fatno +
-	    (clst * sizeof(fat_cluster_t)) / bps, BLOCK_FLAGS_NONE);
+	assert(fatno < FATCNT(bs));
+	rc = block_get(&b, dev_handle, RSCNT(bs) + SF(bs) * fatno +
+	    (clst * sizeof(fat_cluster_t)) / BPS(bs), BLOCK_FLAGS_NONE);
 	if (rc != EOK)
 		return rc;
-	cp = (fat_cluster_t *)b->data + clst % (bps / sizeof(fat_cluster_t));
+	cp = (fat_cluster_t *)b->data +
+	    clst % (BPS(bs) / sizeof(fat_cluster_t));
 	*cp = host2uint16_t_le(value);
 	b->dirty = true;		/* need to sync block */
@@ -364,11 +403,4 @@
     fat_cluster_t *mcl, fat_cluster_t *lcl)
 {
-	uint16_t bps;
-	uint16_t rscnt;
-	uint16_t sf;
-	uint32_t ts;
-	unsigned rde;
-	unsigned rds;
-	unsigned ssa;
 	block_t *blk;
 	fat_cluster_t *lifo;	/* stack for storing free cluster numbers */ 
@@ -380,16 +412,4 @@
 	if (!lifo)
 		return ENOMEM;
-	
-	bps = uint16_t_le2host(bs->bps);
-	rscnt = uint16_t_le2host(bs->rscnt);
-	sf = uint16_t_le2host(bs->sec_per_fat);
-	rde = uint16_t_le2host(bs->root_ent_max);
-	ts = (uint32_t) uint16_t_le2host(bs->totsec16);
-	if (ts == 0)
-		ts = uint32_t_le2host(bs->totsec32);
-
-	rds = (sizeof(fat_dentry_t) * rde) / bps;
-	rds += ((sizeof(fat_dentry_t) * rde) % bps != 0);
-	ssa = rscnt + bs->fatcnt * sf + rds;
 	
 	/*
@@ -397,16 +417,20 @@
 	 */
 	fibril_mutex_lock(&fat_alloc_lock);
-	for (b = 0, cl = 0; b < sf; b++) {
-		rc = block_get(&blk, dev_handle, rscnt + b, BLOCK_FLAGS_NONE);
+	for (b = 0, cl = 0; b < SF(bs); b++) {
+		rc = block_get(&blk, dev_handle, RSCNT(bs) + b,
+		    BLOCK_FLAGS_NONE);
 		if (rc != EOK)
 			goto error;
-		for (c = 0; c < bps / sizeof(fat_cluster_t); c++, cl++) {
+		for (c = 0; c < BPS(bs) / sizeof(fat_cluster_t); c++, cl++) {
 			/*
-			 * Check if the cluster is physically there. This check
-			 * becomes necessary when the file system is created
-			 * with fewer total sectors than how many is inferred
-			 * from the size of the file allocation table.
+			 * Check if the entire cluster is physically there.
+			 * This check becomes necessary when the file system is
+			 * created with fewer total sectors than how many is
+			 * inferred from the size of the file allocation table
+			 * or when the last cluster ends beyond the end of the
+			 * device.
 			 */
-			if ((cl >= 2) && ((cl - 2) * bs->spc + ssa >= ts)) {
+			if ((cl >= FAT_CLST_FIRST) &&
+			    CLBN2PBN(bs, cl, SPC(bs) - 1) >= TS(bs)) {
 				rc = block_put(blk);
 				if (rc != EOK)
@@ -511,33 +535,42 @@
  * @param nodep		Node representing the file.
  * @param mcl		First cluster of the cluster chain to append.
+ * @param lcl		Last cluster of the cluster chain to append.
  *
  * @return		EOK on success or a negative error code.
  */
-int fat_append_clusters(fat_bs_t *bs, fat_node_t *nodep, fat_cluster_t mcl)
+int
+fat_append_clusters(fat_bs_t *bs, fat_node_t *nodep, fat_cluster_t mcl,
+    fat_cluster_t lcl)
 {
 	dev_handle_t dev_handle = nodep->idx->dev_handle;
-	fat_cluster_t lcl;
-	uint16_t numc;
+	fat_cluster_t lastc;
 	uint8_t fatno;
 	int rc;
 
-	rc = fat_cluster_walk(bs, dev_handle, nodep->firstc, &lcl, &numc,
-	    (uint16_t) -1);
-	if (rc != EOK)
-		return rc;
-
-	if (numc == 0) {
+	if (nodep->firstc == FAT_CLST_RES0) {
 		/* No clusters allocated to the node yet. */
 		nodep->firstc = mcl;
-		nodep->dirty = true;		/* need to sync node */
-		return EOK;
-	}
-
-	for (fatno = FAT1; fatno < bs->fatcnt; fatno++) {
-		rc = fat_set_cluster(bs, nodep->idx->dev_handle, fatno, lcl,
-		    mcl);
-		if (rc != EOK)
-			return rc;
-	}
+		nodep->dirty = true;	/* need to sync node */
+	} else {
+		if (nodep->lastc_cached_valid) {
+			lastc = nodep->lastc_cached_value;
+			nodep->lastc_cached_valid = false;
+		} else {
+			rc = fat_cluster_walk(bs, dev_handle, nodep->firstc,
+			    &lastc, NULL, (uint16_t) -1);
+			if (rc != EOK)
+				return rc;
+		}
+
+		for (fatno = FAT1; fatno < bs->fatcnt; fatno++) {
+			rc = fat_set_cluster(bs, nodep->idx->dev_handle, fatno,
+			    lastc, mcl);
+			if (rc != EOK)
+				return rc;
+		}
+	}
+
+	nodep->lastc_cached_valid = true;
+	nodep->lastc_cached_value = lcl;
 
 	return EOK;
@@ -548,5 +581,5 @@
  * @param bs		Buffer holding the boot sector of the file system.
  * @param nodep		FAT node where the chopping will take place.
- * @param lastc		Last cluster which will remain in the node. If this
+ * @param lcl		Last cluster which will remain in the node. If this
  *			argument is FAT_CLST_RES0, then all clusters will
  *			be chopped off.
@@ -554,10 +587,17 @@
  * @return		EOK on success or a negative return code.
  */
-int fat_chop_clusters(fat_bs_t *bs, fat_node_t *nodep, fat_cluster_t lastc)
-{
-	int rc;
-
+int fat_chop_clusters(fat_bs_t *bs, fat_node_t *nodep, fat_cluster_t lcl)
+{
+	int rc;
 	dev_handle_t dev_handle = nodep->idx->dev_handle;
-	if (lastc == FAT_CLST_RES0) {
+
+	/*
+	 * Invalidate cached cluster numbers.
+	 */
+	nodep->lastc_cached_valid = false;
+	if (nodep->currc_cached_value != lcl)
+		nodep->currc_cached_valid = false;
+
+	if (lcl == FAT_CLST_RES0) {
 		/* The node will have zero size and no clusters allocated. */
 		rc = fat_free_clusters(bs, dev_handle, nodep->firstc);
@@ -570,5 +610,5 @@
 		unsigned fatno;
 
-		rc = fat_get_cluster(bs, dev_handle, FAT1, lastc, &nextc);
+		rc = fat_get_cluster(bs, dev_handle, FAT1, lcl, &nextc);
 		if (rc != EOK)
 			return rc;
@@ -576,5 +616,5 @@
 		/* Terminate the cluster chain in all copies of FAT. */
 		for (fatno = FAT1; fatno < bs->fatcnt; fatno++) {
-			rc = fat_set_cluster(bs, dev_handle, fatno, lastc,
+			rc = fat_set_cluster(bs, dev_handle, fatno, lcl,
 			    FAT_CLST_LAST1);
 			if (rc != EOK)
@@ -588,4 +628,10 @@
 	}
 
+	/*
+	 * Update and re-enable the last cluster cache.
+	 */
+	nodep->lastc_cached_valid = true;
+	nodep->lastc_cached_value = lcl;
+
 	return EOK;
 }
@@ -596,15 +642,12 @@
 	int i;
 	block_t *b;
-	unsigned bps;
-	int rc;
-
-	bps = uint16_t_le2host(bs->bps);
-	
-	for (i = 0; i < bs->spc; i++) {
-		rc = _fat_block_get(&b, bs, dev_handle, c, i,
+	int rc;
+
+	for (i = 0; i < SPC(bs); i++) {
+		rc = _fat_block_get(&b, bs, dev_handle, c, NULL, i,
 		    BLOCK_FLAGS_NOREAD);
 		if (rc != EOK)
 			return rc;
-		memset(b->data, 0, bps);
+		memset(b->data, 0, BPS(bs));
 		b->dirty = true;
 		rc = block_put(b);
Index: uspace/srv/fs/fat/fat_fat.h
===================================================================
--- uspace/srv/fs/fat/fat_fat.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/srv/fs/fat/fat_fat.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -64,13 +64,11 @@
     fat_cluster_t *, uint16_t *, uint16_t);
 
-#define fat_block_get(b, bs, np, bn, flags) \
-    _fat_block_get((b), (bs), (np)->idx->dev_handle, (np)->firstc, (bn), \
-    (flags))
-
+extern int fat_block_get(block_t **, struct fat_bs *, struct fat_node *,
+    aoff64_t, int);
 extern int _fat_block_get(block_t **, struct fat_bs *, dev_handle_t,
-    fat_cluster_t, aoff64_t, int);
+    fat_cluster_t, fat_cluster_t *, aoff64_t, int);
 
 extern int fat_append_clusters(struct fat_bs *, struct fat_node *,
-    fat_cluster_t);
+    fat_cluster_t, fat_cluster_t);
 extern int fat_chop_clusters(struct fat_bs *, struct fat_node *,
     fat_cluster_t);
Index: uspace/srv/fs/fat/fat_ops.c
===================================================================
--- uspace/srv/fs/fat/fat_ops.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/srv/fs/fat/fat_ops.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -60,4 +60,7 @@
 #define FS_NODE(node)	((node) ? (node)->bp : NULL)
 
+#define DPS(bs)		(BPS((bs)) / sizeof(fat_dentry_t))
+#define BPC(bs)		(BPS((bs)) * SPC((bs)))
+
 /** Mutex protecting the list of cached free FAT nodes. */
 static FIBRIL_MUTEX_INITIALIZE(ffn_mutex);
@@ -101,4 +104,9 @@
 	node->refcnt = 0;
 	node->dirty = false;
+	node->lastc_cached_valid = false;
+	node->lastc_cached_value = FAT_CLST_LAST1;
+	node->currc_cached_valid = false;
+	node->currc_cached_bn = 0;
+	node->currc_cached_value = FAT_CLST_LAST1;
 }
 
@@ -108,6 +116,4 @@
 	fat_bs_t *bs;
 	fat_dentry_t *d;
-	uint16_t bps;
-	unsigned dps;
 	int rc;
 	
@@ -115,14 +121,13 @@
 
 	bs = block_bb_get(node->idx->dev_handle);
-	bps = uint16_t_le2host(bs->bps);
-	dps = bps / sizeof(fat_dentry_t);
 	
 	/* Read the block that contains the dentry of interest. */
 	rc = _fat_block_get(&b, bs, node->idx->dev_handle, node->idx->pfc,
-	    (node->idx->pdi * sizeof(fat_dentry_t)) / bps, BLOCK_FLAGS_NONE);
+	    NULL, (node->idx->pdi * sizeof(fat_dentry_t)) / BPS(bs),
+	    BLOCK_FLAGS_NONE);
 	if (rc != EOK)
 		return rc;
 
-	d = ((fat_dentry_t *)b->data) + (node->idx->pdi % dps);
+	d = ((fat_dentry_t *)b->data) + (node->idx->pdi % DPS(bs));
 
 	d->firstc = host2uint16_t_le(node->firstc);
@@ -266,7 +271,4 @@
 	fat_dentry_t *d;
 	fat_node_t *nodep = NULL;
-	unsigned bps;
-	unsigned spc;
-	unsigned dps;
 	int rc;
 
@@ -298,11 +300,8 @@
 
 	bs = block_bb_get(idxp->dev_handle);
-	bps = uint16_t_le2host(bs->bps);
-	spc = bs->spc;
-	dps = bps / sizeof(fat_dentry_t);
 
 	/* Read the block that contains the dentry of interest. */
-	rc = _fat_block_get(&b, bs, idxp->dev_handle, idxp->pfc,
-	    (idxp->pdi * sizeof(fat_dentry_t)) / bps, BLOCK_FLAGS_NONE);
+	rc = _fat_block_get(&b, bs, idxp->dev_handle, idxp->pfc, NULL,
+	    (idxp->pdi * sizeof(fat_dentry_t)) / BPS(bs), BLOCK_FLAGS_NONE);
 	if (rc != EOK) {
 		(void) fat_node_put(FS_NODE(nodep));
@@ -310,5 +309,5 @@
 	}
 
-	d = ((fat_dentry_t *)b->data) + (idxp->pdi % dps);
+	d = ((fat_dentry_t *)b->data) + (idxp->pdi % DPS(bs));
 	if (d->attr & FAT_ATTR_SUBDIR) {
 		/* 
@@ -330,5 +329,5 @@
 			return rc;
 		}
-		nodep->size = bps * spc * clusters;
+		nodep->size = BPS(bs) * SPC(bs) * clusters;
 	} else {
 		nodep->type = FAT_FILE;
@@ -368,23 +367,21 @@
 	char name[FAT_NAME_LEN + 1 + FAT_EXT_LEN + 1];
 	unsigned i, j;
-	unsigned bps;		/* bytes per sector */
-	unsigned dps;		/* dentries per sector */
 	unsigned blocks;
 	fat_dentry_t *d;
+	dev_handle_t dev_handle;
 	block_t *b;
 	int rc;
 
 	fibril_mutex_lock(&parentp->idx->lock);
-	bs = block_bb_get(parentp->idx->dev_handle);
-	bps = uint16_t_le2host(bs->bps);
-	dps = bps / sizeof(fat_dentry_t);
-	blocks = parentp->size / bps;
+	dev_handle = parentp->idx->dev_handle;
+	fibril_mutex_unlock(&parentp->idx->lock);
+
+	bs = block_bb_get(dev_handle);
+	blocks = parentp->size / BPS(bs);
 	for (i = 0; i < blocks; i++) {
 		rc = fat_block_get(&b, bs, parentp, i, BLOCK_FLAGS_NONE);
-		if (rc != EOK) {
-			fibril_mutex_unlock(&parentp->idx->lock);
+		if (rc != EOK)
 			return rc;
-		}
-		for (j = 0; j < dps; j++) { 
+		for (j = 0; j < DPS(bs); j++) { 
 			d = ((fat_dentry_t *)b->data) + j;
 			switch (fat_classify_dentry(d)) {
@@ -395,5 +392,4 @@
 				/* miss */
 				rc = block_put(b);
-				fibril_mutex_unlock(&parentp->idx->lock);
 				*rfn = NULL;
 				return rc;
@@ -406,14 +402,6 @@
 				/* hit */
 				fat_node_t *nodep;
-				/*
-				 * Assume tree hierarchy for locking.  We
-				 * already have the parent and now we are going
-				 * to lock the child.  Never lock in the oposite
-				 * order.
-				 */
-				fat_idx_t *idx = fat_idx_get_by_pos(
-				    parentp->idx->dev_handle, parentp->firstc,
-				    i * dps + j);
-				fibril_mutex_unlock(&parentp->idx->lock);
+				fat_idx_t *idx = fat_idx_get_by_pos(dev_handle,
+				    parentp->firstc, i * DPS(bs) + j);
 				if (!idx) {
 					/*
@@ -438,11 +426,8 @@
 		}
 		rc = block_put(b);
-		if (rc != EOK) {
-			fibril_mutex_unlock(&parentp->idx->lock);
+		if (rc != EOK)
 			return rc;
-		}
-	}
-
-	fibril_mutex_unlock(&parentp->idx->lock);
+	}
+
 	*rfn = NULL;
 	return EOK;
@@ -513,9 +498,7 @@
 	fat_bs_t *bs;
 	fat_cluster_t mcl, lcl;
-	uint16_t bps;
 	int rc;
 
 	bs = block_bb_get(dev_handle);
-	bps = uint16_t_le2host(bs->bps);
 	if (flags & L_DIRECTORY) {
 		/* allocate a cluster */
@@ -546,5 +529,5 @@
 		nodep->type = FAT_DIRECTORY;
 		nodep->firstc = mcl;
-		nodep->size = bps * bs->spc;
+		nodep->size = BPS(bs) * SPC(bs);
 	} else {
 		nodep->type = FAT_FILE;
@@ -609,6 +592,4 @@
 	block_t *b;
 	unsigned i, j;
-	uint16_t bps;
-	unsigned dps;
 	unsigned blocks;
 	fat_cluster_t mcl, lcl;
@@ -640,8 +621,6 @@
 	fibril_mutex_lock(&parentp->idx->lock);
 	bs = block_bb_get(parentp->idx->dev_handle);
-	bps = uint16_t_le2host(bs->bps);
-	dps = bps / sizeof(fat_dentry_t);
-
-	blocks = parentp->size / bps;
+
+	blocks = parentp->size / BPS(bs);
 
 	for (i = 0; i < blocks; i++) {
@@ -651,5 +630,5 @@
 			return rc;
 		}
-		for (j = 0; j < dps; j++) {
+		for (j = 0; j < DPS(bs); j++) {
 			d = ((fat_dentry_t *)b->data) + j;
 			switch (fat_classify_dentry(d)) {
@@ -691,5 +670,5 @@
 		return rc;
 	}
-	rc = fat_append_clusters(bs, parentp, mcl);
+	rc = fat_append_clusters(bs, parentp, mcl, lcl);
 	if (rc != EOK) {
 		(void) fat_free_clusters(bs, parentp->idx->dev_handle, mcl);
@@ -697,5 +676,5 @@
 		return rc;
 	}
-	parentp->size += bps * bs->spc;
+	parentp->size += BPS(bs) * SPC(bs);
 	parentp->dirty = true;		/* need to sync node */
 	rc = fat_block_get(&b, bs, parentp, i, BLOCK_FLAGS_NONE);
@@ -771,5 +750,5 @@
 
 	childp->idx->pfc = parentp->firstc;
-	childp->idx->pdi = i * dps + j;
+	childp->idx->pdi = i * DPS(bs) + j;
 	fibril_mutex_unlock(&childp->idx->lock);
 
@@ -793,5 +772,4 @@
 	fat_bs_t *bs;
 	fat_dentry_t *d;
-	uint16_t bps;
 	block_t *b;
 	bool has_children;
@@ -812,13 +790,12 @@
 	fibril_mutex_lock(&childp->idx->lock);
 	bs = block_bb_get(childp->idx->dev_handle);
-	bps = uint16_t_le2host(bs->bps);
 
 	rc = _fat_block_get(&b, bs, childp->idx->dev_handle, childp->idx->pfc,
-	    (childp->idx->pdi * sizeof(fat_dentry_t)) / bps,
+	    NULL, (childp->idx->pdi * sizeof(fat_dentry_t)) / BPS(bs),
 	    BLOCK_FLAGS_NONE);
 	if (rc != EOK) 
 		goto error;
 	d = (fat_dentry_t *)b->data +
-	    (childp->idx->pdi % (bps / sizeof(fat_dentry_t)));
+	    (childp->idx->pdi % (BPS(bs) / sizeof(fat_dentry_t)));
 	/* mark the dentry as not-currently-used */
 	d->name[0] = FAT_DENTRY_ERASED;
@@ -852,6 +829,4 @@
 	fat_bs_t *bs;
 	fat_node_t *nodep = FAT_NODE(fn);
-	unsigned bps;
-	unsigned dps;
 	unsigned blocks;
 	block_t *b;
@@ -866,8 +841,6 @@
 	fibril_mutex_lock(&nodep->idx->lock);
 	bs = block_bb_get(nodep->idx->dev_handle);
-	bps = uint16_t_le2host(bs->bps);
-	dps = bps / sizeof(fat_dentry_t);
-
-	blocks = nodep->size / bps;
+
+	blocks = nodep->size / BPS(bs);
 
 	for (i = 0; i < blocks; i++) {
@@ -879,5 +852,5 @@
 			return rc;
 		}
-		for (j = 0; j < dps; j++) {
+		for (j = 0; j < DPS(bs); j++) {
 			d = ((fat_dentry_t *)b->data) + j;
 			switch (fat_classify_dentry(d)) {
@@ -976,6 +949,4 @@
 	enum cache_mode cmode;
 	fat_bs_t *bs;
-	uint16_t bps;
-	uint16_t rde;
 	
 	/* Accept the mount options */
@@ -1014,9 +985,5 @@
 	bs = block_bb_get(dev_handle);
 	
-	/* Read the number of root directory entries. */
-	bps = uint16_t_le2host(bs->bps);
-	rde = uint16_t_le2host(bs->root_ent_max);
-
-	if (bps != BS_SIZE) {
+	if (BPS(bs) != BS_SIZE) {
 		block_fini(dev_handle);
 		ipc_answer_0(rid, ENOTSUP);
@@ -1025,5 +992,5 @@
 
 	/* Initialize the block cache */
-	rc = block_cache_init(dev_handle, bps, 0 /* XXX */, cmode);
+	rc = block_cache_init(dev_handle, BPS(bs), 0 /* XXX */, cmode);
 	if (rc != EOK) {
 		block_fini(dev_handle);
@@ -1087,5 +1054,5 @@
 	rootp->refcnt = 1;
 	rootp->lnkcnt = 0;	/* FS root is not linked */
-	rootp->size = rde * sizeof(fat_dentry_t);
+	rootp->size = RDE(bs) * sizeof(fat_dentry_t);
 	rootp->idx = ridxp;
 	ridxp->nodep = rootp;
@@ -1165,5 +1132,4 @@
 	fat_node_t *nodep;
 	fat_bs_t *bs;
-	uint16_t bps;
 	size_t bytes;
 	block_t *b;
@@ -1191,5 +1157,4 @@
 
 	bs = block_bb_get(dev_handle);
-	bps = uint16_t_le2host(bs->bps);
 
 	if (nodep->type == FAT_FILE) {
@@ -1204,7 +1169,7 @@
 			(void) async_data_read_finalize(callid, NULL, 0);
 		} else {
-			bytes = min(len, bps - pos % bps);
+			bytes = min(len, BPS(bs) - pos % BPS(bs));
 			bytes = min(bytes, nodep->size - pos);
-			rc = fat_block_get(&b, bs, nodep, pos / bps,
+			rc = fat_block_get(&b, bs, nodep, pos / BPS(bs),
 			    BLOCK_FLAGS_NONE);
 			if (rc != EOK) {
@@ -1214,6 +1179,6 @@
 				return;
 			}
-			(void) async_data_read_finalize(callid, b->data + pos % bps,
-			    bytes);
+			(void) async_data_read_finalize(callid,
+			    b->data + pos % BPS(bs), bytes);
 			rc = block_put(b);
 			if (rc != EOK) {
@@ -1230,6 +1195,6 @@
 
 		assert(nodep->type == FAT_DIRECTORY);
-		assert(nodep->size % bps == 0);
-		assert(bps % sizeof(fat_dentry_t) == 0);
+		assert(nodep->size % BPS(bs) == 0);
+		assert(BPS(bs) % sizeof(fat_dentry_t) == 0);
 
 		/*
@@ -1239,6 +1204,6 @@
 		 * the position pointer accordingly.
 		 */
-		bnum = (pos * sizeof(fat_dentry_t)) / bps;
-		while (bnum < nodep->size / bps) {
+		bnum = (pos * sizeof(fat_dentry_t)) / BPS(bs);
+		while (bnum < nodep->size / BPS(bs)) {
 			aoff64_t o;
 
@@ -1247,6 +1212,6 @@
 			if (rc != EOK)
 				goto err;
-			for (o = pos % (bps / sizeof(fat_dentry_t));
-			    o < bps / sizeof(fat_dentry_t);
+			for (o = pos % (BPS(bs) / sizeof(fat_dentry_t));
+			    o < BPS(bs) / sizeof(fat_dentry_t);
 			    o++, pos++) {
 				d = ((fat_dentry_t *)b->data) + o;
@@ -1306,7 +1271,4 @@
 	size_t bytes, size;
 	block_t *b;
-	uint16_t bps;
-	unsigned spc;
-	unsigned bpc;		/* bytes per cluster */
 	aoff64_t boundary;
 	int flags = BLOCK_FLAGS_NONE;
@@ -1334,7 +1296,4 @@
 
 	bs = block_bb_get(dev_handle);
-	bps = uint16_t_le2host(bs->bps);
-	spc = bs->spc;
-	bpc = bps * spc;
 
 	/*
@@ -1345,9 +1304,9 @@
 	 * value signalizing a smaller number of bytes written. 
 	 */ 
-	bytes = min(len, bps - pos % bps);
-	if (bytes == bps)
+	bytes = min(len, BPS(bs) - pos % BPS(bs));
+	if (bytes == BPS(bs))
 		flags |= BLOCK_FLAGS_NOREAD;
 	
-	boundary = ROUND_UP(nodep->size, bpc);
+	boundary = ROUND_UP(nodep->size, BPC(bs));
 	if (pos < boundary) {
 		/*
@@ -1364,5 +1323,5 @@
 			return;
 		}
-		rc = fat_block_get(&b, bs, nodep, pos / bps, flags);
+		rc = fat_block_get(&b, bs, nodep, pos / BPS(bs), flags);
 		if (rc != EOK) {
 			(void) fat_node_put(fn);
@@ -1371,6 +1330,6 @@
 			return;
 		}
-		(void) async_data_write_finalize(callid, b->data + pos % bps,
-		    bytes);
+		(void) async_data_write_finalize(callid,
+		    b->data + pos % BPS(bs), bytes);
 		b->dirty = true;		/* need to sync block */
 		rc = block_put(b);
@@ -1396,5 +1355,5 @@
 		fat_cluster_t mcl, lcl; 
  
-		nclsts = (ROUND_UP(pos + bytes, bpc) - boundary) / bpc;
+		nclsts = (ROUND_UP(pos + bytes, BPC(bs)) - boundary) / BPC(bs);
 		/* create an independent chain of nclsts clusters in all FATs */
 		rc = fat_alloc_clusters(bs, dev_handle, nclsts, &mcl, &lcl);
@@ -1415,6 +1374,6 @@
 			return;
 		}
-		rc = _fat_block_get(&b, bs, dev_handle, lcl, (pos / bps) % spc,
-		    flags);
+		rc = _fat_block_get(&b, bs, dev_handle, lcl, NULL,
+		    (pos / BPS(bs)) % SPC(bs), flags);
 		if (rc != EOK) {
 			(void) fat_free_clusters(bs, dev_handle, mcl);
@@ -1424,6 +1383,6 @@
 			return;
 		}
-		(void) async_data_write_finalize(callid, b->data + pos % bps,
-		    bytes);
+		(void) async_data_write_finalize(callid,
+		    b->data + pos % BPS(bs), bytes);
 		b->dirty = true;		/* need to sync block */
 		rc = block_put(b);
@@ -1438,5 +1397,5 @@
 		 * node's cluster chain.
 		 */
-		rc = fat_append_clusters(bs, nodep, mcl);
+		rc = fat_append_clusters(bs, nodep, mcl, lcl);
 		if (rc != EOK) {
 			(void) fat_free_clusters(bs, dev_handle, mcl);
@@ -1462,7 +1421,4 @@
 	fat_node_t *nodep;
 	fat_bs_t *bs;
-	uint16_t bps;
-	uint8_t spc;
-	unsigned bpc;	/* bytes per cluster */
 	int rc;
 
@@ -1479,7 +1435,4 @@
 
 	bs = block_bb_get(dev_handle);
-	bps = uint16_t_le2host(bs->bps);
-	spc = bs->spc;
-	bpc = bps * spc;
 
 	if (nodep->size == size) {
@@ -1491,5 +1444,5 @@
 		 */
 		rc = EINVAL;
-	} else if (ROUND_UP(nodep->size, bpc) == ROUND_UP(size, bpc)) {
+	} else if (ROUND_UP(nodep->size, BPC(bs)) == ROUND_UP(size, BPC(bs))) {
 		/*
 		 * The node will be shrunk, but no clusters will be deallocated.
@@ -1509,5 +1462,5 @@
 			fat_cluster_t lastc;
 			rc = fat_cluster_walk(bs, dev_handle, nodep->firstc,
-			    &lastc, NULL, (size - 1) / bpc);
+			    &lastc, NULL, (size - 1) / BPC(bs));
 			if (rc != EOK)
 				goto out;
@@ -1564,6 +1517,25 @@
 void fat_sync(ipc_callid_t rid, ipc_call_t *request)
 {
-	/* Dummy implementation */
-	ipc_answer_0(rid, EOK);
+	dev_handle_t dev_handle = (dev_handle_t) IPC_GET_ARG1(*request);
+	fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request);
+	
+	fs_node_t *fn;
+	int rc = fat_node_get(&fn, dev_handle, index);
+	if (rc != EOK) {
+		ipc_answer_0(rid, rc);
+		return;
+	}
+	if (!fn) {
+		ipc_answer_0(rid, ENOENT);
+		return;
+	}
+	
+	fat_node_t *nodep = FAT_NODE(fn);
+	
+	nodep->dirty = true;
+	rc = fat_node_sync(nodep);
+	
+	fat_node_put(fn);
+	ipc_answer_0(rid, rc);
 }
 
Index: uspace/srv/fs/tmpfs/tmpfs_ops.c
===================================================================
--- uspace/srv/fs/tmpfs/tmpfs_ops.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/srv/fs/tmpfs/tmpfs_ops.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -41,5 +41,5 @@
 #include <ipc/ipc.h>
 #include <macros.h>
-#include <limits.h>
+#include <stdint.h>
 #include <async.h>
 #include <errno.h>
@@ -736,5 +736,8 @@
 void tmpfs_sync(ipc_callid_t rid, ipc_call_t *request)
 {
-	/* Dummy implementation */
+	/*
+	 * TMPFS keeps its data structures always consistent,
+	 * thus the sync operation is a no-op.
+	 */
 	ipc_answer_0(rid, EOK);
 }
Index: uspace/srv/hid/console/gcons.c
===================================================================
--- uspace/srv/hid/console/gcons.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/srv/hid/console/gcons.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -286,4 +286,7 @@
 	ssize_t nx = (ssize_t) mouse_x + dx;
 	ssize_t ny = (ssize_t) mouse_y + dy;
+
+	if (!use_gcons)
+		return;
 	
 	mouse_x = (size_t) limit(nx, 0, xres);
Index: uspace/srv/hid/fb/fb.c
===================================================================
--- uspace/srv/hid/fb/fb.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/srv/hid/fb/fb.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -1347,6 +1347,6 @@
 {
 	mouse_hide();
-	pointer_x = x;
-	pointer_y = y;
+	pointer_x = x % screen.xres;
+	pointer_y = y % screen.yres;
 	mouse_show();
 }
Index: uspace/srv/hid/fb/main.c
===================================================================
--- uspace/srv/hid/fb/main.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/srv/hid/fb/main.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -105,5 +105,5 @@
 #endif
 #ifdef SKI_ENABLED
-	if ((!initialized) && (!fb_present)) {
+	if ((!initialized) && (fb_kind == 6)) {
 		if (ski_init() == 0)
 			initialized = true;
Index: uspace/srv/hid/kbd/Makefile
===================================================================
--- uspace/srv/hid/kbd/Makefile	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/srv/hid/kbd/Makefile	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -58,4 +58,9 @@
 
 ifeq ($(UARCH),arm32)
+	ifeq ($(MACHINE),gta02)
+		SOURCES += \
+			port/chardev.c \
+			ctl/stty.c
+	endif
 	ifeq ($(MACHINE),testarm)
 		SOURCES += \
Index: uspace/srv/hid/kbd/port/chardev.c
===================================================================
--- uspace/srv/hid/kbd/port/chardev.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/srv/hid/kbd/port/chardev.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -41,4 +41,5 @@
 #include <kbd.h>
 #include <vfs/vfs.h>
+#include <sys/stat.h>
 #include <fcntl.h>
 #include <errno.h>
@@ -50,21 +51,41 @@
 #define NAME "kbd"
 
+/** List of devices to try connecting to. */
+static const char *in_devs[] = {
+	"/dev/char/ps2a",
+	"/dev/char/s3c24ser"
+};
+
+static const int num_devs = sizeof(in_devs) / sizeof(in_devs[0]);
+
 int kbd_port_init(void)
 {
-	const char *input = "/dev/char/ps2a";
 	int input_fd;
+	int i;
 
-	printf(NAME ": open %s\n", input);
+	input_fd = -1;
+	for (i = 0; i < num_devs; i++) {
+		struct stat s;
 
-	input_fd = open(input, O_RDONLY);
+		if (stat(in_devs[i], &s) == EOK)
+			break;
+	}
+
+	if (i >= num_devs) {
+		printf(NAME ": Could not find any suitable input device.\n");
+		return -1;
+	}
+
+	input_fd = open(in_devs[i], O_RDONLY);
 	if (input_fd < 0) {
-		printf(NAME ": Failed opening %s (%d)\n", input, input_fd);
-		return false;
+		printf(NAME ": failed opening device %s (%d).\n", in_devs[i],
+		    input_fd);
+		return -1;
 	}
 
 	dev_phone = fd_phone(input_fd);
 	if (dev_phone < 0) {
-		printf(NAME ": Failed to connect to device\n");
-		return false;
+		printf(NAME ": Failed connecting to device\n");
+		return -1;
 	}
 
@@ -73,5 +94,5 @@
 	if (ipc_connect_to_me(dev_phone, 0, 0, 0, &phonehash) != 0) {
 		printf(NAME ": Failed to create callback from device\n");
-		return false;
+		return -1;
 	}
 
Index: pace/srv/hid/kbd/port/i8042.h
===================================================================
--- uspace/srv/hid/kbd/port/i8042.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ 	(revision )
@@ -1,55 +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 kbd_port
- * @ingroup  kbd
- * @{
- */
-
-/** @file
- * @brief i8042 port driver.
- */
-
-#ifndef KBD_PORT_i8042_H_
-#define KBD_PORT_i8042_H_
-
-#include <libarch/ddi.h>
-#include <libarch/types.h>
-
-struct i8042 {
-	ioport8_t data;
-	uint8_t pad[3];
-	ioport8_t status;
-} __attribute__ ((packed));
-typedef struct i8042 i8042_t;
-
-#endif
-
-/**
- * @}
- */ 
Index: uspace/srv/hid/s3c24xx_ts/Makefile
===================================================================
--- uspace/srv/hid/s3c24xx_ts/Makefile	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
+++ uspace/srv/hid/s3c24xx_ts/Makefile	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -0,0 +1,37 @@
+#
+# Copyright (c) 2010 Jiri Svoboda
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# - Redistributions of source code must retain the above copyright
+#   notice, this list of conditions and the following disclaimer.
+# - Redistributions in binary form must reproduce the above copyright
+#   notice, this list of conditions and the following disclaimer in the
+#   documentation and/or other materials provided with the distribution.
+# - The name of the author may not be used to endorse or promote products
+#   derived from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+
+USPACE_PREFIX = ../../..
+
+# Need to use short name because of FAT 8+3 limit
+BINARY = s3c24ts
+
+SOURCES = \
+	s3c24xx_ts.c
+
+include $(USPACE_PREFIX)/Makefile.common
Index: uspace/srv/hid/s3c24xx_ts/s3c24xx_ts.c
===================================================================
--- uspace/srv/hid/s3c24xx_ts/s3c24xx_ts.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
+++ uspace/srv/hid/s3c24xx_ts/s3c24xx_ts.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -0,0 +1,408 @@
+/*
+ * Copyright (c) 2010 Jiri Svoboda
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup mouse
+ * @{
+ */
+/**
+ * @file
+ * @brief Samsung Samsung S3C24xx on-chip ADC and touch-screen interface driver.
+ *
+ * This interface is present on the Samsung S3C24xx CPU (on the gta02 platform).
+ */
+
+#include <ddi.h>
+#include <libarch/ddi.h>
+#include <devmap.h>
+#include <io/console.h>
+#include <vfs/vfs.h>
+#include <ipc/ipc.h>
+#include <ipc/mouse.h>
+#include <async.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sysinfo.h>
+#include <errno.h>
+
+#include "s3c24xx_ts.h"
+
+#define NAME "s3c24ser"
+#define NAMESPACE "hid_in"
+
+static irq_cmd_t ts_irq_cmds[] = {
+	{
+		.cmd = CMD_ACCEPT
+	}
+};
+
+static irq_code_t ts_irq_code = {
+	sizeof(ts_irq_cmds) / sizeof(irq_cmd_t),
+	ts_irq_cmds
+};
+
+/** S3C24xx touchscreen instance structure */
+static s3c24xx_ts_t *ts;
+
+static void s3c24xx_ts_connection(ipc_callid_t iid, ipc_call_t *icall);
+static void s3c24xx_ts_irq_handler(ipc_callid_t iid, ipc_call_t *call);
+static void s3c24xx_ts_pen_down(s3c24xx_ts_t *ts);
+static void s3c24xx_ts_pen_up(s3c24xx_ts_t *ts);
+static void s3c24xx_ts_eoc(s3c24xx_ts_t *ts);
+static int s3c24xx_ts_init(s3c24xx_ts_t *ts);
+static void s3c24xx_ts_wait_for_int_mode(s3c24xx_ts_t *ts, ts_updn_t updn);
+static void s3c24xx_ts_convert_samples(int smp0, int smp1, int *x, int *y);
+static int lin_map_range(int v, int i0, int i1, int o0, int o1);
+
+int main(int argc, char *argv[])
+{
+	int rc;
+
+	printf(NAME ": S3C24xx touchscreen driver\n");
+
+	rc = devmap_driver_register(NAME, s3c24xx_ts_connection);
+	if (rc < 0) {
+		printf(NAME ": Unable to register driver.\n");
+		return -1;
+	}
+
+	ts = malloc(sizeof(s3c24xx_ts_t));
+	if (ts == NULL)
+		return -1;
+
+	if (s3c24xx_ts_init(ts) != EOK)
+		return -1;
+
+	rc = devmap_device_register(NAMESPACE "/mouse", &ts->dev_handle);
+	if (rc != EOK) {
+		devmap_hangup_phone(DEVMAP_DRIVER);
+		printf(NAME ": Unable to register device %s.\n",
+		    NAMESPACE "/mouse");
+		return -1;
+	}
+
+	printf(NAME ": Registered device %s.\n", NAMESPACE "/mouse");
+
+	printf(NAME ": Accepting connections\n");
+	task_retval(0);
+	async_manager();
+
+	/* Not reached */
+	return 0;
+}
+
+/** Initialize S3C24xx touchscreen interface. */
+static int s3c24xx_ts_init(s3c24xx_ts_t *ts)
+{
+	void *vaddr;
+	sysarg_t inr;
+
+	inr = S3C24XX_TS_INR;
+	ts->paddr = S3C24XX_TS_ADDR;
+
+	if (pio_enable((void *) ts->paddr, sizeof(s3c24xx_adc_io_t),
+	    &vaddr) != 0)
+		return -1;
+
+	ts->io = vaddr;
+	ts->client_phone = -1;
+	ts->state = ts_wait_pendown;
+	ts->last_x = 0;
+	ts->last_y = 0;
+
+	printf(NAME ": device at physical address 0x%x, inr %d.\n",
+	    ts->paddr, inr);
+
+	async_set_interrupt_received(s3c24xx_ts_irq_handler);
+	ipc_register_irq(inr, device_assign_devno(), 0, &ts_irq_code);
+
+	s3c24xx_ts_wait_for_int_mode(ts, updn_down);
+
+	return EOK;
+}
+
+/** Switch interface to wait for interrupt mode.
+ *
+ * In this mode we receive an interrupt when pen goes up/down, depending
+ * on @a updn.
+ *
+ * @param ts	Touchscreen instance
+ * @param updn	@c updn_up to wait for pen up, @c updn_down to wait for pen
+ *		down.
+ */
+static void s3c24xx_ts_wait_for_int_mode(s3c24xx_ts_t *ts, ts_updn_t updn)
+{
+	uint32_t con, tsc;
+
+	/*
+	 * Configure ADCCON register
+	 */
+
+	con = pio_read_32(&ts->io->con);
+
+	/* Disable standby, disable start-by-read, clear manual start bit */
+	con = con & ~(ADCCON_STDBM | ADCCON_READ_START | ADCCON_ENABLE_START);
+
+	/* Set prescaler value 0xff, XP for input. */
+	con = con | (ADCCON_PRSCVL(0xff) << 6) | ADCCON_SEL_MUX(SMUX_XP);
+
+	/* Enable prescaler. */
+	con = con | ADCCON_PRSCEN;
+
+ 	pio_write_32(&ts->io->con, con);
+
+	/*
+	 * Configure ADCTSC register
+	 */
+
+	tsc = pio_read_32(&ts->io->tsc);
+
+	/* Select whether waiting for pen up or pen down. */
+	if (updn == updn_up)
+		tsc |= ADCTSC_DSUD_UP;
+	else
+		tsc &= ~ADCTSC_DSUD_UP;
+
+	/*
+	 * Enable XP pull-up and disable all drivers except YM. This is
+	 * according to the manual. This gives us L on XP input when touching
+	 * and (pulled up to) H when not touching.
+	 */
+	tsc = tsc & ~(ADCTSC_XM_ENABLE | ADCTSC_AUTO_PST |
+	    ADCTSC_PULLUP_DISABLE);
+	tsc = tsc | ADCTSC_YP_DISABLE | ADCTSC_XP_DISABLE | ADCTSC_YM_ENABLE;
+
+	/* Select wait-for-interrupt mode. */
+	tsc = (tsc & ~ADCTSC_XY_PST_MASK) | ADCTSC_XY_PST_WAITINT;
+
+	pio_write_32(&ts->io->tsc, tsc);
+}
+
+/** Handle touchscreen interrupt */
+static void s3c24xx_ts_irq_handler(ipc_callid_t iid, ipc_call_t *call)
+{
+	ts_updn_t updn;
+
+	(void) iid; (void) call;
+
+	/* Read up/down interrupt flags. */
+	updn = pio_read_32(&ts->io->updn);
+
+	if (updn & (ADCUPDN_TSC_DN | ADCUPDN_TSC_UP)) {
+		/* Clear up/down interrupt flags. */
+		pio_write_32(&ts->io->updn, updn &
+		    ~(ADCUPDN_TSC_DN | ADCUPDN_TSC_UP));
+	}
+
+	if (updn & ADCUPDN_TSC_DN) {
+		/* Pen-down interrupt */
+		s3c24xx_ts_pen_down(ts);
+	} else if (updn & ADCUPDN_TSC_UP) {
+		/* Pen-up interrupt */
+		s3c24xx_ts_pen_up(ts);
+	} else {
+		/* Presumably end-of-conversion interrupt */
+
+		/* Check end-of-conversion flag. */
+		if ((pio_read_32(&ts->io->con) & ADCCON_ECFLG) == 0) {
+			printf(NAME ": Unrecognized ts int.\n");
+			return;
+		}
+
+		if (ts->state != ts_sample_pos) {
+			/*
+			 * We got an extra interrupt ater switching to
+			 * wait for interrupt mode.
+			 */
+			return;
+		}
+
+		/* End-of-conversion interrupt */
+		s3c24xx_ts_eoc(ts);
+	}
+}
+
+/** Handle pen-down interrupt.
+ *
+ * @param ts	Touchscreen instance
+ */
+static void s3c24xx_ts_pen_down(s3c24xx_ts_t *ts)
+{
+	/* Pen-down interrupt */
+
+	ts->state = ts_sample_pos;
+
+	/* Enable auto xy-conversion mode */
+	pio_write_32(&ts->io->tsc, (pio_read_32(&ts->io->tsc)
+	    & ~3) | 4);
+
+	/* Start the conversion. */
+	pio_write_32(&ts->io->con, pio_read_32(&ts->io->con)
+	    | ADCCON_ENABLE_START);
+}
+
+/** Handle pen-up interrupt.
+ *
+ * @param ts	Touchscreen instance
+ */
+static void s3c24xx_ts_pen_up(s3c24xx_ts_t *ts)
+{
+	int button, press;
+
+	/* Pen-up interrupt */
+
+	ts->state = ts_wait_pendown;
+
+	button = 1;
+	press = 0;
+	async_msg_2(ts->client_phone, MEVENT_BUTTON, button, press);
+
+	s3c24xx_ts_wait_for_int_mode(ts, updn_down);
+}
+
+/** Handle end-of-conversion interrupt.
+ *
+ * @param ts	Touchscreen instance
+ */
+static void s3c24xx_ts_eoc(s3c24xx_ts_t *ts)
+{
+	uint32_t data;
+	int button, press;
+	int smp0, smp1;
+	int x_pos, y_pos;
+	int dx, dy;
+
+	ts->state = ts_wait_penup;
+
+	/* Read in sampled data. */
+
+	data = pio_read_32(&ts->io->dat0);
+	smp0 = data & 0x3ff;
+
+	data = pio_read_32(&ts->io->dat1);
+	smp1 = data & 0x3ff;
+
+	/* Convert to screen coordinates. */
+	s3c24xx_ts_convert_samples(smp0, smp1, &x_pos, &y_pos);
+
+	printf("s0: 0x%03x, s1:0x%03x -> x:%d,y:%d\n", smp0, smp1,
+	    x_pos, y_pos);
+
+	/* Get differences. */
+	dx = x_pos - ts->last_x;
+	dy = y_pos - ts->last_y;
+
+	button = 1;
+	press = 1;
+
+	/* Send notifications to client. */
+	async_msg_2(ts->client_phone, MEVENT_MOVE, dx, dy);
+	async_msg_2(ts->client_phone, MEVENT_BUTTON, button, press);
+
+	ts->last_x = x_pos;
+	ts->last_y = y_pos;
+
+	s3c24xx_ts_wait_for_int_mode(ts, updn_up);
+}
+
+/** Convert sampled data to screen coordinates. */
+static void s3c24xx_ts_convert_samples(int smp0, int smp1, int *x, int *y)
+{
+	/*
+	 * The orientation and display dimensions are GTA02-specific and the
+	 * calibration values might even specific to the individual piece
+	 * of hardware.
+	 *
+	 * The calibration values can be obtained by touching corners
+	 * of the screen with the stylus and noting the sampled values.
+	 */
+	*x = lin_map_range(smp1, 0xa1, 0x396, 0, 479);
+	*y = lin_map_range(smp0, 0x69, 0x38a, 639, 0);
+}
+
+/** Map integer from one range to another range in a linear fashion.
+ *
+ * i0 < i1 is required. i0 is mapped to o0, i1 to o1. If o1 < o0, then the
+ * mapping will be descending. If v is outside of [i0, i1], it is clamped.
+ *
+ * @param v	Value to map.
+ * @param i0	Lower bound of input range.
+ * @param i1	Upper bound of input range.
+ * @param o0	First bound of output range.
+ * @param o1	Second bound of output range.
+ *
+ * @return	Mapped value ov, o0 <= ov <= o1.
+ */
+static int lin_map_range(int v, int i0, int i1, int o0, int o1)
+{
+	if (v < i0)
+		v = i0;
+
+	if (v > i1)
+		v = i1;
+
+	return o0 + (o1 - o0) * (v - i0) / (i1 - i0);
+}
+
+/** Handle mouse client connection. */
+static void s3c24xx_ts_connection(ipc_callid_t iid, ipc_call_t *icall)
+{
+	ipc_callid_t callid;
+	ipc_call_t call;
+	int retval;
+
+	ipc_answer_0(iid, EOK);
+
+	while (1) {
+		callid = async_get_call(&call);
+		switch (IPC_GET_METHOD(call)) {
+		case IPC_M_PHONE_HUNGUP:
+			if (ts->client_phone != -1) {
+				ipc_hangup(ts->client_phone);
+				ts->client_phone = -1;
+			}
+
+			ipc_answer_0(callid, EOK);
+			return;
+		case IPC_M_CONNECT_TO_ME:
+			if (ts->client_phone != -1) {
+				retval = ELIMIT;
+				break;
+			}
+			ts->client_phone = IPC_GET_ARG5(call);
+			retval = 0;
+			break;
+		default:
+			retval = EINVAL;
+		}
+		ipc_answer_0(callid, retval);
+	}
+}
+
+/** @}
+ */
Index: uspace/srv/hid/s3c24xx_ts/s3c24xx_ts.h
===================================================================
--- uspace/srv/hid/s3c24xx_ts/s3c24xx_ts.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
+++ uspace/srv/hid/s3c24xx_ts/s3c24xx_ts.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -0,0 +1,140 @@
+/*
+ * 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
+ * @brief Samsung S3C24xx on-chip ADC and touch-screen interface driver.
+ */
+
+#ifndef S3C24XX_TS_H_
+#define S3C24XX_TS_H_
+
+#include <sys/types.h>
+
+/** S3C24xx ADC and touch-screen I/O */
+typedef struct {
+	uint32_t con;
+	uint32_t tsc;
+	uint32_t dly;
+	uint32_t dat0;
+	uint32_t dat1;
+	uint32_t updn;
+} s3c24xx_adc_io_t;
+
+/* Fields in ADCCON register */
+#define ADCCON_ECFLG		0x8000
+#define ADCCON_PRSCEN		0x4000
+
+#define ADCCON_PRSCVL(val)	(((val) & 0xff) << 6)
+
+#define ADCCON_SEL_MUX(smux)	(((smux) & 7) << 3)
+
+#define ADCCON_STDBM		0x0004
+#define ADCCON_READ_START	0x0002
+#define ADCCON_ENABLE_START	0x0001
+
+/* Values for ADCCON_SEL_MUX */
+#define SMUX_AIN0		0
+#define SMUX_AIN1		1
+#define SMUX_AIN2		2
+#define SMUX_AIN3		3
+#define SMUX_YM			4
+#define SMUX_YP			5
+#define SMUX_XM			6
+#define SMUX_XP			7
+
+
+/* Fields in ADCTSC register */
+#define ADCTSC_DSUD_UP		0x0100
+#define ADCTSC_YM_ENABLE	0x0080
+#define ADCTSC_YP_DISABLE	0x0040
+#define ADCTSC_XM_ENABLE	0x0020
+#define ADCTSC_XP_DISABLE	0x0010
+#define ADCTSC_PULLUP_DISABLE	0x0008
+#define ADCTSC_AUTO_PST		0x0004
+
+#define ADCTSC_XY_PST_NOOP	0x0000
+#define ADCTSC_XY_PST_X		0x0001
+#define ADCTSC_XY_PST_Y		0x0002
+#define ADCTSC_XY_PST_WAITINT	0x0003
+#define ADCTSC_XY_PST_MASK	0x0003
+
+/* Fields in ADCDAT0, ADCDAT1 registers */
+#define ADCDAT_UPDOWN		0x8000
+#define ADCDAT_AUTO_PST		0x4000
+
+/* Fields in ADCUPDN register */
+#define ADCUPDN_TSC_UP		0x0002
+#define ADCUPDN_TSC_DN		0x0001
+
+/** Touchscreen interrupt number */
+#define S3C24XX_TS_INR		31
+
+/** Touchscreen I/O address */
+#define S3C24XX_TS_ADDR		0x58000000
+
+typedef enum {
+	ts_wait_pendown,
+	ts_sample_pos,
+	ts_wait_penup
+} ts_state_t;
+
+typedef enum {
+	updn_up,
+	updn_down
+} ts_updn_t;
+
+/** S3C24xx touchscreen driver instance */
+typedef struct {
+	/** Physical device address */
+	uintptr_t paddr;
+
+	/** Device I/O structure */
+	s3c24xx_adc_io_t *io;
+
+	/** Callback phone to the client */
+	int client_phone;
+
+	/** Device handle */
+	dev_handle_t dev_handle;
+
+	/** Device/driver state */
+	ts_state_t state;
+
+	/** Previous position reported to client. */
+	int last_x;
+	int last_y;
+} s3c24xx_ts_t;
+
+#endif
+
+/** @}
+ */
Index: pace/srv/hw/bus/pci/Makefile.build
===================================================================
--- uspace/srv/hw/bus/pci/Makefile.build	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ 	(revision )
@@ -1,61 +1,0 @@
-#
-# Copyright (c) 2005 Martin Decky
-# Copyright (c) 2007 Jakub Jermar
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions
-# are met:
-#
-# - Redistributions of source code must retain the above copyright
-#   notice, this list of conditions and the following disclaimer.
-# - Redistributions in binary form must reproduce the above copyright
-#   notice, this list of conditions and the following disclaimer in the
-#   documentation and/or other materials provided with the distribution.
-# - The name of the author may not be used to endorse or promote products
-#   derived from this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
-# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
-# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
-# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
-# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
-# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-#
-
-## Setup toolchain
-#
-
-include Makefile.common
-include $(LIBC_PREFIX)/Makefile.toolchain
-
-## Sources
-#
-
-SOURCES = \
-	pci.c
-
-OBJECTS := $(addsuffix .o,$(basename $(SOURCES)))
-
-.PHONY: all
-
-all: $(OUTPUT) $(OUTPUT).disasm
-
--include $(DEPEND)
-
-$(OUTPUT).disasm: $(OUTPUT)
-	$(OBJDUMP) -d $< > $@
-
-$(OUTPUT): $(OBJECTS) $(LIBS)
-	$(LD) -T $(LIBC_PREFIX)/arch/$(UARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map
-
-%.o: %.c $(DEPEND)
-	$(CC) $(DEFS) $(CFLAGS) -c $< -o $@
-
-$(DEPEND):
-	makedepend -f - -- $(DEPEND_DEFS) $(CFLAGS) -- $(SOURCES) > $@ 2> /dev/null
-	-[ -f $(DEPEND_PREV) ] && diff -q $(DEPEND_PREV) $@ && mv -f $(DEPEND_PREV) $@
Index: pace/srv/hw/bus/pci/Makefile.common
===================================================================
--- uspace/srv/hw/bus/pci/Makefile.common	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ 	(revision )
@@ -1,40 +1,0 @@
-#
-# Copyright (c) 2005 Martin Decky
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions
-# are met:
-#
-# - Redistributions of source code must retain the above copyright
-#   notice, this list of conditions and the following disclaimer.
-# - Redistributions in binary form must reproduce the above copyright
-#   notice, this list of conditions and the following disclaimer in the
-#   documentation and/or other materials provided with the distribution.
-# - The name of the author may not be used to endorse or promote products
-#   derived from this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
-# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
-# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
-# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
-# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
-# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-#
-
-
-## Common names
-#
-
-LIBC_PREFIX = ../../lib/libc
-SOFTINT_PREFIX = ../../lib/softint
-LIBPCI = libpci/libpci.a
-LIBS = $(LIBPCI) $(LIBC_PREFIX)/libc.a
-
-DEPEND = Makefile.depend
-DEPEND_PREV = $(DEPEND).prev
-OUTPUT = pci
Index: uspace/srv/hw/char/s3c24xx_uart/Makefile
===================================================================
--- uspace/srv/hw/char/s3c24xx_uart/Makefile	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
+++ uspace/srv/hw/char/s3c24xx_uart/Makefile	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -0,0 +1,38 @@
+#
+# Copyright (c) 2005 Martin Decky
+# Copyright (c) 2007 Jakub Jermar
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# - Redistributions of source code must retain the above copyright
+#   notice, this list of conditions and the following disclaimer.
+# - Redistributions in binary form must reproduce the above copyright
+#   notice, this list of conditions and the following disclaimer in the
+#   documentation and/or other materials provided with the distribution.
+# - The name of the author may not be used to endorse or promote products
+#   derived from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+
+USPACE_PREFIX = ../../../..
+
+# Need to use short name because of FAT 8+3 limit
+BINARY = s3c24ser
+
+SOURCES = \
+	s3c24xx_uart.c
+
+include $(USPACE_PREFIX)/Makefile.common
Index: uspace/srv/hw/char/s3c24xx_uart/s3c24xx_uart.c
===================================================================
--- uspace/srv/hw/char/s3c24xx_uart/s3c24xx_uart.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
+++ uspace/srv/hw/char/s3c24xx_uart/s3c24xx_uart.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -0,0 +1,216 @@
+/*
+ * 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 driver_serial
+ * @{
+ */
+/**
+ * @file
+ * @brief Samsung S3C24xx on-chip UART driver.
+ *
+ * This UART is present on the Samsung S3C24xx CPU (on the gta02 platform).
+ */
+
+#include <ddi.h>
+#include <libarch/ddi.h>
+#include <devmap.h>
+#include <ipc/ipc.h>
+#include <ipc/char.h>
+#include <async.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sysinfo.h>
+#include <errno.h>
+
+#include "s3c24xx_uart.h"
+
+#define NAME "s3c24ser"
+#define NAMESPACE "char"
+
+static irq_cmd_t uart_irq_cmds[] = {
+	{
+		.cmd = CMD_ACCEPT
+	}
+};
+
+static irq_code_t uart_irq_code = {
+	sizeof(uart_irq_cmds) / sizeof(irq_cmd_t),
+	uart_irq_cmds
+};
+
+/** S3C24xx UART instance structure */
+static s3c24xx_uart_t *uart;
+
+static void s3c24xx_uart_connection(ipc_callid_t iid, ipc_call_t *icall);
+static void s3c24xx_uart_irq_handler(ipc_callid_t iid, ipc_call_t *call);
+static int s3c24xx_uart_init(s3c24xx_uart_t *uart);
+static void s3c24xx_uart_sendb(s3c24xx_uart_t *uart, uint8_t byte);
+
+int main(int argc, char *argv[])
+{
+	int rc;
+
+	printf(NAME ": S3C24xx on-chip UART driver\n");
+
+	rc = devmap_driver_register(NAME, s3c24xx_uart_connection);
+	if (rc < 0) {
+		printf(NAME ": Unable to register driver.\n");
+		return -1;
+	}
+
+	uart = malloc(sizeof(s3c24xx_uart_t));
+	if (uart == NULL)
+		return -1;
+
+	if (s3c24xx_uart_init(uart) != EOK)
+		return -1;
+
+	rc = devmap_device_register(NAMESPACE "/" NAME, &uart->dev_handle);
+	if (rc != EOK) {
+		devmap_hangup_phone(DEVMAP_DRIVER);
+		printf(NAME ": Unable to register device %s.\n");
+		return -1;
+	}
+
+	printf(NAME ": Registered device %s.\n", NAMESPACE "/" NAME);
+
+	printf(NAME ": Accepting connections\n");
+	task_retval(0);
+	async_manager();
+
+	/* Not reached */
+	return 0;
+}
+
+/** Character device connection handler. */
+static void s3c24xx_uart_connection(ipc_callid_t iid, ipc_call_t *icall)
+{
+	ipc_callid_t callid;
+	ipc_call_t call;
+	ipcarg_t method;
+	int retval;
+
+	/* Answer the IPC_M_CONNECT_ME_TO call. */
+	ipc_answer_0(iid, EOK);
+
+	while (1) {
+		callid = async_get_call(&call);
+		method = IPC_GET_METHOD(call);
+		switch (method) {
+		case IPC_M_PHONE_HUNGUP:
+			/* The other side has hung up. */
+			ipc_answer_0(callid, EOK);
+			return;
+		case IPC_M_CONNECT_TO_ME:
+			printf(NAME ": creating callback connection\n");
+			uart->client_phone = IPC_GET_ARG5(call);
+			retval = 0;
+			break;
+		case CHAR_WRITE_BYTE:
+			printf(NAME ": write %d to device\n",
+			    IPC_GET_ARG1(call));
+			s3c24xx_uart_sendb(uart, (uint8_t) IPC_GET_ARG1(call));
+			retval = 0;
+			break;
+		default:
+			retval = EINVAL;
+			break;
+		}
+		ipc_answer_0(callid, retval);
+	}
+}
+
+static void s3c24xx_uart_irq_handler(ipc_callid_t iid, ipc_call_t *call)
+{
+	(void) iid; (void) call;
+
+	while ((pio_read_32(&uart->io->ufstat) & S3C24XX_UFSTAT_RX_COUNT) != 0) {
+		uint32_t data = pio_read_32(&uart->io->urxh) & 0xff;
+		uint32_t status = pio_read_32(&uart->io->uerstat);
+
+		if (uart->client_phone != -1) {
+			async_msg_1(uart->client_phone, CHAR_NOTIF_BYTE,
+			    data);
+		}
+
+		if (status != 0)
+			printf(NAME ": Error status 0x%x\n", status);
+	}
+}
+
+/** Initialize S3C24xx on-chip UART. */
+static int s3c24xx_uart_init(s3c24xx_uart_t *uart)
+{
+	void *vaddr;
+	sysarg_t inr;
+
+	if (sysinfo_get_value("s3c24xx_uart.address.physical",
+	    &uart->paddr) != EOK)
+		return -1;
+
+	if (pio_enable((void *) uart->paddr, sizeof(s3c24xx_uart_io_t),
+	    &vaddr) != 0)
+		return -1;
+
+	if (sysinfo_get_value("s3c24xx_uart.inr", &inr) != EOK)
+		return -1;
+
+	uart->io = vaddr;
+	uart->client_phone = -1;
+
+	printf(NAME ": device at physical address 0x%x, inr %d.\n",
+	    uart->paddr, inr);
+
+	async_set_interrupt_received(s3c24xx_uart_irq_handler);
+
+	ipc_register_irq(inr, device_assign_devno(), 0, &uart_irq_code);
+
+	/* Enable FIFO, Tx trigger level: empty, Rx trigger level: 1 byte. */
+	pio_write_32(&uart->io->ufcon, UFCON_FIFO_ENABLE |
+	    UFCON_TX_FIFO_TLEVEL_EMPTY | UFCON_RX_FIFO_TLEVEL_1B);
+
+	/* Set RX interrupt to pulse mode */
+	pio_write_32(&uart->io->ucon,
+	    pio_read_32(&uart->io->ucon) & ~UCON_RX_INT_LEVEL);
+
+	return EOK;
+}
+
+/** Send a byte to the UART. */
+static void s3c24xx_uart_sendb(s3c24xx_uart_t *uart, uint8_t byte)
+{
+	/* Wait for space becoming available in Tx FIFO. */
+	while ((pio_read_32(&uart->io->ufstat) & S3C24XX_UFSTAT_TX_FULL) != 0)
+		;
+
+	pio_write_32(&uart->io->utxh, byte);
+}
+
+/** @}
+ */
Index: uspace/srv/hw/char/s3c24xx_uart/s3c24xx_uart.h
===================================================================
--- uspace/srv/hw/char/s3c24xx_uart/s3c24xx_uart.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
+++ uspace/srv/hw/char/s3c24xx_uart/s3c24xx_uart.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -0,0 +1,96 @@
+/*
+ * 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
+ * @brief Samsung S3C24xx on-chip UART driver.
+ */
+
+#ifndef S3C24XX_UART_H_
+#define S3C24XX_UART_H_
+
+#include <sys/types.h>
+
+/** S3C24xx UART I/O */
+typedef struct {
+	uint32_t ulcon;
+	uint32_t ucon;
+	uint32_t ufcon;
+	uint32_t umcon;
+
+	uint32_t utrstat;
+	uint32_t uerstat;
+	uint32_t ufstat;
+	uint32_t umstat;
+
+	uint32_t utxh;
+	uint32_t urxh;
+
+	uint32_t ubrdiv;
+} s3c24xx_uart_io_t;
+
+/* Bits in UTRSTAT register */
+#define S3C24XX_UTRSTAT_TX_EMPTY	0x4
+#define S3C24XX_UTRSTAT_RDATA		0x1
+
+/* Bits in UFSTAT register */
+#define S3C24XX_UFSTAT_TX_FULL		0x4000
+#define S3C24XX_UFSTAT_RX_FULL		0x0040
+#define S3C24XX_UFSTAT_RX_COUNT		0x002f
+
+/* Bits in UCON register */
+#define UCON_RX_INT_LEVEL		0x100
+
+/* Bits in UFCON register */
+#define UFCON_TX_FIFO_TLEVEL_EMPTY	0x00
+#define UFCON_RX_FIFO_TLEVEL_1B		0x00
+#define UFCON_FIFO_ENABLE		0x01
+
+
+/** S3C24xx UART instance */
+typedef struct {
+	/** Physical device address */
+	uintptr_t paddr;
+
+	/** Device I/O structure */
+	s3c24xx_uart_io_t *io;
+
+	/** Callback phone to the client */
+	int client_phone;
+
+	/** Device handle */
+	dev_handle_t dev_handle;
+} s3c24xx_uart_t;
+
+#endif
+
+/** @}
+ */
Index: pace/srv/hw/cir/fhc/Makefile.build
===================================================================
--- uspace/srv/hw/cir/fhc/Makefile.build	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ 	(revision )
@@ -1,61 +1,0 @@
-#
-# Copyright (c) 2005 Martin Decky
-# Copyright (c) 2007 Jakub Jermar
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions
-# are met:
-#
-# - Redistributions of source code must retain the above copyright
-#   notice, this list of conditions and the following disclaimer.
-# - Redistributions in binary form must reproduce the above copyright
-#   notice, this list of conditions and the following disclaimer in the
-#   documentation and/or other materials provided with the distribution.
-# - The name of the author may not be used to endorse or promote products
-#   derived from this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
-# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
-# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
-# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
-# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
-# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-#
-
-## Setup toolchain
-#
-
-include Makefile.common
-include $(LIBC_PREFIX)/Makefile.toolchain
-
-## Sources
-#
-
-SOURCES = \
-	fhc.c
-
-OBJECTS := $(addsuffix .o,$(basename $(SOURCES)))
-
-.PHONY: all
-
-all: $(OUTPUT) $(OUTPUT).disasm
-
--include $(DEPEND)
-
-$(OUTPUT).disasm: $(OUTPUT)
-	$(OBJDUMP) -d $< > $@
-
-$(OUTPUT): $(OBJECTS) $(LIBS)
-	$(LD) -T $(LIBC_PREFIX)/arch/$(UARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map
-
-%.o: %.c $(DEPEND)
-	$(CC) $(DEFS) $(CFLAGS) -c $< -o $@
-
-$(DEPEND):
-	makedepend -f - -- $(DEPEND_DEFS) $(CFLAGS) -- $(SOURCES) > $@ 2> /dev/null
-	-[ -f $(DEPEND_PREV) ] && diff -q $(DEPEND_PREV) $@ && mv -f $(DEPEND_PREV) $@
Index: pace/srv/hw/cir/fhc/Makefile.common
===================================================================
--- uspace/srv/hw/cir/fhc/Makefile.common	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ 	(revision )
@@ -1,39 +1,0 @@
-#
-# Copyright (c) 2005 Martin Decky
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions
-# are met:
-#
-# - Redistributions of source code must retain the above copyright
-#   notice, this list of conditions and the following disclaimer.
-# - Redistributions in binary form must reproduce the above copyright
-#   notice, this list of conditions and the following disclaimer in the
-#   documentation and/or other materials provided with the distribution.
-# - The name of the author may not be used to endorse or promote products
-#   derived from this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
-# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
-# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
-# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
-# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
-# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-#
-
-
-## Common names
-#
-
-LIBC_PREFIX = ../../../lib/libc
-SOFTINT_PREFIX = ../../../lib/softint
-LIBS = $(LIBC_PREFIX)/libc.a
-
-DEPEND = Makefile.depend
-DEPEND_PREV = $(DEPEND).prev
-OUTPUT = fhc
Index: pace/srv/hw/cir/obio/Makefile.build
===================================================================
--- uspace/srv/hw/cir/obio/Makefile.build	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ 	(revision )
@@ -1,61 +1,0 @@
-#
-# Copyright (c) 2005 Martin Decky
-# Copyright (c) 2007 Jakub Jermar
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions
-# are met:
-#
-# - Redistributions of source code must retain the above copyright
-#   notice, this list of conditions and the following disclaimer.
-# - Redistributions in binary form must reproduce the above copyright
-#   notice, this list of conditions and the following disclaimer in the
-#   documentation and/or other materials provided with the distribution.
-# - The name of the author may not be used to endorse or promote products
-#   derived from this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
-# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
-# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
-# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
-# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
-# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-#
-
-## Setup toolchain
-#
-
-include Makefile.common
-include $(LIBC_PREFIX)/Makefile.toolchain
-
-## Sources
-#
-
-SOURCES = \
-	obio.c
-
-OBJECTS := $(addsuffix .o,$(basename $(SOURCES)))
-
-.PHONY: all
-
-all: $(OUTPUT) $(OUTPUT).disasm
-
--include $(DEPEND)
-
-$(OUTPUT).disasm: $(OUTPUT)
-	$(OBJDUMP) -d $< > $@
-
-$(OUTPUT): $(OBJECTS) $(LIBS)
-	$(LD) -T $(LIBC_PREFIX)/arch/$(UARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map
-
-%.o: %.c $(DEPEND)
-	$(CC) $(DEFS) $(CFLAGS) -c $< -o $@
-
-$(DEPEND):
-	makedepend -f - -- $(DEPEND_DEFS) $(CFLAGS) -- $(SOURCES) > $@ 2> /dev/null
-	-[ -f $(DEPEND_PREV) ] && diff -q $(DEPEND_PREV) $@ && mv -f $(DEPEND_PREV) $@
Index: pace/srv/hw/cir/obio/Makefile.common
===================================================================
--- uspace/srv/hw/cir/obio/Makefile.common	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ 	(revision )
@@ -1,39 +1,0 @@
-#
-# Copyright (c) 2005 Martin Decky
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions
-# are met:
-#
-# - Redistributions of source code must retain the above copyright
-#   notice, this list of conditions and the following disclaimer.
-# - Redistributions in binary form must reproduce the above copyright
-#   notice, this list of conditions and the following disclaimer in the
-#   documentation and/or other materials provided with the distribution.
-# - The name of the author may not be used to endorse or promote products
-#   derived from this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
-# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
-# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
-# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
-# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
-# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-#
-
-
-## Common names
-#
-
-LIBC_PREFIX = ../../../lib/libc
-SOFTINT_PREFIX = ../../../lib/softint
-LIBS = $(LIBC_PREFIX)/libc.a
-
-DEPEND = Makefile.depend
-DEPEND_PREV = $(DEPEND).prev
-OUTPUT = obio
Index: uspace/srv/hw/netif/dp8390/Makefile
===================================================================
--- uspace/srv/hw/netif/dp8390/Makefile	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/srv/hw/netif/dp8390/Makefile	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -30,6 +30,6 @@
 USPACE_PREFIX = ../../../..
 ROOT_PATH = $(USPACE_PREFIX)/..
-LIBS = $(LIBNET_PREFIX)/libnet.a $(LIBSOCKET_PREFIX)/libsocket.a
-EXTRA_CFLAGS = -I$(LIBNET_PREFIX)/include -I$(LIBSOCKET_PREFIX)/include
+LIBS = $(LIBNET_PREFIX)/libnet.a
+EXTRA_CFLAGS = -I$(LIBNET_PREFIX)/include
 
 COMMON_MAKEFILE = $(ROOT_PATH)/Makefile.common
Index: uspace/srv/hw/netif/dp8390/dp8390.c
===================================================================
--- uspace/srv/hw/netif/dp8390/dp8390.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/srv/hw/netif/dp8390/dp8390.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -34,10 +34,10 @@
 
 #include <assert.h>
+#include <byteorder.h>
 #include <errno.h>
 
-#include <net_byteorder.h>
 #include <netif_local.h>
-#include <packet/packet.h>
-#include <packet/packet_client.h>
+#include <net/packet.h>
+#include <packet_client.h>
 
 #include "dp8390_drv.h"
Index: uspace/srv/hw/netif/dp8390/dp8390.h
===================================================================
--- uspace/srv/hw/netif/dp8390/dp8390.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/srv/hw/netif/dp8390/dp8390.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -36,5 +36,5 @@
 #define __NET_NETIF_DP8390_H__
 
-#include <packet/packet.h>
+#include <net/packet.h>
 
 #include "dp8390_port.h"
Index: uspace/srv/hw/netif/dp8390/dp8390_module.c
===================================================================
--- uspace/srv/hw/netif/dp8390/dp8390_module.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/srv/hw/netif/dp8390/dp8390_module.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -39,14 +39,13 @@
 #include <ddi.h>
 #include <errno.h>
+#include <err.h>
 #include <malloc.h>
 #include <ipc/ipc.h>
 #include <ipc/services.h>
 
-#include <net_err.h>
-#include <net_messages.h>
-#include <net_modules.h>
-#include <packet/packet_client.h>
+#include <net/modules.h>
+#include <packet_client.h>
 #include <adt/measured_strings.h>
-#include <net_device.h>
+#include <net/device.h>
 #include <nil_interface.h>
 #include <netif_interface.h>
Index: uspace/srv/net/il/arp/Makefile
===================================================================
--- uspace/srv/net/il/arp/Makefile	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/srv/net/il/arp/Makefile	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -29,6 +29,6 @@
 
 USPACE_PREFIX = ../../../..
-LIBS = $(LIBNET_PREFIX)/libnet.a $(LIBSOCKET_PREFIX)/libsocket.a
-EXTRA_CFLAGS = -I$(LIBNET_PREFIX)/include -I$(LIBSOCKET_PREFIX)/include
+LIBS = $(LIBNET_PREFIX)/libnet.a
+EXTRA_CFLAGS = -I$(LIBNET_PREFIX)/include
 BINARY = arp
 
Index: uspace/srv/net/il/arp/arp.c
===================================================================
--- uspace/srv/net/il/arp/arp.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/srv/net/il/arp/arp.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -45,21 +45,21 @@
 #include <ipc/ipc.h>
 #include <ipc/services.h>
-
-#include <net_err.h>
-#include <net_messages.h>
-#include <net_modules.h>
-#include <net_byteorder.h>
-#include <net_device.h>
+#include <ipc/net.h>
+#include <ipc/arp.h>
+#include <ipc/il.h>
+#include <byteorder.h>
+#include <err.h>
+
+#include <net/modules.h>
+#include <net/device.h>
 #include <arp_interface.h>
 #include <nil_interface.h>
 #include <protocol_map.h>
 #include <adt/measured_strings.h>
-#include <packet/packet.h>
-#include <packet/packet_client.h>
+#include <net/packet.h>
+#include <packet_client.h>
 #include <packet_remote.h>
-#include <il_messages.h>
 #include <il_interface.h>
 #include <il_local.h>
-#include <arp_messages.h>
 
 #include "arp.h"
@@ -227,11 +227,4 @@
 	printf("Device %d cleared\n", device_id);
 	fibril_rwlock_write_unlock(&arp_globals.lock);
-	return EOK;
-}
-
-int arp_connect_module(services_t service){
-	if(service != SERVICE_ARP){
-		return EINVAL;
-	}
 	return EOK;
 }
@@ -543,8 +536,4 @@
 }
 
-task_id_t arp_task_get_id(void){
-	return task_get_id();
-}
-
 measured_string_ref arp_translate_message(device_id_t device_id, services_t protocol, measured_string_ref target){
 	arp_device_ref device;
@@ -603,24 +592,4 @@
 	nil_send_msg(device->phone, device_id, packet, SERVICE_ARP);
 	return NULL;
-}
-
-int arp_translate_req(int arp_phone, device_id_t device_id, services_t protocol, measured_string_ref address, measured_string_ref * translation, char ** data){
-	measured_string_ref tmp;
-
-	fibril_rwlock_read_lock(&arp_globals.lock);
-	tmp = arp_translate_message(device_id, protocol, address);
-	if(tmp){
-		*translation = measured_string_copy(tmp);
-		fibril_rwlock_read_unlock(&arp_globals.lock);
-		if(*translation){
-			*data = (** translation).value;
-			return EOK;
-		}else{
-			return ENOMEM;
-		}
-	}else{
-		fibril_rwlock_read_unlock(&arp_globals.lock);
-		return ENOENT;
-	}
 }
 
Index: uspace/srv/net/il/arp/arp.h
===================================================================
--- uspace/srv/net/il/arp/arp.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/srv/net/il/arp/arp.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -43,5 +43,5 @@
 #include <ipc/services.h>
 
-#include <net_device.h>
+#include <net/device.h>
 #include <net_hardware.h>
 #include <adt/generic_char_map.h>
Index: uspace/srv/net/il/arp/arp_module.c
===================================================================
--- uspace/srv/net/il/arp/arp_module.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/srv/net/il/arp/arp_module.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -40,12 +40,12 @@
 #include <async.h>
 #include <stdio.h>
+#include <err.h>
 
 #include <ipc/ipc.h>
 #include <ipc/services.h>
 
-#include <net_err.h>
-#include <net_modules.h>
+#include <net/modules.h>
 #include <net_interface.h>
-#include <packet/packet.h>
+#include <net/packet.h>
 #include <il_local.h>
 
@@ -80,5 +80,5 @@
 	
 	async_set_client_connection(client_connection);
-	arp_globals.net_phone = net_connect_module(SERVICE_NETWORKING);
+	arp_globals.net_phone = net_connect_module();
 	ERROR_PROPAGATE(pm_init());
 	
Index: uspace/srv/net/il/ip/Makefile
===================================================================
--- uspace/srv/net/il/ip/Makefile	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/srv/net/il/ip/Makefile	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -29,6 +29,6 @@
 
 USPACE_PREFIX = ../../../..
-LIBS = $(LIBNET_PREFIX)/libnet.a $(LIBSOCKET_PREFIX)/libsocket.a
-EXTRA_CFLAGS = -I$(LIBNET_PREFIX)/include -I$(LIBSOCKET_PREFIX)/include
+LIBS = $(LIBNET_PREFIX)/libnet.a
+EXTRA_CFLAGS = -I$(LIBNET_PREFIX)/include
 BINARY = ip
 
Index: uspace/srv/net/il/ip/ip.c
===================================================================
--- uspace/srv/net/il/ip/ip.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/srv/net/il/ip/ip.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -38,4 +38,5 @@
 #include <async.h>
 #include <errno.h>
+#include <err.h>
 #include <fibril_synch.h>
 #include <stdio.h>
@@ -43,20 +44,25 @@
 #include <ipc/ipc.h>
 #include <ipc/services.h>
+#include <ipc/net.h>
+#include <ipc/nil.h>
+#include <ipc/il.h>
+#include <ipc/ip.h>
 #include <sys/types.h>
-
-#include <net_err.h>
-#include <net_messages.h>
-#include <net_modules.h>
+#include <byteorder.h>
+
+#include <net/socket_codes.h>
+#include <net/in.h>
+#include <net/in6.h>
+#include <net/inet.h>
+#include <net/modules.h>
+#include <net/device.h>
+#include <net/packet.h>
+#include <net/icmp_codes.h>
+
 #include <arp_interface.h>
-#include <net_byteorder.h>
 #include <net_checksum.h>
-#include <net_device.h>
 #include <icmp_client.h>
-#include <icmp_codes.h>
 #include <icmp_interface.h>
 #include <il_interface.h>
-#include <in.h>
-#include <in6.h>
-#include <inet.h>
 #include <ip_client.h>
 #include <ip_interface.h>
@@ -64,19 +70,14 @@
 #include <nil_interface.h>
 #include <tl_interface.h>
-#include <socket_codes.h>
-#include <socket_errno.h>
 #include <adt/measured_strings.h>
 #include <adt/module_map.h>
-#include <packet/packet_client.h>
+#include <packet_client.h>
 #include <packet_remote.h>
-#include <nil_messages.h>
-#include <il_messages.h>
 #include <il_local.h>
-#include <ip_local.h>
 
 #include "ip.h"
 #include "ip_header.h"
-#include "ip_messages.h"
 #include "ip_module.h"
+#include "ip_local.h"
 
 /** IP module name.
@@ -422,5 +423,5 @@
 	ip_globals.client_connection = client_connection;
 	ERROR_PROPAGATE(modules_initialize(&ip_globals.modules));
-	ERROR_PROPAGATE(add_module(NULL, &ip_globals.modules, ARP_NAME, ARP_FILENAME, SERVICE_ARP, arp_task_get_id(), arp_connect_module));
+	ERROR_PROPAGATE(add_module(NULL, &ip_globals.modules, ARP_NAME, ARP_FILENAME, SERVICE_ARP, 0, arp_connect_module));
 	fibril_rwlock_write_unlock(&ip_globals.lock);
 	return EOK;
@@ -619,12 +620,4 @@
 	fibril_rwlock_write_unlock(&ip_globals.netifs_lock);
 	return EOK;
-}
-
-int ip_connect_module(services_t service){
-	return EOK;
-}
-
-int ip_bind_service(services_t service, int protocol, services_t me, async_client_conn_t receiver, tl_received_msg_t received_msg){
-	return ip_register(protocol, me, 0, received_msg);
 }
 
Index: uspace/srv/net/il/ip/ip.h
===================================================================
--- uspace/srv/net/il/ip/ip.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/srv/net/il/ip/ip.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -42,6 +42,6 @@
 #include <ipc/services.h>
 
-#include <net_device.h>
-#include <inet.h>
+#include <net/device.h>
+#include <net/inet.h>
 #include <ip_interface.h>
 #include <adt/int_map.h>
Index: uspace/srv/net/il/ip/ip_local.h
===================================================================
--- uspace/srv/net/il/ip/ip_local.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
+++ uspace/srv/net/il/ip/ip_local.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2009 Lukas Mejdrech
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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 ip
+ * @{
+ */
+
+#ifndef NET_IP_LOCAL_H_
+#define NET_IP_LOCAL_H_
+
+#include <async.h>
+#include <ipc/services.h>
+
+#include <net/ip_codes.h>
+#include <net/inet.h>
+#include <net/in.h>
+
+extern int ip_received_error_msg_local(int, device_id_t, packet_t, services_t,
+    services_t);
+extern int ip_set_gateway_req_local(int, device_id_t, in_addr_t);
+extern int ip_packet_size_req_local(int, device_id_t, packet_dimension_ref);
+extern int ip_received_error_msg_local(int, device_id_t, packet_t, services_t,
+    services_t);
+extern int ip_device_req_local(int, device_id_t, services_t);
+extern int ip_add_route_req_local(int, device_id_t, in_addr_t, in_addr_t,
+    in_addr_t);
+extern int ip_send_msg_local(int, device_id_t, packet_t, services_t,
+    services_t);
+extern int ip_get_route_req_local(int, ip_protocol_t, const struct sockaddr *,
+    socklen_t, device_id_t *, void **, size_t *);
+
+#endif
+
+/** @}
+ */
Index: uspace/srv/net/il/ip/ip_module.c
===================================================================
--- uspace/srv/net/il/ip/ip_module.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/srv/net/il/ip/ip_module.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -42,9 +42,9 @@
 #include <ipc/ipc.h>
 #include <ipc/services.h>
+#include <err.h>
 
-#include <net_err.h>
-#include <net_modules.h>
+#include <net/modules.h>
 #include <net_interface.h>
-#include <packet/packet.h>
+#include <net/packet.h>
 #include <il_local.h>
 
@@ -79,5 +79,5 @@
 	
 	async_set_client_connection(client_connection);
-	ip_globals.net_phone = net_connect_module(SERVICE_NETWORKING);
+	ip_globals.net_phone = net_connect_module();
 	ERROR_PROPAGATE(pm_init());
 	
Index: uspace/srv/net/net/Makefile
===================================================================
--- uspace/srv/net/net/Makefile	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/srv/net/net/Makefile	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -30,6 +30,6 @@
 USPACE_PREFIX = ../../..
 ROOT_PATH = $(USPACE_PREFIX)/..
-LIBS = $(LIBNET_PREFIX)/libnet.a $(LIBSOCKET_PREFIX)/libsocket.a
-EXTRA_CFLAGS = -I$(LIBNET_PREFIX)/include -I$(LIBSOCKET_PREFIX)/include
+LIBS = $(LIBNET_PREFIX)/libnet.a $(LIBPACKET_PREFIX)/libpacket.a
+EXTRA_CFLAGS = -I$(LIBNET_PREFIX)/include -I$(LIBPACKET_PREFIX)/include
 
 COMMON_MAKEFILE = $(ROOT_PATH)/Makefile.common
Index: uspace/srv/net/net/net.c
===================================================================
--- uspace/srv/net/net/net.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/srv/net/net/net.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -40,4 +40,5 @@
 #include <ddi.h>
 #include <errno.h>
+#include <err.h>
 #include <malloc.h>
 #include <stdio.h>
@@ -46,20 +47,19 @@
 #include <ipc/ipc.h>
 #include <ipc/services.h>
-
-#include <net_err.h>
-#include <net_messages.h>
-#include <net_modules.h>
+#include <ipc/net.h>
+#include <ipc/net_net.h>
+#include <ipc/il.h>
+
+#include <net/modules.h>
 #include <adt/char_map.h>
 #include <adt/generic_char_map.h>
 #include <adt/measured_strings.h>
 #include <adt/module_map.h>
-#include <packet/packet.h>
-#include <il_messages.h>
+#include <net/packet.h>
 #include <netif_remote.h>
-#include <net_device.h>
+#include <net/device.h>
 #include <nil_interface.h>
 #include <net_interface.h>
 #include <ip_interface.h>
-#include <net_net_messages.h>
 
 #include "net.h"
Index: uspace/srv/net/net/net.h
===================================================================
--- uspace/srv/net/net/net.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/srv/net/net/net.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -41,10 +41,10 @@
 #include <ipc/ipc.h>
 
-#include <net_device.h>
+#include <net/device.h>
 #include <adt/char_map.h>
 #include <adt/generic_char_map.h>
 #include <adt/measured_strings.h>
 #include <adt/module_map.h>
-#include <packet/packet.h>
+#include <net/packet.h>
 
 /** @name Modules definitions
Index: pace/srv/net/net/net_bundle.c
===================================================================
--- uspace/srv/net/net/net_bundle.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ 	(revision )
@@ -1,135 +1,0 @@
-/*
- * Copyright (c) 2009 Lukas Mejdrech
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (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 net
- *  @{
- */
-
-/** @file
- *  Wrapper for the bundled networking and TCP/IP stact modules.
- *  Distributes messages and initializes all module parts.
- */
-
-#include <str.h>
-
-#include <ipc/ipc.h>
-
-#include "../messages.h"
-
-#include "../include/ip_interface.h"
-
-#include "../structures/measured_strings.h"
-#include "../structures/module_map.h"
-#include "../structures/packet/packet_server.h"
-
-#include "../il/arp/arp_module.h"
-#include "../il/ip/ip_module.h"
-#include "../tl/icmp/icmp_module.h"
-#include "../tl/udp/udp_module.h"
-#include "../tl/tcp/tcp_module.h"
-
-#include "net.h"
-
-/** Networking module global data.
- */
-extern net_globals_t	net_globals;
-
-/** Initializes the networking module for the chosen subsystem build type.
- *  @param[in] client_connection The client connection processing function. The module skeleton propagates its own one.
- *  @returns EOK on success.
- *  @returns ENOMEM if there is not enough memory left.
- */
-int net_initialize_build(async_client_conn_t client_connection){
-	ERROR_DECLARE;
-
-	ipcarg_t phonehash;
-
-	ERROR_PROPAGATE(REGISTER_ME(SERVICE_IP, &phonehash));
-	ERROR_PROPAGATE(add_module(NULL, &net_globals.modules, IP_NAME, IP_FILENAME, SERVICE_IP, task_get_id(), ip_connect_module));
-	ERROR_PROPAGATE(ip_initialize(client_connection));
-	ERROR_PROPAGATE(REGISTER_ME(SERVICE_ARP, &phonehash));
-	ERROR_PROPAGATE(arp_initialize(client_connection));
-	ERROR_PROPAGATE(REGISTER_ME(SERVICE_ICMP, &phonehash));
-	ERROR_PROPAGATE(icmp_initialize(client_connection));
-	ERROR_PROPAGATE(REGISTER_ME(SERVICE_UDP, &phonehash));
-	ERROR_PROPAGATE(udp_initialize(client_connection));
-	ERROR_PROPAGATE(REGISTER_ME(SERVICE_TCP, &phonehash));
-	ERROR_PROPAGATE(tcp_initialize(client_connection));
-	return EOK;
-}
-
-/** Processes the module message.
- *  Distributes the message to the right bundled module.
- *  @param[in] callid The message identifier.
- *  @param[in] call The message parameters.
- *  @param[out] answer The message answer parameters.
- *  @param[out] answer_count The last parameter for the actual answer in the answer parameter.
- *  @returns EOK on success.
- *  @returns ENOTSUP if the message is not known.
- *  @returns Other error codes as defined for each bundled module message function.
- */
-int net_module_message(ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count){
-	if((IPC_GET_METHOD(*call) == IPC_M_CONNECT_TO_ME)
-		|| IS_NET_IL_MESSAGE(call)
-		|| IS_NET_TL_MESSAGE(call)
-		|| IS_NET_SOCKET_MESSAGE(call)){
-		switch(IPC_GET_TARGET(call)){
-			case SERVICE_IP:
-				return ip_message(callid, call, answer, answer_count);
-			case SERVICE_ARP:
-				return arp_message(callid, call, answer, answer_count);
-			case SERVICE_ICMP:
-				return icmp_message(callid, call, answer, answer_count);
-			case SERVICE_UDP:
-				return udp_message(callid, call, answer, answer_count);
-			case SERVICE_TCP:
-				return tcp_message(callid, call, answer, answer_count);
-			default:
-				return EINVAL;
-		}
-	}else if(IS_NET_IP_MESSAGE(call)){
-		return ip_message(callid, call, answer, answer_count);
-	}else if(IS_NET_ARP_MESSAGE(call)){
-		return arp_message(callid, call, answer, answer_count);
-	}else if(IS_NET_ICMP_MESSAGE(call)){
-		return icmp_message(callid, call, answer, answer_count);
-	}else if(IS_NET_UDP_MESSAGE(call)){
-		return udp_message(callid, call, answer, answer_count);
-	}else if(IS_NET_TCP_MESSAGE(call)){
-		return tcp_message(callid, call, answer, answer_count);
-	}else{
-		if(IS_NET_PACKET_MESSAGE(call)){
-			return packet_server_message(callid, call, answer, answer_count);
-		}else{
-			return net_message(callid, call, answer, answer_count);
-		}
-	}
-}
-
-/** @}
- */
Index: uspace/srv/net/net/net_standalone.c
===================================================================
--- uspace/srv/net/net/net_standalone.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/srv/net/net/net_standalone.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -38,10 +38,10 @@
 
 #include <ipc/ipc.h>
+#include <ipc/net.h>
 
-#include <net_messages.h>
 #include <ip_interface.h>
 #include <adt/measured_strings.h>
 #include <adt/module_map.h>
-#include <packet/packet_server.h>
+#include <packet_server.h>
 
 #include "net.h"
@@ -94,6 +94,5 @@
  * @return EOK on success.
  * @return ENOTSUP if the message is not known.
- * @return Other error codes as defined for each bundled module
- *         message function.
+ * @return Other error codes.
  *
  */
Index: uspace/srv/net/netif/lo/Makefile
===================================================================
--- uspace/srv/net/netif/lo/Makefile	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/srv/net/netif/lo/Makefile	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -30,6 +30,6 @@
 USPACE_PREFIX = ../../../..
 ROOT_PATH = $(USPACE_PREFIX)/..
-LIBS = $(LIBNET_PREFIX)/libnet.a $(LIBSOCKET_PREFIX)/libsocket.a
-EXTRA_CFLAGS = -I$(LIBNET_PREFIX)/include -I$(LIBSOCKET_PREFIX)/include
+LIBS = $(LIBNET_PREFIX)/libnet.a
+EXTRA_CFLAGS = -I$(LIBNET_PREFIX)/include
 
 COMMON_MAKEFILE = $(ROOT_PATH)/Makefile.common
Index: uspace/srv/net/netif/lo/lo.c
===================================================================
--- uspace/srv/net/netif/lo/lo.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/srv/net/netif/lo/lo.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -37,4 +37,5 @@
 #include <async.h>
 #include <errno.h>
+#include <err.h>
 #include <stdio.h>
 #include <str.h>
@@ -42,13 +43,11 @@
 #include <ipc/ipc.h>
 #include <ipc/services.h>
-
-#include <net_err.h>
-#include <net_messages.h>
-#include <net_modules.h>
+#include <ipc/nil.h>
+
+#include <net/modules.h>
 #include <adt/measured_strings.h>
-#include <packet/packet_client.h>
-#include <net_device.h>
+#include <packet_client.h>
+#include <net/device.h>
 #include <nil_interface.h>
-#include <nil_messages.h>
 #include <netif_interface.h>
 #include <netif_local.h>
Index: uspace/srv/net/netstart/Makefile
===================================================================
--- uspace/srv/net/netstart/Makefile	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/srv/net/netstart/Makefile	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -29,6 +29,6 @@
 
 USPACE_PREFIX = ../../..
-LIBS = $(LIBNET_PREFIX)/libnet.a $(LIBSOCKET_PREFIX)/libsocket.a
-EXTRA_CFLAGS = -I$(LIBNET_PREFIX)/include -I$(LIBSOCKET_PREFIX)/include
+LIBS = $(LIBNET_PREFIX)/libnet.a
+EXTRA_CFLAGS = -I$(LIBNET_PREFIX)/include
 
 BINARY = netstart
Index: uspace/srv/net/netstart/netstart.c
===================================================================
--- uspace/srv/net/netstart/netstart.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/srv/net/netstart/netstart.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -45,10 +45,10 @@
 #include <task.h>
 #include <str_error.h>
+#include <err.h>
 #include <ipc/ipc.h>
 #include <ipc/services.h>
+#include <ipc/net_net.h>
 
-#include <net_err.h>
-#include <net_modules.h>
-#include <net_net_messages.h>
+#include <net/modules.h>
 
 #include "self_test.h"
Index: uspace/srv/net/nil/eth/Makefile
===================================================================
--- uspace/srv/net/nil/eth/Makefile	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/srv/net/nil/eth/Makefile	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -30,6 +30,6 @@
 USPACE_PREFIX = ../../../..
 ROOT_PATH = $(USPACE_PREFIX)/..
-LIBS = $(LIBNET_PREFIX)/libnet.a $(LIBSOCKET_PREFIX)/libsocket.a
-EXTRA_CFLAGS = -I$(LIBNET_PREFIX)/include -I$(LIBSOCKET_PREFIX)/include
+LIBS = $(LIBNET_PREFIX)/libnet.a
+EXTRA_CFLAGS = -I$(LIBNET_PREFIX)/include
 
 COMMON_MAKEFILE = $(ROOT_PATH)/Makefile.common
Index: uspace/srv/net/nil/eth/eth.c
===================================================================
--- uspace/srv/net/nil/eth/eth.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/srv/net/nil/eth/eth.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -40,18 +40,18 @@
 #include <mem.h>
 #include <stdio.h>
+#include <byteorder.h>
 #include <str.h>
+#include <err.h>
 
 #include <ipc/ipc.h>
+#include <ipc/net.h>
 #include <ipc/services.h>
 
-#include <net_err.h>
-#include <net_messages.h>
-#include <net_modules.h>
-#include <net_byteorder.h>
+#include <net/modules.h>
 #include <net_checksum.h>
 #include <ethernet_lsap.h>
 #include <ethernet_protocols.h>
 #include <protocol_map.h>
-#include <net_device.h>
+#include <net/device.h>
 #include <netif_interface.h>
 #include <net_interface.h>
@@ -59,5 +59,5 @@
 #include <il_interface.h>
 #include <adt/measured_strings.h>
-#include <packet/packet_client.h>
+#include <packet_client.h>
 #include <packet_remote.h>
 #include <nil_local.h>
@@ -788,6 +788,4 @@
 }
 
-#ifndef CONFIG_NETIF_NIL_BUNDLE
-
 /** Default thread for new connections.
  *
@@ -839,6 +837,4 @@
 }
 
-#endif /* CONFIG_NETIF_NIL_BUNDLE */
-
 /** @}
  */
Index: uspace/srv/net/nil/eth/eth.h
===================================================================
--- uspace/srv/net/nil/eth/eth.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/srv/net/nil/eth/eth.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -41,5 +41,5 @@
 #include <ipc/services.h>
 
-#include <net_device.h>
+#include <net/device.h>
 #include <adt/measured_strings.h>
 
Index: uspace/srv/net/nil/eth/eth_module.c
===================================================================
--- uspace/srv/net/nil/eth/eth_module.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/srv/net/nil/eth/eth_module.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -38,12 +38,12 @@
 #include <async.h>
 #include <stdio.h>
+#include <err.h>
 
 #include <ipc/ipc.h>
 #include <ipc/services.h>
 
-#include <net_err.h>
-#include <net_modules.h>
+#include <net/modules.h>
 #include <net_interface.h>
-#include <packet/packet.h>
+#include <net/packet.h>
 #include <nil_local.h>
 
@@ -63,5 +63,5 @@
 	
 	async_set_client_connection(client_connection);
-	int net_phone = net_connect_module(SERVICE_NETWORKING);
+	int net_phone = net_connect_module();
 	ERROR_PROPAGATE(pm_init());
 	
Index: uspace/srv/net/nil/nildummy/Makefile
===================================================================
--- uspace/srv/net/nil/nildummy/Makefile	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/srv/net/nil/nildummy/Makefile	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -30,6 +30,6 @@
 USPACE_PREFIX = ../../../..
 ROOT_PATH = $(USPACE_PREFIX)/..
-LIBS = $(LIBNET_PREFIX)/libnet.a $(LIBSOCKET_PREFIX)/libsocket.a
-EXTRA_CFLAGS = -I$(LIBNET_PREFIX)/include -I$(LIBSOCKET_PREFIX)/include
+LIBS = $(LIBNET_PREFIX)/libnet.a
+EXTRA_CFLAGS = -I$(LIBNET_PREFIX)/include
 
 COMMON_MAKEFILE = $(ROOT_PATH)/Makefile.common
Index: uspace/srv/net/nil/nildummy/nildummy.c
===================================================================
--- uspace/srv/net/nil/nildummy/nildummy.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/srv/net/nil/nildummy/nildummy.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -41,16 +41,16 @@
 #include <stdio.h>
 #include <str.h>
+#include <err.h>
 #include <ipc/ipc.h>
+#include <ipc/net.h>
 #include <ipc/services.h>
 
-#include <net_err.h>
-#include <net_messages.h>
-#include <net_modules.h>
-#include <net_device.h>
+#include <net/modules.h>
+#include <net/device.h>
 #include <netif_interface.h>
 #include <nil_interface.h>
 #include <il_interface.h>
 #include <adt/measured_strings.h>
-#include <packet/packet.h>
+#include <net/packet.h>
 #include <packet_remote.h>
 #include <nil_local.h>
@@ -410,6 +410,4 @@
 }
 
-#ifndef CONFIG_NETIF_NIL_BUNDLE
-
 /** Default thread for new connections.
  *
@@ -461,6 +459,4 @@
 }
 
-#endif /* CONFIG_NETIF_NIL_BUNDLE */
-
 /** @}
  */
Index: uspace/srv/net/nil/nildummy/nildummy.h
===================================================================
--- uspace/srv/net/nil/nildummy/nildummy.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/srv/net/nil/nildummy/nildummy.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -41,5 +41,5 @@
 #include <ipc/services.h>
 
-#include <net_device.h>
+#include <net/device.h>
 #include <adt/measured_strings.h>
 
Index: uspace/srv/net/nil/nildummy/nildummy_module.c
===================================================================
--- uspace/srv/net/nil/nildummy/nildummy_module.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/srv/net/nil/nildummy/nildummy_module.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -38,12 +38,12 @@
 #include <async.h>
 #include <stdio.h>
+#include <err.h>
 
 #include <ipc/ipc.h>
 #include <ipc/services.h>
 
-#include <net_err.h>
-#include <net_modules.h>
+#include <net/modules.h>
 #include <net_interface.h>
-#include <packet/packet.h>
+#include <net/packet.h>
 #include <nil_local.h>
 
@@ -71,5 +71,5 @@
 	
 	async_set_client_connection(client_connection);
-	int net_phone = net_connect_module(SERVICE_NETWORKING);
+	int net_phone = net_connect_module();
 	ERROR_PROPAGATE(pm_init());
 	
Index: uspace/srv/net/tl/icmp/Makefile
===================================================================
--- uspace/srv/net/tl/icmp/Makefile	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/srv/net/tl/icmp/Makefile	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -29,6 +29,6 @@
 
 USPACE_PREFIX = ../../../..
-LIBS = $(LIBNET_PREFIX)/libnet.a $(LIBSOCKET_PREFIX)/libsocket.a
-EXTRA_CFLAGS = -I$(LIBNET_PREFIX)/include -I$(LIBSOCKET_PREFIX)/include
+LIBS = $(LIBNET_PREFIX)/libnet.a
+EXTRA_CFLAGS = -I$(LIBNET_PREFIX)/include
 BINARY = icmp
 
Index: uspace/srv/net/tl/icmp/icmp.c
===================================================================
--- uspace/srv/net/tl/icmp/icmp.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/srv/net/tl/icmp/icmp.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -44,31 +44,32 @@
 #include <ipc/ipc.h>
 #include <ipc/services.h>
+#include <ipc/net.h>
+#include <ipc/tl.h>
+#include <ipc/icmp.h>
 #include <sys/time.h>
 #include <sys/types.h>
-
-#include <net_err.h>
-#include <net_messages.h>
-#include <net_modules.h>
-#include <packet/packet_client.h>
+#include <byteorder.h>
+#include <errno.h>
+#include <err.h>
+
+#include <net/socket_codes.h>
+#include <net/ip_protocols.h>
+#include <net/inet.h>
+
+#include <net/modules.h>
+#include <packet_client.h>
 #include <packet_remote.h>
-#include <net_byteorder.h>
 #include <net_checksum.h>
-#include <icmp_api.h>
+#include <net/icmp_api.h>
 #include <icmp_client.h>
-#include <icmp_codes.h>
-#include <icmp_common.h>
+#include <net/icmp_codes.h>
+#include <net/icmp_common.h>
 #include <icmp_interface.h>
 #include <il_interface.h>
-#include <inet.h>
 #include <ip_client.h>
 #include <ip_interface.h>
-#include <ip_protocols.h>
 #include <net_interface.h>
-#include <socket_codes.h>
-#include <socket_errno.h>
-#include <tl_messages.h>
 #include <tl_interface.h>
 #include <tl_local.h>
-#include <icmp_messages.h>
 #include <icmp_header.h>
 
@@ -98,5 +99,5 @@
 /** Free identifier numbers pool end.
  */
-#define ICMP_FREE_IDS_END	MAX_UINT16
+#define ICMP_FREE_IDS_END	UINT16_MAX
 
 /** Computes the ICMP datagram checksum.
@@ -263,5 +264,5 @@
 	}else{
 		res = icmp_echo(echo_data->identifier, echo_data->sequence_number, size, timeout, ttl, tos, dont_fragment, addr, addrlen);
-		if(echo_data->sequence_number < MAX_UINT16){
+		if(echo_data->sequence_number < UINT16_MAX){
 			++ echo_data->sequence_number;
 		}else{
@@ -448,28 +449,4 @@
 }
 
-int icmp_connect_module(services_t service, suseconds_t timeout){
-	icmp_echo_ref echo_data;
-	icmp_param_t id;
-	int index;
-
-	echo_data = (icmp_echo_ref) malloc(sizeof(*echo_data));
-	if(! echo_data){
-		return ENOMEM;
-	}
-	// assign a new identifier
-	fibril_rwlock_write_lock(&icmp_globals.lock);
-	index = icmp_bind_free_id(echo_data);
-	if(index < 0){
-		free(echo_data);
-		fibril_rwlock_write_unlock(&icmp_globals.lock);
-		return index;
-	}else{
-		id = echo_data->identifier;
-		fibril_rwlock_write_unlock(&icmp_globals.lock);
-		// return the echo data identifier as the ICMP phone
-		return id;
-	}
-}
-
 int icmp_initialize(async_client_conn_t client_connection){
 	ERROR_DECLARE;
@@ -484,5 +461,5 @@
 	icmp_replies_initialize(&icmp_globals.replies);
 	icmp_echo_data_initialize(&icmp_globals.echo_data);
-	icmp_globals.ip_phone = ip_bind_service(SERVICE_IP, IPPROTO_ICMP, SERVICE_ICMP, client_connection, icmp_received_msg);
+	icmp_globals.ip_phone = ip_bind_service(SERVICE_IP, IPPROTO_ICMP, SERVICE_ICMP, client_connection);
 	if(icmp_globals.ip_phone < 0){
 		return icmp_globals.ip_phone;
@@ -731,5 +708,5 @@
 							fibril_rwlock_write_unlock(&icmp_globals.lock);
 							free(addr);
-							if(echo_data->sequence_number < MAX_UINT16){
+							if(echo_data->sequence_number < UINT16_MAX){
 								++ echo_data->sequence_number;
 							}else{
Index: uspace/srv/net/tl/icmp/icmp.h
===================================================================
--- uspace/srv/net/tl/icmp/icmp.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/srv/net/tl/icmp/icmp.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -40,5 +40,5 @@
 #include <fibril_synch.h>
 
-#include <icmp_codes.h>
+#include <net/icmp_codes.h>
 #include <adt/int_map.h>
 #include <icmp_header.h>
@@ -67,5 +67,4 @@
 
 /** Echo specific data map.
- *  The bundle module gets an identifier of the assigned echo specific data while connecting.
  *  The identifier is used in the future semi-remote calls instead of the ICMP phone.
  */
Index: uspace/srv/net/tl/icmp/icmp_module.c
===================================================================
--- uspace/srv/net/tl/icmp/icmp_module.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/srv/net/tl/icmp/icmp_module.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -40,10 +40,10 @@
 #include <async.h>
 #include <stdio.h>
+#include <err.h>
 #include <ipc/ipc.h>
 #include <ipc/services.h>
 
-#include <net_err.h>
-#include <net_modules.h>
-#include <packet/packet.h>
+#include <net/modules.h>
+#include <net/packet.h>
 #include <net_interface.h>
 #include <tl_local.h>
@@ -69,5 +69,5 @@
 
 	async_set_client_connection(client_connection);
-	icmp_globals.net_phone = net_connect_module(SERVICE_NETWORKING);
+	icmp_globals.net_phone = net_connect_module();
 	if(icmp_globals.net_phone < 0){
 		return icmp_globals.net_phone;
Index: uspace/srv/net/tl/tcp/Makefile
===================================================================
--- uspace/srv/net/tl/tcp/Makefile	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/srv/net/tl/tcp/Makefile	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -29,6 +29,6 @@
 
 USPACE_PREFIX = ../../../..
-LIBS = $(LIBNET_PREFIX)/libnet.a $(LIBSOCKET_PREFIX)/libsocket.a
-EXTRA_CFLAGS = -I$(LIBNET_PREFIX)/include -I$(LIBSOCKET_PREFIX)/include
+LIBS = $(LIBNET_PREFIX)/libnet.a
+EXTRA_CFLAGS = -I$(LIBNET_PREFIX)/include
 BINARY = tcp
 
Index: uspace/srv/net/tl/tcp/tcp.c
===================================================================
--- uspace/srv/net/tl/tcp/tcp.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/srv/net/tl/tcp/tcp.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -42,31 +42,31 @@
 //TODO remove stdio
 #include <stdio.h>
+#include <errno.h>
+#include <err.h>
 
 #include <ipc/ipc.h>
 #include <ipc/services.h>
-
-#include <net_err.h>
-#include <net_messages.h>
-#include <net_modules.h>
+#include <ipc/net.h>
+#include <ipc/tl.h>
+#include <ipc/socket.h>
+
+#include <net/socket_codes.h>
+#include <net/ip_protocols.h>
+#include <net/in.h>
+#include <net/in6.h>
+#include <net/inet.h>
+#include <net/modules.h>
+
 #include <adt/dynamic_fifo.h>
-#include <packet/packet_client.h>
+#include <packet_client.h>
 #include <packet_remote.h>
 #include <net_checksum.h>
-#include <in.h>
-#include <in6.h>
-#include <inet.h>
 #include <ip_client.h>
 #include <ip_interface.h>
-#include <ip_protocols.h>
 #include <icmp_client.h>
 #include <icmp_interface.h>
 #include <net_interface.h>
-#include <socket_codes.h>
-#include <socket_errno.h>
-#include <tcp_codes.h>
 #include <socket_core.h>
-#include <socket_messages.h>
 #include <tl_common.h>
-#include <tl_messages.h>
 #include <tl_local.h>
 #include <tl_interface.h>
@@ -76,49 +76,40 @@
 #include "tcp_module.h"
 
-/** TCP module name.
- */
+/** TCP module name. */
 #define NAME	"TCP protocol"
 
-/** The TCP window default value.
- */
-#define NET_DEFAULT_TCP_WINDOW	10240
-
-/** Initial timeout for new connections.
- */
+/** The TCP window default value. */
+#define NET_DEFAULT_TCP_WINDOW		10240
+
+/** Initial timeout for new connections. */
 #define NET_DEFAULT_TCP_INITIAL_TIMEOUT	3000000L
 
-/** Default timeout for closing.
- */
-#define NET_DEFAULT_TCP_TIME_WAIT_TIMEOUT	2000L
-
-/** The initial outgoing sequence number.
- */
-#define TCP_INITIAL_SEQUENCE_NUMBER		2999
-
-/** Maximum TCP fragment size.
- */
-#define MAX_TCP_FRAGMENT_SIZE	65535
-
-/** Free ports pool start.
- */
-#define TCP_FREE_PORTS_START	1025
-
-/** Free ports pool end.
- */
+/** Default timeout for closing. */
+#define NET_DEFAULT_TCP_TIME_WAIT_TIMEOUT 2000L
+
+/** The initial outgoing sequence number. */
+#define TCP_INITIAL_SEQUENCE_NUMBER	2999
+
+/** Maximum TCP fragment size. */
+#define MAX_TCP_FRAGMENT_SIZE		65535
+
+/** Free ports pool start. */
+#define TCP_FREE_PORTS_START		1025
+
+/** Free ports pool end. */
 #define TCP_FREE_PORTS_END		65535
 
-/** Timeout for connection initialization, SYN sent.
- */
-#define TCP_SYN_SENT_TIMEOUT	1000000L
-
-/** The maximum number of timeouts in a row before singaling connection lost.
- */
+/** Timeout for connection initialization, SYN sent. */
+#define TCP_SYN_SENT_TIMEOUT		1000000L
+
+/** The maximum number of timeouts in a row before singaling connection lost. */
 #define TCP_MAX_TIMEOUTS		8
 
-/** The number of acknowledgements before retransmit.
- */
+/** The number of acknowledgements before retransmit. */
 #define TCP_FAST_RETRANSMIT_COUNT	3
 
-/** Returns a value indicating whether the value is in the interval respecting the possible overflow.
+/** Returns a value indicating whether the value is in the interval respecting
+ *  the possible overflow.
+ *
  *  The high end and/or the value may overflow, be lower than the low value.
  *  @param[in] lower The last value before the interval.
@@ -126,15 +117,18 @@
  *  @param[in] higher_equal The last value in the interval.
  */
-#define IS_IN_INTERVAL_OVERFLOW(lower, value, higher_equal)	((((lower) < (value)) && (((value) <= (higher_equal)) || ((higher_equal) < (lower)))) || (((value) <= (higher_equal)) && ((higher_equal) < (lower))))
+#define IS_IN_INTERVAL_OVERFLOW(lower, value, higher_equal) \
+	((((lower) < (value)) && (((value) <= (higher_equal)) || \
+	((higher_equal) < (lower)))) || (((value) <= (higher_equal)) && \
+	((higher_equal) < (lower))))
 
 /** Type definition of the TCP timeout.
  *  @see tcp_timeout
  */
-typedef struct tcp_timeout	tcp_timeout_t;
+typedef struct tcp_timeout tcp_timeout_t;
 
 /** Type definition of the TCP timeout pointer.
  *  @see tcp_timeout
  */
-typedef tcp_timeout_t *	tcp_timeout_ref;
+typedef tcp_timeout_t *tcp_timeout_ref;
 
 /** TCP reply timeout data.
@@ -142,31 +136,30 @@
  *  @see tcp_timeout()
  */
-struct tcp_timeout{
-	/** TCP global data are going to be read only.
-	 */
+struct tcp_timeout {
+	/** TCP global data are going to be read only. */
 	int globals_read_only;
-	/** Socket port.
-	 */
+
+	/** Socket port. */
 	int port;
-	/** Local sockets.
-	 */
+
+	/** Local sockets. */
 	socket_cores_ref local_sockets;
-	/** Socket identifier.
-	 */
+
+	/** Socket identifier. */
 	int socket_id;
-	/** Socket state.
-	 */
+
+	/** Socket state. */
 	tcp_socket_state_t state;
-	/** Sent packet sequence number.
-	 */
+
+	/** Sent packet sequence number. */
 	int sequence_number;
-	/** Timeout in microseconds.
-	 */
+
+	/** Timeout in microseconds. */
 	suseconds_t timeout;
-	/** Port map key.
-	 */
-	char * key;
-	/** Port map key length.
-	 */
+
+	/** Port map key. */
+	char *key;
+
+	/** Port map key length. */
 	size_t key_length;
 };
@@ -179,72 +172,121 @@
 int tcp_release_and_return(packet_t packet, int result);
 
-void tcp_prepare_operation_header(socket_core_ref socket, tcp_socket_data_ref socket_data, tcp_header_ref header, int synchronize, int finalize);
-int tcp_prepare_timeout(int (*timeout_function)(void * tcp_timeout_t), socket_core_ref socket, tcp_socket_data_ref socket_data, size_t sequence_number, tcp_socket_state_t state, suseconds_t timeout, int globals_read_only);
+void tcp_prepare_operation_header(socket_core_ref socket,
+    tcp_socket_data_ref socket_data, tcp_header_ref header, int synchronize,
+    int finalize);
+int tcp_prepare_timeout(int (*timeout_function)(void *tcp_timeout_t),
+    socket_core_ref socket, tcp_socket_data_ref socket_data,
+    size_t sequence_number, tcp_socket_state_t state, suseconds_t timeout,
+    int globals_read_only);
 void tcp_free_socket_data(socket_core_ref socket);
-int tcp_timeout(void * data);
-int tcp_release_after_timeout(void * data);
-int tcp_process_packet(device_id_t device_id, packet_t packet, services_t error);
-int tcp_connect_core(socket_core_ref socket, socket_cores_ref local_sockets, struct sockaddr * addr, socklen_t addrlen);
-int tcp_queue_prepare_packet(socket_core_ref socket, tcp_socket_data_ref socket_data, packet_t packet, size_t data_length);
-int tcp_queue_packet(socket_core_ref socket, tcp_socket_data_ref socket_data, packet_t packet, size_t data_length);
-packet_t tcp_get_packets_to_send(socket_core_ref socket, tcp_socket_data_ref socket_data);
+
+int tcp_timeout(void *data);
+
+int tcp_release_after_timeout(void *data);
+
+int tcp_process_packet(device_id_t device_id, packet_t packet,
+    services_t error);
+int tcp_connect_core(socket_core_ref socket, socket_cores_ref local_sockets,
+    struct sockaddr *addr, socklen_t addrlen);
+int tcp_queue_prepare_packet(socket_core_ref socket,
+    tcp_socket_data_ref socket_data, packet_t packet, size_t data_length);
+int tcp_queue_packet(socket_core_ref socket, tcp_socket_data_ref socket_data,
+    packet_t packet, size_t data_length);
+packet_t tcp_get_packets_to_send(socket_core_ref socket,
+    tcp_socket_data_ref socket_data);
 void tcp_send_packets(device_id_t device_id, packet_t packet);
-void tcp_process_acknowledgement(socket_core_ref socket, tcp_socket_data_ref socket_data, tcp_header_ref header);
-packet_t tcp_send_prepare_packet(socket_core_ref socket, tcp_socket_data_ref socket_data, packet_t packet, size_t data_length, size_t sequence_number);
-packet_t tcp_prepare_copy(socket_core_ref socket, tcp_socket_data_ref socket_data, packet_t packet, size_t data_length, size_t sequence_number);
-void tcp_retransmit_packet(socket_core_ref socket, tcp_socket_data_ref socket_data, size_t sequence_number);
-int tcp_create_notification_packet(packet_t * packet, socket_core_ref socket, tcp_socket_data_ref socket_data, int synchronize, int finalize);
+
+void tcp_process_acknowledgement(socket_core_ref socket,
+    tcp_socket_data_ref socket_data, tcp_header_ref header);
+packet_t tcp_send_prepare_packet(socket_core_ref socket,
+    tcp_socket_data_ref socket_data, packet_t packet, size_t data_length,
+    size_t sequence_number);
+packet_t tcp_prepare_copy(socket_core_ref socket,
+    tcp_socket_data_ref socket_data, packet_t packet, size_t data_length,
+    size_t sequence_number);
+void tcp_retransmit_packet(socket_core_ref socket,
+    tcp_socket_data_ref socket_data, size_t sequence_number);
+int tcp_create_notification_packet(packet_t * packet, socket_core_ref socket,
+    tcp_socket_data_ref socket_data, int synchronize, int finalize);
 void tcp_refresh_socket_data(tcp_socket_data_ref socket_data);
+
 void tcp_initialize_socket_data(tcp_socket_data_ref socket_data);
-int tcp_process_listen(socket_core_ref listening_socket, tcp_socket_data_ref listening_socket_data, tcp_header_ref header, packet_t packet, struct sockaddr * src, struct sockaddr * dest, size_t addrlen);
-int tcp_process_syn_sent(socket_core_ref socket, tcp_socket_data_ref socket_data, tcp_header_ref header, packet_t packet);
-int tcp_process_syn_received(socket_core_ref socket, tcp_socket_data_ref socket_data, tcp_header_ref header, packet_t packet);
-int tcp_process_established(socket_core_ref socket, tcp_socket_data_ref socket_data, tcp_header_ref header, packet_t packet, int fragments, size_t total_length);
-int tcp_queue_received_packet(socket_core_ref socket, tcp_socket_data_ref socket_data, packet_t packet, int fragments, size_t total_length);
-
-int tcp_received_msg(device_id_t device_id, packet_t packet, services_t receiver, services_t error);
+
+int tcp_process_listen(socket_core_ref listening_socket,
+    tcp_socket_data_ref listening_socket_data, tcp_header_ref header,
+    packet_t packet, struct sockaddr *src, struct sockaddr *dest,
+    size_t addrlen);
+int tcp_process_syn_sent(socket_core_ref socket,
+    tcp_socket_data_ref socket_data, tcp_header_ref header, packet_t packet);
+int tcp_process_syn_received(socket_core_ref socket,
+    tcp_socket_data_ref socket_data, tcp_header_ref header, packet_t packet);
+int tcp_process_established(socket_core_ref socket,
+    tcp_socket_data_ref socket_data, tcp_header_ref header, packet_t packet,
+    int fragments, size_t total_length);
+int tcp_queue_received_packet(socket_core_ref socket,
+    tcp_socket_data_ref socket_data, packet_t packet, int fragments,
+    size_t total_length);
+
+int tcp_received_msg(device_id_t device_id, packet_t packet,
+    services_t receiver, services_t error);
 int tcp_process_client_messages(ipc_callid_t callid, ipc_call_t call);
-int tcp_listen_message(socket_cores_ref local_sockets, int socket_id, int backlog);
-int tcp_connect_message(socket_cores_ref local_sockets, int socket_id, struct sockaddr * addr, socklen_t addrlen);
-int tcp_recvfrom_message(socket_cores_ref local_sockets, int socket_id, int flags, size_t * addrlen);
-int tcp_send_message(socket_cores_ref local_sockets, int socket_id, int fragments, size_t * data_fragment_size, int flags);
-int tcp_accept_message(socket_cores_ref local_sockets, int socket_id, int new_socket_id, size_t * data_fragment_size, size_t * addrlen);
+
+int tcp_listen_message(socket_cores_ref local_sockets, int socket_id,
+    int backlog);
+int tcp_connect_message(socket_cores_ref local_sockets, int socket_id,
+    struct sockaddr *addr, socklen_t addrlen);
+int tcp_recvfrom_message(socket_cores_ref local_sockets, int socket_id,
+    int flags, size_t * addrlen);
+int tcp_send_message(socket_cores_ref local_sockets, int socket_id,
+    int fragments, size_t * data_fragment_size, int flags);
+int tcp_accept_message(socket_cores_ref local_sockets, int socket_id,
+    int new_socket_id, size_t * data_fragment_size, size_t * addrlen);
 int tcp_close_message(socket_cores_ref local_sockets, int socket_id);
 
-/** TCP global data.
- */
-tcp_globals_t	tcp_globals;
-
-int tcp_initialize(async_client_conn_t client_connection){
+/** TCP global data. */
+tcp_globals_t tcp_globals;
+
+int tcp_initialize(async_client_conn_t client_connection)
+{
 	ERROR_DECLARE;
 
 	assert(client_connection);
+
 	fibril_rwlock_initialize(&tcp_globals.lock);
 	fibril_rwlock_write_lock(&tcp_globals.lock);
-	tcp_globals.icmp_phone = icmp_connect_module(SERVICE_ICMP, ICMP_CONNECT_TIMEOUT);
-	tcp_globals.ip_phone = ip_bind_service(SERVICE_IP, IPPROTO_TCP, SERVICE_TCP, client_connection, tcp_received_msg);
-	if(tcp_globals.ip_phone < 0){
+
+	tcp_globals.icmp_phone = icmp_connect_module(SERVICE_ICMP,
+	    ICMP_CONNECT_TIMEOUT);
+	tcp_globals.ip_phone = ip_bind_service(SERVICE_IP, IPPROTO_TCP,
+	    SERVICE_TCP, client_connection);
+	if (tcp_globals.ip_phone < 0)
 		return tcp_globals.ip_phone;
-	}
+	
 	ERROR_PROPAGATE(socket_ports_initialize(&tcp_globals.sockets));
-	if(ERROR_OCCURRED(packet_dimensions_initialize(&tcp_globals.dimensions))){
+	if (ERROR_OCCURRED(packet_dimensions_initialize(
+	    &tcp_globals.dimensions))) {
 		socket_ports_destroy(&tcp_globals.sockets);
 		return ERROR_CODE;
 	}
+
 	tcp_globals.last_used_port = TCP_FREE_PORTS_START - 1;
 	fibril_rwlock_write_unlock(&tcp_globals.lock);
+
 	return EOK;
 }
 
-int tcp_received_msg(device_id_t device_id, packet_t packet, services_t receiver, services_t error){
+int
+tcp_received_msg(device_id_t device_id, packet_t packet, services_t receiver,
+    services_t error)
+{
 	ERROR_DECLARE;
 
-	if(receiver != SERVICE_TCP){
+	if (receiver != SERVICE_TCP)
 		return EREFUSED;
-	}
+
 	fibril_rwlock_write_lock(&tcp_globals.lock);
-	if(ERROR_OCCURRED(tcp_process_packet(device_id, packet, error))){
+	if (ERROR_OCCURRED(tcp_process_packet(device_id, packet, error)))
 		fibril_rwlock_write_unlock(&tcp_globals.lock);
-	}
+
 	printf("receive %d \n", ERROR_CODE);
 
@@ -252,5 +294,6 @@
 }
 
-int tcp_process_packet(device_id_t device_id, packet_t packet, services_t error){
+int tcp_process_packet(device_id_t device_id, packet_t packet, services_t error)
+{
 	ERROR_DECLARE;
 
@@ -259,5 +302,5 @@
 	int result;
 	tcp_header_ref header;
-	socket_core_ref  socket;
+	socket_core_ref socket;
 	tcp_socket_data_ref socket_data;
 	packet_t next_packet;
@@ -267,24 +310,26 @@
 	icmp_type_t type;
 	icmp_code_t code;
-	struct sockaddr * src;
-	struct sockaddr * dest;
+	struct sockaddr *src;
+	struct sockaddr *dest;
 	size_t addrlen;
 
-	printf("p1 \n");
-	if(error){
-		switch(error){
-			case SERVICE_ICMP:
-				// process error
-				result = icmp_client_process_packet(packet, &type, &code, NULL, NULL);
-				if(result < 0){
-					return tcp_release_and_return(packet, result);
-				}
-				length = (size_t) result;
-				if(ERROR_OCCURRED(packet_trim(packet, length, 0))){
-					return tcp_release_and_return(packet, ERROR_CODE);
-				}
-				break;
-			default:
-				return tcp_release_and_return(packet, ENOTSUP);
+	if (error) {
+		switch (error) {
+		case SERVICE_ICMP:
+			// process error
+			result = icmp_client_process_packet(packet, &type,
+			    &code, NULL, NULL);
+			if (result < 0)
+				return tcp_release_and_return(packet, result);
+
+			length = (size_t) result;
+			if (ERROR_OCCURRED(packet_trim(packet, length, 0))) {
+				return tcp_release_and_return(packet,
+				    ERROR_CODE);
+			}
+			break;
+
+		default:
+			return tcp_release_and_return(packet, ENOTSUP);
 		}
 	}
@@ -292,50 +337,52 @@
 	// TODO process received ipopts?
 	result = ip_client_process_packet(packet, NULL, NULL, NULL, NULL, NULL);
-//	printf("ip len %d\n", result);
-	if(result < 0){
+	if (result < 0)
 		return tcp_release_and_return(packet, result);
-	}
+
 	offset = (size_t) result;
 
 	length = packet_get_data_length(packet);
-//	printf("packet len %d\n", length);
-	if(length <= 0){
+	if (length <= 0)
 		return tcp_release_and_return(packet, EINVAL);
-	}
-	if(length < TCP_HEADER_SIZE + offset){
+
+	if (length < TCP_HEADER_SIZE + offset)
 		return tcp_release_and_return(packet, NO_DATA);
-	}
 
 	// trim all but TCP header
-	if(ERROR_OCCURRED(packet_trim(packet, offset, 0))){
+	if (ERROR_OCCURRED(packet_trim(packet, offset, 0)))
 		return tcp_release_and_return(packet, ERROR_CODE);
-	}
 
 	// get tcp header
 	header = (tcp_header_ref) packet_get_data(packet);
-	if(! header){
+	if (!header)
 		return tcp_release_and_return(packet, NO_DATA);
-	}
-//	printf("header len %d, port %d \n", TCP_HEADER_LENGTH(header), ntohs(header->destination_port));
+
+//      printf("header len %d, port %d \n", TCP_HEADER_LENGTH(header),
+//	    ntohs(header->destination_port));
 
 	result = packet_get_addr(packet, (uint8_t **) &src, (uint8_t **) &dest);
-	if(result <= 0){
+	if (result <= 0)
 		return tcp_release_and_return(packet, result);
-	}
+
 	addrlen = (size_t) result;
 
-	if(ERROR_OCCURRED(tl_set_address_port(src, addrlen, ntohs(header->source_port)))){
+	if (ERROR_OCCURRED(tl_set_address_port(src, addrlen,
+	    ntohs(header->source_port)))) 
 		return tcp_release_and_return(packet, ERROR_CODE);
-	}
-
+	
 	// find the destination socket
-	socket = socket_port_find(&tcp_globals.sockets, ntohs(header->destination_port), (const char *) src, addrlen);
-	if(! socket){
-//		printf("listening?\n");
+	socket = socket_port_find(&tcp_globals.sockets,
+	    ntohs(header->destination_port), (const char *) src, addrlen);
+	if (!socket) {
 		// find the listening destination socket
-		socket = socket_port_find(&tcp_globals.sockets, ntohs(header->destination_port), SOCKET_MAP_KEY_LISTENING, 0);
-		if(! socket){
-			if(tl_prepare_icmp_packet(tcp_globals.net_phone, tcp_globals.icmp_phone, packet, error) == EOK){
-				icmp_destination_unreachable_msg(tcp_globals.icmp_phone, ICMP_PORT_UNREACH, 0, packet);
+		socket = socket_port_find(&tcp_globals.sockets,
+		    ntohs(header->destination_port), SOCKET_MAP_KEY_LISTENING,
+		    0);
+		if (!socket) {
+			if (tl_prepare_icmp_packet(tcp_globals.net_phone,
+			    tcp_globals.icmp_phone, packet, error) == EOK) {
+				icmp_destination_unreachable_msg(
+				    tcp_globals.icmp_phone, ICMP_PORT_UNREACH,
+				    0, packet);
 			}
 			return EADDRNOTAVAIL;
@@ -354,85 +401,113 @@
 	checksum = 0;
 	total_length = 0;
-	do{
-		++ fragments;
+	do {
+		++fragments;
 		length = packet_get_data_length(next_packet);
-		if(length <= 0){
+		if (length <= 0)
 			return tcp_release_and_return(packet, NO_DATA);
-		}
+
 		total_length += length;
+
 		// add partial checksum if set
-		if(! error){
-			checksum = compute_checksum(checksum, packet_get_data(packet), packet_get_data_length(packet));
-		}
-	}while((next_packet = pq_next(next_packet)));
-//	printf("fragments %d of %d bytes\n", fragments, total_length);
-
-//	printf("lock?\n");
+		if (!error) {
+			checksum = compute_checksum(checksum,
+			    packet_get_data(packet),
+			    packet_get_data_length(packet));
+		}
+
+	} while ((next_packet = pq_next(next_packet)));
+
 	fibril_rwlock_write_lock(socket_data->local_lock);
-//	printf("locked\n");
-	if(! error){
-		if(socket_data->state == TCP_SOCKET_LISTEN){
-			if(socket_data->pseudo_header){
-				free(socket_data->pseudo_header);
-				socket_data->pseudo_header = NULL;
-				socket_data->headerlen = 0;
-			}
-			if(ERROR_OCCURRED(ip_client_get_pseudo_header(IPPROTO_TCP, src, addrlen, dest, addrlen, total_length, &socket_data->pseudo_header, &socket_data->headerlen))){
-				fibril_rwlock_write_unlock(socket_data->local_lock);
-				return tcp_release_and_return(packet, ERROR_CODE);
-			}
-		}else if(ERROR_OCCURRED(ip_client_set_pseudo_header_data_length(socket_data->pseudo_header, socket_data->headerlen, total_length))){
+
+	if (error)
+		goto error;
+	
+	if (socket_data->state == TCP_SOCKET_LISTEN) {
+
+		if (socket_data->pseudo_header) {
+			free(socket_data->pseudo_header);
+			socket_data->pseudo_header = NULL;
+			socket_data->headerlen = 0;
+		}
+
+		if (ERROR_OCCURRED(ip_client_get_pseudo_header(IPPROTO_TCP, src,
+		    addrlen, dest, addrlen, total_length,
+		    &socket_data->pseudo_header, &socket_data->headerlen))) {
 			fibril_rwlock_write_unlock(socket_data->local_lock);
 			return tcp_release_and_return(packet, ERROR_CODE);
 		}
-		checksum = compute_checksum(checksum, socket_data->pseudo_header, socket_data->headerlen);
-		if(flip_checksum(compact_checksum(checksum)) != IP_CHECKSUM_ZERO){
-			printf("checksum err %x -> %x\n", header->checksum, flip_checksum(compact_checksum(checksum)));
-			fibril_rwlock_write_unlock(socket_data->local_lock);
-			if(! ERROR_OCCURRED(tl_prepare_icmp_packet(tcp_globals.net_phone, tcp_globals.icmp_phone, packet, error))){
-				// checksum error ICMP
-				icmp_parameter_problem_msg(tcp_globals.icmp_phone, ICMP_PARAM_POINTER, ((size_t) ((void *) &header->checksum)) - ((size_t) ((void *) header)), packet);
-			}
-			return EINVAL;
-		}
-	}
-
+
+	} else if (ERROR_OCCURRED(ip_client_set_pseudo_header_data_length(
+	    socket_data->pseudo_header, socket_data->headerlen,
+	    total_length))) {
+		fibril_rwlock_write_unlock(socket_data->local_lock);
+		return tcp_release_and_return(packet, ERROR_CODE);
+	}
+	
+	checksum = compute_checksum(checksum, socket_data->pseudo_header,
+	    socket_data->headerlen);
+	if (flip_checksum(compact_checksum(checksum)) != IP_CHECKSUM_ZERO) {
+		printf("checksum err %x -> %x\n", header->checksum,
+		    flip_checksum(compact_checksum(checksum)));
+		fibril_rwlock_write_unlock(socket_data->local_lock);
+
+		if (ERROR_NONE(tl_prepare_icmp_packet(tcp_globals.net_phone,
+		    tcp_globals.icmp_phone, packet, error))) {
+			// checksum error ICMP
+			icmp_parameter_problem_msg(tcp_globals.icmp_phone,
+			    ICMP_PARAM_POINTER,
+			    ((size_t) ((void *) &header->checksum)) -
+			    ((size_t) ((void *) header)), packet);
+		}
+
+		return EINVAL;
+	}
+
+error:
 	fibril_rwlock_read_unlock(&tcp_globals.lock);
 
 	// TODO error reporting/handling
-//	printf("st %d\n", socket_data->state);
-	switch(socket_data->state){
-		case TCP_SOCKET_LISTEN:
-			ERROR_CODE = tcp_process_listen(socket, socket_data, header, packet, src, dest, addrlen);
-			break;
-		case TCP_SOCKET_SYN_RECEIVED:
-			ERROR_CODE = tcp_process_syn_received(socket, socket_data, header, packet);
-			break;
-		case TCP_SOCKET_SYN_SENT:
-			ERROR_CODE = tcp_process_syn_sent(socket, socket_data, header, packet);
-			break;
-		case TCP_SOCKET_FIN_WAIT_1:
-			// ack changing the state to FIN_WAIT_2 gets processed later
-		case TCP_SOCKET_FIN_WAIT_2:
-			// fin changing state to LAST_ACK gets processed later
-		case TCP_SOCKET_LAST_ACK:
-			// ack releasing the socket get processed later
-		case TCP_SOCKET_CLOSING:
-			// ack releasing the socket gets processed later
-		case TCP_SOCKET_ESTABLISHED:
-			ERROR_CODE = tcp_process_established(socket, socket_data, header, packet, fragments, total_length);
-			break;
-		default:
-			pq_release_remote(tcp_globals.net_phone, packet_get_id(packet));
-	}
-
-	if(ERROR_CODE != EOK){
+	switch (socket_data->state) {
+	case TCP_SOCKET_LISTEN:
+		ERROR_CODE = tcp_process_listen(socket, socket_data, header,
+		    packet, src, dest, addrlen);
+		break;
+	case TCP_SOCKET_SYN_RECEIVED:
+		ERROR_CODE = tcp_process_syn_received(socket, socket_data,
+		    header, packet);
+		break;
+	case TCP_SOCKET_SYN_SENT:
+		ERROR_CODE = tcp_process_syn_sent(socket, socket_data, header,
+		    packet);
+		break;
+	case TCP_SOCKET_FIN_WAIT_1:
+		// ack changing the state to FIN_WAIT_2 gets processed later
+	case TCP_SOCKET_FIN_WAIT_2:
+		// fin changing state to LAST_ACK gets processed later
+	case TCP_SOCKET_LAST_ACK:
+		// ack releasing the socket get processed later
+	case TCP_SOCKET_CLOSING:
+		// ack releasing the socket gets processed later
+	case TCP_SOCKET_ESTABLISHED:
+		ERROR_CODE = tcp_process_established(socket, socket_data,
+		    header, packet, fragments, total_length);
+		break;
+	default:
+		pq_release_remote(tcp_globals.net_phone, packet_get_id(packet));
+	}
+
+	if (ERROR_CODE != EOK) {
 		printf("process %d\n", ERROR_CODE);
 		fibril_rwlock_write_unlock(socket_data->local_lock);
 	}
+
 	return EOK;
 }
 
-int tcp_process_established(socket_core_ref socket, tcp_socket_data_ref socket_data, tcp_header_ref header, packet_t packet, int fragments, size_t total_length){
+int
+tcp_process_established(socket_core_ref socket, tcp_socket_data_ref socket_data,
+    tcp_header_ref header, packet_t packet, int fragments,
+    size_t total_length)
+{
 	ERROR_DECLARE;
 
@@ -455,60 +530,72 @@
 	old_incoming = socket_data->next_incoming;
 
-	if(header->finalize){
+	if (header->finalize)
 		socket_data->fin_incoming = new_sequence_number;
-	}
-
-//	printf("pe %d < %d <= %d\n", new_sequence_number, socket_data->next_incoming, new_sequence_number + total_length);
+
 	// trim begining if containing expected data
-	if(IS_IN_INTERVAL_OVERFLOW(new_sequence_number, socket_data->next_incoming, new_sequence_number + total_length)){
+	if (IS_IN_INTERVAL_OVERFLOW(new_sequence_number,
+	    socket_data->next_incoming, new_sequence_number + total_length)) {
+
 		// get the acknowledged offset
-		if(socket_data->next_incoming < new_sequence_number){
-			offset = new_sequence_number - socket_data->next_incoming;
-		}else{
-			offset = socket_data->next_incoming - new_sequence_number;
-		}
-//		printf("offset %d\n", offset);
+		if (socket_data->next_incoming < new_sequence_number) {
+			offset = new_sequence_number -
+			    socket_data->next_incoming;
+		} else {
+			offset = socket_data->next_incoming -
+			    new_sequence_number;
+		}
+
 		new_sequence_number += offset;
 		total_length -= offset;
 		length = packet_get_data_length(packet);
 		// trim the acknowledged data
-		while(length <= offset){
+		while (length <= offset) {
 			// release the acknowledged packets
 			next_packet = pq_next(packet);
-			pq_release_remote(tcp_globals.net_phone, packet_get_id(packet));
+			pq_release_remote(tcp_globals.net_phone,
+			    packet_get_id(packet));
 			packet = next_packet;
 			offset -= length;
 			length = packet_get_data_length(packet);
 		}
-		if((offset > 0)
-			&& (ERROR_OCCURRED(packet_trim(packet, offset, 0)))){
+
+		if ((offset > 0) && (ERROR_OCCURRED(packet_trim(packet,
+		    offset, 0))))
 			return tcp_release_and_return(packet, ERROR_CODE);
-		}
+
 		assert(new_sequence_number == socket_data->next_incoming);
 	}
 
 	// release if overflowing the window
-//	if(IS_IN_INTERVAL_OVERFLOW(socket_data->next_incoming + socket_data->window, new_sequence_number, new_sequence_number + total_length)){
-//		return tcp_release_and_return(packet, EOVERFLOW);
-//	}
-
 /*
+	if (IS_IN_INTERVAL_OVERFLOW(socket_data->next_incoming +
+	    socket_data->window, new_sequence_number, new_sequence_number +
+	    total_length)) {
+		return tcp_release_and_return(packet, EOVERFLOW);
+	}
+
 	// trim end if overflowing the window
-	if(IS_IN_INTERVAL_OVERFLOW(new_sequence_number, socket_data->next_incoming + socket_data->window, new_sequence_number + total_length)){
+	if (IS_IN_INTERVAL_OVERFLOW(new_sequence_number,
+	    socket_data->next_incoming + socket_data->window,
+	    new_sequence_number + total_length)) {
 		// get the allowed data length
-		if(socket_data->next_incoming + socket_data->window < new_sequence_number){
-			offset = new_sequence_number - socket_data->next_incoming + socket_data->window;
-		}else{
-			offset = socket_data->next_incoming + socket_data->window - new_sequence_number;
+		if (socket_data->next_incoming + socket_data->window <
+		    new_sequence_number) {
+			offset = new_sequence_number -
+			    socket_data->next_incoming + socket_data->window;
+		} else {
+			offset = socket_data->next_incoming +
+			    socket_data->window - new_sequence_number;
 		}
 		next_packet = packet;
 		// trim the overflowing data
-		while(next_packet && (offset > 0)){
+		while (next_packet && (offset > 0)) {
 			length = packet_get_data_length(packet);
-			if(length <= offset){
+			if (length <= offset)
 				next_packet = pq_next(next_packet);
-			}else if(ERROR_OCCURRED(packet_trim(next_packet, 0, length - offset))){
-				return tcp_release_and_return(packet, ERROR_CODE);
-			}
+			else if (ERROR_OCCURRED(packet_trim(next_packet, 0,
+			    length - offset)))
+				return tcp_release_and_return(packet,
+				    ERROR_CODE);
 			offset -= length;
 			total_length -= length - offset;
@@ -516,15 +603,17 @@
 		// release the overflowing packets
 		next_packet = pq_next(next_packet);
-		if(next_packet){
+		if (next_packet) {
 			tmp_packet = next_packet;
 			next_packet = pq_next(next_packet);
 			pq_insert_after(tmp_packet, next_packet);
-			pq_release_remote(tcp_globals.net_phone, packet_get_id(tmp_packet));
-		}
-		assert(new_sequence_number + total_length == socket_data->next_incoming + socket_data->window);
+			pq_release_remote(tcp_globals.net_phone,
+			    packet_get_id(tmp_packet));
+		}
+		assert(new_sequence_number + total_length ==
+		    socket_data->next_incoming + socket_data->window);
 	}
 */
 	// the expected one arrived?
-	if(new_sequence_number == socket_data->next_incoming){
+	if (new_sequence_number == socket_data->next_incoming) {
 		printf("expected\n");
 		// process acknowledgement
@@ -533,64 +622,88 @@
 		// remove the header
 		total_length -= TCP_HEADER_LENGTH(header);
-		if(ERROR_OCCURRED(packet_trim(packet, TCP_HEADER_LENGTH(header), 0))){
+		if (ERROR_OCCURRED(packet_trim(packet,
+		    TCP_HEADER_LENGTH(header), 0)))
 			return tcp_release_and_return(packet, ERROR_CODE);
-		}
-
-		if(total_length){
-			ERROR_PROPAGATE(tcp_queue_received_packet(socket, socket_data, packet, fragments, total_length));
-		}else{
+
+		if (total_length) {
+			ERROR_PROPAGATE(tcp_queue_received_packet(socket,
+			    socket_data, packet, fragments, total_length));
+		} else {
 			total_length = 1;
 		}
+
 		socket_data->next_incoming = old_incoming + total_length;
 		packet = socket_data->incoming;
-		while(packet){
-			if(ERROR_OCCURRED(pq_get_order(socket_data->incoming, &order, NULL))){
+		while (packet) {
+
+			if (ERROR_OCCURRED(pq_get_order(socket_data->incoming,
+			    &order, NULL))) {
 				// remove the corrupted packet
 				next_packet = pq_detach(packet);
-				if(packet == socket_data->incoming){
+				if (packet == socket_data->incoming)
 					socket_data->incoming = next_packet;
-				}
-				pq_release_remote(tcp_globals.net_phone, packet_get_id(packet));
+				pq_release_remote(tcp_globals.net_phone,
+				    packet_get_id(packet));
 				packet = next_packet;
 				continue;
 			}
+
 			sequence_number = (uint32_t) order;
-			if(IS_IN_INTERVAL_OVERFLOW(sequence_number, old_incoming, socket_data->next_incoming)){
+			if (IS_IN_INTERVAL_OVERFLOW(sequence_number,
+			    old_incoming, socket_data->next_incoming)) {
 				// move to the next
 				packet = pq_next(packet);
-			// coninual data?
-			}else if(IS_IN_INTERVAL_OVERFLOW(old_incoming, sequence_number, socket_data->next_incoming)){
+				// coninual data?
+			} else if (IS_IN_INTERVAL_OVERFLOW(old_incoming,
+			    sequence_number, socket_data->next_incoming)) {
 				// detach the packet
 				next_packet = pq_detach(packet);
-				if(packet == socket_data->incoming){
+				if (packet == socket_data->incoming)
 					socket_data->incoming = next_packet;
-				}
 				// get data length
 				length = packet_get_data_length(packet);
 				new_sequence_number = sequence_number + length;
-				if(length <= 0){
+				if (length <= 0) {
 					// remove the empty packet
-					pq_release_remote(tcp_globals.net_phone, packet_get_id(packet));
+					pq_release_remote(tcp_globals.net_phone,
+					    packet_get_id(packet));
 					packet = next_packet;
 					continue;
 				}
 				// exactly following
-				if(sequence_number == socket_data->next_incoming){
+				if (sequence_number ==
+				    socket_data->next_incoming) {
 					// queue received data
-					ERROR_PROPAGATE(tcp_queue_received_packet(socket, socket_data, packet, 1, packet_get_data_length(packet)));
-					socket_data->next_incoming = new_sequence_number;
+					ERROR_PROPAGATE(
+					    tcp_queue_received_packet(socket,
+					    socket_data, packet, 1,
+					    packet_get_data_length(packet)));
+					socket_data->next_incoming =
+					    new_sequence_number;
 					packet = next_packet;
 					continue;
-				// at least partly following data?
-				}else if(IS_IN_INTERVAL_OVERFLOW(sequence_number, socket_data->next_incoming, new_sequence_number)){
-					if(socket_data->next_incoming < new_sequence_number){
-						length = new_sequence_number - socket_data->next_incoming;
-					}else{
-						length = socket_data->next_incoming - new_sequence_number;
+					// at least partly following data?
+				} else if (IS_IN_INTERVAL_OVERFLOW(
+				    sequence_number, socket_data->next_incoming,
+				    new_sequence_number)) {
+					if (socket_data->next_incoming <
+					    new_sequence_number) {
+						length = new_sequence_number -
+						    socket_data->next_incoming;
+					} else {
+						length =
+						    socket_data->next_incoming -
+						    new_sequence_number;
 					}
-					if(! ERROR_OCCURRED(packet_trim(packet, length, 0))){
+					if (ERROR_NONE(packet_trim(packet,
+					    length, 0))) {
 						// queue received data
-						ERROR_PROPAGATE(tcp_queue_received_packet(socket, socket_data, packet, 1, packet_get_data_length(packet)));
-						socket_data->next_incoming = new_sequence_number;
+						ERROR_PROPAGATE(
+						    tcp_queue_received_packet(
+						    socket, socket_data, packet,
+						    1, packet_get_data_length(
+						    packet)));
+						socket_data->next_incoming =
+						    new_sequence_number;
 						packet = next_packet;
 						continue;
@@ -598,12 +711,15 @@
 				}
 				// remove the duplicit or corrupted packet
-				pq_release_remote(tcp_globals.net_phone, packet_get_id(packet));
+				pq_release_remote(tcp_globals.net_phone,
+				    packet_get_id(packet));
 				packet = next_packet;
 				continue;
-			}else{
+			} else {
 				break;
 			}
 		}
-	}else if(IS_IN_INTERVAL(socket_data->next_incoming, new_sequence_number, socket_data->next_incoming + socket_data->window)){
+	} else if (IS_IN_INTERVAL(socket_data->next_incoming,
+	    new_sequence_number,
+	    socket_data->next_incoming + socket_data->window)) {
 		printf("in window\n");
 		// process acknowledgement
@@ -612,27 +728,33 @@
 		// remove the header
 		total_length -= TCP_HEADER_LENGTH(header);
-		if(ERROR_OCCURRED(packet_trim(packet, TCP_HEADER_LENGTH(header), 0))){
+		if (ERROR_OCCURRED(packet_trim(packet,
+		    TCP_HEADER_LENGTH(header), 0)))
 			return tcp_release_and_return(packet, ERROR_CODE);
-		}
 
 		next_packet = pq_detach(packet);
 		length = packet_get_data_length(packet);
-		if(ERROR_OCCURRED(pq_add(&socket_data->incoming, packet, new_sequence_number, length))){
+		if (ERROR_OCCURRED(pq_add(&socket_data->incoming, packet,
+		    new_sequence_number, length))) {
 			// remove the corrupted packets
-			pq_release_remote(tcp_globals.net_phone, packet_get_id(packet));
-			pq_release_remote(tcp_globals.net_phone, packet_get_id(next_packet));
-		}else{
-			while(next_packet){
+			pq_release_remote(tcp_globals.net_phone,
+			    packet_get_id(packet));
+			pq_release_remote(tcp_globals.net_phone,
+			    packet_get_id(next_packet));
+		} else {
+			while (next_packet) {
 				new_sequence_number += length;
 				tmp_packet = pq_detach(next_packet);
 				length = packet_get_data_length(next_packet);
-				if(ERROR_OCCURRED(pq_set_order(next_packet, new_sequence_number, length))
-					|| ERROR_OCCURRED(pq_insert_after(packet, next_packet))){
-					pq_release_remote(tcp_globals.net_phone, packet_get_id(next_packet));
+				if (ERROR_OCCURRED(pq_set_order(next_packet,
+				    new_sequence_number, length)) ||
+				    ERROR_OCCURRED(pq_insert_after(packet,
+				    next_packet))) {
+					pq_release_remote(tcp_globals.net_phone,
+					    packet_get_id(next_packet));
 				}
 				next_packet = tmp_packet;
 			}
 		}
-	}else{
+	} else {
 		printf("unexpected\n");
 		// release duplicite or restricted
@@ -641,32 +763,43 @@
 
 	// change state according to the acknowledging incoming fin
-	if(IS_IN_INTERVAL_OVERFLOW(old_incoming, socket_data->fin_incoming, socket_data->next_incoming)){
-		switch(socket_data->state){
-			case TCP_SOCKET_FIN_WAIT_1:
-			case TCP_SOCKET_FIN_WAIT_2:
-			case TCP_SOCKET_CLOSING:
-				socket_data->state = TCP_SOCKET_CLOSING;
-				break;
+	if (IS_IN_INTERVAL_OVERFLOW(old_incoming, socket_data->fin_incoming,
+	    socket_data->next_incoming)) {
+		switch (socket_data->state) {
+		case TCP_SOCKET_FIN_WAIT_1:
+		case TCP_SOCKET_FIN_WAIT_2:
+		case TCP_SOCKET_CLOSING:
+			socket_data->state = TCP_SOCKET_CLOSING;
+			break;
 			//case TCP_ESTABLISHED:
-			default:
-				socket_data->state = TCP_SOCKET_CLOSE_WAIT;
-				break;
+		default:
+			socket_data->state = TCP_SOCKET_CLOSE_WAIT;
+			break;
 		}
 	}
 
 	packet = tcp_get_packets_to_send(socket, socket_data);
-	if(! packet){
+	if (!packet) {
 		// create the notification packet
-		ERROR_PROPAGATE(tcp_create_notification_packet(&packet, socket, socket_data, 0, 0));
-		ERROR_PROPAGATE(tcp_queue_prepare_packet(socket, socket_data, packet, 1));
-		packet = tcp_send_prepare_packet(socket, socket_data, packet, 1, socket_data->last_outgoing + 1);
-	}
+		ERROR_PROPAGATE(tcp_create_notification_packet(&packet, socket,
+		    socket_data, 0, 0));
+		ERROR_PROPAGATE(tcp_queue_prepare_packet(socket, socket_data,
+		    packet, 1));
+		packet = tcp_send_prepare_packet(socket, socket_data, packet, 1,
+		    socket_data->last_outgoing + 1);
+	}
+
 	fibril_rwlock_write_unlock(socket_data->local_lock);
+
 	// send the packet
 	tcp_send_packets(socket_data->device_id, packet);
+
 	return EOK;
 }
 
-int tcp_queue_received_packet(socket_core_ref socket, tcp_socket_data_ref socket_data, packet_t packet, int fragments, size_t total_length){
+int
+tcp_queue_received_packet(socket_core_ref socket,
+    tcp_socket_data_ref socket_data, packet_t packet, int fragments,
+    size_t total_length)
+{
 	ERROR_DECLARE;
 
@@ -681,6 +814,9 @@
 
 	// queue the received packet
-	if(ERROR_OCCURRED(dyn_fifo_push(&socket->received, packet_get_id(packet), SOCKET_MAX_RECEIVED_SIZE))
-	    || ERROR_OCCURRED(tl_get_ip_packet_dimension(tcp_globals.ip_phone, &tcp_globals.dimensions, socket_data->device_id, &packet_dimension))){
+	if (ERROR_OCCURRED(dyn_fifo_push(&socket->received,
+	    packet_get_id(packet), SOCKET_MAX_RECEIVED_SIZE)) ||
+	    ERROR_OCCURRED(tl_get_ip_packet_dimension(tcp_globals.ip_phone,
+	    &tcp_globals.dimensions, socket_data->device_id,
+	    &packet_dimension))) {
 		return tcp_release_and_return(packet, ERROR_CODE);
 	}
@@ -690,9 +826,17 @@
 
 	// notify the destination socket
-	async_msg_5(socket->phone, NET_SOCKET_RECEIVED, (ipcarg_t) socket->socket_id, ((packet_dimension->content < socket_data->data_fragment_size) ? packet_dimension->content : socket_data->data_fragment_size), 0, 0, (ipcarg_t) fragments);
+	async_msg_5(socket->phone, NET_SOCKET_RECEIVED,
+	    (ipcarg_t) socket->socket_id,
+	    ((packet_dimension->content < socket_data->data_fragment_size) ?
+	    packet_dimension->content : socket_data->data_fragment_size), 0, 0,
+	    (ipcarg_t) fragments);
+
 	return EOK;
 }
 
-int tcp_process_syn_sent(socket_core_ref socket, tcp_socket_data_ref socket_data, tcp_header_ref header, packet_t packet){
+int
+tcp_process_syn_sent(socket_core_ref socket, tcp_socket_data_ref socket_data,
+    tcp_header_ref header, packet_t packet)
+{
 	ERROR_DECLARE;
 
@@ -705,41 +849,50 @@
 	assert(packet);
 
-	if(header->synchronize){
-		// process acknowledgement
-		tcp_process_acknowledgement(socket, socket_data, header);
-
-		socket_data->next_incoming = ntohl(header->sequence_number) + 1;
-		// release additional packets
-		next_packet = pq_detach(packet);
-		if(next_packet){
-			pq_release_remote(tcp_globals.net_phone, packet_get_id(next_packet));
-		}
-		// trim if longer than the header
-		if((packet_get_data_length(packet) > sizeof(*header))
-			&& ERROR_OCCURRED(packet_trim(packet, 0, packet_get_data_length(packet) - sizeof(*header)))){
-			return tcp_release_and_return(packet, ERROR_CODE);
-		}
-		tcp_prepare_operation_header(socket, socket_data, header, 0, 0);
-		fibril_mutex_lock(&socket_data->operation.mutex);
-		socket_data->operation.result = tcp_queue_packet(socket, socket_data, packet, 1);
-		if(socket_data->operation.result == EOK){
-			socket_data->state = TCP_SOCKET_ESTABLISHED;
-			packet = tcp_get_packets_to_send(socket, socket_data);
-			if(packet){
-				fibril_rwlock_write_unlock(socket_data->local_lock);
-				// send the packet
-				tcp_send_packets(socket_data->device_id, packet);
-				// signal the result
-				fibril_condvar_signal(&socket_data->operation.condvar);
-				fibril_mutex_unlock(&socket_data->operation.mutex);
-				return EOK;
-			}
-		}
-		fibril_mutex_unlock(&socket_data->operation.mutex);
-	}
+	if (!header->synchronize)
+		return tcp_release_and_return(packet, EINVAL);
+	
+	// process acknowledgement
+	tcp_process_acknowledgement(socket, socket_data, header);
+
+	socket_data->next_incoming = ntohl(header->sequence_number) + 1;
+	// release additional packets
+	next_packet = pq_detach(packet);
+	if (next_packet) {
+		pq_release_remote(tcp_globals.net_phone,
+		    packet_get_id(next_packet));
+	}
+	// trim if longer than the header
+	if ((packet_get_data_length(packet) > sizeof(*header)) &&
+	    ERROR_OCCURRED(packet_trim(packet, 0,
+	    packet_get_data_length(packet) - sizeof(*header)))) {
+		return tcp_release_and_return(packet, ERROR_CODE);
+	}
+	tcp_prepare_operation_header(socket, socket_data, header, 0, 0);
+	fibril_mutex_lock(&socket_data->operation.mutex);
+	socket_data->operation.result = tcp_queue_packet(socket, socket_data,
+	    packet, 1);
+	if (socket_data->operation.result == EOK) {
+		socket_data->state = TCP_SOCKET_ESTABLISHED;
+		packet = tcp_get_packets_to_send(socket, socket_data);
+		if (packet) {
+			fibril_rwlock_write_unlock( socket_data->local_lock);
+			// send the packet
+			tcp_send_packets(socket_data->device_id, packet);
+			// signal the result
+			fibril_condvar_signal( &socket_data->operation.condvar);
+			fibril_mutex_unlock( &socket_data->operation.mutex);
+			return EOK;
+		}
+	}
+	fibril_mutex_unlock(&socket_data->operation.mutex);
 	return tcp_release_and_return(packet, EINVAL);
 }
 
-int tcp_process_listen(socket_core_ref listening_socket, tcp_socket_data_ref listening_socket_data, tcp_header_ref header, packet_t packet, struct sockaddr * src, struct sockaddr * dest, size_t addrlen){
+int
+tcp_process_listen(socket_core_ref listening_socket,
+    tcp_socket_data_ref listening_socket_data, tcp_header_ref header,
+    packet_t packet, struct sockaddr *src, struct sockaddr *dest,
+    size_t addrlen)
+{
 	ERROR_DECLARE;
 
@@ -757,128 +910,144 @@
 	assert(packet);
 
-//	printf("syn %d\n", header->synchronize);
-	if(header->synchronize){
-		socket_data = (tcp_socket_data_ref) malloc(sizeof(*socket_data));
-		if(! socket_data){
-			return tcp_release_and_return(packet, ENOMEM);
-		}else{
-			tcp_initialize_socket_data(socket_data);
-			socket_data->local_lock = listening_socket_data->local_lock;
-			socket_data->local_sockets = listening_socket_data->local_sockets;
-			socket_data->listening_socket_id = listening_socket->socket_id;
-
-			socket_data->next_incoming = ntohl(header->sequence_number);
-			socket_data->treshold = socket_data->next_incoming + ntohs(header->window);
-
-			socket_data->addrlen = addrlen;
-			socket_data->addr = malloc(socket_data->addrlen);
-			if(! socket_data->addr){
-				free(socket_data);
-				return tcp_release_and_return(packet, ENOMEM);
-			}
-			memcpy(socket_data->addr, src, socket_data->addrlen);
-
-			socket_data->dest_port = ntohs(header->source_port);
-			if(ERROR_OCCURRED(tl_set_address_port(socket_data->addr, socket_data->addrlen, socket_data->dest_port))){
-				free(socket_data->addr);
-				free(socket_data);
-				pq_release_remote(tcp_globals.net_phone, packet_get_id(packet));
-				return ERROR_CODE;
-			}
-
-//			printf("addr %p\n", socket_data->addr, socket_data->addrlen);
-			// create a socket
-			socket_id = -1;
-			if(ERROR_OCCURRED(socket_create(socket_data->local_sockets, listening_socket->phone, socket_data, &socket_id))){
-				free(socket_data->addr);
-				free(socket_data);
-				return tcp_release_and_return(packet, ERROR_CODE);
-			}
-
-			printf("new_sock %d\n", socket_id);
-			socket_data->pseudo_header = listening_socket_data->pseudo_header;
-			socket_data->headerlen = listening_socket_data->headerlen;
-			listening_socket_data->pseudo_header = NULL;
-			listening_socket_data->headerlen = 0;
-
-			fibril_rwlock_write_unlock(socket_data->local_lock);
-//			printf("list lg\n");
-			fibril_rwlock_write_lock(&tcp_globals.lock);
-//			printf("list locked\n");
-			// find the destination socket
-			listening_socket = socket_port_find(&tcp_globals.sockets, listening_port, SOCKET_MAP_KEY_LISTENING, 0);
-			if((! listening_socket) || (listening_socket->socket_id != listening_socket_id)){
-				fibril_rwlock_write_unlock(&tcp_globals.lock);
-				// a shadow may remain until app hangs up
-				return tcp_release_and_return(packet, EOK/*ENOTSOCK*/);
-			}
-//			printf("port %d\n", listening_socket->port);
-			listening_socket_data = (tcp_socket_data_ref) listening_socket->specific_data;
-			assert(listening_socket_data);
-
-//			printf("list ll\n");
-			fibril_rwlock_write_lock(listening_socket_data->local_lock);
-//			printf("list locked\n");
-
-			socket = socket_cores_find(listening_socket_data->local_sockets, socket_id);
-			if(! socket){
-				// where is the socket?!?
-				fibril_rwlock_write_unlock(&tcp_globals.lock);
-				return ENOTSOCK;
-			}
-			socket_data = (tcp_socket_data_ref) socket->specific_data;
-			assert(socket_data);
-
-//			uint8_t * data = socket_data->addr;
-//			printf("addr %d of %x %x %x %x-%x %x %x %x-%x %x %x %x-%x %x %x %x\n", socket_data->addrlen, data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7], data[8], data[9], data[10], data[11], data[12], data[13], data[14], data[15]);
-
-			ERROR_CODE = socket_port_add(&tcp_globals.sockets, listening_port, socket, (const char *) socket_data->addr, socket_data->addrlen);
-			assert(socket == socket_port_find(&tcp_globals.sockets, listening_port, (const char *) socket_data->addr, socket_data->addrlen));
-			//ERROR_CODE = socket_bind_free_port(&tcp_globals.sockets, socket, TCP_FREE_PORTS_START, TCP_FREE_PORTS_END, tcp_globals.last_used_port);
-			//tcp_globals.last_used_port = socket->port;
-//			printf("bound %d\n", socket->port);
-			fibril_rwlock_write_unlock(&tcp_globals.lock);
-			if(ERROR_CODE != EOK){
-				socket_destroy(tcp_globals.net_phone, socket->socket_id, socket_data->local_sockets, &tcp_globals.sockets, tcp_free_socket_data);
-				return tcp_release_and_return(packet, ERROR_CODE);
-			}
-
-			socket_data->state = TCP_SOCKET_LISTEN;
-			socket_data->next_incoming = ntohl(header->sequence_number) + 1;
-			// release additional packets
-			next_packet = pq_detach(packet);
-			if(next_packet){
-				pq_release_remote(tcp_globals.net_phone, packet_get_id(next_packet));
-			}
-			// trim if longer than the header
-			if((packet_get_data_length(packet) > sizeof(*header))
-				&& ERROR_OCCURRED(packet_trim(packet, 0, packet_get_data_length(packet) - sizeof(*header)))){
-				socket_destroy(tcp_globals.net_phone, socket->socket_id, socket_data->local_sockets, &tcp_globals.sockets, tcp_free_socket_data);
-				return tcp_release_and_return(packet, ERROR_CODE);
-			}
-			tcp_prepare_operation_header(socket, socket_data, header, 1, 0);
-			if(ERROR_OCCURRED(tcp_queue_packet(socket, socket_data, packet, 1))){
-				socket_destroy(tcp_globals.net_phone, socket->socket_id, socket_data->local_sockets, &tcp_globals.sockets, tcp_free_socket_data);
-				return ERROR_CODE;
-			}
-			packet = tcp_get_packets_to_send(socket, socket_data);
-//			printf("send %d\n", packet_get_id(packet));
-			if(! packet){
-				socket_destroy(tcp_globals.net_phone, socket->socket_id, socket_data->local_sockets, &tcp_globals.sockets, tcp_free_socket_data);
-				return EINVAL;
-			}else{
-				socket_data->state = TCP_SOCKET_SYN_RECEIVED;
-//				printf("unlock\n");
-				fibril_rwlock_write_unlock(socket_data->local_lock);
-				// send the packet
-				tcp_send_packets(socket_data->device_id, packet);
-				return EOK;
-			}
-		}
-	}
-	return tcp_release_and_return(packet, EINVAL);
-}
-
-int tcp_process_syn_received(socket_core_ref socket, tcp_socket_data_ref socket_data, tcp_header_ref header, packet_t packet){
+	if (!header->synchronize)
+		return tcp_release_and_return(packet, EINVAL);
+
+	socket_data = (tcp_socket_data_ref) malloc(sizeof(*socket_data));
+	if (!socket_data)
+		return tcp_release_and_return(packet, ENOMEM);
+
+	tcp_initialize_socket_data(socket_data);
+	socket_data->local_lock = listening_socket_data->local_lock;
+	socket_data->local_sockets = listening_socket_data->local_sockets;
+	socket_data->listening_socket_id = listening_socket->socket_id;
+	socket_data->next_incoming = ntohl(header->sequence_number);
+	socket_data->treshold = socket_data->next_incoming +
+	    ntohs(header->window);
+	socket_data->addrlen = addrlen;
+	socket_data->addr = malloc(socket_data->addrlen);
+	if (!socket_data->addr) {
+		free(socket_data);
+		return tcp_release_and_return(packet, ENOMEM);
+	}
+	memcpy(socket_data->addr, src, socket_data->addrlen);
+	socket_data->dest_port = ntohs(header->source_port);
+	if (ERROR_OCCURRED(tl_set_address_port(socket_data->addr,
+	    socket_data->addrlen, socket_data->dest_port))) {
+		free(socket_data->addr);
+		free(socket_data);
+		pq_release_remote(tcp_globals.net_phone, packet_get_id(packet));
+		return ERROR_CODE;
+	}
+
+	// create a socket
+	socket_id = -1;
+	if (ERROR_OCCURRED(socket_create(socket_data->local_sockets,
+	    listening_socket->phone, socket_data, &socket_id))) {
+		free(socket_data->addr);
+		free(socket_data);
+		return tcp_release_and_return(packet, ERROR_CODE);
+	}
+
+	printf("new_sock %d\n", socket_id);
+	socket_data->pseudo_header = listening_socket_data->pseudo_header;
+	socket_data->headerlen = listening_socket_data->headerlen;
+	listening_socket_data->pseudo_header = NULL;
+	listening_socket_data->headerlen = 0;
+
+	fibril_rwlock_write_unlock(socket_data->local_lock);
+	fibril_rwlock_write_lock(&tcp_globals.lock);
+
+	// find the destination socket
+	listening_socket = socket_port_find(&tcp_globals.sockets,
+	    listening_port, SOCKET_MAP_KEY_LISTENING, 0);
+	if ((!listening_socket) ||
+	    (listening_socket->socket_id != listening_socket_id)) {
+		fibril_rwlock_write_unlock(&tcp_globals.lock);
+		// a shadow may remain until app hangs up
+		return tcp_release_and_return(packet, EOK /*ENOTSOCK*/);
+	}
+	listening_socket_data =
+	    (tcp_socket_data_ref) listening_socket->specific_data;
+	assert(listening_socket_data);
+
+	fibril_rwlock_write_lock(listening_socket_data->local_lock);
+
+	socket = socket_cores_find(listening_socket_data->local_sockets,
+	    socket_id);
+	if (!socket) {
+		// where is the socket?!?
+		fibril_rwlock_write_unlock(&tcp_globals.lock);
+		return ENOTSOCK;
+	}
+	socket_data = (tcp_socket_data_ref) socket->specific_data;
+	assert(socket_data);
+
+	ERROR_CODE = socket_port_add(&tcp_globals.sockets, listening_port,
+	    socket, (const char *) socket_data->addr, socket_data->addrlen);
+	assert(socket == socket_port_find(&tcp_globals.sockets, listening_port,
+	    (const char *) socket_data->addr, socket_data->addrlen));
+
+//	ERROR_CODE = socket_bind_free_port(&tcp_globals.sockets, socket,
+//	    TCP_FREE_PORTS_START, TCP_FREE_PORTS_END,
+//	    tcp_globals.last_used_port);
+//	tcp_globals.last_used_port = socket->port;
+	fibril_rwlock_write_unlock(&tcp_globals.lock);
+	if (ERROR_CODE != EOK) {
+		socket_destroy(tcp_globals.net_phone, socket->socket_id,
+		    socket_data->local_sockets, &tcp_globals.sockets,
+		    tcp_free_socket_data);
+		return tcp_release_and_return(packet, ERROR_CODE);
+	}
+
+	socket_data->state = TCP_SOCKET_LISTEN;
+	socket_data->next_incoming = ntohl(header->sequence_number) + 1;
+
+	// release additional packets
+	next_packet = pq_detach(packet);
+	if (next_packet) {
+		pq_release_remote(tcp_globals.net_phone,
+		    packet_get_id(next_packet));
+	}
+
+	// trim if longer than the header
+	if ((packet_get_data_length(packet) > sizeof(*header)) &&
+	    ERROR_OCCURRED(packet_trim(packet, 0,
+	    packet_get_data_length(packet) - sizeof(*header)))) {
+		socket_destroy(tcp_globals.net_phone, socket->socket_id,
+		    socket_data->local_sockets, &tcp_globals.sockets,
+		    tcp_free_socket_data);
+		return tcp_release_and_return(packet, ERROR_CODE);
+	}
+
+	tcp_prepare_operation_header(socket, socket_data, header, 1, 0);
+
+	if (ERROR_OCCURRED(tcp_queue_packet(socket, socket_data, packet, 1))) {
+		socket_destroy(tcp_globals.net_phone, socket->socket_id,
+		    socket_data->local_sockets, &tcp_globals.sockets,
+		    tcp_free_socket_data);
+		return ERROR_CODE;
+	}
+
+	packet = tcp_get_packets_to_send(socket, socket_data);
+	if (!packet) {
+		socket_destroy(tcp_globals.net_phone, socket->socket_id,
+		    socket_data->local_sockets, &tcp_globals.sockets,
+		    tcp_free_socket_data);
+		return EINVAL;
+	}
+
+	socket_data->state = TCP_SOCKET_SYN_RECEIVED;
+	fibril_rwlock_write_unlock(socket_data->local_lock);
+
+	// send the packet
+	tcp_send_packets(socket_data->device_id, packet);
+
+	return EOK;
+}
+
+int
+tcp_process_syn_received(socket_core_ref socket,
+    tcp_socket_data_ref socket_data, tcp_header_ref header, packet_t packet)
+{
 	ERROR_DECLARE;
 
@@ -892,49 +1061,60 @@
 	assert(packet);
 
-	printf("syn_rec\n");
-	if(header->acknowledge){
-		// process acknowledgement
-		tcp_process_acknowledgement(socket, socket_data, header);
-
-		socket_data->next_incoming = ntohl(header->sequence_number);// + 1;
-		pq_release_remote(tcp_globals.net_phone, packet_get_id(packet));
-		socket_data->state = TCP_SOCKET_ESTABLISHED;
-		listening_socket = socket_cores_find(socket_data->local_sockets, socket_data->listening_socket_id);
-		if(listening_socket){
-			listening_socket_data = (tcp_socket_data_ref) listening_socket->specific_data;
-			assert(listening_socket_data);
-
-			// queue the received packet
-			if(! ERROR_OCCURRED(dyn_fifo_push(&listening_socket->accepted, (-1 * socket->socket_id), listening_socket_data->backlog))){
-				// notify the destination socket
-				async_msg_5(socket->phone, NET_SOCKET_ACCEPTED, (ipcarg_t) listening_socket->socket_id, socket_data->data_fragment_size, TCP_HEADER_SIZE, 0, (ipcarg_t) socket->socket_id);
-				fibril_rwlock_write_unlock(socket_data->local_lock);
-				return EOK;
-			}
-		}
-		// send FIN
-		socket_data->state = TCP_SOCKET_FIN_WAIT_1;
-
-		// create the notification packet
-		ERROR_PROPAGATE(tcp_create_notification_packet(&packet, socket, socket_data, 0, 1));
-
+	if (!header->acknowledge)
+		return tcp_release_and_return(packet, EINVAL);
+
+	// process acknowledgement
+	tcp_process_acknowledgement(socket, socket_data, header);
+
+	socket_data->next_incoming = ntohl(header->sequence_number);	// + 1;
+	pq_release_remote(tcp_globals.net_phone, packet_get_id(packet));
+	socket_data->state = TCP_SOCKET_ESTABLISHED;
+	listening_socket = socket_cores_find(socket_data->local_sockets,
+	    socket_data->listening_socket_id);
+	if (listening_socket) {
+		listening_socket_data =
+		    (tcp_socket_data_ref) listening_socket->specific_data;
+		assert(listening_socket_data);
+
+		// queue the received packet
+		if (ERROR_NONE(dyn_fifo_push(&listening_socket->accepted,
+		    (-1 * socket->socket_id),
+		    listening_socket_data->backlog))) {
+
+			// notify the destination socket
+			async_msg_5(socket->phone, NET_SOCKET_ACCEPTED,
+			    (ipcarg_t) listening_socket->socket_id,
+			    socket_data->data_fragment_size, TCP_HEADER_SIZE,
+			    0, (ipcarg_t) socket->socket_id);
+
+			fibril_rwlock_write_unlock(socket_data->local_lock);
+			return EOK;
+		}
+	}
+	// send FIN
+	socket_data->state = TCP_SOCKET_FIN_WAIT_1;
+
+	// create the notification packet
+	ERROR_PROPAGATE(tcp_create_notification_packet(&packet, socket,
+	    socket_data, 0, 1));
+
+	// send the packet
+	ERROR_PROPAGATE(tcp_queue_packet(socket, socket_data, packet, 1));
+
+	// flush packets
+	packet = tcp_get_packets_to_send(socket, socket_data);
+	fibril_rwlock_write_unlock(socket_data->local_lock);
+	if (packet) {
 		// send the packet
-		ERROR_PROPAGATE(tcp_queue_packet(socket, socket_data, packet, 1));
-
-		// flush packets
-		packet = tcp_get_packets_to_send(socket, socket_data);
-		fibril_rwlock_write_unlock(socket_data->local_lock);
-		if(packet){
-			// send the packet
-			tcp_send_packets(socket_data->device_id, packet);
-		}
-		return EOK;
-	}else{
-		return tcp_release_and_return(packet, EINVAL);
-	}
-	return EINVAL;
-}
-
-void tcp_process_acknowledgement(socket_core_ref socket, tcp_socket_data_ref socket_data, tcp_header_ref header){
+		tcp_send_packets(socket_data->device_id, packet);
+	}
+
+	return EOK;
+}
+
+void
+tcp_process_acknowledgement(socket_core_ref socket,
+    tcp_socket_data_ref socket_data, tcp_header_ref header)
+{
 	size_t number;
 	size_t length;
@@ -949,65 +1129,78 @@
 	assert(header);
 
-	if(header->acknowledge){
-		number = ntohl(header->acknowledgement_number);
-		// if more data acknowledged
-		if(number != socket_data->expected){
-			old = socket_data->expected;
-			if(IS_IN_INTERVAL_OVERFLOW(old, socket_data->fin_outgoing, number)){
-				switch(socket_data->state){
-					case TCP_SOCKET_FIN_WAIT_1:
-						socket_data->state = TCP_SOCKET_FIN_WAIT_2;
-						break;
-					case TCP_SOCKET_LAST_ACK:
-					case TCP_SOCKET_CLOSING:
-						// fin acknowledged - release the socket in another fibril
-						tcp_prepare_timeout(tcp_release_after_timeout, socket, socket_data, 0, TCP_SOCKET_TIME_WAIT, NET_DEFAULT_TCP_TIME_WAIT_TIMEOUT, true);
-						break;
-					default:
-						break;
-				}
+	if (!header->acknowledge)
+		return;
+
+	number = ntohl(header->acknowledgement_number);
+	// if more data acknowledged
+	if (number != socket_data->expected) {
+		old = socket_data->expected;
+		if (IS_IN_INTERVAL_OVERFLOW(old, socket_data->fin_outgoing,
+		    number)) {
+			switch (socket_data->state) {
+			case TCP_SOCKET_FIN_WAIT_1:
+				socket_data->state = TCP_SOCKET_FIN_WAIT_2;
+				break;
+			case TCP_SOCKET_LAST_ACK:
+			case TCP_SOCKET_CLOSING:
+				// fin acknowledged - release the socket in
+				// another fibril
+				tcp_prepare_timeout(tcp_release_after_timeout,
+				    socket, socket_data, 0,
+				    TCP_SOCKET_TIME_WAIT,
+				    NET_DEFAULT_TCP_TIME_WAIT_TIMEOUT, true);
+				break;
+			default:
+				break;
 			}
-			// update the treshold if higher than set
-			if(number + ntohs(header->window) > socket_data->expected + socket_data->treshold){
-				socket_data->treshold = number + ntohs(header->window) - socket_data->expected;
-			}
-			// set new expected sequence number
-			socket_data->expected = number;
+		}
+		// update the treshold if higher than set
+		if (number + ntohs(header->window) >
+		    socket_data->expected + socket_data->treshold) {
+			socket_data->treshold = number + ntohs(header->window) -
+			    socket_data->expected;
+		}
+		// set new expected sequence number
+		socket_data->expected = number;
+		socket_data->expected_count = 1;
+		packet = socket_data->outgoing;
+		while (pq_get_order(packet, &number, &length) == EOK) {
+			if (IS_IN_INTERVAL_OVERFLOW((uint32_t) old,
+			    (uint32_t) (number + length),
+			    (uint32_t) socket_data->expected)) {
+				next = pq_detach(packet);
+				if (packet == socket_data->outgoing)
+					socket_data->outgoing = next;
+
+				// add to acknowledged or release
+				if (pq_add(&acknowledged, packet, 0, 0) != EOK)
+					pq_release_remote(tcp_globals.net_phone,
+					    packet_get_id(packet));
+				packet = next;
+			} else if (old < socket_data->expected)
+				break;
+		}
+		// release acknowledged
+		if (acknowledged) {
+			pq_release_remote(tcp_globals.net_phone,
+			    packet_get_id(acknowledged));
+		}
+		return;
+		// if the same as the previous time
+	}
+	if (number == socket_data->expected) {
+		// increase the counter
+		++socket_data->expected_count;
+		if (socket_data->expected_count == TCP_FAST_RETRANSMIT_COUNT) {
 			socket_data->expected_count = 1;
-			packet = socket_data->outgoing;
-			while(pq_get_order(packet, &number, &length) == EOK){
-				if(IS_IN_INTERVAL_OVERFLOW((uint32_t) old, (uint32_t)(number + length), (uint32_t) socket_data->expected)){
-					next = pq_detach(packet);
-					if(packet == socket_data->outgoing){
-						socket_data->outgoing = next;
-					}
-					// add to acknowledged or release
-					if(pq_add(&acknowledged, packet, 0, 0) != EOK){
-						pq_release_remote(tcp_globals.net_phone, packet_get_id(packet));
-					}
-					packet = next;
-				}else if(old < socket_data->expected){
-					break;
-				}
-			}
-			// release acknowledged
-			if(acknowledged){
-				pq_release_remote(tcp_globals.net_phone, packet_get_id(acknowledged));
-			}
-			return;
-		// if the same as the previous time
-		}else if(number == socket_data->expected){
-			// increase the counter
-			++ socket_data->expected_count;
-			if(socket_data->expected_count == TCP_FAST_RETRANSMIT_COUNT){
-				socket_data->expected_count = 1;
-				// TODO retransmit lock
-				//tcp_retransmit_packet(socket, socket_data, number);
-			}
-		}
-	}
-}
-
-int tcp_message_standalone(ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count){
+			// TODO retransmit lock
+			//tcp_retransmit_packet(socket, socket_data, number);
+		}
+	}
+}
+
+int tcp_message_standalone(ipc_callid_t callid, ipc_call_t * call,
+    ipc_call_t * answer, int *answer_count)
+{
 	ERROR_DECLARE;
 
@@ -1019,19 +1212,24 @@
 
 	*answer_count = 0;
-	switch(IPC_GET_METHOD(*call)){
-		case NET_TL_RECEIVED:
-			//fibril_rwlock_read_lock(&tcp_globals.lock);
-			if(! ERROR_OCCURRED(packet_translate_remote(tcp_globals.net_phone, &packet, IPC_GET_PACKET(call)))){
-				ERROR_CODE = tcp_received_msg(IPC_GET_DEVICE(call), packet, SERVICE_TCP, IPC_GET_ERROR(call));
-			}
-			//fibril_rwlock_read_unlock(&tcp_globals.lock);
-			return ERROR_CODE;
-		case IPC_M_CONNECT_TO_ME:
-			return tcp_process_client_messages(callid, * call);
-	}
+	switch (IPC_GET_METHOD(*call)) {
+	case NET_TL_RECEIVED:
+		//fibril_rwlock_read_lock(&tcp_globals.lock);
+		if (ERROR_NONE(packet_translate_remote(tcp_globals.net_phone,
+		    &packet, IPC_GET_PACKET(call)))) {
+			ERROR_CODE = tcp_received_msg(IPC_GET_DEVICE(call),
+			    packet, SERVICE_TCP, IPC_GET_ERROR(call));
+		}
+		//fibril_rwlock_read_unlock(&tcp_globals.lock);
+		return ERROR_CODE;
+
+	case IPC_M_CONNECT_TO_ME:
+		return tcp_process_client_messages(callid, *call);
+	}
+
 	return ENOTSUP;
 }
 
-void tcp_refresh_socket_data(tcp_socket_data_ref socket_data){
+void tcp_refresh_socket_data(tcp_socket_data_ref socket_data)
+{
 	assert(socket_data);
 
@@ -1048,5 +1246,6 @@
 }
 
-void tcp_initialize_socket_data(tcp_socket_data_ref socket_data){
+void tcp_initialize_socket_data(tcp_socket_data_ref socket_data)
+{
 	assert(socket_data);
 
@@ -1057,10 +1256,11 @@
 }
 
-int tcp_process_client_messages(ipc_callid_t callid, ipc_call_t call){
+int tcp_process_client_messages(ipc_callid_t callid, ipc_call_t call)
+{
 	int res;
 	bool keep_on_going = true;
 	socket_cores_t local_sockets;
 	int app_phone = IPC_GET_PHONE(&call);
-	struct sockaddr * addr;
+	struct sockaddr *addr;
 	int socket_id;
 	size_t addrlen;
@@ -1083,168 +1283,208 @@
 	fibril_rwlock_initialize(&lock);
 
-	while(keep_on_going){
+	while (keep_on_going) {
 
 		// answer the call
 		answer_call(callid, res, &answer, answer_count);
-
 		// refresh data
 		refresh_answer(&answer, &answer_count);
-
 		// get the next call
 		callid = async_get_call(&call);
 
 		// process the call
-		switch(IPC_GET_METHOD(call)){
-			case IPC_M_PHONE_HUNGUP:
-				keep_on_going = false;
-				res = EHANGUP;
+		switch (IPC_GET_METHOD(call)) {
+		case IPC_M_PHONE_HUNGUP:
+			keep_on_going = false;
+			res = EHANGUP;
+			break;
+
+		case NET_SOCKET:
+			socket_data =
+			    (tcp_socket_data_ref) malloc(sizeof(*socket_data));
+			if (!socket_data) {
+				res = ENOMEM;
 				break;
-			case NET_SOCKET:
-				socket_data = (tcp_socket_data_ref) malloc(sizeof(*socket_data));
-				if(! socket_data){
-					res = ENOMEM;
-				}else{
-					tcp_initialize_socket_data(socket_data);
-					socket_data->local_lock = &lock;
-					socket_data->local_sockets = &local_sockets;
-					fibril_rwlock_write_lock(&lock);
-					socket_id = SOCKET_GET_SOCKET_ID(call);
-					res = socket_create(&local_sockets, app_phone, socket_data, &socket_id);
-					SOCKET_SET_SOCKET_ID(answer, socket_id);
-					fibril_rwlock_write_unlock(&lock);
-					if(res == EOK){
-						if (tl_get_ip_packet_dimension(tcp_globals.ip_phone, &tcp_globals.dimensions, DEVICE_INVALID_ID, &packet_dimension) == EOK){
-							SOCKET_SET_DATA_FRAGMENT_SIZE(answer, ((packet_dimension->content < socket_data->data_fragment_size) ? packet_dimension->content : socket_data->data_fragment_size));
-						}
-//						SOCKET_SET_DATA_FRAGMENT_SIZE(answer, MAX_TCP_FRAGMENT_SIZE);
-						SOCKET_SET_HEADER_SIZE(answer, TCP_HEADER_SIZE);
-						answer_count = 3;
-					}else{
-						free(socket_data);
-					}
+			}
+			
+			tcp_initialize_socket_data(socket_data);
+			socket_data->local_lock = &lock;
+			socket_data->local_sockets = &local_sockets;
+			fibril_rwlock_write_lock(&lock);
+			socket_id = SOCKET_GET_SOCKET_ID(call);
+			res = socket_create(&local_sockets, app_phone,
+			    socket_data, &socket_id);
+			SOCKET_SET_SOCKET_ID(answer, socket_id);
+			fibril_rwlock_write_unlock(&lock);
+			if (res != EOK) {
+				free(socket_data);
+				break;
+			}
+			if (tl_get_ip_packet_dimension(tcp_globals.ip_phone,
+			    &tcp_globals.dimensions, DEVICE_INVALID_ID,
+			    &packet_dimension) == EOK) {
+				SOCKET_SET_DATA_FRAGMENT_SIZE(answer,
+				    ((packet_dimension->content <
+				    socket_data->data_fragment_size) ?
+				    packet_dimension->content :
+				    socket_data->data_fragment_size));
+			}
+//                      SOCKET_SET_DATA_FRAGMENT_SIZE(answer, MAX_TCP_FRAGMENT_SIZE);
+			SOCKET_SET_HEADER_SIZE(answer, TCP_HEADER_SIZE);
+			answer_count = 3;
+			break;
+
+		case NET_SOCKET_BIND:
+			res = data_receive((void **) &addr, &addrlen);
+			if (res != EOK)
+				break;
+			fibril_rwlock_write_lock(&tcp_globals.lock);
+			fibril_rwlock_write_lock(&lock);
+			res = socket_bind(&local_sockets, &tcp_globals.sockets,
+			    SOCKET_GET_SOCKET_ID(call), addr, addrlen,
+			    TCP_FREE_PORTS_START, TCP_FREE_PORTS_END,
+			    tcp_globals.last_used_port);
+			if (res == EOK) {
+				socket = socket_cores_find(&local_sockets,
+				    SOCKET_GET_SOCKET_ID(call));
+				if (socket) {
+					socket_data = (tcp_socket_data_ref)
+					    socket->specific_data;
+					assert(socket_data);
+					socket_data->state = TCP_SOCKET_LISTEN;
 				}
+			}
+			fibril_rwlock_write_unlock(&lock);
+			fibril_rwlock_write_unlock(&tcp_globals.lock);
+			free(addr);
+			break;
+
+		case NET_SOCKET_LISTEN:
+			fibril_rwlock_read_lock(&tcp_globals.lock);
+//                      fibril_rwlock_write_lock(&tcp_globals.lock);
+			fibril_rwlock_write_lock(&lock);
+			res = tcp_listen_message(&local_sockets,
+			    SOCKET_GET_SOCKET_ID(call),
+			    SOCKET_GET_BACKLOG(call));
+			fibril_rwlock_write_unlock(&lock);
+//                      fibril_rwlock_write_unlock(&tcp_globals.lock);
+			fibril_rwlock_read_unlock(&tcp_globals.lock);
+			break;
+
+		case NET_SOCKET_CONNECT:
+			res = data_receive((void **) &addr, &addrlen);
+			if (res != EOK)
 				break;
-			case NET_SOCKET_BIND:
-				res = data_receive((void **) &addr, &addrlen);
-				if(res == EOK){
-					fibril_rwlock_write_lock(&tcp_globals.lock);
-					fibril_rwlock_write_lock(&lock);
-					res = socket_bind(&local_sockets, &tcp_globals.sockets, SOCKET_GET_SOCKET_ID(call), addr, addrlen, TCP_FREE_PORTS_START, TCP_FREE_PORTS_END, tcp_globals.last_used_port);
-					if(res == EOK){
-						socket = socket_cores_find(&local_sockets, SOCKET_GET_SOCKET_ID(call));
-						if(socket){
-							socket_data = (tcp_socket_data_ref) socket->specific_data;
-							assert(socket_data);
-							socket_data->state = TCP_SOCKET_LISTEN;
-						}
-					}
-					fibril_rwlock_write_unlock(&lock);
-					fibril_rwlock_write_unlock(&tcp_globals.lock);
-					free(addr);
-				}
-				break;
-			case NET_SOCKET_LISTEN:
-				fibril_rwlock_read_lock(&tcp_globals.lock);
-//				fibril_rwlock_write_lock(&tcp_globals.lock);
-				fibril_rwlock_write_lock(&lock);
-				res = tcp_listen_message(&local_sockets, SOCKET_GET_SOCKET_ID(call), SOCKET_GET_BACKLOG(call));
+			// the global lock may be released in the
+			// tcp_connect_message() function
+			fibril_rwlock_write_lock(&tcp_globals.lock);
+			fibril_rwlock_write_lock(&lock);
+			res = tcp_connect_message(&local_sockets,
+			    SOCKET_GET_SOCKET_ID(call), addr, addrlen);
+			if (res != EOK) {
 				fibril_rwlock_write_unlock(&lock);
-//				fibril_rwlock_write_unlock(&tcp_globals.lock);
-				fibril_rwlock_read_unlock(&tcp_globals.lock);
-				break;
-			case NET_SOCKET_CONNECT:
-				res = data_receive((void **) &addr, &addrlen);
-				if(res == EOK){
-					// the global lock may be released in the tcp_connect_message() function
-					fibril_rwlock_write_lock(&tcp_globals.lock);
-					fibril_rwlock_write_lock(&lock);
-					res = tcp_connect_message(&local_sockets, SOCKET_GET_SOCKET_ID(call), addr, addrlen);
-					if(res != EOK){
-						fibril_rwlock_write_unlock(&lock);
-						fibril_rwlock_write_unlock(&tcp_globals.lock);
-						free(addr);
-					}
-				}
-				break;
-			case NET_SOCKET_ACCEPT:
-				fibril_rwlock_read_lock(&tcp_globals.lock);
-				fibril_rwlock_write_lock(&lock);
-				res = tcp_accept_message(&local_sockets, SOCKET_GET_SOCKET_ID(call), SOCKET_GET_NEW_SOCKET_ID(call), &size, &addrlen);
-				SOCKET_SET_DATA_FRAGMENT_SIZE(answer, size);
+				fibril_rwlock_write_unlock(&tcp_globals.lock);
+				free(addr);
+			}
+			break;
+
+		case NET_SOCKET_ACCEPT:
+			fibril_rwlock_read_lock(&tcp_globals.lock);
+			fibril_rwlock_write_lock(&lock);
+			res = tcp_accept_message(&local_sockets,
+			    SOCKET_GET_SOCKET_ID(call),
+			    SOCKET_GET_NEW_SOCKET_ID(call), &size, &addrlen);
+			SOCKET_SET_DATA_FRAGMENT_SIZE(answer, size);
+			fibril_rwlock_write_unlock(&lock);
+			fibril_rwlock_read_unlock(&tcp_globals.lock);
+			if (res > 0) {
+				SOCKET_SET_SOCKET_ID(answer, res);
+				SOCKET_SET_ADDRESS_LENGTH(answer, addrlen);
+				answer_count = 3;
+			}
+			break;
+
+		case NET_SOCKET_SEND:
+			fibril_rwlock_read_lock(&tcp_globals.lock);
+			fibril_rwlock_write_lock(&lock);
+			res = tcp_send_message(&local_sockets,
+			    SOCKET_GET_SOCKET_ID(call),
+			    SOCKET_GET_DATA_FRAGMENTS(call), &size,
+			    SOCKET_GET_FLAGS(call));
+			SOCKET_SET_DATA_FRAGMENT_SIZE(answer, size);
+			if (res != EOK) {
 				fibril_rwlock_write_unlock(&lock);
 				fibril_rwlock_read_unlock(&tcp_globals.lock);
-				if(res > 0){
-					SOCKET_SET_SOCKET_ID(answer, res);
-					SOCKET_SET_ADDRESS_LENGTH(answer, addrlen);
-					answer_count = 3;
-				}
+			} else {
+				answer_count = 2;
+			}
+			break;
+
+		case NET_SOCKET_SENDTO:
+			res = data_receive((void **) &addr, &addrlen);
+			if (res != EOK)
 				break;
-			case NET_SOCKET_SEND:
-				fibril_rwlock_read_lock(&tcp_globals.lock);
-				fibril_rwlock_write_lock(&lock);
-				res = tcp_send_message(&local_sockets, SOCKET_GET_SOCKET_ID(call), SOCKET_GET_DATA_FRAGMENTS(call), &size, SOCKET_GET_FLAGS(call));
-				SOCKET_SET_DATA_FRAGMENT_SIZE(answer, size);
-				if(res != EOK){
-					fibril_rwlock_write_unlock(&lock);
-					fibril_rwlock_read_unlock(&tcp_globals.lock);
-				}else{
-					answer_count = 2;
-				}
-				break;
-			case NET_SOCKET_SENDTO:
-				res = data_receive((void **) &addr, &addrlen);
-				if(res == EOK){
-					fibril_rwlock_read_lock(&tcp_globals.lock);
-					fibril_rwlock_write_lock(&lock);
-					res = tcp_send_message(&local_sockets, SOCKET_GET_SOCKET_ID(call), SOCKET_GET_DATA_FRAGMENTS(call), &size, SOCKET_GET_FLAGS(call));
-					SOCKET_SET_DATA_FRAGMENT_SIZE(answer, size);
-					if(res != EOK){
-						fibril_rwlock_write_unlock(&lock);
-						fibril_rwlock_read_unlock(&tcp_globals.lock);
-					}else{
-						answer_count = 2;
-					}
-					free(addr);
-				}
-				break;
-			case NET_SOCKET_RECV:
-				fibril_rwlock_read_lock(&tcp_globals.lock);
-				fibril_rwlock_write_lock(&lock);
-				res = tcp_recvfrom_message(&local_sockets, SOCKET_GET_SOCKET_ID(call), SOCKET_GET_FLAGS(call), NULL);
+			fibril_rwlock_read_lock(&tcp_globals.lock);
+			fibril_rwlock_write_lock(&lock);
+			res = tcp_send_message(&local_sockets,
+			    SOCKET_GET_SOCKET_ID(call),
+			    SOCKET_GET_DATA_FRAGMENTS(call), &size,
+			    SOCKET_GET_FLAGS(call));
+			SOCKET_SET_DATA_FRAGMENT_SIZE(answer, size);
+			if (res != EOK) {
 				fibril_rwlock_write_unlock(&lock);
 				fibril_rwlock_read_unlock(&tcp_globals.lock);
-				if(res > 0){
-					SOCKET_SET_READ_DATA_LENGTH(answer, res);
-					answer_count = 1;
-					res = EOK;
-				}
-				break;
-			case NET_SOCKET_RECVFROM:
-				fibril_rwlock_read_lock(&tcp_globals.lock);
-				fibril_rwlock_write_lock(&lock);
-				res = tcp_recvfrom_message(&local_sockets, SOCKET_GET_SOCKET_ID(call), SOCKET_GET_FLAGS(call), &addrlen);
+			} else {
+				answer_count = 2;
+			}
+			free(addr);
+			break;
+
+		case NET_SOCKET_RECV:
+			fibril_rwlock_read_lock(&tcp_globals.lock);
+			fibril_rwlock_write_lock(&lock);
+			res = tcp_recvfrom_message(&local_sockets,
+			    SOCKET_GET_SOCKET_ID(call), SOCKET_GET_FLAGS(call),
+			    NULL);
+			fibril_rwlock_write_unlock(&lock);
+			fibril_rwlock_read_unlock(&tcp_globals.lock);
+			if (res > 0) {
+				SOCKET_SET_READ_DATA_LENGTH(answer, res);
+				answer_count = 1;
+				res = EOK;
+			}
+			break;
+
+		case NET_SOCKET_RECVFROM:
+			fibril_rwlock_read_lock(&tcp_globals.lock);
+			fibril_rwlock_write_lock(&lock);
+			res = tcp_recvfrom_message(&local_sockets,
+			    SOCKET_GET_SOCKET_ID(call), SOCKET_GET_FLAGS(call),
+			    &addrlen);
+			fibril_rwlock_write_unlock(&lock);
+			fibril_rwlock_read_unlock(&tcp_globals.lock);
+			if (res > 0) {
+				SOCKET_SET_READ_DATA_LENGTH(answer, res);
+				SOCKET_SET_ADDRESS_LENGTH(answer, addrlen);
+				answer_count = 3;
+				res = EOK;
+			}
+			break;
+
+		case NET_SOCKET_CLOSE:
+			fibril_rwlock_write_lock(&tcp_globals.lock);
+			fibril_rwlock_write_lock(&lock);
+			res = tcp_close_message(&local_sockets,
+			    SOCKET_GET_SOCKET_ID(call));
+			if (res != EOK) {
 				fibril_rwlock_write_unlock(&lock);
-				fibril_rwlock_read_unlock(&tcp_globals.lock);
-				if(res > 0){
-					SOCKET_SET_READ_DATA_LENGTH(answer, res);
-					SOCKET_SET_ADDRESS_LENGTH(answer, addrlen);
-					answer_count = 3;
-					res = EOK;
-				}
-				break;
-			case NET_SOCKET_CLOSE:
-				fibril_rwlock_write_lock(&tcp_globals.lock);
-				fibril_rwlock_write_lock(&lock);
-				res = tcp_close_message(&local_sockets, SOCKET_GET_SOCKET_ID(call));
-				if(res != EOK){
-					fibril_rwlock_write_unlock(&lock);
-					fibril_rwlock_write_unlock(&tcp_globals.lock);
-				}
-				break;
-			case NET_SOCKET_GETSOCKOPT:
-			case NET_SOCKET_SETSOCKOPT:
-			default:
-				res = ENOTSUP;
-				break;
+				fibril_rwlock_write_unlock(&tcp_globals.lock);
+			}
+			break;
+
+		case NET_SOCKET_GETSOCKOPT:
+		case NET_SOCKET_SETSOCKOPT:
+		default:
+			res = ENOTSUP;
+			break;
 		}
 	}
@@ -1255,10 +1495,12 @@
 	printf("release\n");
 	// release all local sockets
-	socket_cores_release(tcp_globals.net_phone, &local_sockets, &tcp_globals.sockets, tcp_free_socket_data);
+	socket_cores_release(tcp_globals.net_phone, &local_sockets,
+	    &tcp_globals.sockets, tcp_free_socket_data);
 
 	return EOK;
 }
 
-int tcp_timeout(void * data){
+int tcp_timeout(void *data)
+{
 	tcp_timeout_ref timeout = data;
 	int keep_write_lock = false;
@@ -1271,53 +1513,61 @@
 	async_usleep(timeout->timeout);
 	// lock the globals
-	if(timeout->globals_read_only){
+	if (timeout->globals_read_only) 
 		fibril_rwlock_read_lock(&tcp_globals.lock);
-	}else{
+	else 
 		fibril_rwlock_write_lock(&tcp_globals.lock);
-	}
+
 	// find the pending operation socket
-	socket = socket_port_find(&tcp_globals.sockets, timeout->port, timeout->key, timeout->key_length);
-	if(socket && (socket->socket_id == timeout->socket_id)){
-		socket_data = (tcp_socket_data_ref) socket->specific_data;
-		assert(socket_data);
-		if(socket_data->local_sockets == timeout->local_sockets){
-			fibril_rwlock_write_lock(socket_data->local_lock);
-			if(timeout->sequence_number){
-				// increase the timeout counter;
-				++ socket_data->timeout_count;
-				if(socket_data->timeout_count == TCP_MAX_TIMEOUTS){
-					// TODO release as connection lost
-					//tcp_refresh_socket_data(socket_data);
-					fibril_rwlock_write_unlock(socket_data->local_lock);
-				}else{
-					// retransmit
-//					tcp_retransmit_packet(socket, socket_data, timeout->sequence_number);
-					fibril_rwlock_write_unlock(socket_data->local_lock);
-				}
-			}else{
-				fibril_mutex_lock(&socket_data->operation.mutex);
-				// set the timeout operation result if state not changed
-				if(socket_data->state == timeout->state){
-					socket_data->operation.result = ETIMEOUT;
-					// notify the main fibril
-					fibril_condvar_signal(&socket_data->operation.condvar);
-					// keep the global write lock
-					keep_write_lock = true;
-				}else{
-					// operation is ok, do nothing
-					// unlocking from now on, so the unlock order does not matter...
-					fibril_rwlock_write_unlock(socket_data->local_lock);
-				}
-				fibril_mutex_unlock(&socket_data->operation.mutex);
-			}
-		}
-	}
+	socket = socket_port_find(&tcp_globals.sockets, timeout->port,
+	    timeout->key, timeout->key_length);
+	if (!(socket && (socket->socket_id == timeout->socket_id)))
+		goto out;
+	
+	socket_data = (tcp_socket_data_ref) socket->specific_data;
+	assert(socket_data);
+	if (socket_data->local_sockets != timeout->local_sockets)
+		goto out;
+	
+	fibril_rwlock_write_lock(socket_data->local_lock);
+	if (timeout->sequence_number) {
+		// increase the timeout counter;
+		++socket_data->timeout_count;
+		if (socket_data->timeout_count == TCP_MAX_TIMEOUTS) {
+			// TODO release as connection lost
+			//tcp_refresh_socket_data(socket_data);
+			fibril_rwlock_write_unlock(socket_data->local_lock);
+		} else {
+			// retransmit
+//                      tcp_retransmit_packet(socket,
+//			    socket_data, timeout->sequence_number);
+			fibril_rwlock_write_unlock(socket_data->local_lock);
+		}
+	} else {
+		fibril_mutex_lock(&socket_data->operation.mutex);
+		// set the timeout operation result if state not
+		// changed
+		if (socket_data->state == timeout->state) {
+			socket_data->operation.result = ETIMEOUT;
+			// notify the main fibril
+			fibril_condvar_signal(&socket_data->operation.condvar);
+			// keep the global write lock
+			keep_write_lock = true;
+		} else {
+			// operation is ok, do nothing
+			// unlocking from now on, so the unlocki
+			// order does not matter...
+			fibril_rwlock_write_unlock(socket_data->local_lock);
+		}
+		fibril_mutex_unlock(&socket_data->operation.mutex);
+	}
+
+out:
 	// unlock only if no socket
-	if(timeout->globals_read_only){
+	if (timeout->globals_read_only)
 		fibril_rwlock_read_unlock(&tcp_globals.lock);
-	}else if(! keep_write_lock){
+	else if (!keep_write_lock)
 		// release if not desired
 		fibril_rwlock_write_unlock(&tcp_globals.lock);
-	}
+	
 	// release the timeout structure
 	free(timeout);
@@ -1325,9 +1575,10 @@
 }
 
-int tcp_release_after_timeout(void * data){
+int tcp_release_after_timeout(void *data)
+{
 	tcp_timeout_ref timeout = data;
 	socket_core_ref socket;
 	tcp_socket_data_ref socket_data;
-	fibril_rwlock_t * local_lock;
+	fibril_rwlock_t *local_lock;
 
 	assert(timeout);
@@ -1338,12 +1589,15 @@
 	fibril_rwlock_write_lock(&tcp_globals.lock);
 	// find the pending operation socket
-	socket = socket_port_find(&tcp_globals.sockets, timeout->port, timeout->key, timeout->key_length);
-	if(socket && (socket->socket_id == timeout->socket_id)){
+	socket = socket_port_find(&tcp_globals.sockets, timeout->port,
+	    timeout->key, timeout->key_length);
+	if (socket && (socket->socket_id == timeout->socket_id)) {
 		socket_data = (tcp_socket_data_ref) socket->specific_data;
 		assert(socket_data);
-		if(socket_data->local_sockets == timeout->local_sockets){
+		if (socket_data->local_sockets == timeout->local_sockets) {
 			local_lock = socket_data->local_lock;
 			fibril_rwlock_write_lock(local_lock);
-			socket_destroy(tcp_globals.net_phone, timeout->socket_id, timeout->local_sockets, &tcp_globals.sockets, tcp_free_socket_data);
+			socket_destroy(tcp_globals.net_phone,
+			    timeout->socket_id, timeout->local_sockets,
+			    &tcp_globals.sockets, tcp_free_socket_data);
 			fibril_rwlock_write_unlock(local_lock);
 		}
@@ -1356,5 +1610,8 @@
 }
 
-void tcp_retransmit_packet(socket_core_ref socket, tcp_socket_data_ref socket_data, size_t sequence_number){
+void
+tcp_retransmit_packet(socket_core_ref socket, tcp_socket_data_ref socket_data,
+    size_t sequence_number)
+{
 	packet_t packet;
 	packet_t copy;
@@ -1368,18 +1625,20 @@
 	packet = pq_find(socket_data->outgoing, sequence_number);
 	printf("retransmit %d\n", packet_get_id(packet));
-	if(packet){
+	if (packet) {
 		pq_get_order(packet, NULL, &data_length);
-		copy = tcp_prepare_copy(socket, socket_data, packet, data_length, sequence_number);
+		copy = tcp_prepare_copy(socket, socket_data, packet,
+		    data_length, sequence_number);
 		fibril_rwlock_write_unlock(socket_data->local_lock);
-//		printf("r send %d\n", packet_get_id(packet));
-		if(copy){
+//              printf("r send %d\n", packet_get_id(packet));
+		if (copy) 
 			tcp_send_packets(socket_data->device_id, copy);
-		}
-	}else{
+	} else {
 		fibril_rwlock_write_unlock(socket_data->local_lock);
 	}
 }
 
-int tcp_listen_message(socket_cores_ref local_sockets, int socket_id, int backlog){
+int
+tcp_listen_message(socket_cores_ref local_sockets, int socket_id, int backlog)
+{
 	socket_core_ref socket;
 	tcp_socket_data_ref socket_data;
@@ -1387,12 +1646,12 @@
 	assert(local_sockets);
 
-	if(backlog < 0){
+	if (backlog < 0) 
 		return EINVAL;
-	}
+
 	// find the socket
 	socket = socket_cores_find(local_sockets, socket_id);
-	if(! socket){
+	if (!socket) 
 		return ENOTSOCK;
-	}
+	
 	// get the socket specific data
 	socket_data = (tcp_socket_data_ref) socket->specific_data;
@@ -1400,8 +1659,12 @@
 	// set the backlog
 	socket_data->backlog = backlog;
+
 	return EOK;
 }
 
-int tcp_connect_message(socket_cores_ref local_sockets, int socket_id, struct sockaddr * addr, socklen_t addrlen){
+int
+tcp_connect_message(socket_cores_ref local_sockets, int socket_id,
+    struct sockaddr *addr, socklen_t addrlen)
+{
 	ERROR_DECLARE;
 
@@ -1414,12 +1677,14 @@
 	// find the socket
 	socket = socket_cores_find(local_sockets, socket_id);
-	if(! socket){
+	if (!socket)
 		return ENOTSOCK;
-	}
-	if(ERROR_OCCURRED(tcp_connect_core(socket, local_sockets, addr, addrlen))){
+	
+	if (ERROR_OCCURRED(tcp_connect_core(socket, local_sockets, addr,
+	    addrlen))) {
 		tcp_free_socket_data(socket);
 		// unbind if bound
-		if(socket->port > 0){
-			socket_ports_exclude(&tcp_globals.sockets, socket->port);
+		if (socket->port > 0) {
+			socket_ports_exclude(&tcp_globals.sockets,
+			    socket->port);
 			socket->port = 0;
 		}
@@ -1428,5 +1693,8 @@
 }
 
-int tcp_connect_core(socket_core_ref socket, socket_cores_ref local_sockets, struct sockaddr * addr, socklen_t addrlen){
+int
+tcp_connect_core(socket_core_ref socket, socket_cores_ref local_sockets,
+    struct sockaddr *addr, socklen_t addrlen)
+{
 	ERROR_DECLARE;
 
@@ -1442,20 +1710,28 @@
 	assert(socket_data);
 	assert(socket->specific_data == socket_data);
-	if((socket_data->state != TCP_SOCKET_INITIAL)
-		&& ((socket_data->state != TCP_SOCKET_LISTEN) || (socket->port <= 0))){
+	if ((socket_data->state != TCP_SOCKET_INITIAL) &&
+	    ((socket_data->state != TCP_SOCKET_LISTEN) ||
+	    (socket->port <= 0)))
 		return EINVAL;
-	}
+
 	// get the destination port
-	ERROR_PROPAGATE(tl_get_address_port(addr, addrlen, &socket_data->dest_port));
-	if(socket->port <= 0){
+	ERROR_PROPAGATE(tl_get_address_port(addr, addrlen,
+	    &socket_data->dest_port));
+	if (socket->port <= 0) {
 		// try to find a free port
-		ERROR_PROPAGATE(socket_bind_free_port(&tcp_globals.sockets, socket, TCP_FREE_PORTS_START, TCP_FREE_PORTS_END, tcp_globals.last_used_port));
+		ERROR_PROPAGATE(socket_bind_free_port(&tcp_globals.sockets,
+		    socket, TCP_FREE_PORTS_START, TCP_FREE_PORTS_END,
+		    tcp_globals.last_used_port));
 		// set the next port as the search starting port number
 		tcp_globals.last_used_port = socket->port;
 	}
-	ERROR_PROPAGATE(ip_get_route_req(tcp_globals.ip_phone, IPPROTO_TCP, addr, addrlen, &socket_data->device_id, &socket_data->pseudo_header, &socket_data->headerlen));
+
+	ERROR_PROPAGATE(ip_get_route_req(tcp_globals.ip_phone, IPPROTO_TCP,
+	    addr, addrlen, &socket_data->device_id,
+	    &socket_data->pseudo_header, &socket_data->headerlen));
 
 	// create the notification packet
-	ERROR_PROPAGATE(tcp_create_notification_packet(&packet, socket, socket_data, 1, 0));
+	ERROR_PROPAGATE(tcp_create_notification_packet(&packet, socket,
+	    socket_data, 1, 0));
 
 	// unlock the globals and wait for an operation
@@ -1465,12 +1741,16 @@
 	socket_data->addrlen = addrlen;
 	// send the packet
-	if(ERROR_OCCURRED(tcp_queue_packet(socket, socket_data, packet, 1))
-		|| ERROR_OCCURRED(tcp_prepare_timeout(tcp_timeout, socket, socket_data, 0, TCP_SOCKET_INITIAL, NET_DEFAULT_TCP_INITIAL_TIMEOUT, false))){
+	if (ERROR_OCCURRED(tcp_queue_packet(socket, socket_data, packet, 1)) ||
+	    ERROR_OCCURRED(tcp_prepare_timeout(tcp_timeout, socket, socket_data,
+	    0, TCP_SOCKET_INITIAL, NET_DEFAULT_TCP_INITIAL_TIMEOUT, false))) {
+
 		socket_data->addr = NULL;
 		socket_data->addrlen = 0;
 		fibril_rwlock_write_lock(&tcp_globals.lock);
-	}else{
+
+	} else {
+
 		packet = tcp_get_packets_to_send(socket, socket_data);
-		if(packet){
+		if (packet) {
 			fibril_mutex_lock(&socket_data->operation.mutex);
 			fibril_rwlock_write_unlock(socket_data->local_lock);
@@ -1478,12 +1758,14 @@
 			printf("connecting %d\n", packet_get_id(packet));
 			tcp_send_packets(socket_data->device_id, packet);
+
 			// wait for a reply
-			fibril_condvar_wait(&socket_data->operation.condvar, &socket_data->operation.mutex);
+			fibril_condvar_wait(&socket_data->operation.condvar,
+			    &socket_data->operation.mutex);
 			ERROR_CODE = socket_data->operation.result;
-			if(ERROR_CODE != EOK){
+			if (ERROR_CODE != EOK) {
 				socket_data->addr = NULL;
 				socket_data->addrlen = 0;
 			}
-		}else{
+		} else {
 			socket_data->addr = NULL;
 			socket_data->addrlen = 0;
@@ -1498,5 +1780,8 @@
 }
 
-int tcp_queue_prepare_packet(socket_core_ref socket, tcp_socket_data_ref socket_data, packet_t packet, size_t data_length){
+int
+tcp_queue_prepare_packet(socket_core_ref socket,
+    tcp_socket_data_ref socket_data, packet_t packet, size_t data_length)
+{
 	ERROR_DECLARE;
 
@@ -1509,21 +1794,26 @@
 	// get tcp header
 	header = (tcp_header_ref) packet_get_data(packet);
-	if(! header){
+	if (!header)
 		return NO_DATA;
-	}
+	
 	header->destination_port = htons(socket_data->dest_port);
 	header->source_port = htons(socket->port);
 	header->sequence_number = htonl(socket_data->next_outgoing);
-	if(ERROR_OCCURRED(packet_set_addr(packet, NULL, (uint8_t *) socket_data->addr, socket_data->addrlen))){
+
+	if (ERROR_OCCURRED(packet_set_addr(packet, NULL,
+	    (uint8_t *) socket_data->addr, socket_data->addrlen)))
 		return tcp_release_and_return(packet, EINVAL);
-	}
+
 	// remember the outgoing FIN
-	if(header->finalize){
+	if (header->finalize) 
 		socket_data->fin_outgoing = socket_data->next_outgoing;
-	}
+	
 	return EOK;
 }
 
-int tcp_queue_packet(socket_core_ref socket, tcp_socket_data_ref socket_data, packet_t packet, size_t data_length){
+int
+tcp_queue_packet(socket_core_ref socket, tcp_socket_data_ref socket_data,
+    packet_t packet, size_t data_length)
+{
 	ERROR_DECLARE;
 
@@ -1532,14 +1822,18 @@
 	assert(socket->specific_data == socket_data);
 
-	ERROR_PROPAGATE(tcp_queue_prepare_packet(socket, socket_data, packet, data_length));
-
-	if(ERROR_OCCURRED(pq_add(&socket_data->outgoing, packet, socket_data->next_outgoing, data_length))){
+	ERROR_PROPAGATE(tcp_queue_prepare_packet(socket, socket_data, packet,
+	    data_length));
+
+	if (ERROR_OCCURRED(pq_add(&socket_data->outgoing, packet,
+	    socket_data->next_outgoing, data_length)))
 		return tcp_release_and_return(packet, ERROR_CODE);
-	}
+
 	socket_data->next_outgoing += data_length;
 	return EOK;
 }
 
-packet_t tcp_get_packets_to_send(socket_core_ref socket, tcp_socket_data_ref socket_data){
+packet_t
+tcp_get_packets_to_send(socket_core_ref socket, tcp_socket_data_ref socket_data)
+{
 	ERROR_DECLARE;
 
@@ -1555,38 +1849,47 @@
 
 	packet = pq_find(socket_data->outgoing, socket_data->last_outgoing + 1);
-	while(packet){
+	while (packet) {
 		pq_get_order(packet, NULL, &data_length);
+
 		// send only if fits into the window
 		// respecting the possible overflow
-		if(IS_IN_INTERVAL_OVERFLOW((uint32_t) socket_data->last_outgoing, (uint32_t)(socket_data->last_outgoing + data_length), (uint32_t)(socket_data->expected + socket_data->treshold))){
-			copy = tcp_prepare_copy(socket, socket_data, packet, data_length, socket_data->last_outgoing + 1);
-			if(! copy){
-				return sending;
-			}
-			if(! sending){
-				sending = copy;
-			}else{
-				if(ERROR_OCCURRED(pq_insert_after(previous, copy))){
-					pq_release_remote(tcp_globals.net_phone, packet_get_id(copy));
-					return sending;
-				}
-			}
-			previous = copy;
-			packet = pq_next(packet);
-			// overflow occurred ?
-			if((! packet) && (socket_data->last_outgoing > socket_data->next_outgoing)){
-				printf("gpts overflow\n");
-				// continue from the beginning
-				packet = socket_data->outgoing;
-			}
-			socket_data->last_outgoing += data_length;
-		}else{
+		if (!IS_IN_INTERVAL_OVERFLOW(
+		    (uint32_t) socket_data->last_outgoing,
+		    (uint32_t) (socket_data->last_outgoing + data_length),
+		    (uint32_t) (socket_data->expected + socket_data->treshold)))
 			break;
-		}
-	}
+
+		copy = tcp_prepare_copy(socket, socket_data, packet,
+		    data_length, socket_data->last_outgoing + 1);
+		if (!copy) 
+			return sending;
+			
+		if (!sending) {
+			sending = copy;
+		} else if (ERROR_OCCURRED(pq_insert_after(previous, copy))) {
+			pq_release_remote(tcp_globals.net_phone,
+			    packet_get_id(copy));
+			return sending;
+		}
+
+		previous = copy;
+		packet = pq_next(packet);
+		// overflow occurred ?
+		if ((!packet) &&
+		    (socket_data->last_outgoing > socket_data->next_outgoing)) {
+			printf("gpts overflow\n");
+			// continue from the beginning
+			packet = socket_data->outgoing;
+		}
+		socket_data->last_outgoing += data_length;
+	}
+
 	return sending;
 }
 
-packet_t tcp_send_prepare_packet(socket_core_ref socket, tcp_socket_data_ref socket_data, packet_t packet, size_t data_length, size_t sequence_number){
+packet_t
+tcp_send_prepare_packet(socket_core_ref socket, tcp_socket_data_ref socket_data,
+    packet_t packet, size_t data_length, size_t sequence_number)
+{
 	ERROR_DECLARE;
 
@@ -1599,5 +1902,7 @@
 
 	// adjust the pseudo header
-	if(ERROR_OCCURRED(ip_client_set_pseudo_header_data_length(socket_data->pseudo_header, socket_data->headerlen, packet_get_data_length(packet)))){
+	if (ERROR_OCCURRED(ip_client_set_pseudo_header_data_length(
+	    socket_data->pseudo_header, socket_data->headerlen,
+	    packet_get_data_length(packet)))) {
 		pq_release_remote(tcp_globals.net_phone, packet_get_id(packet));
 		return NULL;
@@ -1606,5 +1911,5 @@
 	// get the header
 	header = (tcp_header_ref) packet_get_data(packet);
-	if(! header){
+	if (!header) {
 		pq_release_remote(tcp_globals.net_phone, packet_get_id(packet));
 		return NULL;
@@ -1613,6 +1918,7 @@
 
 	// adjust the header
-	if(socket_data->next_incoming){
-		header->acknowledgement_number = htonl(socket_data->next_incoming);
+	if (socket_data->next_incoming) {
+		header->acknowledgement_number =
+		    htonl(socket_data->next_incoming);
 		header->acknowledge = 1;
 	}
@@ -1621,18 +1927,26 @@
 	// checksum
 	header->checksum = 0;
-	checksum = compute_checksum(0, socket_data->pseudo_header, socket_data->headerlen);
-	checksum = compute_checksum(checksum, (uint8_t *) packet_get_data(packet), packet_get_data_length(packet));
+	checksum = compute_checksum(0, socket_data->pseudo_header,
+	    socket_data->headerlen);
+	checksum = compute_checksum(checksum, (uint8_t *) packet_get_data(packet),
+	    packet_get_data_length(packet));
 	header->checksum = htons(flip_checksum(compact_checksum(checksum)));
+
 	// prepare the packet
-	if(ERROR_OCCURRED(ip_client_prepare_packet(packet, IPPROTO_TCP, 0, 0, 0, 0))
-	// prepare the timeout
-		|| ERROR_OCCURRED(tcp_prepare_timeout(tcp_timeout, socket, socket_data, sequence_number, socket_data->state, socket_data->timeout, true))){
+	if (ERROR_OCCURRED(ip_client_prepare_packet(packet, IPPROTO_TCP, 0, 0,
+	    0, 0)) || ERROR_OCCURRED(tcp_prepare_timeout(tcp_timeout, socket,
+	    socket_data, sequence_number, socket_data->state,
+	    socket_data->timeout, true))) {
 		pq_release_remote(tcp_globals.net_phone, packet_get_id(packet));
 		return NULL;
 	}
+
 	return packet;
 }
 
-packet_t tcp_prepare_copy(socket_core_ref socket, tcp_socket_data_ref socket_data, packet_t packet, size_t data_length, size_t sequence_number){
+packet_t
+tcp_prepare_copy(socket_core_ref socket, tcp_socket_data_ref socket_data,
+    packet_t packet, size_t data_length, size_t sequence_number)
+{
 	packet_t copy;
 
@@ -1643,22 +1957,28 @@
 	// make a copy of the packet
 	copy = packet_get_copy(tcp_globals.net_phone, packet);
-	if(! copy){
+	if (!copy)
 		return NULL;
-	}
-
-	return tcp_send_prepare_packet(socket, socket_data, copy, data_length, sequence_number);
-}
-
-void tcp_send_packets(device_id_t device_id, packet_t packet){
+
+	return tcp_send_prepare_packet(socket, socket_data, copy, data_length,
+	    sequence_number);
+}
+
+void tcp_send_packets(device_id_t device_id, packet_t packet)
+{
 	packet_t next;
 
-	while(packet){
+	while (packet) {
 		next = pq_detach(packet);
-		ip_send_msg(tcp_globals.ip_phone, device_id, packet, SERVICE_TCP, 0);
+		ip_send_msg(tcp_globals.ip_phone, device_id, packet,
+		    SERVICE_TCP, 0);
 		packet = next;
 	}
 }
 
-void tcp_prepare_operation_header(socket_core_ref socket, tcp_socket_data_ref socket_data, tcp_header_ref header, int synchronize, int finalize){
+void
+tcp_prepare_operation_header(socket_core_ref socket,
+    tcp_socket_data_ref socket_data, tcp_header_ref header, int synchronize,
+    int finalize)
+{
 	assert(socket);
 	assert(socket_data);
@@ -1674,5 +1994,10 @@
 }
 
-int tcp_prepare_timeout(int (*timeout_function)(void * tcp_timeout_t), socket_core_ref socket, tcp_socket_data_ref socket_data, size_t sequence_number, tcp_socket_state_t state, suseconds_t timeout, int globals_read_only){
+int
+tcp_prepare_timeout(int (*timeout_function)(void *tcp_timeout_t),
+    socket_core_ref socket, tcp_socket_data_ref socket_data,
+    size_t sequence_number, tcp_socket_state_t state, suseconds_t timeout,
+    int globals_read_only)
+{
 	tcp_timeout_ref operation_timeout;
 	fid_t fibril;
@@ -1683,8 +2008,9 @@
 
 	// prepare the timeout with key bundle structure
-	operation_timeout = malloc(sizeof(*operation_timeout) + socket->key_length + 1);
-	if(! operation_timeout){
+	operation_timeout = malloc(sizeof(*operation_timeout) +
+	    socket->key_length + 1);
+	if (!operation_timeout)
 		return ENOMEM;
-	}
+
 	bzero(operation_timeout, sizeof(*operation_timeout));
 	operation_timeout->globals_read_only = globals_read_only;
@@ -1697,5 +2023,6 @@
 
 	// copy the key
-	operation_timeout->key = ((char *) operation_timeout) + sizeof(*operation_timeout);
+	operation_timeout->key = ((char *) operation_timeout) +
+	    sizeof(*operation_timeout);
 	operation_timeout->key_length = socket->key_length;
 	memcpy(operation_timeout->key, socket->key, socket->key_length);
@@ -1704,9 +2031,9 @@
 	// prepare the timeouting thread
 	fibril = fibril_create(timeout_function, operation_timeout);
-	if(! fibril){
+	if (!fibril) {
 		free(operation_timeout);
 		return EPARTY;
 	}
-//	fibril_mutex_lock(&socket_data->operation.mutex);
+//      fibril_mutex_lock(&socket_data->operation.mutex);
 	// start the timeouting fibril
 	fibril_add_ready(fibril);
@@ -1715,5 +2042,8 @@
 }
 
-int tcp_recvfrom_message(socket_cores_ref local_sockets, int socket_id, int flags, size_t * addrlen){
+int
+tcp_recvfrom_message(socket_cores_ref local_sockets, int socket_id, int flags,
+    size_t * addrlen)
+{
 	ERROR_DECLARE;
 
@@ -1728,21 +2058,22 @@
 	// find the socket
 	socket = socket_cores_find(local_sockets, socket_id);
-	if(! socket){
+	if (!socket)
 		return ENOTSOCK;
-	}
+
 	// get the socket specific data
-	if(! socket->specific_data){
+	if (!socket->specific_data)
 		return NO_DATA;
-	}
+
 	socket_data = (tcp_socket_data_ref) socket->specific_data;
 
 	// check state
-	if((socket_data->state != TCP_SOCKET_ESTABLISHED) && (socket_data->state != TCP_SOCKET_CLOSE_WAIT)){
+	if ((socket_data->state != TCP_SOCKET_ESTABLISHED) &&
+	    (socket_data->state != TCP_SOCKET_CLOSE_WAIT))
 		return ENOTCONN;
-	}
 
 	// send the source address if desired
-	if(addrlen){
-		ERROR_PROPAGATE(data_reply(socket_data->addr, socket_data->addrlen));
+	if (addrlen) {
+		ERROR_PROPAGATE(data_reply(socket_data->addr,
+		    socket_data->addrlen));
 		*addrlen = socket_data->addrlen;
 	}
@@ -1750,8 +2081,9 @@
 	// get the next received packet
 	packet_id = dyn_fifo_value(&socket->received);
-	if(packet_id < 0){
+	if (packet_id < 0)
 		return NO_DATA;
-	}
-	ERROR_PROPAGATE(packet_translate_remote(tcp_globals.net_phone, &packet, packet_id));
+
+	ERROR_PROPAGATE(packet_translate_remote(tcp_globals.net_phone, &packet,
+	    packet_id));
 
 	// reply the packets
@@ -1765,5 +2097,8 @@
 }
 
-int tcp_send_message(socket_cores_ref local_sockets, int socket_id, int fragments, size_t * data_fragment_size, int flags){
+int
+tcp_send_message(socket_cores_ref local_sockets, int socket_id, int fragments,
+    size_t * data_fragment_size, int flags)
+{
 	ERROR_DECLARE;
 
@@ -1782,36 +2117,42 @@
 	// find the socket
 	socket = socket_cores_find(local_sockets, socket_id);
-	if(! socket){
+	if (!socket)
 		return ENOTSOCK;
-	}
+
 	// get the socket specific data
-	if(! socket->specific_data){
+	if (!socket->specific_data)
 		return NO_DATA;
-	}
+
 	socket_data = (tcp_socket_data_ref) socket->specific_data;
 
 	// check state
-	if((socket_data->state != TCP_SOCKET_ESTABLISHED) && (socket_data->state != TCP_SOCKET_CLOSE_WAIT)){
+	if ((socket_data->state != TCP_SOCKET_ESTABLISHED) &&
+	    (socket_data->state != TCP_SOCKET_CLOSE_WAIT))
 		return ENOTCONN;
-	}
-
-	ERROR_PROPAGATE(tl_get_ip_packet_dimension(tcp_globals.ip_phone, &tcp_globals.dimensions, socket_data->device_id, &packet_dimension));
-
-	*data_fragment_size = ((packet_dimension->content < socket_data->data_fragment_size) ? packet_dimension->content : socket_data->data_fragment_size);
-
-	for(index = 0; index < fragments; ++ index){
+
+	ERROR_PROPAGATE(tl_get_ip_packet_dimension(tcp_globals.ip_phone,
+	   &tcp_globals.dimensions, socket_data->device_id, &packet_dimension));
+
+	*data_fragment_size =
+	    ((packet_dimension->content < socket_data->data_fragment_size) ?
+	    packet_dimension->content : socket_data->data_fragment_size);
+
+	for (index = 0; index < fragments; ++index) {
 		// read the data fragment
-		result = tl_socket_read_packet_data(tcp_globals.net_phone, &packet, TCP_HEADER_SIZE, packet_dimension, socket_data->addr, socket_data->addrlen);
-		if(result < 0){
+		result = tl_socket_read_packet_data(tcp_globals.net_phone,
+		    &packet, TCP_HEADER_SIZE, packet_dimension,
+		    socket_data->addr, socket_data->addrlen);
+		if (result < 0)
 			return result;
-		}
+
 		total_length = (size_t) result;
 		// prefix the tcp header
 		header = PACKET_PREFIX(packet, tcp_header_t);
-		if(! header){
+		if (!header)
 			return tcp_release_and_return(packet, ENOMEM);
-		}
+
 		tcp_prepare_operation_header(socket, socket_data, header, 0, 0);
-		ERROR_PROPAGATE(tcp_queue_packet(socket, socket_data, packet, 0));
+		ERROR_PROPAGATE(tcp_queue_packet(socket, socket_data, packet,
+		    0));
 	}
 
@@ -1820,5 +2161,6 @@
 	fibril_rwlock_write_unlock(socket_data->local_lock);
 	fibril_rwlock_read_unlock(&tcp_globals.lock);
-	if(packet){
+
+	if (packet) {
 		// send the packet
 		tcp_send_packets(socket_data->device_id, packet);
@@ -1828,5 +2170,7 @@
 }
 
-int tcp_close_message(socket_cores_ref local_sockets, int socket_id){
+int
+tcp_close_message(socket_cores_ref local_sockets, int socket_id)
+{
 	ERROR_DECLARE;
 
@@ -1837,7 +2181,7 @@
 	// find the socket
 	socket = socket_cores_find(local_sockets, socket_id);
-	if(! socket){
+	if (!socket)
 		return ENOTSOCK;
-	}
+
 	// get the socket specific data
 	socket_data = (tcp_socket_data_ref) socket->specific_data;
@@ -1845,25 +2189,32 @@
 
 	// check state
-	switch(socket_data->state){
-		case TCP_SOCKET_ESTABLISHED:
-			socket_data->state = TCP_SOCKET_FIN_WAIT_1;
-			break;
-		case TCP_SOCKET_CLOSE_WAIT:
-			socket_data->state = TCP_SOCKET_LAST_ACK;
-			break;
-//		case TCP_SOCKET_LISTEN:
-		default:
-			// just destroy
-			if(! ERROR_OCCURRED(socket_destroy(tcp_globals.net_phone, socket_id, local_sockets, &tcp_globals.sockets, tcp_free_socket_data))){
-				fibril_rwlock_write_unlock(socket_data->local_lock);
-				fibril_rwlock_write_unlock(&tcp_globals.lock);
-			}
-			return ERROR_CODE;
-	}
+	switch (socket_data->state) {
+	case TCP_SOCKET_ESTABLISHED:
+		socket_data->state = TCP_SOCKET_FIN_WAIT_1;
+		break;
+
+	case TCP_SOCKET_CLOSE_WAIT:
+		socket_data->state = TCP_SOCKET_LAST_ACK;
+		break;
+
+//      case TCP_SOCKET_LISTEN:
+
+	default:
+		// just destroy
+		if (ERROR_NONE(socket_destroy(tcp_globals.net_phone, socket_id,
+		    local_sockets, &tcp_globals.sockets,
+		    tcp_free_socket_data))) {
+			fibril_rwlock_write_unlock(socket_data->local_lock);
+			fibril_rwlock_write_unlock(&tcp_globals.lock);
+		}
+		return ERROR_CODE;
+	}
+
 	// send FIN
 	// TODO should I wait to complete?
 
 	// create the notification packet
-	ERROR_PROPAGATE(tcp_create_notification_packet(&packet, socket, socket_data, 0, 1));
+	ERROR_PROPAGATE(tcp_create_notification_packet(&packet, socket,
+	    socket_data, 0, 1));
 
 	// send the packet
@@ -1874,12 +2225,17 @@
 	fibril_rwlock_write_unlock(socket_data->local_lock);
 	fibril_rwlock_write_unlock(&tcp_globals.lock);
-	if(packet){
+
+	if (packet) {
 		// send the packet
 		tcp_send_packets(socket_data->device_id, packet);
 	}
+
 	return EOK;
 }
 
-int tcp_create_notification_packet(packet_t * packet, socket_core_ref socket, tcp_socket_data_ref socket_data, int synchronize, int finalize){
+int
+tcp_create_notification_packet(packet_t * packet, socket_core_ref socket,
+    tcp_socket_data_ref socket_data, int synchronize, int finalize)
+{
 	ERROR_DECLARE;
 
@@ -1890,21 +2246,31 @@
 
 	// get the device packet dimension
-	ERROR_PROPAGATE(tl_get_ip_packet_dimension(tcp_globals.ip_phone, &tcp_globals.dimensions, socket_data->device_id, &packet_dimension));
+	ERROR_PROPAGATE(tl_get_ip_packet_dimension(tcp_globals.ip_phone,
+	    &tcp_globals.dimensions, socket_data->device_id,
+	    &packet_dimension));
+
 	// get a new packet
-	*packet = packet_get_4_remote(tcp_globals.net_phone, TCP_HEADER_SIZE, packet_dimension->addr_len, packet_dimension->prefix, packet_dimension->suffix);
-	if(! * packet){
+	*packet = packet_get_4_remote(tcp_globals.net_phone, TCP_HEADER_SIZE,
+	    packet_dimension->addr_len, packet_dimension->prefix,
+	    packet_dimension->suffix);
+	
+	if (!*packet) 
 		return ENOMEM;
-	}
+
 	// allocate space in the packet
 	header = PACKET_SUFFIX(*packet, tcp_header_t);
-	if(! header){
+	if (!header)
 		tcp_release_and_return(*packet, ENOMEM);
-	}
-
-	tcp_prepare_operation_header(socket, socket_data, header, synchronize, finalize);
+
+	tcp_prepare_operation_header(socket, socket_data, header, synchronize,
+	    finalize);
+
 	return EOK;
 }
 
-int tcp_accept_message(socket_cores_ref local_sockets, int socket_id, int new_socket_id, size_t * data_fragment_size, size_t * addrlen){
+int
+tcp_accept_message(socket_cores_ref local_sockets, int socket_id,
+    int new_socket_id, size_t * data_fragment_size, size_t * addrlen)
+{
 	ERROR_DECLARE;
 
@@ -1920,7 +2286,7 @@
 	// find the socket
 	socket = socket_cores_find(local_sockets, socket_id);
-	if(! socket){
+	if (!socket)
 		return ENOTSOCK;
-	}
+
 	// get the socket specific data
 	socket_data = (tcp_socket_data_ref) socket->specific_data;
@@ -1928,40 +2294,52 @@
 
 	// check state
-	if(socket_data->state != TCP_SOCKET_LISTEN){
+	if (socket_data->state != TCP_SOCKET_LISTEN)
 		return EINVAL;
-	}
-
-	do{
+
+	do {
 		socket_id = dyn_fifo_value(&socket->accepted);
-		if(socket_id < 0){
+		if (socket_id < 0)
 			return ENOTSOCK;
-		}
 		socket_id *= -1;
 
 		accepted = socket_cores_find(local_sockets, socket_id);
-		if(! accepted){
+		if (!accepted)
 			return ENOTSOCK;
-		}
+
 		// get the socket specific data
 		socket_data = (tcp_socket_data_ref) accepted->specific_data;
 		assert(socket_data);
 		// TODO can it be in another state?
-		if(socket_data->state == TCP_SOCKET_ESTABLISHED){
-			ERROR_PROPAGATE(data_reply(socket_data->addr, socket_data->addrlen));
-			ERROR_PROPAGATE(tl_get_ip_packet_dimension(tcp_globals.ip_phone, &tcp_globals.dimensions, socket_data->device_id, &packet_dimension));
+		if (socket_data->state == TCP_SOCKET_ESTABLISHED) {
+			ERROR_PROPAGATE(data_reply(socket_data->addr,
+			    socket_data->addrlen));
+			ERROR_PROPAGATE(tl_get_ip_packet_dimension(
+			    tcp_globals.ip_phone, &tcp_globals.dimensions,
+			    socket_data->device_id, &packet_dimension));
 			*addrlen = socket_data->addrlen;
-			*data_fragment_size = ((packet_dimension->content < socket_data->data_fragment_size) ? packet_dimension->content : socket_data->data_fragment_size);
-			if(new_socket_id > 0){
-				ERROR_PROPAGATE(socket_cores_update(local_sockets, accepted->socket_id, new_socket_id));
+
+			*data_fragment_size =
+			    ((packet_dimension->content <
+			    socket_data->data_fragment_size) ?
+			    packet_dimension->content :
+			    socket_data->data_fragment_size);
+	
+			if (new_socket_id > 0) {
+				ERROR_PROPAGATE(socket_cores_update(
+				    local_sockets, accepted->socket_id,
+				    new_socket_id));
 				accepted->socket_id = new_socket_id;
 			}
 		}
 		dyn_fifo_pop(&socket->accepted);
-	}while(socket_data->state != TCP_SOCKET_ESTABLISHED);
+	} while (socket_data->state != TCP_SOCKET_ESTABLISHED);
+
 	printf("ret accept %d\n", accepted->socket_id);
 	return accepted->socket_id;
 }
 
-void tcp_free_socket_data(socket_core_ref socket){
+void
+tcp_free_socket_data(socket_core_ref socket)
+{
 	tcp_socket_data_ref socket_data;
 
@@ -1974,6 +2352,6 @@
 	assert(socket_data);
 	//free the pseudo header
-	if(socket_data->pseudo_header){
-		if(socket_data->headerlen){
+	if (socket_data->pseudo_header) {
+		if (socket_data->headerlen) {
 			printf("d pseudo\n");
 			free(socket_data->pseudo_header);
@@ -1984,6 +2362,6 @@
 	socket_data->headerlen = 0;
 	// free the address
-	if(socket_data->addr){
-		if(socket_data->addrlen){
+	if (socket_data->addr) {
+		if (socket_data->addrlen) {
 			printf("d addr\n");
 			free(socket_data->addr);
@@ -1995,5 +2373,6 @@
 }
 
-int tcp_release_and_return(packet_t packet, int result){
+int tcp_release_and_return(packet_t packet, int result)
+{
 	pq_release_remote(tcp_globals.net_phone, packet_get_id(packet));
 	return result;
@@ -2013,25 +2392,36 @@
 	 */
 	ipc_answer_0(iid, EOK);
-	
-	while(true) {
+
+	while (true) {
 		ipc_call_t answer;
 		int answer_count;
-		
-		/* Clear the answer structure */
+
+		/*
+		   Clear the answer structure 
+		 */
 		refresh_answer(&answer, &answer_count);
-		
-		/* Fetch the next message */
+
+		/*
+		   Fetch the next message 
+		 */
 		ipc_call_t call;
 		ipc_callid_t callid = async_get_call(&call);
-		
-		/* Process the message */
+
+		/*
+		   Process the message 
+		 */
 		int res = tl_module_message_standalone(callid, &call, &answer,
 		    &answer_count);
-		
-		/* End if said to either by the message or the processing result */
-		if ((IPC_GET_METHOD(call) == IPC_M_PHONE_HUNGUP) || (res == EHANGUP))
+
+		/*
+		   End if said to either by the message or the processing result 
+		 */
+		if ((IPC_GET_METHOD(call) == IPC_M_PHONE_HUNGUP) ||
+		    (res == EHANGUP))
 			return;
-		
-		/* Answer the message */
+
+		/*
+		   Answer the message 
+		 */
 		answer_call(callid, res, &answer, answer_count);
 	}
@@ -2047,12 +2437,15 @@
  *
  */
-int main(int argc, char *argv[])
+int
+main(int argc, char *argv[])
 {
 	ERROR_DECLARE;
-	
-	/* Start the module */
+
+	/*
+	   Start the module 
+	 */
 	if (ERROR_OCCURRED(tl_module_start_standalone(tl_client_connection)))
 		return ERROR_CODE;
-	
+
 	return EOK;
 }
Index: uspace/srv/net/tl/tcp/tcp.h
===================================================================
--- uspace/srv/net/tl/tcp/tcp.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/srv/net/tl/tcp/tcp.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -40,6 +40,6 @@
 #include <fibril_synch.h>
 
-#include <packet/packet.h>
-#include <net_device.h>
+#include <net/packet.h>
+#include <net/device.h>
 #include <socket_core.h>
 #include <tl_common.h>
Index: uspace/srv/net/tl/tcp/tcp_module.c
===================================================================
--- uspace/srv/net/tl/tcp/tcp_module.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/srv/net/tl/tcp/tcp_module.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -40,12 +40,13 @@
 #include <async.h>
 #include <stdio.h>
+#include <err.h>
 #include <ipc/ipc.h>
 #include <ipc/services.h>
 
-#include <net_err.h>
-#include <net_modules.h>
-#include <packet/packet.h>
+#include <net/ip_protocols.h>
+#include <net/modules.h>
+
+#include <net/packet.h>
 #include <net_interface.h>
-#include <ip_protocols.h>
 #include <ip_interface.h>
 #include <tl_local.h>
@@ -70,5 +71,5 @@
 	
 	async_set_client_connection(client_connection);
-	tcp_globals.net_phone = net_connect_module(SERVICE_NETWORKING);
+	tcp_globals.net_phone = net_connect_module();
 	ERROR_PROPAGATE(pm_init());
 	
Index: uspace/srv/net/tl/udp/Makefile
===================================================================
--- uspace/srv/net/tl/udp/Makefile	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/srv/net/tl/udp/Makefile	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -29,6 +29,6 @@
 
 USPACE_PREFIX = ../../../..
-LIBS = $(LIBNET_PREFIX)/libnet.a $(LIBSOCKET_PREFIX)/libsocket.a
-EXTRA_CFLAGS = -I$(LIBNET_PREFIX)/include -I$(LIBSOCKET_PREFIX)/include
+LIBS = $(LIBNET_PREFIX)/libnet.a
+EXTRA_CFLAGS = -I$(LIBNET_PREFIX)/include
 BINARY = udp
 
Index: uspace/srv/net/tl/udp/udp.c
===================================================================
--- uspace/srv/net/tl/udp/udp.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/srv/net/tl/udp/udp.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -42,29 +42,30 @@
 #include <ipc/ipc.h>
 #include <ipc/services.h>
-
-#include <net_err.h>
-#include <net_messages.h>
-#include <net_modules.h>
+#include <ipc/net.h>
+#include <ipc/tl.h>
+#include <ipc/socket.h>
+#include <errno.h>
+#include <err.h>
+
+#include <net/socket_codes.h>
+#include <net/ip_protocols.h>
+#include <net/in.h>
+#include <net/in6.h>
+#include <net/inet.h>
+#include <net/modules.h>
+
 #include <adt/dynamic_fifo.h>
-#include <packet/packet_client.h>
+#include <packet_client.h>
 #include <packet_remote.h>
 #include <net_checksum.h>
-#include <in.h>
-#include <in6.h>
-#include <inet.h>
 #include <ip_client.h>
 #include <ip_interface.h>
-#include <ip_protocols.h>
 #include <icmp_client.h>
 #include <icmp_interface.h>
 #include <net_interface.h>
-#include <socket_codes.h>
-#include <socket_errno.h>
 #include <socket_core.h>
-#include <socket_messages.h>
 #include <tl_common.h>
 #include <tl_local.h>
 #include <tl_interface.h>
-#include <tl_messages.h>
 
 #include "udp.h"
@@ -72,61 +73,69 @@
 #include "udp_module.h"
 
-/** UDP module name.
- */
+/** UDP module name. */
 #define NAME	"UDP protocol"
 
-/** Default UDP checksum computing.
- */
+/** Default UDP checksum computing. */
 #define NET_DEFAULT_UDP_CHECKSUM_COMPUTING	true
 
-/** Default UDP autobind when sending via unbound sockets.
- */
+/** Default UDP autobind when sending via unbound sockets. */
 #define NET_DEFAULT_UDP_AUTOBINDING	true
 
-/** Maximum UDP fragment size.
- */
-#define MAX_UDP_FRAGMENT_SIZE	65535
-
-/** Free ports pool start.
- */
-#define UDP_FREE_PORTS_START	1025
-
-/** Free ports pool end.
- */
+/** Maximum UDP fragment size. */
+#define MAX_UDP_FRAGMENT_SIZE		65535
+
+/** Free ports pool start. */
+#define UDP_FREE_PORTS_START		1025
+
+/** Free ports pool end. */
 #define UDP_FREE_PORTS_END		65535
 
 /** Processes the received UDP packet queue.
+ *
  *  Is used as an entry point from the underlying IP module.
  *  Locks the global lock and calls udp_process_packet() function.
+ *
  *  @param[in] device_id The receiving device identifier.
  *  @param[in,out] packet The received packet queue.
- *  @param receiver The target service. Ignored parameter.
- *  @param[in] error The packet error reporting service. Prefixes the received packet.
- *  @returns EOK on success.
- *  @returns Other error codes as defined for the udp_process_packet() function.
- */
-int udp_received_msg(device_id_t device_id, packet_t packet, services_t receiver, services_t error);
+ *  @param receiver	The target service. Ignored parameter.
+ *  @param[in] error	The packet error reporting service. Prefixes the
+ *			received packet.
+ *  @returns		EOK on success.
+ *  @returns		Other error codes as defined for the
+ *			udp_process_packet() function.
+ */
+int
+udp_received_msg(device_id_t device_id, packet_t packet, services_t receiver,
+    services_t error);
 
 /** Processes the received UDP packet queue.
+ *
  *  Notifies the destination socket application.
- *  Releases the packet on error or sends an ICMP error notification..
+ *  Releases the packet on error or sends an ICMP error notification.
+ *
  *  @param[in] device_id The receiving device identifier.
  *  @param[in,out] packet The received packet queue.
- *  @param[in] error The packet error reporting service. Prefixes the received packet.
- *  @returns EOK on success.
- *  @returns EINVAL if the packet is not valid.
- *  @returns EINVAL if the stored packet address is not the an_addr_t.
- *  @returns EINVAL if the packet does not contain any data.
- *  @returns NO_DATA if the packet content is shorter than the user datagram header.
- *  @returns ENOMEM if there is not enough memory left.
- *  @returns EADDRNOTAVAIL if the destination socket does not exist.
- *  @returns Other error codes as defined for the ip_client_process_packet() function.
- */
-int udp_process_packet(device_id_t device_id, packet_t packet, services_t error);
+ *  @param[in] error	The packet error reporting service. Prefixes the
+ *			received packet.
+ *  @returns		EOK on success.
+ *  @returns		EINVAL if the packet is not valid.
+ *  @returns		EINVAL if the stored packet address is not the
+ *			an_addr_t.
+ *  @returns		EINVAL if the packet does not contain any data.
+ *  @returns 		NO_DATA if the packet content is shorter than the user
+ *			datagram header.
+ *  @returns		ENOMEM if there is not enough memory left.
+ *  @returns		EADDRNOTAVAIL if the destination socket does not exist.
+ *  @returns		Other error codes as defined for the
+ *			ip_client_process_packet() function.
+ */
+int
+udp_process_packet(device_id_t device_id, packet_t packet, services_t error);
 
 /** Releases the packet and returns the result.
- *  @param[in] packet The packet queue to be released.
- *  @param[in] result The result to be returned.
- *  @return The result parameter.
+ *
+ *  @param[in] packet	The packet queue to be released.
+ *  @param[in] result	The result to be returned.
+ *  @return		The result parameter.
  */
 int udp_release_and_return(packet_t packet, int result);
@@ -137,51 +146,68 @@
 
 /** Processes the socket client messages.
+ *
  *  Runs until the client module disconnects.
- *  @param[in] callid The message identifier.
- *  @param[in] call The message parameters.
- *  @returns EOK on success.
- *  @see socket.h
+ *
+ *  @param[in] callid 	The message identifier.
+ *  @param[in] call	The message parameters.
+ *  @returns		EOK on success.
+ *  @see		socket.h
  */
 int udp_process_client_messages(ipc_callid_t callid, ipc_call_t call);
 
 /** Sends data from the socket to the remote address.
+ *
  *  Binds the socket to a free port if not already connected/bound.
  *  Handles the NET_SOCKET_SENDTO message.
  *  Supports AF_INET and AF_INET6 address families.
+ *
  *  @param[in,out] local_sockets The application local sockets.
  *  @param[in] socket_id Socket identifier.
- *  @param[in] addr The destination address.
- *  @param[in] addrlen The address length.
+ *  @param[in] addr	The destination address.
+ *  @param[in] addrlen	The address length.
  *  @param[in] fragments The number of data fragments.
  *  @param[out] data_fragment_size The data fragment size in bytes.
- *  @param[in] flags Various send flags.
- *  @returns EOK on success.
- *  @returns EAFNOTSUPPORT if the address family is not supported.
- *  @returns ENOTSOCK if the socket is not found.
- *  @returns EINVAL if the address is invalid.
- *  @returns ENOTCONN if the sending socket is not and cannot be bound.
- *  @returns ENOMEM if there is not enough memory left.
- *  @returns Other error codes as defined for the socket_read_packet_data() function.
- *  @returns Other error codes as defined for the ip_client_prepare_packet() function.
- *  @returns Other error codes as defined for the ip_send_msg() function.
- */
-int udp_sendto_message(socket_cores_ref local_sockets, int socket_id, const struct sockaddr * addr, socklen_t addrlen, int fragments, size_t * data_fragment_size, int flags);
+ *  @param[in] flags	Various send flags.
+ *  @returns		EOK on success.
+ *  @returns		EAFNOTSUPPORT if the address family is not supported.
+ *  @returns		ENOTSOCK if the socket is not found.
+ *  @returns		EINVAL if the address is invalid.
+ *  @returns		ENOTCONN if the sending socket is not and cannot be
+ *			bound.
+ *  @returns		ENOMEM if there is not enough memory left.
+ *  @returns		Other error codes as defined for the
+ *			socket_read_packet_data() function.
+ *  @returns		Other error codes as defined for the
+ *			ip_client_prepare_packet() function.
+ *  @returns		Other error codes as defined for the ip_send_msg()
+ *			function.
+ */
+int
+udp_sendto_message(socket_cores_ref local_sockets, int socket_id,
+    const struct sockaddr * addr, socklen_t addrlen, int fragments,
+    size_t * data_fragment_size, int flags);
 
 /** Receives data to the socket.
+ *
  *  Handles the NET_SOCKET_RECVFROM message.
  *  Replies the source address as well.
+ *
  *  @param[in] local_sockets The application local sockets.
  *  @param[in] socket_id Socket identifier.
- *  @param[in] flags Various receive flags.
- *  @param[out] addrlen The source address length.
- *  @returns The number of bytes received.
- *  @returns ENOTSOCK if the socket is not found.
- *  @returns NO_DATA if there are no received packets or data.
- *  @returns ENOMEM if there is not enough memory left.
- *  @returns EINVAL if the received address is not an IP address.
- *  @returns Other error codes as defined for the packet_translate() function.
- *  @returns Other error codes as defined for the data_reply() function.
- */
-int udp_recvfrom_message(socket_cores_ref local_sockets, int socket_id, int flags, size_t * addrlen);
+ *  @param[in] flags	Various receive flags.
+ *  @param[out] addrlen	The source address length.
+ *  @returns		The number of bytes received.
+ *  @returns		ENOTSOCK if the socket is not found.
+ *  @returns		NO_DATA if there are no received packets or data.
+ *  @returns		ENOMEM if there is not enough memory left.
+ *  @returns		EINVAL if the received address is not an IP address.
+ *  @returns		Other error codes as defined for the packet_translate()
+ *			function.
+ *  @returns		Other error codes as defined for the data_reply()
+ *			function.
+ */
+int
+udp_recvfrom_message(socket_cores_ref local_sockets, int socket_id, int flags,
+    size_t * addrlen);
 
 /*@}*/
@@ -189,10 +215,20 @@
 /** UDP global data.
  */
-udp_globals_t	udp_globals;
-
-int udp_initialize(async_client_conn_t client_connection){
+udp_globals_t udp_globals;
+
+int udp_initialize(async_client_conn_t client_connection)
+{
 	ERROR_DECLARE;
 
-	measured_string_t names[] = {{str_dup("UDP_CHECKSUM_COMPUTING"), 22}, {str_dup("UDP_AUTOBINDING"), 15}};
+	measured_string_t names[] = {
+		{
+			str_dup("UDP_CHECKSUM_COMPUTING"),
+			22
+		},
+		{
+			str_dup("UDP_AUTOBINDING"),
+			15
+		}
+	};
 	measured_string_ref configuration;
 	size_t count = sizeof(names) / sizeof(measured_string_t);
@@ -201,13 +237,18 @@
 	fibril_rwlock_initialize(&udp_globals.lock);
 	fibril_rwlock_write_lock(&udp_globals.lock);
-	udp_globals.icmp_phone = icmp_connect_module(SERVICE_ICMP, ICMP_CONNECT_TIMEOUT);
-	udp_globals.ip_phone = ip_bind_service(SERVICE_IP, IPPROTO_UDP, SERVICE_UDP, client_connection, udp_received_msg);
-	if(udp_globals.ip_phone < 0){
+
+	udp_globals.icmp_phone = icmp_connect_module(SERVICE_ICMP,
+	    ICMP_CONNECT_TIMEOUT);
+	udp_globals.ip_phone = ip_bind_service(SERVICE_IP, IPPROTO_UDP,
+	    SERVICE_UDP, client_connection);
+	if (udp_globals.ip_phone < 0)
 		return udp_globals.ip_phone;
-	}
+
 	// read default packet dimensions
-	ERROR_PROPAGATE(ip_packet_size_req(udp_globals.ip_phone, -1, &udp_globals.packet_dimension));
+	ERROR_PROPAGATE(ip_packet_size_req(udp_globals.ip_phone, -1,
+	    &udp_globals.packet_dimension));
 	ERROR_PROPAGATE(socket_ports_initialize(&udp_globals.sockets));
-	if(ERROR_OCCURRED(packet_dimensions_initialize(&udp_globals.dimensions))){
+	if (ERROR_OCCURRED(packet_dimensions_initialize(
+	    &udp_globals.dimensions))) {
 		socket_ports_destroy(&udp_globals.sockets);
 		return ERROR_CODE;
@@ -216,35 +257,43 @@
 	udp_globals.packet_dimension.content -= sizeof(udp_header_t);
 	udp_globals.last_used_port = UDP_FREE_PORTS_START - 1;
+
 	// get configuration
 	udp_globals.checksum_computing = NET_DEFAULT_UDP_CHECKSUM_COMPUTING;
 	udp_globals.autobinding = NET_DEFAULT_UDP_AUTOBINDING;
 	configuration = &names[0];
-	ERROR_PROPAGATE(net_get_conf_req(udp_globals.net_phone, &configuration, count, &data));
-	if(configuration){
-		if(configuration[0].value){
-			udp_globals.checksum_computing = (configuration[0].value[0] == 'y');
-		}
-		if(configuration[1].value){
-			udp_globals.autobinding = (configuration[1].value[0] == 'y');
-		}
+	ERROR_PROPAGATE(net_get_conf_req(udp_globals.net_phone, &configuration,
+	    count, &data));
+	if (configuration) {
+		if (configuration[0].value)
+			udp_globals.checksum_computing =
+			    (configuration[0].value[0] == 'y');
+		
+		if (configuration[1].value)
+			udp_globals.autobinding =
+			    (configuration[1].value[0] == 'y');
+
 		net_free_settings(configuration, data);
 	}
+
 	fibril_rwlock_write_unlock(&udp_globals.lock);
 	return EOK;
 }
 
-int udp_received_msg(device_id_t device_id, packet_t packet, services_t receiver, services_t error){
+int
+udp_received_msg(device_id_t device_id, packet_t packet, services_t receiver,
+    services_t error)
+{
 	int result;
 
 	fibril_rwlock_write_lock(&udp_globals.lock);
 	result = udp_process_packet(device_id, packet, error);
-	if(result != EOK){
+	if (result != EOK)
 		fibril_rwlock_write_unlock(&udp_globals.lock);
-	}
 
 	return result;
 }
 
-int udp_process_packet(device_id_t device_id, packet_t packet, services_t error){
+int udp_process_packet(device_id_t device_id, packet_t packet, services_t error)
+{
 	ERROR_DECLARE;
 
@@ -262,57 +311,57 @@
 	icmp_code_t code;
 	void *ip_header;
-	struct sockaddr * src;
-	struct sockaddr * dest;
+	struct sockaddr *src;
+	struct sockaddr *dest;
 	packet_dimension_ref packet_dimension;
 
-	if(error){
-		switch(error){
-			case SERVICE_ICMP:
-				// ignore error
-				// length = icmp_client_header_length(packet);
-				// process error
-				result = icmp_client_process_packet(packet, &type, &code, NULL, NULL);
-				if(result < 0){
-					return udp_release_and_return(packet, result);
-				}
-				length = (size_t) result;
-				if(ERROR_OCCURRED(packet_trim(packet, length, 0))){
-					return udp_release_and_return(packet, ERROR_CODE);
-				}
-				break;
-			default:
-				return udp_release_and_return(packet, ENOTSUP);
-		}
-	}
+	if (error) {
+		switch (error) {
+		case SERVICE_ICMP:
+			// ignore error
+			// length = icmp_client_header_length(packet);
+			// process error
+			result = icmp_client_process_packet(packet, &type,
+			    &code, NULL, NULL);
+			if (result < 0)
+				return udp_release_and_return(packet, result);
+			length = (size_t) result;
+			if (ERROR_OCCURRED(packet_trim(packet, length, 0)))
+				return udp_release_and_return(packet,
+				    ERROR_CODE);
+			break;
+		default:
+			return udp_release_and_return(packet, ENOTSUP);
+		}
+	}
+
 	// TODO process received ipopts?
 	result = ip_client_process_packet(packet, NULL, NULL, NULL, NULL, NULL);
-	if(result < 0){
+	if (result < 0)
 		return udp_release_and_return(packet, result);
-	}
 	offset = (size_t) result;
 
 	length = packet_get_data_length(packet);
-	if(length <= 0){
+	if (length <= 0)
 		return udp_release_and_return(packet, EINVAL);
-	}
-	if(length < UDP_HEADER_SIZE + offset){
+	if (length < UDP_HEADER_SIZE + offset)
 		return udp_release_and_return(packet, NO_DATA);
-	}
 
 	// trim all but UDP header
-	if(ERROR_OCCURRED(packet_trim(packet, offset, 0))){
+	if (ERROR_OCCURRED(packet_trim(packet, offset, 0)))
 		return udp_release_and_return(packet, ERROR_CODE);
-	}
 
 	// get udp header
 	header = (udp_header_ref) packet_get_data(packet);
-	if(! header){
+	if (!header)
 		return udp_release_and_return(packet, NO_DATA);
-	}
+
 	// find the destination socket
-	socket = socket_port_find(&udp_globals.sockets, ntohs(header->destination_port), SOCKET_MAP_KEY_LISTENING, 0);
-	if(! socket){
-		if(tl_prepare_icmp_packet(udp_globals.net_phone, udp_globals.icmp_phone, packet, error) == EOK){
-			icmp_destination_unreachable_msg(udp_globals.icmp_phone, ICMP_PORT_UNREACH, 0, packet);
+	socket = socket_port_find(&udp_globals.sockets,
+	ntohs(header->destination_port), SOCKET_MAP_KEY_LISTENING, 0);
+	if (!socket) {
+		if (tl_prepare_icmp_packet(udp_globals.net_phone,
+		    udp_globals.icmp_phone, packet, error) == EOK) {
+			icmp_destination_unreachable_msg(udp_globals.icmp_phone,
+			    ICMP_PORT_UNREACH, 0, packet);
 		}
 		return EADDRNOTAVAIL;
@@ -323,59 +372,81 @@
 	fragments = 0;
 	total_length = ntohs(header->total_length);
+
 	// compute header checksum if set
-	if(header->checksum && (! error)){
-		result = packet_get_addr(packet, (uint8_t **) &src, (uint8_t **) &dest);
-		if(result <= 0){
+	if (header->checksum && (!error)) {
+		result = packet_get_addr(packet, (uint8_t **) &src,
+		    (uint8_t **) &dest);
+		if( result <= 0)
 			return udp_release_and_return(packet, result);
-		}
-		if(ERROR_OCCURRED(ip_client_get_pseudo_header(IPPROTO_UDP, src, result, dest, result, total_length, &ip_header, &length))){
+
+		if (ERROR_OCCURRED(ip_client_get_pseudo_header(IPPROTO_UDP,
+		    src, result, dest, result, total_length, &ip_header,
+		    &length))) {
 			return udp_release_and_return(packet, ERROR_CODE);
-		}else{
+		} else {
 			checksum = compute_checksum(0, ip_header, length);
-			// the udp header checksum will be added with the first fragment later
+			// the udp header checksum will be added with the first
+			// fragment later
 			free(ip_header);
 		}
-	}else{
+	} else {
 		header->checksum = 0;
 		checksum = 0;
 	}
 
-	do{
+	do {
 		++ fragments;
 		length = packet_get_data_length(next_packet);
-		if(length <= 0){
+		if (length <= 0)
 			return udp_release_and_return(packet, NO_DATA);
-		}
-		if(total_length < length){
-			if(ERROR_OCCURRED(packet_trim(next_packet, 0, length - total_length))){
-				return udp_release_and_return(packet, ERROR_CODE);
+
+		if (total_length < length) {
+			if (ERROR_OCCURRED(packet_trim(next_packet, 0,
+			    length - total_length))) {
+				return udp_release_and_return(packet,
+				    ERROR_CODE);
 			}
+
 			// add partial checksum if set
-			if(header->checksum){
-				checksum = compute_checksum(checksum, packet_get_data(packet), packet_get_data_length(packet));
+			if (header->checksum) {
+				checksum = compute_checksum(checksum,
+				    packet_get_data(packet),
+				    packet_get_data_length(packet));
 			}
+
 			// relese the rest of the packet fragments
 			tmp_packet = pq_next(next_packet);
-			while(tmp_packet){
+			while (tmp_packet) {
 				next_packet = pq_detach(tmp_packet);
-				pq_release_remote(udp_globals.net_phone, packet_get_id(tmp_packet));
+				pq_release_remote(udp_globals.net_phone,
+				    packet_get_id(tmp_packet));
 				tmp_packet = next_packet;
 			}
+
 			// exit the loop
 			break;
 		}
 		total_length -= length;
+
 		// add partial checksum if set
-		if(header->checksum){
-			checksum = compute_checksum(checksum, packet_get_data(packet), packet_get_data_length(packet));
-		}
-	}while((next_packet = pq_next(next_packet)) && (total_length > 0));
+		if (header->checksum) {
+			checksum = compute_checksum(checksum,
+			    packet_get_data(packet),
+			    packet_get_data_length(packet));
+		}
+
+	} while ((next_packet = pq_next(next_packet)) && (total_length > 0));
 
 	// check checksum
-	if(header->checksum){
-		if(flip_checksum(compact_checksum(checksum)) != IP_CHECKSUM_ZERO){
-			if(tl_prepare_icmp_packet(udp_globals.net_phone, udp_globals.icmp_phone, packet, error) == EOK){
+	if (header->checksum) {
+		if (flip_checksum(compact_checksum(checksum)) !=
+		    IP_CHECKSUM_ZERO) {
+			if (tl_prepare_icmp_packet(udp_globals.net_phone,
+			    udp_globals.icmp_phone, packet, error) == EOK) {
 				// checksum error ICMP
-				icmp_parameter_problem_msg(udp_globals.icmp_phone, ICMP_PARAM_POINTER, ((size_t) ((void *) &header->checksum)) - ((size_t) ((void *) header)), packet);
+				icmp_parameter_problem_msg(
+				    udp_globals.icmp_phone, ICMP_PARAM_POINTER,
+				    ((size_t) ((void *) &header->checksum)) -
+				    ((size_t) ((void *) header)), packet);
 			}
 			return EINVAL;
@@ -384,6 +455,8 @@
 
 	// queue the received packet
-	if(ERROR_OCCURRED(dyn_fifo_push(&socket->received, packet_get_id(packet), SOCKET_MAX_RECEIVED_SIZE))
-	    || ERROR_OCCURRED(tl_get_ip_packet_dimension(udp_globals.ip_phone, &udp_globals.dimensions, device_id, &packet_dimension))){
+	if (ERROR_OCCURRED(dyn_fifo_push(&socket->received,
+	    packet_get_id(packet), SOCKET_MAX_RECEIVED_SIZE)) ||
+	    ERROR_OCCURRED(tl_get_ip_packet_dimension(udp_globals.ip_phone,
+	    &udp_globals.dimensions, device_id, &packet_dimension))) {
 		return udp_release_and_return(packet, ERROR_CODE);
 	}
@@ -391,9 +464,15 @@
 	// notify the destination socket
 	fibril_rwlock_write_unlock(&udp_globals.lock);
-	async_msg_5(socket->phone, NET_SOCKET_RECEIVED, (ipcarg_t) socket->socket_id, packet_dimension->content, 0, 0, (ipcarg_t) fragments);
+	async_msg_5(socket->phone, NET_SOCKET_RECEIVED,
+	    (ipcarg_t) socket->socket_id, packet_dimension->content, 0, 0,
+	    (ipcarg_t) fragments);
+
 	return EOK;
 }
 
-int udp_message_standalone(ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count){
+int
+udp_message_standalone(ipc_callid_t callid, ipc_call_t * call,
+    ipc_call_t * answer, int * answer_count)
+{
 	ERROR_DECLARE;
 
@@ -401,22 +480,28 @@
 
 	*answer_count = 0;
-	switch(IPC_GET_METHOD(*call)){
-		case NET_TL_RECEIVED:
-			if(! ERROR_OCCURRED(packet_translate_remote(udp_globals.net_phone, &packet, IPC_GET_PACKET(call)))){
-				ERROR_CODE = udp_received_msg(IPC_GET_DEVICE(call), packet, SERVICE_UDP, IPC_GET_ERROR(call));
-			}
-			return ERROR_CODE;
-		case IPC_M_CONNECT_TO_ME:
-			return udp_process_client_messages(callid, * call);
-	}
+
+	switch (IPC_GET_METHOD(*call)) {
+	case NET_TL_RECEIVED:
+		if (!ERROR_OCCURRED(packet_translate_remote(
+		    udp_globals.net_phone, &packet, IPC_GET_PACKET(call)))) {
+			ERROR_CODE = udp_received_msg(IPC_GET_DEVICE(call),
+			    packet, SERVICE_UDP, IPC_GET_ERROR(call));
+		}
+		return ERROR_CODE;
+	
+	case IPC_M_CONNECT_TO_ME:
+		return udp_process_client_messages(callid, * call);
+	}
+
 	return ENOTSUP;
 }
 
-int udp_process_client_messages(ipc_callid_t callid, ipc_call_t call){
+int udp_process_client_messages(ipc_callid_t callid, ipc_call_t call)
+{
 	int res;
 	bool keep_on_going = true;
 	socket_cores_t local_sockets;
 	int app_phone = IPC_GET_PHONE(&call);
-	struct sockaddr * addr;
+	struct sockaddr *addr;
 	int socket_id;
 	size_t addrlen;
@@ -433,9 +518,10 @@
 	answer_count = 0;
 
-	// The client connection is only in one fibril and therefore no additional locks are needed.
+	// The client connection is only in one fibril and therefore no
+	// additional locks are needed.
 
 	socket_cores_initialize(&local_sockets);
 
-	while(keep_on_going){
+	while (keep_on_going) {
 
 		// answer the call
@@ -449,67 +535,94 @@
 
 		// process the call
-		switch(IPC_GET_METHOD(call)){
-			case IPC_M_PHONE_HUNGUP:
-				keep_on_going = false;
-				res = EHANGUP;
+		switch (IPC_GET_METHOD(call)) {
+		case IPC_M_PHONE_HUNGUP:
+			keep_on_going = false;
+			res = EHANGUP;
+			break;
+
+		case NET_SOCKET:
+			socket_id = SOCKET_GET_SOCKET_ID(call);
+			res = socket_create(&local_sockets, app_phone, NULL,
+			    &socket_id);
+			SOCKET_SET_SOCKET_ID(answer, socket_id);
+
+			if (res != EOK)
 				break;
-			case NET_SOCKET:
-				socket_id = SOCKET_GET_SOCKET_ID(call);
-				res = socket_create(&local_sockets, app_phone, NULL, &socket_id);
-				SOCKET_SET_SOCKET_ID(answer, socket_id);
-
-				if(res == EOK){
-					if (tl_get_ip_packet_dimension(udp_globals.ip_phone, &udp_globals.dimensions, DEVICE_INVALID_ID, &packet_dimension) == EOK){
-						SOCKET_SET_DATA_FRAGMENT_SIZE(answer, packet_dimension->content);
-					}
-//					SOCKET_SET_DATA_FRAGMENT_SIZE(answer, MAX_UDP_FRAGMENT_SIZE);
-					SOCKET_SET_HEADER_SIZE(answer, UDP_HEADER_SIZE);
-					answer_count = 3;
-				}
+			
+			if (tl_get_ip_packet_dimension(udp_globals.ip_phone,
+			    &udp_globals.dimensions, DEVICE_INVALID_ID,
+			    &packet_dimension) == EOK) {
+				SOCKET_SET_DATA_FRAGMENT_SIZE(answer,
+				    packet_dimension->content);
+			}
+
+//			SOCKET_SET_DATA_FRAGMENT_SIZE(answer,
+//			    MAX_UDP_FRAGMENT_SIZE);
+			SOCKET_SET_HEADER_SIZE(answer, UDP_HEADER_SIZE);
+			answer_count = 3;
+			break;
+
+		case NET_SOCKET_BIND:
+			res = data_receive((void **) &addr, &addrlen);
+			if (res != EOK)
 				break;
-			case NET_SOCKET_BIND:
-				res = data_receive((void **) &addr, &addrlen);
-				if(res == EOK){
-					fibril_rwlock_write_lock(&udp_globals.lock);
-					res = socket_bind(&local_sockets, &udp_globals.sockets, SOCKET_GET_SOCKET_ID(call), addr, addrlen, UDP_FREE_PORTS_START, UDP_FREE_PORTS_END, udp_globals.last_used_port);
-					fibril_rwlock_write_unlock(&udp_globals.lock);
-					free(addr);
-				}
+			fibril_rwlock_write_lock(&udp_globals.lock);
+			res = socket_bind(&local_sockets, &udp_globals.sockets,
+			    SOCKET_GET_SOCKET_ID(call), addr, addrlen,
+			    UDP_FREE_PORTS_START, UDP_FREE_PORTS_END,
+			    udp_globals.last_used_port);
+			fibril_rwlock_write_unlock(&udp_globals.lock);
+			free(addr);
+			break;
+
+		case NET_SOCKET_SENDTO:
+			res = data_receive((void **) &addr, &addrlen);
+			if (res != EOK)
 				break;
-			case NET_SOCKET_SENDTO:
-				res = data_receive((void **) &addr, &addrlen);
-				if(res == EOK){
-					fibril_rwlock_write_lock(&udp_globals.lock);
-					res = udp_sendto_message(&local_sockets, SOCKET_GET_SOCKET_ID(call), addr, addrlen, SOCKET_GET_DATA_FRAGMENTS(call), &size, SOCKET_GET_FLAGS(call));
-					SOCKET_SET_DATA_FRAGMENT_SIZE(answer, size);
-					if(res != EOK){
-						fibril_rwlock_write_unlock(&udp_globals.lock);
-					}else{
-						answer_count = 2;
-					}
-					free(addr);
-				}
+
+			fibril_rwlock_write_lock(&udp_globals.lock);
+			res = udp_sendto_message(&local_sockets,
+			    SOCKET_GET_SOCKET_ID(call), addr, addrlen,
+			    SOCKET_GET_DATA_FRAGMENTS(call), &size,
+			    SOCKET_GET_FLAGS(call));
+			SOCKET_SET_DATA_FRAGMENT_SIZE(answer, size);
+
+			if (res != EOK)
+				fibril_rwlock_write_unlock(&udp_globals.lock);
+			else
+				answer_count = 2;
+			
+			free(addr);
+			break;
+
+		case NET_SOCKET_RECVFROM:
+			fibril_rwlock_write_lock(&udp_globals.lock);
+			res = udp_recvfrom_message(&local_sockets,
+			     SOCKET_GET_SOCKET_ID(call), SOCKET_GET_FLAGS(call),
+			     &addrlen);
+			fibril_rwlock_write_unlock(&udp_globals.lock);
+
+			if (res <= 0)
 				break;
-			case NET_SOCKET_RECVFROM:
-				fibril_rwlock_write_lock(&udp_globals.lock);
-				res = udp_recvfrom_message(&local_sockets, SOCKET_GET_SOCKET_ID(call), SOCKET_GET_FLAGS(call), &addrlen);
-				fibril_rwlock_write_unlock(&udp_globals.lock);
-				if(res > 0){
-					SOCKET_SET_READ_DATA_LENGTH(answer, res);
-					SOCKET_SET_ADDRESS_LENGTH(answer, addrlen);
-					answer_count = 3;
-					res = EOK;
-				}
-				break;
-			case NET_SOCKET_CLOSE:
-				fibril_rwlock_write_lock(&udp_globals.lock);
-				res = socket_destroy(udp_globals.net_phone, SOCKET_GET_SOCKET_ID(call), &local_sockets, &udp_globals.sockets, NULL);
-				fibril_rwlock_write_unlock(&udp_globals.lock);
-				break;
-			case NET_SOCKET_GETSOCKOPT:
-			case NET_SOCKET_SETSOCKOPT:
-			default:
-				res = ENOTSUP;
-				break;
+
+			SOCKET_SET_READ_DATA_LENGTH(answer, res);
+			SOCKET_SET_ADDRESS_LENGTH(answer, addrlen);
+			answer_count = 3;
+			res = EOK;
+			break;
+			
+		case NET_SOCKET_CLOSE:
+			fibril_rwlock_write_lock(&udp_globals.lock);
+			res = socket_destroy(udp_globals.net_phone,
+			    SOCKET_GET_SOCKET_ID(call), &local_sockets,
+			    &udp_globals.sockets, NULL);
+			fibril_rwlock_write_unlock(&udp_globals.lock);
+			break;
+
+		case NET_SOCKET_GETSOCKOPT:
+		case NET_SOCKET_SETSOCKOPT:
+		default:
+			res = ENOTSUP;
+			break;
 		}
 	}
@@ -519,10 +632,15 @@
 
 	// release all local sockets
-	socket_cores_release(udp_globals.net_phone, &local_sockets, &udp_globals.sockets, NULL);
+	socket_cores_release(udp_globals.net_phone, &local_sockets,
+	    &udp_globals.sockets, NULL);
 
 	return res;
 }
 
-int udp_sendto_message(socket_cores_ref local_sockets, int socket_id, const struct sockaddr * addr, socklen_t addrlen, int fragments, size_t * data_fragment_size, int flags){
+int
+udp_sendto_message(socket_cores_ref local_sockets, int socket_id,
+    const struct sockaddr *addr, socklen_t addrlen, int fragments,
+    size_t *data_fragment_size, int flags)
+{
 	ERROR_DECLARE;
 
@@ -544,22 +662,27 @@
 
 	socket = socket_cores_find(local_sockets, socket_id);
-	if(! socket){
+	if (!socket)
 		return ENOTSOCK;
-	}
-
-	if((socket->port <= 0) && udp_globals.autobinding){
+
+	if ((socket->port <= 0) && udp_globals.autobinding) {
 		// bind the socket to a random free port if not bound
-//		do{
+//		do {
 			// try to find a free port
 //			fibril_rwlock_read_unlock(&udp_globals.lock);
 //			fibril_rwlock_write_lock(&udp_globals.lock);
 			// might be changed in the meantime
-//			if(socket->port <= 0){
-				if(ERROR_OCCURRED(socket_bind_free_port(&udp_globals.sockets, socket, UDP_FREE_PORTS_START, UDP_FREE_PORTS_END, udp_globals.last_used_port))){
-//					fibril_rwlock_write_unlock(&udp_globals.lock);
-//					fibril_rwlock_read_lock(&udp_globals.lock);
+//			if (socket->port <= 0) {
+				if (ERROR_OCCURRED(socket_bind_free_port(
+				    &udp_globals.sockets, socket,
+				    UDP_FREE_PORTS_START, UDP_FREE_PORTS_END,
+				    udp_globals.last_used_port))) {
+//					fibril_rwlock_write_unlock(
+//					    &udp_globals.lock);
+//					fibril_rwlock_read_lock(
+//					    &udp_globals.lock);
 					return ERROR_CODE;
 				}
-				// set the next port as the search starting port number
+				// set the next port as the search starting port
+				// number
 				udp_globals.last_used_port = socket->port;
 //			}
@@ -567,51 +690,61 @@
 //			fibril_rwlock_read_lock(&udp_globals.lock);
 			// might be changed in the meantime
-//		}while(socket->port <= 0);
-	}
-
-	if(udp_globals.checksum_computing){
-		if(ERROR_OCCURRED(ip_get_route_req(udp_globals.ip_phone, IPPROTO_UDP, addr, addrlen, &device_id, &ip_header, &headerlen))){
+//		} while (socket->port <= 0);
+	}
+
+	if (udp_globals.checksum_computing) {
+		if (ERROR_OCCURRED(ip_get_route_req(udp_globals.ip_phone,
+		    IPPROTO_UDP, addr, addrlen, &device_id, &ip_header,
+		    &headerlen))) {
 			return udp_release_and_return(packet, ERROR_CODE);
 		}
 		// get the device packet dimension
-//		ERROR_PROPAGATE(tl_get_ip_packet_dimension(udp_globals.ip_phone, &udp_globals.dimensions, device_id, &packet_dimension));
-	}
-//	}else{
+//		ERROR_PROPAGATE(tl_get_ip_packet_dimension(udp_globals.ip_phone,
+//		    &udp_globals.dimensions, device_id, &packet_dimension));
+	}
+//	} else {
 		// do not ask all the time
-		ERROR_PROPAGATE(ip_packet_size_req(udp_globals.ip_phone, -1, &udp_globals.packet_dimension));
+		ERROR_PROPAGATE(ip_packet_size_req(udp_globals.ip_phone, -1,
+		    &udp_globals.packet_dimension));
 		packet_dimension = &udp_globals.packet_dimension;
 //	}
 
 	// read the first packet fragment
-	result = tl_socket_read_packet_data(udp_globals.net_phone, &packet, UDP_HEADER_SIZE, packet_dimension, addr, addrlen);
-	if(result < 0){
+	result = tl_socket_read_packet_data(udp_globals.net_phone, &packet,
+	    UDP_HEADER_SIZE, packet_dimension, addr, addrlen);
+	if (result < 0)
 		return result;
-	}
+
 	total_length = (size_t) result;
-	if(udp_globals.checksum_computing){
-		checksum = compute_checksum(0, packet_get_data(packet), packet_get_data_length(packet));
-	}else{
+	if (udp_globals.checksum_computing)
+		checksum = compute_checksum(0, packet_get_data(packet),
+		    packet_get_data_length(packet));
+	else
 		checksum = 0;
-	}
+
 	// prefix the udp header
 	header = PACKET_PREFIX(packet, udp_header_t);
-	if(! header){
+	if(! header)
 		return udp_release_and_return(packet, ENOMEM);
-	}
+
 	bzero(header, sizeof(*header));
 	// read the rest of the packet fragments
-	for(index = 1; index < fragments; ++ index){
-		result = tl_socket_read_packet_data(udp_globals.net_phone, &next_packet, 0, packet_dimension, addr, addrlen);
-		if(result < 0){
+	for (index = 1; index < fragments; ++ index) {
+		result = tl_socket_read_packet_data(udp_globals.net_phone,
+		    &next_packet, 0, packet_dimension, addr, addrlen);
+		if (result < 0)
 			return udp_release_and_return(packet, result);
-		}
-		if(ERROR_OCCURRED(pq_add(&packet, next_packet, index, 0))){
+
+		if (ERROR_OCCURRED(pq_add(&packet, next_packet, index, 0)))
 			return udp_release_and_return(packet, ERROR_CODE);
-		}
+
 		total_length += (size_t) result;
-		if(udp_globals.checksum_computing){
-			checksum = compute_checksum(checksum, packet_get_data(next_packet), packet_get_data_length(next_packet));
-		}
-	}
+		if (udp_globals.checksum_computing) {
+			checksum = compute_checksum(checksum,
+			    packet_get_data(next_packet),
+			    packet_get_data_length(next_packet));
+		}
+	}
+
 	// set the udp header
 	header->source_port = htons((socket->port > 0) ? socket->port : 0);
@@ -619,29 +752,40 @@
 	header->total_length = htons(total_length + sizeof(*header));
 	header->checksum = 0;
-	if(udp_globals.checksum_computing){
+	if (udp_globals.checksum_computing) {
 		// update the pseudo header
-		if(ERROR_OCCURRED(ip_client_set_pseudo_header_data_length(ip_header, headerlen, total_length + UDP_HEADER_SIZE))){
+		if (ERROR_OCCURRED(ip_client_set_pseudo_header_data_length(
+		    ip_header, headerlen, total_length + UDP_HEADER_SIZE))) {
 			free(ip_header);
 			return udp_release_and_return(packet, ERROR_CODE);
 		}
+
 		// finish the checksum computation
 		checksum = compute_checksum(checksum, ip_header, headerlen);
-		checksum = compute_checksum(checksum, (uint8_t *) header, sizeof(*header));
-		header->checksum = htons(flip_checksum(compact_checksum(checksum)));
+		checksum = compute_checksum(checksum, (uint8_t *) header,
+		    sizeof(*header));
+		header->checksum =
+		    htons(flip_checksum(compact_checksum(checksum)));
 		free(ip_header);
-	}else{
+	} else {
 		device_id = DEVICE_INVALID_ID;
 	}
+
 	// prepare the first packet fragment
-	if(ERROR_OCCURRED(ip_client_prepare_packet(packet, IPPROTO_UDP, 0, 0, 0, 0))){
+	if (ERROR_OCCURRED(ip_client_prepare_packet(packet, IPPROTO_UDP, 0, 0,
+	    0, 0))) {
 		return udp_release_and_return(packet, ERROR_CODE);
 	}
+
 	// send the packet
 	fibril_rwlock_write_unlock(&udp_globals.lock);
 	ip_send_msg(udp_globals.ip_phone, device_id, packet, SERVICE_UDP, 0);
+
 	return EOK;
 }
 
-int udp_recvfrom_message(socket_cores_ref local_sockets, int socket_id, int flags, size_t * addrlen){
+int
+udp_recvfrom_message(socket_cores_ref local_sockets, int socket_id, int flags,
+    size_t *addrlen)
+{
 	ERROR_DECLARE;
 
@@ -650,23 +794,25 @@
 	packet_t packet;
 	udp_header_ref header;
-	struct sockaddr * addr;
+	struct sockaddr *addr;
 	size_t length;
-	uint8_t * data;
+	uint8_t *data;
 	int result;
 
 	// find the socket
 	socket = socket_cores_find(local_sockets, socket_id);
-	if(! socket){
+	if (!socket)
 		return ENOTSOCK;
-	}
+
 	// get the next received packet
 	packet_id = dyn_fifo_value(&socket->received);
-	if(packet_id < 0){
+	if (packet_id < 0)
 		return NO_DATA;
-	}
-	ERROR_PROPAGATE(packet_translate_remote(udp_globals.net_phone, &packet, packet_id));
+
+	ERROR_PROPAGATE(packet_translate_remote(udp_globals.net_phone, &packet,
+	    packet_id));
+
 	// get udp header
 	data = packet_get_data(packet);
-	if(! data){
+	if (!data) {
 		pq_release_remote(udp_globals.net_phone, packet_id);
 		return NO_DATA;
@@ -676,9 +822,11 @@
 	// set the source address port
 	result = packet_get_addr(packet, (uint8_t **) &addr, NULL);
-	if(ERROR_OCCURRED(tl_set_address_port(addr, result, ntohs(header->source_port)))){
+	if (ERROR_OCCURRED(tl_set_address_port(addr, result,
+	    ntohs(header->source_port)))) {
 		pq_release_remote(udp_globals.net_phone, packet_id);
 		return ERROR_CODE;
 	}
 	*addrlen = (size_t) result;
+
 	// send the source address
 	ERROR_PROPAGATE(data_reply(addr, * addrlen));
@@ -693,9 +841,11 @@
 	dyn_fifo_pop(&socket->received);
 	pq_release_remote(udp_globals.net_phone, packet_get_id(packet));
+
 	// return the total length
 	return (int) length;
 }
 
-int udp_release_and_return(packet_t packet, int result){
+int udp_release_and_return(packet_t packet, int result)
+{
 	pq_release_remote(udp_globals.net_phone, packet_get_id(packet));
 	return result;
@@ -704,6 +854,6 @@
 /** Default thread for new connections.
  *
- *  @param[in] iid The initial message identifier.
- *  @param[in] icall The initial message call structure.
+ *  @param[in] iid	The initial message identifier.
+ *  @param[in] icall	The initial message call structure.
  *
  */
@@ -716,5 +866,5 @@
 	ipc_answer_0(iid, EOK);
 	
-	while(true) {
+	while (true) {
 		ipc_call_t answer;
 		int answer_count;
@@ -731,6 +881,9 @@
 		    &answer_count);
 		
-		/* End if said to either by the message or the processing result */
-		if ((IPC_GET_METHOD(call) == IPC_M_PHONE_HUNGUP) || (res == EHANGUP))
+		/*
+		 * End if said to either by the message or the processing result
+		 */
+		if ((IPC_GET_METHOD(call) == IPC_M_PHONE_HUNGUP) ||
+		    (res == EHANGUP))
 			return;
 		
@@ -742,10 +895,11 @@
 /** Starts the module.
  *
- *  @param argc The count of the command line arguments. Ignored parameter.
- *  @param argv The command line parameters. Ignored parameter.
- *
- *  @returns EOK on success.
- *  @returns Other error codes as defined for each specific module start function.
- *
+ *  @param argc		The count of the command line arguments. Ignored
+ *			parameter.
+ *  @param argv		The command line parameters. Ignored parameter.
+ *
+ *  @returns		EOK on success.
+ *  @returns		Other error codes as defined for each specific module
+ *			start function.
  */
 int main(int argc, char *argv[])
Index: uspace/srv/net/tl/udp/udp_module.c
===================================================================
--- uspace/srv/net/tl/udp/udp_module.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/srv/net/tl/udp/udp_module.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -40,10 +40,10 @@
 #include <async.h>
 #include <stdio.h>
+#include <err.h>
 #include <ipc/ipc.h>
 #include <ipc/services.h>
 
-#include <net_err.h>
-#include <net_modules.h>
-#include <packet/packet.h>
+#include <net/modules.h>
+#include <net/packet.h>
 #include <net_interface.h>
 #include <tl_local.h>
@@ -69,5 +69,5 @@
 
 	async_set_client_connection(client_connection);
-	udp_globals.net_phone = net_connect_module(SERVICE_NETWORKING);
+	udp_globals.net_phone = net_connect_module();
 	if(udp_globals.net_phone < 0){
 		return udp_globals.net_phone;
Index: uspace/srv/vfs/vfs.h
===================================================================
--- uspace/srv/vfs/vfs.h	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/srv/vfs/vfs.h	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -169,5 +169,5 @@
 
 extern int vfs_grab_phone(fs_handle_t);
-extern void vfs_release_phone(int);
+extern void vfs_release_phone(fs_handle_t, int);
 
 extern fs_handle_t fs_name_to_handle(char *, bool);
Index: uspace/srv/vfs/vfs_lookup.c
===================================================================
--- uspace/srv/vfs/vfs_lookup.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/srv/vfs/vfs_lookup.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -168,5 +168,5 @@
 	ipcarg_t rc;
 	async_wait_for(req, &rc);
-	vfs_release_phone(phone);
+	vfs_release_phone(root->fs_handle, phone);
 	
 	fibril_mutex_lock(&plb_mutex);
@@ -215,5 +215,5 @@
 	ipcarg_t rc;
 	async_wait_for(req, &rc);
-	vfs_release_phone(phone);
+	vfs_release_phone(result->triplet.fs_handle, phone);
 	
 	if (rc == EOK) {
Index: uspace/srv/vfs/vfs_node.c
===================================================================
--- uspace/srv/vfs/vfs_node.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/srv/vfs/vfs_node.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -133,5 +133,5 @@
 		    (ipcarg_t)node->dev_handle, (ipcarg_t)node->index);
 		assert(rc == EOK);
-		vfs_release_phone(phone);
+		vfs_release_phone(node->fs_handle, phone);
 	}
 	if (free_vfs_node)
Index: uspace/srv/vfs/vfs_ops.c
===================================================================
--- uspace/srv/vfs/vfs_ops.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/srv/vfs/vfs_ops.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -39,5 +39,5 @@
 #include <ipc/ipc.h>
 #include <macros.h>
-#include <limits.h>
+#include <stdint.h>
 #include <async.h>
 #include <errno.h>
@@ -131,5 +131,5 @@
 			if (rc != EOK) {
 				async_wait_for(msg, NULL);
-				vfs_release_phone(phone);
+				vfs_release_phone(fs_handle, phone);
 				fibril_rwlock_write_unlock(&namespace_rwlock);
 				ipc_answer_0(rid, rc);
@@ -137,5 +137,5 @@
 			}
 			async_wait_for(msg, &rc);
-			vfs_release_phone(phone);
+			vfs_release_phone(fs_handle, phone);
 			
 			if (rc != EOK) {
@@ -196,6 +196,6 @@
 	if (rc != EOK) {
 		async_wait_for(msg, NULL);
-		vfs_release_phone(mountee_phone);
-		vfs_release_phone(phone);
+		vfs_release_phone(fs_handle, mountee_phone);
+		vfs_release_phone(mp_res.triplet.fs_handle, phone);
 		/* Mount failed, drop reference to mp_node. */
 		if (mp_node)
@@ -206,5 +206,5 @@
 	}
 
-	vfs_release_phone(mountee_phone);
+	vfs_release_phone(fs_handle, mountee_phone);
 	
 	/* send the mount options */
@@ -212,5 +212,5 @@
 	if (rc != EOK) {
 		async_wait_for(msg, NULL);
-		vfs_release_phone(phone);
+		vfs_release_phone(mp_res.triplet.fs_handle, phone);
 		/* Mount failed, drop reference to mp_node. */
 		if (mp_node)
@@ -221,5 +221,5 @@
 	}
 	async_wait_for(msg, &rc);
-	vfs_release_phone(phone);
+	vfs_release_phone(mp_res.triplet.fs_handle, phone);
 	
 	if (rc == EOK) {
@@ -423,5 +423,5 @@
 		rc = async_req_1_0(phone, VFS_OUT_UNMOUNTED,
 		    mr_node->dev_handle);
-		vfs_release_phone(phone);
+		vfs_release_phone(mr_node->fs_handle, phone);
 		if (rc != EOK) {
 			fibril_rwlock_write_unlock(&namespace_rwlock);
@@ -460,5 +460,5 @@
 		rc = async_req_2_0(phone, VFS_OUT_UNMOUNT, mp_node->dev_handle,
 		    mp_node->index);
-		vfs_release_phone(phone);
+		vfs_release_phone(mp_node->fs_handle, phone);
 		if (rc != EOK) {
 			fibril_rwlock_write_unlock(&namespace_rwlock);
@@ -592,4 +592,5 @@
 	}
 	vfs_file_t *file = vfs_file_get(fd);
+	assert(file);
 	file->node = node;
 	if (oflag & O_APPEND)
@@ -715,5 +716,5 @@
 	async_wait_for(msg, &rc);
 	
-	vfs_release_phone(fs_phone);
+	vfs_release_phone(file->node->fs_handle, fs_phone);
 	fibril_mutex_unlock(&file->lock);
 	
@@ -746,5 +747,5 @@
 		async_wait_for(msg, &rc);
 		
-		vfs_release_phone(fs_phone);
+		vfs_release_phone(file->node->fs_handle, fs_phone);
 		fibril_mutex_unlock(&file->lock);
 		
@@ -845,5 +846,5 @@
 	}
 	
-	vfs_release_phone(fs_phone);
+	vfs_release_phone(file->node->fs_handle, fs_phone);
 	
 	size_t bytes = IPC_GET_ARG1(answer);
@@ -969,5 +970,5 @@
 	rc = async_req_4_0(fs_phone, VFS_OUT_TRUNCATE, (ipcarg_t) dev_handle,
 	    (ipcarg_t) index, LOWER32(size), UPPER32(size));
-	vfs_release_phone(fs_phone);
+	vfs_release_phone(fs_handle, fs_phone);
 	return (int)rc;
 }
@@ -1025,5 +1026,5 @@
 	ipc_forward_fast(callid, fs_phone, 0, 0, 0, IPC_FF_ROUTE_FROM_ME);
 	async_wait_for(msg, &rc);
-	vfs_release_phone(fs_phone);
+	vfs_release_phone(file->node->fs_handle, fs_phone);
 
 	fibril_mutex_unlock(&file->lock);
@@ -1076,5 +1077,5 @@
 	ipcarg_t rv;
 	async_wait_for(msg, &rv);
-	vfs_release_phone(fs_phone);
+	vfs_release_phone(node->fs_handle, fs_phone);
 
 	ipc_answer_0(rid, rv);
@@ -1354,4 +1355,5 @@
 		int ret = vfs_close_internal(newfile);
 		if (ret != EOK) {
+			fibril_mutex_unlock(&oldfile->lock);
 			ipc_answer_0(rid, ret);
 			return;
@@ -1360,4 +1362,5 @@
 		ret = vfs_fd_free(newfd);
 		if (ret != EOK) {
+			fibril_mutex_unlock(&oldfile->lock);
 			ipc_answer_0(rid, ret);
 			return;
Index: uspace/srv/vfs/vfs_register.c
===================================================================
--- uspace/srv/vfs/vfs_register.c	(revision a6e54c5db4014406256cc9e1682c3c4771222aef)
+++ uspace/srv/vfs/vfs_register.c	(revision 04cb68f2d06da3440e206ec4339c4d23afa3910a)
@@ -39,5 +39,7 @@
 #include <ipc/services.h>
 #include <async.h>
+#include <async_rel.h>
 #include <fibril.h>
+#include <fibril_synch.h>
 #include <errno.h>
 #include <stdio.h>
@@ -46,5 +48,4 @@
 #include <ctype.h>
 #include <bool.h>
-#include <fibril_synch.h>
 #include <adt/list.h>
 #include <as.h>
@@ -252,4 +253,6 @@
 int vfs_grab_phone(fs_handle_t handle)
 {
+	link_t *cur;
+	fs_info_t *fs;
 	int phone;
 
@@ -262,6 +265,4 @@
 	 */
 	fibril_mutex_lock(&fs_head_lock);
-	link_t *cur;
-	fs_info_t *fs;
 	for (cur = fs_head.next; cur != &fs_head; cur = cur->next) {
 		fs = list_get_instance(cur, fs_info_t, fs_link);
@@ -269,5 +270,5 @@
 			fibril_mutex_unlock(&fs_head_lock);
 			fibril_mutex_lock(&fs->phone_lock);
-			phone = ipc_connect_me_to(fs->phone, 0, 0, 0);
+			phone = async_relation_create(fs->phone);
 			fibril_mutex_unlock(&fs->phone_lock);
 
@@ -284,8 +285,23 @@
  * @param phone		Phone to FS task.
  */
-void vfs_release_phone(int phone)
-{
-	/* TODO: implement connection caching */
-	ipc_hangup(phone);
+void vfs_release_phone(fs_handle_t handle, int phone)
+{
+	link_t *cur;
+	fs_info_t *fs;
+
+	fibril_mutex_lock(&fs_head_lock);
+	for (cur = fs_head.next; cur != &fs_head; cur = cur->next) {
+		fs = list_get_instance(cur, fs_info_t, fs_link);
+		if (fs->fs_handle == handle) {
+			fibril_mutex_unlock(&fs_head_lock);
+			fibril_mutex_lock(&fs->phone_lock);
+			async_relation_destroy(fs->phone, phone);
+			fibril_mutex_unlock(&fs->phone_lock);
+			return;
+		}
+	}
+	/* should not really get here */
+	abort();
+	fibril_mutex_unlock(&fs_head_lock);
 }
 
