Index: HelenOS.config
===================================================================
--- HelenOS.config	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ HelenOS.config	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -37,4 +37,5 @@
 @ "ia64" Intel IA-64
 @ "mips32" MIPS 32-bit
+@ "mips64" MIPS 64-bit
 @ "ppc32" PowerPC 32-bit (iMac G4)
 @ "sparc64" Sun UltraSPARC 64-bit
@@ -48,4 +49,8 @@
 
 % Machine type
+@ "msim" MSIM
+! [PLATFORM=mips64] MACHINE (choice)
+
+% Machine type
 @ "i460GX" i460GX chipset machine
 @ "ski" Ski ia64 simulator
@@ -54,5 +59,4 @@
 % Machine type
 @ "generic" Generic Sun workstation or server
-@ "serengeti" Serengeti system
 ! [PLATFORM=sparc64] MACHINE (choice)
 
@@ -81,8 +85,4 @@
 ! [PLATFORM=sparc64&MACHINE=generic] PROCESSOR (choice)
 
-% CPU type
-@ "us3"
-! [PLATFORM=sparc64&MACHINE=serengeti] PROCESSOR (choice)
-
 % RAM disk format
 @ "tmpfs" TMPFS image
@@ -122,4 +122,8 @@
 
 % Kernel architecture
+@ "mips64"
+! [PLATFORM=mips64] KARCH (choice)
+
+% Kernel architecture
 @ "ppc32"
 ! [PLATFORM=ppc32] KARCH (choice)
@@ -165,4 +169,8 @@
 
 % User space architecture
+@ "mips64"
+! [PLATFORM=mips64] UARCH (choice)
+
+% User space architecture
 @ "ppc32"
 ! [PLATFORM=ppc32] UARCH (choice)
@@ -206,4 +214,8 @@
 @ "mips32"
 ! [PLATFORM=mips32] BARCH (choice)
+
+% Boot architecture
+@ "mips64"
+! [PLATFORM=mips64] BARCH (choice)
 
 % Boot architecture
@@ -229,4 +241,8 @@
 @ "ecoff"
 ! [PLATFORM=mips32&(MACHINE=bgxemul|MACHINE=lgxemul)] IMAGE (choice)
+
+% Image format
+@ "binary"
+! [PLATFORM=mips64] IMAGE (choice)
 
 
@@ -256,5 +272,5 @@
 @ "gcc_cross" GNU C Compiler (cross-compiler)
 @ "gcc_native" GNU C Compiler (native)
-! [PLATFORM=arm32|PLATFORM=mips32|PLATFORM=ppc32] COMPILER (choice)
+! [PLATFORM=arm32|PLATFORM=mips32|PLATFORM=mips64|PLATFORM=ppc32] COMPILER (choice)
 
 % Compiler
@@ -292,14 +308,14 @@
 
 % Page hash table support
-! [PLATFORM=ia64|PLATFORM=sparc64] CONFIG_PAGE_HT (y)
+! [PLATFORM=ia64|PLATFORM=mips64|PLATFORM=sparc64] CONFIG_PAGE_HT (y)
 
 % Software integer division support
-! [PLATFORM=abs32le|PLATFORM=ia32|PLATFORM=arm32|PLATFORM=ia64|PLATFORM=mips32|PLATFORM=ppc32] CONFIG_SOFTINT (y)
+! [PLATFORM=abs32le|PLATFORM=ia32|PLATFORM=arm32|PLATFORM=ia64|PLATFORM=mips32|PLATFORM=mips64|PLATFORM=ppc32] CONFIG_SOFTINT (y)
 
 % ASID support
-! [PLATFORM=ia64|PLATFORM=mips32|PLATFORM=ppc32|PLATFORM=sparc64] CONFIG_ASID (y)
+! [PLATFORM=ia64|PLATFORM=mips32|PLATFORM=mips64|PLATFORM=ppc32|PLATFORM=sparc64] CONFIG_ASID (y)
 
 % ASID FIFO support
-! [PLATFORM=ia64|PLATFORM=mips32|PLATFORM=ppc32|PLATFORM=sparc64] CONFIG_ASID_FIFO (y)
+! [PLATFORM=ia64|PLATFORM=mips32|PLATFORM=mips64|PLATFORM=ppc32|PLATFORM=sparc64] CONFIG_ASID_FIFO (y)
 
 % OpenFirmware tree support
@@ -322,5 +338,5 @@
 
 % Support for SMP
-! [(PLATFORM=ia32&PROCESSOR!=athlon_xp)|PLATFORM=amd64|PLATFORM=sparc64|PLATFORM=ia64|(PLATFORM=mips32&MACHINE=msim)|PLATFORM=abs32le] CONFIG_SMP (y/n)
+! [(PLATFORM=ia32&PROCESSOR!=athlon_xp)|PLATFORM=amd64|PLATFORM=sparc64|PLATFORM=ia64|(PLATFORM=mips32&MACHINE=msim)|(PLATFORM=mips64&MACHINE=msim)|PLATFORM=abs32le] CONFIG_SMP (y/n)
 
 % Debug build
@@ -379,5 +395,5 @@
 @ "generic" Keyboard or serial line
 @ "none" No input device
-! [PLATFORM=ia32|(PLATFORM=arm32&MACHINE=testarm)|PLATFORM=amd64|PLATFORM=mips32|PLATFORM=ppc32|PLATFORM=sparc64] CONFIG_HID_IN (choice)
+! [PLATFORM=ia32|(PLATFORM=arm32&MACHINE=testarm)|PLATFORM=amd64|PLATFORM=mips32|PLATFORM=mips64|PLATFORM=ppc32|PLATFORM=sparc64] CONFIG_HID_IN (choice)
 
 % Input device class
@@ -395,5 +411,5 @@
 @ "generic" Monitor or serial line
 @ "none" No output device
-! [PLATFORM=ia32|PLATFORM=amd64|PLATFORM=sparc64|PLATFORM=ppc32|(PLATFORM=ia64&MACHINE=i460GX)|(PLATFORM=mips32&MACHINE=msim)] CONFIG_HID_OUT (choice)
+! [PLATFORM=ia32|PLATFORM=amd64|PLATFORM=sparc64|PLATFORM=ppc32|(PLATFORM=ia64&MACHINE=i460GX)|(PLATFORM=mips32&MACHINE=msim)|(PLATFORM=mips64&MACHINE=msim)] CONFIG_HID_OUT (choice)
 
 % Output device class
@@ -421,8 +437,8 @@
 
 % Support for msim/GXemul keyboard
-! [CONFIG_HID_IN=generic&PLATFORM=mips32] CONFIG_MIPS_KBD (y/n)
+! [CONFIG_HID_IN=generic&(PLATFORM=mips32|PLATFORM=mips64)] CONFIG_MIPS_KBD (y/n)
 
 % Support for msim/GXemul printer
-! [(CONFIG_HID_OUT=generic|CONFIG_HID_OUT=serial)&PLATFORM=mips32] CONFIG_MIPS_PRN (y/n)
+! [(CONFIG_HID_OUT=generic|CONFIG_HID_OUT=serial)&(PLATFORM=mips32|PLATFORM=mips64)] CONFIG_MIPS_PRN (y/n)
 
 % Support for GXemul keyboard
@@ -447,13 +463,4 @@
 ! [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)
-
-% Support for Serengeti console
-! [CONFIG_HID_OUT=generic&PLATFORM=sparc64&MACHINE=serengeti] CONFIG_SGCN_PRN (y/n)
-
-% Support for Serengeti keyboard
-! [CONFIG_HID_IN=generic&PLATFORM=sparc64&MACHINE=serengeti] CONFIG_SGCN_KBD (y/n)
-
 % Support for i8042 controller
 ! [CONFIG_PC_KBD=y] CONFIG_I8042 (y)
@@ -463,5 +470,5 @@
 
 % Sun keyboard support
-! [(CONFIG_HID_IN=generic|CONFIG_HID_IN=keyboard)&PLATFORM=sparc64&MACHINE=generic&(CONFIG_NS16550=y|CONFIG_Z8530=y)] CONFIG_SUN_KBD (y)
+! [(CONFIG_HID_IN=generic|CONFIG_HID_IN=keyboard)&PLATFORM=sparc64&MACHINE=generic&CONFIG_NS16550=y] CONFIG_SUN_KBD (y)
 
 % Macintosh ADB keyboard support
@@ -475,5 +482,5 @@
 
 % Serial line input module
-! [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)
+! [CONFIG_DSRLNIN=y|(PLATFORM=arm32&MACHINE=gta02)|(PLATFORM=ia64&MACHINE=i460GX&CONFIG_NS16550=y)|(PLATFORM=ia64&MACHINE=ski)|(PLATFORM=sparc64&PROCESSOR=sun4v)] CONFIG_SRLN (y)
 
 % EGA support
@@ -522,7 +529,4 @@
 ! [PLATFORM=sparc64&CONFIG_SMP=y] CONFIG_AP (y/n)
 
-% Preserve A.OUT header in isofs.b
-! [PLATFORM=sparc64&MACHINE=generic] CONFIG_AOUT_ISOFS_B (y)
-
 % Dynamic linking support
 ! [PLATFORM=ia32] CONFIG_RTLD (n/y)
Index: boot/Makefile
===================================================================
--- boot/Makefile	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ boot/Makefile	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -76,5 +76,5 @@
 		cp "$(USPACE_PATH)/$(DRVS_PATH)/$$file_dir/$$file_name/$$file_name.dev" "$(DIST_PATH)/$(DRVS_PATH)/$$file_name/" ; \
 	done
-	
+
 clean: clean_dist
 	$(MAKE) -f $(BUILD) clean PRECHECK=$(PRECHECK)
Index: boot/Makefile.silo
===================================================================
--- boot/Makefile.silo	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ boot/Makefile.silo	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -31,9 +31,5 @@
 include Makefile.common
 
-ifeq ($(CONFIG_AOUT_ISOFS_B),y)
-	SILO_PACKAGE = a.out
-else
-	SILO_PACKAGE = raw
-endif
+SILO_PACKAGE = a.out
 
 ISOFS_B = silo/$(SILO_PACKAGE)/isofs.b
Index: boot/Makefile.uboot
===================================================================
--- boot/Makefile.uboot	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ boot/Makefile.uboot	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -31,6 +31,6 @@
 include Makefile.common
 
-IMAGE_NAME=HelenOS-$(RELEASE)
-BIN_OUTPUT=image.bin
+IMAGE_NAME = HelenOS-$(RELEASE)
+BIN_OUTPUT = image.bin
 
 all: $(POST_OUTPUT)
@@ -40,6 +40,5 @@
 
 $(POST_OUTPUT): $(BIN_OUTPUT)
-	$(MKUIMAGE) -name "$(IMAGE_NAME)" -laddr 0x30008000 -saddr 0x30008000 \
-    $< $@
+	$(MKUIMAGE) -name "$(IMAGE_NAME)" -laddr 0x30008000 -saddr 0x30008000 $< $@
 
 clean:
Index: boot/arch/ia64/include/types.h
===================================================================
--- boot/arch/ia64/include/types.h	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ boot/arch/ia64/include/types.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -30,7 +30,9 @@
 #define BOOT_ia64_TYPES_H_
 
+#include <arch/common.h>
+
 #define TASKMAP_MAX_RECORDS		32
 #define BOOTINFO_TASK_NAME_BUFLEN	32
-#define MEMMAP_ITEMS			128	
+#define MEMMAP_ITEMS			128
 
 typedef uint64_t size_t;
@@ -53,10 +55,10 @@
 	unsigned long base;
 	unsigned long size;
-} efi_memmap_item_t;
+} memmap_item_t;
 
 typedef struct {
 	binit_t taskmap;
 
-	efi_memmap_item_t memmap[MEMMAP_ITEMS];
+	memmap_item_t memmap[MEMMAP_ITEMS];
 	unsigned int memmap_items;
 
@@ -65,6 +67,14 @@
 	unsigned long freq_scale;
 	unsigned int wakeup_intno;
-	int hello_configured;
 } bootinfo_t;
 
+/** This is a minimal ELILO-compatible boot parameter structure. */
+typedef struct {
+	uint64_t cmd_line;
+	uint64_t efi_system_table;
+	uint64_t efi_memmap;
+	uint64_t efi_memmap_sz;
+	uint64_t efi_memdesc_sz;
+} boot_param_t;
+
 #endif
Index: boot/arch/ia64/src/boot.S
===================================================================
--- boot/arch/ia64/src/boot.S	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ boot/arch/ia64/src/boot.S	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -37,4 +37,11 @@
 
 	#
+	# Save the boot parameter structure address passed from the
+	# ELILO-compatible EFI loader.
+	#
+	movl r8 = bootpar ;;
+	st8 [r8] = r28
+
+	#
 	# Initialize the register stack to some sane value.
 	#
@@ -62,4 +69,8 @@
 .bss
 
+.global bootpar
+bootpar:
+	.quad 0
+
 .align STACK_SIZE
 initial_stack:
Index: boot/arch/ia64/src/main.c
===================================================================
--- boot/arch/ia64/src/main.c	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ boot/arch/ia64/src/main.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -30,7 +30,9 @@
 
 #include <arch/main.h>
+#include <arch/types.h>
 #include <arch/arch.h>
 #include <arch/asm.h>
 #include <arch/_components.h>
+#include <genarch/efi.h>
 #include <halt.h>
 #include <printf.h>
@@ -51,9 +53,80 @@
 #define DEFAULT_SYS_FREQ		100000000ULL		/* 100MHz */
 
-#define EFI_MEMMAP_FREE_MEM		0
-#define EFI_MEMMAP_IO			1
-#define EFI_MEMMAP_IO_PORTS		2
+#define MEMMAP_FREE_MEM		0
+#define MEMMAP_IO		1
+#define MEMMAP_IO_PORTS		2
+
+extern boot_param_t *bootpar;
 
 static bootinfo_t bootinfo;
+
+static void read_efi_memmap(void)
+{
+	memmap_item_t *memmap = bootinfo.memmap;
+	size_t items = 0;
+	
+	if (!bootpar) {
+		/* Fake-up a memory map for simulators. */
+		memmap[items].base = DEFAULT_MEMORY_BASE;
+		memmap[items].size = DEFAULT_MEMORY_SIZE;
+		memmap[items].type = MEMMAP_FREE_MEM;
+		items++;
+
+		memmap[items].base = DEFAULT_LEGACY_IO_BASE;
+		memmap[items].size = DEFAULT_LEGACY_IO_SIZE;
+		memmap[items].type = MEMMAP_IO_PORTS;
+		items++;		 
+	} else {
+		char *cur, *mm_base = (char *) bootpar->efi_memmap;
+		size_t mm_size = bootpar->efi_memmap_sz;
+		size_t md_size = bootpar->efi_memdesc_sz;
+		
+		/*
+		 * Walk the EFI memory map using the V1 memory descriptor
+		 * format. The actual memory descriptor can use newer format,
+		 * but it must always be backwards compatible with the V1
+		 * format.
+		 */
+		for (cur = mm_base;
+		    (cur < mm_base + (mm_size - md_size)) &&
+		    (items < MEMMAP_ITEMS);
+		    cur += md_size) {
+			efi_v1_memdesc_t *md = (efi_v1_memdesc_t *) cur;
+
+			switch ((efi_memory_type_t) md->type) {
+			case EFI_CONVENTIONAL_MEMORY:
+				memmap[items].type = MEMMAP_FREE_MEM;
+				break;
+			case EFI_MEMORY_MAPPED_IO:
+				memmap[items].type = MEMMAP_IO;
+				break;
+			case EFI_MEMORY_MAPPED_IO_PORT_SPACE:
+				memmap[items].type = MEMMAP_IO_PORTS;
+				break;
+			default:
+				continue;
+			}
+			
+			memmap[items].base = md->phys_start;
+			memmap[items].size = md->pages * EFI_PAGE_SIZE;
+			items++;
+		}
+	}
+	
+	bootinfo.memmap_items = items;
+}
+
+static void read_sal_configuration(void)
+{
+	if (!bootpar) {
+		/* Configure default values for simulators. */
+		bootinfo.freq_scale = DEFAULT_FREQ_SCALE;
+		bootinfo.sys_freq = DEFAULT_SYS_FREQ;
+	} else {
+		/* TODO: read the real values from SAL */
+		bootinfo.freq_scale = DEFAULT_FREQ_SCALE;
+		bootinfo.sys_freq = DEFAULT_SYS_FREQ;
+	}
+}
 
 void bootstrap(void)
@@ -113,31 +186,7 @@
 	
 	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;
-	}
-	
+	read_efi_memmap();
+	read_sal_configuration();
 	
 	printf("Booting the kernel ...\n");
Index: boot/arch/mips32/Makefile.inc
===================================================================
--- boot/arch/mips32/Makefile.inc	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ boot/arch/mips32/Makefile.inc	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -30,7 +30,5 @@
 BITS = 32
 PAGE_SIZE = 16384
-EXTRA_CFLAGS = -mno-abicalls -G 0 -fno-zero-initialized-in-bss -mips3
-
-RD_SRVS_ESSENTIAL +=
+EXTRA_CFLAGS = -mno-abicalls -G 0 -fno-zero-initialized-in-bss -mips3 -mabi=32
 
 RD_SRVS_NON_ESSENTIAL += \
Index: boot/arch/mips64/Makefile.inc
===================================================================
--- boot/arch/mips64/Makefile.inc	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
+++ boot/arch/mips64/Makefile.inc	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -0,0 +1,54 @@
+#
+# 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_ARCH = mips:4000
+BITS = 64
+PAGE_SIZE = 16384
+EXTRA_CFLAGS = -mno-abicalls -G 0 -fno-zero-initialized-in-bss -mips3 -mabi=64
+
+ifeq ($(MACHINE),msim)
+	BFD_NAME = elf64-tradlittlemips
+	BFD_OUTPUT = binary
+	ENDIANESS = LE
+	EXTRA_GCC_CFLAGS = -mhard-float
+endif
+
+SOURCES = \
+	arch/$(BARCH)/src/asm.S \
+	arch/$(BARCH)/src/main.c \
+	arch/$(BARCH)/src/putchar.c \
+	$(COMPS_C) \
+	genarch/src/division.c \
+	genarch/src/multiplication.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
Index: boot/arch/mips64/_link.ld.in
===================================================================
--- boot/arch/mips64/_link.ld.in	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
+++ boot/arch/mips64/_link.ld.in	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -0,0 +1,30 @@
+OUTPUT_FORMAT(elf64-tradlittlemips)
+ENTRY(start)
+
+SECTIONS {
+	. = 0xffffffffbfc00000;
+	.text : {
+		*(BOOTSTRAP);
+		*(.text);
+	}
+	.data : {
+		*(.data);       /* initialized data */
+		*(.rodata);
+		*(.rodata.*);
+		*(.sdata);
+		*(.reginfo);
+		*(.sbss);
+		*(.scommon);
+		*(.bss);        /* uninitialized static variables */
+		*(COMMON);      /* global variables */
+[[COMPONENTS]]
+	}
+	
+	/DISCARD/ : {
+		*(.gnu.*);
+		*(.mdebug*);
+		*(.pdr);
+		*(.comment);
+		*(.note);
+	}
+}
Index: boot/arch/mips64/include/arch.h
===================================================================
--- boot/arch/mips64/include/arch.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
+++ boot/arch/mips64/include/arch.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -0,0 +1,52 @@
+/*
+ * 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.
+ */
+
+#ifndef BOOT_mips64_ARCH_H_
+#define BOOT_mips64_ARCH_H_
+
+#define PAGE_WIDTH  14
+#define PAGE_SIZE   (1 << PAGE_WIDTH)
+
+#define CPUMAP_OFFSET    0x00001000
+#define STACK_OFFSET     0x00002000
+#define BOOTINFO_OFFSET  0x00003000
+#define BOOT_OFFSET      0x00100000
+#define LOADER_OFFSET    0x1fc00000
+
+#define MSIM_VIDEORAM_ADDRESS  0xffffffffb0000000
+#define MSIM_DORDER_ADDRESS    0xffffffffb0000100
+
+#ifndef __ASM__
+	#define PA2KA(addr)    (((uintptr_t) (addr)) + 0xffffffff80000000)
+	#define KSEG2PA(addr)  (((uintptr_t) (addr)) - 0xffffffffa0000000)
+#else
+	#define PA2KA(addr)    ((addr) + 0xffffffff80000000)
+	#define KSEG2PA(addr)  ((addr) - 0xffffffffa0000000)
+#endif
+
+#endif
Index: boot/arch/mips64/include/asm.h
===================================================================
--- boot/arch/mips64/include/asm.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
+++ boot/arch/mips64/include/asm.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -0,0 +1,1 @@
+../../mips32/include/asm.h
Index: boot/arch/mips64/include/main.h
===================================================================
--- boot/arch/mips64/include/main.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
+++ boot/arch/mips64/include/main.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -0,0 +1,1 @@
+../../mips32/include/main.h
Index: boot/arch/mips64/include/regname.h
===================================================================
--- boot/arch/mips64/include/regname.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
+++ boot/arch/mips64/include/regname.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -0,0 +1,1 @@
+../../mips32/include/regname.h
Index: boot/arch/mips64/include/types.h
===================================================================
--- boot/arch/mips64/include/types.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
+++ boot/arch/mips64/include/types.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -0,0 +1,54 @@
+/*
+ * 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.
+ */
+
+#ifndef BOOT_mips64_TYPES_H_
+#define BOOT_mips64_TYPES_H_
+
+#define TASKMAP_MAX_RECORDS        32
+#define CPUMAP_MAX_RECORDS         32
+#define BOOTINFO_TASK_NAME_BUFLEN  32
+
+typedef uint64_t size_t;
+typedef uint64_t uintptr_t;
+
+typedef struct {
+	/** Address where the task was placed. */
+	void *addr;
+	/** Size of the task's binary. */
+	size_t size;
+	/** Task name. */
+	char name[BOOTINFO_TASK_NAME_BUFLEN];
+} task_t;
+
+typedef struct {
+	uint32_t cpumap;
+	size_t cnt;
+	task_t tasks[TASKMAP_MAX_RECORDS];
+} bootinfo_t;
+
+#endif
Index: boot/arch/mips64/src/asm.S
===================================================================
--- boot/arch/mips64/src/asm.S	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
+++ boot/arch/mips64/src/asm.S	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -0,0 +1,150 @@
+#
+# 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 <arch/arch.h>
+#include <arch/regname.h>
+
+.set noat
+.set noreorder
+.set nomacro
+
+.global start
+.global halt
+.global jump_to_kernel
+
+.section BOOTSTRAP
+
+start:
+	/*
+	 * Setup the CP0 configuration
+	 *  - Enable 64-bit kernel addressing mode
+	 *  - Enable 64-bit supervisor adressing mode
+	 *  - Enable 64-bit user addressing mode
+	 */
+	dmfc0 $a0, $status
+	ori $a0, 0x00e0
+	dmtc0 $a0, $status
+	
+	/*
+	 * Setup CPU map (on msim this code
+	 * is executed in parallel on all CPUs,
+	 * but it not an issue).
+	 */
+	dla $a0, PA2KA(CPUMAP_OFFSET)
+	
+	sw $zero, 0($a0)
+	sw $zero, 4($a0)
+	sw $zero, 8($a0)
+	sw $zero, 12($a0)
+	
+	sw $zero, 16($a0)
+	sw $zero, 20($a0)
+	sw $zero, 24($a0)
+	sw $zero, 28($a0)
+	
+	sw $zero, 32($a0)
+	sw $zero, 36($a0)
+	sw $zero, 40($a0)
+	sw $zero, 44($a0)
+	
+	sw $zero, 48($a0)
+	sw $zero, 52($a0)
+	sw $zero, 56($a0)
+	sw $zero, 60($a0)
+	
+	sw $zero, 64($a0)
+	sw $zero, 68($a0)
+	sw $zero, 72($a0)
+	sw $zero, 76($a0)
+	
+	sw $zero, 80($a0)
+	sw $zero, 84($a0)
+	sw $zero, 88($a0)
+	sw $zero, 92($a0)
+	
+	sw $zero, 96($a0)
+	sw $zero, 100($a0)
+	sw $zero, 104($a0)
+	sw $zero, 108($a0)
+	
+	sw $zero, 112($a0)
+	sw $zero, 116($a0)
+	sw $zero, 120($a0)
+	sw $zero, 124($a0)
+	
+	lui $a1, 1
+	
+#ifdef MACHINE_msim
+	
+	/* Read dorder value */
+	dla $k0, MSIM_DORDER_ADDRESS
+	lw $k1, ($k0)
+	
+	/*
+	 * If we are not running on BSP
+	 * then end in an infinite loop.
+	 */
+	beq $k1, $zero, bsp
+	nop
+	
+	/* Record CPU presence */
+	sll $a2, $k1, 2
+	addu $a2, $a2, $a0
+	sw $a1, ($a2)
+	
+	loop:
+		j loop
+		nop
+	
+#endif
+	
+	bsp:
+		/* Record CPU presence */
+		sw $a1, ($a0)
+		
+		/* Setup initial stack */
+		dla $sp, PA2KA(STACK_OFFSET)
+		
+		j bootstrap
+		nop
+
+.text
+
+halt:
+	j halt
+	nop
+
+jump_to_kernel:
+	/*
+	 * TODO:
+	 *
+	 * Make sure that the I-cache, D-cache and memory are mutually
+	 * coherent before passing control to the copied code.
+	 */
+	j $a0
+	nop
Index: boot/arch/mips64/src/main.c
===================================================================
--- boot/arch/mips64/src/main.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
+++ boot/arch/mips64/src/main.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -0,0 +1,126 @@
+/*
+ * 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/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 TOP2ADDR(top)  (((void *) PA2KA(BOOT_OFFSET)) + (top))
+
+static bootinfo_t *bootinfo = (bootinfo_t *) PA2KA(BOOTINFO_OFFSET);
+static uint32_t *cpumap = (uint32_t *) PA2KA(CPUMAP_OFFSET);
+
+void bootstrap(void)
+{
+	version_print();
+	
+	printf("\nMemory statistics\n");
+	printf(" %p|%p: CPU map\n", (void *) PA2KA(CPUMAP_OFFSET),
+	    (void *) CPUMAP_OFFSET);
+	printf(" %p|%p: bootstrap stack\n", (void *) PA2KA(STACK_OFFSET),
+	    (void *) STACK_OFFSET);
+	printf(" %p|%p: boot info structure\n",
+	    (void *) PA2KA(BOOTINFO_OFFSET), (void *) BOOTINFO_OFFSET);
+	printf(" %p|%p: kernel entry point\n", (void *) PA2KA(BOOT_OFFSET),
+	    (void *) BOOT_OFFSET);
+	printf(" %p|%p: bootloader entry point\n",
+	    (void *) PA2KA(LOADER_OFFSET), (void *) LOADER_OFFSET);
+	
+	size_t i;
+	for (i = 0; i < COMPONENTS; i++)
+		printf(" %p|%p: %s image (%zu/%zu bytes)\n", components[i].start,
+		    (void *) KSEG2PA(components[i].start), components[i].name,
+		    components[i].inflated, components[i].size);
+	
+	void *dest[COMPONENTS];
+	size_t top = 0;
+	size_t cnt = 0;
+	bootinfo->cnt = 0;
+	for (i = 0; i < min(COMPONENTS, TASKMAP_MAX_RECORDS); i++) {
+		top = ALIGN_UP(top, PAGE_SIZE);
+		
+		if (i > 0) {
+			bootinfo->tasks[bootinfo->cnt].addr = TOP2ADDR(top);
+			bootinfo->tasks[bootinfo->cnt].size = components[i].inflated;
+			
+			str_cpy(bootinfo->tasks[bootinfo->cnt].name,
+			    BOOTINFO_TASK_NAME_BUFLEN, components[i].name);
+			
+			bootinfo->cnt++;
+		}
+		
+		dest[i] = TOP2ADDR(top);
+		top += components[i].inflated;
+		cnt++;
+	}
+	
+	printf("\nInflating components ... ");
+	
+	for (i = cnt; i > 0; i--) {
+		void *tail = dest[i - 1] + components[i].inflated;
+		if (tail >= ((void *) PA2KA(LOADER_OFFSET))) {
+			printf("\n%s: Image too large to fit (%p >= %p), halting.\n",
+			    components[i].name, tail, (void *) PA2KA(LOADER_OFFSET));
+			halt();
+		}
+		
+		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");
+	
+	printf("Copying CPU map ... \n");
+	
+	bootinfo->cpumap = 0;
+	for (i = 0; i < CPUMAP_MAX_RECORDS; i++) {
+		if (cpumap[i] != 0)
+			bootinfo->cpumap |= (1 << i);
+	}
+	
+	printf("Booting the kernel ... \n");
+	jump_to_kernel((void *) PA2KA(BOOT_OFFSET), bootinfo);
+}
Index: boot/arch/mips64/src/putchar.c
===================================================================
--- boot/arch/mips64/src/putchar.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
+++ boot/arch/mips64/src/putchar.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -0,0 +1,40 @@
+/*
+ * 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>
+
+void putchar(const wchar_t ch)
+{
+	if (ascii_check(ch))
+		*((char *) MSIM_VIDEORAM_ADDRESS) = ch;
+	else
+		*((char *) MSIM_VIDEORAM_ADDRESS) = U_SPECIAL;
+}
Index: boot/arch/sparc64/Makefile.inc
===================================================================
--- boot/arch/sparc64/Makefile.inc	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ boot/arch/sparc64/Makefile.inc	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -43,5 +43,4 @@
 
 RD_SRVS_ESSENTIAL += \
-	$(USPACE_PATH)/srv/hw/irc/fhc/fhc \
 	$(USPACE_PATH)/srv/hw/irc/obio/obio
 
Index: boot/arch/sparc64/src/main.c
===================================================================
--- boot/arch/sparc64/src/main.c	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ boot/arch/sparc64/src/main.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -182,8 +182,5 @@
 	 * of the "/memory" node to find out which parts of memory
 	 * are used by OBP and redesign the algorithm of copying
-	 * kernel/init tasks/ramdisk from the bootable image to memory
-	 * (which we must do anyway because of issues with claiming the memory
-	 * on Serengeti).
-	 *
+	 * kernel/init tasks/ramdisk from the bootable image to memory.
 	 */
 	bootinfo.physmem_start += OBP_BIAS;
Index: boot/genarch/include/efi.h
===================================================================
--- boot/genarch/include/efi.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
+++ boot/genarch/include/efi.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2011 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_EFI_H_
+#define BOOT_EFI_H_
+
+typedef enum {
+	EFI_RESERVED,
+	EFI_LOADER_CODE,
+	EFI_LOADER_DATA,
+	EFI_BOOT_SERVICES_CODE,
+	EFI_BOOT_SERVICES_DATA,
+	EFI_RUNTIME_SERVICES_CODE,
+	EFI_RUNTIME_SERVICES_DATA,
+	EFI_CONVENTIONAL_MEMORY,
+	EFI_UNUSABLE_MEMORY,
+	EFI_ACPI_RECLAIM_MEMORY,
+	EFI_ACPI_MEMORY_NVS,
+	EFI_MEMORY_MAPPED_IO,
+	EFI_MEMORY_MAPPED_IO_PORT_SPACE,
+	EFI_PAL_CODE
+} efi_memory_type_t;
+
+typedef struct {
+	uint32_t type;
+	uint64_t phys_start;
+	uint64_t virt_start;
+	uint64_t pages;
+	uint64_t attribute;
+} efi_v1_memdesc_t;
+
+#define EFI_PAGE_SIZE	4096
+
+#endif
Index: ntrib/tools/serengeti_silo.sh
===================================================================
--- contrib/tools/serengeti_silo.sh	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ 	(revision )
@@ -1,74 +1,0 @@
-#!/bin/bash
-
-# Download SILO and patch it so that it can be used to create a bootable CD
-# for the Serengeti machine
-#  by Pavel Rimsky <rimskyp@seznam.cz>
-#  portions by Martin Decky <martin@decky.cz>
-#
-#  GPL'ed, copyleft
-#
-
-# stuff to be downloaded
-SILO_DOWNLOAD_FILE='silo-loaders-1.4.11.tar.gz'
-SILO_DOWNLOAD_URL='http://silo.auxio.org/pub/silo/old/'$SILO_DOWNLOAD_FILE
-
-# check whether the last command failed, if so, write an error message and exit
-check_error() {
-    if [ "$1" -ne "0" ]; then
-        echo
-        echo "Script failed: $2"
-        exit
-    fi
-}
-
-# temporary files are to be stored in /tmp
-# the resulting file in the current directory
-WD=`pwd`
-cd /tmp
-
-# download SILO from its official website
-echo ">>> Downloading SILO"
-wget $SILO_DOWNLOAD_URL
-check_error $? "Error downloading SILO."
-
-# unpack the downloaded file
-echo ">>> Unpacking tarball"
-tar xvzf $SILO_DOWNLOAD_FILE
-check_error $? "Error unpacking tarball."
-
-# CD to the unpacked directory
-echo ">>> Changing to the unpacked SILO directory"
-cd boot
-check_error $? "Changing directory failed."
-
-# patch it - remove bytes 512 to 512 + 32 (counted from 0), which belong to
-# the ELF header which is not recognized by the Serengeti firmware
-echo ">>> Patching SILO"
-(((xxd -p -l 512 isofs.b) && (xxd -p -s 544 isofs.b)) | xxd -r -p) \
-	 > isofs.b.patched
-check_error $? "Patching SILO failed"
-mv isofs.b.patched isofs.b
-
-# get rid of files which are not needed for creating the bootable CD
-echo ">>> Purging SILO directory"
-for file in `ls`; do
-	if [ \( -f $file \) -a \( $file != "isofs.b" \) -a \( $file != "second.b" \) ];
-		then
-		rm -fr $file;
-	fi
-done
-check_error $? "Purging SILO directory failed"
-
-# create the gzipped tarball with patched SILO
-echo ">>> Creating tarball with patched SILO"
-tar cvzf silo.patched.tar.gz *.b
-check_error $? "Creating tarball with patched SILO failed"
-
-# and move it to the directory where the user expects it to be
-echo ">>> Moving the tarball with patched SILO to the current directory"
-mv silo.patched.tar.gz $WD
-check_error $? "Moving the tarball with patched SILO failed"
-
-# move back to the working directory from /tmp
-cd $WD
-
Index: defaults/mips64/Makefile.config
===================================================================
--- defaults/mips64/Makefile.config	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
+++ defaults/mips64/Makefile.config	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -0,0 +1,48 @@
+# Platform
+PLATFORM = mips64
+
+# Ramdisk format
+RDFMT = fat
+
+# Compiler
+COMPILER = gcc_cross
+
+# Debug build
+CONFIG_DEBUG = y
+
+# Deadlock detection support for spinlocks
+CONFIG_DEBUG_SPINLOCK = y
+
+# Support for SMP
+CONFIG_SMP = y
+
+# Support for userspace debuggers
+CONFIG_UDEBUG = y
+
+# Kernel console support
+CONFIG_KCONSOLE = y
+
+# Kernel symbol information
+CONFIG_SYMTAB = y
+
+# Detailed kernel logging
+CONFIG_LOG = n
+
+# Kernel function tracing
+CONFIG_TRACE = n
+
+# Compile kernel tests
+CONFIG_TEST = y
+
+# Input device class
+CONFIG_HID_IN = generic
+
+# Output device class
+CONFIG_HID_OUT = generic
+
+# Load disk drivers on startup
+CONFIG_START_BD = n
+
+# Mount /data on startup
+CONFIG_MOUNT_DATA = n
+
Index: defaults/mips64/msim/Makefile.config
===================================================================
--- defaults/mips64/msim/Makefile.config	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
+++ defaults/mips64/msim/Makefile.config	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -0,0 +1,2 @@
+# Machine type
+MACHINE = msim
Index: defaults/mips64/output
===================================================================
--- defaults/mips64/output	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
+++ defaults/mips64/output	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -0,0 +1,1 @@
+image.boot
Index: defaults/sparc64/Makefile.config
===================================================================
--- defaults/sparc64/Makefile.config	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ defaults/sparc64/Makefile.config	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -53,7 +53,4 @@
 CONFIG_AP = y
 
-# Preserve A.OUT header in isofs.b
-CONFIG_AOUT_ISOFS_B = y
-
 # Load disk drivers on startup
 CONFIG_START_BD = n
Index: faults/sparc64/serengeti/Makefile.config
===================================================================
--- defaults/sparc64/serengeti/Makefile.config	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ 	(revision )
@@ -1,11 +1,0 @@
-# Machine type
-MACHINE = serengeti
-RDFMT = tmpfs
-CONFIG_SMP = n
-CONFIG_DEBUG = n
-CONFIG_UDEBUG = n
-CONFIG_SYMTAB = n
-CONFIG_TEST = n
-CONFIG_STRIP_BINARIES = y
-CONFIG_OPTIMIZE_FOR_SIZE = y
-CONFIG_BAREBONE = y
Index: kernel/arch/amd64/Makefile.inc
===================================================================
--- kernel/arch/amd64/Makefile.inc	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ kernel/arch/amd64/Makefile.inc	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -41,5 +41,5 @@
 # is fixed.
 #
-# If GCC generates a code for tail call, instead of generating ..
+# When GCC generates a code for tail call, instead of generating ..
 #
 #   jmp *fnc
@@ -48,4 +48,6 @@
 #
 #   jmp *$fnc
+#
+# See http://gcc.gnu.org/bugzilla/show_bug.cgi?id=48385 for reference.
 #
 
Index: kernel/arch/arm32/src/mach/gta02/gta02.c
===================================================================
--- kernel/arch/arm32/src/mach/gta02/gta02.c	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ kernel/arch/arm32/src/mach/gta02/gta02.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -158,6 +158,4 @@
 {
 #ifdef CONFIG_FB
-	parea_t fb_parea;
-
 	fb_properties_t prop = {
 		.addr = GTA02_FB_BASE,
@@ -170,18 +168,11 @@
 
 	outdev_t *fb_dev = fb_init(&prop);
-	if (fb_dev) {
+	if (fb_dev)
 		stdout_wire(fb_dev);
-		fb_parea.pbase = GTA02_FB_BASE;
-		fb_parea.frames = 150;
-		fb_parea.unpriv = false;
-		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);
+	gta02_scons_dev =
+	    s3c24xx_uart_init(GTA02_SCONS_BASE, S3C24XX_INT_UART2);
 
 	if (gta02_scons_dev) {
Index: kernel/arch/arm32/src/mach/integratorcp/integratorcp.c
===================================================================
--- kernel/arch/arm32/src/mach/integratorcp/integratorcp.c	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ kernel/arch/arm32/src/mach/integratorcp/integratorcp.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -53,5 +53,4 @@
 
 #define SDRAM_SIZE	(sdram[((*(uint32_t *)(ICP_CMCR+ICP_SDRAMCR_OFFSET) & ICP_SDRAM_MASK) >> 2)])
-static parea_t fb_parea;
 static icp_hw_map_t icp_hw_map;
 static irq_t icp_timer_irq;
@@ -296,11 +295,6 @@
 	
 	outdev_t *fbdev = fb_init(&prop);
-	if (fbdev) {
+	if (fbdev)
 		stdout_wire(fbdev);
-		fb_parea.pbase = ICP_FB;
-		fb_parea.frames = 300;
-		fb_parea.unpriv = false;
-		ddi_parea_register(&fb_parea);
-	}
 #endif
 }
Index: kernel/arch/ia32/src/boot/vesa_real.inc
===================================================================
--- kernel/arch/ia32/src/boot/vesa_real.inc	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ kernel/arch/ia32/src/boot/vesa_real.inc	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -154,4 +154,14 @@
 	mov $e_vesa_init - vesa_init, %di
 	push %di
+	/* Write the "VBE2" signature into the info structure in order
+	 * to get proper mode information. The presence of "VBE2"
+	 * indicates two things:
+	 *
+	 *  - VBE controller information structure is expected to be
+	 *    512 bytes long instead of 256 bytes.
+	 *  - The BIOS should report VBE 3.0 information (potentially
+	 *    including non-standard modes in the mode list).
+	 */
+	movl $0x32454256, (%di)
 	int $0x10
 	
Index: kernel/arch/ia64/include/bootinfo.h
===================================================================
--- kernel/arch/ia64/include/bootinfo.h	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ kernel/arch/ia64/include/bootinfo.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -34,5 +34,5 @@
 #define MEMMAP_ITEMS 128
 
-#define EFI_MEMMAP_FREE_MEM 0
+#define MEMMAP_FREE_MEM 0
 
 /** Size of buffer for storing task name in binit_task_t. */
@@ -54,10 +54,10 @@
 	unsigned long base;
 	unsigned long size;
-} efi_memmap_item_t;
+} memmap_item_t;
 
 typedef struct {
 	binit_t taskmap;
 	
-	efi_memmap_item_t memmap[MEMMAP_ITEMS];
+	memmap_item_t memmap[MEMMAP_ITEMS];
 	unsigned int memmap_items;
 	
@@ -66,5 +66,4 @@
 	unsigned long freq_scale;
 	unsigned int wakeup_intno;
-	int hello_configured;
 } bootinfo_t;
 
Index: kernel/arch/ia64/src/drivers/ski.c
===================================================================
--- kernel/arch/ia64/src/drivers/ski.c	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ kernel/arch/ia64/src/drivers/ski.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -57,5 +57,5 @@
 };
 
-static void ski_putchar(outdev_t *, const wchar_t, bool);
+static void ski_putchar(outdev_t *, const wchar_t);
 
 static outdev_operations_t skidev_ops = {
@@ -99,7 +99,4 @@
 static void poll_keyboard(ski_instance_t *instance)
 {
-	if (silent)
-		return;
-	
 	int count = POLL_LIMIT;
 	
@@ -121,5 +118,8 @@
 	
 	while (true) {
-		if (!silent)
+		// TODO FIXME:
+		// This currently breaks the kernel console
+		// before we get the override from uspace.
+		if (console_override)
 			poll_keyboard(instance);
 		
@@ -182,10 +182,12 @@
  * @param dev    Character device.
  * @param ch     Character to be printed.
- * @param silent Whether the output should be silenced.
- *
- */
-static void ski_putchar(outdev_t *dev, const wchar_t ch, bool silent)
-{
-	if (!silent) {
+ *
+ */
+static void ski_putchar(outdev_t *dev, const wchar_t ch)
+{
+	// TODO FIXME:
+	// This currently breaks the kernel console
+	// before we get the override from uspace.
+	if (console_override) {
 		if (ascii_check(ch)) {
 			if (ch == '\n')
@@ -213,5 +215,6 @@
 	if (!fb_exported) {
 		/*
-		 * This is the necessary evil until the userspace driver is entirely
+		 * This is the necessary evil until
+		 * the userspace driver is entirely
 		 * self-sufficient.
 		 */
Index: kernel/arch/ia64/src/ia64.c
===================================================================
--- kernel/arch/ia64/src/ia64.c	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ kernel/arch/ia64/src/ia64.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -151,5 +151,5 @@
 	/* Set platform name. */
 #ifdef MACHINE_ski
-	platform = "pc";
+	platform = "ski";
 #endif
 #ifdef MACHINE_i460GX
Index: kernel/arch/ia64/src/mm/frame.c
===================================================================
--- kernel/arch/ia64/src/mm/frame.c	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ kernel/arch/ia64/src/mm/frame.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -58,5 +58,5 @@
 		unsigned int i;
 		for (i = 0; i < bootinfo->memmap_items; i++) {
-			if (bootinfo->memmap[i].type == EFI_MEMMAP_FREE_MEM) {
+			if (bootinfo->memmap[i].type == MEMMAP_FREE_MEM) {
 				uint64_t base = bootinfo->memmap[i].base;
 				uint64_t size = bootinfo->memmap[i].size;
Index: kernel/arch/mips32/Makefile.inc
===================================================================
--- kernel/arch/mips32/Makefile.inc	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ kernel/arch/mips32/Makefile.inc	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -29,5 +29,5 @@
 BFD_ARCH = mips
 BFD = binary
-GCC_CFLAGS += -mno-abicalls -G 0 -fno-zero-initialized-in-bss -mips3
+GCC_CFLAGS += -mno-abicalls -G 0 -fno-zero-initialized-in-bss -mips3 -mabi=32
 
 BITS = 32
Index: kernel/arch/mips32/include/cycle.h
===================================================================
--- kernel/arch/mips32/include/cycle.h	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ kernel/arch/mips32/include/cycle.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -27,5 +27,5 @@
  */
 
-/** @addtogroup mips2
+/** @addtogroup mips32
  * @{
  */
Index: kernel/arch/mips32/include/debug.h
===================================================================
--- kernel/arch/mips32/include/debug.h	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ kernel/arch/mips32/include/debug.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -34,5 +34,5 @@
 
 #ifndef KERN_mips32_DEBUG_H_
-#define KERN_mips23_DEBUG_H_
+#define KERN_mips32_DEBUG_H_
 
 /** Enter the simulator trace mode */
Index: kernel/arch/mips32/include/mm/frame.h
===================================================================
--- kernel/arch/mips32/include/mm/frame.h	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ kernel/arch/mips32/include/mm/frame.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -42,6 +42,4 @@
 #ifndef __ASM__
 
-#include <typedefs.h>
-
 extern void frame_arch_init(void);
 extern void physmem_print(void);
Index: kernel/arch/mips32/include/stack.h
===================================================================
--- kernel/arch/mips32/include/stack.h	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ kernel/arch/mips32/include/stack.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -39,12 +39,4 @@
 #define STACK_ALIGNMENT		8
 
-#define STACK_ARG0		0
-#define STACK_ARG1		4
-#define STACK_ARG2		8
-#define STACK_ARG3		12
-#define STACK_ARG4		16
-#define STACK_ARG5		20
-#define STACK_ARG6		24
-
 #endif
 
Index: kernel/arch/mips32/src/cache.c
===================================================================
--- kernel/arch/mips32/src/cache.c	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ kernel/arch/mips32/src/cache.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -27,5 +27,5 @@
  */
 
-/** @addtogroup mips32	
+/** @addtogroup mips32
  * @{
  */
Index: kernel/arch/mips32/src/cpu/cpu.c
===================================================================
--- kernel/arch/mips32/src/cpu/cpu.c	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ kernel/arch/mips32/src/cpu/cpu.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -37,5 +37,5 @@
 #include <arch.h>
 #include <arch/cp0.h>
-#include <print.h>	
+#include <print.h>
 
 struct data_t {
Index: kernel/arch/mips32/src/fpu_context.c
===================================================================
--- kernel/arch/mips32/src/fpu_context.c	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ kernel/arch/mips32/src/fpu_context.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -27,5 +27,5 @@
  */
 
-/** @addtogroup mips32	
+/** @addtogroup mips32
  * @{
  */
@@ -40,5 +40,5 @@
 
 void fpu_disable(void)
-{	
+{
 #ifdef CONFIG_FPU
 	cp0_status_write(cp0_status_read() & ~cp0_status_fpu_bit);
Index: kernel/arch/mips32/src/mm/as.c
===================================================================
--- kernel/arch/mips32/src/mm/as.c	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ kernel/arch/mips32/src/mm/as.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -61,9 +61,9 @@
 	/*
 	 * Install ASID.
-	 */	
+	 */
 	hi.value = cp0_entry_hi_read();
 
 	hi.asid = as->asid;
-	cp0_entry_hi_write(hi.value);	
+	cp0_entry_hi_write(hi.value);
 }
 
Index: kernel/arch/mips32/src/mm/tlb.c
===================================================================
--- kernel/arch/mips32/src/mm/tlb.c	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ kernel/arch/mips32/src/mm/tlb.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -73,5 +73,5 @@
 		tlbwi();
 	}
-		
+	
 	/*
 	 * The kernel is going to make use of some wired
@@ -386,13 +386,10 @@
 			ASSERT(pte->w || access != PF_ACCESS_WRITE);
 			return pte;
-			break;
 		case AS_PF_DEFER:
 			*pfrc = AS_PF_DEFER;
 			return NULL;
-			break;
 		case AS_PF_FAULT:
 			*pfrc = AS_PF_FAULT;
 			return NULL;
-			break;
 		default:
 			panic("Unexpected rc (%d).", rc);
Index: kernel/arch/mips32/src/start.S
===================================================================
--- kernel/arch/mips32/src/start.S	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ kernel/arch/mips32/src/start.S	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -222,6 +222,5 @@
 	
 	/* move $k0 pointer to kernel stack */
-	lui $k0, %hi(supervisor_sp)
-	ori $k0, $k0, %lo(supervisor_sp)
+	la $k0, supervisor_sp
 	
 	/* move $k0 (supervisor_sp) */
Index: kernel/arch/mips64/Makefile.inc
===================================================================
--- kernel/arch/mips64/Makefile.inc	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
+++ kernel/arch/mips64/Makefile.inc	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -0,0 +1,64 @@
+#
+# Copyright (c) 2005 Martin Decky
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# - Redistributions of source code must retain the above copyright
+#   notice, this list of conditions and the following disclaimer.
+# - Redistributions in binary form must reproduce the above copyright
+#   notice, this list of conditions and the following disclaimer in the
+#   documentation and/or other materials provided with the distribution.
+# - The name of the author may not be used to endorse or promote products
+#   derived from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+
+BFD_ARCH = mips:4000
+BFD = binary
+GCC_CFLAGS += -mno-abicalls -G 0 -fno-zero-initialized-in-bss -mips3 -mabi=64
+AFLAGS = -64
+
+BITS = 64
+
+## Accepted MACHINEs
+#
+
+ifeq ($(MACHINE),msim)
+	BFD_NAME = elf64-tradlittlemips
+	ENDIANESS = LE
+	GCC_CFLAGS += -mhard-float
+endif
+
+ARCH_SOURCES = \
+	arch/$(KARCH)/src/start.S \
+	arch/$(KARCH)/src/context.S \
+	arch/$(KARCH)/src/mips64.c \
+	arch/$(KARCH)/src/asm.S \
+	arch/$(KARCH)/src/exception.c \
+	arch/$(KARCH)/src/interrupt.c \
+	arch/$(KARCH)/src/cache.c \
+	arch/$(KARCH)/src/debugger.c \
+	arch/$(KARCH)/src/cpu/cpu.c \
+	arch/$(KARCH)/src/debug/stacktrace.c \
+	arch/$(KARCH)/src/debug/stacktrace_asm.S \
+	arch/$(KARCH)/src/mm/frame.c \
+	arch/$(KARCH)/src/mm/page.c \
+	arch/$(KARCH)/src/mm/tlb.c \
+	arch/$(KARCH)/src/mm/as.c \
+	arch/$(KARCH)/src/fpu_context.c \
+	arch/$(KARCH)/src/ddi/ddi.c \
+	arch/$(KARCH)/src/smp/dorder.c \
+	arch/$(KARCH)/src/smp/smp.c
Index: kernel/arch/mips64/_link.ld.in
===================================================================
--- kernel/arch/mips64/_link.ld.in	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
+++ kernel/arch/mips64/_link.ld.in	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -0,0 +1,57 @@
+/*
+ * MIPS64 linker script
+ *
+ *  kernel text
+ *  kernel data
+ *
+ */
+
+#undef mips
+#define mips mips
+
+#define KERNEL_LOAD_ADDRESS 0xffffffff80100000
+
+OUTPUT_ARCH(mips)
+OUTPUT_FORMAT(elf64-tradlittlemips)
+ENTRY(kernel_image_start)
+
+SECTIONS {
+	. = KERNEL_LOAD_ADDRESS;
+	.text : {
+		ktext_start = .;
+		*(.text);
+		ktext_end = .;
+	}
+	.data : {
+		kdata_start = .;
+		*(.data);                       /* initialized data */
+		hardcoded_ktext_size = .;
+		LONG(ktext_end - ktext_start);
+		hardcoded_kdata_size = .;
+		LONG(kdata_end - kdata_start);
+		hardcoded_load_address = .;
+		LONG(KERNEL_LOAD_ADDRESS);
+		*(.rodata*);
+		*(.sdata);
+		*(.reginfo);
+		*(.sbss);
+		*(.scommon);
+		*(.bss);                        /* uninitialized static variables */
+		*(COMMON);                      /* global variables */
+		. = ALIGN(8);
+		symbol_table = .;
+		*(symtab.*);
+	}
+	_gp = . + 0x8000;
+	.lit8 : { *(.lit8) }
+	.lit4 : { *(.lit4) }
+	
+	kdata_end = .;
+	
+	/DISCARD/ : {
+		*(.mdebug*);
+		*(.pdr);
+		*(.comment);
+		*(.note);
+	}
+}
Index: kernel/arch/mips64/include/arch.h
===================================================================
--- kernel/arch/mips64/include/arch.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
+++ kernel/arch/mips64/include/arch.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2005 Martin Decky
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup mips64
+ * @{
+ */
+/** @file
+ */
+
+#ifndef KERN_mips64_ARCH_H_
+#define KERN_mips64_ARCH_H_
+
+#include <typedefs.h>
+
+#define TASKMAP_MAX_RECORDS        32
+#define CPUMAP_MAX_RECORDS         32
+#define BOOTINFO_TASK_NAME_BUFLEN  32
+
+extern size_t cpu_count;
+
+typedef struct {
+	void *addr;
+	size_t size;
+	char name[BOOTINFO_TASK_NAME_BUFLEN];
+} utask_t;
+
+typedef struct {
+	uint32_t cpumap;
+	size_t cnt;
+	utask_t tasks[TASKMAP_MAX_RECORDS];
+} bootinfo_t;
+
+extern void arch_pre_main(void *entry, bootinfo_t *bootinfo);
+
+#endif
+
+/** @}
+ */
Index: kernel/arch/mips64/include/asm.h
===================================================================
--- kernel/arch/mips64/include/asm.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
+++ kernel/arch/mips64/include/asm.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -0,0 +1,117 @@
+/*
+ * 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.
+ */
+
+/** @addtogroup mips64
+ * @{
+ */
+/** @file
+ */
+
+#ifndef KERN_mips64_ASM_H_
+#define KERN_mips64_ASM_H_
+
+#include <typedefs.h>
+#include <config.h>
+#include <trace.h>
+
+NO_TRACE static inline void cpu_sleep(void)
+{
+	/*
+	 * 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.
+ *
+ */
+NO_TRACE static inline uintptr_t get_stack_base(void)
+{
+	uintptr_t base;
+	
+	asm volatile (
+		"and %[base], $29, %[mask]\n"
+		: [base] "=r" (base)
+		: [mask] "r" (~(STACK_SIZE - 1))
+	);
+	
+	return base;
+}
+
+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;
+}
+
+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/mips64/include/asm/boot.h
===================================================================
--- kernel/arch/mips64/include/asm/boot.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
+++ kernel/arch/mips64/include/asm/boot.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -0,0 +1,44 @@
+/*
+ * 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 mips64
+ * @{
+ */
+/** @file
+ */
+
+#ifndef KERN_mips64_BOOT_H_
+#define KERN_mips64_BOOT_H_
+
+/* Temporary stack size for boot process */
+#define TEMP_STACK_SIZE  0x100
+
+#endif
+
+/** @}
+ */
Index: kernel/arch/mips64/include/asm/regname.h
===================================================================
--- kernel/arch/mips64/include/asm/regname.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
+++ kernel/arch/mips64/include/asm/regname.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -0,0 +1,97 @@
+/*
+ * 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 mips64
+ * @{
+ */
+/** @file
+ */
+
+#ifndef KERN_mips64_REGNAME_H_
+#define KERN_mips64_REGNAME_H_
+
+#define zero    0
+#define at      1
+#define v0      2
+#define v1      3
+#define a0      4
+#define a1      5
+#define a2      6
+#define a3      7
+#define t0      8
+#define t1      9
+#define t2      10
+#define t3      11
+#define t4      12
+#define t5      13
+#define t6      14
+#define t7      15
+#define s0      16
+#define s1      17
+#define s2      18
+#define s3      19
+#define s4      20
+#define s5      21
+#define s6      22
+#define s7      23
+#define t8      24
+#define t9      25
+#define k0      26
+#define k1      27
+#define gp      28
+#define sp      29
+#define s8      30
+#define ra      31
+
+#define rindex    0
+#define rrandom   1
+#define entrylo0  2
+#define entrylo1  3
+#define context   4
+#define pagemask  5
+#define wired     6
+#define badvaddr  8
+#define count     9
+#define entryhi   10
+#define compare   11
+#define status    12
+#define cause     13
+#define epc       14
+#define rconfig   16
+#define lladdr    17
+#define watchlo   18
+#define watchhi   19
+#define xcontext  20
+#define rdebug    23
+#define depc      24
+#define eepc      30
+
+#endif
+
+/** @}
+ */
Index: kernel/arch/mips64/include/atomic.h
===================================================================
--- kernel/arch/mips64/include/atomic.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
+++ kernel/arch/mips64/include/atomic.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -0,0 +1,114 @@
+/*
+ * 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 mips64
+ * @{
+ */
+/** @file
+ */
+
+#ifndef KERN_mips64_ATOMIC_H_
+#define KERN_mips64_ATOMIC_H_
+
+#include <trace.h>
+
+#define atomic_inc(x)  ((void) atomic_add(x, 1))
+#define atomic_dec(x)  ((void) atomic_add(x, -1))
+
+#define atomic_postinc(x)  (atomic_add(x, 1) - 1)
+#define atomic_postdec(x)  (atomic_add(x, -1) + 1)
+
+#define atomic_preinc(x)  atomic_add(x, 1)
+#define atomic_predec(x)  atomic_add(x, -1)
+
+/* Atomic addition of immediate value.
+ *
+ * @param val Memory location to which will be the immediate value added.
+ * @param i Signed immediate that will be added to *val.
+ *
+ * @return Value after addition.
+ *
+ */
+NO_TRACE static inline atomic_count_t atomic_add(atomic_t *val,
+    atomic_count_t i)
+{
+	atomic_count_t tmp;
+	atomic_count_t v;
+	
+	asm volatile (
+		"1:\n"
+		"	lld %0, %1\n"
+		"	daddu %0, %0, %3\n"  /* same as daddi, but never traps on overflow */
+		"	move %2, %0\n"
+		"	scd %0, %1\n"
+		"	beq %0, %4, 1b\n"   /* if the atomic operation failed, try again */
+		"	nop\n"
+		: "=&r" (tmp),
+		  "+m" (val->count),
+		  "=&r" (v)
+		: "r" (i),
+		  "i" (0)
+	);
+	
+	return v;
+}
+
+NO_TRACE static inline atomic_count_t test_and_set(atomic_t *val)
+{
+	atomic_count_t tmp;
+	atomic_count_t v;
+	
+	asm volatile (
+		"1:\n"
+		"	lld %2, %1\n"
+		"	bnez %2, 2f\n"
+		"	dli %0, %3\n"
+		"	scd %0, %1\n"
+		"	beqz %0, 1b\n"
+		"	nop\n"
+		"2:\n"
+		: "=&r" (tmp),
+		  "+m" (val->count),
+		  "=&r" (v)
+		: "i" (1)
+	);
+	
+	return v;
+}
+
+NO_TRACE static inline void atomic_lock_arch(atomic_t *val)
+{
+	do {
+		while (val->count);
+	} while (test_and_set(val));
+}
+
+#endif
+
+/** @}
+ */
Index: kernel/arch/mips64/include/barrier.h
===================================================================
--- kernel/arch/mips64/include/barrier.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
+++ kernel/arch/mips64/include/barrier.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -0,0 +1,54 @@
+/*
+ * 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 mips64
+ * @{
+ */
+/** @file
+ */
+
+#ifndef KERN_mips64_BARRIER_H_
+#define KERN_mips64_BARRIER_H_
+
+/*
+ * TODO: implement true MIPS memory barriers for macros below.
+ */
+#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 smc_coherence(a)
+#define smc_coherence_block(a, l)
+
+#endif
+
+/** @}
+ */
Index: kernel/arch/mips64/include/cache.h
===================================================================
--- kernel/arch/mips64/include/cache.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
+++ kernel/arch/mips64/include/cache.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -0,0 +1,45 @@
+/*
+ * 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.
+ */
+
+/** @addtogroup mips64
+ * @{
+ */
+/** @file
+ */
+
+#ifndef KERN_mips64_CACHE_H_
+#define KERN_mips64_CACHE_H_
+
+#include <arch/exception.h>
+
+extern void cache_error(istate_t *);
+
+#endif
+
+/** @}
+ */
Index: kernel/arch/mips64/include/context.h
===================================================================
--- kernel/arch/mips64/include/context.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
+++ kernel/arch/mips64/include/context.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2003-2004 Jakub Jermar
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup mips64
+ * @{
+ */
+/** @file
+ */
+
+#ifndef KERN_mips64_CONTEXT_H_
+#define KERN_mips64_CONTEXT_H_
+
+#include <align.h>
+#include <arch/stack.h>
+
+/*
+ * Put one item onto the stack to support get_stack_base() and align it up.
+ */
+#define SP_DELTA  (0 + ALIGN_UP(STACK_ITEM_SIZE, STACK_ALIGNMENT))
+
+#ifndef __ASM__
+
+#include <typedefs.h>
+
+#define context_set(ctx, pc, stack, size) \
+    context_set_generic(ctx, pc, stack, size)
+
+/*
+ * Only save registers that must be preserved across
+ * function calls.
+ */
+typedef struct {
+	uintptr_t sp;
+	uintptr_t pc;
+	
+	uint64_t s0;
+	uint64_t s1;
+	uint64_t s2;
+	uint64_t s3;
+	uint64_t s4;
+	uint64_t s5;
+	uint64_t s6;
+	uint64_t s7;
+	uint64_t s8;
+	uint64_t gp;
+	
+	ipl_t ipl;
+} context_t;
+
+#endif /* __ASM__ */
+
+#endif
+
+/** @}
+ */
Index: kernel/arch/mips64/include/context_offset.h
===================================================================
--- kernel/arch/mips64/include/context_offset.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
+++ kernel/arch/mips64/include/context_offset.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -0,0 +1,181 @@
+/*
+ * 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 KERN_mips64_CONTEXT_OFFSET_H_
+#define KERN_mips64_CONTEXT_OFFSET_H_
+
+#define OFFSET_SP       0x00
+#define OFFSET_PC       0x08
+#define OFFSET_S0       0x10
+#define OFFSET_S1       0x18
+#define OFFSET_S2       0x20
+#define OFFSET_S3       0x28
+#define OFFSET_S4       0x30
+#define OFFSET_S5       0x38
+#define OFFSET_S6       0x40
+#define OFFSET_S7       0x48
+#define OFFSET_S8       0x50
+#define OFFSET_GP       0x58
+
+#ifdef KERNEL
+	#define OFFSET_IPL  0x60
+#else
+	#define OFFSET_TLS  0x60
+	
+	#define OFFSET_F20  0x68
+	#define OFFSET_F21  0x70
+	#define OFFSET_F22  0x78
+	#define OFFSET_F23  0x80
+	#define OFFSET_F24  0x88
+	#define OFFSET_F25  0x90
+	#define OFFSET_F26  0x98
+	#define OFFSET_F27  0xa0
+	#define OFFSET_F28  0xa8
+	#define OFFSET_F29  0xb0
+	#define OFFSET_F30  0xb8
+#endif /* KERNEL */
+
+#ifdef __ASM__
+
+#include <arch/asm/regname.h>
+
+# ctx: address of the structure with saved context
+.macro CONTEXT_SAVE_ARCH_CORE ctx:req
+	sd $s0, OFFSET_S0(\ctx)
+	sd $s1, OFFSET_S1(\ctx)
+	sd $s2, OFFSET_S2(\ctx)
+	sd $s3, OFFSET_S3(\ctx)
+	sd $s4, OFFSET_S4(\ctx)
+	sd $s5, OFFSET_S5(\ctx)
+	sd $s6, OFFSET_S6(\ctx)
+	sd $s7, OFFSET_S7(\ctx)
+	sd $s8, OFFSET_S8(\ctx)
+	sd $gp, OFFSET_GP(\ctx)
+	
+#ifndef KERNEL
+	sd $k1, OFFSET_TLS(\ctx)
+	
+#ifdef CONFIG_FPU
+	dmfc1 $t0, $20
+	sd $t0, OFFSET_F20(\ctx)
+	
+	dmfc1 $t0,$21
+	sd $t0, OFFSET_F21(\ctx)
+	
+	dmfc1 $t0,$22
+	sd $t0, OFFSET_F22(\ctx)
+	
+	dmfc1 $t0,$23
+	sd $t0, OFFSET_F23(\ctx)
+	
+	dmfc1 $t0,$24
+	sd $t0, OFFSET_F24(\ctx)
+	
+	dmfc1 $t0,$25
+	sd $t0, OFFSET_F25(\ctx)
+	
+	dmfc1 $t0,$26
+	sd $t0, OFFSET_F26(\ctx)
+	
+	dmfc1 $t0,$27
+	sd $t0, OFFSET_F27(\ctx)
+	
+	dmfc1 $t0,$28
+	sd $t0, OFFSET_F28(\ctx)
+	
+	dmfc1 $t0,$29
+	sd $t0, OFFSET_F29(\ctx)
+	
+	dmfc1 $t0,$30
+	sd $t0, OFFSET_F30(\ctx)
+#endif /* CONFIG_FPU */
+#endif /* KERNEL */
+	
+	sd $ra, OFFSET_PC(\ctx)
+	sd $sp, OFFSET_SP(\ctx)
+.endm
+
+# ctx: address of the structure with saved context
+.macro CONTEXT_RESTORE_ARCH_CORE ctx:req
+	ld $s0, OFFSET_S0(\ctx)
+	ld $s1, OFFSET_S1(\ctx)
+	ld $s2, OFFSET_S2(\ctx)
+	ld $s3, OFFSET_S3(\ctx)
+	ld $s4, OFFSET_S4(\ctx)
+	ld $s5, OFFSET_S5(\ctx)
+	ld $s6, OFFSET_S6(\ctx)
+	ld $s7, OFFSET_S7(\ctx)
+	ld $s8, OFFSET_S8(\ctx)
+	ld $gp, OFFSET_GP(\ctx)
+	
+#ifndef KERNEL
+	ld $k1, OFFSET_TLS(\ctx)
+	
+#ifdef CONFIG_FPU
+	ld $t0, OFFSET_F20(\ctx)
+	dmtc1 $t0,$20
+	
+	ld $t0, OFFSET_F21(\ctx)
+	dmtc1 $t0,$21
+	
+	ld $t0, OFFSET_F22(\ctx)
+	dmtc1 $t0,$22
+	
+	ld $t0, OFFSET_F23(\ctx)
+	dmtc1 $t0,$23
+	
+	ld $t0, OFFSET_F24(\ctx)
+	dmtc1 $t0,$24
+	
+	ld $t0, OFFSET_F25(\ctx)
+	dmtc1 $t0,$25
+	
+	ld $t0, OFFSET_F26(\ctx)
+	dmtc1 $t0,$26
+	
+	ld $t0, OFFSET_F27(\ctx)
+	dmtc1 $t0,$27
+	
+	ld $t0, OFFSET_F28(\ctx)
+	dmtc1 $t0,$28
+	
+	ld $t0, OFFSET_F29(\ctx)
+	dmtc1 $t0,$29
+	
+	ld $t0, OFFSET_F30(\ctx)
+	dmtc1 $t0,$30
+#endif /* CONFIG_FPU */
+#endif /* KERNEL */
+	
+	ld $ra, OFFSET_PC(\ctx)
+	ld $sp, OFFSET_SP(\ctx)
+.endm
+
+#endif /* __ASM__ */
+
+#endif
Index: kernel/arch/mips64/include/cp0.h
===================================================================
--- kernel/arch/mips64/include/cp0.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
+++ kernel/arch/mips64/include/cp0.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -0,0 +1,143 @@
+/*
+ * 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.
+ */
+
+/** @addtogroup mips64
+ * @{
+ */
+/** @file
+ */
+
+#ifndef KERN_mips64_CP0_H_
+#define KERN_mips64_CP0_H_
+
+#ifdef KERNEL
+
+#include <typedefs.h>
+
+#else
+
+#include <sys/types.h>
+
+#endif
+
+#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
+#define cp0_status_im_mask   0xff00
+
+#define cp0_cause_excno(cause)   ((cause >> 2) & 0x1f)
+#define cp0_cause_coperr(cause)  ((cause >> 28) & 0x3)
+
+#define fpu_cop_id  1
+
+/*
+ * Magic value for use in msim.
+ */
+#define cp0_compare_value  100000
+
+#define cp0_mask_all_int() \
+	cp0_status_write(cp0_status_read() & ~(cp0_status_im_mask))
+
+#define cp0_unmask_all_int() \
+	cp0_status_write(cp0_status_read() | cp0_status_im_mask)
+
+#define cp0_mask_int(it) \
+	cp0_status_write(cp0_status_read() & ~(1 << (cp0_status_im_shift + (it))))
+
+#define cp0_unmask_int(it) \
+	cp0_status_write(cp0_status_read() | (1 << (cp0_status_im_shift + (it))))
+
+#define GEN_READ_CP0(nm,reg) static inline uint64_t cp0_ ##nm##_read(void) \
+	{ \
+		uint64_t retval; \
+		asm volatile ( \
+			"dmfc0 %0, $" #reg \
+			: "=r" (retval) \
+		); \
+		return retval; \
+	}
+
+#define GEN_WRITE_CP0(nm,reg) static inline void cp0_ ##nm##_write(uint32_t val) \
+	{ \
+		asm volatile ( \
+			"dmtc0 %0, $" #reg \
+			:: "r" (val) \
+		); \
+	}
+
+GEN_READ_CP0(index, 0);
+GEN_WRITE_CP0(index, 0);
+
+GEN_READ_CP0(random, 1);
+
+GEN_READ_CP0(entry_lo0, 2);
+GEN_WRITE_CP0(entry_lo0, 2);
+
+GEN_READ_CP0(entry_lo1, 3);
+GEN_WRITE_CP0(entry_lo1, 3);
+
+GEN_READ_CP0(context, 4);
+GEN_WRITE_CP0(context, 4);
+
+GEN_READ_CP0(pagemask, 5);
+GEN_WRITE_CP0(pagemask, 5);
+
+GEN_READ_CP0(wired, 6);
+GEN_WRITE_CP0(wired, 6);
+
+GEN_READ_CP0(badvaddr, 8);
+
+GEN_READ_CP0(count, 9);
+GEN_WRITE_CP0(count, 9);
+
+GEN_READ_CP0(entry_hi, 10);
+GEN_WRITE_CP0(entry_hi, 10);
+
+GEN_READ_CP0(compare, 11);
+GEN_WRITE_CP0(compare, 11);
+
+GEN_READ_CP0(status, 12);
+GEN_WRITE_CP0(status, 12);
+
+GEN_READ_CP0(cause, 13);
+GEN_WRITE_CP0(cause, 13);
+
+GEN_READ_CP0(epc, 14);
+GEN_WRITE_CP0(epc, 14);
+
+GEN_READ_CP0(prid, 15);
+
+#endif
+
+/** @}
+ */
Index: kernel/arch/mips64/include/cpu.h
===================================================================
--- kernel/arch/mips64/include/cpu.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
+++ kernel/arch/mips64/include/cpu.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -0,0 +1,49 @@
+/*
+ * 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.
+ */
+
+/** @addtogroup mips64
+ * @{
+ */
+/** @file
+ */
+
+#ifndef KERN_mips64_CPU_H_
+#define KERN_mips64_CPU_H_
+
+#include <typedefs.h>
+#include <arch/asm.h>
+
+typedef struct {
+	uint32_t imp_num;
+	uint32_t rev_num;
+} cpu_arch_t;
+
+#endif
+
+/** @}
+ */
Index: kernel/arch/mips64/include/cycle.h
===================================================================
--- kernel/arch/mips64/include/cycle.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
+++ kernel/arch/mips64/include/cycle.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -0,0 +1,50 @@
+/*
+ * 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 mips64
+ * @{
+ */
+/** @file
+ */
+
+#ifndef KERN_mips64_CYCLE_H_
+#define KERN_mips64_CYCLE_H_
+
+#include <arch/cp0.h>
+#include <arch/interrupt.h>
+#include <trace.h>
+
+NO_TRACE static inline uint64_t get_cycle(void)
+{
+	return ((uint64_t) count_hi << 32) + ((uint64_t) cp0_count_read());
+}
+
+#endif
+
+/** @}
+ */
Index: kernel/arch/mips64/include/debug.h
===================================================================
--- kernel/arch/mips64/include/debug.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
+++ kernel/arch/mips64/include/debug.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -0,0 +1,71 @@
+/*
+ * 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 mips64
+ * @{
+ */
+/** @file
+ */
+
+#ifndef KERN_mips64_DEBUG_H_
+#define KERN_mips64_DEBUG_H_
+
+/** 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/mips64/include/debugger.h
===================================================================
--- kernel/arch/mips64/include/debugger.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
+++ kernel/arch/mips64/include/debugger.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -0,0 +1,78 @@
+/*
+ * 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 mips64
+ * @{
+ */
+/** @file
+ */
+
+#ifndef KERN_mips64_DEBUGGER_H_
+#define KERN_mips64_DEBUGGER_H_
+
+#include <arch/exception.h>
+#include <typedefs.h>
+
+#define BKPOINTS_MAX  10
+
+/** 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 */
+	sysarg_t instruction;      /**< Original instruction */
+	sysarg_t nextinstruction;  /**< Original instruction following break */
+	unsigned int flags;        /**< Flags regarding breakpoint */
+	size_t counter;
+	void (*bkfunc)(void *, istate_t *);
+} bpinfo_t;
+
+extern bpinfo_t breakpoints[BKPOINTS_MAX];
+
+extern bool is_jump(sysarg_t);
+
+extern void debugger_init(void);
+extern void debugger_bpoint(istate_t *);
+
+#endif
+
+/** @}
+ */
Index: kernel/arch/mips64/include/drivers/msim.h
===================================================================
--- kernel/arch/mips64/include/drivers/msim.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
+++ kernel/arch/mips64/include/drivers/msim.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -0,0 +1,46 @@
+/*
+ * 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 mips64
+ * @{
+ */
+/** @file
+ */
+
+#ifndef KERN_mips64_MSIM_H_
+#define KERN_mips64_MSIM_H_
+
+/** Address of devices. */
+#define MSIM_VIDEORAM     0xffffffff90000000
+#define MSIM_KBD_ADDRESS  0xffffffff90000000
+#define MSIM_KBD_IRQ      2
+
+#endif
+
+/** @}
+ */
Index: kernel/arch/mips64/include/elf.h
===================================================================
--- kernel/arch/mips64/include/elf.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
+++ kernel/arch/mips64/include/elf.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2006 Sergey Bondari
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup mips64
+ * @{
+ */
+/** @file
+ */
+
+#ifndef KERN_mips64_ELF_H_
+#define KERN_mips64_ELF_H_
+
+#define ELF_MACHINE  EM_MIPS
+
+#ifdef __BE__
+	#define ELF_DATA_ENCODING  ELFDATA2MSB
+#else
+	#define ELF_DATA_ENCODING  ELFDATA2LSB
+#endif
+
+#define ELF_CLASS  ELFCLASS64
+
+#endif
+
+/** @}
+ */
Index: kernel/arch/mips64/include/exception.h
===================================================================
--- kernel/arch/mips64/include/exception.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
+++ kernel/arch/mips64/include/exception.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -0,0 +1,69 @@
+/*
+ * 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.
+ */
+
+/** @addtogroup mips64
+ * @{
+ */
+/** @file
+ */
+
+#ifndef KERN_mips64_EXCEPTION_H_
+#define KERN_mips64_EXCEPTION_H_
+
+#include <typedefs.h>
+#include <arch/istate.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
+
+extern void exception(istate_t *istate);
+extern void tlb_refill_entry(void);
+extern void exception_entry(void);
+extern void cache_error_entry(void);
+extern void exception_init(void);
+
+#endif
+
+/** @}
+ */
Index: kernel/arch/mips64/include/faddr.h
===================================================================
--- kernel/arch/mips64/include/faddr.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
+++ kernel/arch/mips64/include/faddr.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -0,0 +1,45 @@
+/*
+ * 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 mips64
+ * @{
+ */
+/** @file
+ */
+
+#ifndef KERN_mips64_FADDR_H_
+#define KERN_mips64_FADDR_H_
+
+#include <typedefs.h>
+
+#define FADDR(fptr)  ((uintptr_t) (fptr))
+
+#endif
+
+/** @}
+ */
Index: kernel/arch/mips64/include/fpu_context.h
===================================================================
--- kernel/arch/mips64/include/fpu_context.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
+++ kernel/arch/mips64/include/fpu_context.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2005 Jakub Vana
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup mips64
+ * @{
+ */
+/** @file
+ */
+
+#ifndef KERN_mips64_FPU_CONTEXT_H_
+#define KERN_mips64_FPU_CONTEXT_H_
+
+#include <typedefs.h>
+
+#define FPU_CONTEXT_ALIGN  sizeof(sysarg_t)
+
+typedef struct {
+	sysarg_t dregs[32];
+	sysarg_t cregs[32];
+} fpu_context_t;
+
+#endif
+
+/** @}
+ */
Index: kernel/arch/mips64/include/interrupt.h
===================================================================
--- kernel/arch/mips64/include/interrupt.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
+++ kernel/arch/mips64/include/interrupt.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -0,0 +1,54 @@
+/*
+ * 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.
+ */
+
+/** @addtogroup mips64
+ * @{
+ */
+/** @file
+ */
+
+#ifndef KERN_mips64_INTERRUPT_H_
+#define KERN_mips64_INTERRUPT_H_
+
+#include <typedefs.h>
+#include <arch/exception.h>
+
+#define IVT_ITEMS  32
+#define IVT_FIRST  0
+
+#define VECTOR_TLB_SHOOTDOWN_IPI  EXC_Int
+
+extern function virtual_timer_fnc;
+extern uint32_t count_hi;
+
+extern void interrupt_init(void);
+
+#endif
+
+/** @}
+ */
Index: kernel/arch/mips64/include/istate.h
===================================================================
--- kernel/arch/mips64/include/istate.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
+++ kernel/arch/mips64/include/istate.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -0,0 +1,121 @@
+/*
+ * 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.
+ */
+
+/** @addtogroup mips64
+ * @{
+ */
+/** @file
+ */
+
+#ifndef KERN_mips64_ISTATE_H_
+#define KERN_mips64_ISTATE_H_
+
+#include <arch/cp0.h>
+
+#ifdef KERNEL
+
+#include <typedefs.h>
+#include <trace.h>
+
+#else
+
+#include <sys/types.h>
+#define NO_TRACE
+
+#endif
+
+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.
+	 */
+	uint64_t a0;      /* arg1 */
+	uint64_t a1;      /* arg2 */
+	uint64_t a2;      /* arg3 */
+	uint64_t a3;      /* arg4 */
+	uint64_t t0;      /* arg5 */
+	uint64_t t1;      /* arg6 */
+	uint64_t v0;      /* arg7 */
+	uint64_t v1;
+	uint64_t at;
+	uint64_t t2;
+	uint64_t t3;
+	uint64_t t4;
+	uint64_t t5;
+	uint64_t t6;
+	uint64_t t7;
+	uint64_t s0;
+	uint64_t s1;
+	uint64_t s2;
+	uint64_t s3;
+	uint64_t s4;
+	uint64_t s5;
+	uint64_t s6;
+	uint64_t s7;
+	uint64_t t8;
+	uint64_t t9;
+	uint64_t kt0;
+	uint64_t kt1;     /* We use it as thread-local pointer */
+	uint64_t gp;
+	uint64_t sp;
+	uint64_t s8;
+	uint64_t ra;
+	
+	uint64_t lo;
+	uint64_t hi;
+	
+	uint64_t status;  /* cp0_status */
+	uint64_t epc;     /* cp0_epc */
+} istate_t;
+
+NO_TRACE static inline void istate_set_retaddr(istate_t *istate,
+    uintptr_t retaddr)
+{
+	istate->epc = retaddr;
+}
+
+/** Return true if exception happened while in userspace */
+NO_TRACE static inline int istate_from_uspace(istate_t *istate)
+{
+	return istate->status & cp0_status_um_bit;
+}
+
+NO_TRACE static inline uintptr_t istate_get_pc(istate_t *istate)
+{
+	return istate->epc;
+}
+
+NO_TRACE static inline uintptr_t istate_get_fp(istate_t *istate)
+{
+	return istate->sp;
+}
+
+#endif
+
+/** @}
+ */
Index: kernel/arch/mips64/include/mm/as.h
===================================================================
--- kernel/arch/mips64/include/mm/as.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
+++ kernel/arch/mips64/include/mm/as.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -0,0 +1,61 @@
+/*
+ * 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 mips64mm
+ * @{
+ */
+/** @file
+ */
+
+#ifndef KERN_mips64_AS_H_
+#define KERN_mips64_AS_H_
+
+#define KERNEL_ADDRESS_SPACE_SHADOWED_ARCH  0
+
+#define KERNEL_ADDRESS_SPACE_START_ARCH  UINT64_C(0xffffffff80000000)
+#define KERNEL_ADDRESS_SPACE_END_ARCH    UINT64_C(0xffffffff9fffffff)
+#define USER_ADDRESS_SPACE_START_ARCH    UINT64_C(0x0000000000000000)
+#define USER_ADDRESS_SPACE_END_ARCH      UINT32_C(0x000000ffffffffff)
+
+typedef struct {
+} as_arch_t;
+
+#include <genarch/mm/as_ht.h>
+
+#define as_constructor_arch(as, flags)  (as != as)
+#define as_destructor_arch(as)          (as != as)
+#define as_create_arch(as, flags)       (as != as)
+#define as_deinstall_arch(as)
+#define as_invalidate_translation_cache(as, page, cnt)
+
+extern void as_arch_init(void);
+
+#endif
+
+/** @}
+ */
Index: kernel/arch/mips64/include/mm/asid.h
===================================================================
--- kernel/arch/mips64/include/mm/asid.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
+++ kernel/arch/mips64/include/mm/asid.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -0,0 +1,47 @@
+/*
+ * 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 mips64mm
+ * @{
+ */
+/** @file
+ */
+
+#ifndef KERN_mips64_ASID_H_
+#define KERN_mips64_ASID_H_
+
+#include <typedefs.h>
+
+#define ASID_MAX_ARCH  255    /* 2^8 - 1 */
+
+typedef uint8_t asid_t;
+
+#endif
+
+/** @}
+ */
Index: kernel/arch/mips64/include/mm/frame.h
===================================================================
--- kernel/arch/mips64/include/mm/frame.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
+++ kernel/arch/mips64/include/mm/frame.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -0,0 +1,53 @@
+/*
+ * 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 mips64mm
+ * @{
+ */
+/** @file
+ */
+
+#ifndef KERN_mips64_FRAME_H_
+#define KERN_mips64_FRAME_H_
+
+#define FRAME_WIDTH  14  /* 16K */
+#define FRAME_SIZE   (1 << FRAME_WIDTH)
+
+#ifdef KERNEL
+#ifndef __ASM__
+
+extern void frame_arch_init(void);
+extern void physmem_print(void);
+
+#endif /* __ASM__ */
+#endif /* KERNEL */
+
+#endif
+
+/** @}
+ */
Index: kernel/arch/mips64/include/mm/page.h
===================================================================
--- kernel/arch/mips64/include/mm/page.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
+++ kernel/arch/mips64/include/mm/page.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -0,0 +1,63 @@
+/*
+ * 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.
+ */
+
+/** @addtogroup mips64mm
+ * @{
+ */
+/** @file
+ */
+
+#ifndef KERN_mips64_PAGE_H_
+#define KERN_mips64_PAGE_H_
+
+#include <arch/mm/frame.h>
+#include <trace.h>
+
+#define PAGE_WIDTH  FRAME_WIDTH
+#define PAGE_SIZE   FRAME_SIZE
+
+#ifndef __ASM__
+	#define KA2PA(addr)  (((uintptr_t) (addr)) - 0xffffffff80000000)
+	#define PA2KA(addr)  (((uintptr_t) (addr)) + 0xffffffff80000000)
+#else
+	#define KA2PA(addr)  ((addr) - 0xffffffff80000000)
+	#define PA2KA(addr)  ((addr) + 0xffffffff80000000)
+#endif
+
+#ifdef KERNEL
+#ifndef __ASM__
+
+extern void page_arch_init(void);
+
+#endif /* __ASM__ */
+#endif /* KERNEL */
+
+#endif
+
+/** @}
+ */
Index: kernel/arch/mips64/include/mm/tlb.h
===================================================================
--- kernel/arch/mips64/include/mm/tlb.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
+++ kernel/arch/mips64/include/mm/tlb.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -0,0 +1,181 @@
+/*
+ * 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.
+ */
+
+/** @addtogroup mips64mm
+ * @{
+ */
+/** @file
+ */
+
+#ifndef KERN_mips64_TLB_H_
+#define KERN_mips64_TLB_H_
+
+#include <typedefs.h>
+#include <arch/mm/asid.h>
+#include <arch/exception.h>
+#include <trace.h>
+
+#define TLB_ENTRY_COUNT  48
+
+#define TLB_WIRED               1
+#define TLB_KSTACK_WIRED_INDEX  0
+
+#define TLB_PAGE_MASK_4K    (0x000 << 13)
+#define TLB_PAGE_MASK_16K   (0x003 << 13)
+#define TLB_PAGE_MASK_64K   (0x00f << 13)
+#define TLB_PAGE_MASK_256K  (0x03f << 13)
+#define TLB_PAGE_MASK_1M    (0x0ff << 13)
+#define TLB_PAGE_MASK_4M    (0x3ff << 13)
+#define TLB_PAGE_MASK_16M   (0xfff << 13)
+
+#define PAGE_UNCACHED             2
+#define PAGE_CACHEABLE_EXC_WRITE  5
+
+typedef union {
+	struct {
+#ifdef __BE__
+		unsigned int : 2;       /* zero */
+		unsigned int pfn : 24;  /* frame number */
+		unsigned int c : 3;     /* cache coherency attribute */
+		unsigned int d : 1;     /* dirty/write-protect bit */
+		unsigned int v : 1;     /* valid bit */
+		unsigned int g : 1;     /* global bit */
+#else
+		unsigned int g : 1;     /* global bit */
+		unsigned int v : 1;     /* valid bit */
+		unsigned int d : 1;     /* dirty/write-protect bit */
+		unsigned int c : 3;     /* cache coherency attribute */
+		unsigned int pfn : 24;  /* frame number */
+		unsigned int : 2;       /* zero */
+#endif
+	} __attribute__ ((packed));
+	uint32_t value;
+} entry_lo_t;
+
+typedef union {
+	struct {
+#ifdef __BE__
+		unsigned int vpn2 : 19;
+		unsigned int : 5;
+		unsigned int asid : 8;
+#else
+		unsigned int asid : 8;
+		unsigned int : 5;
+		unsigned int vpn2 : 19;
+#endif
+	} __attribute__ ((packed));
+	uint32_t value;
+} entry_hi_t;
+
+typedef union {
+	struct {
+#ifdef __BE__
+		unsigned int : 7;
+		unsigned int mask : 12;
+		unsigned int : 13;
+#else
+		unsigned int : 13;
+		unsigned int mask : 12;
+		unsigned int : 7;
+#endif
+	} __attribute__ ((packed));
+	uint32_t value;
+} page_mask_t;
+
+typedef union {
+	struct {
+#ifdef __BE__
+		unsigned int p : 1;
+		unsigned int : 27;
+		unsigned int index : 4;
+#else
+		unsigned int index : 4;
+		unsigned int : 27;
+		unsigned int p : 1;
+#endif
+	} __attribute__ ((packed));
+	uint32_t value;
+} tlb_index_t;
+
+/** Probe TLB for Matching Entry
+ *
+ * Probe TLB for Matching Entry.
+ */
+NO_TRACE static inline void tlbp(void)
+{
+	asm volatile (
+		"tlbp\n\t"
+	);
+}
+
+/** Read Indexed TLB Entry
+ *
+ * Read Indexed TLB Entry.
+ */
+NO_TRACE static inline void tlbr(void)
+{
+	asm volatile (
+		"tlbr\n\t"
+	);
+}
+
+/** Write Indexed TLB Entry
+ *
+ * Write Indexed TLB Entry.
+ */
+NO_TRACE static inline void tlbwi(void)
+{
+	asm volatile (
+		"tlbwi\n\t"
+	);
+}
+
+/** Write Random TLB Entry
+ *
+ * Write Random TLB Entry.
+ */
+NO_TRACE static inline void tlbwr(void)
+{
+	asm volatile (
+		"tlbwr\n\t"
+	);
+}
+
+#define tlb_invalidate(asid)  tlb_invalidate_asid(asid)
+
+extern void tlb_invalid(istate_t *);
+extern void tlb_refill(istate_t *);
+extern void tlb_modified(istate_t *);
+extern void tlb_prepare_entry_lo(entry_lo_t *, bool, bool, bool, bool,
+    uintptr_t);
+extern void tlb_prepare_entry_hi(entry_hi_t *, asid_t, uintptr_t);
+
+#endif
+
+/** @}
+ */
Index: kernel/arch/mips64/include/proc/task.h
===================================================================
--- kernel/arch/mips64/include/proc/task.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
+++ kernel/arch/mips64/include/proc/task.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2006 Jakub Jermar
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup mips64proc
+ * @{
+ */
+/** @file
+ */
+
+#ifndef KERN_mips64_TASK_H_
+#define KERN_mips64_TASK_H_
+
+typedef struct {
+} task_arch_t;
+
+#define task_create_arch(task)
+#define task_destroy_arch(task)
+
+#endif
+
+/** @}
+ */
Index: kernel/arch/mips64/include/proc/thread.h
===================================================================
--- kernel/arch/mips64/include/proc/thread.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
+++ kernel/arch/mips64/include/proc/thread.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -0,0 +1,48 @@
+/*
+ * 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.
+ */
+
+/** @addtogroup mips64proc
+ * @{
+ */
+/** @file
+ */
+
+#ifndef KERN_mips64_THREAD_H_
+#define KERN_mips64_THREAD_H_
+
+typedef struct {
+} thread_arch_t;
+
+#define thr_constructor_arch(thread)
+#define thr_destructor_arch(thread)
+#define thread_create_arch(thread)
+
+#endif
+
+/** @}
+ */
Index: kernel/arch/mips64/include/smp/dorder.h
===================================================================
--- kernel/arch/mips64/include/smp/dorder.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
+++ kernel/arch/mips64/include/smp/dorder.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -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 mips64
+ * @{
+ */
+/** @file
+ */
+
+#ifndef KERN_mips64_DORDER_H_
+#define KERN_mips64_DORDER_H_
+
+#include <typedefs.h>
+
+extern uint32_t dorder_cpuid(void);
+extern void dorder_ipi_ack(uint32_t);
+
+#endif
+
+/** @}
+ */
Index: kernel/arch/mips64/include/stack.h
===================================================================
--- kernel/arch/mips64/include/stack.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
+++ kernel/arch/mips64/include/stack.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -0,0 +1,44 @@
+/*
+ * 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 mips64
+ * @{
+ */
+/** @file
+ */
+
+#ifndef KERN_mips64_STACK_H_
+#define KERN_mips64_STACK_H_
+
+#define STACK_ITEM_SIZE  8
+#define STACK_ALIGNMENT  8
+
+#endif
+
+/** @}
+ */
Index: kernel/arch/mips64/include/types.h
===================================================================
--- kernel/arch/mips64/include/types.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
+++ kernel/arch/mips64/include/types.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -0,0 +1,64 @@
+/*
+ * 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.
+ */
+
+/** @addtogroup mips64
+ * @{
+ */
+/** @file
+ */
+
+#ifndef KERN_mips64_TYPES_H_
+#define KERN_mips64_TYPES_H_
+
+typedef uint64_t size_t;
+typedef int64_t ssize_t;
+
+typedef uint64_t uintptr_t;
+typedef uint64_t pfn_t;
+
+typedef uint64_t ipl_t;
+
+typedef uint64_t sysarg_t;
+typedef int64_t native_t;
+typedef uint64_t atomic_count_t;
+
+typedef struct {
+} fncptr_t;
+
+#define INTN_C(c)   INT64_C(c)
+#define UINTN_C(c)  UINT64_C(c)
+
+#define PRIdn  PRId64  /**< Format for native_t. */
+#define PRIun  PRIu64  /**< Format for sysarg_t. */
+#define PRIxn  PRIx64  /**< Format for hexadecimal sysarg_t. */
+#define PRIua  PRIu64  /**< Format for atomic_count_t. */
+
+#endif
+
+/** @}
+ */
Index: kernel/arch/mips64/src/asm.S
===================================================================
--- kernel/arch/mips64/src/asm.S	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
+++ kernel/arch/mips64/src/asm.S	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -0,0 +1,301 @@
+/*
+ * 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>
+
+.text
+
+.macro cp0_read reg
+	dmfc0 $2, \reg
+	j $31
+	nop
+.endm
+
+.macro cp0_write reg
+	dmtc0 $4, \reg
+	j $31
+	nop
+.endm
+
+.set noat
+.set noreorder
+.set nomacro
+
+.global asm_delay_loop
+asm_delay_loop:
+	j $31
+	nop
+
+.global cpu_halt
+cpu_halt:
+	j cpu_halt
+	nop
+
+.global memcpy_from_uspace
+.global memcpy_to_uspace
+.global memcpy_from_uspace_failover_address
+.global memcpy_to_uspace_failover_address
+memcpy_from_uspace:
+memcpy_to_uspace:
+	move $t2, $a0  /* save dst */
+	
+	addiu $v0, $a1, 3
+	li $v1, -4  /* 0xfffffffffffffffc */
+	and $v0, $v0, $v1
+	beq $a1, $v0, 3f
+	move $t0, $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
+
+memcpy_from_uspace_failover_address:
+memcpy_to_uspace_failover_address:
+	jr $ra
+	move $v0, $zero
+
+.macro fpu_gp_save reg ctx
+	mfc1 $t0, $\reg
+	sw $t0, \reg * 4(\ctx)
+.endm
+
+.macro fpu_gp_restore reg ctx
+	lw $t0, \reg * 4(\ctx)
+	mtc1 $t0, $\reg
+.endm
+
+.macro fpu_ct_save reg ctx
+	cfc1 $t0, $1
+	sw $t0, (\reg + 32) * 4(\ctx)
+.endm
+
+.macro fpu_ct_restore reg ctx
+	lw $t0, (\reg + 32) * 4(\ctx)
+	ctc1 $t0, $\reg
+.endm
+
+.global fpu_context_save
+fpu_context_save:
+#ifdef CONFIG_FPU
+	fpu_gp_save 0, $a0
+	fpu_gp_save 1, $a0
+	fpu_gp_save 2, $a0
+	fpu_gp_save 3, $a0
+	fpu_gp_save 4, $a0
+	fpu_gp_save 5, $a0
+	fpu_gp_save 6, $a0
+	fpu_gp_save 7, $a0
+	fpu_gp_save 8, $a0
+	fpu_gp_save 9, $a0
+	fpu_gp_save 10, $a0
+	fpu_gp_save 11, $a0
+	fpu_gp_save 12, $a0
+	fpu_gp_save 13, $a0
+	fpu_gp_save 14, $a0
+	fpu_gp_save 15, $a0
+	fpu_gp_save 16, $a0
+	fpu_gp_save 17, $a0
+	fpu_gp_save 18, $a0
+	fpu_gp_save 19, $a0
+	fpu_gp_save 20, $a0
+	fpu_gp_save 21, $a0
+	fpu_gp_save 22, $a0
+	fpu_gp_save 23, $a0
+	fpu_gp_save 24, $a0
+	fpu_gp_save 25, $a0
+	fpu_gp_save 26, $a0
+	fpu_gp_save 27, $a0
+	fpu_gp_save 28, $a0
+	fpu_gp_save 29, $a0
+	fpu_gp_save 30, $a0
+	fpu_gp_save 31, $a0
+	
+	fpu_ct_save 1, $a0
+	fpu_ct_save 2, $a0
+	fpu_ct_save 3, $a0
+	fpu_ct_save 4, $a0
+	fpu_ct_save 5, $a0
+	fpu_ct_save 6, $a0
+	fpu_ct_save 7, $a0
+	fpu_ct_save 8, $a0
+	fpu_ct_save 9, $a0
+	fpu_ct_save 10, $a0
+	fpu_ct_save 11, $a0
+	fpu_ct_save 12, $a0
+	fpu_ct_save 13, $a0
+	fpu_ct_save 14, $a0
+	fpu_ct_save 15, $a0
+	fpu_ct_save 16, $a0
+	fpu_ct_save 17, $a0
+	fpu_ct_save 18, $a0
+	fpu_ct_save 19, $a0
+	fpu_ct_save 20, $a0
+	fpu_ct_save 21, $a0
+	fpu_ct_save 22, $a0
+	fpu_ct_save 23, $a0
+	fpu_ct_save 24, $a0
+	fpu_ct_save 25, $a0
+	fpu_ct_save 26, $a0
+	fpu_ct_save 27, $a0
+	fpu_ct_save 28, $a0
+	fpu_ct_save 29, $a0
+	fpu_ct_save 30, $a0
+	fpu_ct_save 31, $a0
+#endif
+	j $ra
+	nop
+
+.global fpu_context_restore
+fpu_context_restore:
+#ifdef CONFIG_FPU
+	fpu_gp_restore 0, $a0
+	fpu_gp_restore 1, $a0
+	fpu_gp_restore 2, $a0
+	fpu_gp_restore 3, $a0
+	fpu_gp_restore 4, $a0
+	fpu_gp_restore 5, $a0
+	fpu_gp_restore 6, $a0
+	fpu_gp_restore 7, $a0
+	fpu_gp_restore 8, $a0
+	fpu_gp_restore 9, $a0
+	fpu_gp_restore 10, $a0
+	fpu_gp_restore 11, $a0
+	fpu_gp_restore 12, $a0
+	fpu_gp_restore 13, $a0
+	fpu_gp_restore 14, $a0
+	fpu_gp_restore 15, $a0
+	fpu_gp_restore 16, $a0
+	fpu_gp_restore 17, $a0
+	fpu_gp_restore 18, $a0
+	fpu_gp_restore 19, $a0
+	fpu_gp_restore 20, $a0
+	fpu_gp_restore 21, $a0
+	fpu_gp_restore 22, $a0
+	fpu_gp_restore 23, $a0
+	fpu_gp_restore 24, $a0
+	fpu_gp_restore 25, $a0
+	fpu_gp_restore 26, $a0
+	fpu_gp_restore 27, $a0
+	fpu_gp_restore 28, $a0
+	fpu_gp_restore 29, $a0
+	fpu_gp_restore 30, $a0
+	fpu_gp_restore 31, $a0
+	
+	fpu_ct_restore 1, $a0
+	fpu_ct_restore 2, $a0
+	fpu_ct_restore 3, $a0
+	fpu_ct_restore 4, $a0
+	fpu_ct_restore 5, $a0
+	fpu_ct_restore 6, $a0
+	fpu_ct_restore 7, $a0
+	fpu_ct_restore 8, $a0
+	fpu_ct_restore 9, $a0
+	fpu_ct_restore 10, $a0
+	fpu_ct_restore 11, $a0
+	fpu_ct_restore 12, $a0
+	fpu_ct_restore 13, $a0
+	fpu_ct_restore 14, $a0
+	fpu_ct_restore 15, $a0
+	fpu_ct_restore 16, $a0
+	fpu_ct_restore 17, $a0
+	fpu_ct_restore 18, $a0
+	fpu_ct_restore 19, $a0
+	fpu_ct_restore 20, $a0
+	fpu_ct_restore 21, $a0
+	fpu_ct_restore 22, $a0
+	fpu_ct_restore 23, $a0
+	fpu_ct_restore 24, $a0
+	fpu_ct_restore 25, $a0
+	fpu_ct_restore 26, $a0
+	fpu_ct_restore 27, $a0
+	fpu_ct_restore 28, $a0
+	fpu_ct_restore 29, $a0
+	fpu_ct_restore 30, $a0
+	fpu_ct_restore 31, $a0
+#endif
+	j $ra
+	nop
+
+.global early_putchar
+early_putchar:
+	j $ra
+	nop
Index: kernel/arch/mips64/src/cache.c
===================================================================
--- kernel/arch/mips64/src/cache.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
+++ kernel/arch/mips64/src/cache.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -0,0 +1,1 @@
+../../mips32/src/cache.c
Index: kernel/arch/mips64/src/context.S
===================================================================
--- kernel/arch/mips64/src/context.S	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
+++ kernel/arch/mips64/src/context.S	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -0,0 +1,1 @@
+../../mips32/src/context.S
Index: kernel/arch/mips64/src/cpu
===================================================================
--- kernel/arch/mips64/src/cpu	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
+++ kernel/arch/mips64/src/cpu	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -0,0 +1,1 @@
+../../mips32/src/cpu
Index: kernel/arch/mips64/src/ddi
===================================================================
--- kernel/arch/mips64/src/ddi	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
+++ kernel/arch/mips64/src/ddi	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -0,0 +1,1 @@
+../../mips32/src/ddi
Index: kernel/arch/mips64/src/debug
===================================================================
--- kernel/arch/mips64/src/debug	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
+++ kernel/arch/mips64/src/debug	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -0,0 +1,1 @@
+../../mips32/src/debug
Index: kernel/arch/mips64/src/debugger.c
===================================================================
--- kernel/arch/mips64/src/debugger.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
+++ kernel/arch/mips64/src/debugger.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -0,0 +1,1 @@
+../../mips32/src/debugger.c
Index: kernel/arch/mips64/src/exception.c
===================================================================
--- kernel/arch/mips64/src/exception.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
+++ kernel/arch/mips64/src/exception.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -0,0 +1,231 @@
+/*
+ * 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.
+ */
+
+/** @addtogroup mips64
+ * @{
+ */
+/** @file
+ */
+
+#include <arch/exception.h>
+#include <arch/interrupt.h>
+#include <arch/mm/tlb.h>
+#include <panic.h>
+#include <arch/cp0.h>
+#include <typedefs.h>
+#include <arch.h>
+#include <debug.h>
+#include <proc/thread.h>
+#include <print.h>
+#include <interrupt.h>
+#include <func.h>
+#include <ddi/irq.h>
+#include <arch/debugger.h>
+#include <symtab.h>
+
+static const char *exctable[] = {
+	"Interrupt",
+	"TLB Modified",
+	"TLB Invalid",
+	"TLB Invalid Store",
+	"Address Error - load/instr. fetch",
+	"Address Error - store",
+	"Bus Error - fetch instruction",
+	"Bus Error - data reference",
+	"Syscall",
+	"BreakPoint",
+	"Reserved Instruction",
+	"Coprocessor Unusable",
+	"Arithmetic Overflow",
+	"Trap",
+	"Virtual Coherency - instruction",
+	"Floating Point",
+	NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+	"WatchHi/WatchLo",  /* 23 */
+	NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+	"Virtual Coherency - data",
+};
+
+void istate_decode(istate_t *istate)
+{
+	printf("epc=%#018" PRIx64 "\tsta=%#018" PRIx64 "\t"
+	    "lo =%#018" PRIx64 "\thi =%#018" PRIx64 "\n",
+	    istate->epc, istate->status, istate->lo, istate->hi);
+	
+	printf("a0 =%#018" PRIx64 "\ta1 =%#018" PRIx64 "\t"
+	    "a2 =%#018" PRIx64 "\ta3 =%#018" PRIx64 "\n",
+	    istate->a0, istate->a1, istate->a2, istate->a3);
+	
+	printf("t0 =%#018" PRIx64 "\tt1 =%#018" PRIx64 "\t"
+	    "t2 =%#018" PRIx64 "\tt3 =%#018" PRIx64 "\n",
+	    istate->t0, istate->t1, istate->t2, istate->t3);
+	
+	printf("t4 =%#018" PRIx64 "\tt5 =%#018" PRIx64 "\t"
+	    "t6 =%#018" PRIx64 "\tt7 =%#018" PRIx64 "\n",
+	    istate->t4, istate->t5, istate->t6, istate->t7);
+	
+	printf("t8 =%#018" PRIx64 "\tt9 =%#018" PRIx64 "\t"
+	    "v0 =%#018" PRIx64 "\tv1 =%#018" PRIx64 "\n",
+	    istate->t8, istate->t9, istate->v0, istate->v1);
+	
+	printf("s0 =%#018" PRIx64 "\ts1 =%#018" PRIx64 "\t"
+	    "s2 =%#018" PRIx64 "\ts3 =%#018" PRIx64 "\n",
+	    istate->s0, istate->s1, istate->s2, istate->s3);
+	
+	printf("s4 =%#018" PRIx64 "\ts5 =%#018" PRIx64 "\t"
+	    "s6 =%#018" PRIx64 "\ts7 =%#018" PRIx64 "\n",
+	    istate->s4, istate->s5, istate->s6, istate->s7);
+	
+	printf("s8 =%#018" PRIx64 "\tat =%#018" PRIx64 "\t"
+	    "kt0=%#018" PRIx64 "\tkt1=%#018" PRIx64 "\n",
+	    istate->s8, istate->at, istate->kt0, istate->kt1);
+	
+	printf("sp =%#018" PRIx64 "\tra =%#018" PRIx64 "\t"
+	    "gp =%#018" PRIx64 "\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]);
+	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->kt1;
+	} else
+		unhandled_exception(n, istate);
+}
+
+static void breakpoint_exception(unsigned int n, istate_t *istate)
+{
+#ifdef CONFIG_DEBUG
+	debugger_bpoint(istate);
+#else
+	/* it is necessary to not re-execute BREAK instruction after 
+	   returning from Exception handler
+	   (see page 138 in R4000 Manual for more information) */
+	istate->epc += 4;
+#endif
+}
+
+static void tlbmod_exception(unsigned int n, istate_t *istate)
+{
+	tlb_modified(istate);
+}
+
+static void tlbinv_exception(unsigned int n, istate_t *istate)
+{
+	tlb_invalid(istate);
+}
+
+#ifdef CONFIG_FPU_LAZY
+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_badtrap(istate, n,
+		    "Unhandled Coprocessor Unusable Exception.");
+	}
+}
+#endif
+
+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)) {
+			irq_t *irq = irq_dispatch_and_lock(i);
+			if (irq) {
+				/*
+				 * The IRQ handler was found.
+				 */
+				irq->handler(irq);
+				irq_spinlock_unlock(&irq->lock, false);
+			} else {
+				/*
+				 * Spurious interrupt.
+				 */
+#ifdef CONFIG_DEBUG
+				printf("cpu%u: spurious interrupt (inum=%u)\n",
+				    CPU->id, i);
+#endif
+			}
+		}
+	}
+}
+
+/** Handle syscall userspace call */
+static void syscall_exception(unsigned int n, istate_t *istate)
+{
+	fault_if_from_uspace(istate, "Syscall is handled through shortcut.");
+}
+
+void exception_init(void)
+{
+	unsigned int i;
+	
+	/* Clear exception table */
+	for (i = 0; i < IVT_ITEMS; i++)
+		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", true,
+	    (iroutine_t) cpuns_exception);
+#endif
+	
+	exc_register(EXC_Sys, "syscall", true,
+	    (iroutine_t) syscall_exception);
+}
+
+/** @}
+ */
Index: kernel/arch/mips64/src/fpu_context.c
===================================================================
--- kernel/arch/mips64/src/fpu_context.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
+++ kernel/arch/mips64/src/fpu_context.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -0,0 +1,1 @@
+../../mips32/src/fpu_context.c
Index: kernel/arch/mips64/src/interrupt.c
===================================================================
--- kernel/arch/mips64/src/interrupt.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
+++ kernel/arch/mips64/src/interrupt.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -0,0 +1,189 @@
+/*
+ * 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.
+ */
+
+/** @addtogroup mips64
+ * @{
+ */
+/** @file
+ */
+
+#include <interrupt.h>
+#include <arch/interrupt.h>
+#include <typedefs.h>
+#include <arch.h>
+#include <arch/cp0.h>
+#include <arch/smp/dorder.h>
+#include <time/clock.h>
+#include <ipc/sysipc.h>
+#include <ddi/device.h>
+
+#define IRQ_COUNT   8
+#define TIMER_IRQ   7
+#define DORDER_IRQ  5
+
+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.
+ *
+ * @return Old interrupt priority level.
+ */
+ipl_t interrupts_disable(void)
+{
+	ipl_t ipl = (ipl_t) cp0_status_read();
+	cp0_status_write(ipl & ~cp0_status_ie_enabled_bit);
+	return ipl;
+}
+
+/** Enable interrupts.
+ *
+ * @return Old interrupt priority level.
+ */
+ipl_t interrupts_enable(void)
+{
+	ipl_t ipl = (ipl_t) cp0_status_read();
+	cp0_status_write(ipl | cp0_status_ie_enabled_bit);
+	return ipl;
+}
+
+/** Restore interrupt priority level.
+ *
+ * @param ipl Saved interrupt priority level.
+ */
+void interrupts_restore(ipl_t ipl)
+{
+	cp0_status_write(cp0_status_read() | (ipl & cp0_status_ie_enabled_bit));
+}
+
+/** Read interrupt priority level.
+ *
+ * @return Current interrupt priority level.
+ */
+ipl_t interrupts_read(void)
+{
+	return cp0_status_read();
+}
+
+/** 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
+ *
+ */
+static void timer_start(void)
+{
+	lastcount = cp0_count_read();
+	nextcount = cp0_compare_value + cp0_count_read();
+	cp0_compare_write(nextcount);
+}
+
+static irq_ownership_t timer_claim(irq_t *irq)
+{
+	return IRQ_ACCEPT;
+}
+
+static void timer_irq_handler(irq_t *irq)
+{
+	if (cp0_count_read() < lastcount)
+		/* Count overflow detected */
+		count_hi++;
+	
+	lastcount = cp0_count_read();
+	
+	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);
+	
+	/*
+	 * We are holding a lock which prevents preemption.
+	 * Release the lock, call clock() and reacquire the lock again.
+	 */
+	irq_spinlock_unlock(&irq->lock, false);
+	clock();
+	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());
+}
+
+/* Initialize basic tables for exception dispatching */
+void interrupt_init(void)
+{
+	irq_init(IRQ_COUNT, IRQ_COUNT);
+	
+	irq_initialize(&timer_irq);
+	timer_irq.devno = device_assign_devno();
+	timer_irq.inr = TIMER_IRQ;
+	timer_irq.claim = timer_claim;
+	timer_irq.handler = timer_irq_handler;
+	irq_register(&timer_irq);
+	
+	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/mips64/src/mips64.c
===================================================================
--- kernel/arch/mips64/src/mips64.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
+++ kernel/arch/mips64/src/mips64.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -0,0 +1,259 @@
+/*
+ * 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.
+ */
+
+/** @addtogroup mips64
+ * @{
+ */
+/** @file
+ */
+
+#include <arch.h>
+#include <arch/cp0.h>
+#include <arch/exception.h>
+#include <arch/debug.h>
+#include <mm/as.h>
+#include <userspace.h>
+#include <memstr.h>
+#include <proc/thread.h>
+#include <proc/uarg.h>
+#include <print.h>
+#include <console/console.h>
+#include <syscall/syscall.h>
+#include <sysinfo/sysinfo.h>
+#include <arch/interrupt.h>
+#include <interrupt.h>
+#include <console/chardev.h>
+#include <arch/barrier.h>
+#include <arch/debugger.h>
+#include <genarch/fb/fb.h>
+#include <genarch/fb/visuals.h>
+#include <genarch/drivers/dsrln/dsrlnin.h>
+#include <genarch/drivers/dsrln/dsrlnout.h>
+#include <genarch/srln/srln.h>
+#include <macros.h>
+#include <config.h>
+#include <str.h>
+#include <arch/drivers/msim.h>
+#include <arch/asm/regname.h>
+
+/* Size of the code jumping to the exception handler code
+ * - J+NOP
+ */
+#define EXCEPTION_JUMP_SIZE  8
+
+#define TLB_EXC    ((char *) 0xffffffff80000000)
+#define NORM_EXC   ((char *) 0xffffffff80000180)
+#define CACHE_EXC  ((char *) 0xffffffff80000100)
+
+
+/* Why the linker moves the variable 64K away in assembler
+ * when not in .text section?
+ */
+
+/* Stack pointer saved when entering user mode */
+uintptr_t supervisor_sp __attribute__ ((section (".text")));
+
+size_t cpu_count = 0;
+
+/** Performs mips64-specific initialization before main_bsp() is called. */
+void arch_pre_main(void *entry __attribute__((unused)), bootinfo_t *bootinfo)
+{
+	init.cnt = min3(bootinfo->cnt, TASKMAP_MAX_RECORDS, CONFIG_INIT_TASKS);
+	
+	size_t i;
+	for (i = 0; i < init.cnt; i++) {
+		init.tasks[i].addr = (uintptr_t) bootinfo->tasks[i].addr;
+		init.tasks[i].size = bootinfo->tasks[i].size;
+		str_cpy(init.tasks[i].name, CONFIG_TASK_NAME_BUFLEN,
+		    bootinfo->tasks[i].name);
+	}
+	
+	for (i = 0; i < CPUMAP_MAX_RECORDS; i++) {
+		if ((bootinfo->cpumap & (1 << i)) != 0)
+			cpu_count++;
+	}
+}
+
+void arch_pre_mm_init(void)
+{
+	/* It is not assumed by default */
+	interrupts_disable();
+	
+	/* Initialize dispatch table */
+	exception_init();
+
+	/* Copy the exception vectors to the right places */
+	memcpy(TLB_EXC, (char *) tlb_refill_entry, EXCEPTION_JUMP_SIZE);
+	smc_coherence_block(TLB_EXC, EXCEPTION_JUMP_SIZE);
+	memcpy(NORM_EXC, (char *) exception_entry, EXCEPTION_JUMP_SIZE);
+	smc_coherence_block(NORM_EXC, EXCEPTION_JUMP_SIZE);
+	memcpy(CACHE_EXC, (char *) cache_error_entry, EXCEPTION_JUMP_SIZE);
+	smc_coherence_block(CACHE_EXC, EXCEPTION_JUMP_SIZE);
+	
+	/*
+	 * Switch to BEV normal level so that exception vectors point to the
+	 * kernel. Clear the error level.
+	 */
+	cp0_status_write(cp0_status_read() &
+	    ~(cp0_status_bev_bootstrap_bit | cp0_status_erl_error_bit));
+	
+	/*
+	 * Mask all interrupts
+	 */
+	cp0_mask_all_int();
+	
+	debugger_init();
+}
+
+void arch_post_mm_init(void)
+{
+	interrupt_init();
+	
+#ifdef CONFIG_MIPS_PRN
+	outdev_t *dsrlndev = dsrlnout_init((ioport8_t *) MSIM_KBD_ADDRESS);
+	if (dsrlndev)
+		stdout_wire(dsrlndev);
+#endif
+}
+
+void arch_post_cpu_init(void)
+{
+}
+
+void arch_pre_smp_init(void)
+{
+}
+
+void arch_post_smp_init(void)
+{
+	static const char *platform;
+	
+	/* Set platform name. */
+#ifdef MACHINE_msim
+	platform = "msim";
+#endif
+	sysinfo_set_item_data("platform", NULL, (void *) platform,
+	    str_size(platform));
+	
+#ifdef CONFIG_MIPS_KBD
+	/*
+	 * Initialize the msim/GXemul keyboard port. Then initialize the serial line
+	 * module and connect it to the msim/GXemul keyboard. Enable keyboard interrupts.
+	 */
+	dsrlnin_instance_t *dsrlnin_instance
+	    = dsrlnin_init((dsrlnin_t *) MSIM_KBD_ADDRESS, MSIM_KBD_IRQ);
+	if (dsrlnin_instance) {
+		srln_instance_t *srln_instance = srln_init();
+		if (srln_instance) {
+			indev_t *sink = stdin_wire();
+			indev_t *srln = srln_wire(srln_instance, sink);
+			dsrlnin_wire(dsrlnin_instance, srln);
+			cp0_unmask_int(MSIM_KBD_IRQ);
+		}
+	}
+	
+	/*
+	 * This is the necessary evil until the userspace driver is entirely
+	 * self-sufficient.
+	 */
+	sysinfo_set_item_val("kbd", NULL, true);
+	sysinfo_set_item_val("kbd.inr", NULL, MSIM_KBD_IRQ);
+	sysinfo_set_item_val("kbd.address.virtual", NULL, MSIM_KBD_ADDRESS);
+#endif
+}
+
+void calibrate_delay_loop(void)
+{
+}
+
+void userspace(uspace_arg_t *kernel_uarg)
+{
+	/* EXL = 1, UM = 1, IE = 1 */
+	cp0_status_write(cp0_status_read() | (cp0_status_exl_exception_bit |
+	    cp0_status_um_bit | cp0_status_ie_enabled_bit));
+	cp0_epc_write((uintptr_t) kernel_uarg->uspace_entry);
+	userspace_asm(((uintptr_t) kernel_uarg->uspace_stack + STACK_SIZE),
+	    (uintptr_t) kernel_uarg->uspace_uarg,
+	    (uintptr_t) kernel_uarg->uspace_entry);
+	
+	while (1);
+}
+
+/** Perform mips64 specific tasks needed before the new task is run. */
+void before_task_runs_arch(void)
+{
+}
+
+/** Perform mips64 specific tasks needed before the new thread is scheduled. */
+void before_thread_runs_arch(void)
+{
+	supervisor_sp =
+	    (uintptr_t) &THREAD->kstack[STACK_SIZE - SP_DELTA];
+}
+
+void after_thread_ran_arch(void)
+{
+}
+
+/** Set thread-local-storage pointer
+ *
+ * We have it currently in K1, it is
+ * possible to have it separately in the future.
+ */
+sysarg_t sys_tls_set(sysarg_t addr)
+{
+	return 0;
+}
+
+void arch_reboot(void)
+{
+	___halt();
+	while (1);
+}
+
+/** Construct function pointer
+ *
+ * @param fptr   function pointer structure
+ * @param addr   function address
+ * @param caller calling function address
+ *
+ * @return address of the function pointer
+ *
+ */
+void *arch_construct_function(fncptr_t *fptr, void *addr, void *caller)
+{
+	return addr;
+}
+
+void irq_initialize_arch(irq_t *irq)
+{
+	(void) irq;
+}
+
+/** @}
+ */
Index: kernel/arch/mips64/src/mm/as.c
===================================================================
--- kernel/arch/mips64/src/mm/as.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
+++ kernel/arch/mips64/src/mm/as.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -0,0 +1,70 @@
+/*
+ * 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 mips64mm
+ * @{
+ */
+/** @file
+ */
+
+#include <arch/mm/as.h>
+#include <genarch/mm/as_ht.h>
+#include <genarch/mm/page_ht.h>
+#include <genarch/mm/asid_fifo.h>
+#include <arch/mm/tlb.h>
+#include <mm/tlb.h>
+#include <mm/as.h>
+#include <arch/cp0.h>
+
+/** Architecture dependent address space init. */
+void as_arch_init(void)
+{
+	as_operations = &as_ht_operations;
+	asid_fifo_init();
+}
+
+/** Install address space.
+ *
+ * Install ASID.
+ *
+ * @param as Address space structure.
+ *
+ */
+void as_install_arch(as_t *as)
+{
+	/*
+	 * Install ASID.
+	 */
+	entry_hi_t hi;
+	hi.value = cp0_entry_hi_read();
+	hi.asid = as->asid;
+	cp0_entry_hi_write(hi.value);
+}
+
+/** @}
+ */
Index: kernel/arch/mips64/src/mm/frame.c
===================================================================
--- kernel/arch/mips64/src/mm/frame.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
+++ kernel/arch/mips64/src/mm/frame.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -0,0 +1,242 @@
+/*
+ * 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 mips64mm
+ * @{
+ */
+/** @file
+ */
+
+#include <macros.h>
+#include <arch/mm/frame.h>
+#include <arch/mm/tlb.h>
+#include <interrupt.h>
+#include <mm/frame.h>
+#include <mm/asid.h>
+#include <config.h>
+#include <arch/drivers/msim.h>
+#include <print.h>
+
+#define ZERO_PAGE_MASK    TLB_PAGE_MASK_256K
+#define ZERO_FRAMES       2048
+#define ZERO_PAGE_WIDTH   18  /* 256K */
+#define ZERO_PAGE_SIZE    (1 << ZERO_PAGE_WIDTH)
+#define ZERO_PAGE_ASID    ASID_INVALID
+#define ZERO_PAGE_TLBI    0
+#define ZERO_PAGE_ADDR    0
+#define ZERO_PAGE_OFFSET  (ZERO_PAGE_SIZE / sizeof(uint32_t) - 1)
+#define ZERO_PAGE_VALUE   (((volatile uint32_t *) ZERO_PAGE_ADDR)[ZERO_PAGE_OFFSET])
+
+#define ZERO_PAGE_VALUE_KSEG1(frame) \
+	(((volatile uint32_t *) (0xa0000000 + (frame << ZERO_PAGE_WIDTH)))[ZERO_PAGE_OFFSET])
+
+#define MAX_REGIONS  32
+
+typedef struct {
+	pfn_t start;
+	pfn_t count;
+} phys_region_t;
+
+static size_t phys_regions_count = 0;
+static phys_region_t phys_regions[MAX_REGIONS];
+
+/** Check whether frame is available
+ *
+ * Returns true if given frame is generally available for use.
+ * Returns false if given frame is used for physical memory
+ * mapped devices and cannot be used.
+ *
+ */
+static bool frame_available(pfn_t frame)
+{
+#ifdef MACHINE_msim
+	/* MSIM device (dprinter) */
+	if (frame == (KA2PA(MSIM_VIDEORAM) >> ZERO_PAGE_WIDTH))
+		return false;
+	
+	/* MSIM device (dkeyboard) */
+	if (frame == (KA2PA(MSIM_KBD_ADDRESS) >> ZERO_PAGE_WIDTH))
+		return false;
+#endif
+	
+	return true;
+}
+
+/** Check whether frame is safe to write
+ *
+ * Returns true if given frame is safe for read/write test.
+ * Returns false if given frame should not be touched.
+ *
+ */
+static bool frame_safe(pfn_t frame)
+{
+	/* Kernel structures */
+	if ((frame << ZERO_PAGE_WIDTH) < KA2PA(config.base))
+		return false;
+	
+	/* Kernel */
+	if (overlaps(frame << ZERO_PAGE_WIDTH, ZERO_PAGE_SIZE,
+	    KA2PA(config.base), config.kernel_size))
+		return false;
+	
+	/* Kernel stack */
+	if (overlaps(frame << ZERO_PAGE_WIDTH, ZERO_PAGE_SIZE,
+	    KA2PA(config.stack_base), config.stack_size))
+		return false;
+	
+	/* Init tasks */
+	bool safe = true;
+	size_t i;
+	for (i = 0; i < init.cnt; i++)
+		if (overlaps(frame << ZERO_PAGE_WIDTH, ZERO_PAGE_SIZE,
+		    KA2PA(init.tasks[i].addr), init.tasks[i].size)) {
+			safe = false;
+			break;
+		}
+	
+	return safe;
+}
+
+static void frame_add_region(pfn_t start_frame, pfn_t end_frame)
+{
+	if (end_frame > start_frame) {
+		/* Convert 1M frames to 16K frames */
+		pfn_t first = ADDR2PFN(start_frame << ZERO_PAGE_WIDTH);
+		pfn_t count = ADDR2PFN((end_frame - start_frame) << ZERO_PAGE_WIDTH);
+		
+		/* Interrupt vector frame is blacklisted */
+		pfn_t conf_frame;
+		if (first == 0)
+			conf_frame = 1;
+		else
+			conf_frame = first;
+		
+		zone_create(first, count, conf_frame, 0);
+		
+		if (phys_regions_count < MAX_REGIONS) {
+			phys_regions[phys_regions_count].start = first;
+			phys_regions[phys_regions_count].count = count;
+			phys_regions_count++;
+		}
+	}
+}
+
+/** Create memory zones
+ *
+ * Walk through available 256 KB chunks of physical
+ * memory and create zones.
+ *
+ * Note: It is assumed that the TLB is not yet being
+ * used in any way, thus there is no interference.
+ *
+ */
+void frame_arch_init(void)
+{
+	ipl_t ipl = interrupts_disable();
+	
+	/* Clear and initialize TLB */
+	cp0_pagemask_write(ZERO_PAGE_MASK);
+	cp0_entry_lo0_write(0);
+	cp0_entry_lo1_write(0);
+	cp0_entry_hi_write(0);
+	
+	for (size_t i = 0; i < TLB_ENTRY_COUNT; i++) {
+		cp0_index_write(i);
+		tlbwi();
+	}
+	
+	pfn_t start_frame = 0;
+	pfn_t frame;
+	bool avail = true;
+	
+	/* Walk through all 1 MB frames */
+	for (frame = 0; frame < ZERO_FRAMES; frame++) {
+		if (!frame_available(frame))
+			avail = false;
+		else {
+			if (frame_safe(frame)) {
+				entry_lo_t lo0;
+				entry_lo_t lo1;
+				entry_hi_t hi;
+				tlb_prepare_entry_lo(&lo0, false, true, true, false, frame << (ZERO_PAGE_WIDTH - 12));
+				tlb_prepare_entry_lo(&lo1, false, false, false, false, 0);
+				tlb_prepare_entry_hi(&hi, ZERO_PAGE_ASID, ZERO_PAGE_ADDR);
+				
+				cp0_pagemask_write(ZERO_PAGE_MASK);
+				cp0_entry_lo0_write(lo0.value);
+				cp0_entry_lo1_write(lo1.value);
+				cp0_entry_hi_write(hi.value);
+				cp0_index_write(ZERO_PAGE_TLBI);
+				tlbwi();
+				
+				ZERO_PAGE_VALUE = 0;
+				if (ZERO_PAGE_VALUE != 0)
+					avail = false;
+				else {
+					ZERO_PAGE_VALUE = 0xdeadbeef;
+					if (ZERO_PAGE_VALUE != 0xdeadbeef)
+						avail = false;
+				}
+			}
+		}
+		
+		if (!avail) {
+			frame_add_region(start_frame, frame);
+			start_frame = frame + 1;
+			avail = true;
+		}
+	}
+	
+	frame_add_region(start_frame, frame);
+	
+	/* Blacklist interrupt vector frame */
+	frame_mark_unavailable(0, 1);
+	
+	/* Cleanup */
+	cp0_pagemask_write(ZERO_PAGE_MASK);
+	cp0_entry_lo0_write(0);
+	cp0_entry_lo1_write(0);
+	cp0_entry_hi_write(0);
+	cp0_index_write(ZERO_PAGE_TLBI);
+	tlbwi();
+	
+	interrupts_restore(ipl);
+}
+
+void physmem_print(void)
+{
+	printf("[base            ] [size            ]\n");
+	
+	for (size_t i = 0; i < phys_regions_count; i++) {
+		printf("%#018lx %18lu\n", PFN2ADDR(phys_regions[i].start),
+		    PFN2ADDR(phys_regions[i].count));
+	}
+}
+
+/** @}
+ */
Index: kernel/arch/mips64/src/mm/page.c
===================================================================
--- kernel/arch/mips64/src/mm/page.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
+++ kernel/arch/mips64/src/mm/page.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -0,0 +1,55 @@
+/*
+ * 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.
+ */
+
+/** @addtogroup mips64mm
+ * @{
+ */
+/** @file
+ */
+
+#include <arch/mm/page.h>
+#include <genarch/mm/page_ht.h>
+#include <mm/page.h>
+#include <mm/frame.h>
+
+void page_arch_init(void)
+{
+	page_mapping_operations = &ht_mapping_operations;
+}
+
+/** Map device into kernel space
+ * - on mips, all devices are already mapped into kernel space,
+ *   translate the physical address to uncached area
+ */
+uintptr_t hw_map(uintptr_t physaddr, size_t size)
+{
+	return physaddr + 0xffffffffa0000000;
+}
+
+/** @}
+ */
Index: kernel/arch/mips64/src/mm/tlb.c
===================================================================
--- kernel/arch/mips64/src/mm/tlb.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
+++ kernel/arch/mips64/src/mm/tlb.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -0,0 +1,573 @@
+/*
+ * 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.
+ */
+
+/** @addtogroup mips64mm
+ * @{
+ */
+/** @file
+ */
+
+#include <arch/mm/tlb.h>
+#include <mm/asid.h>
+#include <mm/tlb.h>
+#include <mm/page.h>
+#include <mm/as.h>
+#include <arch/cp0.h>
+#include <panic.h>
+#include <arch.h>
+#include <synch/mutex.h>
+#include <print.h>
+#include <debug.h>
+#include <align.h>
+#include <interrupt.h>
+#include <symtab.h>
+
+/** Initialize TLB.
+ *
+ * Invalidate all entries and mark wired entries.
+ *
+ */
+void tlb_arch_init(void)
+{
+	cp0_pagemask_write(TLB_PAGE_MASK_16K);
+	cp0_entry_hi_write(0);
+	cp0_entry_lo0_write(0);
+	cp0_entry_lo1_write(0);
+	
+	/* Clear and initialize TLB. */
+	
+	for (unsigned int i = 0; i < TLB_ENTRY_COUNT; i++) {
+		cp0_index_write(i);
+		tlbwi();
+	}
+	
+	/*
+	 * The kernel is going to make use of some wired
+	 * entries (e.g. mapping kernel stacks in kseg3).
+	 */
+	cp0_wired_write(TLB_WIRED);
+}
+
+/** Try to find PTE for faulting address.
+ *
+ * @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(uintptr_t badvaddr, int access,
+    istate_t *istate, int *pfrc)
+{
+	entry_hi_t hi;
+	hi.value = cp0_entry_hi_read();
+	
+	/*
+	 * Handler cannot succeed if the ASIDs don't match.
+	 */
+	if (hi.asid != AS->asid) {
+		printf("EntryHi.asid=%d, AS->asid=%d\n", hi.asid, AS->asid);
+		return NULL;
+	}
+	
+	/*
+	 * Check if the mapping exists in page tables.
+	 */
+	pte_t *pte = page_mapping_find(AS, badvaddr, true);
+	if ((pte) && (pte->p) && ((pte->w) || (access != PF_ACCESS_WRITE))) {
+		/*
+		 * Mapping found in page tables.
+		 * Immediately succeed.
+		 */
+		return pte;
+	} else {
+		int rc;
+		
+		/*
+		 * Mapping not found in page tables.
+		 * Resort to higher-level page fault handler.
+		 */
+		switch (rc = as_page_fault(badvaddr, access, istate)) {
+		case AS_PF_OK:
+			/*
+			 * The higher-level page fault handler succeeded,
+			 * The mapping ought to be in place.
+			 */
+			pte = page_mapping_find(AS, badvaddr, true);
+			ASSERT(pte);
+			ASSERT(pte->p);
+			ASSERT((pte->w) || (access != PF_ACCESS_WRITE));
+			return pte;
+		case AS_PF_DEFER:
+			*pfrc = AS_PF_DEFER;
+			return NULL;
+		case AS_PF_FAULT:
+			*pfrc = AS_PF_FAULT;
+			return NULL;
+		default:
+			panic("Unexpected return code (%d).", rc);
+		}
+	}
+}
+
+void tlb_prepare_entry_lo(entry_lo_t *lo, bool g, bool v, bool d,
+    bool c, uintptr_t addr)
+{
+	lo->value = 0;
+	lo->g = g;
+	lo->v = v;
+	lo->d = d;
+	lo->c = c ? PAGE_CACHEABLE_EXC_WRITE : PAGE_UNCACHED;
+	lo->pfn = ADDR2PFN(addr);
+}
+
+void tlb_prepare_entry_hi(entry_hi_t *hi, asid_t asid, uintptr_t addr)
+{
+	hi->value = ALIGN_DOWN(addr, PAGE_SIZE * 2);
+	hi->asid = asid;
+}
+
+static void tlb_refill_fail(istate_t *istate)
+{
+	uintptr_t va = cp0_badvaddr_read();
+	
+	fault_if_from_uspace(istate, "TLB Refill Exception on %p.",
+	    (void *) va);
+	panic_memtrap(istate, PF_ACCESS_UNKNOWN, va, "TLB Refill Exception.");
+}
+
+static void tlb_invalid_fail(istate_t *istate)
+{
+	uintptr_t va = cp0_badvaddr_read();
+	
+	fault_if_from_uspace(istate, "TLB Invalid Exception on %p.",
+	    (void *) va);
+	panic_memtrap(istate, PF_ACCESS_UNKNOWN, va, "TLB Invalid Exception.");
+}
+
+static void tlb_modified_fail(istate_t *istate)
+{
+	uintptr_t va = cp0_badvaddr_read();
+	
+	fault_if_from_uspace(istate, "TLB Modified Exception on %p.",
+	    (void *) va);
+	panic_memtrap(istate, PF_ACCESS_WRITE, va, "TLB Modified Exception.");
+}
+
+/** Process TLB Refill Exception.
+ *
+ * @param istate Interrupted register context.
+ *
+ */
+void tlb_refill(istate_t *istate)
+{
+	uintptr_t badvaddr = cp0_badvaddr_read();
+	
+	mutex_lock(&AS->lock);
+	asid_t asid = AS->asid;
+	mutex_unlock(&AS->lock);
+	
+	int pfrc;
+	pte_t *pte = find_mapping_and_check(badvaddr, PF_ACCESS_READ,
+	    istate, &pfrc);
+	if (!pte) {
+		switch (pfrc) {
+		case AS_PF_FAULT:
+			goto fail;
+			break;
+		case AS_PF_DEFER:
+			/*
+			 * The page fault came during copy_from_uspace()
+			 * or copy_to_uspace().
+			 */
+			return;
+		default:
+			panic("Unexpected pfrc (%d).", pfrc);
+		}
+	}
+	
+	/*
+	 * Record access to PTE.
+	 */
+	pte->a = 1;
+	
+	entry_lo_t lo;
+	entry_hi_t hi;
+	
+	tlb_prepare_entry_hi(&hi, asid, badvaddr);
+	tlb_prepare_entry_lo(&lo, pte->g, pte->p, pte->d, pte->c,
+	    pte->frame);
+	
+	/*
+	 * New entry is to be inserted into TLB
+	 */
+	cp0_entry_hi_write(hi.value);
+	
+	if ((badvaddr / PAGE_SIZE) % 2 == 0) {
+		cp0_entry_lo0_write(lo.value);
+		cp0_entry_lo1_write(0);
+	} else {
+		cp0_entry_lo0_write(0);
+		cp0_entry_lo1_write(lo.value);
+	}
+	
+	cp0_pagemask_write(TLB_PAGE_MASK_16K);
+	tlbwr();
+	
+	return;
+	
+fail:
+	tlb_refill_fail(istate);
+}
+
+/** Process TLB Invalid Exception.
+ *
+ * @param istate Interrupted register context.
+ *
+ */
+void tlb_invalid(istate_t *istate)
+{
+	uintptr_t badvaddr = cp0_badvaddr_read();
+	
+	/*
+	 * Locate the faulting entry in TLB.
+	 */
+	entry_hi_t hi;
+	hi.value = cp0_entry_hi_read();
+	
+	tlb_prepare_entry_hi(&hi, hi.asid, badvaddr);
+	cp0_entry_hi_write(hi.value);
+	tlbp();
+	
+	tlb_index_t index;
+	index.value = cp0_index_read();
+	
+	/*
+	 * Fail if the entry is not in TLB.
+	 */
+	if (index.p) {
+		printf("TLB entry not found.\n");
+		goto fail;
+	}
+	
+	int pfrc;
+	pte_t *pte = find_mapping_and_check(badvaddr, PF_ACCESS_READ,
+	    istate, &pfrc);
+	if (!pte) {
+		switch (pfrc) {
+		case AS_PF_FAULT:
+			goto fail;
+			break;
+		case AS_PF_DEFER:
+			/*
+			 * The page fault came during copy_from_uspace()
+			 * or copy_to_uspace().
+			 */
+			return;
+		default:
+			panic("Unexpected pfrc (%d).", pfrc);
+		}
+	}
+	
+	/*
+	 * Read the faulting TLB entry.
+	 */
+	tlbr();
+	
+	/*
+	 * Record access to PTE.
+	 */
+	pte->a = 1;
+	
+	entry_lo_t lo;
+	tlb_prepare_entry_lo(&lo, pte->g, pte->p, pte->d, pte->c,
+	    pte->frame);
+	
+	/*
+	 * The entry is to be updated in TLB.
+	 */
+	if ((badvaddr / PAGE_SIZE) % 2 == 0)
+		cp0_entry_lo0_write(lo.value);
+	else
+		cp0_entry_lo1_write(lo.value);
+	
+	cp0_pagemask_write(TLB_PAGE_MASK_16K);
+	tlbwi();
+	
+	return;
+	
+fail:
+	tlb_invalid_fail(istate);
+}
+
+/** Process TLB Modified Exception.
+ *
+ * @param istate Interrupted register context.
+ *
+ */
+void tlb_modified(istate_t *istate)
+{
+	uintptr_t badvaddr = cp0_badvaddr_read();
+	
+	/*
+	 * Locate the faulting entry in TLB.
+	 */
+	entry_hi_t hi;
+	hi.value = cp0_entry_hi_read();
+	
+	tlb_prepare_entry_hi(&hi, hi.asid, badvaddr);
+	cp0_entry_hi_write(hi.value);
+	tlbp();
+	
+	tlb_index_t index;
+	index.value = cp0_index_read();
+	
+	/*
+	 * Fail if the entry is not in TLB.
+	 */
+	if (index.p) {
+		printf("TLB entry not found.\n");
+		goto fail;
+	}
+	
+	int pfrc;
+	pte_t *pte = find_mapping_and_check(badvaddr, PF_ACCESS_WRITE,
+	    istate, &pfrc);
+	if (!pte) {
+		switch (pfrc) {
+		case AS_PF_FAULT:
+			goto fail;
+			break;
+		case AS_PF_DEFER:
+			/*
+			 * The page fault came during copy_from_uspace()
+			 * or copy_to_uspace().
+			 */
+			return;
+		default:
+			panic("Unexpected pfrc (%d).", pfrc);
+		}
+	}
+	
+	/*
+	 * Read the faulting TLB entry.
+	 */
+	tlbr();
+	
+	/*
+	 * Record access and write to PTE.
+	 */
+	pte->a = 1;
+	pte->d = 1;
+	
+	entry_lo_t lo;
+	tlb_prepare_entry_lo(&lo, pte->g, pte->p, pte->w, pte->c,
+	    pte->frame);
+	
+	/*
+	 * The entry is to be updated in TLB.
+	 */
+	if ((badvaddr / PAGE_SIZE) % 2 == 0)
+		cp0_entry_lo0_write(lo.value);
+	else
+		cp0_entry_lo1_write(lo.value);
+	
+	cp0_pagemask_write(TLB_PAGE_MASK_16K);
+	tlbwi();
+	
+	return;
+	
+fail:
+	tlb_modified_fail(istate);
+}
+
+/** Print contents of TLB. */
+void tlb_print(void)
+{
+	entry_hi_t hi_save;
+	hi_save.value = cp0_entry_hi_read();
+	
+	printf("[nr] [asid] [vpn2] [mask] [gvdc] [pfn ]\n");
+	
+	for (unsigned int i = 0; i < TLB_ENTRY_COUNT; i++) {
+		cp0_index_write(i);
+		tlbr();
+		
+		page_mask_t mask;
+		mask.value = cp0_pagemask_read();
+		
+		entry_hi_t hi;
+		hi.value = cp0_entry_hi_read();
+		
+		entry_lo_t lo0;
+		lo0.value = cp0_entry_lo0_read();
+		
+		entry_lo_t lo1;
+		lo1.value = cp0_entry_lo1_read();
+		
+		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",
+		    lo1.g, lo1.v, lo1.d, lo1.c, lo1.pfn);
+	}
+	
+	cp0_entry_hi_write(hi_save.value);
+}
+
+/** Invalidate all not wired TLB entries. */
+void tlb_invalidate_all(void)
+{
+	entry_hi_t hi_save;
+	hi_save.value = cp0_entry_hi_read();
+	ipl_t ipl = interrupts_disable();
+	
+	for (unsigned int i = TLB_WIRED; i < TLB_ENTRY_COUNT; i++) {
+		cp0_index_write(i);
+		tlbr();
+		
+		entry_lo_t lo0;
+		lo0.value = cp0_entry_lo0_read();
+		
+		entry_lo_t lo1;
+		lo1.value = cp0_entry_lo1_read();
+		
+		lo0.v = 0;
+		lo1.v = 0;
+		
+		cp0_entry_lo0_write(lo0.value);
+		cp0_entry_lo1_write(lo1.value);
+		
+		tlbwi();
+	}
+	
+	interrupts_restore(ipl);
+	cp0_entry_hi_write(hi_save.value);
+}
+
+/** Invalidate all TLB entries belonging to specified address space.
+ *
+ * @param asid Address space identifier.
+ *
+ */
+void tlb_invalidate_asid(asid_t asid)
+{
+	ASSERT(asid != ASID_INVALID);
+	
+	entry_hi_t hi_save;
+	hi_save.value = cp0_entry_hi_read();
+	ipl_t ipl = interrupts_disable();
+	
+	for (unsigned int i = 0; i < TLB_ENTRY_COUNT; i++) {
+		cp0_index_write(i);
+		tlbr();
+		
+		entry_hi_t hi;
+		hi.value = cp0_entry_hi_read();
+		
+		if (hi.asid == asid) {
+			entry_lo_t lo0;
+			lo0.value = cp0_entry_lo0_read();
+			
+			entry_lo_t lo1;
+			lo1.value = cp0_entry_lo1_read();
+			
+			lo0.v = 0;
+			lo1.v = 0;
+			
+			cp0_entry_lo0_write(lo0.value);
+			cp0_entry_lo1_write(lo1.value);
+			
+			tlbwi();
+		}
+	}
+	
+	interrupts_restore(ipl);
+	cp0_entry_hi_write(hi_save.value);
+}
+
+/** Invalidate TLB entries for specified page range belonging to specified
+ * address space.
+ *
+ * @param asid Address space identifier.
+ * @param page First page whose TLB entry is to be invalidated.
+ * @param cnt  Number of entries to invalidate.
+ *
+ */
+void tlb_invalidate_pages(asid_t asid, uintptr_t page, size_t cnt)
+{
+	if (asid == ASID_INVALID)
+		return;
+	
+	entry_hi_t hi_save;
+	hi_save.value = cp0_entry_hi_read();
+	ipl_t ipl = interrupts_disable();
+	
+	for (unsigned int i = 0; i < cnt + 1; i += 2) {
+		entry_hi_t hi;
+		hi.value = 0;
+		tlb_prepare_entry_hi(&hi, asid, page + i * PAGE_SIZE);
+		cp0_entry_hi_write(hi.value);
+		
+		tlbp();
+		
+		tlb_index_t index;
+		index.value = cp0_index_read();
+		
+		if (!index.p) {
+			/*
+			 * Entry was found, index register contains valid
+			 * index.
+			 */
+			tlbr();
+			
+			entry_lo_t lo0;
+			lo0.value = cp0_entry_lo0_read();
+			
+			entry_lo_t lo1;
+			lo1.value = cp0_entry_lo1_read();
+			
+			lo0.v = 0;
+			lo1.v = 0;
+			
+			cp0_entry_lo0_write(lo0.value);
+			cp0_entry_lo1_write(lo1.value);
+			
+			tlbwi();
+		}
+	}
+	
+	interrupts_restore(ipl);
+	cp0_entry_hi_write(hi_save.value);
+}
+
+/** @}
+ */
Index: kernel/arch/mips64/src/smp/dorder.c
===================================================================
--- kernel/arch/mips64/src/smp/dorder.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
+++ kernel/arch/mips64/src/smp/dorder.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -0,0 +1,61 @@
+/*
+ * 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 mips64
+ * @{
+ */
+/** @file
+ */
+
+#include <typedefs.h>
+#include <smp/ipi.h>
+#include <arch/smp/dorder.h>
+
+#define MSIM_DORDER_ADDRESS  0xffffffffb0000100
+
+#ifdef CONFIG_SMP
+
+void ipi_broadcast_arch(int ipi)
+{
+	*((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/mips64/src/smp/smp.c
===================================================================
--- kernel/arch/mips64/src/smp/smp.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
+++ kernel/arch/mips64/src/smp/smp.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2009 Martin Decky
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup mips64
+ * @{
+ */
+/** @file
+ */
+
+#include <config.h>
+#include <smp/smp.h>
+#include <arch/arch.h>
+
+#ifdef CONFIG_SMP
+
+void smp_init(void)
+{
+	config.cpu_count = cpu_count;
+}
+
+void kmp(void *arg __attribute__((unused)))
+{
+}
+
+#endif /* CONFIG_SMP */
+
+/** @}
+ */
Index: kernel/arch/mips64/src/start.S
===================================================================
--- kernel/arch/mips64/src/start.S	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
+++ kernel/arch/mips64/src/start.S	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -0,0 +1,385 @@
+#
+# Copyright (c) 2003-2004 Jakub Jermar
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# - Redistributions of source code must retain the above copyright
+#   notice, this list of conditions and the following disclaimer.
+# - Redistributions in binary form must reproduce the above copyright
+#   notice, this list of conditions and the following disclaimer in the
+#   documentation and/or other materials provided with the distribution.
+# - The name of the author may not be used to endorse or promote products
+#   derived from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+
+#include <arch/asm/regname.h>
+#include <arch/mm/page.h>
+#include <arch/asm/boot.h>
+#include <arch/context_offset.h>
+#include <arch/stack.h>
+
+.text
+
+.set noat
+.set noreorder
+.set nomacro
+
+.global kernel_image_start
+.global tlb_refill_entry
+.global cache_error_entry
+.global exception_entry
+.global userspace_asm
+
+/*
+ * 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         8
+#define ISTATE_OFFSET_A2         16
+#define ISTATE_OFFSET_A3         24
+#define ISTATE_OFFSET_T0         32
+#define ISTATE_OFFSET_T1         40
+#define ISTATE_OFFSET_V0         48
+#define ISTATE_OFFSET_V1         56
+#define ISTATE_OFFSET_AT         64
+#define ISTATE_OFFSET_T2         72
+#define ISTATE_OFFSET_T3         80
+#define ISTATE_OFFSET_T4         88
+#define ISTATE_OFFSET_T5         96
+#define ISTATE_OFFSET_T6         104
+#define ISTATE_OFFSET_T7         112
+#define ISTATE_OFFSET_S0         120
+#define ISTATE_OFFSET_S1         128
+#define ISTATE_OFFSET_S2         136
+#define ISTATE_OFFSET_S3         144
+#define ISTATE_OFFSET_S4         152
+#define ISTATE_OFFSET_S5         160
+#define ISTATE_OFFSET_S6         168
+#define ISTATE_OFFSET_S7         176
+#define ISTATE_OFFSET_T8         184
+#define ISTATE_OFFSET_T9         192
+#define ISTATE_OFFSET_KT0        200
+#define ISTATE_OFFSET_KT1        208
+#define ISTATE_OFFSET_GP         216
+#define ISTATE_OFFSET_SP         224
+#define ISTATE_OFFSET_S8         232
+#define ISTATE_OFFSET_RA         240
+#define ISTATE_OFFSET_LO         248
+#define ISTATE_OFFSET_HI         252
+#define ISTATE_OFFSET_STATUS     256
+#define ISTATE_OFFSET_EPC        264
+#define ISTATE_OFFSET_ALIGNMENT  272
+
+#define ISTATE_SOFT_SIZE         280
+
+/*
+ * 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
+	sd $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
+	sd $at, ISTATE_OFFSET_AT(\r)
+	sd $v0, ISTATE_OFFSET_V0(\r)
+	sd $v1, ISTATE_OFFSET_V1(\r)
+	sd $a0, ISTATE_OFFSET_A0(\r)
+	sd $a1, ISTATE_OFFSET_A1(\r)
+	sd $a2, ISTATE_OFFSET_A2(\r)
+	sd $a3, ISTATE_OFFSET_A3(\r)
+	sd $t0, ISTATE_OFFSET_T0(\r)
+	sd $t1, ISTATE_OFFSET_T1(\r)
+	sd $t2, ISTATE_OFFSET_T2(\r)
+	sd $t3, ISTATE_OFFSET_T3(\r)
+	sd $t4, ISTATE_OFFSET_T4(\r)
+	sd $t5, ISTATE_OFFSET_T5(\r)
+	sd $t6, ISTATE_OFFSET_T6(\r)
+	sd $t7, ISTATE_OFFSET_T7(\r)
+	sd $t8, ISTATE_OFFSET_T8(\r)
+	sd $t9, ISTATE_OFFSET_T9(\r)
+	sd $s0, ISTATE_OFFSET_S0(\r)
+	sd $s1, ISTATE_OFFSET_S1(\r)
+	sd $s2, ISTATE_OFFSET_S2(\r)
+	sd $s3, ISTATE_OFFSET_S3(\r)
+	sd $s4, ISTATE_OFFSET_S4(\r)
+	sd $s5, ISTATE_OFFSET_S5(\r)
+	sd $s6, ISTATE_OFFSET_S6(\r)
+	sd $s7, ISTATE_OFFSET_S7(\r)
+	sd $s8, ISTATE_OFFSET_S8(\r)
+	
+	mflo $at
+	sw $at, ISTATE_OFFSET_LO(\r)
+	mfhi $at
+	sw $at, ISTATE_OFFSET_HI(\r)
+	
+	sd $gp, ISTATE_OFFSET_GP(\r)
+	sd $ra, ISTATE_OFFSET_RA(\r)
+	sd $k0, ISTATE_OFFSET_KT0(\r)
+	sd $k1, ISTATE_OFFSET_KT1(\r)
+	
+	dmfc0 $t0, $status
+	dmfc0 $t1, $epc
+	
+	/* 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
+	
+	sd $t2, ISTATE_OFFSET_STATUS(\r)
+	sd $t1, ISTATE_OFFSET_EPC(\r)
+	dmtc0 $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.
+	 */
+	dmfc0 $t0, $status
+	ld $t1, ISTATE_OFFSET_STATUS(\r)
+	
+	/* mask UM, EXL, ERL, IE */
+	li $t2, ~REG_SAVE_MASK
+	and $t0, $t0, $t2
+	
+	/* copy UM, EXL, ERL, IE from saved status */
+	or $t0, $t0, $t1
+	dmtc0 $t0, $status
+	
+	ld $v0, ISTATE_OFFSET_V0(\r)
+	ld $v1, ISTATE_OFFSET_V1(\r)
+	ld $a0, ISTATE_OFFSET_A0(\r)
+	ld $a1, ISTATE_OFFSET_A1(\r)
+	ld $a2, ISTATE_OFFSET_A2(\r)
+	ld $a3, ISTATE_OFFSET_A3(\r)
+	ld $t0, ISTATE_OFFSET_T0(\r)
+	ld $t1, ISTATE_OFFSET_T1(\r)
+	ld $t2, ISTATE_OFFSET_T2(\r)
+	ld $t3, ISTATE_OFFSET_T3(\r)
+	ld $t4, ISTATE_OFFSET_T4(\r)
+	ld $t5, ISTATE_OFFSET_T5(\r)
+	ld $t6, ISTATE_OFFSET_T6(\r)
+	ld $t7, ISTATE_OFFSET_T7(\r)
+	ld $t8, ISTATE_OFFSET_T8(\r)
+	ld $t9, ISTATE_OFFSET_T9(\r)
+	
+	ld $gp, ISTATE_OFFSET_GP(\r)
+	ld $ra, ISTATE_OFFSET_RA(\r)
+	ld $k1, ISTATE_OFFSET_KT1(\r)
+	
+	lw $at, ISTATE_OFFSET_LO(\r)
+	mtlo $at
+	lw $at, ISTATE_OFFSET_HI(\r)
+	mthi $at
+	
+	ld $at, ISTATE_OFFSET_EPC(\r)
+	dmtc0 $at, $epc
+	
+	ld $at, ISTATE_OFFSET_AT(\r)
+	ld $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.
+ */
+.macro KERNEL_STACK_TO_K0
+	/* if we are in user mode */
+	dmfc0 $k0, $status
+	andi $k0, 0x10
+	
+	beq $k0, $0, 1f
+	move $k0, $sp
+	
+	/* move $k0 pointer to kernel stack */
+	dla $k0, supervisor_sp
+	
+	/* move $k0 (supervisor_sp) */
+	lw $k0, ($k0)
+	
+	1:
+.endm
+
+.org 0x0
+kernel_image_start:
+	/* 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 */
+	lui $gp, 0x8000
+	
+	/* $a1 contains physical address of bootinfo_t */
+	jal arch_pre_main
+	nop
+	
+	j main_bsp
+	nop
+
+.space TEMP_STACK_SIZE
+end_stack:
+
+tlb_refill_entry:
+	j tlb_refill_handler
+	nop
+
+cache_error_entry:
+	j cache_error_handler
+	nop
+
+exception_entry:
+	j exception_handler
+	nop
+
+	FAKE_ABI_PROLOGUE
+exception_handler:
+	KERNEL_STACK_TO_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 */
+	
+	beqz $k0, syscall_shortcut
+	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) */
+	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.
+ *
+ */
+syscall_shortcut:
+	mfc0 $t3, $epc
+	mfc0 $t2, $status
+	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, ISTATE_OFFSET_STATUS($sp)
+	mtc0 $t2, $status
+	
+	/*
+	 * 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, ISTATE_OFFSET_V0($sp)  /* save the syscall number on the stack */
+	
+	/* restore status */
+	mfc0 $t2, $status
+	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 */
+	mtc0 $t2, $status
+	
+	/* restore epc + 4 */
+	lw $t2, ISTATE_OFFSET_EPC($sp)
+	lw $k1, ISTATE_OFFSET_KT1($sp)
+	addi $t2, $t2, 4
+	mtc0 $t2, $epc
+	
+	lw $sp, ISTATE_OFFSET_SP($sp)  /* restore $sp */
+	eret
+
+	FAKE_ABI_PROLOGUE
+tlb_refill_handler:
+	KERNEL_STACK_TO_K0
+	sub $k0, ISTATE_SOFT_SIZE
+	REGISTERS_STORE_AND_EXC_RESET $k0
+	sw $sp, ISTATE_OFFSET_SP($k0)
+	move $sp, $k0
+	
+	jal tlb_refill
+	move $a0, $sp 
+	
+	REGISTERS_LOAD $sp
+	eret
+
+	FAKE_ABI_PROLOGUE
+cache_error_handler:
+	KERNEL_STACK_TO_K0
+	sub $k0, ISTATE_SOFT_SIZE 
+	REGISTERS_STORE_AND_EXC_RESET $k0
+	sw $sp, ISTATE_OFFSET_SP($k0)
+	move $sp, $k0
+	
+	jal cache_error
+	move $a0, $sp
+	
+	REGISTERS_LOAD $sp
+	eret
+
+userspace_asm:
+	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/sparc64/Makefile.inc
===================================================================
--- kernel/arch/sparc64/Makefile.inc	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ kernel/arch/sparc64/Makefile.inc	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -84,7 +84,5 @@
 	arch/$(KARCH)/src/drivers/tick.c \
 	arch/$(KARCH)/src/drivers/kbd.c \
-	arch/$(KARCH)/src/drivers/sgcn.c \
 	arch/$(KARCH)/src/drivers/pci.c \
-	arch/$(KARCH)/src/drivers/fhc.c \
 	arch/$(KARCH)/src/trap/$(USARCH)/interrupt.c
 
Index: rnel/arch/sparc64/include/drivers/fhc.h
===================================================================
--- kernel/arch/sparc64/include/drivers/fhc.h	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ 	(revision )
@@ -1,54 +1,0 @@
-/*
- * Copyright (c) 2006 Jakub Jermar
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/** @addtogroup sparc64
- * @{
- */
-/** @file
- */
-
-#ifndef KERN_sparc64_FHC_H_
-#define KERN_sparc64_FHC_H_
-
-#include <typedefs.h>
-#include <genarch/ofw/ofw_tree.h>
-
-typedef struct {
-	volatile uint32_t *uart_imap;
-} fhc_t;
-
-extern fhc_t *central_fhc;
-
-extern fhc_t *fhc_init(ofw_tree_node_t *);
-extern void fhc_enable_interrupt(fhc_t *, int);
-extern void fhc_clear_interrupt(void *, int);
-
-#endif
-
-/** @}
- */
Index: rnel/arch/sparc64/include/drivers/sgcn.h
===================================================================
--- kernel/arch/sparc64/include/drivers/sgcn.h	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ 	(revision )
@@ -1,151 +1,0 @@
-/*
- * Copyright (c) 2008 Pavel Rimsky
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/** @addtogroup sparc64	
- * @{
- */
-/** @file
- */
-
-#ifndef KERN_sparc64_SGCN_H_
-#define KERN_sparc64_SGCN_H_
-
-#include <typedefs.h>
-#include <console/chardev.h>
-#include <proc/thread.h>
-#include <synch/spinlock.h>
-
-/* number of bytes in the TOC magic, including the NULL-terminator */
-#define TOC_MAGIC_BYTES  8
-
-/* number of bytes in the TOC key, including the NULL-terminator */
-#define TOC_KEY_SIZE  8
-
-/* maximum number of entries in the SRAM table of contents */
-#define MAX_TOC_ENTRIES  32
-
-/* number of bytes in the SGCN buffer magic, including the NULL-terminator */
-#define SGCN_MAGIC_BYTES  4
-
-/**
- * Entry in the SRAM table of contents. Describes one segment of the SRAM
- * which serves a particular purpose (e.g. OBP serial console, Solaris serial
- * console, Solaris mailbox,...).
- */
-typedef struct {
-	/** key (e.g. "OBPCONS", "SOLCONS", "SOLMBOX",...) */
-	char key[TOC_KEY_SIZE];
-	
-	/** size of the segment in bytes */
-	uint32_t size;
-	
-	/** offset of the segment within SRAM */
-	uint32_t offset;
-} __attribute ((packed)) toc_entry_t;
-
-/**
- * SRAM table of contents. Describes all segments within the SRAM.
- */
-typedef struct {
-	/** hard-wired to "TOCSRAM" */
-	char magic[TOC_MAGIC_BYTES];
-	
-	/** we don't need this */
-	char unused[8];
-	
-	/** TOC entries */
-	toc_entry_t keys[MAX_TOC_ENTRIES];
-} __attribute__ ((packed)) iosram_toc_t;
-
-/**
- * SGCN buffer header. It is placed at the very beginning of the SGCN
- * buffer.
- */
-typedef struct {
-	/** hard-wired to "CON" */
-	char magic[SGCN_MAGIC_BYTES];
-	
-	/** we don't need this */
-	char unused[8];
-	
-	/** offset within the SGCN buffer of the input buffer start */
-	uint32_t in_begin;
-	
-	/** offset within the SGCN buffer of the input buffer end */
-	uint32_t in_end;
-	
-	/** offset within the SGCN buffer of the input buffer read pointer */
-	uint32_t in_rdptr;
-	
-	/** offset within the SGCN buffer of the input buffer write pointer */
-	uint32_t in_wrptr;
-	
-	/** offset within the SGCN buffer of the output buffer start */
-	uint32_t out_begin;
-	
-	/** offset within the SGCN buffer of the output buffer end */
-	uint32_t out_end;
-	
-	/** offset within the SGCN buffer of the output buffer read pointer */
-	uint32_t out_rdptr;
-	
-	/** offset within the SGCN buffer of the output buffer write pointer */
-	uint32_t out_wrptr;
-} __attribute__ ((packed)) sgcn_buffer_header_t;
-
-typedef struct {
-	/** Starting address of SRAM */
-	uintptr_t sram_begin;
-	
-	/** Starting address of the SGCN buffer */
-	uintptr_t buffer_begin;
-	
-	/**
-	 * Ensure that writing to the buffer and consequent
-	 * update of the write pointer are one atomic operation.
-	 */
-	SPINLOCK_DECLARE(output_lock);
-	
-	/**
-	 * Prevent the input buffer read/write pointers from
-	 * getting to inconsistent state.
-	 */
-	SPINLOCK_DECLARE(input_lock);
-	
-	thread_t *thread;
-	indev_t *srlnin;
-} sgcn_instance_t;
-
-extern sgcn_instance_t *sgcnin_init(void);
-extern void sgcnin_wire(sgcn_instance_t *, indev_t *);
-extern outdev_t *sgcnout_init(void);
-
-#endif
-
-/** @}
- */
Index: kernel/arch/sparc64/src/console.c
===================================================================
--- kernel/arch/sparc64/src/console.c	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ kernel/arch/sparc64/src/console.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -38,5 +38,4 @@
 #include <arch/drivers/scr.h>
 #include <arch/drivers/kbd.h>
-#include <arch/drivers/sgcn.h>
 #include <genarch/srln/srln.h>
 #include <console/chardev.h>
@@ -89,26 +88,4 @@
 }
 
-/** Initilize I/O on the Serengeti machine. */
-static void serengeti_init(void)
-{
-#ifdef CONFIG_SGCN_KBD
-	sgcn_instance_t *sgcn_instance = sgcnin_init();
-	if (sgcn_instance) {
-		srln_instance_t *srln_instance = srln_init();
-		if (srln_instance) {
-			indev_t *sink = stdin_wire();
-			indev_t *srln = srln_wire(srln_instance, sink);
-			sgcnin_wire(sgcn_instance, srln);
-		}
-	}
-#endif
-	
-#ifdef CONFIG_SGCN_PRN
-	outdev_t *sgcndev = sgcnout_init();
-	if (sgcndev)
-		stdout_wire(sgcndev);
-#endif
-}
-
 /**
  * Initialize input/output. Auto-detects the type of machine
@@ -127,9 +104,6 @@
 	prop = ofw_tree_getprop(aliases, "def-cn");
 	
-	if ((!prop) || (!prop->value) || (str_cmp(prop->value, "/sgcn") != 0)) {
+	if ((!prop) || (!prop->value))
 		standard_console_init(aliases);
-	} else {
-		serengeti_init();
-	}
 }
 
Index: rnel/arch/sparc64/src/drivers/fhc.c
===================================================================
--- kernel/arch/sparc64/src/drivers/fhc.c	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ 	(revision )
@@ -1,129 +1,0 @@
-/*
- * Copyright (c) 2006 Jakub Jermar
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/** @addtogroup sparc64
- * @{
- */
-/**
- * @file
- * @brief	FireHose Controller (FHC) driver.
- *
- * Note that this driver is a result of reverse engineering
- * rather than implementation of a specification. This
- * is due to the fact that the FHC documentation is not
- * publicly available.
- */
-
-#include <arch/drivers/fhc.h>
-#include <arch/trap/interrupt.h>
-#include <mm/page.h>
-#include <mm/slab.h>
-#include <typedefs.h>
-#include <genarch/ofw/ofw_tree.h>
-#include <genarch/ofw/fhc.h>
-#include <sysinfo/sysinfo.h>
-
-fhc_t *central_fhc = NULL;
-
-/**
- * I suspect this must be hardcoded in the FHC.
- * If it is not, than we can read all IMAP registers
- * and get the complete mapping.
- */
-#define FHC_UART_INR	0x39	
-
-#define FHC_UART_IMAP	0x0
-#define FHC_UART_ICLR	0x4
-
-#define UART_IMAP_REG	4
-
-fhc_t *fhc_init(ofw_tree_node_t *node)
-{
-	fhc_t *fhc;
-	ofw_tree_property_t *prop;
-
-	prop = ofw_tree_getprop(node, "reg");
-	
-	if (!prop || !prop->value)
-		return NULL;
-		
-	size_t regs = prop->size / sizeof(ofw_central_reg_t);
-	if (regs + 1 < UART_IMAP_REG)
-		return NULL;
-
-	ofw_central_reg_t *reg = &((ofw_central_reg_t *) prop->value)[UART_IMAP_REG];
-
-	uintptr_t paddr;
-	if (!ofw_central_apply_ranges(node->parent, reg, &paddr))
-		return NULL;
-
-	fhc = (fhc_t *) malloc(sizeof(fhc_t), FRAME_ATOMIC);
-	if (!fhc)
-		return NULL;
-
-	fhc->uart_imap = (uint32_t *) hw_map(paddr, reg->size);
-	
-	/*
-	 * Set sysinfo data needed by the uspace FHC driver.
-	 */
-	sysinfo_set_item_val("fhc.uart.size", NULL, reg->size);
-	sysinfo_set_item_val("fhc.uart.physical", NULL, paddr);
-	sysinfo_set_item_val("kbd.cir.fhc", NULL, 1);
-
-	return fhc;
-}
-
-void fhc_enable_interrupt(fhc_t *fhc, int inr)
-{
-	switch (inr) {
-	case FHC_UART_INR:
-		fhc->uart_imap[FHC_UART_IMAP] |= IMAP_V_MASK;
-		break;
-	default:
-		panic("Unexpected INR (%d).", inr);
-		break;
-	}
-}
-
-void fhc_clear_interrupt(void *fhcp, int inr)
-{
-	fhc_t *fhc = (fhc_t *)fhcp;
-	ASSERT(fhc->uart_imap);
-
-	switch (inr) {
-	case FHC_UART_INR:
-		fhc->uart_imap[FHC_UART_ICLR] = 0;
-		break;
-	default:
-		panic("Unexpected INR (%d).", inr);
-		break;
-	}
-}
-
-/** @}
- */
Index: kernel/arch/sparc64/src/drivers/kbd.c
===================================================================
--- kernel/arch/sparc64/src/drivers/kbd.c	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ kernel/arch/sparc64/src/drivers/kbd.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -35,5 +35,4 @@
 #include <arch/drivers/kbd.h>
 #include <genarch/ofw/ofw_tree.h>
-#include <genarch/ofw/fhc.h>
 #include <genarch/ofw/ebus.h>
 #include <console/console.h>
@@ -51,8 +50,4 @@
 #endif
 
-#ifdef CONFIG_Z8530
-#include <genarch/drivers/z8530/z8530.h>
-#endif
-
 #ifdef CONFIG_NS16550
 #include <genarch/drivers/ns16550/ns16550.h>
@@ -60,90 +55,4 @@
 
 #ifdef CONFIG_SUN_KBD
-
-#ifdef CONFIG_Z8530
-
-static bool kbd_z8530_init(ofw_tree_node_t *node)
-{
-	const char *name = ofw_tree_node_name(node);
-	
-	if (str_cmp(name, "zs") != 0)
-		return false;
-	
-	/*
-	 * Read 'interrupts' property.
-	 */
-	ofw_tree_property_t *prop = ofw_tree_getprop(node, "interrupts");
-	if ((!prop) || (!prop->value)) {
-		printf("z8530: Unable to find interrupts property\n");
-		return false;
-	}
-	
-	uint32_t interrupts = *((uint32_t *) prop->value);
-	
-	/*
-	 * Read 'reg' property.
-	 */
-	prop = ofw_tree_getprop(node, "reg");
-	if ((!prop) || (!prop->value)) {
-		printf("z8530: Unable to find reg property\n");
-		return false;
-	}
-	
-	size_t size = ((ofw_fhc_reg_t *) prop->value)->size;
-	
-	uintptr_t pa;
-	if (!ofw_fhc_apply_ranges(node->parent,
-	    ((ofw_fhc_reg_t *) prop->value), &pa)) {
-		printf("z8530: Failed to determine address\n");
-		return false;
-	}
-	
-	inr_t inr;
-	cir_t cir;
-	void *cir_arg;
-	if (!ofw_fhc_map_interrupt(node->parent,
-	    ((ofw_fhc_reg_t *) prop->value), interrupts, &inr, &cir,
-	    &cir_arg)) {
-		printf("z8530: Failed to determine interrupt\n");
-		return false;
-	}
-	
-	/*
-	 * We need to pass aligned address to hw_map().
-	 * However, the physical keyboard address can
-	 * be pretty much unaligned, depending on the
-	 * underlying controller.
-	 */
-	uintptr_t aligned_addr = ALIGN_DOWN(pa, PAGE_SIZE);
-	size_t offset = pa - aligned_addr;
-	
-	z8530_t *z8530 = (z8530_t *)
-	    (hw_map(aligned_addr, offset + size) + offset);
-	
-	z8530_instance_t *z8530_instance = z8530_init(z8530, inr, cir, cir_arg);
-	if (z8530_instance) {
-		kbrd_instance_t *kbrd_instance = kbrd_init();
-		if (kbrd_instance) {
-			indev_t *sink = stdin_wire();
-			indev_t *kbrd = kbrd_wire(kbrd_instance, sink);
-			z8530_wire(z8530_instance, kbrd);
-		}
-	}
-	
-	/*
-	 * This is the necessary evil until the userspace drivers are
-	 * entirely self-sufficient.
-	 */
-	sysinfo_set_item_val("kbd", NULL, true);
-	sysinfo_set_item_val("kbd.inr", NULL, inr);
-	sysinfo_set_item_val("kbd.address.kernel", NULL,
-	    (uintptr_t) z8530);
-	sysinfo_set_item_val("kbd.address.physical", NULL, pa);
-	sysinfo_set_item_val("kbd.type.z8530", NULL, true);
-	
-	return true;
-}
-
-#endif /* CONFIG_Z8530 */
 
 #ifdef CONFIG_NS16550
@@ -243,8 +152,4 @@
 void kbd_init(ofw_tree_node_t *node)
 {
-#ifdef CONFIG_Z8530
-	kbd_z8530_init(node);
-#endif
-	
 #ifdef CONFIG_NS16550
 	kbd_ns16550_init(node);
Index: kernel/arch/sparc64/src/drivers/niagara.c
===================================================================
--- kernel/arch/sparc64/src/drivers/niagara.c	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ kernel/arch/sparc64/src/drivers/niagara.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -32,5 +32,5 @@
 /**
  * @file
- * @brief	Niagara input/output driver based on hypervisor calls.
+ * @brief Niagara input/output driver based on hypervisor calls.
  */
 
@@ -52,13 +52,13 @@
 #include <genarch/srln/srln.h>
 
-/* polling interval in miliseconds */
+/* Polling interval in miliseconds */
 #define POLL_INTERVAL  10000
 
-/* device instance */
+/* Device instance */
 static niagara_instance_t *instance = NULL;
 
-static void niagara_putchar(outdev_t *, const wchar_t, bool);
-
-/** character device operations */
+static void niagara_putchar(outdev_t *, const wchar_t);
+
+/** Character device operations */
 static outdev_operations_t niagara_ops = {
 	.write = niagara_putchar,
@@ -66,103 +66,115 @@
 };
 
-/*
+/**
  * The driver uses hypercalls to print characters to the console. Since the
  * hypercall cannot be performed from the userspace, we do this:
- * The kernel "little brother" driver (which will be present no matter what the
- * DDI architecture is - as we need the kernel part for the kconsole)
+ *
+ * The kernel "little brother" driver (which will be present no matter what
+ * the DDI architecture is -- as we need the kernel part for the kconsole)
  * defines a shared buffer. Kernel walks through the buffer (in the same thread
  * which is used for polling the keyboard) and prints any pending characters
- * to the console (using hypercalls). The userspace fb server maps this shared
- * buffer to its address space and output operation it does is performed using
- * the mapped buffer. The shared buffer definition follows.
- */
-#define OUTPUT_BUFFER_SIZE	((PAGE_SIZE) - 2 * 8)
+ * to the console (using hypercalls).
+ *
+ * The userspace fb server maps this shared buffer to its address space and
+ * output operation it does is performed using the mapped buffer. The shared
+ * buffer definition follows.
+ */
+#define OUTPUT_BUFFER_SIZE  ((PAGE_SIZE) - 2 * 8)
+
 static volatile struct {
 	uint64_t read_ptr;
 	uint64_t write_ptr;
 	char data[OUTPUT_BUFFER_SIZE];
-}
-	__attribute__ ((packed))
-	__attribute__ ((aligned(PAGE_SIZE)))
-	output_buffer;
+} __attribute__ ((packed)) __attribute__ ((aligned(PAGE_SIZE))) output_buffer;
+
+static parea_t outbuf_parea;
 
 /**
  * Analogous to the output_buffer, see the previous definition.
  */
-#define INPUT_BUFFER_SIZE	((PAGE_SIZE) - 2 * 8)
+#define INPUT_BUFFER_SIZE  ((PAGE_SIZE) - 2 * 8)
+
 static volatile struct {
 	uint64_t write_ptr;
 	uint64_t read_ptr;
 	char data[INPUT_BUFFER_SIZE];
-}
-	__attribute__ ((packed))
-	__attribute__ ((aligned(PAGE_SIZE)))
-	input_buffer;
-
-
-/** Writes a single character to the standard output. */
+} __attribute__ ((packed)) __attribute__ ((aligned(PAGE_SIZE))) input_buffer;
+
+static parea_t inbuf_parea;
+
+/** Write a single character to the standard output. */
 static inline void do_putchar(const char c) {
-	/* repeat until the buffer is non-full */
-	while (__hypercall_fast1(CONS_PUTCHAR, c) == HV_EWOULDBLOCK)
-		;
-}
-
-/** Writes a single character to the standard output. */
-static void niagara_putchar(outdev_t *dev, const wchar_t ch, bool silent)
-{
-        if (silent)
-            return;
-
-	do_putchar(ch);
-	if (ch == '\n')
-		do_putchar('\r');
-}
-
-/**
- * Function regularly called by the keyboard polling thread. Asks the
- * hypervisor whether there is any unread character. If so, it picks it up
- * and sends it to the upper layers of HelenOS.
- *
- * Apart from that, it also checks whether the userspace output driver has
- * pushed any characters to the output buffer. If so, it prints them.
- */
-static void niagara_poll(niagara_instance_t *instance)
-{
-	/* print any pending characters from the shared buffer to the console */
+	/* Repeat until the buffer is non-full */
+	while (__hypercall_fast1(CONS_PUTCHAR, c) == HV_EWOULDBLOCK);
+}
+
+/** Write a single character to the standard output. */
+static void niagara_putchar(outdev_t *dev, const wchar_t ch)
+{
+	if ((!outbuf_parea.mapped) || (console_override)) {
+		do_putchar(ch);
+		if (ch == '\n')
+			do_putchar('\r');
+	}
+}
+
+/** Poll keyboard and print pending characters.
+ *
+ * Ask the hypervisor whether there is any unread character. If so,
+ * pick it up and send it to the indev layer.
+ *
+ * Check whether the userspace output driver has pushed any
+ * characters to the output buffer and eventually print them.
+ *
+ */
+static void niagara_poll(void)
+{
+	/*
+	 * Print any pending characters from the
+	 * shared buffer to the console.
+	 */
+	
 	while (output_buffer.read_ptr != output_buffer.write_ptr) {
 		do_putchar(output_buffer.data[output_buffer.read_ptr]);
 		output_buffer.read_ptr =
-			((output_buffer.read_ptr) + 1) % OUTPUT_BUFFER_SIZE;
-	}
-
+		    ((output_buffer.read_ptr) + 1) % OUTPUT_BUFFER_SIZE;
+	}
+	
+	/*
+	 * Read character from keyboard.
+	 */
+	
 	uint64_t c;
-
-	/* read character from keyboard, send it to upper layers of HelenOS */
 	if (__hypercall_fast_ret1(0, 0, 0, 0, 0, CONS_GETCHAR, &c) == HV_EOK) {
-		if (!silent) {
-			/* kconsole active, send the character to kernel */
+		if ((!inbuf_parea.mapped) || (console_override)) {
+			/*
+			 * Kernel console is active, send
+			 * the character to kernel.
+			 */
 			indev_push_character(instance->srlnin, c);
 		} else {
-			/* kconsole inactive, send the character to uspace driver */
+			/*
+			 * Kernel console is inactive, send
+			 * the character to uspace driver.
+			 */
 			input_buffer.data[input_buffer.write_ptr] = (char) c;
 			input_buffer.write_ptr =
-				((input_buffer.write_ptr) + 1) % INPUT_BUFFER_SIZE;
+			    ((input_buffer.write_ptr) + 1) % INPUT_BUFFER_SIZE;
 		}
 	}
 }
 
-/**
- * Polling thread function.
- */
-static void kniagarapoll(void *instance) {
+/** Polling thread function.
+ *
+ */
+static void kniagarapoll(void *arg) {
 	while (true) {
-		niagara_poll(instance);
+		niagara_poll();
 		thread_usleep(POLL_INTERVAL);
 	}
 }
 
-/**
- * Initializes the input/output subsystem so that the Niagara standard
- * input/output is used.
+/** Initialize the input/output subsystem
+ *
  */
 static void niagara_init(void)
@@ -172,57 +184,54 @@
 	
 	instance = malloc(sizeof(niagara_instance_t), FRAME_ATOMIC);
-	
-	if (instance) {
-		instance->thread = thread_create(kniagarapoll, instance, TASK, 0,
-			"kniagarapoll", true);
-		
-		if (!instance->thread) {
-			free(instance);
-			instance = NULL;
-			return;
-		}
-	}
-
+	instance->thread = thread_create(kniagarapoll, NULL, TASK, 0,
+	    "kniagarapoll", true);
+	
+	if (!instance->thread) {
+		free(instance);
+		instance = NULL;
+		return;
+	}
+	
 	instance->srlnin = NULL;
-
+	
 	output_buffer.read_ptr = 0;
 	output_buffer.write_ptr = 0;
 	input_buffer.write_ptr = 0;
 	input_buffer.read_ptr = 0;
-
+	
 	/*
 	 * Set sysinfos and pareas so that the userspace counterpart of the
 	 * niagara fb and kbd driver can communicate with kernel using shared
 	 * buffers.
- 	 */
-
+	 */
+	
 	sysinfo_set_item_val("fb.kind", NULL, 5);
-
+	
 	sysinfo_set_item_val("niagara.outbuf.address", NULL,
-		KA2PA(&output_buffer));
+	    KA2PA(&output_buffer));
 	sysinfo_set_item_val("niagara.outbuf.size", NULL,
-		PAGE_SIZE);
+	    PAGE_SIZE);
 	sysinfo_set_item_val("niagara.outbuf.datasize", NULL,
-		OUTPUT_BUFFER_SIZE);
-
+	    OUTPUT_BUFFER_SIZE);
+	
 	sysinfo_set_item_val("niagara.inbuf.address", NULL,
-		KA2PA(&input_buffer));
+	    KA2PA(&input_buffer));
 	sysinfo_set_item_val("niagara.inbuf.size", NULL,
-		PAGE_SIZE);
+	    PAGE_SIZE);
 	sysinfo_set_item_val("niagara.inbuf.datasize", NULL,
-		INPUT_BUFFER_SIZE);
-
-	static parea_t outbuf_parea;
+	   INPUT_BUFFER_SIZE);
+	
 	outbuf_parea.pbase = (uintptr_t) (KA2PA(&output_buffer));
 	outbuf_parea.frames = 1;
 	outbuf_parea.unpriv = false;
+	outbuf_parea.mapped = false;
 	ddi_parea_register(&outbuf_parea);
-
-	static parea_t inbuf_parea;
+	
 	inbuf_parea.pbase = (uintptr_t) (KA2PA(&input_buffer));
 	inbuf_parea.frames = 1;
 	inbuf_parea.unpriv = false;
+	inbuf_parea.mapped = false;
 	ddi_parea_register(&inbuf_parea);
-
+	
 	outdev_t *niagara_dev = malloc(sizeof(outdev_t), FRAME_ATOMIC);
 	outdev_initialize("niagara_dev", niagara_dev, &niagara_ops);
@@ -230,11 +239,11 @@
 }
 
-/**
- * A public function which initializes input from the Niagara console.
+/** Initialize input from the Niagara console.
+ *
  */
 niagara_instance_t *niagarain_init(void)
 {
 	niagara_init();
-
+	
 	if (instance) {
 		srln_instance_t *srln_instance = srln_init();
@@ -242,10 +251,10 @@
 			indev_t *sink = stdin_wire();
 			indev_t *srln = srln_wire(srln_instance, sink);
-
-			// wire std. input to niagara
+			
 			instance->srlnin = srln;
 			thread_ready(instance->thread);
 		}
 	}
+	
 	return instance;
 }
Index: rnel/arch/sparc64/src/drivers/sgcn.c
===================================================================
--- kernel/arch/sparc64/src/drivers/sgcn.c	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ 	(revision )
@@ -1,358 +1,0 @@
-/*
- * Copyright (c) 2008 Pavel Rimsky
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/** @addtogroup sparc64
- * @{
- */
-/**
- * @file
- * @brief SGCN driver.
- */
-
-#include <arch.h>
-#include <arch/drivers/sgcn.h>
-#include <arch/drivers/kbd.h>
-#include <genarch/ofw/ofw_tree.h>
-#include <debug.h>
-#include <str.h>
-#include <print.h>
-#include <mm/page.h>
-#include <proc/thread.h>
-#include <console/chardev.h>
-#include <console/console.h>
-#include <sysinfo/sysinfo.h>
-#include <synch/spinlock.h>
-
-#define POLL_INTERVAL  10000
-
-/*
- * Physical address at which the SBBC starts. This value has been obtained
- * by inspecting (using Simics) memory accesses made by OBP. It is valid
- * for the Simics-simulated Serengeti machine. The author of this code is
- * not sure whether this value is valid generally. 
- */
-#define SBBC_START  0x63000000000
-
-/* offset of SRAM within the SBBC memory */
-#define SBBC_SRAM_OFFSET  0x900000
-
-/* size (in bytes) of the physical memory area which will be mapped */
-#define MAPPED_AREA_SIZE  (128 * 1024)
-
-/* magic string contained at the beginning of SRAM */
-#define SRAM_TOC_MAGIC  "TOCSRAM"
-
-/*
- * Key into the SRAM table of contents which identifies the entry
- * describing the OBP console buffer. It is worth mentioning
- * that the OBP console buffer is not the only console buffer
- * which can be used. It is, however, used because when the kernel
- * is running, the OBP buffer is not used by OBP any more but OBP
- * has already made necessary arrangements so that the output will
- * be read from the OBP buffer and input will go to the OBP buffer.
- * Therefore HelenOS needs to make no such arrangements any more.
- */
-#define CONSOLE_KEY  "OBPCONS"
-
-/* magic string contained at the beginning of the console buffer */
-#define SGCN_BUFFER_MAGIC  "CON"
-
-/*
- * Returns a pointer to the object of a given type which is placed at the given
- * offset from the SRAM beginning.
- */
-#define SRAM(type, offset)  ((type *) (instance->sram_begin + (offset)))
-
-/* Returns a pointer to the SRAM table of contents. */
-#define SRAM_TOC  (SRAM(iosram_toc_t, 0))
-
-/*
- * Returns a pointer to the object of a given type which is placed at the given
- * offset from the console buffer beginning.
- */
-#define SGCN_BUFFER(type, offset) \
-	((type *) (instance->buffer_begin + (offset)))
-
-/** Returns a pointer to the console buffer header. */
-#define SGCN_BUFFER_HEADER  (SGCN_BUFFER(sgcn_buffer_header_t, 0))
-
-static void sgcn_putchar(outdev_t *, const wchar_t, bool);
-
-static outdev_operations_t sgcndev_ops = {
-	.write = sgcn_putchar,
-	.redraw = NULL
-};
-
-static sgcn_instance_t *instance = NULL;
-
-/**
- * Set some sysinfo values (SRAM address and SRAM size).
- */
-static void register_sram(uintptr_t sram_begin_physical)
-{
-	sysinfo_set_item_val("sram.area.size", NULL, MAPPED_AREA_SIZE);
-	sysinfo_set_item_val("sram.address.physical", NULL,
-	    sram_begin_physical);
-}
-
-/**
- * Initializes the starting address of SRAM.
- *
- * The SRAM starts 0x900000 + C bytes behind the SBBC start in the
- * physical memory, where C is the value read from the "iosram-toc"
- * property of the "/chosen" OBP node. The sram_begin variable will
- * be set to the virtual address which maps to the SRAM physical
- * address.
- */
-static void init_sram_begin(void)
-{
-	ASSERT(instance);
-	
-	ofw_tree_node_t *chosen = ofw_tree_lookup("/chosen");
-	if (!chosen)
-		panic("Cannot find '/chosen'.");
-	
-	ofw_tree_property_t *iosram_toc =
-	    ofw_tree_getprop(chosen, "iosram-toc");
-	if (!iosram_toc)
-		panic("Cannot find property 'iosram-toc'.");
-	if (!iosram_toc->value)
-		panic("Cannot find SRAM TOC.");
-	
-	uintptr_t sram_begin_physical = SBBC_START + SBBC_SRAM_OFFSET
-	    + *((uint32_t *) iosram_toc->value);
-	instance->sram_begin = hw_map(sram_begin_physical, MAPPED_AREA_SIZE);
-	
-	register_sram(sram_begin_physical);
-}
-
-/**
- * Function regularly called by the keyboard polling thread. Finds out whether
- * there are some unread characters in the input queue. If so, it picks them up
- * and sends them to the upper layers of HelenOS.
- */
-static void sgcn_poll(sgcn_instance_t *instance)
-{
-	uint32_t begin = SGCN_BUFFER_HEADER->in_begin;
-	uint32_t end = SGCN_BUFFER_HEADER->in_end;
-	uint32_t size = end - begin;
-	
-	if (silent)
-		return;
-	
-	spinlock_lock(&instance->input_lock);
-	
-	/* we need pointers to volatile variables */
-	volatile char *buf_ptr = (volatile char *)
-	    SGCN_BUFFER(char, SGCN_BUFFER_HEADER->in_rdptr);
-	volatile uint32_t *in_wrptr_ptr = &(SGCN_BUFFER_HEADER->in_wrptr);
-	volatile uint32_t *in_rdptr_ptr = &(SGCN_BUFFER_HEADER->in_rdptr);
-	
-	while (*in_rdptr_ptr != *in_wrptr_ptr) {
-		buf_ptr = (volatile char *)
-		    SGCN_BUFFER(char, SGCN_BUFFER_HEADER->in_rdptr);
-		char c = *buf_ptr;
-		*in_rdptr_ptr = (((*in_rdptr_ptr) - begin + 1) % size) + begin;
-		
-		indev_push_character(instance->srlnin, c);
-	}
-	
-	spinlock_unlock(&instance->input_lock);
-}
-
-/**
- * Polling thread function.
- */
-static void ksgcnpoll(void *instance) {
-	while (true) {
-		if (!silent)
-			sgcn_poll(instance);
-		
-		thread_usleep(POLL_INTERVAL);
-	}
-}
-
-/**
- * Initializes the starting address of the SGCN buffer.
- *
- * The offset of the SGCN buffer within SRAM is obtained from the
- * SRAM table of contents. The table of contents contains
- * information about several buffers, among which there is an OBP
- * console buffer - this one will be used as the SGCN buffer. 
- *
- * This function also writes the offset of the SGCN buffer within SRAM
- * under the sram.buffer.offset sysinfo key.
- */
-static void sgcn_init(void)
-{
-	if (instance)
-		return;
-	
-	instance = malloc(sizeof(sgcn_instance_t), FRAME_ATOMIC);
-	
-	if (instance) {
-		instance->thread = thread_create(ksgcnpoll, instance, TASK, 0,
-		    "ksgcnpoll", true);
-		
-		if (!instance->thread) {
-			free(instance);
-			instance = NULL;
-			return;
-		}
-		
-		init_sram_begin();
-		
-		ASSERT(str_cmp(SRAM_TOC->magic, SRAM_TOC_MAGIC) == 0);
-		
-		/* Lookup TOC entry with the correct key */
-		uint32_t i;
-		for (i = 0; i < MAX_TOC_ENTRIES; i++) {
-			if (str_cmp(SRAM_TOC->keys[i].key, CONSOLE_KEY) == 0)
-				break;
-		}
-		ASSERT(i < MAX_TOC_ENTRIES);
-		
-		instance->buffer_begin =
-		    instance->sram_begin + SRAM_TOC->keys[i].offset;
-		
-		sysinfo_set_item_val("sram.buffer.offset", NULL,
-		    SRAM_TOC->keys[i].offset);
-		
-		instance->srlnin = NULL;
-	}
-}
-
-/**
- * Writes a single character to the SGCN (circular) output buffer
- * and updates the output write pointer so that SGCN gets to know
- * that the character has been written.
- */
-static void sgcn_do_putchar(const char c)
-{
-	uint32_t begin = SGCN_BUFFER_HEADER->out_begin;
-	uint32_t end = SGCN_BUFFER_HEADER->out_end;
-	uint32_t size = end - begin;
-	
-	/* We need pointers to volatile variables */
-	volatile char *buf_ptr = (volatile char *)
-	    SGCN_BUFFER(char, SGCN_BUFFER_HEADER->out_wrptr);
-	volatile uint32_t *out_wrptr_ptr = &(SGCN_BUFFER_HEADER->out_wrptr);
-	volatile uint32_t *out_rdptr_ptr = &(SGCN_BUFFER_HEADER->out_rdptr);
-	
-	/*
-	 * Write the character and increment the write pointer modulo the
-	 * output buffer size. Note that if we are to rewrite a character
-	 * which has not been read by the SGCN controller yet (i.e. the output
-	 * buffer is full), we need to wait until the controller reads some more
-	 * characters. We wait actively, which means that all threads waiting
-	 * for the lock are blocked. However, this situation is
-	 *   1) rare - the output buffer is big, so filling the whole
-	 *             output buffer is improbable
-	 *   2) short-lasting - it will take the controller only a fraction
-	 *             of millisecond to pick the unread characters up
-	 *   3) not serious - the blocked threads are those that print something
-	 *             to user console, which is not a time-critical operation
-	 */
-	uint32_t new_wrptr = (((*out_wrptr_ptr) - begin + 1) % size) + begin;
-	while (*out_rdptr_ptr == new_wrptr);
-	
-	*buf_ptr = c;
-	*out_wrptr_ptr = new_wrptr;
-}
-
-/**
- * SGCN output operation. Prints a single character to the SGCN. Newline
- * character is converted to CRLF.
- */
-static void sgcn_putchar(outdev_t *dev, const wchar_t ch, bool silent)
-{
-	if (!silent) {
-		spinlock_lock(&instance->output_lock);
-		
-		if (ascii_check(ch)) {
-			if (ch == '\n')
-				sgcn_do_putchar('\r');
-			sgcn_do_putchar(ch);
-		} else
-			sgcn_do_putchar(U_SPECIAL);
-		
-		spinlock_unlock(&instance->output_lock);
-	}
-}
-
-/**
- * A public function which initializes input from the Serengeti console.
- */
-sgcn_instance_t *sgcnin_init(void)
-{
-	sgcn_init();
-	return instance;
-}
-
-void sgcnin_wire(sgcn_instance_t *instance, indev_t *srlnin)
-{
-	ASSERT(instance);
-	ASSERT(srlnin);
-	
-	instance->srlnin = srlnin;
-	thread_ready(instance->thread);
-	
-	sysinfo_set_item_val("kbd", NULL, true);
-}
-
-/**
- * A public function which initializes output to the Serengeti console.
- */
-outdev_t *sgcnout_init(void)
-{
-	sgcn_init();
-	if (!instance)
-		return NULL;
-	
-	outdev_t *sgcndev = malloc(sizeof(outdev_t), FRAME_ATOMIC);
-	if (!sgcndev)
-		return NULL;
-	
-	outdev_initialize("sgcndev", sgcndev, &sgcndev_ops);
-	sgcndev->data = instance;
-	
-	if (!fb_exported) {
-		/*
-		 * This is the necessary evil until the userspace driver is entirely
-		 * self-sufficient.
-		 */
-		sysinfo_set_item_val("fb.kind", NULL, 4);
-		
-		fb_exported = true;
-	}
-	
-	return sgcndev;
-}
-
-/** @}
- */
Index: kernel/genarch/Makefile.inc
===================================================================
--- kernel/genarch/Makefile.inc	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ kernel/genarch/Makefile.inc	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -100,9 +100,4 @@
 endif
 
-ifeq ($(CONFIG_Z8530),y)
-	GENARCH_SOURCES += \
-		genarch/src/drivers/z8530/z8530.c
-endif
-
 ifeq ($(CONFIG_VIA_CUDA),y)
 	GENARCH_SOURCES += \
@@ -141,5 +136,4 @@
 	GENARCH_SOURCES += \
 		genarch/src/ofw/ebus.c \
-		genarch/src/ofw/fhc.c \
 		genarch/src/ofw/pci.c  \
 		genarch/src/ofw/sbus.c \
Index: kernel/genarch/include/drivers/s3c24xx_uart/s3c24xx_uart.h
===================================================================
--- kernel/genarch/include/drivers/s3c24xx_uart/s3c24xx_uart.h	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ kernel/genarch/include/drivers/s3c24xx_uart/s3c24xx_uart.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -38,4 +38,5 @@
 #define KERN_S3C24XX_UART_H_
 
+#include <ddi/ddi.h>
 #include <ddi/irq.h>
 #include <console/chardev.h>
@@ -83,7 +84,8 @@
 	indev_t *indev;
 	irq_t irq;
+	parea_t parea;
 } s3c24xx_uart_t;
 
-extern outdev_t *s3c24xx_uart_init(s3c24xx_uart_io_t *, inr_t inr);
+extern outdev_t *s3c24xx_uart_init(uintptr_t, inr_t inr);
 extern void s3c24xx_uart_input_wire(s3c24xx_uart_t *,
     indev_t *);
Index: rnel/genarch/include/drivers/z8530/z8530.h
===================================================================
--- kernel/genarch/include/drivers/z8530/z8530.h	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ 	(revision )
@@ -1,128 +1,0 @@
-/*
- * Copyright (c) 2009 Jakub Jermar
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/** @addtogroup genarch
- * @{
- */
-/**
- * @file
- * @brief Headers for Zilog 8530 serial controller.
- */
-
-#ifndef KERN_Z8530_H_
-#define KERN_Z8530_H_
-
-#include <ddi/irq.h>
-#include <typedefs.h>
-#include <console/chardev.h>
-
-#define WR0   0
-#define WR1   1
-#define WR2   2
-#define WR3   3
-#define WR4   4
-#define WR5   5
-#define WR6   6
-#define WR7   7
-#define WR8   8
-#define WR9   9
-#define WR10  10
-#define WR11  11
-#define WR12  12
-#define WR13  13
-#define WR14  14
-#define WR15  15
-
-#define RR0   0
-#define RR1   1
-#define RR2   2
-#define RR3   3
-#define RR8   8
-#define RR10  10
-#define RR12  12
-#define RR13  13
-#define RR14  14
-#define RR15  15
-
-/** Reset pending TX interrupt. */
-#define WR0_TX_IP_RST  (0x5 << 3)
-#define WR0_ERR_RST    (0x6 << 3)
-
-/** Receive Interrupts Disabled. */
-#define WR1_RID     (0x0 << 3)
-/** Receive Interrupt on First Character or Special Condition. */
-#define WR1_RIFCSC  (0x1 << 3)
-/** Interrupt on All Receive Characters or Special Conditions. */
-#define WR1_IARCSC  (0x2 << 3)
-/** Receive Interrupt on Special Condition. */
-#define WR1_RISC    (0x3 << 3)
-/** Parity Is Special Condition. */
-#define WR1_PISC    (0x1 << 2)
-
-/** Rx Enable. */
-#define WR3_RX_ENABLE  (0x1 << 0)
-/** 8-bits per character. */
-#define WR3_RX8BITSCH  (0x3 << 6)
-
-/** Master Interrupt Enable. */
-#define WR9_MIE  (0x1 << 3)
-
-/** Receive Character Available. */
-#define RR0_RCA  (0x1 << 0)
-
-/** z8530's registers. */
-typedef struct {
-	union {
-		ioport8_t ctl_b;
-		ioport8_t status_b;
-	} __attribute__ ((packed));
-	uint8_t pad1;
-	ioport8_t data_b;
-	uint8_t pad2;
-	union {
-		ioport8_t ctl_a;
-		ioport8_t status_a;
-	} __attribute__ ((packed));
-	uint8_t pad3;
-	ioport8_t data_a;
-} __attribute__ ((packed)) z8530_t;
-
-/** Structure representing the z8530 device. */
-typedef struct {
-	irq_t irq;
-	z8530_t *z8530;
-	indev_t *kbrdin;
-} z8530_instance_t;
-
-extern z8530_instance_t *z8530_init(z8530_t *, inr_t, cir_t, void *);
-extern void z8530_wire(z8530_instance_t *, indev_t *);
-
-#endif
-
-/** @}
- */
Index: rnel/genarch/include/ofw/fhc.h
===================================================================
--- kernel/genarch/include/ofw/fhc.h	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ 	(revision )
@@ -1,67 +1,0 @@
-/*
- * Copyright (c) 2006 Jakub Jermar
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef KERN_FHC_H_
-#define KERN_FHC_H_
-
-#include <genarch/ofw/ofw_tree.h>
-#include <typedefs.h>
-#include <ddi/irq.h>
-#include <typedefs.h>
-
-typedef struct {
-	uint64_t addr;
-	uint32_t size;
-} __attribute__ ((packed)) ofw_fhc_reg_t;
-
-typedef struct {
-	uint64_t child_base;
-	uint64_t parent_base;
-	uint32_t size;
-} __attribute__ ((packed)) ofw_fhc_range_t;
-
-typedef struct {
-	uint64_t addr;
-	uint32_t size;
-} __attribute__ ((packed)) ofw_central_reg_t;
-
-typedef struct {
-	uint64_t child_base;
-	uint64_t parent_base;
-	uint32_t size;
-} __attribute__ ((packed)) ofw_central_range_t;
-
-extern bool ofw_fhc_apply_ranges(ofw_tree_node_t *, ofw_fhc_reg_t *,
-    uintptr_t *);
-extern bool ofw_central_apply_ranges(ofw_tree_node_t *, ofw_central_reg_t *,
-    uintptr_t *);
-
-extern bool ofw_fhc_map_interrupt(ofw_tree_node_t *, ofw_fhc_reg_t *,
-    uint32_t, int *, cir_t *, void **);
-
-#endif
Index: kernel/genarch/src/drivers/dsrln/dsrlnout.c
===================================================================
--- kernel/genarch/src/drivers/dsrln/dsrlnout.c	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ kernel/genarch/src/drivers/dsrln/dsrlnout.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -42,14 +42,16 @@
 #include <sysinfo/sysinfo.h>
 #include <str.h>
+#include <ddi/ddi.h>
 
 typedef struct {
+	parea_t parea;
 	ioport8_t *base;
 } dsrlnout_instance_t;
 
-static void dsrlnout_putchar(outdev_t *dev, const wchar_t ch, bool silent)
+static void dsrlnout_putchar(outdev_t *dev, const wchar_t ch)
 {
 	dsrlnout_instance_t *instance = (dsrlnout_instance_t *) dev->data;
 	
-	if (!silent) {
+	if ((!instance->parea.mapped) || (console_override)) {
 		if (ascii_check(ch))
 			pio_write_8(instance->base, ch);
@@ -70,5 +72,6 @@
 		return NULL;
 	
-	dsrlnout_instance_t *instance = malloc(sizeof(dsrlnout_instance_t), FRAME_ATOMIC);
+	dsrlnout_instance_t *instance = malloc(sizeof(dsrlnout_instance_t),
+	    FRAME_ATOMIC);
 	if (!instance) {
 		free(dsrlndev);
@@ -80,8 +83,15 @@
 	
 	instance->base = base;
+	link_initialize(&instance->parea.link);
+	instance->parea.pbase = KA2PA(base);
+	instance->parea.frames = 1;
+	instance->parea.unpriv = false;
+	instance->parea.mapped = false;
+	ddi_parea_register(&instance->parea);
 	
 	if (!fb_exported) {
 		/*
-		 * This is the necessary evil until the userspace driver is entirely
+		 * This is the necessary evil until
+		 * the userspace driver is entirely
 		 * self-sufficient.
 		 */
Index: kernel/genarch/src/drivers/ega/ega.c
===================================================================
--- kernel/genarch/src/drivers/ega/ega.c	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ kernel/genarch/src/drivers/ega/ega.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -64,4 +64,6 @@
 	IRQ_SPINLOCK_DECLARE(lock);
 	
+	parea_t parea;
+	
 	uint32_t cursor;
 	uint8_t *addr;
@@ -70,5 +72,5 @@
 } ega_instance_t;
 
-static void ega_putchar(outdev_t *, wchar_t, bool);
+static void ega_putchar(outdev_t *, wchar_t);
 static void ega_redraw(outdev_t *);
 
@@ -437,5 +439,5 @@
  * This function takes care of scrolling.
  */
-static void ega_check_cursor(ega_instance_t *instance, bool silent)
+static void ega_check_cursor(ega_instance_t *instance)
 {
 	if (instance->cursor < EGA_SCREEN)
@@ -448,5 +450,5 @@
 	    EGA_COLS, EMPTY_CHAR);
 	
-	if (!silent) {
+	if ((!instance->parea.mapped) || (console_override)) {
 		memmove((void *) instance->addr,
 		    (void *) (instance->addr + EGA_COLS * 2),
@@ -459,7 +461,7 @@
 }
 
-static void ega_show_cursor(ega_instance_t *instance, bool silent)
-{
-	if (!silent) {
+static void ega_show_cursor(ega_instance_t *instance)
+{
+	if ((!instance->parea.mapped) || (console_override)) {
 		pio_write_8(instance->base + EGA_INDEX_REG, 0x0a);
 		uint8_t stat = pio_read_8(instance->base + EGA_DATA_REG);
@@ -469,7 +471,7 @@
 }
 
-static void ega_move_cursor(ega_instance_t *instance, bool silent)
-{
-	if (!silent) {
+static void ega_move_cursor(ega_instance_t *instance)
+{
+	if ((!instance->parea.mapped) || (console_override)) {
 		pio_write_8(instance->base + EGA_INDEX_REG, 0x0e);
 		pio_write_8(instance->base + EGA_DATA_REG,
@@ -481,7 +483,7 @@
 }
 
-static void ega_sync_cursor(ega_instance_t *instance, bool silent)
-{
-	if (!silent) {
+static void ega_sync_cursor(ega_instance_t *instance)
+{
+	if ((!instance->parea.mapped) || (console_override)) {
 		pio_write_8(instance->base + EGA_INDEX_REG, 0x0e);
 		uint8_t hi = pio_read_8(instance->base + EGA_DATA_REG);
@@ -503,14 +505,14 @@
 	    EGA_SCREEN - instance->cursor, EMPTY_CHAR);
 	
-	if (!silent)
+	if ((!instance->parea.mapped) || (console_override))
 		memsetw(instance->addr + instance->cursor * 2,
 		    EGA_SCREEN - instance->cursor, EMPTY_CHAR);
 	
-	ega_check_cursor(instance, silent);
-	ega_move_cursor(instance, silent);
-	ega_show_cursor(instance, silent);
-}
-
-static void ega_display_char(ega_instance_t *instance, wchar_t ch, bool silent)
+	ega_check_cursor(instance);
+	ega_move_cursor(instance);
+	ega_show_cursor(instance);
+}
+
+static void ega_display_char(ega_instance_t *instance, wchar_t ch)
 {
 	uint16_t index = ega_oem_glyph(ch);
@@ -529,5 +531,5 @@
 	instance->backbuf[instance->cursor * 2 + 1] = style;
 	
-	if (!silent) {
+	if ((!instance->parea.mapped) || (console_override)) {
 		instance->addr[instance->cursor * 2] = glyph;
 		instance->addr[instance->cursor * 2 + 1] = style;
@@ -535,5 +537,5 @@
 }
 
-static void ega_putchar(outdev_t *dev, wchar_t ch, bool silent)
+static void ega_putchar(outdev_t *dev, wchar_t ch)
 {
 	ega_instance_t *instance = (ega_instance_t *) dev->data;
@@ -555,10 +557,10 @@
 		break;
 	default:
-		ega_display_char(instance, ch, silent);
+		ega_display_char(instance, ch);
 		instance->cursor++;
 		break;
 	}
-	ega_check_cursor(instance, silent);
-	ega_move_cursor(instance, silent);
+	ega_check_cursor(instance);
+	ega_move_cursor(instance);
 	
 	irq_spinlock_unlock(&instance->lock, true);
@@ -572,6 +574,6 @@
 	
 	memcpy(instance->addr, instance->backbuf, EGA_VRAM_SIZE);
-	ega_move_cursor(instance, silent);
-	ega_show_cursor(instance, silent);
+	ega_move_cursor(instance);
+	ega_show_cursor(instance);
 	
 	irq_spinlock_unlock(&instance->lock, true);
@@ -612,12 +614,20 @@
 	}
 	
+	link_initialize(&instance->parea.link);
+	instance->parea.pbase = addr;
+	instance->parea.frames = SIZE2FRAMES(EGA_VRAM_SIZE);
+	instance->parea.unpriv = false;
+	instance->parea.mapped = false;
+	ddi_parea_register(&instance->parea);
+	
 	/* Synchronize the back buffer and cursor position. */
 	memcpy(instance->backbuf, instance->addr, EGA_VRAM_SIZE);
-	ega_sync_cursor(instance, silent);
+	ega_sync_cursor(instance);
 	
 	if (!fb_exported) {
 		/*
-		 * This is the necessary evil until the userspace driver is entirely
-		 * self-sufficient.
+		 * We export the kernel framebuffer for uspace usage.
+		 * This is used in the case the uspace framebuffer
+		 * driver is not self-sufficient.
 		 */
 		sysinfo_set_item_val("fb", NULL, true);
Index: kernel/genarch/src/drivers/s3c24xx_uart/s3c24xx_uart.c
===================================================================
--- kernel/genarch/src/drivers/s3c24xx_uart/s3c24xx_uart.c	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ kernel/genarch/src/drivers/s3c24xx_uart/s3c24xx_uart.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -44,4 +44,5 @@
 #include <arch/asm.h>
 #include <mm/slab.h>
+#include <mm/page.h>
 #include <sysinfo/sysinfo.h>
 #include <str.h>
@@ -59,11 +60,14 @@
 }
 
-static void s3c24xx_uart_putchar(outdev_t *dev, wchar_t ch, bool silent)
+static void s3c24xx_uart_putchar(outdev_t *dev, wchar_t ch)
 {
-	if (!silent) {
+	s3c24xx_uart_t *uart =
+	    (s3c24xx_uart_t *) dev->data;
+	
+	if ((!uart->parea.mapped) || (console_override)) {
 		if (!ascii_check(ch)) {
 			s3c24xx_uart_sendb(dev, U_SPECIAL);
 		} else {
-    			if (ch == '\n')
+			if (ch == '\n')
 				s3c24xx_uart_sendb(dev, (uint8_t) '\r');
 			s3c24xx_uart_sendb(dev, (uint8_t) ch);
@@ -93,5 +97,5 @@
 };
 
-outdev_t *s3c24xx_uart_init(s3c24xx_uart_io_t *io, inr_t inr)
+outdev_t *s3c24xx_uart_init(uintptr_t paddr, inr_t inr)
 {
 	outdev_t *uart_dev = malloc(sizeof(outdev_t), FRAME_ATOMIC);
@@ -109,5 +113,5 @@
 	uart_dev->data = uart;
 
-	uart->io = io;
+	uart->io = (s3c24xx_uart_io_t *) hw_map(paddr, PAGE_SIZE);
 	uart->indev = NULL;
 
@@ -127,13 +131,21 @@
 	pio_write_32(&uart->io->ucon,
 	    pio_read_32(&uart->io->ucon) & ~UCON_RX_INT_LEVEL);
-
+	
+	link_initialize(&uart->parea.link);
+	uart->parea.pbase = paddr;
+	uart->parea.frames = 1;
+	uart->parea.unpriv = false;
+	uart->parea.mapped = false;
+	ddi_parea_register(&uart->parea);
+	
 	if (!fb_exported) {
 		/*
-		 * This is the necessary evil until the userspace driver is entirely
+		 * 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));
+		sysinfo_set_item_val("fb.address.physical", NULL, paddr);
 
 		fb_exported = true;
Index: rnel/genarch/src/drivers/z8530/z8530.c
===================================================================
--- kernel/genarch/src/drivers/z8530/z8530.c	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ 	(revision )
@@ -1,136 +1,0 @@
-/*
- * Copyright (c) 2009 Jakub Jermar
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/** @addtogroup genarch
- * @{
- */
-/**
- * @file
- * @brief Zilog 8530 serial controller driver.
- */
-
-#include <genarch/drivers/z8530/z8530.h>
-#include <console/chardev.h>
-#include <ddi/irq.h>
-#include <arch/asm.h>
-#include <mm/slab.h>
-#include <ddi/device.h>
-
-static inline void z8530_write(ioport8_t *ctl, uint8_t reg, uint8_t val)
-{
-	/*
-	 * Registers 8-15 will automatically issue the Point High
-	 * command as their bit 3 is 1.
-	 */
-	pio_write_8(ctl, reg);  /* Select register */
-	pio_write_8(ctl, val);  /* Write value */
-}
-
-static inline uint8_t z8530_read(ioport8_t *ctl, uint8_t reg) 
-{
-	/*
-	 * Registers 8-15 will automatically issue the Point High
-	 * command as their bit 3 is 1.
-	 */
-	pio_write_8(ctl, reg);   /* Select register */
-	return pio_read_8(ctl);
-}
-
-static irq_ownership_t z8530_claim(irq_t *irq)
-{
-	z8530_instance_t *instance = irq->instance;
-	z8530_t *dev = instance->z8530;
-	
-	if (z8530_read(&dev->ctl_a, RR0) & RR0_RCA)
-		return IRQ_ACCEPT;
-	else
-		return IRQ_DECLINE;
-}
-
-static void z8530_irq_handler(irq_t *irq)
-{
-	z8530_instance_t *instance = irq->instance;
-	z8530_t *dev = instance->z8530;
-	
-	if (z8530_read(&dev->ctl_a, RR0) & RR0_RCA) {
-		uint8_t data = z8530_read(&dev->ctl_a, RR8);
-		indev_push_character(instance->kbrdin, data);
-	}
-}
-
-/** Initialize z8530. */
-z8530_instance_t *z8530_init(z8530_t *dev, inr_t inr, cir_t cir, void *cir_arg)
-{
-	z8530_instance_t *instance
-	    = malloc(sizeof(z8530_instance_t), FRAME_ATOMIC);
-	if (instance) {
-		instance->z8530 = dev;
-		instance->kbrdin = NULL;
-		
-		irq_initialize(&instance->irq);
-		instance->irq.devno = device_assign_devno();
-		instance->irq.inr = inr;
-		instance->irq.claim = z8530_claim;
-		instance->irq.handler = z8530_irq_handler;
-		instance->irq.instance = instance;
-		instance->irq.cir = cir;
-		instance->irq.cir_arg = cir_arg;
-	}
-	
-	return instance;
-}
-
-void z8530_wire(z8530_instance_t *instance, indev_t *kbrdin)
-{
-	ASSERT(instance);
-	ASSERT(kbrdin);
-	
-	instance->kbrdin = kbrdin;
-	
-	irq_register(&instance->irq);
-	
-	(void) z8530_read(&instance->z8530->ctl_a, RR8);
-	
-	/*
-	 * Clear any pending TX interrupts or we never manage
-	 * to set FHC UART interrupt state to idle.
-	 */
-	z8530_write(&instance->z8530->ctl_a, WR0, WR0_TX_IP_RST);
-	
-	/* interrupt on all characters */
-	z8530_write(&instance->z8530->ctl_a, WR1, WR1_IARCSC);
-	
-	/* 8 bits per character and enable receiver */
-	z8530_write(&instance->z8530->ctl_a, WR3, WR3_RX8BITSCH | WR3_RX_ENABLE);
-	
-	/* Master Interrupt Enable. */
-	z8530_write(&instance->z8530->ctl_a, WR9, WR9_MIE);
-}
-
-/** @}
- */
Index: kernel/genarch/src/fb/fb.c
===================================================================
--- kernel/genarch/src/fb/fb.c	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ kernel/genarch/src/fb/fb.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -82,4 +82,6 @@
 	SPINLOCK_DECLARE(lock);
 	
+	parea_t parea;
+	
 	uint8_t *addr;
 	uint16_t *backbuf;
@@ -109,5 +111,5 @@
 } fb_instance_t;
 
-static void fb_putchar(outdev_t *dev, wchar_t ch, bool silent);
+static void fb_putchar(outdev_t *dev, wchar_t ch);
 static void fb_redraw_internal(fb_instance_t *instance);
 static void fb_redraw(outdev_t *dev);
@@ -215,5 +217,5 @@
  *
  */
-static void logo_hide(fb_instance_t *instance, bool silent)
+static void logo_hide(fb_instance_t *instance)
 {
 	instance->ylogo = 0;
@@ -221,5 +223,5 @@
 	instance->rowtrim = instance->rows;
 	
-	if (!silent)
+	if ((!instance->parea.mapped) || (console_override))
 		fb_redraw_internal(instance);
 }
@@ -229,5 +231,5 @@
  */
 static void glyph_draw(fb_instance_t *instance, uint16_t glyph,
-    unsigned int col, unsigned int row, bool silent, bool overlay)
+    unsigned int col, unsigned int row, bool overlay)
 {
 	unsigned int x = COL2X(col);
@@ -236,10 +238,10 @@
 	
 	if (y >= instance->ytrim)
-		logo_hide(instance, silent);
+		logo_hide(instance);
 	
 	if (!overlay)
 		instance->backbuf[BB_POS(instance, col, row)] = glyph;
 	
-	if (!silent) {
+	if ((!instance->parea.mapped) || (console_override)) {
 		for (yd = 0; yd < FONT_SCANLINES; yd++)
 			memcpy(&instance->addr[FB_POS(instance, x, y + yd + instance->ylogo)],
@@ -253,12 +255,12 @@
  *
  */
-static void screen_scroll(fb_instance_t *instance, bool silent)
+static void screen_scroll(fb_instance_t *instance)
 {
 	if (instance->ylogo > 0) {
-		logo_hide(instance, silent);
+		logo_hide(instance);
 		return;
 	}
 	
-	if (!silent) {
+	if ((!instance->parea.mapped) || (console_override)) {
 		unsigned int row;
 		
@@ -298,13 +300,13 @@
 }
 
-static void cursor_put(fb_instance_t *instance, bool silent)
+static void cursor_put(fb_instance_t *instance)
 {
 	unsigned int col = instance->position % instance->cols;
 	unsigned int row = instance->position / instance->cols;
 	
-	glyph_draw(instance, fb_font_glyph(U_CURSOR), col, row, silent, true);
-}
-
-static void cursor_remove(fb_instance_t *instance, bool silent)
+	glyph_draw(instance, fb_font_glyph(U_CURSOR), col, row, true);
+}
+
+static void cursor_remove(fb_instance_t *instance)
 {
 	unsigned int col = instance->position % instance->cols;
@@ -312,5 +314,5 @@
 	
 	glyph_draw(instance, instance->backbuf[BB_POS(instance, col, row)],
-	    col, row, silent, true);
+	    col, row, true);
 }
 
@@ -362,5 +364,5 @@
  *
  */
-static void fb_putchar(outdev_t *dev, wchar_t ch, bool silent)
+static void fb_putchar(outdev_t *dev, wchar_t ch)
 {
 	fb_instance_t *instance = (fb_instance_t *) dev->data;
@@ -369,23 +371,23 @@
 	switch (ch) {
 	case '\n':
-		cursor_remove(instance, silent);
+		cursor_remove(instance);
 		instance->position += instance->cols;
 		instance->position -= instance->position % instance->cols;
 		break;
 	case '\r':
-		cursor_remove(instance, silent);
+		cursor_remove(instance);
 		instance->position -= instance->position % instance->cols;
 		break;
 	case '\b':
-		cursor_remove(instance, silent);
+		cursor_remove(instance);
 		if (instance->position % instance->cols)
 			instance->position--;
 		break;
 	case '\t':
-		cursor_remove(instance, silent);
+		cursor_remove(instance);
 		do {
 			glyph_draw(instance, fb_font_glyph(' '),
 			    instance->position % instance->cols,
-			    instance->position / instance->cols, silent, false);
+			    instance->position / instance->cols, false);
 			instance->position++;
 		} while ((instance->position % 8)
@@ -395,5 +397,5 @@
 		glyph_draw(instance, fb_font_glyph(ch),
 		    instance->position % instance->cols,
-		    instance->position / instance->cols, silent, false);
+		    instance->position / instance->cols, false);
 		instance->position++;
 	}
@@ -401,8 +403,8 @@
 	if (instance->position >= instance->cols * instance->rows) {
 		instance->position -= instance->cols;
-		screen_scroll(instance, silent);
-	}
-	
-	cursor_put(instance, silent);
+		screen_scroll(instance);
+	}
+	
+	cursor_put(instance);
 	
 	spinlock_unlock(&instance->lock);
@@ -555,4 +557,5 @@
 	
 	spinlock_initialize(&instance->lock, "*fb.instance.lock");
+	
 	instance->rgb_conv = rgb_conv;
 	instance->pixelbytes = pixelbytes;
@@ -623,8 +626,16 @@
 	glyphs_render(instance);
 	
+	link_initialize(&instance->parea.link);
+	instance->parea.pbase = props->addr;
+	instance->parea.frames = SIZE2FRAMES(fbsize);
+	instance->parea.unpriv = false;
+	instance->parea.mapped = false;
+	ddi_parea_register(&instance->parea);
+	
 	if (!fb_exported) {
 		/*
-		 * This is the necessary evil until the userspace driver is entirely
-		 * self-sufficient.
+		 * We export the kernel framebuffer for uspace usage.
+		 * This is used in the case the uspace framebuffer
+		 * driver is not self-sufficient.
 		 */
 		sysinfo_set_item_val("fb", NULL, true);
Index: rnel/genarch/src/ofw/fhc.c
===================================================================
--- kernel/genarch/src/ofw/fhc.c	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ 	(revision )
@@ -1,137 +1,0 @@
-/*
- * Copyright (c) 2006 Jakub Jermar
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/** @addtogroup ofw
- * @{
- */
-/**
- * @file
- * @brief	FHC 'reg' and 'ranges' properties handling.
- *
- */
-
-#include <genarch/ofw/ofw_tree.h>
-#include <genarch/ofw/fhc.h>
-#include <arch/drivers/fhc.h>
-#include <str.h>
-#include <panic.h>
-#include <macros.h>
-
-bool ofw_fhc_apply_ranges(ofw_tree_node_t *node, ofw_fhc_reg_t *reg, uintptr_t *pa)
-{
-	ofw_tree_property_t *prop;
-	ofw_fhc_range_t *range;
-	size_t ranges;
-
-	prop = ofw_tree_getprop(node, "ranges");
-	if (!prop)
-		return false;
-		
-	ranges = prop->size / sizeof(ofw_fhc_range_t);
-	range = prop->value;
-	
-	unsigned int i;
-	
-	for (i = 0; i < ranges; i++) {
-		if (overlaps(reg->addr, reg->size, range[i].child_base, range[i].size)) {
-			uintptr_t addr;
-			
-			addr = range[i].parent_base + (reg->addr - range[i].child_base);
-			if (!node->parent->parent) {
-				*pa = addr;
-				return true;
-			}
-			if (str_cmp(ofw_tree_node_name(node->parent), "central") != 0)
-				panic("Unexpected parent node: %s.", ofw_tree_node_name(node->parent));
-			
-			ofw_central_reg_t central_reg;
-			
-			central_reg.addr = addr;
-			central_reg.size = reg->size;
-			
-			return ofw_central_apply_ranges(node->parent, &central_reg, pa);
-		}
-	}
-
-	return false;
-}
-
-bool ofw_central_apply_ranges(ofw_tree_node_t *node, ofw_central_reg_t *reg, uintptr_t *pa)
-{
-	if (node->parent->parent)
-		panic("Unexpected parent node: %s.", ofw_tree_node_name(node->parent));
-	
-	ofw_tree_property_t *prop;
-	ofw_central_range_t *range;
-	size_t ranges;
-	
-	prop = ofw_tree_getprop(node, "ranges");
-	if (!prop)
-		return false;
-		
-	ranges = prop->size / sizeof(ofw_central_range_t);
-	range = prop->value;
-	
-	unsigned int i;
-	
-	for (i = 0; i < ranges; i++) {
-		if (overlaps(reg->addr, reg->size, range[i].child_base, range[i].size)) {
-			*pa = range[i].parent_base + (reg->addr - range[i].child_base);
-			return true;
-		}
-	}
-	
-	return false;
-}
-
-bool
-ofw_fhc_map_interrupt(ofw_tree_node_t *node, ofw_fhc_reg_t *reg,
-    uint32_t interrupt, int *inr, cir_t *cir, void **cir_arg)
-{
-	fhc_t *fhc = NULL;
-	if (!node->device) {
-		fhc = fhc_init(node);
-		if (!fhc)
-			return false;
-		node->device = fhc;
-		central_fhc = fhc;
-	}
-	
-	/*
-	 * The interrupt controller for the interrupt is the FHC itself.
-	 */
-	fhc_enable_interrupt(fhc, interrupt);
-	
-	*inr = interrupt;
-	*cir = fhc_clear_interrupt;
-	*cir_arg = fhc;
-	return true;
-}
-
-/** @}
- */
Index: kernel/generic/include/console/chardev.h
===================================================================
--- kernel/generic/include/console/chardev.h	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ kernel/generic/include/console/chardev.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -73,5 +73,5 @@
 typedef struct {
 	/** Write character to output. */
-	void (* write)(struct outdev *, wchar_t, bool);
+	void (* write)(struct outdev *, wchar_t);
 	
 	/** Redraw any previously cached characters. */
Index: kernel/generic/include/console/console.h
===================================================================
--- kernel/generic/include/console/console.h	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ kernel/generic/include/console/console.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -72,6 +72,5 @@
 extern void release_console(void);
 
-extern sysarg_t sys_debug_enable_console(void);
-extern sysarg_t sys_debug_disable_console(void);
+extern sysarg_t sys_debug_activate_console(void);
 
 #endif /* KERN_CONSOLE_H_ */
Index: kernel/generic/include/ddi/ddi.h
===================================================================
--- kernel/generic/include/ddi/ddi.h	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ kernel/generic/include/ddi/ddi.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -48,4 +48,6 @@
 	pfn_t frames;     /**< Number of frames in the area. */
 	bool unpriv;      /**< Allow mapping by unprivileged tasks. */
+	bool mapped;      /**< Indicate whether the area is actually
+	                       mapped. */
 } parea_t;
 
Index: kernel/generic/include/mm/as.h
===================================================================
--- kernel/generic/include/mm/as.h	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ kernel/generic/include/mm/as.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -65,4 +65,5 @@
 #include <arch/mm/as.h>
 #include <arch/mm/asid.h>
+#include <arch/istate.h>
 #include <typedefs.h>
 #include <synch/spinlock.h>
Index: kernel/generic/include/panic.h
===================================================================
--- kernel/generic/include/panic.h	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ kernel/generic/include/panic.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -60,5 +60,5 @@
 struct istate;
 
-extern bool silent;
+extern bool console_override;
 
 extern void panic_common(panic_category_t, struct istate *, int,
Index: kernel/generic/include/syscall/syscall.h
===================================================================
--- kernel/generic/include/syscall/syscall.h	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ kernel/generic/include/syscall/syscall.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -94,6 +94,5 @@
 	SYS_SYSINFO_GET_DATA,
 	
-	SYS_DEBUG_ENABLE_CONSOLE,
-	SYS_DEBUG_DISABLE_CONSOLE,
+	SYS_DEBUG_ACTIVATE_CONSOLE,
 	
 	SYSCALL_END
Index: kernel/generic/src/console/console.c
===================================================================
--- kernel/generic/src/console/console.c	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ kernel/generic/src/console/console.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -87,5 +87,5 @@
 };
 
-static void stdout_write(outdev_t *, wchar_t, bool);
+static void stdout_write(outdev_t *, wchar_t);
 static void stdout_redraw(outdev_t *);
 
@@ -95,6 +95,6 @@
 };
 
-/** Silence output */
-bool silent = false;
+/** Override kernel console lockout */
+bool console_override = false;
 
 /** Standard input and output character devices */
@@ -122,10 +122,10 @@
 }
 
-static void stdout_write(outdev_t *dev, wchar_t ch, bool silent)
+static void stdout_write(outdev_t *dev, wchar_t ch)
 {
 	list_foreach(dev->list, cur) {
 		outdev_t *sink = list_get_instance(cur, outdev_t, link);
 		if ((sink) && (sink->op->write))
-			sink->op->write(sink, ch, silent);
+			sink->op->write(sink, ch);
 	}
 }
@@ -156,4 +156,5 @@
 	klog_parea.frames = SIZE2FRAMES(sizeof(klog));
 	klog_parea.unpriv = false;
+	klog_parea.mapped = false;
 	ddi_parea_register(&klog_parea);
 	
@@ -167,11 +168,11 @@
 void grab_console(void)
 {
-	bool prev = silent;
-	
-	silent = false;
+	bool prev = console_override;
+	
+	console_override = true;
 	if ((stdout) && (stdout->op->redraw))
 		stdout->op->redraw(stdout);
 	
-	if ((stdin) && (prev)) {
+	if ((stdin) && (!prev)) {
 		/*
 		 * Force the console to print the prompt.
@@ -183,10 +184,9 @@
 void release_console(void)
 {
-	// FIXME arch_release_console
-	silent = true;
-}
-
-/** Tell kernel to get keyboard/console access again */
-sysarg_t sys_debug_enable_console(void)
+	console_override = false;
+}
+
+/** Activate kernel console override */
+sysarg_t sys_debug_activate_console(void)
 {
 #ifdef CONFIG_KCONSOLE
@@ -196,11 +196,4 @@
 	return false;
 #endif
-}
-
-/** Tell kernel to relinquish keyboard/console access */
-sysarg_t sys_debug_disable_console(void)
-{
-	release_console();
-	return true;
 }
 
@@ -289,5 +282,5 @@
 			 */
 			spinlock_unlock(&klog_lock);
-			stdout->op->write(stdout, tmp, silent);
+			stdout->op->write(stdout, tmp);
 			spinlock_lock(&klog_lock);
 		}
@@ -317,5 +310,5 @@
 		 * it should be no longer buffered.
 		 */
-		stdout->op->write(stdout, ch, silent);
+		stdout->op->write(stdout, ch);
 	} else {
 		/*
Index: kernel/generic/src/ddi/ddi.c
===================================================================
--- kernel/generic/src/ddi/ddi.c	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ kernel/generic/src/ddi/ddi.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -122,5 +122,31 @@
 	backend_data.frames = pages;
 	
-	/* Find the zone of the physical memory */
+	/*
+	 * Check if the memory region is explicitly enabled
+	 * for mapping by any parea structure.
+	 */
+	
+	mutex_lock(&parea_lock);
+	btree_node_t *nodep;
+	parea_t *parea = (parea_t *) btree_search(&parea_btree,
+	    (btree_key_t) pf, &nodep);
+	
+	if ((parea != NULL) && (parea->frames >= pages)) {
+		if ((!priv) && (!parea->unpriv)) {
+			mutex_unlock(&parea_lock);
+			return EPERM;
+		}
+		
+		goto map;
+	}
+	
+	parea = NULL;
+	mutex_unlock(&parea_lock);
+	
+	/*
+	 * Check if the memory region is part of physical
+	 * memory generally enabled for mapping.
+	 */
+	
 	irq_spinlock_lock(&zones.lock, true);
 	size_t znum = find_zone(ADDR2PFN(pf), pages, 0);
@@ -153,32 +179,4 @@
 	}
 	
-	if (zone_flags_available(zones.info[znum].flags)) {
-		/*
-		 * Frames are part of physical memory, check
-		 * if the memory region is enabled for mapping.
-		 */
-		irq_spinlock_unlock(&zones.lock, true);
-		
-		mutex_lock(&parea_lock);
-		btree_node_t *nodep;
-		parea_t *parea = (parea_t *) btree_search(&parea_btree,
-		    (btree_key_t) pf, &nodep);
-		
-		if ((!parea) || (parea->frames < pages)) {
-			mutex_unlock(&parea_lock);
-			return ENOENT;
-		}
-		
-		if (!priv) {
-			if (!parea->unpriv) {
-				mutex_unlock(&parea_lock);
-				return EPERM;
-			}
-		}
-		
-		mutex_unlock(&parea_lock);
-		goto map;
-	}
-	
 	irq_spinlock_unlock(&zones.lock, true);
 	return ENOENT;
@@ -188,7 +186,11 @@
 	    AS_AREA_ATTR_NONE, &phys_backend, &backend_data)) {
 		/*
-		 * The address space area could not have been created.
+		 * The address space area was not created.
 		 * We report it using ENOMEM.
 		 */
+		
+		if (parea != NULL)
+			mutex_unlock(&parea_lock);
+		
 		return ENOMEM;
 	}
@@ -197,5 +199,11 @@
 	 * Mapping is created on-demand during page fault.
 	 */
-	return 0;
+	
+	if (parea != NULL) {
+		parea->mapped = true;
+		mutex_unlock(&parea_lock);
+	}
+	
+	return EOK;
 }
 
Index: kernel/generic/src/ddi/irq.c
===================================================================
--- kernel/generic/src/ddi/irq.c	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ kernel/generic/src/ddi/irq.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -275,24 +275,26 @@
 {
 	/*
-	 * If the kernel console is silenced,
-	 * then try first the uspace handlers,
-	 * eventually fall back to kernel handlers.
+	 * If the kernel console override is on,
+	 * then try first the kernel handlers
+	 * and eventually fall back to uspace
+	 * handlers.
 	 *
-	 * If the kernel console is active,
-	 * then do it the other way around.
+	 * In the usual case the uspace handlers
+	 * have precedence.
 	 */
-	if (silent) {
-		irq_t *irq = irq_dispatch_and_lock_uspace(inr);
+	
+	if (console_override) {
+		irq_t *irq = irq_dispatch_and_lock_kernel(inr);
 		if (irq)
 			return irq;
 		
-		return irq_dispatch_and_lock_kernel(inr);
-	}
-	
-	irq_t *irq = irq_dispatch_and_lock_kernel(inr);
+		return irq_dispatch_and_lock_uspace(inr);
+	}
+	
+	irq_t *irq = irq_dispatch_and_lock_uspace(inr);
 	if (irq)
 		return irq;
 	
-	return irq_dispatch_and_lock_uspace(inr);
+	return irq_dispatch_and_lock_kernel(inr);
 }
 
Index: kernel/generic/src/debug/panic.c
===================================================================
--- kernel/generic/src/debug/panic.c	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ kernel/generic/src/debug/panic.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -48,7 +48,5 @@
     uintptr_t address, const char *fmt, ...)
 {
-	va_list args;
-	
-	silent = false;
+	console_override = true;
 	
 	printf("\n%s Kernel panic ", BANNER_LEFT);
@@ -57,4 +55,5 @@
 	printf("due to ");
 	
+	va_list args;
 	va_start(args, fmt);
 	if (cat == PANIC_ASSERT) {
Index: kernel/generic/src/lib/rd.c
===================================================================
--- kernel/generic/src/lib/rd.c	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ kernel/generic/src/lib/rd.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -91,4 +91,5 @@
 	rd_parea.frames = SIZE2FRAMES(dsize);
 	rd_parea.unpriv = false;
+	rd_parea.mapped = false;
 	ddi_parea_register(&rd_parea);
 
Index: kernel/generic/src/mm/as.c
===================================================================
--- kernel/generic/src/mm/as.c	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ kernel/generic/src/mm/as.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -1284,5 +1284,5 @@
  * thing which is forbidden in this context is locking the address space.
  *
- * When this function is enetered, no spinlocks may be held.
+ * When this function is entered, no spinlocks may be held.
  *
  * @param old Old address space or NULL.
Index: kernel/generic/src/syscall/syscall.c
===================================================================
--- kernel/generic/src/syscall/syscall.c	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ kernel/generic/src/syscall/syscall.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -186,7 +186,6 @@
 	(syshandler_t) sys_sysinfo_get_data,
 	
-	/* Debug calls */
-	(syshandler_t) sys_debug_enable_console,
-	(syshandler_t) sys_debug_disable_console
+	/* Kernel console syscalls. */
+	(syshandler_t) sys_debug_activate_console
 };
 
Index: kernel/generic/src/time/clock.c
===================================================================
--- kernel/generic/src/time/clock.c	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ kernel/generic/src/time/clock.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -94,4 +94,5 @@
 	clock_parea.frames = 1;
 	clock_parea.unpriv = true;
+	clock_parea.mapped = false;
 	ddi_parea_register(&clock_parea);
 	
Index: release/Makefile
===================================================================
--- release/Makefile	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ release/Makefile	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -34,5 +34,5 @@
 PROFILES = amd64 arm32/GXemul arm32/integratorcp arm32/gta02 ia32 \
     ia64/i460GX ia64/ski mips32/GXemul mips32/msim sparc64/niagara \
-    sparc64/serengeti sparc64/ultra
+    sparc64/ultra
 
 BZR = bzr
Index: tools/autotool.py
===================================================================
--- tools/autotool.py	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ tools/autotool.py	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -243,5 +243,7 @@
 	outf.close()
 	
-	args = [common['CC'], "-S", "-o", PROBE_OUTPUT, PROBE_SOURCE]
+	args = [common['CC']]
+	args.extend(common['CC_ARGS'])
+	args.extend(["-S", "-o", PROBE_OUTPUT, PROBE_SOURCE])
 	
 	try:
@@ -361,4 +363,7 @@
 		typedefs.append({'oldtype': "signed %s" % probe['signed_sizes'][b], 'newtype': "int%u_t" % (b * 8)})
 		
+		macros.append({'oldmacro': "unsigned %s" % probe['unsigned_sizes'][b], 'newmacro': "UINT%u_T" % (b * 8)})
+		macros.append({'oldmacro': "signed %s" % probe['signed_sizes'][b], 'newmacro': "INT%u_T" % (b * 8)})
+		
 		macros.append({'oldmacro': "\"%so\"" % probe['unsigned_strcs'][b], 'newmacro': "PRIo%u" % (b * 8)})
 		macros.append({'oldmacro': "\"%su\"" % probe['unsigned_strcs'][b], 'newmacro': "PRIu%u" % (b * 8)})
@@ -523,4 +528,5 @@
 		
 		# Compiler
+		common['CC_ARGS'] = []
 		if (config['COMPILER'] == "gcc_cross"):
 			if (config['PLATFORM'] == "abs32le"):
@@ -536,4 +542,5 @@
 				if (config['CROSS_TARGET'] == "mips32"):
 					gnu_target = "mipsel-linux-gnu"
+					common['CC_ARGS'].append("-mabi=32")
 			
 			if (config['PLATFORM'] == "amd64"):
@@ -555,4 +562,5 @@
 			if (config['PLATFORM'] == "mips32"):
 				check_config(config, "MACHINE")
+				common['CC_ARGS'].append("-mabi=32")
 				
 				if ((config['MACHINE'] == "lgxemul") or (config['MACHINE'] == "msim")):
@@ -563,4 +571,12 @@
 					target = "mips32eb"
 					gnu_target = "mips-linux-gnu"
+			
+			if (config['PLATFORM'] == "mips64"):
+				check_config(config, "MACHINE")
+				common['CC_ARGS'].append("-mabi=64")
+				
+				if (config['MACHINE'] == "msim"):
+					target = config['PLATFORM']
+					gnu_target = "mips64el-linux-gnu"
 			
 			if (config['PLATFORM'] == "ppc32"):
Index: tools/toolchain.sh
===================================================================
--- tools/toolchain.sh	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ tools/toolchain.sh	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -54,5 +54,5 @@
 
 BINUTILS_VERSION="2.21"
-GCC_VERSION="4.6.0"
+GCC_VERSION="4.6.1"
 GDB_VERSION="7.2"
 
@@ -274,7 +274,7 @@
 	
 	download_fetch "${BINUTILS_SOURCE}" "${BINUTILS}" "c84c5acc9d266f1a7044b51c85a823f5"
-	download_fetch "${GCC_SOURCE}" "${GCC_CORE}" "b1957f3209080b2f55bc3756d3a62b7c"
-	download_fetch "${GCC_SOURCE}" "${GCC_OBJC}" "120d4675366ee82ea52f9ed65b57da04"
-	download_fetch "${GCC_SOURCE}" "${GCC_CPP}" "a30090fa655d0db4c970740d353c81f1"
+	download_fetch "${GCC_SOURCE}" "${GCC_CORE}" "0c0e7e35d2215e19de9c97efba507553"
+	download_fetch "${GCC_SOURCE}" "${GCC_OBJC}" "cbf0d4b701827922cf37ba6a4ace0079"
+	download_fetch "${GCC_SOURCE}" "${GCC_CPP}" "0d75ca7ca35b1e7f252223f9d23a6ad1"
 	download_fetch "${GDB_SOURCE}" "${GDB}" "64260e6c56979ee750a01055f16091a5"
 }
Index: uspace/Makefile
===================================================================
--- uspace/Makefile	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/Makefile	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -153,5 +153,4 @@
 ifeq ($(UARCH),sparc64)
 	DIRS += \
-		srv/hw/irc/fhc \
 		srv/hw/irc/obio
 endif
@@ -165,4 +164,5 @@
 	lib/block \
 	lib/clui \
+	lib/scsi \
 	lib/softint \
 	lib/softfloat \
Index: uspace/Makefile.common
===================================================================
--- uspace/Makefile.common	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/Makefile.common	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -124,4 +124,6 @@
 LIBNET_PREFIX = $(LIB_PREFIX)/net
 
+LIBSCSI_PREFIX = $(LIB_PREFIX)/scsi
+
 ifeq ($(STATIC_NEEDED),y)
 	STATIC_BUILD = y
Index: uspace/app/ext2info/ext2info.c
===================================================================
--- uspace/app/ext2info/ext2info.c	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/app/ext2info/ext2info.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -590,5 +590,5 @@
 	printf("  Directory contents:\n");
 	
-	rc = ext2_directory_iterator_init(&it, fs, inode_ref);
+	rc = ext2_directory_iterator_init(&it, fs, inode_ref, 0);
 	if (rc != EOK) {
 		printf("Failed initializing directory iterator\n");
Index: uspace/app/init/init.c
===================================================================
--- uspace/app/init/init.c	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/app/init/init.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -270,5 +270,4 @@
 	spawn("/srv/apic");
 	spawn("/srv/i8259");
-	spawn("/srv/fhc");
 	spawn("/srv/obio");
 	srv_start("/srv/cuda_adb");
Index: uspace/app/ping/ping.c
===================================================================
--- uspace/app/ping/ping.c	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/app/ping/ping.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -36,5 +36,4 @@
 
 #include <async.h>
-#include <async_obsolete.h>
 #include <stdio.h>
 #include <str.h>
@@ -341,9 +340,9 @@
 	    config.dest_str, config.size, config.size);
 	
-	int icmp_phone = icmp_connect_module();
-	if (icmp_phone < 0) {
+	async_sess_t *sess = icmp_connect_module();
+	if (!sess) {
 		fprintf(stderr, "%s: Unable to connect to ICMP service (%s)\n", NAME,
-		    str_error(icmp_phone));
-		return icmp_phone;
+		    str_error(errno));
+		return errno;
 	}
 	
@@ -356,10 +355,10 @@
 			    str_error(ret));
 			
-			async_obsolete_hangup(icmp_phone);
+			async_hangup(sess);
 			return ret;
 		}
 		
 		/* Ping! */
-		int result = icmp_echo_msg(icmp_phone, config.size, config.timeout,
+		int result = icmp_echo_msg(sess, config.size, config.timeout,
 		    config.ttl, config.tos, !config.fragments, config.dest_raw,
 		    config.dest_len);
@@ -371,5 +370,5 @@
 			    str_error(ret));
 			
-			async_obsolete_hangup(icmp_phone);
+			async_hangup(sess);
 			return ret;
 		}
@@ -391,5 +390,5 @@
 	}
 	
-	async_obsolete_hangup(icmp_phone);
+	async_hangup(sess);
 	
 	return 0;
Index: uspace/app/trace/syscalls.c
===================================================================
--- uspace/app/trace/syscalls.c	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/app/trace/syscalls.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -80,5 +80,5 @@
     [SYS_SYSINFO_GET_DATA] = { "sysinfo_get_data",		5,	V_ERRNO },
 
-    [SYS_DEBUG_ENABLE_CONSOLE] = { "debug_enable_console", 0,	V_ERRNO },
+    [SYS_DEBUG_ACTIVATE_CONSOLE] = { "debug_activate_console", 0,	V_ERRNO },
     [SYS_IPC_CONNECT_KBOX] = { "ipc_connect_kbox",	1,	V_ERRNO }
 };
Index: uspace/drv/bus/usb/uhci/transfer_list.c
===================================================================
--- uspace/drv/bus/usb/uhci/transfer_list.c	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/drv/bus/usb/uhci/transfer_list.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -141,5 +141,5 @@
 	list_append(&batch->link, &instance->batch_list);
 
-	usb_log_debug("Batch %p " USB_TRANSFER_BATCH_FMT " scheduled in queue %s.\n",
+	usb_log_debug2("Batch %p " USB_TRANSFER_BATCH_FMT " scheduled in queue %s.\n",
 	    batch, USB_TRANSFER_BATCH_ARGS(*batch), instance->name);
 	fibril_mutex_unlock(&instance->guard);
Index: uspace/drv/bus/usb/usbmast/Makefile
===================================================================
--- uspace/drv/bus/usb/usbmast/Makefile	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/drv/bus/usb/usbmast/Makefile	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -32,17 +32,20 @@
 	$(LIBUSBDEV_PREFIX)/libusbdev.a \
 	$(LIBUSB_PREFIX)/libusb.a \
-	$(LIBDRV_PREFIX)/libdrv.a
+	$(LIBDRV_PREFIX)/libdrv.a \
+	$(LIBSCSI_PREFIX)/libscsi.a
 
 EXTRA_CFLAGS += \
 	-I$(LIBUSB_PREFIX)/include \
 	-I$(LIBUSBDEV_PREFIX)/include \
-	-I$(LIBDRV_PREFIX)/include
+	-I$(LIBDRV_PREFIX)/include \
+	-I$(LIBSCSI_PREFIX)/include
 
 BINARY = usbmast
 
 SOURCES = \
-	inquiry.c \
+	cmds.c \
 	main.c \
-	mast.c
+	mast.c \
+	scsi_ms.c
 
 include $(USPACE_PREFIX)/Makefile.common
Index: uspace/drv/bus/usb/usbmast/cmds.c
===================================================================
--- uspace/drv/bus/usb/usbmast/cmds.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
+++ uspace/drv/bus/usb/usbmast/cmds.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2011 Vojtech Horky
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup drvusbmast
+ * @{
+ */
+/** @file
+ * USB mass storage commands.
+ */
+
+#include <byteorder.h>
+#include <mem.h>
+#include <sys/types.h>
+#include <usb/usb.h>
+#include "cmds.h"
+
+void usb_massstor_cbw_prepare(usb_massstor_cbw_t *cbw,
+    uint32_t tag, uint32_t transfer_length, usb_direction_t dir,
+    uint8_t lun, uint8_t cmd_len, const uint8_t *cmd)
+{
+	cbw->dCBWSignature = uint32_host2usb(0x43425355);
+	cbw->dCBWTag = tag;
+	cbw->dCBWDataTransferLength = transfer_length;
+
+	cbw->bmCBWFlags = 0;
+	if (dir == USB_DIRECTION_IN) {
+		cbw->bmCBWFlags |= (1 << 7);
+	}
+
+	/* Only lowest 4 bits. */
+	cbw->bCBWLUN = lun & 0x0F;
+
+	/* Only lowest 5 bits. */
+	cbw->bCBWBLength = cmd_len & 0x1F;
+
+	memcpy(cbw->CBWCB, cmd, cbw->bCBWBLength);
+}
+
+/**
+ * @}
+ */
Index: uspace/drv/bus/usb/usbmast/cmds.h
===================================================================
--- uspace/drv/bus/usb/usbmast/cmds.h	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/drv/bus/usb/usbmast/cmds.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -57,25 +57,6 @@
 } __attribute__((packed)) usb_massstor_csw_t;
 
-static inline void usb_massstor_cbw_prepare(usb_massstor_cbw_t *cbw,
-    uint32_t tag, uint32_t transfer_length, usb_direction_t dir,
-    uint8_t lun, uint8_t cmd_len, uint8_t *cmd)
-{
-	cbw->dCBWSignature = uint32_host2usb(0x43425355);
-	cbw->dCBWTag = tag;
-	cbw->dCBWDataTransferLength = transfer_length;
-
-	cbw->bmCBWFlags = 0;
-	if (dir == USB_DIRECTION_IN) {
-		cbw->bmCBWFlags |= (1 << 7);
-	}
-
-	/* Only lowest 4 bits. */
-	cbw->bCBWLUN = lun & 0x0F;
-
-	/* Only lowest 5 bits. */
-	cbw->bCBWBLength = cmd_len & 0x1F;
-
-	memcpy(cbw->CBWCB, cmd, cbw->bCBWBLength);
-}
+extern void usb_massstor_cbw_prepare(usb_massstor_cbw_t *, uint32_t, uint32_t,
+    usb_direction_t, uint8_t, uint8_t, const uint8_t *);
 
 #endif
Index: pace/drv/bus/usb/usbmast/inquiry.c
===================================================================
--- uspace/drv/bus/usb/usbmast/inquiry.c	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ 	(revision )
@@ -1,193 +1,0 @@
-/*
- * Copyright (c) 2011 Vojtech Horky
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/** @addtogroup drvusbmast
- * @{
- */
-/**
- * @file
- * Main routines of USB mass storage driver.
- */
-#include <usb/dev/driver.h>
-#include <usb/debug.h>
-#include <usb/classes/classes.h>
-#include <usb/classes/massstor.h>
-#include <errno.h>
-#include <str_error.h>
-#include <str.h>
-#include <ctype.h>
-#include "cmds.h"
-#include "scsi.h"
-#include "mast.h"
-
-#define BITS_GET_MASK(type, bitcount) (((type)(1 << (bitcount)))-1)
-#define BITS_GET_MID_MASK(type, bitcount, offset) \
-	((type)( BITS_GET_MASK(type, (bitcount) + (offset)) - BITS_GET_MASK(type, bitcount) ))
-#define BITS_GET(type, number, bitcount, offset) \
-	((type)( (number) & (BITS_GET_MID_MASK(type, bitcount, offset)) ) >> (offset))
-
-#define INQUIRY_RESPONSE_LENGTH 36
-
-#define STR_UNKNOWN "<unknown>"
-
-/** String constants for SCSI peripheral device types. */
-static const char *str_peripheral_device_types[] = {
-	"direct-access device",
-	"sequential-access device",
-	"printer device",
-	"processor device",
-	"write-once device",
-	"CDROM device",
-	"scanner device",
-	"optical memory device",
-	"medium changer",
-	"communications device",
-	"graphic arts pre-press device",
-	"graphic arts pre-press device",
-	"storage array controller device",
-	"enclosure services device",
-	"simplified direct-access device",
-	"optical card reader/writer device",
-	"bridging expander",
-	"object-based storage device",
-	"automation driver interface",
-	STR_UNKNOWN, // 0x13
-	STR_UNKNOWN, // 0x14
-	STR_UNKNOWN, // 0x15
-	STR_UNKNOWN, // 0x16
-	STR_UNKNOWN, // 0x17
-	STR_UNKNOWN, // 0x18
-	STR_UNKNOWN, // 0x19
-	STR_UNKNOWN, // 0x1A
-	STR_UNKNOWN, // 0x1B
-	STR_UNKNOWN, // 0x1C
-	STR_UNKNOWN, // 0x1D
-	"well-known logical unit",
-	"uknown or no device state"
-};
-#define str_peripheral_device_types_count \
-	(sizeof(str_peripheral_device_types)/sizeof(str_peripheral_device_types[0]))
-
-/** Get string representation for SCSI peripheral device type.
- *
- * See for example here for a list
- * http://en.wikipedia.org/wiki/SCSI_Peripheral_Device_Type.
- *
- * @param type SCSI peripheral device type code.
- * @return String representation.
- */
-const char *usb_str_masstor_scsi_peripheral_device_type(int type)
-{
-	if ((type < 0)
-	    || ((size_t)type >= str_peripheral_device_types_count)) {
-		return STR_UNKNOWN;
-	}
-	return str_peripheral_device_types[type];
-}
-
-/** Trim trailing spaces from a string (rewrite with string terminator).
- *
- * @param name String to be trimmed (in-out parameter).
- */
-static void trim_trailing_spaces(char *name)
-{
-	size_t len = str_length(name);
-	while ((len > 0) && isspace((int) name[len - 1])) {
-		name[len - 1] = 0;
-		len--;
-	}
-}
-
-/** Perform SCSI INQUIRY command on USB mass storage device.
- *
- * @param dev USB device.
- * @param bulk_in_idx Index (in dev->pipes) of bulk in pipe.
- * @param bulk_out_idx Index of bulk out pipe.
- * @param inquiry_result Where to store parsed inquiry result.
- * @return Error code.
- */
-int usb_massstor_inquiry(usb_device_t *dev,
-    size_t bulk_in_idx, size_t bulk_out_idx,
-    usb_massstor_inquiry_result_t *inquiry_result)
-{
-	scsi_cmd_inquiry_t inquiry = {
-		.op_code = 0x12,
-		.lun_evpd = 0,
-		.page_code = 0,
-		.alloc_length = host2uint16_t_be(INQUIRY_RESPONSE_LENGTH),
-		.ctrl = 0
-	};
-	size_t response_len;
-	uint8_t response[INQUIRY_RESPONSE_LENGTH];
-
-	int rc;
-
-	rc = usb_massstor_data_in(dev, bulk_in_idx, bulk_out_idx,
-	    0xDEADBEEF, 0, (uint8_t *) &inquiry, sizeof(inquiry),
-	    response, INQUIRY_RESPONSE_LENGTH, &response_len);
-
-	if (rc != EOK) {
-		usb_log_error("Failed to probe device %s using %s: %s.\n",
-		   dev->ddf_dev->name, "SCSI:INQUIRY", str_error(rc));
-		return rc;
-	}
-
-	if (response_len < 8) {
-		usb_log_error("The SCSI response is too short.\n");
-		return ERANGE;
-	}
-
-	/*
-	 * This is an ugly part of the code. We will parse the returned
-	 * data by hand and try to get as many useful data as possible.
-	 */
-	bzero(inquiry_result, sizeof(*inquiry_result));
-
-	/* This shall be returned by all devices. */
-	inquiry_result->peripheral_device_type
-	    = BITS_GET(uint8_t, response[0], 5, 0);
-	inquiry_result->removable = BITS_GET(uint8_t, response[1], 1, 7);
-
-	if (response_len < 32) {
-		return EOK;
-	}
-
-	str_ncpy(inquiry_result->vendor_id, 9,
-	    (const char *) &response[8], 8);
-	trim_trailing_spaces(inquiry_result->vendor_id);
-
-	str_ncpy(inquiry_result->product_and_revision, 12,
-	    (const char *) &response[16], 11);
-	trim_trailing_spaces(inquiry_result->product_and_revision);
-
-	return EOK;
-}
-
-/**
- * @}
- */
Index: uspace/drv/bus/usb/usbmast/main.c
===================================================================
--- uspace/drv/bus/usb/usbmast/main.c	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/drv/bus/usb/usbmast/main.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -1,4 +1,5 @@
 /*
  * Copyright (c) 2011 Vojtech Horky
+ * Copyright (c) 2011 Jiri Svoboda
  * All rights reserved.
  *
@@ -34,4 +35,8 @@
  * Main routines of USB mass storage driver.
  */
+#include <as.h>
+#include <async.h>
+#include <ipc/bd.h>
+#include <macros.h>
 #include <usb/dev/driver.h>
 #include <usb/debug.h>
@@ -41,11 +46,8 @@
 #include <str_error.h>
 #include "cmds.h"
-#include "scsi.h"
 #include "mast.h"
+#include "scsi_ms.h"
 
 #define NAME "usbmast"
-
-#define BULK_IN_EP 0
-#define BULK_OUT_EP 1
 
 #define GET_BULK_IN(dev) ((dev)->pipes[BULK_IN_EP].pipe)
@@ -75,4 +77,22 @@
 };
 
+/** Mass storage function.
+ *
+ * Serves as soft state for function/LUN.
+ */
+typedef struct {
+	/** DDF function */
+	ddf_fun_t *ddf_fun;
+	/** Total number of blocks. */
+	uint64_t nblocks;
+	/** Block size in bytes. */
+	size_t block_size;
+	/** USB device function belongs to */
+	usb_device_t *usb_dev;
+} usbmast_fun_t;
+
+static void usbmast_bd_connection(ipc_callid_t iid, ipc_call_t *icall,
+    void *arg);
+
 /** Callback when new device is attached and recognized as a mass storage.
  *
@@ -83,20 +103,28 @@
 {
 	int rc;
-	const char *fun_name = "ctl";
-
-	ddf_fun_t *ctl_fun = ddf_fun_create(dev->ddf_dev, fun_exposed,
-	    fun_name);
-	if (ctl_fun == NULL) {
-		usb_log_error("Failed to create control function.\n");
-		return ENOMEM;
-	}
-	rc = ddf_fun_bind(ctl_fun);
-	if (rc != EOK) {
-		usb_log_error("Failed to bind control function: %s.\n",
-		    str_error(rc));
-		return rc;
-	}
-
-	usb_log_info("Pretending to control mass storage `%s'.\n",
+	const char *fun_name = "a";
+	ddf_fun_t *fun = NULL;
+	usbmast_fun_t *msfun = NULL;
+
+	/* Allocate softstate */
+	msfun = calloc(1, sizeof(usbmast_fun_t));
+	if (msfun == NULL) {
+		usb_log_error("Failed allocating softstate.\n");
+		rc = ENOMEM;
+		goto error;
+	}
+
+	fun = ddf_fun_create(dev->ddf_dev, fun_exposed, fun_name);
+	if (fun == NULL) {
+		usb_log_error("Failed to create DDF function %s.\n", fun_name);
+		rc = ENOMEM;
+		goto error;
+	}
+
+	/* Set up a connection handler. */
+	fun->conn_handler = usbmast_bd_connection;
+	fun->driver_data = msfun;
+
+	usb_log_info("Initializing mass storage `%s'.\n",
 	    dev->ddf_dev->name);
 	usb_log_debug(" Bulk in endpoint: %d [%zuB].\n",
@@ -107,23 +135,136 @@
 	    (size_t) dev->pipes[BULK_OUT_EP].descriptor->max_packet_size);
 
+	usb_log_debug("Get LUN count...\n");
 	size_t lun_count = usb_masstor_get_lun_count(dev);
 
-	usb_massstor_inquiry_result_t inquiry;
-	rc = usb_massstor_inquiry(dev, BULK_IN_EP, BULK_OUT_EP, &inquiry);
+	/* XXX Handle more than one LUN properly. */
+	if (lun_count > 1) {
+		usb_log_warning ("Mass storage has %zu LUNs. Ignoring all "
+		    "but first.\n", lun_count);
+	}
+
+	usb_log_debug("Inquire...\n");
+	usbmast_inquiry_data_t inquiry;
+	rc = usbmast_inquiry(dev, &inquiry);
 	if (rc != EOK) {
-		usb_log_warning("Failed to inquiry device `%s': %s.\n",
+		usb_log_warning("Failed to inquire device `%s': %s.\n",
 		    dev->ddf_dev->name, str_error(rc));
-		return EOK;
+		rc = EIO;
+		goto error;
 	}
 
 	usb_log_info("Mass storage `%s': " \
-	    "`%s' by `%s' is %s (%s), %zu LUN(s).\n",
+	    "%s by %s rev. %s is %s (%s), %zu LUN(s).\n",
 	    dev->ddf_dev->name,
-	    inquiry.product_and_revision, inquiry.vendor_id,
-	    usb_str_masstor_scsi_peripheral_device_type(inquiry.peripheral_device_type),
+	    inquiry.product,
+	    inquiry.vendor,
+	    inquiry.revision,
+	    usbmast_scsi_dev_type_str(inquiry.device_type),
 	    inquiry.removable ? "removable" : "non-removable",
 	    lun_count);
 
+	uint32_t nblocks, block_size;
+
+	rc = usbmast_read_capacity(dev, &nblocks, &block_size);
+	if (rc != EOK) {
+		usb_log_warning("Failed to read capacity, device `%s': %s.\n",
+		    dev->ddf_dev->name, str_error(rc));
+		rc = EIO;
+		goto error;
+	}
+
+	usb_log_info("Read Capacity: nblocks=%" PRIu32 ", "
+	    "block_size=%" PRIu32 "\n", nblocks, block_size);
+
+	msfun->nblocks = nblocks;
+	msfun->block_size = block_size;
+	msfun->usb_dev = dev;
+
+	rc = ddf_fun_bind(fun);
+	if (rc != EOK) {
+		usb_log_error("Failed to bind DDF function %s: %s.\n",
+		    fun_name, str_error(rc));
+		goto error;
+	}
+
 	return EOK;
+
+	/* Error cleanup */
+error:
+	if (fun != NULL)
+		ddf_fun_destroy(fun);
+	if (msfun != NULL)
+		free(msfun);
+	return rc;
+}
+
+/** Blockdev client connection handler. */
+static void usbmast_bd_connection(ipc_callid_t iid, ipc_call_t *icall,
+    void *arg)
+{
+	usbmast_fun_t *msfun;
+	void *comm_buf = NULL;
+	size_t comm_size;
+	ipc_callid_t callid;
+	ipc_call_t call;
+	unsigned int flags;
+	sysarg_t method;
+	uint64_t ba;
+	size_t cnt;
+	int retval;
+
+	async_answer_0(iid, EOK);
+
+	if (!async_share_out_receive(&callid, &comm_size, &flags)) {
+		async_answer_0(callid, EHANGUP);
+		return;
+	}
+
+	comm_buf = as_get_mappable_page(comm_size);
+	if (comm_buf == NULL) {
+		async_answer_0(callid, EHANGUP);
+		return;
+	}
+
+	(void) async_share_out_finalize(callid, comm_buf);
+
+	msfun = (usbmast_fun_t *) ((ddf_fun_t *)arg)->driver_data;
+
+	while (true) {
+		callid = async_get_call(&call);
+		method = IPC_GET_IMETHOD(call);
+
+		if (!method) {
+			/* The other side hung up. */
+			async_answer_0(callid, EOK);
+			return;
+		}
+
+		switch (method) {
+		case BD_GET_BLOCK_SIZE:
+			async_answer_1(callid, EOK, msfun->block_size);
+			break;
+		case BD_GET_NUM_BLOCKS:
+			async_answer_2(callid, EOK, LOWER32(msfun->nblocks),
+			    UPPER32(msfun->nblocks));
+			break;
+		case BD_READ_BLOCKS:
+			ba = MERGE_LOUP32(IPC_GET_ARG1(call), IPC_GET_ARG2(call));
+			cnt = IPC_GET_ARG3(call);
+			retval = usbmast_read(msfun->usb_dev, ba, cnt,
+			    msfun->block_size, comm_buf);
+			async_answer_0(callid, retval);
+			break;
+		case BD_WRITE_BLOCKS:
+			ba = MERGE_LOUP32(IPC_GET_ARG1(call), IPC_GET_ARG2(call));
+			cnt = IPC_GET_ARG3(call);
+			retval = usbmast_write(msfun->usb_dev, ba, cnt,
+			    msfun->block_size, comm_buf);
+			async_answer_0(callid, retval);
+			break;
+		default:
+			async_answer_0(callid, EINVAL);
+		}
+	}
 }
 
Index: uspace/drv/bus/usb/usbmast/mast.c
===================================================================
--- uspace/drv/bus/usb/usbmast/mast.c	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/drv/bus/usb/usbmast/mast.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -42,42 +42,42 @@
 #include <usb/dev/request.h>
 
-bool usb_mast_verbose = true;
+bool usb_mast_verbose = false;
 
 #define MASTLOG(format, ...) \
 	do { \
 		if (usb_mast_verbose) { \
-			usb_log_debug("USB cl08: " format, ##__VA_ARGS__); \
+			usb_log_debug2("USB cl08: " format, ##__VA_ARGS__); \
 		} \
 	} while (false)
 
-/** Request data from mass storage device.
- *
- * @param bulk_in_pipe Bulk in pipe to the device.
- * @param bulk_out_pipe Bulk out pipe to the device.
- * @param tag Command block wrapper tag (automatically compared with answer).
- * @param lun LUN index.
- * @param cmd SCSI command buffer (in SCSI endianness).
- * @param cmd_size Length of SCSI command @p cmd in bytes.
- * @param in_buffer Buffer where to store the answer (CSW is not returned).
- * @param in_buffer_size Size of the buffer (size of the request to the device).
- * @param received_size Number of actually received bytes.
- * @return Error code.
- */
-int usb_massstor_data_in(usb_device_t *dev,
-    size_t bulk_in_pipe_index, size_t bulk_out_pipe_index,
-    uint32_t tag, uint8_t lun, void *cmd, size_t cmd_size,
-    void *in_buffer, size_t in_buffer_size, size_t *received_size)
+/** Send command via bulk-only transport.
+ *
+ * @param tag		Command block wrapper tag (automatically compared
+ *			with answer)
+ * @param lun		LUN
+ * @param cmd		Command block
+ * @param cmd_size	Command block size in bytes
+ * @param ddir		Direction in which data will be transferred
+ * @param dbuf		Data send/receive buffer
+ * @param dbuf_size	Size of the data buffer
+ * @param xferred_size	Number of bytes actually transferred
+ *
+ * @return		Error code
+ */
+static int usb_massstor_cmd(usb_device_t *dev, uint32_t tag, uint8_t lun,
+    const void *cmd, size_t cmd_size, usb_direction_t ddir, void *dbuf,
+    size_t dbuf_size, size_t *xferred_size)
 {
 	int rc;
 	size_t act_size;
-	usb_pipe_t *bulk_in_pipe = dev->pipes[bulk_in_pipe_index].pipe;
-	usb_pipe_t *bulk_out_pipe = dev->pipes[bulk_out_pipe_index].pipe;
+	usb_pipe_t *bulk_in_pipe = dev->pipes[BULK_IN_EP].pipe;
+	usb_pipe_t *bulk_out_pipe = dev->pipes[BULK_OUT_EP].pipe;
 
 	/* Prepare CBW - command block wrapper */
 	usb_massstor_cbw_t cbw;
-	usb_massstor_cbw_prepare(&cbw, tag, in_buffer_size,
-	    USB_DIRECTION_IN, lun, cmd_size, cmd);
-
-	/* First, send the CBW. */
+	usb_massstor_cbw_prepare(&cbw, tag, dbuf_size, ddir, lun, cmd_size,
+	    cmd);
+
+	/* Send the CBW. */
 	rc = usb_pipe_write(bulk_out_pipe, &cbw, sizeof(cbw));
 	MASTLOG("CBW '%s' sent: %s.\n",
@@ -88,11 +88,23 @@
 	}
 
-	/* Try to retrieve the data from the device. */
-	act_size = 0;
-	rc = usb_pipe_read(bulk_in_pipe, in_buffer, in_buffer_size, &act_size);
-	MASTLOG("Received %zuB (%s): %s.\n", act_size,
-	    usb_debug_str_buffer((uint8_t *) in_buffer, act_size, 0),
-	    str_error(rc));
-	if (rc != EOK) {
+	if (ddir == USB_DIRECTION_IN) {
+		/* Recieve data from the device. */
+		rc = usb_pipe_read(bulk_in_pipe, dbuf, dbuf_size, &act_size);
+		MASTLOG("Received %zu bytes (%s): %s.\n", act_size,
+		    usb_debug_str_buffer((uint8_t *) dbuf, act_size, 0),
+		    str_error(rc));
+	} else {
+		/* Send data to the device. */
+		rc = usb_pipe_write(bulk_out_pipe, dbuf, dbuf_size);
+		MASTLOG("Sent %zu bytes (%s): %s.\n", act_size,
+		    usb_debug_str_buffer((uint8_t *) dbuf, act_size, 0),
+		    str_error(rc));
+	}
+
+	if (rc != EOK) {
+		/*
+		 * XXX If the pipe is stalled, we should clear it
+		 * and read CSW.
+		 */
 		return rc;
 	}
@@ -102,15 +114,19 @@
 	size_t csw_size;
 	rc = usb_pipe_read(bulk_in_pipe, &csw, sizeof(csw), &csw_size);
-	MASTLOG("CSW '%s' received (%zuB): %s.\n",
+	MASTLOG("CSW '%s' received (%zu bytes): %s.\n",
 	    usb_debug_str_buffer((uint8_t *) &csw, csw_size, 0), csw_size,
 	    str_error(rc));
 	if (rc != EOK) {
-		return rc;
-	}
+		MASTLOG("rc != EOK\n");
+		return rc;
+	}
+
 	if (csw_size != sizeof(csw)) {
+		MASTLOG("csw_size != sizeof(csw)\n");
 		return ERANGE;
 	}
 
 	if (csw.dCSWTag != tag) {
+		MASTLOG("csw.dCSWTag != tag\n");
 		return EBADCHECKSUM;
 	}
@@ -120,4 +136,5 @@
 	 */
 	if (csw.dCSWStatus != 0) {
+		MASTLOG("csw.dCSWStatus != 0\n");
 		// FIXME: better error code
 		// FIXME: distinguish 0x01 and 0x02
@@ -126,15 +143,62 @@
 
 	size_t residue = (size_t) uint32_usb2host(csw.dCSWDataResidue);
-	if (residue > in_buffer_size) {
+	if (residue > dbuf_size) {
+		MASTLOG("residue > dbuf_size\n");
 		return ERANGE;
 	}
-	if (act_size != in_buffer_size - residue) {
-		return ERANGE;
-	}
-	if (received_size != NULL) {
-		*received_size = in_buffer_size - residue;
-	}
+
+	/*
+	 * When the device has less data to send than requested (or cannot
+	 * receive moredata), it can either stall the pipe or send garbage
+	 * (ignore data) and indicate that via the residue field in CSW.
+	 * That means dbuf_size - residue is the authoritative size of data
+	 * received (sent).
+	 */
+
+	if (xferred_size != NULL)
+		*xferred_size = dbuf_size - residue;
 
 	return EOK;
+}
+
+/** Perform data-in command.
+ *
+ * @param tag		Command block wrapper tag (automatically compared with
+ *			answer)
+ * @param lun		LUN
+ * @param cmd		CDB (Command Descriptor)
+ * @param cmd_size	CDB length in bytes
+ * @param dbuf		Data receive buffer
+ * @param dbuf_size	Data receive buffer size in bytes
+ * @param proc_size	Number of bytes actually processed by device
+ *
+ * @return Error code
+ */
+int usb_massstor_data_in(usb_device_t *dev, uint32_t tag, uint8_t lun,
+    const void *cmd, size_t cmd_size, void *dbuf, size_t dbuf_size, size_t *proc_size)
+{
+	return usb_massstor_cmd(dev, tag, lun, cmd, cmd_size, USB_DIRECTION_IN,
+	    dbuf, dbuf_size, proc_size);
+}
+
+/** Perform data-out command.
+ *
+ * @param tag		Command block wrapper tag (automatically compared with
+ *			answer)
+ * @param lun		LUN
+ * @param cmd		CDB (Command Descriptor)
+ * @param cmd_size	CDB length in bytes
+ * @param data		Command data
+ * @param data_size	Size of @a data in bytes
+ * @param proc_size	Number of bytes actually processed by device
+ *
+ * @return Error code
+ */
+int usb_massstor_data_out(usb_device_t *dev, uint32_t tag, uint8_t lun,
+    const void *cmd, size_t cmd_size, const void *data, size_t data_size,
+    size_t *proc_size)
+{
+	return usb_massstor_cmd(dev, tag, lun, cmd, cmd_size, USB_DIRECTION_OUT,
+	    (void *) data, data_size, proc_size);
 }
 
@@ -157,9 +221,6 @@
  *
  * @param dev Device to be reseted.
- * @param bulk_in_idx Index of bulk in pipe.
- * @param bulk_out_idx Index of bulk out pipe.
- */
-void usb_massstor_reset_recovery(usb_device_t *dev,
-    size_t bulk_in_idx, size_t bulk_out_idx)
+ */
+void usb_massstor_reset_recovery(usb_device_t *dev)
 {
 	/* We would ignore errors here because if this fails
@@ -167,6 +228,6 @@
 	 */
 	usb_massstor_reset(dev);
-	usb_pipe_clear_halt(&dev->ctrl_pipe, dev->pipes[bulk_in_idx].pipe);
-	usb_pipe_clear_halt(&dev->ctrl_pipe, dev->pipes[bulk_out_idx].pipe);
+	usb_pipe_clear_halt(&dev->ctrl_pipe, dev->pipes[BULK_IN_EP].pipe);
+	usb_pipe_clear_halt(&dev->ctrl_pipe, dev->pipes[BULK_OUT_EP].pipe);
 }
 
Index: uspace/drv/bus/usb/usbmast/mast.h
===================================================================
--- uspace/drv/bus/usb/usbmast/mast.h	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/drv/bus/usb/usbmast/mast.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -37,4 +37,5 @@
 #define USB_USBMAST_MAST_H_
 
+#include <scsi/spc.h>
 #include <sys/types.h>
 #include <usb/usb.h>
@@ -42,28 +43,15 @@
 #include <usb/dev/driver.h>
 
-/** Result of SCSI INQUIRY command.
- * This is already parsed structure, not the original buffer returned by
- * the device.
- */
-typedef struct {
-	/** SCSI peripheral device type. */
-	int peripheral_device_type;
-	/** Whether the device is removable. */
-	bool removable;
-	/** Vendor ID string. */
-	char vendor_id[9];
-	/** Product ID and product revision string. */
-	char product_and_revision[12];
-} usb_massstor_inquiry_result_t;
+#define BULK_IN_EP 0
+#define BULK_OUT_EP 1
 
-int usb_massstor_data_in(usb_device_t *dev, size_t, size_t,
-    uint32_t, uint8_t, void *, size_t, void *, size_t, size_t *);
-int usb_massstor_reset(usb_device_t *);
-void usb_massstor_reset_recovery(usb_device_t *, size_t, size_t);
-int usb_massstor_get_max_lun(usb_device_t *);
-size_t usb_masstor_get_lun_count(usb_device_t *);
-int usb_massstor_inquiry(usb_device_t *, size_t, size_t,
-    usb_massstor_inquiry_result_t *);
-const char *usb_str_masstor_scsi_peripheral_device_type(int);
+extern int usb_massstor_data_in(usb_device_t *, uint32_t, uint8_t, const void *,
+    size_t, void *, size_t, size_t *);
+extern int usb_massstor_data_out(usb_device_t *, uint32_t, uint8_t, const void *,
+    size_t, const void *, size_t, size_t *);
+extern int usb_massstor_reset(usb_device_t *);
+extern void usb_massstor_reset_recovery(usb_device_t *);
+extern int usb_massstor_get_max_lun(usb_device_t *);
+extern size_t usb_masstor_get_lun_count(usb_device_t *);
 
 #endif
Index: pace/drv/bus/usb/usbmast/scsi.h
===================================================================
--- uspace/drv/bus/usb/usbmast/scsi.h	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ 	(revision )
@@ -1,54 +1,0 @@
-/*
- * Copyright (c) 2011 Vojtech Horky
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/** @addtogroup drvusbmast
- * @{
- */
-/** @file
- * SCSI related structures.
- */
-
-#ifndef USB_USBMAST_SCSI_H_
-#define USB_USBMAST_SCSI_H_
-
-#include <sys/types.h>
-#include <usb/usb.h>
-
-typedef struct {
-	uint8_t op_code;
-	uint8_t lun_evpd;
-	uint8_t page_code;
-	uint16_t alloc_length;
-	uint8_t ctrl;
-} __attribute__((packed)) scsi_cmd_inquiry_t;
-
-#endif
-
-/**
- * @}
- */
Index: uspace/drv/bus/usb/usbmast/scsi_ms.c
===================================================================
--- uspace/drv/bus/usb/usbmast/scsi_ms.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
+++ uspace/drv/bus/usb/usbmast/scsi_ms.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -0,0 +1,291 @@
+/*
+ * Copyright (c) 2011 Vojtech Horky
+ * Copyright (c) 2011 Jiri Svoboda
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup drvusbmast
+ * @{
+ */
+/**
+ * @file
+ * SCSI functions for USB mass storage driver.
+ */
+#include <bitops.h>
+#include <byteorder.h>
+#include <inttypes.h>
+#include <macros.h>
+#include <usb/dev/driver.h>
+#include <usb/debug.h>
+#include <errno.h>
+#include <str_error.h>
+#include <str.h>
+#include <scsi/sbc.h>
+#include <scsi/spc.h>
+#include "cmds.h"
+#include "mast.h"
+#include "scsi_ms.h"
+
+/** Get string representation for SCSI peripheral device type.
+ *
+ * @param type		SCSI peripheral device type code.
+ * @return		String representation.
+ */
+const char *usbmast_scsi_dev_type_str(unsigned type)
+{
+	return scsi_get_dev_type_str(type);
+}
+
+/** Perform SCSI Inquiry command on USB mass storage device.
+ *
+ * @param dev		USB device.
+ * @param inquiry_result Where to store parsed inquiry result.
+ * @return		Error code.
+ */
+int usbmast_inquiry(usb_device_t *dev, usbmast_inquiry_data_t *inq_res)
+{
+	scsi_std_inquiry_data_t inq_data;
+	size_t response_len;
+	scsi_cdb_inquiry_t cdb;
+	int rc;
+
+	memset(&cdb, 0, sizeof(cdb));
+	cdb.op_code = SCSI_CMD_INQUIRY;
+	cdb.alloc_len = host2uint16_t_be(sizeof(inq_data));
+
+	rc = usb_massstor_data_in(dev, 0xDEADBEEF, 0, (uint8_t *) &cdb,
+	    sizeof(cdb), &inq_data, sizeof(inq_data), &response_len);
+
+	if (rc != EOK) {
+		usb_log_error("Inquiry failed, device %s: %s.\n",
+		   dev->ddf_dev->name, str_error(rc));
+		return rc;
+	}
+
+	if (response_len < SCSI_STD_INQUIRY_DATA_MIN_SIZE) {
+		usb_log_error("SCSI Inquiry response too short (%zu).\n",
+		    response_len);
+		return EIO;
+	}
+
+	/*
+	 * Parse inquiry data and fill in the result structure.
+	 */
+
+	bzero(inq_res, sizeof(*inq_res));
+
+	inq_res->device_type = BIT_RANGE_EXTRACT(uint8_t,
+	    inq_data.pqual_devtype, SCSI_PQDT_DEV_TYPE_h, SCSI_PQDT_DEV_TYPE_l);
+
+	inq_res->removable = BIT_RANGE_EXTRACT(uint8_t,
+	    inq_data.rmb, SCSI_RMB_RMB, SCSI_RMB_RMB);
+
+	spascii_to_str(inq_res->vendor, SCSI_INQ_VENDOR_STR_BUFSIZE,
+	    inq_data.vendor, sizeof(inq_data.vendor));
+
+	spascii_to_str(inq_res->product, SCSI_INQ_PRODUCT_STR_BUFSIZE,
+	    inq_data.product, sizeof(inq_data.product));
+
+	spascii_to_str(inq_res->revision, SCSI_INQ_REVISION_STR_BUFSIZE,
+	    inq_data.revision, sizeof(inq_data.revision));
+
+	return EOK;
+}
+
+/** Perform SCSI Request Sense command on USB mass storage device.
+ *
+ * @param dev		USB device
+ * @param buf		Destination buffer
+ * @param size		Size of @a buf
+ *
+ * @return		Error code.
+ */
+int usbmast_request_sense(usb_device_t *dev, void *buf, size_t size)
+{
+	scsi_cdb_request_sense_t cdb;
+	size_t data_len;
+	int rc;
+
+	memset(&cdb, 0, sizeof(cdb));
+	cdb.op_code = SCSI_CMD_REQUEST_SENSE;
+	cdb.alloc_len = min(size, SCSI_SENSE_DATA_MAX_SIZE);
+
+	rc = usb_massstor_data_in(dev, 0xDEADBEEF, 0, (uint8_t *) &cdb,
+	    sizeof(cdb), buf, size, &data_len);
+
+        if (rc != EOK) {
+		usb_log_error("Request Sense failed, device %s: %s.\n",
+		   dev->ddf_dev->name, str_error(rc));
+		return rc;
+	}
+
+	if (data_len < SCSI_SENSE_DATA_MIN_SIZE) {
+		/* The missing bytes should be considered to be zeroes. */
+		memset((uint8_t *)buf + data_len, 0,
+		    SCSI_SENSE_DATA_MIN_SIZE - data_len);
+	}
+
+	return EOK;
+}
+
+/** Perform SCSI Read Capacity command on USB mass storage device.
+ *
+ * @param dev		USB device.
+ * @param nblocks	Output, number of blocks.
+ * @param block_size	Output, block size in bytes.
+ *
+ * @return		Error code.
+ */
+int usbmast_read_capacity(usb_device_t *dev, uint32_t *nblocks,
+    uint32_t *block_size)
+{
+	scsi_cdb_read_capacity_10_t cdb;
+	scsi_read_capacity_10_data_t data;
+	size_t data_len;
+	int rc;
+
+	memset(&cdb, 0, sizeof(cdb));
+	cdb.op_code = SCSI_CMD_READ_CAPACITY_10;
+
+	rc = usb_massstor_data_in(dev, 0xDEADBEEF, 0, (uint8_t *) &cdb,
+	    sizeof(cdb), &data, sizeof(data), &data_len);
+
+        if (rc != EOK) {
+		usb_log_error("Read Capacity (10) failed, device %s: %s.\n",
+		   dev->ddf_dev->name, str_error(rc));
+		return rc;
+	}
+
+	if (data_len < sizeof(data)) {
+		usb_log_error("SCSI Read Capacity response too short (%zu).\n",
+		    data_len);
+		return EIO;
+	}
+
+	*nblocks = uint32_t_be2host(data.last_lba) + 1;
+	*block_size = uint32_t_be2host(data.block_size);
+
+	return EOK;
+}
+
+/** Perform SCSI Read command on USB mass storage device.
+ *
+ * @param dev		USB device.
+ * @param ba		Address of first block.
+ * @param nblocks	Number of blocks to read.
+ * @param bsize		Block size.
+ *
+ * @return		Error code.
+ */
+int usbmast_read(usb_device_t *dev, uint64_t ba, size_t nblocks, size_t bsize,
+    void *buf)
+{
+	scsi_cdb_read_12_t cdb;
+	size_t data_len;
+	int rc;
+
+	/* XXX Need softstate to store block size. */
+
+	if (ba > UINT32_MAX)
+		return ELIMIT;
+
+	if ((uint64_t)nblocks * bsize > UINT32_MAX)
+		return ELIMIT;
+
+	memset(&cdb, 0, sizeof(cdb));
+	cdb.op_code = SCSI_CMD_READ_12;
+	cdb.lba = host2uint32_t_be(ba);
+	cdb.xfer_len = host2uint32_t_be(nblocks);
+
+	rc = usb_massstor_data_in(dev, 0xDEADBEEF, 0, (uint8_t *) &cdb,
+	    sizeof(cdb), buf, nblocks * bsize, &data_len);
+
+        if (rc != EOK) {
+		usb_log_error("Read (12) failed, device %s: %s.\n",
+		   dev->ddf_dev->name, str_error(rc));
+		return rc;
+	}
+
+	if (data_len < nblocks * bsize) {
+		usb_log_error("SCSI Read response too short (%zu).\n",
+		    data_len);
+		return EIO;
+	}
+
+	return EOK;
+}
+
+/** Perform SCSI Write command on USB mass storage device.
+ *
+ * @param dev		USB device
+ * @param ba		Address of first block
+ * @param nblocks	Number of blocks to read
+ * @param bsize		Block size
+ * @param data		Data to write
+ *
+ * @return		Error code
+ */
+int usbmast_write(usb_device_t *dev, uint64_t ba, size_t nblocks, size_t bsize,
+    const void *data)
+{
+	scsi_cdb_write_12_t cdb;
+	size_t sent_len;
+	int rc;
+
+	/* XXX Need softstate to store block size. */
+
+	if (ba > UINT32_MAX)
+		return ELIMIT;
+
+	if ((uint64_t)nblocks * bsize > UINT32_MAX)
+		return ELIMIT;
+
+	memset(&cdb, 0, sizeof(cdb));
+	cdb.op_code = SCSI_CMD_WRITE_12;
+	cdb.lba = host2uint32_t_be(ba);
+	cdb.xfer_len = host2uint32_t_be(nblocks);
+
+	rc = usb_massstor_data_out(dev, 0xDEADBEEF, 0, (uint8_t *) &cdb,
+	    sizeof(cdb), data, nblocks * bsize, &sent_len);
+
+        if (rc != EOK) {
+		usb_log_error("Write (12) failed, device %s: %s.\n",
+		   dev->ddf_dev->name, str_error(rc));
+		return rc;
+	}
+
+	if (sent_len < nblocks * bsize) {
+		usb_log_error("SCSI Write not all bytes transferred (%zu).\n",
+		    sent_len);
+		return EIO;
+	}
+
+	return EOK;
+}
+
+/**
+ * @}
+ */
Index: uspace/drv/bus/usb/usbmast/scsi_ms.h
===================================================================
--- uspace/drv/bus/usb/usbmast/scsi_ms.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
+++ uspace/drv/bus/usb/usbmast/scsi_ms.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2011 Vojtech Horky
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup drvusbmast
+ * @{
+ */
+/** @file
+ * SCSI functions for USB mass storage.
+ */
+
+#ifndef USB_USBMAST_SCSI_MS_H_
+#define USB_USBMAST_SCSI_MS_H_
+
+#include <scsi/spc.h>
+#include <sys/types.h>
+#include <usb/usb.h>
+#include <usb/dev/driver.h>
+
+/** Result of SCSI Inquiry command.
+ * This is already parsed structure, not the original buffer returned by
+ * the device.
+ */
+typedef struct {
+	/** SCSI peripheral device type */
+	unsigned device_type;
+	/** Whether the device is removable */
+	bool removable;
+	/** Vendor ID string */
+	char vendor[SCSI_INQ_VENDOR_STR_BUFSIZE];
+	/** Product ID string */
+	char product[SCSI_INQ_PRODUCT_STR_BUFSIZE];
+	/** Revision string */
+	char revision[SCSI_INQ_REVISION_STR_BUFSIZE];
+} usbmast_inquiry_data_t;
+
+extern int usbmast_inquiry(usb_device_t *, usbmast_inquiry_data_t *);
+extern int usbmast_request_sense(usb_device_t *, void *, size_t);
+extern int usbmast_read_capacity(usb_device_t *, uint32_t *, uint32_t *);
+extern int usbmast_read(usb_device_t *, uint64_t, size_t, size_t, void *);
+extern int usbmast_write(usb_device_t *, uint64_t, size_t, size_t,
+    const void *);
+extern const char *usbmast_scsi_dev_type_str(unsigned);
+
+#endif
+
+/**
+ * @}
+ */
Index: uspace/lib/c/Makefile
===================================================================
--- uspace/lib/c/Makefile	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/lib/c/Makefile	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -69,5 +69,4 @@
 	generic/devmap.c \
 	generic/devman.c \
-	generic/devman_obsolete.c \
 	generic/device/hw_res.c \
 	generic/device/char_dev.c \
Index: uspace/lib/c/arch/mips32/Makefile.common
===================================================================
--- uspace/lib/c/arch/mips32/Makefile.common	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/lib/c/arch/mips32/Makefile.common	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -27,5 +27,5 @@
 #
 
-GCC_CFLAGS += -mips3
+GCC_CFLAGS += -mips3 -mabi=32
 
 ENDIANESS = LE
Index: uspace/lib/c/arch/mips32/include/atomic.h
===================================================================
--- uspace/lib/c/arch/mips32/include/atomic.h	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/lib/c/arch/mips32/include/atomic.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -31,5 +31,5 @@
  */
 /** @file
- * @ingroup libcmips32eb
+ * @ingroup libcmips32
  */
 
Index: uspace/lib/c/arch/mips32/include/fibril.h
===================================================================
--- uspace/lib/c/arch/mips32/include/fibril.h	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/lib/c/arch/mips32/include/fibril.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -27,9 +27,9 @@
  */
 
-/** @addtogroup libcmips32	
+/** @addtogroup libcmips32
  * @{
  */
 /** @file
- * @ingroup libcmips32eb	
+ * @ingroup libcmips32
  */
 
Index: uspace/lib/c/arch/mips32/include/thread.h
===================================================================
--- uspace/lib/c/arch/mips32/include/thread.h	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/lib/c/arch/mips32/include/thread.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -27,9 +27,9 @@
  */
 
-/** @addtogroup libcmips32	
+/** @addtogroup libcmips32
  * @{
  */
 /** @file
- * @ingroup libcmips32eb	
+ * @ingroup libcmips32
  */
 
Index: uspace/lib/c/arch/mips32/include/tls.h
===================================================================
--- uspace/lib/c/arch/mips32/include/tls.h	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/lib/c/arch/mips32/include/tls.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -27,9 +27,9 @@
  */
 
-/** @addtogroup libcmips32	
+/** @addtogroup libcmips32
  * @{
  */
 /** @file
- * @ingroup libcmips32eb	
+ * @ingroup libcmips32
  */
 
Index: uspace/lib/c/arch/mips32/include/types.h
===================================================================
--- uspace/lib/c/arch/mips32/include/types.h	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/lib/c/arch/mips32/include/types.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -31,5 +31,5 @@
  */
 /** @file
- * @ingroup libcmips32eb
+ * @ingroup libcmips32
  */
 
Index: uspace/lib/c/arch/mips32/src/syscall.c
===================================================================
--- uspace/lib/c/arch/mips32/src/syscall.c	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/lib/c/arch/mips32/src/syscall.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -27,9 +27,9 @@
  */
 
- /** @addtogroup libcmips32
+/** @addtogroup libcmips32
  * @{
  */
 /** @file
-  * @ingroup libcmips32eb	
+  * @ingroup libcmips32
  */
 
@@ -64,5 +64,4 @@
 }
 
- /** @}
+/** @}
  */
-
Index: uspace/lib/c/arch/mips32/src/tls.c
===================================================================
--- uspace/lib/c/arch/mips32/src/tls.c	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/lib/c/arch/mips32/src/tls.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -27,9 +27,9 @@
  */
 
-/** @addtogroup libcmips32	
+/** @addtogroup libcmips32
  * @{
  */
 /** @file
- * @ingroup libcmips32eb	
+ * @ingroup libcmips32
  */
 
Index: uspace/lib/c/arch/mips32eb/Makefile.common
===================================================================
--- uspace/lib/c/arch/mips32eb/Makefile.common	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/lib/c/arch/mips32eb/Makefile.common	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -27,5 +27,5 @@
 #
 
-GCC_CFLAGS += -mips3
+GCC_CFLAGS += -mips3 -mabi=32
 
 ENDIANESS = BE
Index: uspace/lib/c/arch/mips64/Makefile.common
===================================================================
--- uspace/lib/c/arch/mips64/Makefile.common	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
+++ uspace/lib/c/arch/mips64/Makefile.common	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -0,0 +1,35 @@
+#
+# 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 += -mips3 -mabi=64
+AFLAGS = -64
+
+ENDIANESS = LE
+
+BFD_ARCH = mips:4000
+BFD_NAME = elf64-tradlittlemips
Index: uspace/lib/c/arch/mips64/Makefile.inc
===================================================================
--- uspace/lib/c/arch/mips64/Makefile.inc	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
+++ uspace/lib/c/arch/mips64/Makefile.inc	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -0,0 +1,39 @@
+#
+# Copyright (c) 2005 Martin Decky
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# - Redistributions of source code must retain the above copyright
+#   notice, this list of conditions and the following disclaimer.
+# - Redistributions in binary form must reproduce the above copyright
+#   notice, this list of conditions and the following disclaimer in the
+#   documentation and/or other materials provided with the distribution.
+# - The name of the author may not be used to endorse or promote products
+#   derived from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+
+ARCH_SOURCES = \
+	arch/$(UARCH)/src/entry.s \
+	arch/$(UARCH)/src/entryjmp.s \
+	arch/$(UARCH)/src/thread_entry.s \
+	arch/$(UARCH)/src/syscall.c \
+	arch/$(UARCH)/src/fibril.S \
+	arch/$(UARCH)/src/tls.c \
+	arch/$(UARCH)/src/stacktrace.c \
+	arch/$(UARCH)/src/stacktrace_asm.S
+
+.PRECIOUS: arch/$(UARCH)/src/entry.o
Index: uspace/lib/c/arch/mips64/_link.ld.in
===================================================================
--- uspace/lib/c/arch/mips64/_link.ld.in	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
+++ uspace/lib/c/arch/mips64/_link.ld.in	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -0,0 +1,73 @@
+OUTPUT_FORMAT(elf64-tradlittlemips)
+STARTUP(LIBC_PATH/arch/UARCH/src/entry.o)
+ENTRY(__entry)
+
+PHDRS {
+#ifdef LOADER
+	interp PT_INTERP;
+	text PT_LOAD FILEHDR PHDRS FLAGS(5);
+#else
+	text PT_LOAD FLAGS(5);
+#endif
+	data PT_LOAD FLAGS(6);
+}
+
+SECTIONS {
+#ifdef LOADER
+	.interp : {
+		*(.interp);
+	} :interp
+	
+	. = 0x70004000 + SIZEOF_HEADERS;
+#else
+	. = 0x4000 + SIZEOF_HEADERS;
+#endif
+	.init : {
+		*(.init);
+	} :text
+	
+	.text : {
+		*(.text .text.*);
+		*(.rodata .rodata.*);
+	} :text
+	
+	. = . + 0x4000;
+	
+	.data : {
+		*(.data);
+		*(.data.rel*);
+	} :data
+	
+	.got : {
+		_gp = .;
+		*(.got);
+	} :data
+	
+	.tdata : {
+		_tdata_start = .;
+		*(.tdata);
+		_tdata_end = .;
+	} :data
+	
+	.tbss : {
+		_tbss_start = .;
+		*(.tbss);
+		_tbss_end = .;
+	} :data
+	
+	_tls_alignment = MAX(ALIGNOF(.tdata), ALIGNOF(.tbss));
+	
+	.sbss : {
+		*(.scommon);
+		*(.sbss);
+	}
+	
+	.bss : {
+		*(.bss);
+		*(COMMON);
+	} :data
+	
+	/DISCARD/ : {
+		*(*);
+	}
+}
Index: uspace/lib/c/arch/mips64/include/atomic.h
===================================================================
--- uspace/lib/c/arch/mips64/include/atomic.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
+++ uspace/lib/c/arch/mips64/include/atomic.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -0,0 +1,86 @@
+/*
+ * 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 libcmips64
+ * @{
+ */
+/** @file
+ * @ingroup libcmips64
+ */
+
+#ifndef LIBC_mips64_ATOMIC_H_
+#define LIBC_mips64_ATOMIC_H_
+
+#define LIBC_ARCH_ATOMIC_H_
+
+#include <atomicdflt.h>
+
+#define atomic_inc(x)  ((void) atomic_add(x, 1))
+#define atomic_dec(x)  ((void) atomic_add(x, -1))
+
+#define atomic_postinc(x)  (atomic_add(x, 1) - 1)
+#define atomic_postdec(x)  (atomic_add(x, -1) + 1)
+
+#define atomic_preinc(x)  atomic_add(x, 1)
+#define atomic_predec(x)  atomic_add(x, -1)
+
+/* Atomic addition of immediate value.
+ *
+ * @param val Memory location to which will be the immediate value added.
+ * @param i   Signed immediate that will be added to *val.
+ *
+ * @return Value after addition.
+ *
+ */
+static inline atomic_count_t atomic_add(atomic_t *val, atomic_count_t i)
+{
+	atomic_count_t tmp;
+	atomic_count_t v;
+	
+	asm volatile (
+		"1:\n"
+		"	lld %0, %1\n"
+		"	daddu %0, %0, %3\n"  /* same as add, but never traps on overflow */
+		"	move %2, %0\n"
+		"	scd %0, %1\n"
+		"	beq %0, %4, 1b\n"    /* if the atomic operation failed, try again */
+		"	nop\n"
+		: "=&r" (tmp),
+		  "+m" (val->count),
+		  "=&r" (v)
+		: "r" (i),
+		  "i" (0)
+	);
+	
+	return v;
+}
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/arch/mips64/include/config.h
===================================================================
--- uspace/lib/c/arch/mips64/include/config.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
+++ uspace/lib/c/arch/mips64/include/config.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2006 Jakub Jermar
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup libcmips64
+ * @{
+ */
+/** @file
+ */
+
+#ifndef LIBC_mips64_CONFIG_H_
+#define LIBC_mips64_CONFIG_H_
+
+#define PAGE_WIDTH  14
+#define PAGE_SIZE   (1 << PAGE_WIDTH)
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/arch/mips64/include/ddi.h
===================================================================
--- uspace/lib/c/arch/mips64/include/ddi.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
+++ uspace/lib/c/arch/mips64/include/ddi.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2009 Jakub Jermar
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @file
+ * @ingroup libcmips64
+ */
+
+#ifndef LIBC_mips64_DDI_H_
+#define LIBC_mips64_DDI_H_
+
+#include <sys/types.h>
+#include <libarch/types.h>
+
+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: uspace/lib/c/arch/mips64/include/faddr.h
===================================================================
--- uspace/lib/c/arch/mips64/include/faddr.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
+++ uspace/lib/c/arch/mips64/include/faddr.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -0,0 +1,45 @@
+/*
+ * 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 libcmips64
+ * @{
+ */
+/** @file
+ */
+
+#ifndef LIBC_mips64_FADDR_H_
+#define LIBC_mips64_FADDR_H_
+
+#include <libarch/types.h>
+
+#define FADDR(fptr)  ((uintptr_t) (fptr))
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/arch/mips64/include/fibril.h
===================================================================
--- uspace/lib/c/arch/mips64/include/fibril.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
+++ uspace/lib/c/arch/mips64/include/fibril.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2006 Ondrej Palkovsky
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup libcmips64
+ * @{
+ */
+/** @file
+ * @ingroup libcmips64
+ */
+
+#ifndef LIBC_mips64_FIBRIL_H_
+#define LIBC_mips64_FIBRIL_H_
+
+#include <sys/types.h>
+
+/* We define our own context_set, because we need to set
+ * the TLS pointer to the tcb+0x7000
+ *
+ * See tls_set in thread.h
+ */
+#define context_set(c, _pc, stack, size, ptls) \
+	(c)->pc = (sysarg_t) (_pc); \
+	(c)->sp = ((sysarg_t) (stack)) + (size) - SP_DELTA; \
+	(c)->tls = ((sysarg_t)(ptls)) + 0x7000 + sizeof(tcb_t);
+
+/* +16 is just for sure that the called function
+ * have space to store it's arguments
+ */
+#define SP_DELTA  (8 + 16)
+
+typedef struct {
+	uint64_t sp;
+	uint64_t pc;
+	
+	uint64_t s0;
+	uint64_t s1;
+	uint64_t s2;
+	uint64_t s3;
+	uint64_t s4;
+	uint64_t s5;
+	uint64_t s6;
+	uint64_t s7;
+	uint64_t s8;
+	uint64_t gp;
+	uint64_t tls; /* Thread local storage (k1) */
+	
+	uint64_t f20;
+	uint64_t f21;
+	uint64_t f22;
+	uint64_t f23;
+	uint64_t f24;
+	uint64_t f25;
+	uint64_t f26;
+	uint64_t f27;
+	uint64_t f28;
+	uint64_t f29;
+	uint64_t f30;
+} context_t;
+
+static inline uintptr_t context_get_fp(context_t *ctx)
+{
+	return ctx->sp;
+}
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/arch/mips64/include/inttypes.h
===================================================================
--- uspace/lib/c/arch/mips64/include/inttypes.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
+++ uspace/lib/c/arch/mips64/include/inttypes.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -0,0 +1,44 @@
+/*
+ * 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 libcmips64
+ * @{
+ */
+
+#ifndef LIBC_mips64_INTTYPES_H_
+#define LIBC_mips64_INTTYPES_H_
+
+#define PRIdn  PRId64  /**< Format for native_t. */
+#define PRIun  PRIu64  /**< Format for sysarg_t. */
+#define PRIxn  PRIx64  /**< Format for hexadecimal sysarg_t. */
+#define PRIua  PRIu64  /**< Format for atomic_count_t. */
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/arch/mips64/include/istate.h
===================================================================
--- uspace/lib/c/arch/mips64/include/istate.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
+++ uspace/lib/c/arch/mips64/include/istate.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2010 Jiri Svoboda
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup libcmips64
+ * @{
+ */
+/** @file
+ */
+
+#ifndef LIBC_mips64__ISTATE_H_
+#define LIBC_mips64__ISTATE_H_
+
+#include <arch/istate.h>
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/arch/mips64/include/syscall.h
===================================================================
--- uspace/lib/c/arch/mips64/include/syscall.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
+++ uspace/lib/c/arch/mips64/include/syscall.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -0,0 +1,46 @@
+/*
+ * 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 libc
+ * @{
+ */
+/**
+ * @file
+ */
+
+#ifndef LIBC_mips64_SYSCALL_H_
+#define LIBC_mips64_SYSCALL_H_
+
+#define LIBARCH_SYSCALL_GENERIC
+
+#include <syscall.h>
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/arch/mips64/include/thread.h
===================================================================
--- uspace/lib/c/arch/mips64/include/thread.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
+++ uspace/lib/c/arch/mips64/include/thread.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2006 Ondrej Palkovsky
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup libcmips64
+ * @{
+ */
+/** @file
+ * @ingroup libcmips64
+ */
+
+#ifndef LIBC_mips64_THREAD_H_
+#define LIBC_mips64_THREAD_H_
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/arch/mips64/include/tls.h
===================================================================
--- uspace/lib/c/arch/mips64/include/tls.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
+++ uspace/lib/c/arch/mips64/include/tls.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2006 Ondrej Palkovsky
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup libcmips64
+ * @{
+ */
+/** @file
+ * @ingroup libcmips64
+ */
+
+/* TLS for MIPS is described in http://www.linux-mips.org/wiki/NPTL */
+
+#ifndef LIBC_mips64_TLS_H_
+#define LIBC_mips64_TLS_H_
+
+/*
+ * FIXME: Note that the use of variant I contradicts the observations made in
+ * the note below. Nevertheless the scheme we have used for allocating and
+ * deallocatin TLS corresponds to TLS variant I.
+ */
+#define CONFIG_TLS_VARIANT_1
+
+/* I did not find any specification (neither MIPS nor PowerPC), but
+ * as I found it
+ * - it uses Variant II
+ * - TCB is at Address(First TLS Block)+0x7000.
+ * - DTV is at Address(First TLS Block)+0x8000
+ * - What would happen if the TLS data was larger then 0x7000?
+ * - The linker never accesses DTV directly, has the second definition any
+ *   sense?
+ * We will make it this way:
+ * - TCB is at TP-0x7000-sizeof(tcb)
+ * - No assumption about DTV etc., but it will not have a fixed address
+ */
+#define MIPS_TP_OFFSET 0x7000
+
+typedef struct {
+	void *fibril_data;
+} tcb_t;
+
+static inline void __tcb_set(tcb_t *tcb)
+{
+	void *tp = tcb;
+	tp += MIPS_TP_OFFSET + sizeof(tcb_t);
+	
+	/* Move tls to K1 */
+	asm volatile (
+		"add $27, %0, $0"
+		:: "r" (tp)
+	);
+}
+
+static inline tcb_t *__tcb_get(void)
+{
+	void *retval;
+	
+	asm volatile (
+		"add %0, $27, $0"
+		: "=r" (retval)
+	);
+	
+	return (tcb_t *) (retval - MIPS_TP_OFFSET - sizeof(tcb_t));
+}
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/arch/mips64/include/types.h
===================================================================
--- uspace/lib/c/arch/mips64/include/types.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
+++ uspace/lib/c/arch/mips64/include/types.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -0,0 +1,61 @@
+/*
+ * 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 libcmips64
+ * @{
+ */
+/** @file
+ * @ingroup libcmips32
+ */
+
+#ifndef LIBC_mips64_TYPES_H_
+#define LIBC_mips64_TYPES_H_
+
+#define __64_BITS__
+
+#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;
+
+typedef int64_t ssize_t;
+typedef uint64_t size_t;
+
+typedef uint64_t uintptr_t;
+typedef uint64_t atomic_count_t;
+typedef int64_t atomic_signed_t;
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/arch/mips64/src/entry.s
===================================================================
--- uspace/lib/c/arch/mips64/src/entry.s	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
+++ uspace/lib/c/arch/mips64/src/entry.s	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -0,0 +1,57 @@
+#
+# 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.
+#
+
+.text
+.section .init, "ax"
+
+.global __entry
+
+.set noreorder
+.option pic2
+
+## User-space task entry point
+#
+# $a0 ($4) contains the PCB pointer
+#
+.ent __entry
+__entry:
+	.frame $sp, 32, $31
+	.cpload $25
+	
+	# FIXME: Reflect exactly ABI specs here
+	
+	addiu $sp, -32
+	.cprestore 16   # Allow PIC code
+	
+	# Pass pcb_ptr to __main() as the first argument. pcb_ptr is already
+	# in $a0. As the first argument is passed in $a0, no operation
+	# is needed.
+	
+	jal __main
+	nop
+.end
Index: uspace/lib/c/arch/mips64/src/entryjmp.s
===================================================================
--- uspace/lib/c/arch/mips64/src/entryjmp.s	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
+++ uspace/lib/c/arch/mips64/src/entryjmp.s	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -0,0 +1,49 @@
+#
+# 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.
+#
+
+.text
+.section .text
+.global entry_point_jmp
+.set noreorder
+
+## void entry_point_jmp(void *entry_point, void *pcb);
+#
+# $a0 (=$4) contains entry_point
+# $a1 (=$5) contains pcb
+#
+# Jump to program entry point
+.ent entry_point_jmp
+entry_point_jmp:
+	# tmp := entry_point
+	move $25, $a0
+	
+	# Pass pcb to the entry point in $a0
+	move $a0, $a1
+	jr $25
+	nop
+.end
Index: uspace/lib/c/arch/mips64/src/fibril.S
===================================================================
--- uspace/lib/c/arch/mips64/src/fibril.S	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
+++ uspace/lib/c/arch/mips64/src/fibril.S	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -0,0 +1,55 @@
+#
+# 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
+
+#include <arch/context_offset.h>
+
+.global context_save
+.global context_restore
+
+context_save:
+	CONTEXT_SAVE_ARCH_CORE $a0
+	
+	# context_save returns 1
+	j $ra
+	li $v0, 1
+
+context_restore:
+	CONTEXT_RESTORE_ARCH_CORE $a0
+	
+	# Just for the jump into first function,
+	# but one instruction should not bother us
+	move $t9, $ra
+	
+	# context_restore returns 0
+	j $ra
+	xor $v0, $v0
Index: uspace/lib/c/arch/mips64/src/stacktrace.c
===================================================================
--- uspace/lib/c/arch/mips64/src/stacktrace.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
+++ uspace/lib/c/arch/mips64/src/stacktrace.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2010 Jakub Jermar
+ * Copyright (c) 2010 Jiri Svoboda
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup libcmips64 mips64
+ * @ingroup lc
+ * @{
+ */
+/** @file
+ */
+
+#include <sys/types.h>
+#include <bool.h>
+#include <errno.h>
+
+#include <stacktrace.h>
+
+bool stacktrace_fp_valid(stacktrace_t *st, uintptr_t fp)
+{
+	(void) st; (void) fp;
+	return false;
+}
+
+int stacktrace_fp_prev(stacktrace_t *st, uintptr_t fp, uintptr_t *prev)
+{
+	(void) st; (void) fp; (void) prev;
+	return ENOTSUP;
+}
+
+int stacktrace_ra_get(stacktrace_t *st, uintptr_t fp, uintptr_t *ra)
+{
+	(void) st; (void) fp; (void) ra;
+	return ENOTSUP;
+}
+
+/** @}
+ */
Index: uspace/lib/c/arch/mips64/src/stacktrace_asm.S
===================================================================
--- uspace/lib/c/arch/mips64/src/stacktrace_asm.S	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
+++ uspace/lib/c/arch/mips64/src/stacktrace_asm.S	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -0,0 +1,42 @@
+#
+# Copyright (c) 2009 Jakub Jermar
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# - Redistributions of source code must retain the above copyright
+#   notice, this list of conditions and the following disclaimer.
+# - Redistributions in binary form must reproduce the above copyright
+#   notice, this list of conditions and the following disclaimer in the
+#   documentation and/or other materials provided with the distribution.
+# - The name of the author may not be used to endorse or promote products
+#   derived from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+
+.text
+
+.set noat
+.set noreorder
+
+.global stacktrace_prepare
+.global stacktrace_fp_get
+.global stacktrace_pc_get
+
+stacktrace_prepare:
+stacktrace_fp_get:
+stacktrace_pc_get:
+	j $ra
+	xor $v0, $v0
Index: uspace/lib/c/arch/mips64/src/syscall.c
===================================================================
--- uspace/lib/c/arch/mips64/src/syscall.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
+++ uspace/lib/c/arch/mips64/src/syscall.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -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.
+ */
+
+/** @addtogroup libcmips64
+ * @{
+ */
+/** @file
+  * @ingroup libcmips64
+ */
+
+#include <libc.h>
+
+sysarg_t __syscall(const sysarg_t p1, const sysarg_t p2, const sysarg_t p3,
+    const sysarg_t p4, const sysarg_t p5, const sysarg_t p6, const syscall_t id)
+{
+	register sysarg_t __mips_reg_a0 asm("$4") = p1;
+	register sysarg_t __mips_reg_a1 asm("$5") = p2;
+	register sysarg_t __mips_reg_a2 asm("$6") = p3;
+	register sysarg_t __mips_reg_a3 asm("$7") = p4;
+	register sysarg_t __mips_reg_t0 asm("$8") = p5;
+	register sysarg_t __mips_reg_t1 asm("$9") = p6;
+	register sysarg_t __mips_reg_v0 asm("$2") = id;
+	
+	asm volatile (
+		"syscall\n"
+		: "=r" (__mips_reg_v0)
+		: "r" (__mips_reg_a0),
+		  "r" (__mips_reg_a1),
+		  "r" (__mips_reg_a2),
+		  "r" (__mips_reg_a3),
+		  "r" (__mips_reg_t0),
+		  "r" (__mips_reg_t1),
+		  "r" (__mips_reg_v0)
+		/*
+		 * We are a function call, although
+		 * C does not know it
+		 */
+		: "%ra"
+	);
+	
+	return __mips_reg_v0;
+}
+
+/** @}
+ */
Index: uspace/lib/c/arch/mips64/src/thread_entry.s
===================================================================
--- uspace/lib/c/arch/mips64/src/thread_entry.s	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
+++ uspace/lib/c/arch/mips64/src/thread_entry.s	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -0,0 +1,59 @@
+#
+# 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.
+#
+
+.text
+
+.set noat
+.set noreorder
+.option pic2
+
+.globl __thread_entry
+
+## User-space thread entry point for all but the first threads.
+#
+#
+.ent __thread_entry
+__thread_entry:
+	.frame $sp, 32, $31
+	.cpload $25
+	
+	#
+	# v0 contains address of uarg.
+	#
+	add $4, $2, 0
+	
+	addiu $sp, -32
+	.cprestore 16
+	
+	jal __thread_main
+	nop
+	
+	#
+	# Not reached.
+	#
+.end __thread_entry
Index: uspace/lib/c/arch/mips64/src/tls.c
===================================================================
--- uspace/lib/c/arch/mips64/src/tls.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
+++ uspace/lib/c/arch/mips64/src/tls.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2006 Ondrej Palkovsky
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup libcmips64
+ * @{
+ */
+/** @file
+ * @ingroup libcmips64
+ */
+
+#include <tls.h>
+#include <sys/types.h>
+
+tcb_t * __alloc_tls(void **data, size_t size)
+{
+	return tls_alloc_variant_1(data, size);
+}
+
+void __free_tls_arch(tcb_t *tcb, size_t size)
+{
+	tls_free_variant_1(tcb, size);
+}
+
+/** @}
+ */
Index: uspace/lib/c/generic/adt/measured_strings.c
===================================================================
--- uspace/lib/c/generic/adt/measured_strings.c	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/lib/c/generic/adt/measured_strings.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -42,5 +42,4 @@
 #include <errno.h>
 #include <async.h>
-#include <async_obsolete.h>
 
 /** Creates a new measured string bundled with a copy of the given string
@@ -298,5 +297,5 @@
  * size has to be negotiated in advance.
  *
- * @param[in] phone	The other module phone.
+ * @param[in] exch	Exchange.
  * @param[out] strings	The returned measured strings array.
  * @param[out] data	The measured strings data. This memory block stores the
@@ -305,5 +304,5 @@
  * @return		EOK on success.
  * @return		EINVAL if the strings or data parameter is NULL.
- * @return		EINVAL if the phone or count parameter is not positive.
+ * @return		EINVAL if the exch or count parameter is invalid.
  * @return		EINVAL if the sent array differs in size.
  * @return		ENOMEM if there is not enough memory left.
@@ -311,7 +310,6 @@
  *			async_data_read_start() function.
  */
-int
-measured_strings_return(int phone, measured_string_t **strings, uint8_t **data,
-    size_t count)
+int measured_strings_return(async_exch_t *exch, measured_string_t **strings,
+    uint8_t **data, size_t count)
 {
 	size_t *lengths;
@@ -320,5 +318,5 @@
 	int rc;
 
-	if ((phone < 0) || (!strings) || (!data) || (count <= 0))
+	if ((exch == NULL) || (!strings) || (!data) || (count <= 0))
 		return EINVAL;
 
@@ -327,5 +325,5 @@
 		return ENOMEM;
 
-	rc = async_obsolete_data_read_start(phone, lengths,
+	rc = async_data_read_start(exch, lengths,
 	    sizeof(size_t) * (count + 1));
 	if (rc != EOK) {
@@ -352,5 +350,5 @@
 		(*strings)[index].length = lengths[index];
 		if (lengths[index] > 0) {
-			rc = async_obsolete_data_read_start(phone, next, lengths[index]);
+			rc = async_data_read_start(exch, next, lengths[index]);
 			if (rc != EOK) {
 			    	free(lengths);
@@ -376,15 +374,14 @@
  * size has to be negotiated in advance.
  *
- * @param[in] phone	The other module phone.
+ * @param[in] exch	Exchange.
  * @param[in] strings	The measured strings array to be transferred.
  * @param[in] count	The measured strings array size.
  * @return		EOK on success.
  * @return		EINVAL if the strings parameter is NULL.
- * @return		EINVAL if the phone or count parameter is not positive.
+ * @return		EINVAL if the exch or count parameter is invalid.
  * @return		Other error codes as defined for the
  *			async_data_write_start() function.
  */
-int
-measured_strings_send(int phone, const measured_string_t *strings,
+int measured_strings_send(async_exch_t *exch, const measured_string_t *strings,
     size_t count)
 {
@@ -393,5 +390,5 @@
 	int rc;
 
-	if ((phone < 0) || (!strings) || (count <= 0))
+	if ((exch == NULL) || (!strings) || (count <= 0))
 		return EINVAL;
 
@@ -400,5 +397,5 @@
 		return ENOMEM;
 
-	rc = async_obsolete_data_write_start(phone, lengths,
+	rc = async_data_write_start(exch, lengths,
 	    sizeof(size_t) * (count + 1));
 	if (rc != EOK) {
@@ -411,5 +408,5 @@
 	for (index = 0; index < count; index++) {
 		if (strings[index].length > 0) {
-			rc = async_obsolete_data_write_start(phone, strings[index].value,
+			rc = async_data_write_start(exch, strings[index].value,
 			    strings[index].length);
 			if (rc != EOK)
@@ -423,3 +420,2 @@
 /** @}
  */
-
Index: pace/lib/c/generic/devman_obsolete.c
===================================================================
--- uspace/lib/c/generic/devman_obsolete.c	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ 	(revision )
@@ -1,149 +1,0 @@
-/*
- * Copyright (c) 2007 Josef Cejka
- * Copyright (c) 2009 Jiri Svoboda
- * Copyright (c) 2010 Lenka Trochtova
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING 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
- */
-
-#include <str.h>
-#include <stdio.h>
-#include <ipc/services.h>
-#include <ipc/devman.h>
-#include <devman_obsolete.h>
-#include <async.h>
-#include <async_obsolete.h>
-#include <ns.h>
-#include <ns_obsolete.h>
-#include <fibril_synch.h>
-#include <errno.h>
-#include <malloc.h>
-#include <bool.h>
-#include <adt/list.h>
-
-static int devman_phone_driver = -1;
-static int devman_phone_client = -1;
-
-static FIBRIL_MUTEX_INITIALIZE(devman_phone_mutex);
-
-int devman_obsolete_get_phone(devman_interface_t iface, unsigned int flags)
-{
-	switch (iface) {
-	case DEVMAN_DRIVER:
-		fibril_mutex_lock(&devman_phone_mutex);
-		if (devman_phone_driver >= 0) {
-			fibril_mutex_unlock(&devman_phone_mutex);
-			return devman_phone_driver;
-		}
-		
-		if (flags & IPC_FLAG_BLOCKING)
-			devman_phone_driver = service_obsolete_connect_blocking(
-			    SERVICE_DEVMAN, DEVMAN_DRIVER, 0);
-		else
-			devman_phone_driver = service_obsolete_connect(SERVICE_DEVMAN,
-			    DEVMAN_DRIVER, 0);
-		
-		fibril_mutex_unlock(&devman_phone_mutex);
-		return devman_phone_driver;
-	case DEVMAN_CLIENT:
-		fibril_mutex_lock(&devman_phone_mutex);
-		if (devman_phone_client >= 0) {
-			fibril_mutex_unlock(&devman_phone_mutex);
-			return devman_phone_client;
-		}
-		
-		if (flags & IPC_FLAG_BLOCKING) {
-			devman_phone_client = service_obsolete_connect_blocking(
-			    SERVICE_DEVMAN, DEVMAN_CLIENT, 0);
-		} else {
-			devman_phone_client = service_obsolete_connect(SERVICE_DEVMAN,
-			    DEVMAN_CLIENT, 0);
-		}
-		
-		fibril_mutex_unlock(&devman_phone_mutex);
-		return devman_phone_client;
-	default:
-		return -1;
-	}
-}
-
-void devman_obsolete_hangup_phone(devman_interface_t iface)
-{
-	switch (iface) {
-	case DEVMAN_DRIVER:
-		if (devman_phone_driver >= 0) {
-			async_obsolete_hangup(devman_phone_driver);
-			devman_phone_driver = -1;
-		}
-		break;
-	case DEVMAN_CLIENT:
-		if (devman_phone_client >= 0) {
-			async_obsolete_hangup(devman_phone_client);
-			devman_phone_client = -1;
-		}
-		break;
-	default:
-		break;
-	}
-}
-
-int devman_obsolete_device_connect(devman_handle_t handle, unsigned int flags)
-{
-	int phone;
-	
-	if (flags & IPC_FLAG_BLOCKING) {
-		phone = service_obsolete_connect_blocking(SERVICE_DEVMAN,
-		    DEVMAN_CONNECT_TO_DEVICE, handle);
-	} else {
-		phone = service_obsolete_connect(SERVICE_DEVMAN,
-		    DEVMAN_CONNECT_TO_DEVICE, handle);
-	}
-	
-	return phone;
-}
-
-int devman_obsolete_parent_device_connect(devman_handle_t handle, unsigned int flags)
-{
-	int phone;
-	
-	if (flags & IPC_FLAG_BLOCKING) {
-		phone = service_obsolete_connect_blocking(SERVICE_DEVMAN,
-		    DEVMAN_CONNECT_TO_PARENTS_DEVICE, handle);
-	} else {
-		phone = service_obsolete_connect(SERVICE_DEVMAN,
-		    DEVMAN_CONNECT_TO_PARENTS_DEVICE, handle);
-	}
-	
-	return phone;
-}
-
-/** @}
- */
Index: uspace/lib/c/generic/io/console.c
===================================================================
--- uspace/lib/c/generic/io/console.c	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/lib/c/generic/io/console.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -76,9 +76,5 @@
 bool console_kcon(void)
 {
-#if 0
 	return __SYSCALL0(SYS_DEBUG_ACTIVATE_CONSOLE);
-#endif
-	
-	return false;
 }
 
Index: uspace/lib/c/generic/net/icmp_api.c
===================================================================
--- uspace/lib/c/generic/net/icmp_api.c	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/lib/c/generic/net/icmp_api.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -42,5 +42,4 @@
 #include <net/ip_codes.h>
 #include <async.h>
-#include <async_obsolete.h>
 #include <sys/types.h>
 #include <sys/time.h>
@@ -55,5 +54,5 @@
  * timeout occurs.
  *
- * @param[in] icmp_phone The ICMP module phone used for (semi)remote calls.
+ * @param[in] sess The ICMP session.
  * @param[in] size	The message data length in bytes.
  * @param[in] timeout	The timeout in milliseconds.
@@ -74,5 +73,5 @@
  */
 int
-icmp_echo_msg(int icmp_phone, size_t size, mseconds_t timeout, ip_ttl_t ttl,
+icmp_echo_msg(async_sess_t *sess, size_t size, mseconds_t timeout, ip_ttl_t ttl,
     ip_tos_t tos, int dont_fragment, const struct sockaddr *addr,
     socklen_t addrlen)
@@ -83,10 +82,14 @@
 	if (addrlen <= 0)
 		return EINVAL;
-
-	message_id = async_obsolete_send_5(icmp_phone, NET_ICMP_ECHO, size, timeout, ttl,
+	
+	async_exch_t *exch = async_exchange_begin(sess);
+	
+	message_id = async_send_5(exch, NET_ICMP_ECHO, size, timeout, ttl,
 	    tos, (sysarg_t) dont_fragment, NULL);
-
+	
 	/* Send the address */
-	async_obsolete_data_write_start(icmp_phone, addr, (size_t) addrlen);
+	async_data_write_start(exch, addr, (size_t) addrlen);
+	
+	async_exchange_end(exch);
 
 	async_wait_for(message_id, &result);
Index: uspace/lib/c/generic/net/icmp_common.c
===================================================================
--- uspace/lib/c/generic/net/icmp_common.c	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/lib/c/generic/net/icmp_common.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -45,8 +45,8 @@
 /** Connect to the ICMP module.
  *
- * @return ICMP module phone on success.
+ * @return ICMP module session.
  *
  */
-int icmp_connect_module(void)
+async_sess_t *icmp_connect_module(void)
 {
 	return connect_to_service(SERVICE_ICMP);
Index: uspace/lib/c/generic/net/modules.c
===================================================================
--- uspace/lib/c/generic/net/modules.c	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/lib/c/generic/net/modules.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -40,5 +40,4 @@
 
 #include <async.h>
-#include <async_obsolete.h>
 #include <malloc.h>
 #include <errno.h>
@@ -47,8 +46,4 @@
 #include <net/modules.h>
 #include <ns.h>
-#include <ns_obsolete.h>
-
-/** The time between connect requests in microseconds. */
-#define MODULE_WAIT_TIME  (10 * 1000)
 
 /** Answer a call.
@@ -98,55 +93,65 @@
 }
 
-/** Create bidirectional connection with the needed module service and registers
+/** Create bidirectional connection with the needed module service and register
  * 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, sysarg_t arg1, sysarg_t arg2, sysarg_t arg3,
-    async_client_conn_t client_receiver)
+ * @param[in] need            Needed module service.
+ * @param[in] arg1            First parameter.
+ * @param[in] arg2            Second parameter.
+ * @param[in] arg3            Third parameter.
+ * @param[in] client_receiver Message receiver.
+ *
+ * @return Session to the needed service.
+ * @return Other error codes as defined for the async_connect_to_me()
+ *         function.
+ *
+ */
+async_sess_t *bind_service(services_t need, sysarg_t arg1, sysarg_t arg2,
+    sysarg_t arg3, async_client_conn_t client_receiver)
 {
 	/* Connect to the needed service */
-	int phone = connect_to_service(need);
-	if (phone >= 0) {
+	async_sess_t *sess = connect_to_service(need);
+	if (sess != NULL) {
 		/* Request the bidirectional connection */
-		int rc = async_obsolete_connect_to_me(phone, arg1, arg2, arg3,
+		async_exch_t *exch = async_exchange_begin(sess);
+		int rc = async_connect_to_me(exch, arg1, arg2, arg3,
 		    client_receiver, NULL);
+		async_exchange_end(exch);
+		
 		if (rc != EOK) {
-			async_obsolete_hangup(phone);
-			return rc;
+			async_hangup(sess);
+			errno = rc;
+			return NULL;
 		}
 	}
 	
-	return phone;
-}
-
-/** Connects to the needed module.
- *
- * @param[in] need	The needed module service.
- * @return		The phone of the needed service.
- */
-int connect_to_service(services_t need)
-{
-	return service_obsolete_connect_blocking(need, 0, 0);
-}
-
-/** Replies the data to the other party.
- *
- * @param[in] data	The data buffer to be sent.
+	return sess;
+}
+
+/** Connect to the needed module.
+ *
+ * @param[in] need Needed module service.
+ *
+ * @return Session to the needed service.
+ * @return NULL if the connection timeouted.
+ *
+ */
+async_sess_t *connect_to_service(services_t need)
+{
+	return service_connect_blocking(EXCHANGE_SERIALIZE, need, 0, 0);
+}
+
+/** Reply the data to the other party.
+ *
+ * @param[in] data        The data buffer to be sent.
  * @param[in] data_length The buffer length.
- * @return		EOK on success.
- * @return		EINVAL if the client does not expect the data.
- * @return		EOVERFLOW if the client does not expect all the data.
- *			Only partial data are transfered.
- * @return		Other error codes as defined for the
- *			async_data_read_finalize() function.
+ *
+ * @return EOK on success.
+ * @return EINVAL if the client does not expect the data.
+ * @return EOVERFLOW if the client does not expect all the data.
+ *         Only partial data are transfered.
+ * @return Other error codes as defined for the
+ *         async_data_read_finalize() function.
+ *
  */
 int data_reply(void *data, size_t data_length)
@@ -154,9 +159,9 @@
 	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) {
@@ -164,5 +169,5 @@
 		return EOVERFLOW;
 	}
-
+	
 	/* Send the data */
 	return async_data_read_finalize(callid, data, data_length);
Index: uspace/lib/c/generic/net/socket_client.c
===================================================================
--- uspace/lib/c/generic/net/socket_client.c	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/lib/c/generic/net/socket_client.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -39,5 +39,4 @@
 #include <assert.h>
 #include <async.h>
-#include <async_obsolete.h>
 #include <fibril_synch.h>
 #include <stdint.h>
@@ -84,6 +83,6 @@
 	/** Socket identifier. */
 	int socket_id;
-	/** Parent module phone. */
-	int phone;
+	/** Parent module session. */
+	async_sess_t *sess;
 	/** Parent module service. */
 	services_t service;
@@ -144,12 +143,8 @@
 /** 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;
+	/** TCP module session. */
+	async_sess_t *tcp_sess;
+	/** UDP module session. */
+	async_sess_t *udp_sess;
 
 	/** Active sockets. */
@@ -164,7 +159,6 @@
 	fibril_rwlock_t lock;
 } socket_globals = {
-	.tcp_phone = -1,
-	.udp_phone = -1,
-//	.last_id = 0,
+	.tcp_sess = NULL,
+	.udp_sess = NULL,
 	.sockets = NULL,
 	.lock = FIBRIL_RWLOCK_INITIALIZER(socket_globals.lock)
@@ -280,38 +274,36 @@
 }
 
-/** Returns the TCP module phone.
- *
- * Connects to the TCP module if necessary.
- *
- * @return		The TCP module phone.
- * @return		Other error codes as defined for the
- *			bind_service() function.
- */
-static int socket_get_tcp_phone(void)
-{
-	if (socket_globals.tcp_phone < 0) {
-		socket_globals.tcp_phone = bind_service(SERVICE_TCP,
+/** Return the TCP module session.
+ *
+ * Connect to the TCP module if necessary.
+ *
+ * @return The TCP module session.
+ *
+ */
+static async_sess_t *socket_get_tcp_sess(void)
+{
+	if (socket_globals.tcp_sess == NULL) {
+		socket_globals.tcp_sess = bind_service(SERVICE_TCP,
 		    0, 0, SERVICE_TCP, socket_connection);
 	}
 
-	return socket_globals.tcp_phone;
-}
-
-/** Returns the UDP module phone.
- *
- * Connects to the UDP module if necessary.
- *
- * @return		The UDP module phone.
- * @return		Other error codes as defined for the
- *			bind_service() function.
- */
-static int socket_get_udp_phone(void)
-{
-	if (socket_globals.udp_phone < 0) {
-		socket_globals.udp_phone = bind_service(SERVICE_UDP,
+	return socket_globals.tcp_sess;
+}
+
+/** Return the UDP module session.
+ *
+ * Connect to the UDP module if necessary.
+ *
+ * @return The UDP module session.
+ *
+ */
+static async_sess_t *socket_get_udp_sess(void)
+{
+	if (socket_globals.udp_sess == NULL) {
+		socket_globals.udp_sess = bind_service(SERVICE_UDP,
 		    0, 0, SERVICE_UDP, socket_connection);
 	}
 
-	return socket_globals.udp_phone;
+	return socket_globals.udp_sess;
 }
 
@@ -329,5 +321,4 @@
 	sockets = socket_get_sockets();
 	count = 0;
-//	socket_id = socket_globals.last_id;
 
 	do {
@@ -342,14 +333,10 @@
 			if (socket_id < INT_MAX) {
 				++socket_id;
-/*			} else if(socket_globals.last_id) {
- *				socket_globals.last_id = 0;
- *				socket_id = 1;
- */			} else {
+			} else {
 				return ELIMIT;
 			}
 		}
 	} while (sockets_find(sockets, socket_id));
-
-//	last_id = socket_id
+	
 	return socket_id;
 }
@@ -358,14 +345,13 @@
  *
  * @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_t *socket, int socket_id, int phone,
-    services_t service)
+ * @param[in] socket_id  The new socket identifier.
+ * @param[in] sess       The parent module session.
+ * @param[in] service    The parent module service.
+ */
+static void socket_initialize(socket_t *socket, int socket_id,
+    async_sess_t *sess, services_t service)
 {
 	socket->socket_id = socket_id;
-	socket->phone = phone;
+	socket->sess = sess;
 	socket->service = service;
 	dyn_fifo_initialize(&socket->received, SOCKET_INITIAL_RECEIVED_SIZE);
@@ -397,5 +383,5 @@
 {
 	socket_t *socket;
-	int phone;
+	async_sess_t *sess;
 	int socket_id;
 	services_t service;
@@ -414,5 +400,5 @@
 			switch (protocol) {
 			case IPPROTO_TCP:
-				phone = socket_get_tcp_phone();
+				sess = socket_get_tcp_sess();
 				service = SERVICE_TCP;
 				break;
@@ -429,5 +415,5 @@
 			switch (protocol) {
 			case IPPROTO_UDP:
-				phone = socket_get_udp_phone();
+				sess = socket_get_udp_sess();
 				service = SERVICE_UDP;
 				break;
@@ -450,6 +436,6 @@
 	}
 
-	if (phone < 0)
-		return phone;
+	if (sess == NULL)
+		return ENOENT;
 
 	/* Create a new socket structure */
@@ -468,7 +454,10 @@
 		return socket_id;
 	}
-
-	rc = (int) async_obsolete_req_3_3(phone, NET_SOCKET, socket_id, 0, service, NULL,
+	
+	async_exch_t *exch = async_exchange_begin(sess);
+	rc = (int) async_req_3_3(exch, NET_SOCKET, socket_id, 0, service, NULL,
 	    &fragment_size, &header_size);
+	async_exchange_end(exch);
+	
 	if (rc != EOK) {
 		fibril_rwlock_write_unlock(&socket_globals.lock);
@@ -481,5 +470,5 @@
 
 	/* Finish the new socket initialization */
-	socket_initialize(socket, socket_id, phone, service);
+	socket_initialize(socket, socket_id, sess, service);
 	/* Store the new socket */
 	rc = sockets_add(socket_get_sockets(), socket_id, socket);
@@ -490,6 +479,10 @@
 		dyn_fifo_destroy(&socket->accepted);
 		free(socket);
-		async_obsolete_msg_3(phone, NET_SOCKET_CLOSE, (sysarg_t) socket_id, 0,
+		
+		exch = async_exchange_begin(sess);
+		async_msg_3(exch, NET_SOCKET_CLOSE, (sysarg_t) socket_id, 0,
 		    service);
+		async_exchange_end(exch);
+		
 		return rc;
 	}
@@ -535,8 +528,10 @@
 
 	/* Request the message */
-	message_id = async_obsolete_send_3(socket->phone, message,
+	async_exch_t *exch = async_exchange_begin(socket->sess);
+	message_id = async_send_3(exch, message,
 	    (sysarg_t) socket->socket_id, arg2, socket->service, NULL);
 	/* Send the address */
-	async_obsolete_data_write_start(socket->phone, data, datalength);
+	async_data_write_start(exch, data, datalength);
+	async_exchange_end(exch);
 
 	fibril_rwlock_read_unlock(&socket_globals.lock);
@@ -595,6 +590,8 @@
 
 	/* Request listen backlog change */
-	result = (int) async_obsolete_req_3_0(socket->phone, NET_SOCKET_LISTEN,
+	async_exch_t *exch = async_exchange_begin(socket->sess);
+	result = (int) async_req_3_0(exch, NET_SOCKET_LISTEN,
 	    (sysarg_t) socket->socket_id, (sysarg_t) backlog, socket->service);
+	async_exchange_end(exch);
 
 	fibril_rwlock_read_unlock(&socket_globals.lock);
@@ -666,5 +663,5 @@
 		return socket_id;
 	}
-	socket_initialize(new_socket, socket_id, socket->phone,
+	socket_initialize(new_socket, socket_id, socket->sess,
 	    socket->service);
 	result = sockets_add(socket_get_sockets(), new_socket->socket_id,
@@ -678,10 +675,13 @@
 
 	/* Request accept */
-	message_id = async_obsolete_send_5(socket->phone, NET_SOCKET_ACCEPT,
+	async_exch_t *exch = async_exchange_begin(socket->sess);
+	message_id = async_send_5(exch, NET_SOCKET_ACCEPT,
 	    (sysarg_t) socket->socket_id, 0, socket->service, 0,
 	    new_socket->socket_id, &answer);
 
 	/* Read address */
-	async_obsolete_data_read_start(socket->phone, cliaddr, *addrlen);
+	async_data_read_start(exch, cliaddr, *addrlen);
+	async_exchange_end(exch);
+	
 	fibril_rwlock_write_unlock(&socket_globals.lock);
 	async_wait_for(message_id, &ipc_result);
@@ -777,6 +777,9 @@
 
 	/* Request close */
-	rc = (int) async_obsolete_req_3_0(socket->phone, NET_SOCKET_CLOSE,
+	async_exch_t *exch = async_exchange_begin(socket->sess);
+	rc = (int) async_req_3_0(exch, NET_SOCKET_CLOSE,
 	    (sysarg_t) socket->socket_id, 0, socket->service);
+	async_exchange_end(exch);
+	
 	if (rc != EOK) {
 		fibril_rwlock_write_unlock(&socket_globals.lock);
@@ -850,5 +853,7 @@
 
 	/* Request send */
-	message_id = async_obsolete_send_5(socket->phone, message,
+	async_exch_t *exch = async_exchange_begin(socket->sess);
+	
+	message_id = async_send_5(exch, message,
 	    (sysarg_t) socket->socket_id,
 	    (fragments == 1 ? datalength : socket->data_fragment_size),
@@ -857,11 +862,11 @@
 	/* Send the address if given */
 	if (!toaddr ||
-	    (async_obsolete_data_write_start(socket->phone, toaddr, addrlen) == EOK)) {
+	    (async_data_write_start(exch, toaddr, addrlen) == EOK)) {
 		if (fragments == 1) {
 			/* Send all if only one fragment */
-			async_obsolete_data_write_start(socket->phone, data, datalength);
+			async_data_write_start(exch, data, datalength);
 		} else {
 			/* Send the first fragment */
-			async_obsolete_data_write_start(socket->phone, data,
+			async_data_write_start(exch, data,
 			    socket->data_fragment_size - socket->header_size);
 			data = ((const uint8_t *) data) +
@@ -870,5 +875,5 @@
 			/* Send the middle fragments */
 			while (--fragments > 1) {
-				async_obsolete_data_write_start(socket->phone, data,
+				async_data_write_start(exch, data,
 				    socket->data_fragment_size);
 				data = ((const uint8_t *) data) +
@@ -877,9 +882,11 @@
 
 			/* Send the last fragment */
-			async_obsolete_data_write_start(socket->phone, data,
+			async_data_write_start(exch, data,
 			    (datalength + socket->header_size) %
 			    socket->data_fragment_size);
 		}
 	}
+	
+	async_exchange_end(exch);
 
 	async_wait_for(message_id, &result);
@@ -1023,4 +1030,6 @@
 		return 0;
 	}
+	
+	async_exch_t *exch = async_exchange_begin(socket->sess);
 
 	/* Prepare lengths if more fragments */
@@ -1035,5 +1044,5 @@
 
 		/* Request packet data */
-		message_id = async_obsolete_send_4(socket->phone, message,
+		message_id = async_send_4(exch, message,
 		    (sysarg_t) socket->socket_id, 0, socket->service,
 		    (sysarg_t) flags, &answer);
@@ -1041,8 +1050,8 @@
 		/* Read the address if desired */
 		if(!fromaddr ||
-		    (async_obsolete_data_read_start(socket->phone, fromaddr,
+		    (async_data_read_start(exch, fromaddr,
 		    *addrlen) == EOK)) {
 			/* Read the fragment lengths */
-			if (async_obsolete_data_read_start(socket->phone, lengths,
+			if (async_data_read_start(exch, lengths,
 			    sizeof(int) * (fragments + 1)) == EOK) {
 				if (lengths[fragments] <= datalength) {
@@ -1051,6 +1060,5 @@
 					for (index = 0; index < fragments;
 					    ++index) {
-						async_obsolete_data_read_start(
-						    socket->phone, data,
+						async_data_read_start(exch, data,
 						    lengths[index]);
 						data = ((uint8_t *) data) +
@@ -1064,5 +1072,5 @@
 	} else { /* fragments == 1 */
 		/* Request packet data */
-		message_id = async_obsolete_send_4(socket->phone, message,
+		message_id = async_send_4(exch, message,
 		    (sysarg_t) socket->socket_id, 0, socket->service,
 		    (sysarg_t) flags, &answer);
@@ -1070,10 +1078,11 @@
 		/* Read the address if desired */
 		if (!fromaddr ||
-		    (async_obsolete_data_read_start(socket->phone, fromaddr,
-		        *addrlen) == EOK)) {
+		    (async_data_read_start(exch, fromaddr, *addrlen) == EOK)) {
 			/* Read all if only one fragment */
-			async_obsolete_data_read_start(socket->phone, data, datalength);
+			async_data_read_start(exch, data, datalength);
 		}
 	}
+	
+	async_exchange_end(exch);
 
 	async_wait_for(message_id, &ipc_result);
@@ -1187,14 +1196,18 @@
 
 	/* Request option value */
-	message_id = async_obsolete_send_3(socket->phone, NET_SOCKET_GETSOCKOPT,
+	async_exch_t *exch = async_exchange_begin(socket->sess);
+	
+	message_id = async_send_3(exch, NET_SOCKET_GETSOCKOPT,
 	    (sysarg_t) socket->socket_id, (sysarg_t) optname, socket->service,
 	    NULL);
 
 	/* Read the length */
-	if (async_obsolete_data_read_start(socket->phone, optlen,
+	if (async_data_read_start(exch, optlen,
 	    sizeof(*optlen)) == EOK) {
 		/* Read the value */
-		async_obsolete_data_read_start(socket->phone, value, *optlen);
-	}
+		async_data_read_start(exch, value, *optlen);
+	}
+	
+	async_exchange_end(exch);
 
 	fibril_rwlock_read_unlock(&socket_globals.lock);
Index: uspace/lib/c/generic/str.c
===================================================================
--- uspace/lib/c/generic/str.c	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/lib/c/generic/str.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -544,4 +544,67 @@
 	
 	str_cpy(dest + dstr_size, size - dstr_size, src);
+}
+
+/** Convert space-padded ASCII to string.
+ *
+ * Common legacy text encoding in hardware is 7-bit ASCII fitted into
+ * a fixed-with byte buffer (bit 7 always zero), right-padded with spaces
+ * (ASCII 0x20). Convert space-padded ascii to string representation.
+ *
+ * If the text does not fit into the destination buffer, the function converts
+ * as many characters as possible and returns EOVERFLOW.
+ *
+ * If the text contains non-ASCII bytes (with bit 7 set), the whole string is
+ * converted anyway and invalid characters are replaced with question marks
+ * (U_SPECIAL) and the function returns EIO.
+ *
+ * Regardless of return value upon return @a dest will always be well-formed.
+ *
+ * @param dest		Destination buffer
+ * @param size		Size of destination buffer
+ * @param src		Space-padded ASCII.
+ * @param n		Size of the source buffer in bytes.
+ *
+ * @return		EOK on success, EOVERFLOW if the text does not fit
+ *			destination buffer, EIO if the text contains
+ *			non-ASCII bytes.
+ */
+int spascii_to_str(char *dest, size_t size, const uint8_t *src, size_t n)
+{
+	size_t sidx;
+	size_t didx;
+	size_t dlast;
+	uint8_t byte;
+	int rc;
+	int result;
+
+	/* There must be space for a null terminator in the buffer. */
+	assert(size > 0);
+	result = EOK;
+
+	didx = 0;
+	dlast = 0;
+	for (sidx = 0; sidx < n; ++sidx) {
+		byte = src[sidx];
+		if (!ascii_check(byte)) {
+			byte = U_SPECIAL;
+			result = EIO;
+		}
+
+		rc = chr_encode(byte, dest, &didx, size - 1);
+		if (rc != EOK) {
+			assert(rc == EOVERFLOW);
+			dest[didx] = '\0';
+			return rc;
+		}
+
+		/* Remember dest index after last non-empty character */
+		if (byte != 0x20)
+			dlast = didx;
+	}
+
+	/* Terminate string after last non-empty character */
+	dest[dlast] = '\0';
+	return result;
 }
 
Index: uspace/lib/c/include/adt/measured_strings.h
===================================================================
--- uspace/lib/c/include/adt/measured_strings.h	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/lib/c/include/adt/measured_strings.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -41,4 +41,5 @@
 
 #include <sys/types.h>
+#include <async.h>
 
 /** Type definition of the character string with measured length.
@@ -64,6 +65,9 @@
 extern int measured_strings_receive(measured_string_t **, uint8_t **, size_t);
 extern int measured_strings_reply(const measured_string_t *, size_t);
-extern int measured_strings_return(int, measured_string_t **, uint8_t **, size_t);
-extern int measured_strings_send(int, const measured_string_t *, size_t);
+
+extern int measured_strings_return(async_exch_t *, measured_string_t **,
+    uint8_t **, size_t);
+extern int measured_strings_send(async_exch_t *, const measured_string_t *,
+    size_t);
 
 #endif
Index: uspace/lib/c/include/bitops.h
===================================================================
--- uspace/lib/c/include/bitops.h	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/lib/c/include/bitops.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -38,4 +38,19 @@
 #include <sys/types.h>
 
+/** Mask with bit @a n set. */
+#define BIT_V(type, n) \
+    ((type)1 << ((n) - 1))
+
+/** Mask with rightmost @a n bits set. */
+#define BIT_RRANGE(type, n) \
+    (BIT_V(type, (n) + 1) - 1)
+
+/** Mask with bits @a hi .. @a lo set. @a hi >= @a lo. */
+#define BIT_RANGE(type, hi, lo) \
+    (BIT_RRANGE(type, (hi) - (lo) + 1) << (lo))
+
+/** Extract range of bits @a hi .. @a lo from @a value. */
+#define BIT_RANGE_EXTRACT(type, hi, lo, value) \
+    (((value) >> (lo)) & BIT_RRANGE(type, (hi) - (lo) + 1))
 
 /** Return position of first non-zero bit from left (i.e. [log_2(arg)]).
Index: pace/lib/c/include/devman_obsolete.h
===================================================================
--- uspace/lib/c/include/devman_obsolete.h	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ 	(revision )
@@ -1,52 +1,0 @@
-/*
- * Copyright (c) 2009 Jiri Svoboda
- * Copyright (c) 2010 Lenka Trochtova 
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING 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_DEVMAN_OBSOLETE_H_
-#define LIBC_DEVMAN_OBSOLETE_H_
-
-#include <ipc/devman.h>
-#include <async.h>
-#include <bool.h>
-
-extern int devman_obsolete_get_phone(devman_interface_t, unsigned int);
-extern void devman_obsolete_hangup_phone(devman_interface_t);
-
-extern int devman_obsolete_device_connect(devman_handle_t, unsigned int);
-extern int devman_obsolete_parent_device_connect(devman_handle_t, unsigned int);
-
-#endif
-
-/** @}
- */
Index: uspace/lib/c/include/fourcc.h
===================================================================
--- uspace/lib/c/include/fourcc.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
+++ uspace/lib/c/include/fourcc.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2011 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_FOURCC_H_
+#define LIBC_FOURCC_H_
+
+#include <libarch/common.h>
+
+#define FOURCC(a, b, c, d) \
+	(((UINT32_T) (a)) | (((UINT32_T) (b)) << 8) | \
+	    (((UINT32_T) (c)) << 16) | (((UINT32_T) (d)) << 24))
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/include/ipc/console.h
===================================================================
--- uspace/lib/c/include/ipc/console.h	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/lib/c/include/ipc/console.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -48,6 +48,5 @@
 	CONSOLE_SET_COLOR,
 	CONSOLE_SET_RGB_COLOR,
-	CONSOLE_CURSOR_VISIBILITY,
-	CONSOLE_KCON_ENABLE
+	CONSOLE_CURSOR_VISIBILITY
 } console_request_t;
 
Index: uspace/lib/c/include/ipc/net.h
===================================================================
--- uspace/lib/c/include/ipc/net.h	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/lib/c/include/ipc/net.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -335,11 +335,4 @@
 #define IPC_GET_ERROR(call)  ((services_t) IPC_GET_ARG4(call))
 
-/** Return the phone message argument.
- *
- * @param[in] call Message call structure.
- *
- */
-#define IPC_GET_PHONE(call)  ((int) IPC_GET_ARG5(call))
-
 /** Set the device identifier in the message answer.
  *
Index: uspace/lib/c/include/ipc/services.h
===================================================================
--- uspace/lib/c/include/ipc/services.h	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/lib/c/include/ipc/services.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -38,23 +38,25 @@
 #define LIBC_SERVICES_H_
 
+#include <fourcc.h>
+
 typedef enum {
-	SERVICE_NONE = 0,
-	SERVICE_LOAD,
-	SERVICE_VIDEO,
-	SERVICE_VFS,
-	SERVICE_DEVMAP,
-	SERVICE_DEVMAN,
-	SERVICE_IRC,
-	SERVICE_CLIPBOARD,
-	SERVICE_NETWORKING,
-	SERVICE_LO,
-	SERVICE_NE2000,
-	SERVICE_ETHERNET,
-	SERVICE_NILDUMMY,
-	SERVICE_IP,
-	SERVICE_ARP,
-	SERVICE_ICMP,
-	SERVICE_UDP,
-	SERVICE_TCP
+	SERVICE_NONE       = 0,
+	SERVICE_LOAD       = FOURCC('l', 'o', 'a', 'd'),
+	SERVICE_VIDEO      = FOURCC('v', 'i', 'd', ' '),
+	SERVICE_VFS        = FOURCC('v', 'f', 's', ' '),
+	SERVICE_DEVMAP     = FOURCC('d', 'e', 'v', 'p'),
+	SERVICE_DEVMAN     = FOURCC('d', 'e', 'v', 'n'),
+	SERVICE_IRC        = FOURCC('i', 'r', 'c', ' '),
+	SERVICE_CLIPBOARD  = FOURCC('c', 'l', 'i', 'p'),
+	SERVICE_NETWORKING = FOURCC('n', 'e', 't', ' '),
+	SERVICE_LO         = FOURCC('l', 'o', ' ', ' '),
+	SERVICE_NE2000     = FOURCC('n', 'e', '2', 'k'),
+	SERVICE_ETHERNET   = FOURCC('e', 't', 'h', ' '),
+	SERVICE_NILDUMMY   = FOURCC('n', 'i', 'l', 'd'),
+	SERVICE_IP         = FOURCC('i', 'p', 'v', '4'),
+	SERVICE_ARP        = FOURCC('a', 'r', 'p', ' '),
+	SERVICE_ICMP       = FOURCC('i', 'c', 'm', 'p'),
+	SERVICE_UDP        = FOURCC('u', 'd', 'p', ' '),
+	SERVICE_TCP        = FOURCC('t', 'c', 'p', ' ')
 } services_t;
 
Index: uspace/lib/c/include/net/icmp_api.h
===================================================================
--- uspace/lib/c/include/net/icmp_api.h	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/lib/c/include/net/icmp_api.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -42,9 +42,9 @@
 #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>
+#include <async.h>
 
 /** @name ICMP module application interface
@@ -53,6 +53,6 @@
 /*@{*/
 
-extern int icmp_echo_msg(int, size_t, mseconds_t, ip_ttl_t, ip_tos_t, int,
-    const struct sockaddr *, socklen_t);
+extern int icmp_echo_msg(async_sess_t *, size_t, mseconds_t, ip_ttl_t, ip_tos_t,
+    int, const struct sockaddr *, socklen_t);
 
 /*@}*/
Index: uspace/lib/c/include/net/icmp_common.h
===================================================================
--- uspace/lib/c/include/net/icmp_common.h	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/lib/c/include/net/icmp_common.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -40,6 +40,7 @@
 #include <ipc/services.h>
 #include <sys/time.h>
+#include <async.h>
 
-extern int icmp_connect_module(void);
+extern async_sess_t *icmp_connect_module(void);
 
 #endif
Index: uspace/lib/c/include/net/modules.h
===================================================================
--- uspace/lib/c/include/net/modules.h	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/lib/c/include/net/modules.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -46,17 +46,15 @@
 #include <sys/time.h>
 
-/** Connect to the needed module function type definition.
+/** Connect to module function type definition.
  *
- * @param[in] need The needed module service.
- *
- * @return The phone of the needed service.
+ * @return Session to the service.
  *
  */
-typedef int connect_module_t(services_t need);
+typedef async_sess_t *connect_module_t(services_t);
 
 extern void answer_call(ipc_callid_t, int, ipc_call_t *, size_t);
-extern int bind_service(services_t, sysarg_t, sysarg_t, sysarg_t,
+extern async_sess_t *bind_service(services_t, sysarg_t, sysarg_t, sysarg_t,
     async_client_conn_t);
-extern int connect_to_service(services_t);
+extern async_sess_t *connect_to_service(services_t);
 extern int data_reply(void *, size_t);
 extern void refresh_answer(ipc_call_t *, size_t *);
Index: uspace/lib/c/include/str.h
===================================================================
--- uspace/lib/c/include/str.h	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/lib/c/include/str.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -48,4 +48,10 @@
 #define STR_BOUNDS(length)  ((length) << 2)
 
+/**
+ * Maximum size of a buffer needed to a string converted from space-padded
+ * ASCII of size @a spa_size using spascii_to_str().
+ */
+#define SPASCII_STR_BUFSIZE(spa_size) ((spa_size) + 1)
+
 extern wchar_t str_decode(const char *str, size_t *offset, size_t sz);
 extern int chr_encode(const wchar_t ch, char *str, size_t *offset, size_t sz);
@@ -73,4 +79,5 @@
 extern void str_append(char *dest, size_t size, const char *src);
 
+extern int spascii_to_str(char *dest, size_t size, const uint8_t *src, size_t n);
 extern void wstr_to_str(char *dest, size_t size, const wchar_t *src);
 extern char *wstr_to_astr(const wchar_t *src);
Index: uspace/lib/drv/generic/driver.c
===================================================================
--- uspace/lib/drv/generic/driver.c	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/lib/drv/generic/driver.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -314,4 +314,10 @@
 		    " %" PRIun " was found.\n", driver->name, handle);
 		async_answer_0(iid, ENOENT);
+		return;
+	}
+	
+	if (fun->conn_handler != NULL) {
+		/* Driver has a custom connection handler. */
+		(*fun->conn_handler)(iid, icall, (void *)fun);
 		return;
 	}
Index: uspace/lib/drv/include/ddf/driver.h
===================================================================
--- uspace/lib/drv/include/ddf/driver.h	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/lib/drv/include/ddf/driver.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -118,4 +118,6 @@
 	/** Implementation of operations provided by this function */
 	ddf_dev_ops_t *ops;
+	/** Connection handler or @c NULL to use the DDF default handler. */
+	async_client_conn_t conn_handler;
 	
 	/** Link in the list of functions handled by the driver */
Index: uspace/lib/ext2/libext2_directory.c
===================================================================
--- uspace/lib/ext2/libext2_directory.c	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/lib/ext2/libext2_directory.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -86,32 +86,17 @@
  * @param fs pointer to filesystem structure
  * @param inode pointer to inode reference structure
+ * @param pos position within inode to start at, 0 is the first entry
  * @return EOK on success or negative error code on failure
  */
 int ext2_directory_iterator_init(ext2_directory_iterator_t *it,
-    ext2_filesystem_t *fs, ext2_inode_ref_t *inode_ref)
-{
-	int rc;
-	uint32_t block_id;
-	uint32_t block_size;
-	
+    ext2_filesystem_t *fs, ext2_inode_ref_t *inode_ref, aoff64_t pos)
+{	
 	it->inode_ref = inode_ref;
 	it->fs = fs;
-	
-	/* Get the first data block, so we can get the first entry */
-	rc = ext2_filesystem_get_inode_data_block_index(fs, inode_ref->inode, 0, 
-	    &block_id);
-	if (rc != EOK) {
-		return rc;
-	}
-	
-	rc = block_get(&it->current_block, fs->device, block_id, 0);
-	if (rc != EOK) {
-		return rc;
-	}
-	
-	block_size = ext2_superblock_get_block_size(fs->superblock);
-	
-	it->current_offset = 0;	
-	return ext2_directory_iterator_set(it, block_size);
+	it->current = NULL;
+	it->current_offset = 0;
+	it->current_block = NULL;
+	
+	return ext2_directory_iterator_seek(it, pos);
 }
 
@@ -124,6 +109,23 @@
 int ext2_directory_iterator_next(ext2_directory_iterator_t *it)
 {
+	uint16_t skip;
+	
+	assert(it->current != NULL);
+	
+	skip = ext2_directory_entry_ll_get_entry_length(it->current);
+	
+	return ext2_directory_iterator_seek(it, it->current_offset + skip);
+}
+
+/**
+ * Seek the directory iterator to the given byte offset within the inode.
+ * 
+ * @param it pointer to iterator to initialize
+ * @return EOK on success or negative error code on failure
+ */
+int ext2_directory_iterator_seek(ext2_directory_iterator_t *it, aoff64_t pos)
+{
 	int rc;
-	uint16_t skip;
+	
 	uint64_t size;
 	aoff64_t current_block_idx;
@@ -132,19 +134,20 @@
 	uint32_t block_size;
 	
-	assert(it->current != NULL);
-	
-	skip = ext2_directory_entry_ll_get_entry_length(it->current);
 	size = ext2_inode_get_size(it->fs->superblock, it->inode_ref->inode);
 	
+	/* The iterator is not valid until we seek to the desired position */
+	it->current = NULL;
+	
 	/* Are we at the end? */
-	if (it->current_offset + skip >= size) {
-		rc = block_put(it->current_block);
-		it->current_block = NULL;
-		it->current = NULL;
-		if (rc != EOK) {
-			return rc;
+	if (pos >= size) {		
+		if (it->current_block) {
+			rc = block_put(it->current_block);
+			it->current_block = NULL;
+			if (rc != EOK) {
+				return rc;
+			}
 		}
 		
-		it->current_offset += skip;
+		it->current_offset = pos;
 		return EOK;
 	}
@@ -152,15 +155,16 @@
 	block_size = ext2_superblock_get_block_size(it->fs->superblock);
 	current_block_idx = it->current_offset / block_size;
-	next_block_idx = (it->current_offset + skip) / block_size;
-	
-	/* If we are moving accross block boundary,
+	next_block_idx = pos / block_size;
+	
+	/* If we don't have a block or are moving accross block boundary,
 	 * we need to get another block
 	 */
-	if (current_block_idx != next_block_idx) {
-		rc = block_put(it->current_block);
-		it->current_block = NULL;
-		it->current = NULL;
-		if (rc != EOK) {
-			return rc;
+	if (it->current_block == NULL || current_block_idx != next_block_idx) {		
+		if (it->current_block) {
+			rc = block_put(it->current_block);
+			it->current_block = NULL;
+			if (rc != EOK) {
+				return rc;
+			}
 		}
 		
@@ -179,8 +183,15 @@
 	}
 	
-	it->current_offset += skip;
+	it->current_offset = pos;
 	return ext2_directory_iterator_set(it, block_size);
 }
 
+/** Setup the entry at the current iterator offset.
+ * 
+ * This function checks the validity of the directory entry,
+ * before setting the data pointer.
+ *
+ * @return EOK on success or error code on failure 
+ */
 static int ext2_directory_iterator_set(ext2_directory_iterator_t *it,
     uint32_t block_size)
Index: uspace/lib/ext2/libext2_directory.h
===================================================================
--- uspace/lib/ext2/libext2_directory.h	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/lib/ext2/libext2_directory.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -71,6 +71,7 @@
 
 extern int ext2_directory_iterator_init(ext2_directory_iterator_t *,
-    ext2_filesystem_t *, ext2_inode_ref_t *);
+    ext2_filesystem_t *, ext2_inode_ref_t *, aoff64_t);
 extern int ext2_directory_iterator_next(ext2_directory_iterator_t *);
+extern int ext2_directory_iterator_seek(ext2_directory_iterator_t *, aoff64_t pos);
 extern int ext2_directory_iterator_fini(ext2_directory_iterator_t *);
 
Index: uspace/lib/net/adt/module_map.c
===================================================================
--- uspace/lib/net/adt/module_map.c	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/lib/net/adt/module_map.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -39,9 +39,5 @@
 #include <unistd.h>
 #include <errno.h>
-
-#include <ipc/services.h>
-
 #include <net/modules.h>
-
 #include <adt/generic_char_map.h>
 #include <adt/module_map.h>
@@ -49,19 +45,20 @@
 GENERIC_CHAR_MAP_IMPLEMENT(modules, module_t)
 
-/** Adds module to the module map.
+/** Add 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.
- * @return		EOK on success.
- * @return		ENOMEM if there is not enough memory left.
+ * @param[out] module         Module structure added.
+ * @param[in]  modules        Module map.
+ * @param[in]  name           Module name.
+ * @param[in]  filename       Full path filename.
+ * @param[in]  service        Module service.
+ * @param[in]  task_id        Module current task identifier.
+ *                            Zero means not running.
+ * @param[in]  connect_module Module connecting function.
+ *
+ * @return EOK on success.
+ * @return ENOMEM if there is not enough memory left.
+ *
  */
-int
-add_module(module_t **module, modules_t *modules, const uint8_t *name,
+int add_module(module_t **module, modules_t *modules, const uint8_t *name,
     const uint8_t *filename, services_t service, task_id_t task_id,
     connect_module_t connect_module)
@@ -69,11 +66,11 @@
 	module_t *tmp_module;
 	int rc;
-
+	
 	tmp_module = (module_t *) malloc(sizeof(module_t));
 	if (!tmp_module)
 		return ENOMEM;
-
+	
 	tmp_module->task_id = task_id;
-	tmp_module->phone = 0;
+	tmp_module->sess = NULL;
 	tmp_module->usage = 0;
 	tmp_module->name = name;
@@ -81,5 +78,5 @@
 	tmp_module->service = service;
 	tmp_module->connect_module = connect_module;
-
+	
 	rc = modules_add(modules, tmp_module->name, 0, tmp_module);
 	if (rc != EOK) {
@@ -87,29 +84,30 @@
 		return rc;
 	}
+	
 	if (module)
 		*module = tmp_module;
-
+	
 	return EOK;
 }
 
-/** Searches and returns the specified module.
+/** Search and return 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.
- * @return		The running module found. It does not have to be
- *			connected.
- * @return		NULL if there is no such module.
+ * @param[in] modules Module map.
+ * @param[in] name    Module name.
+ *
+ * @return The running module found. It does not have to be
+ *         connected.
+ * @return NULL if there is no such module.
+ *
  */
 module_t *get_running_module(modules_t *modules, uint8_t *name)
 {
-	module_t *module;
-
-	module = modules_find(modules, name, 0);
+	module_t *module = modules_find(modules, name, 0);
 	if (!module)
 		return NULL;
-
+	
 	if (!module->task_id) {
 		module->task_id = net_spawn(module->filename);
@@ -117,7 +115,8 @@
 			return NULL;
 	}
-	if (!module->phone)
-		module->phone = module->connect_module(module->service);
-
+	
+	if (!module->sess)
+		module->sess = module->connect_module(module->service);
+	
 	return module;
 }
Index: uspace/lib/net/generic/generic.c
===================================================================
--- uspace/lib/net/generic/generic.c	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/lib/net/generic/generic.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -37,5 +37,4 @@
 #include <generic.h>
 #include <async.h>
-#include <async_obsolete.h>
 #include <ipc/services.h>
 #include <net/device.h>
@@ -45,18 +44,19 @@
 /** 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_obsolete_msg_3(phone, (sysarg_t) message, (sysarg_t) device_id,
-	    (sysarg_t) state, target);
+ * @param[in] sess      Service module session.
+ * @param[in] message   Service specific message.
+ * @param[in] device_id Device identifier.
+ * @param[in] state     New device state.
+ * @param[in] target    Target module service.
+ *
+ * @return EOK on success.
+ *
+ */
+int generic_device_state_msg_remote(async_sess_t *sess, sysarg_t message,
+    device_id_t device_id, sysarg_t state, services_t target)
+{
+	async_exch_t *exch = async_exchange_begin(sess);
+	async_msg_3(exch, message, (sysarg_t) device_id, state, target);
+	async_exchange_end(exch);
 	
 	return EOK;
@@ -65,54 +65,59 @@
 /** 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_obsolete_req_3_0(phone, (sysarg_t) message,
-	    (sysarg_t) device_id, (sysarg_t) arg2, (sysarg_t) service);
+ * @param[in] sess      Service module session.
+ * @param[in] message   Service specific message.
+ * @param[in] device_id Device identifier.
+ * @param[in] arg2      Second argument of the message.
+ * @param[in] service   Device module service.
+ *
+ * @return EOK on success.
+ * @return Other error codes as defined for the specific service
+ *         message.
+ *
+ */
+int generic_device_req_remote(async_sess_t *sess, sysarg_t message,
+    device_id_t device_id, sysarg_t arg2, services_t service)
+{
+	async_exch_t *exch = async_exchange_begin(sess);
+	int rc = async_req_3_0(exch, message, (sysarg_t) device_id,
+	    arg2, (sysarg_t) service);
+	async_exchange_end(exch);
+	
+	return rc;
 }
 
 /** 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.
- * @return		EOK on success.
- * @return		EBADMEM if the address parameter and/or the data
- *			parameter is NULL.
- * @return		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_t **address, uint8_t **data)
-{
-	aid_t message_id;
+ * @param[in] sess      Service module session.
+ * @param[in] message   Service specific message.
+ * @param[in] device_id Device identifier.
+ * @param[out] address  Desired address.
+ * @param[out] data     Address data container.
+ *
+ * @return EOK on success.
+ * @return EBADMEM if the address parameter and/or the data
+ *         parameter is NULL.
+ * @return Other error codes as defined for the specific service
+ *         message.
+ *
+ */
+int generic_get_addr_req(async_sess_t *sess, sysarg_t message,
+    device_id_t device_id, measured_string_t **address, uint8_t **data)
+{
+	if ((!address) || (!data))
+		return EBADMEM;
+	
+	/* Request the address */
+	async_exch_t *exch = async_exchange_begin(sess);
+	aid_t message_id = async_send_1(exch, message, (sysarg_t) device_id,
+	    NULL);
+	int rc = measured_strings_return(exch, address, data, 1);
+	async_exchange_end(exch);
+	
 	sysarg_t result;
-	int string;
-
-	if (!address || !data)
-		return EBADMEM;
-
-	/* Request the address */
-	message_id = async_obsolete_send_1(phone, (sysarg_t) message,
-	    (sysarg_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)) {
+	if ((rc == EOK) && (result != EOK)) {
 		/* Clear the data */
 		free(*address);
@@ -125,16 +130,17 @@
 /** 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_t *packet_dimension)
+ * @param[in] sess              Service module session.
+ * @param[in] message           Service specific message.
+ * @param[in] device_id         Device identifier.
+ * @param[out] packet_dimension 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(async_sess_t *sess, sysarg_t message,
+    device_id_t device_id, packet_dimension_t *packet_dimension)
 {
 	if (!packet_dimension)
@@ -146,6 +152,8 @@
 	sysarg_t suffix;
 	
-	sysarg_t result = async_obsolete_req_1_4(phone, (sysarg_t) message,
-	    (sysarg_t) device_id, &addr_len, &prefix, &content, &suffix);
+	async_exch_t *exch = async_exchange_begin(sess);
+	sysarg_t result = async_req_1_4(exch, message, (sysarg_t) device_id,
+	    &addr_len, &prefix, &content, &suffix);
+	async_exchange_end(exch);
 	
 	packet_dimension->prefix = (size_t) prefix;
@@ -159,25 +167,31 @@
 /** 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)
-{
+ * @param[in] sess      Service module session.
+ * @param[in] message   Service specific message.
+ * @param[in] device_id Device identifier.
+ * @param[in] packet_id Received packet or the received packet queue
+ *                      identifier.
+ * @param[in] target    Target module service.
+ * @param[in] error     Error module service.
+ *
+ * @return EOK on success.
+ *
+ */
+int generic_received_msg_remote(async_sess_t *sess, sysarg_t message,
+    device_id_t device_id, packet_id_t packet_id, services_t target,
+    services_t error)
+{
+	async_exch_t *exch = async_exchange_begin(sess);
+	
 	if (error) {
-		async_obsolete_msg_4(phone, (sysarg_t) message, (sysarg_t) device_id,
+		async_msg_4(exch, message, (sysarg_t) device_id,
 		    (sysarg_t) packet_id, (sysarg_t) target, (sysarg_t) error);
 	} else {
-		async_obsolete_msg_3(phone, (sysarg_t) message, (sysarg_t) device_id,
+		async_msg_3(exch, message, (sysarg_t) device_id,
 		    (sysarg_t) packet_id, (sysarg_t) target);
 	}
 	
+	async_exchange_end(exch);
+	
 	return EOK;
 }
@@ -185,25 +199,30 @@
 /** 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)
-{
+ * @param[in] sess      Service module session.
+ * @param[in] message   Service specific message.
+ * @param[in] device_id Device identifier.
+ * @param[in] packet_id Packet or the packet queue identifier.
+ * @param[in] sender    Sending module service.
+ * @param[in] error     Error module service.
+ *
+ * @return EOK on success.
+ *
+ */
+int generic_send_msg_remote(async_sess_t *sess, sysarg_t message,
+    device_id_t device_id, packet_id_t packet_id, services_t sender,
+    services_t error)
+{
+	async_exch_t *exch = async_exchange_begin(sess);
+	
 	if (error) {
-		async_obsolete_msg_4(phone, (sysarg_t) message, (sysarg_t) device_id,
+		async_msg_4(exch, message, (sysarg_t) device_id,
 		    (sysarg_t) packet_id, (sysarg_t) sender, (sysarg_t) error);
 	} else {
-		async_obsolete_msg_3(phone, (sysarg_t) message, (sysarg_t) device_id,
+		async_msg_3(exch, message, (sysarg_t) device_id,
 		    (sysarg_t) packet_id, (sysarg_t) sender);
 	}
 	
+	async_exchange_end(exch);
+	
 	return EOK;
 }
@@ -213,48 +232,51 @@
  * 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.
- * @return		EOK on success.
- * @return		EINVAL if the configuration parameter is NULL.
- * @return		EINVAL if the count parameter is zero.
- * @return		EBADMEM if the translation or the data parameters are
- *			NULL.
- * @return		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_t *configuration, size_t count,
+ * @param[in] sess          Service module session.
+ * @param[in] message       Service specific message.
+ * @param[in] device_id     Device identifier.
+ * @param[in] service       Module service.
+ * @param[in] configuration Key strings.
+ * @param[in] count         Number of configuration keys.
+ * @param[out] translation  Translated values.
+ * @param[out] data         Translation data container.
+ *
+ * @return EOK on success.
+ * @return EINVAL if the configuration parameter is NULL.
+ * @return EINVAL if the count parameter is zero.
+ * @return EBADMEM if the translation or the data parameters are
+ *         NULL.
+ * @return Other error codes as defined for the specific service
+ *         message.
+ *
+ */
+int generic_translate_req(async_sess_t *sess, sysarg_t message,
+    device_id_t device_id, services_t service,
+    measured_string_t *configuration, size_t count,
     measured_string_t **translation, uint8_t **data)
 {
-	aid_t message_id;
+	if ((!configuration) || (count == 0))
+		return EINVAL;
+	
+	if ((!translation) || (!data))
+		return EBADMEM;
+	
+	/* Request the translation */
+	async_exch_t *exch = async_exchange_begin(sess);
+	aid_t message_id = async_send_3(exch, message, (sysarg_t) device_id,
+	    (sysarg_t) count, (sysarg_t) service, NULL);
+	measured_strings_send(exch, configuration, count);
+	int rc = measured_strings_return(exch, translation, data, count);
+	async_exchange_end(exch);
+	
 	sysarg_t result;
-	int string;
-
-	if (!configuration || (count == 0))
-		return EINVAL;
-	if (!translation || !data)
-		return EBADMEM;
-
-	/* Request the translation */
-	message_id = async_obsolete_send_3(phone, (sysarg_t) message,
-	    (sysarg_t) device_id, (sysarg_t) count, (sysarg_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)) {
+	if ((rc == EOK) && (result != EOK)) {
 		/* Clear the data */
 		free(*translation);
 		free(*data);
 	}
-
+	
 	return (int) result;
 }
Index: uspace/lib/net/generic/net_remote.c
===================================================================
--- uspace/lib/net/generic/net_remote.c	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/lib/net/generic/net_remote.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -47,19 +47,22 @@
 #include <adt/measured_strings.h>
 
-/** Connects to the networking module.
+/** Connect to the networking module.
  *
- * @return		The networking module phone on success.
+ * @return Networking module session on success.
+ *
  */
-int net_connect_module(void)
+async_sess_t *net_connect_module(void)
 {
 	return connect_to_service(SERVICE_NETWORKING);
 }
 
-/** Frees the received settings.
+/** Free the received settings.
  *
- * @param[in] settings	The received settings.
- * @param[in] data	The received settings data.
- * @see	net_get_device_conf_req()
+ * @param[in] settings Received settings.
+ * @param[in] data     Received settings data.
+ *
+ * @see net_get_device_conf_req()
  * @see net_get_conf_req()
+ *
  */
 void net_free_settings(measured_string_t *settings, uint8_t *data)
@@ -71,5 +74,5 @@
 }
 
-/** Returns the global configuration.
+/** Return the global configuration.
  *
  * The configuration names are read and the appropriate settings are set
@@ -77,48 +80,52 @@
  * 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]     sess          Networking module session.
+ * @param[in,out] configuration 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.
- * @return		EOK on success.
- * @return		EINVAL if the configuration is NULL.
- * @return		EINVAL if the count is zero.
- * @return		Other error codes as defined for the
- *			generic_translate_req() function.
+ * @param[in]     count         Configuration entries count.
+ * @param[in,out] data          Configuration and settings data.
+ *
+ * @return EOK on success.
+ * @return EINVAL if the configuration is NULL.
+ * @return EINVAL if the count is zero.
+ * @return Other error codes as defined for the
+ *         generic_translate_req() function.
+ *
  */
-int
-net_get_conf_req(int net_phone, measured_string_t **configuration,
+int net_get_conf_req(async_sess_t *sess, measured_string_t **configuration,
     size_t count, uint8_t **data)
 {
-	return generic_translate_req(net_phone, NET_NET_GET_DEVICE_CONF, 0, 0,
+	return generic_translate_req(sess, NET_NET_GET_DEVICE_CONF, 0, 0,
 	    *configuration, count, configuration, data);
 }
 
-/** Returns the device specific configuration.
+/** Return the device specific configuration.
  *
- * Returns the global configuration if the device specific is not found.
+ * Return 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.
- * @return		EOK on success.
- * @return		EINVAL if the configuration is NULL.
- * @return		EINVAL if the count is zero.
- * @return		Other error codes as defined for the
- *			generic_translate_req() function.
+ * @param[in]     sess          The networking module session.
+ * @param[in]     device_id     Device identifier.
+ * @param[in,out] configuration Requested device configuration. The names
+ *                              are read and the appropriate settings are
+ *                              set instead.
+ * @param[in]     count         Configuration entries count.
+ * @param[in,out] data          Configuration and settings data.
+ *
+ * @return EOK on success.
+ * @return EINVAL if the configuration is NULL.
+ * @return EINVAL if the count is zero.
+ * @return 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,
+int net_get_device_conf_req(async_sess_t *sess, device_id_t device_id,
     measured_string_t **configuration, size_t count, uint8_t **data)
 {
-	return generic_translate_req(net_phone, NET_NET_GET_DEVICE_CONF,
+	return generic_translate_req(sess, 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 eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/lib/net/generic/packet_client.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -247,33 +247,34 @@
 }
 
-/** 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.
- * @return		The packet copy.
- * @return		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;
-
+/** Return the packet copy.
+ *
+ * Copy the addresses, data, order and metric values.
+ * Queue placement is not copied.
+ *
+ * @param[in] sess   Packet server module session.
+ * @param[in] packet Original packet.
+ *
+ * @return Packet copy.
+ * @return NULL on error.
+ *
+ */
+packet_t *packet_get_copy(async_sess_t *sess, packet_t *packet)
+{
+	if (!packet_is_valid(packet))
+		return NULL;
+	
 	/* Get a new packet */
-	copy = packet_get_4_remote(phone, PACKET_DATA_LENGTH(packet),
+	packet_t *copy = packet_get_4_remote(sess, 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);
+	uint8_t *src = NULL;
+	uint8_t *dest = NULL;
+	size_t addrlen = packet_get_addr(packet, &src, &dest);
+	
 	/* Copy data */
 	if ((packet_copy_data(copy, packet_get_data(packet),
@@ -286,5 +287,5 @@
 		return copy;
 	} else {
-		pq_release_remote(phone, copy->packet_id);
+		pq_release_remote(sess, copy->packet_id);
 		return NULL;
 	}
Index: uspace/lib/net/generic/packet_remote.c
===================================================================
--- uspace/lib/net/generic/packet_remote.c	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/lib/net/generic/packet_remote.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -37,5 +37,4 @@
 
 #include <async.h>
-#include <async_obsolete.h>
 #include <errno.h>
 #include <ipc/packet.h>
@@ -52,63 +51,64 @@
  * Create the local packet mapping as well.
  *
- * @param[in]  phone     The packet server module phone.
- * @param[out] packet    The packet reference pointer to store the received
+ * @param[in]  sess      Packet server module session.
+ * @param[out] packet    Packet reference pointer to store the received
  *                       packet reference.
- * @param[in]  packet_id The packet identifier.
- * @param[in]  size      The packet total size in bytes.
+ * @param[in]  packet_id Packet identifier.
+ * @param[in]  size      Packet total size in bytes.
  *
  * @return EOK on success.
  * @return Other error codes as defined for the pm_add() function.
- * @return Other error codes as defined for the async_obsolete_share_in_start() function.
- *
- */
-static int
-packet_return(int phone, packet_t **packet, packet_id_t packet_id, size_t size)
-{
+ * @return Other error codes as defined for the async_share_in_start()
+ *         function.
+ *
+ */
+static int packet_return(async_sess_t *sess, packet_t **packet,
+    packet_id_t packet_id, size_t size)
+{
+	*packet = (packet_t *) as_get_mappable_page(size);
+	
+	async_exch_t *exch = async_exchange_begin(sess);
 	ipc_call_t answer;
-	aid_t message;
-	int rc;
-	
-	message = async_obsolete_send_1(phone, NET_PACKET_GET, packet_id, &answer);
-
-	*packet = (packet_t *) as_get_mappable_page(size);
-	rc = async_obsolete_share_in_start_0_0(phone, *packet, size);
+	aid_t message = async_send_1(exch, NET_PACKET_GET, packet_id, &answer);
+	int rc = async_share_in_start_0_0(exch, *packet, size);
+	async_exchange_end(exch);
+	
+	sysarg_t result;
+	async_wait_for(message, &result);
+	
 	if (rc != EOK) {
 		munmap(*packet, size);
-		async_wait_for(message, NULL);
 		return rc;
 	}
+	
 	rc = pm_add(*packet);
 	if (rc != EOK) {
 		munmap(*packet, size);
-		async_wait_for(message, NULL);
 		return rc;
 	}
 	
-	sysarg_t result;
-	async_wait_for(message, &result);
-	
 	return result;
 }
 
-/** 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.
- * @return		EOK on success.
- * @return		EINVAL if the packet parameter is NULL.
- * @return		Other error codes as defined for the NET_PACKET_GET_SIZE
- *			message.
- * @return		Other error codes as defined for the packet_return()
- *			function.
- */
-int packet_translate_remote(int phone, packet_t **packet, packet_id_t packet_id)
-{
-	int rc;
-	
+/** Translate the packet identifier to the packet reference.
+ *
+ * Try to find mapping first. The packet server is asked to share
+ * the packet if the mapping is not present.
+ *
+ * @param[in]  sess      Packet server module session.
+ * @param[out] packet    Packet reference.
+ * @param[in]  packet_id Packet identifier.
+ *
+ * @return EOK on success.
+ * @return EINVAL if the packet parameter is NULL.
+ * @return Other error codes as defined for the NET_PACKET_GET_SIZE
+ *         message.
+ * @return Other error codes as defined for the packet_return()
+ *         function.
+ *
+ */
+int packet_translate_remote(async_sess_t *sess, packet_t **packet,
+    packet_id_t packet_id)
+{
 	if (!packet)
 		return EINVAL;
@@ -116,18 +116,21 @@
 	*packet = pm_find(packet_id);
 	if (!*packet) {
+		async_exch_t *exch = async_exchange_begin(sess);
 		sysarg_t size;
+		int rc = async_req_1_1(exch, NET_PACKET_GET_SIZE, packet_id,
+		    &size);
+		async_exchange_end(exch);
 		
-		rc = async_obsolete_req_1_1(phone, NET_PACKET_GET_SIZE, packet_id,
-		    &size);
 		if (rc != EOK)
 			return rc;
-		rc = packet_return(phone, packet, packet_id, size);
+		
+		rc = packet_return(sess, packet, packet_id, size);
 		if (rc != EOK)
 			return rc;
 	}
+	
 	if ((*packet)->next) {
 		packet_t *next;
-		
-		return packet_translate_remote(phone, &next, (*packet)->next);
+		return packet_translate_remote(sess, &next, (*packet)->next);
 	}
 	
@@ -135,33 +138,35 @@
 }
 
-/** 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.
- * @return		The packet reference.
- * @return		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)
-{
+/** Obtain the packet of given dimensions.
+ *
+ * Contact the packet server to return the appropriate packet.
+ *
+ * @param[in] sess        Packet server module session.
+ * @param[in] addr_len    Source and destination addresses maximal length
+ *                        in bytes.
+ * @param[in] max_prefix  Maximal prefix length in bytes.
+ * @param[in] max_content Maximal content length in bytes.
+ * @param[in] max_suffix  Maximal suffix length in bytes.
+ *
+ * @return The packet reference.
+ * @return NULL on error.
+ *
+ */
+packet_t *packet_get_4_remote(async_sess_t *sess, size_t max_content,
+    size_t addr_len, size_t max_prefix, size_t max_suffix)
+{
+	async_exch_t *exch = async_exchange_begin(sess);
 	sysarg_t packet_id;
 	sysarg_t size;
-	int rc;
-	
-	rc = async_obsolete_req_4_2(phone, NET_PACKET_CREATE_4, max_content, addr_len,
+	int rc = async_req_4_2(exch, NET_PACKET_CREATE_4, max_content, addr_len,
 	    max_prefix, max_suffix, &packet_id, &size);
+	async_exchange_end(exch);
+	
 	if (rc != EOK)
 		return NULL;
 	
-	
 	packet_t *packet = pm_find(packet_id);
 	if (!packet) {
-		rc = packet_return(phone, &packet, packet_id, size);
+		rc = packet_return(sess, &packet, packet_id, size);
 		if (rc != EOK)
 			return NULL;
@@ -171,21 +176,24 @@
 }
 
-/** 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.
- * @return		The packet reference.
- * @return		NULL on error.
- */
-packet_t *packet_get_1_remote(int phone, size_t content)
-{
+/** Obtain the packet of given content size.
+ *
+ * Contact the packet server to return the appropriate packet.
+ *
+ * @param[in] sess    Packet server module session.
+ * @param[in] content Maximal content length in bytes.
+ *
+ * @return The packet reference.
+ * @return NULL on error.
+ *
+ */
+packet_t *packet_get_1_remote(async_sess_t *sess, size_t content)
+{
+	async_exch_t *exch = async_exchange_begin(sess);
 	sysarg_t packet_id;
 	sysarg_t size;
-	int rc;
-	
-	rc = async_obsolete_req_1_2(phone, NET_PACKET_CREATE_1, content, &packet_id,
+	int rc = async_req_1_2(exch, NET_PACKET_CREATE_1, content, &packet_id,
 	    &size);
+	async_exchange_end(exch);
+	
 	if (rc != EOK)
 		return NULL;
@@ -193,5 +201,5 @@
 	packet_t *packet = pm_find(packet_id);
 	if (!packet) {
-		rc = packet_return(phone, &packet, packet_id, size);
+		rc = packet_return(sess, &packet, packet_id, size);
 		if (rc != EOK)
 			return NULL;
@@ -201,5 +209,5 @@
 }
 
-/** Releases the packet queue.
+/** Release the packet queue.
  *
  * All packets in the queue are marked as free for use.
@@ -208,10 +216,13 @@
  * 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)
-{
-	async_obsolete_msg_1(phone, NET_PACKET_RELEASE, packet_id);
+ * @param[in] sess      Packet server module session.
+ * @param[in] packet_id Packet identifier.
+ *
+ */
+void pq_release_remote(async_sess_t *sess, packet_id_t packet_id)
+{
+	async_exch_t *exch = async_exchange_begin(sess);
+	async_msg_1(exch, NET_PACKET_RELEASE, packet_id);
+	async_exchange_end(exch);
 }
 
Index: uspace/lib/net/il/arp_remote.c
===================================================================
--- uspace/lib/net/il/arp_remote.c	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/lib/net/il/arp_remote.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -38,25 +38,20 @@
 #include <arp_interface.h>
 #include <generic.h>
-
-#include <async.h>
-#include <async_obsolete.h>
-#include <errno.h>
 #include <ipc/services.h>
 #include <ipc/arp.h>
-
 #include <net/modules.h>
 #include <net/device.h>
 #include <adt/measured_strings.h>
+#include <async.h>
+#include <errno.h>
 
-/** Connects to the ARP module.
+/** Connect to the ARP module.
  *
- * @param service	The ARP module service. Ignored parameter.
- * @return		The ARP module phone on success.
+ * @return ARP module session on success.
+ *
  */
-int arp_connect_module(services_t service)
+async_sess_t *arp_connect_module(services_t service)
 {
-	if (service != SERVICE_ARP)
-		return EINVAL;
-
+	// FIXME: Get rid of the useless argument
 	return connect_to_service(SERVICE_ARP);
 }
@@ -64,31 +59,98 @@
 /** Cleans the cache.
  *
- * @param[in] arp_phone	The ARP module phone used for (semi)remote calls.
- * @return		EOK on success.
+ * @param[in] sess ARP module session.
+ *
+ * @return EOK on success.
+ *
  */
-int arp_clean_cache_req(int arp_phone)
+int arp_clean_cache_req(async_sess_t *sess)
 {
-	return (int) async_obsolete_req_0_0(arp_phone, NET_ARP_CLEAN_CACHE);
+	async_exch_t *exch = async_exchange_begin(sess);
+	int rc = async_req_0_0(exch, NET_ARP_CLEAN_CACHE);
+	async_exchange_end(exch);
+	
+	return rc;
 }
 
-/** Clears the given protocol address from the cache.
+/** Clear 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.
- * @return		EOK on success.
- * @return		ENOENT if the mapping is not found.
+ * @param[in] sess      ARP module session.
+ * @param[in] device_id Device identifier.
+ * @param[in] protocol  Requesting protocol service.
+ * @param[in] address   Protocol address to be cleared.
+ *
+ * @return EOK on success.
+ * @return 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_t *address)
+int arp_clear_address_req(async_sess_t *sess, device_id_t device_id,
+    services_t protocol, measured_string_t *address)
 {
-	aid_t message_id;
+	async_exch_t *exch = async_exchange_begin(sess);
+	aid_t message_id = async_send_2(exch, NET_ARP_CLEAR_ADDRESS,
+	    (sysarg_t) device_id, protocol, NULL);
+	measured_strings_send(exch, address, 1);
+	async_exchange_end(exch);
+	
 	sysarg_t result;
+	async_wait_for(message_id, &result);
+	
+	return (int) result;
+}
 
-	message_id = async_obsolete_send_2(arp_phone, NET_ARP_CLEAR_ADDRESS,
-	    (sysarg_t) device_id, protocol, NULL);
-	measured_strings_send(arp_phone, address, 1);
+/** Clear the device cache.
+ *
+ * @param[in] sess      ARP module session.
+ * @param[in] device_id Device identifier.
+ *
+ * @return EOK on success.
+ * @return ENOENT if the device is not found.
+ *
+ */
+int arp_clear_device_req(async_sess_t *sess, device_id_t device_id)
+{
+	async_exch_t *exch = async_exchange_begin(sess);
+	int rc = async_req_1_0(exch, NET_ARP_CLEAR_DEVICE,
+	    (sysarg_t) device_id);
+	async_exchange_end(exch);
+	
+	return rc;
+}
+
+/** Register new device and the requesting protocol service.
+ *
+ * Connect to the network interface layer service.
+ * Determine the device broadcast address, its address lengths and packet size.
+ *
+ * @param[in] sess      ARP module session.
+ * @param[in] device_id New device identifier.
+ * @param[in] protocol  Requesting protocol service.
+ * @param[in] netif     Underlying device network interface layer service.
+ * @param[in] address   Local requesting protocol address of the device.
+ *
+ * @return EOK on success.
+ * @return EEXIST if the device is already used.
+ * @return ENOMEM if there is not enough memory left.
+ * @return ENOENT if the network interface service is not known.
+ * @return EREFUSED if the network interface service is not
+ *         responding.
+ * @return Other error codes as defined for the
+ *         nil_packet_get_size() function.
+ * @return Other error codes as defined for the nil_get_addr()
+ *         function.
+ * @return Other error codes as defined for the
+ *         nil_get_broadcast_addr() function.
+ *
+ */
+int arp_device_req(async_sess_t *sess, device_id_t device_id,
+    services_t protocol, services_t netif, measured_string_t *address)
+{
+	async_exch_t *exch = async_exchange_begin(sess);
+	aid_t message_id = async_send_3(exch, NET_ARP_DEVICE,
+	    (sysarg_t) device_id, protocol, netif, NULL);
+	measured_strings_send(exch, address, 1);
+	async_exchange_end(exch);
+	
+	sysarg_t result;
 	async_wait_for(message_id, &result);
 
@@ -96,76 +158,28 @@
 }
 
-/** Clears the device cache.
+/** Translate the given protocol address to the network interface address.
  *
- * @param[in] arp_phone	The ARP module phone used for (semi)remote calls.
- * @param[in] device_id	The device identifier.
- * @return		EOK on success.
- * @return		ENOENT if the device is not found.
+ * Broadcast the ARP request if the mapping is not found.
+ * Allocate and returns the needed memory block as the data parameter.
+ *
+ * @param[in]  sess        ARP module session.
+ * @param[in]  device_id   Device identifier.
+ * @param[in]  protocol    Requesting protocol service.
+ * @param[in]  address     Local requesting protocol address.
+ * @param[out] translation Translation of the local protocol address.
+ * @param[out] data        Allocated raw translation data container.
+ *
+ * @return EOK on success.
+ * @return EINVAL if the address parameter is NULL.
+ * @return EBADMEM if the translation or the data parameters are
+ *         NULL.
+ * @return ENOENT if the mapping is not found.
+ *
  */
-int arp_clear_device_req(int arp_phone, device_id_t device_id)
+int arp_translate_req(async_sess_t *sess, device_id_t device_id,
+    services_t protocol, measured_string_t *address,
+    measured_string_t **translation, uint8_t **data)
 {
-	return (int) async_obsolete_req_1_0(arp_phone, NET_ARP_CLEAR_DEVICE,
-	    (sysarg_t) device_id);
-}
-
-/** 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.
- * @return		EOK on success.
- * @return		EEXIST if the device is already used.
- * @return		ENOMEM if there is not enough memory left.
- * @return		ENOENT if the network interface service is not known.
- * @return		EREFUSED if the network interface service is not
- *			responding.
- * @return		Other error codes as defined for the
- *			nil_packet_get_size() function.
- * @return		Other error codes as defined for the nil_get_addr()
- *			function.
- * @return		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_t *address)
-{
-	aid_t message_id;
-	sysarg_t result;
-
-	message_id = async_obsolete_send_3(arp_phone, NET_ARP_DEVICE,
-	    (sysarg_t) device_id, protocol, netif, NULL);
-	measured_strings_send(arp_phone, address, 1);
-	async_wait_for(message_id, &result);
-
-	return (int) result;
-}
-
-/** 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.
- * @return		EOK on success.
- * @return		EINVAL if the address parameter is NULL.
- * @return		EBADMEM if the translation or the data parameters are
- *			NULL.
- * @return		ENOENT if the mapping is not found.
- */
-int
-arp_translate_req(int arp_phone, device_id_t device_id, services_t protocol,
-    measured_string_t *address, measured_string_t **translation, uint8_t **data)
-{
-	return generic_translate_req(arp_phone, NET_ARP_TRANSLATE, device_id,
+	return generic_translate_req(sess, NET_ARP_TRANSLATE, device_id,
 	    protocol, address, 1, translation, data);
 }
Index: uspace/lib/net/il/il_remote.c
===================================================================
--- uspace/lib/net/il/il_remote.c	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/lib/net/il/il_remote.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -39,8 +39,6 @@
 #include <generic.h>
 #include <packet_client.h>
-
 #include <ipc/services.h>
 #include <ipc/il.h>
-
 #include <net/device.h>
 #include <net/packet.h>
@@ -48,9 +46,8 @@
 /** Notify the internetwork layer modules about the device state change.
  *
- * @param[in] il_phone  The internetwork layer module phone used for
- *                      (semi)remote calls.
- * @param[in] device_id The device identifier.
- * @param[in] state     The new device state.
- * @param[in] target    The target internetwork module service to be
+ * @param[in] sess      Internetwork layer module session.
+ * @param[in] device_id Device identifier.
+ * @param[in] state     New device state.
+ * @param[in] target    Target internetwork module service to be
  *                      delivered to.
  *
@@ -58,8 +55,8 @@
  *
  */
-int il_device_state_msg(int il_phone, device_id_t device_id,
+int il_device_state_msg(async_sess_t *sess, device_id_t device_id,
     device_state_t state, services_t target)
 {
-	return generic_device_state_msg_remote(il_phone, NET_IL_DEVICE_STATE,
+	return generic_device_state_msg_remote(sess, NET_IL_DEVICE_STATE,
 	    device_id, state, target);
 }
@@ -67,9 +64,8 @@
 /** Notify the internetwork layer modules about the received packet/s.
  *
- * @param[in] il_phone  The internetwork layer module phone used for
- *                      (semi)remote calls.
- * @param[in] device_id The device identifier.
- * @param[in] packet    The received packet or the received packet queue.
- * @param[in] target    The target internetwork module service to be
+ * @param[in] sess      Internetwork layer module session.
+ * @param[in] device_id Device identifier.
+ * @param[in] packet    Received packet or the received packet queue.
+ * @param[in] target    Target internetwork module service to be
  *                      delivered to.
  *
@@ -77,8 +73,8 @@
  *
  */
-int il_received_msg(int il_phone, device_id_t device_id, packet_t *packet,
+int il_received_msg(async_sess_t *sess, device_id_t device_id, packet_t *packet,
     services_t target)
 {
-	return generic_received_msg_remote(il_phone, NET_IL_RECEIVED, device_id,
+	return generic_received_msg_remote(sess, NET_IL_RECEIVED, device_id,
 	    packet_get_id(packet), target, 0);
 }
@@ -86,9 +82,8 @@
 /** Notify the internetwork layer modules about the mtu change.
  *
- * @param[in] il_phone  The internetwork layer module phone used for
- *                      (semi)remote calls.
- * @param[in] device_id The device identifier.
- * @param[in] mtu       The new mtu value.
- * @param[in] target    The target internetwork module service to be
+ * @param[in] sess      Internetwork layer module session.
+ * @param[in] device_id Device identifier.
+ * @param[in] mtu       New MTU value.
+ * @param[in] target    Target internetwork module service to be
  *                      delivered to.
  *
@@ -96,9 +91,9 @@
  *
  */
-int il_mtu_changed_msg(int il_phone, device_id_t device_id, size_t mtu,
+int il_mtu_changed_msg(async_sess_t *sess, device_id_t device_id, size_t mtu,
     services_t target)
 {
-	return generic_device_state_msg_remote(il_phone, NET_IL_MTU_CHANGED,
-	    device_id, (int) mtu, target);
+	return generic_device_state_msg_remote(sess, NET_IL_MTU_CHANGED,
+	    device_id, mtu, target);
 }
 
Index: uspace/lib/net/il/il_skel.c
===================================================================
--- uspace/lib/net/il/il_skel.c	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/lib/net/il/il_skel.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -38,10 +38,8 @@
 #include <bool.h>
 #include <errno.h>
+#include <ns.h>
 #include <il_skel.h>
 #include <net_interface.h>
 #include <net/modules.h>
-
-// FIXME: remove this header
-#include <kernel/ipc/ipc_methods.h>
 
 /** Default thread for new connections.
@@ -99,14 +97,12 @@
  * @return Other error codes as defined for the il_initialize()
  *         function.
- * @return Other error codes as defined for the REGISTER_ME() macro
- *         function.
  *
  */
-int il_module_start(int service)
+int il_module_start(sysarg_t service)
 {
 	async_set_client_connection(il_client_connection);
-	int net_phone = net_connect_module();
-	if (net_phone < 0)
-		return net_phone;
+	async_sess_t *sess = net_connect_module();
+	if (!sess)
+		return ENOENT;
 	
 	int rc = pm_init();
@@ -114,9 +110,9 @@
 		return rc;
 	
-	rc = il_initialize(net_phone);
+	rc = il_initialize(sess);
 	if (rc != EOK)
 		goto out;
 	
-	rc = async_connect_to_me(PHONE_NS, service, 0, 0, NULL, NULL);
+	rc = service_register(service);
 	if (rc != EOK)
 		goto out;
Index: uspace/lib/net/il/ip_remote.c
===================================================================
--- uspace/lib/net/il/ip_remote.c	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/lib/net/il/ip_remote.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -44,9 +44,7 @@
 #include <packet_client.h>
 #include <generic.h>
-#include <async_obsolete.h>
 #include <ipc/services.h>
 #include <ipc/il.h>
 #include <ipc/ip.h>
-
 #include <net/modules.h>
 #include <net/device.h>
@@ -57,44 +55,50 @@
  * The target network is routed using this device.
  *
- * @param[in] ip_phone	The IP module phone used for (semi)remote calls.
- * @param[in] device_id	The device identifier.
- * @param[in] address	The target network address.
- * @param[in] netmask	The target network mask.
- * @param[in] gateway	The target network gateway. Not used if zero.
- */
-int ip_add_route_req_remote(int ip_phone, device_id_t device_id,
+ * @param[in] sess      IP module sessions.
+ * @param[in] device_id Device identifier.
+ * @param[in] address   Target network address.
+ * @param[in] netmask   Target network mask.
+ * @param[in] gateway   Target network gateway. Not used if zero.
+ *
+ */
+int ip_add_route_req_remote(async_sess_t *sess, device_id_t device_id,
     in_addr_t address, in_addr_t netmask, in_addr_t gateway)
 {
-	return (int) async_obsolete_req_4_0(ip_phone, NET_IP_ADD_ROUTE,
+	async_exch_t *exch = async_exchange_begin(sess);
+	int rc = async_req_4_0(exch, NET_IP_ADD_ROUTE,
 	    (sysarg_t) device_id, (sysarg_t) gateway.s_addr,
 	    (sysarg_t) address.s_addr, (sysarg_t) netmask.s_addr);
-}
-
-/** Creates bidirectional connection with the ip module service and registers
+	async_exchange_end(exch);
+	
+	return rc;
+}
+
+/** Create bidirectional connection with the ip module service and register
  * the message receiver.
  *
- * @param[in] service	The IP module service.
- * @param[in] protocol	The transport layer protocol.
- * @param[in] me	The requesting module service.
- * @param[in] receiver	The message receiver. Used for remote connection.
- * @return		The phone of the needed service.
- * @return		EOK on success.
- * @return		Other error codes as defined for the bind_service()
- *			function.
- */
-int ip_bind_service(services_t service, int protocol, services_t me,
+ * @param[in] service  IP module service.
+ * @param[in] protocol Transport layer protocol.
+ * @param[in] me       Rquesting module service.
+ * @param[in] receiver Message receiver. Used for remote connection.
+ *
+ * @return Session to the needed service.
+ * @return NULL on failure.
+ *
+ */
+async_sess_t *ip_bind_service(services_t service, int protocol, services_t me,
     async_client_conn_t receiver)
 {
-	return (int) bind_service(service, (sysarg_t) protocol, me, service,
+	return bind_service(service, (sysarg_t) protocol, me, service,
 	    receiver);
 }
 
-/** Connects to the IP module.
- *
- * @param service	The IP module service. Ignored parameter.
- * @return		The IP module phone on success.
- */
-int ip_connect_module(services_t service)
-{
+/** Connect to the IP module.
+ *
+ * @return The IP module session.
+ *
+ */
+async_sess_t *ip_connect_module(services_t service)
+{
+	// FIXME: Get rid of the useless argument
 	return connect_to_service(SERVICE_IP);
 }
@@ -105,21 +109,22 @@
  * If the device uses ARP registers also the new ARP device.
  *
- * @param[in] ip_phone	The IP module phone used for (semi)remote calls.
- * @param[in] device_id	The new device identifier.
- * @param[in] netif	The underlying device network interface layer service.
- * @return		EOK on success.
- * @return		ENOMEM if there is not enough memory left.
- * @return		EINVAL if the device configuration is invalid.
- * @return		ENOTSUP if the device uses IPv6.
- * @return		ENOTSUP if the device uses DHCP.
- * @return		Other error codes as defined for the
- *			net_get_device_conf_req() function.
- * @return		Other error codes as defined for the arp_device_req()
- *			function.
- */
-int ip_device_req_remote(int ip_phone, device_id_t device_id,
+ * @param[in] sess      IP module session.
+ * @param[in] device_id New device identifier.
+ *
+ * @return EOK on success.
+ * @return ENOMEM if there is not enough memory left.
+ * @return EINVAL if the device configuration is invalid.
+ * @return ENOTSUP if the device uses IPv6.
+ * @return ENOTSUP if the device uses DHCP.
+ * @return Other error codes as defined for the
+ *         net_get_device_conf_req() function.
+ * @return Other error codes as defined for the arp_device_req()
+ *         function.
+ *
+ */
+int ip_device_req_remote(async_sess_t *sess, device_id_t device_id,
     services_t service)
 {
-	return generic_device_req_remote(ip_phone, NET_IP_DEVICE, device_id, 0,
+	return generic_device_req_remote(sess, NET_IP_DEVICE, device_id, 0,
 	    service);
 }
@@ -128,35 +133,37 @@
  * destination address.
  *
- * @param[in] ip_phone	The IP module phone used for (semi)remote calls.
- * @param[in] protocol	The transport protocol.
- * @param[in] destination The destination address.
- * @param[in] addrlen	The destination address length.
- * @param[out] device_id The device identifier.
- * @param[out] header	The constructed IP pseudo header.
- * @param[out] headerlen The IP pseudo header length.
- *
- */
-int ip_get_route_req_remote(int ip_phone, ip_protocol_t protocol,
+ * @param[in] sess        IP module session.
+ * @param[in] protocol    Transport protocol.
+ * @param[in] destination Destination address.
+ * @param[in] addrlen     Destination address length.
+ * @param[out] device_id  Device identifier.
+ * @param[out] header     Constructed IP pseudo header.
+ * @param[out] headerlen  IP pseudo header length.
+ *
+ */
+int ip_get_route_req_remote(async_sess_t *sess, ip_protocol_t protocol,
     const struct sockaddr *destination, socklen_t addrlen,
     device_id_t *device_id, void **header, size_t *headerlen)
 {
-	if (!destination || (addrlen == 0))
+	if ((!destination) || (addrlen == 0))
 		return EINVAL;
 	
-	if (!device_id || !header || !headerlen)
+	if ((!device_id) || (!header) || (!headerlen))
 		return EBADMEM;
 	
 	*header = NULL;
 	
+	async_exch_t *exch = async_exchange_begin(sess);
+	
 	ipc_call_t answer;
-	aid_t message_id = async_obsolete_send_1(ip_phone, NET_IP_GET_ROUTE,
+	aid_t message_id = async_send_1(exch, NET_IP_GET_ROUTE,
 	    (sysarg_t) protocol, &answer);
 	
-	if ((async_obsolete_data_write_start(ip_phone, destination, addrlen) == EOK) &&
-	    (async_obsolete_data_read_start(ip_phone, headerlen,
-	    sizeof(*headerlen)) == EOK) && (*headerlen > 0)) {
+	if ((async_data_write_start(exch, destination, addrlen) == EOK) &&
+	    (async_data_read_start(exch, headerlen, sizeof(*headerlen)) == EOK) &&
+	    (*headerlen > 0)) {
 		*header = malloc(*headerlen);
 		if (*header) {
-			if (async_obsolete_data_read_start(ip_phone, *header,
+			if (async_data_read_start(exch, *header,
 			    *headerlen) != EOK)
 				free(*header);
@@ -164,4 +171,6 @@
 	}
 	
+	async_exchange_end(exch);
+	
 	sysarg_t result;
 	async_wait_for(message_id, &result);
@@ -177,16 +186,18 @@
 /** Return the device packet dimension for sending.
  *
- * @param[in] ip_phone	The IP module phone used for (semi)remote calls.
- * @param[in] device_id	The device identifier.
- * @param[out] packet_dimension The packet dimension.
- * @return		EOK on success.
- * @return		ENOENT if there is no such device.
- * @return		Other error codes as defined for the
- *			generic_packet_size_req_remote() function.
- */
-int ip_packet_size_req_remote(int ip_phone, device_id_t device_id,
+ * @param[in] sess              IP module session.
+ * @param[in] device_id         Device identifier.
+ * @param[out] packet_dimension Packet dimension.
+ *
+ * @return EOK on success.
+ * @return ENOENT if there is no such device.
+ * @return Other error codes as defined for the
+ *         generic_packet_size_req_remote() function.
+ *
+ */
+int ip_packet_size_req_remote(async_sess_t *sess, device_id_t device_id,
     packet_dimension_t *packet_dimension)
 {
-	return generic_packet_size_req_remote(ip_phone, NET_IP_PACKET_SPACE,
+	return generic_packet_size_req_remote(sess, NET_IP_PACKET_SPACE,
 	    device_id, packet_dimension);
 }
@@ -194,17 +205,19 @@
 /** Notify the IP module about the received error notification packet.
  *
- * @param[in] ip_phone	The IP module phone used for (semi)remote calls.
- * @param[in] device_id	The device identifier.
- * @param[in] packet	The received packet or the received packet queue.
- * @param[in] target	The target internetwork module service to be
- *			delivered to.
- * @param[in] error	The packet error reporting service. Prefixes the
- *			received packet.
- * @return		EOK on success.
- */
-int ip_received_error_msg_remote(int ip_phone, device_id_t device_id,
+ * @param[in] sess      IP module session.
+ * @param[in] device_id Device identifier.
+ * @param[in] packet    Received packet or the received packet queue.
+ * @param[in] target    Target internetwork module service to be
+ *                      delivered to.
+ * @param[in] error     Packet error reporting service. Prefixes the
+ *                      received packet.
+ *
+ * @return EOK on success.
+ *
+ */
+int ip_received_error_msg_remote(async_sess_t *sess, device_id_t device_id,
     packet_t *packet, services_t target, services_t error)
 {
-	return generic_received_msg_remote(ip_phone, NET_IP_RECEIVED_ERROR,
+	return generic_received_msg_remote(sess, NET_IP_RECEIVED_ERROR,
 	    device_id, packet_get_id(packet), target, error);
 }
@@ -214,19 +227,21 @@
  * The packets may get fragmented if needed.
  *
- * @param[in] ip_phone	The IP module phone used for (semi)remote calls.
- * @param[in] device_id	The device identifier.
- * @param[in] packet	The packet fragments as a packet queue. All the
- *			packets have to have the same destination address.
- * @param[in] sender	The sending module service.
- * @param[in] error	The packet error reporting service. Prefixes the
- *			received packet.
- * @return		EOK on success.
- * @return		Other error codes as defined for the generic_send_msg()
- *			function.
- */
-int ip_send_msg_remote(int ip_phone, device_id_t device_id, packet_t *packet,
-    services_t sender, services_t error)
-{
-	return generic_send_msg_remote(ip_phone, NET_IP_SEND, device_id,
+ * @param[in] sess      IP module session.
+ * @param[in] device_id Device identifier.
+ * @param[in] packet    Packet fragments as a packet queue. All the
+ *                      packets have to have the same destination address.
+ * @param[in] sender    Sending module service.
+ * @param[in] error     Packet error reporting service. Prefixes the
+ *                      received packet.
+ *
+ * @return EOK on success.
+ * @return Other error codes as defined for the generic_send_msg()
+ *         function.
+ *
+ */
+int ip_send_msg_remote(async_sess_t *sess, device_id_t device_id,
+    packet_t *packet, services_t sender, services_t error)
+{
+	return generic_send_msg_remote(sess, NET_IP_SEND, device_id,
 	    packet_get_id(packet), sender, error);
 }
@@ -236,13 +251,18 @@
  * This gateway is used if no other route is found.
  *
- * @param[in] ip_phone	The IP module phone used for (semi)remote calls.
- * @param[in] device_id	The device identifier.
- * @param[in] gateway	The default gateway.
- */
-int ip_set_gateway_req_remote(int ip_phone, device_id_t device_id,
+ * @param[in] sess      IP module session.
+ * @param[in] device_id Device identifier.
+ * @param[in] gateway   Default gateway.
+ *
+ */
+int ip_set_gateway_req_remote(async_sess_t *sess, device_id_t device_id,
     in_addr_t gateway)
 {
-	return (int) async_obsolete_req_2_0(ip_phone, NET_IP_SET_GATEWAY,
+	async_exch_t *exch = async_exchange_begin(sess);
+	int rc = async_req_2_0(exch, NET_IP_SET_GATEWAY,
 	    (sysarg_t) device_id, (sysarg_t) gateway.s_addr);
+	async_exchange_end(exch);
+	
+	return rc;
 }
 
Index: uspace/lib/net/include/adt/module_map.h
===================================================================
--- uspace/lib/net/include/adt/module_map.h	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/lib/net/include/adt/module_map.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -39,5 +39,5 @@
 
 #include <task.h>
-#include <ipc/services.h>
+#include <async.h>
 #include <net/modules.h>
 #include <adt/generic_char_map.h>
@@ -60,6 +60,6 @@
 	/** Module service identifier. */
 	services_t service;
-	/** Module phone if running and connected. */
-	int phone;
+	/** Module session if running and connected. */
+	async_sess_t *sess;
 	/** Usage counter. */
 	int usage;
Index: uspace/lib/net/include/arp_interface.h
===================================================================
--- uspace/lib/net/include/arp_interface.h	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/lib/net/include/arp_interface.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -36,9 +36,8 @@
 #include <adt/measured_strings.h>
 #include <task.h>
-
 #include <ipc/services.h>
-
 #include <net/device.h>
 #include <net/socket.h>
+#include <async.h>
 
 /** @name ARP module interface
@@ -47,13 +46,13 @@
 /*@{*/
 
-extern int arp_device_req(int, device_id_t, services_t, services_t,
+extern int arp_device_req(async_sess_t *, device_id_t, services_t, services_t,
     measured_string_t *);
-extern int arp_translate_req(int, device_id_t, services_t, measured_string_t *,
-    measured_string_t **, uint8_t **);
-extern int arp_clear_device_req(int, device_id_t);
-extern int arp_clear_address_req(int, device_id_t, services_t,
+extern int arp_translate_req(async_sess_t *, device_id_t, services_t,
+    measured_string_t *, measured_string_t **, uint8_t **);
+extern int arp_clear_device_req(async_sess_t *, device_id_t);
+extern int arp_clear_address_req(async_sess_t *, device_id_t, services_t,
     measured_string_t *);
-extern int arp_clean_cache_req(int);
-extern int arp_connect_module(services_t);
+extern int arp_clean_cache_req(async_sess_t *);
+extern async_sess_t *arp_connect_module(services_t);
 
 /*@}*/
Index: uspace/lib/net/include/generic.h
===================================================================
--- uspace/lib/net/include/generic.h	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/lib/net/include/generic.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -38,24 +38,24 @@
 #define LIBNET_GENERIC_H_
 
-#include <async.h>
 #include <ipc/services.h>
-
 #include <net/device.h>
 #include <adt/measured_strings.h>
 #include <net/packet.h>
+#include <async.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_t **,
-    uint8_t **);
-extern int generic_packet_size_req_remote(int, int, device_id_t,
+extern int generic_device_state_msg_remote(async_sess_t *, sysarg_t,
+    device_id_t, sysarg_t, services_t);
+extern int generic_device_req_remote(async_sess_t *, sysarg_t, device_id_t,
+    sysarg_t, services_t);
+extern int generic_get_addr_req(async_sess_t *, sysarg_t, device_id_t,
+    measured_string_t **, uint8_t **);
+extern int generic_packet_size_req_remote(async_sess_t *, sysarg_t, device_id_t,
     packet_dimension_t *);
-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_t *, size_t, measured_string_t **, uint8_t **);
+extern int generic_received_msg_remote(async_sess_t *, sysarg_t, device_id_t,
+    packet_id_t, services_t, services_t);
+extern int generic_send_msg_remote(async_sess_t *, sysarg_t, device_id_t,
+    packet_id_t, services_t, services_t);
+extern int generic_translate_req(async_sess_t *, sysarg_t, device_id_t,
+    services_t, measured_string_t *, size_t, measured_string_t **, uint8_t **);
 
 #endif
Index: uspace/lib/net/include/icmp_remote.h
===================================================================
--- uspace/lib/net/include/icmp_remote.h	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/lib/net/include/icmp_remote.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -36,5 +36,4 @@
 #include <net/socket_codes.h>
 #include <sys/types.h>
-
 #include <net/device.h>
 #include <adt/measured_strings.h>
@@ -44,4 +43,5 @@
 #include <net/icmp_codes.h>
 #include <net/icmp_common.h>
+#include <async.h>
 
 /** @name ICMP module interface
@@ -50,9 +50,9 @@
 /*@{*/
 
-extern int icmp_destination_unreachable_msg(int, icmp_code_t, icmp_param_t,
-    packet_t *);
-extern int icmp_source_quench_msg(int, packet_t *);
-extern int icmp_time_exceeded_msg(int, icmp_code_t, packet_t *);
-extern int icmp_parameter_problem_msg(int, icmp_code_t, icmp_param_t,
+extern int icmp_destination_unreachable_msg(async_sess_t *, icmp_code_t,
+    icmp_param_t, packet_t *);
+extern int icmp_source_quench_msg(async_sess_t *, packet_t *);
+extern int icmp_time_exceeded_msg(async_sess_t *, icmp_code_t, packet_t *);
+extern int icmp_parameter_problem_msg(async_sess_t *, icmp_code_t, icmp_param_t,
     packet_t *);
 
Index: uspace/lib/net/include/il_remote.h
===================================================================
--- uspace/lib/net/include/il_remote.h	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/lib/net/include/il_remote.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -41,7 +41,7 @@
 #include <ipc/services.h>
 #include <sys/types.h>
-
 #include <net/device.h>
 #include <net/packet.h>
+#include <async.h>
 
 /** @name Internetwork layer module interface
@@ -50,7 +50,8 @@
 /*@{*/
 
-extern int il_device_state_msg(int, device_id_t, device_state_t, services_t);
-extern int il_received_msg(int, device_id_t, packet_t *, services_t);
-extern int il_mtu_changed_msg(int, device_id_t, size_t, services_t);
+extern int il_device_state_msg(async_sess_t *, device_id_t, device_state_t,
+    services_t);
+extern int il_received_msg(async_sess_t *, device_id_t, packet_t *, services_t);
+extern int il_mtu_changed_msg(async_sess_t *, device_id_t, size_t, services_t);
 
 /*@}*/
Index: uspace/lib/net/include/il_skel.h
===================================================================
--- uspace/lib/net/include/il_skel.h	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/lib/net/include/il_skel.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -39,11 +39,9 @@
  */
 
-#include <async.h>
-#include <fibril_synch.h>
 #include <ipc/services.h>
-
 #include <adt/measured_strings.h>
 #include <net/device.h>
 #include <net/packet.h>
+#include <async.h>
 
 /** Module initialization.
@@ -51,5 +49,5 @@
  * This has to be implemented in user code.
  *
- * @param[in] net_phone Networking module phone.
+ * @param[in] sess Networking module session.
  *
  * @return EOK on success.
@@ -58,5 +56,5 @@
  *
  */
-extern int il_initialize(int net_phone);
+extern int il_initialize(async_sess_t *sess);
 
 /** Process the internetwork layer module message.
@@ -76,5 +74,5 @@
     ipc_call_t *answer, size_t *answer_count);
 
-extern int il_module_start(int);
+extern int il_module_start(sysarg_t);
 
 #endif
Index: uspace/lib/net/include/ip_interface.h
===================================================================
--- uspace/lib/net/include/ip_interface.h	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/lib/net/include/ip_interface.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -35,14 +35,11 @@
 
 #include <net/socket_codes.h>
-#include <async.h>
 #include <ipc/services.h>
-
 #include <net/device.h>
 #include <net/packet.h>
-
 #include <net/in.h>
 #include <net/ip_codes.h>
-
 #include <ip_remote.h>
+#include <async.h>
 
 #define ip_received_error_msg  ip_received_error_msg_remote
@@ -61,18 +58,20 @@
 /** The transport layer notification function type definition.
  *
- * Notifies the transport layer modules about the received packet/s.
+ * Notify the transport layer modules about the received packet/s.
  *
- * @param[in] device_id	The device identifier.
- * @param[in] packet	The received packet or the received packet queue.
- * @param[in] receiver	The receiving module service.
- * @param[in] error	The packet error reporting service. Prefixes the
- *			received packet.
- * @return		EOK on success.
+ * @param[in] device_id Device identifier.
+ * @param[in] packet    Received packet or the received packet queue.
+ * @param[in] receiver  Receiving module service.
+ * @param[in] error     Packet error reporting service. Prefixes the
+ *                      received packet.
+ *
+ * @return EOK on success.
+ *
  */
 typedef int (*tl_received_msg_t)(device_id_t device_id, packet_t *packet,
     services_t receiver, services_t error);
 
-extern int ip_bind_service(services_t, int, services_t, async_client_conn_t);
-extern int ip_connect_module(services_t);
+extern async_sess_t *ip_bind_service(services_t, int, services_t, async_client_conn_t);
+extern async_sess_t *ip_connect_module(services_t);
 
 /*@}*/
Index: uspace/lib/net/include/ip_remote.h
===================================================================
--- uspace/lib/net/include/ip_remote.h	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/lib/net/include/ip_remote.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -35,5 +35,4 @@
 
 #include <ipc/services.h>
-
 #include <net/ip_codes.h>
 #include <net/inet.h>
@@ -42,16 +41,18 @@
 #include <net/device.h>
 #include <net/socket.h>
+#include <async.h>
 
-extern int ip_set_gateway_req_remote(int, device_id_t, in_addr_t);
-extern int ip_packet_size_req_remote(int, device_id_t, packet_dimension_t *);
-extern int ip_received_error_msg_remote(int, device_id_t, packet_t *, services_t,
-    services_t);
-extern int ip_device_req_remote(int, device_id_t, services_t);
-extern int ip_add_route_req_remote(int, device_id_t, in_addr_t, in_addr_t,
-    in_addr_t);
-extern int ip_send_msg_remote(int, device_id_t, packet_t *, services_t,
-    services_t);
-extern int ip_get_route_req_remote(int, ip_protocol_t, const struct sockaddr *,
-    socklen_t, device_id_t *, void **, size_t *);
+extern int ip_set_gateway_req_remote(async_sess_t *, device_id_t, in_addr_t);
+extern int ip_packet_size_req_remote(async_sess_t *, device_id_t,
+    packet_dimension_t *);
+extern int ip_received_error_msg_remote(async_sess_t *, device_id_t, packet_t *,
+    services_t, services_t);
+extern int ip_device_req_remote(async_sess_t *, device_id_t, services_t);
+extern int ip_add_route_req_remote(async_sess_t *, device_id_t, in_addr_t,
+    in_addr_t, in_addr_t);
+extern int ip_send_msg_remote(async_sess_t *, device_id_t, packet_t *,
+    services_t, services_t);
+extern int ip_get_route_req_remote(async_sess_t *, ip_protocol_t,
+    const struct sockaddr *, socklen_t, device_id_t *, void **, size_t *);
 
 #endif
Index: uspace/lib/net/include/net_interface.h
===================================================================
--- uspace/lib/net/include/net_interface.h	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/lib/net/include/net_interface.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -38,4 +38,5 @@
 #include <net/device.h>
 #include <adt/measured_strings.h>
+#include <async.h>
 
 /** @name Networking module interface
@@ -44,9 +45,10 @@
 /*@{*/
 
-extern int net_get_device_conf_req(int, device_id_t, measured_string_t **,
-    size_t, uint8_t **);
-extern int net_get_conf_req(int, measured_string_t **, size_t, uint8_t **);
+extern int net_get_device_conf_req(async_sess_t *, device_id_t,
+    measured_string_t **, size_t, uint8_t **);
+extern int net_get_conf_req(async_sess_t *, measured_string_t **, size_t,
+    uint8_t **);
 extern void net_free_settings(measured_string_t *, uint8_t *);
-extern int net_connect_module(void);
+extern async_sess_t *net_connect_module(void);
 
 /*@}*/
Index: uspace/lib/net/include/netif_remote.h
===================================================================
--- uspace/lib/net/include/netif_remote.h	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/lib/net/include/netif_remote.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -34,19 +34,18 @@
 #define LIBNET_NETIF_REMOTE_H_
 
-#include <async.h>
 #include <ipc/services.h>
 #include <adt/measured_strings.h>
-
 #include <net/device.h>
 #include <net/packet.h>
+#include <async.h>
 
-extern int netif_get_addr_req(int, device_id_t, measured_string_t **,
+extern int netif_get_addr_req(async_sess_t *, device_id_t, measured_string_t **,
     uint8_t **);
-extern int netif_probe_req(int, device_id_t, int, void *);
-extern int netif_send_msg(int, device_id_t, packet_t *, services_t);
-extern int netif_start_req(int, device_id_t);
-extern int netif_stop_req(int, device_id_t);
-extern int netif_stats_req(int, device_id_t, device_stats_t *);
-extern int netif_bind_service(services_t, device_id_t, services_t,
+extern int netif_probe_req(async_sess_t *, device_id_t, int, void *);
+extern int netif_send_msg(async_sess_t *, device_id_t, packet_t *, services_t);
+extern int netif_start_req(async_sess_t *, device_id_t);
+extern int netif_stop_req(async_sess_t *, device_id_t);
+extern int netif_stats_req(async_sess_t *, device_id_t, device_stats_t *);
+extern async_sess_t *netif_bind_service(services_t, device_id_t, services_t,
     async_client_conn_t);
 
Index: uspace/lib/net/include/netif_skel.h
===================================================================
--- uspace/lib/net/include/netif_skel.h	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/lib/net/include/netif_skel.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -39,18 +39,16 @@
 #define NET_NETIF_SKEL_H_
 
-#include <async.h>
 #include <fibril_synch.h>
 #include <ipc/services.h>
-
 #include <adt/measured_strings.h>
 #include <net/device.h>
 #include <net/packet.h>
+#include <async.h>
 
 /** Network interface device specific data. */
 typedef struct {
-	device_id_t device_id;  /**< Device identifier. */
-	int nil_phone;          /**< Receiving network interface layer phone. */
-	device_state_t state;   /**< Actual device state. */
-	void *specific;         /**< Driver specific data. */
+	device_id_t device_id;   /**< Device identifier. */
+	device_state_t state;    /**< Actual device state. */
+	void *specific;          /**< Driver specific data. */
 } netif_device_t;
 
@@ -65,5 +63,6 @@
 /** Network interface module skeleton global data. */
 typedef struct {
-	int net_phone;                  /**< Networking module phone. */
+	async_sess_t *sess;             /**< Networking module session. */
+	async_sess_t *nil_sess;         /**< Network interface layer session. */
 	netif_device_map_t device_map;  /**< Device map. */
 	fibril_rwlock_t lock;           /**< Safety lock. */
@@ -127,5 +126,4 @@
  * @return Other error codes as defined for the specific module
  *         message implementation.
- 
  *
  */
Index: uspace/lib/net/include/nil_remote.h
===================================================================
--- uspace/lib/net/include/nil_remote.h	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/lib/net/include/nil_remote.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -38,29 +38,31 @@
 #include <net/packet.h>
 #include <generic.h>
+#include <async.h>
 
 #define nil_bind_service(service, device_id, me, receiver) \
 	bind_service(service, device_id, me, 0, receiver)
 
-#define nil_packet_size_req(nil_phone, device_id, packet_dimension) \
-	generic_packet_size_req_remote(nil_phone, NET_NIL_PACKET_SPACE, \
+#define nil_packet_size_req(sess, device_id, packet_dimension) \
+	generic_packet_size_req_remote(sess, NET_NIL_PACKET_SPACE, \
 	    device_id, packet_dimension)
 
-#define nil_get_addr_req(nil_phone, device_id, address, data) \
-	generic_get_addr_req(nil_phone, NET_NIL_ADDR, device_id, address, data)
+#define nil_get_addr_req(sess, device_id, address, data) \
+	generic_get_addr_req(sess, NET_NIL_ADDR, device_id, address, data)
 
-#define nil_get_broadcast_addr_req(nil_phone, device_id, address, data) \
-	generic_get_addr_req(nil_phone, NET_NIL_BROADCAST_ADDR, device_id, \
+#define nil_get_broadcast_addr_req(sess, device_id, address, data) \
+	generic_get_addr_req(sess, NET_NIL_BROADCAST_ADDR, device_id, \
 	    address, data)
 
-#define nil_send_msg(nil_phone, device_id, packet, sender) \
-	generic_send_msg_remote(nil_phone, NET_NIL_SEND, device_id, \
+#define nil_send_msg(sess, device_id, packet, sender) \
+	generic_send_msg_remote(sess, NET_NIL_SEND, device_id, \
 	    packet_get_id(packet), sender, 0)
 
-#define nil_device_req(nil_phone, device_id, mtu, netif_service) \
-	generic_device_req_remote(nil_phone, NET_NIL_DEVICE, device_id, mtu, \
+#define nil_device_req(sess, device_id, mtu, netif_service) \
+	generic_device_req_remote(sess, NET_NIL_DEVICE, device_id, mtu, \
 	    netif_service)
 
-extern int nil_device_state_msg(int, device_id_t, int);
-extern int nil_received_msg(int, device_id_t, packet_t *, services_t);
+extern int nil_device_state_msg(async_sess_t *, device_id_t, sysarg_t);
+extern int nil_received_msg(async_sess_t *, device_id_t, packet_t *,
+    services_t);
 
 #endif
Index: uspace/lib/net/include/nil_skel.h
===================================================================
--- uspace/lib/net/include/nil_skel.h	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/lib/net/include/nil_skel.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -39,11 +39,9 @@
 #define LIBNET_NIL_SKEL_H_
 
-#include <async.h>
-#include <fibril_synch.h>
 #include <ipc/services.h>
-
 #include <adt/measured_strings.h>
 #include <net/device.h>
 #include <net/packet.h>
+#include <async.h>
 
 /** Module initialization.
@@ -51,5 +49,5 @@
  * This has to be implemented in user code.
  *
- * @param[in] net_phone Networking module phone.
+ * @param[in] sess Networking module session.
  *
  * @return EOK on success.
@@ -58,5 +56,5 @@
  *
  */
-extern int nil_initialize(int net_phone);
+extern int nil_initialize(async_sess_t *sess);
 
 /** Notify the network interface layer about the device state change.
@@ -64,5 +62,4 @@
  * This has to be implemented in user code.
  *
- * @param[in] nil_phone Network interface layer phone.
  * @param[in] device_id Device identifier.
  * @param[in] state     New device state.
@@ -73,5 +70,5 @@
  *
  */
-extern int nil_device_state_msg_local(int, device_id_t, int);
+extern int nil_device_state_msg_local(device_id_t device_id, sysarg_t state);
 
 /** Pass the packet queue to the network interface layer.
@@ -82,5 +79,4 @@
  * This has to be implemented in user code.
  *
- * @param[in] nil_phone Network interface layer phone.
  * @param[in] device_id Source device identifier.
  * @param[in] packet    Received packet or the received packet queue.
@@ -92,5 +88,6 @@
  *
  */
-extern int nil_received_msg_local(int, device_id_t, packet_t *, services_t);
+extern int nil_received_msg_local(device_id_t device_id, packet_t *packet,
+    services_t target);
 
 /** Message processing function.
@@ -98,5 +95,4 @@
  * This has to be implemented in user code.
  *
- * @param[in]  name   Module name.
  * @param[in]  callid Message identifier.
  * @param[in]  call   Message parameters.
@@ -112,8 +108,8 @@
  *
  */
-extern int nil_module_message(ipc_callid_t, ipc_call_t *, ipc_call_t *,
-    size_t *);
+extern int nil_module_message(ipc_callid_t callid, ipc_call_t *call,
+    ipc_call_t *answer, size_t *count);
 
-extern int nil_module_start(int);
+extern int nil_module_start(sysarg_t);
 
 #endif
Index: uspace/lib/net/include/packet_client.h
===================================================================
--- uspace/lib/net/include/packet_client.h	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/lib/net/include/packet_client.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -49,4 +49,5 @@
 
 #include <net/packet.h>
+#include <async.h>
 
 /** @name Packet client interface */
@@ -108,5 +109,5 @@
 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, packet_t *);
+extern packet_t *packet_get_copy(async_sess_t *, packet_t *);
 
 /*@}*/
Index: uspace/lib/net/include/packet_remote.h
===================================================================
--- uspace/lib/net/include/packet_remote.h	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/lib/net/include/packet_remote.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -36,9 +36,11 @@
 #include <net/packet.h>
 #include <sys/types.h>
+#include <async.h>
 
-extern int packet_translate_remote(int, packet_t **, packet_id_t);
-extern packet_t *packet_get_4_remote(int, size_t, size_t, size_t, size_t);
-extern packet_t *packet_get_1_remote(int, size_t);
-extern void pq_release_remote(int, packet_id_t);
+extern int packet_translate_remote(async_sess_t *, packet_t **, packet_id_t);
+extern packet_t *packet_get_4_remote(async_sess_t *, size_t, size_t, size_t,
+    size_t);
+extern packet_t *packet_get_1_remote(async_sess_t *, size_t);
+extern void pq_release_remote(async_sess_t *, packet_id_t);
 
 #endif
Index: uspace/lib/net/include/socket_core.h
===================================================================
--- uspace/lib/net/include/socket_core.h	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/lib/net/include/socket_core.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -27,5 +27,5 @@
  */
 
-/** @addtogroup libnet 
+/** @addtogroup libnet
  *  @{
  */
@@ -45,19 +45,20 @@
 #include <net/device.h>
 #include <net/packet.h>
+#include <async.h>
 
 /** Initial size of the received packet queue. */
-#define SOCKET_INITIAL_RECEIVED_SIZE	4
+#define SOCKET_INITIAL_RECEIVED_SIZE  4
 
 /** Maximum size of the received packet queue. */
-#define SOCKET_MAX_RECEIVED_SIZE	0
+#define SOCKET_MAX_RECEIVED_SIZE  0
 
 /** Initial size of the sockets for acceptance queue. */
-#define SOCKET_INITIAL_ACCEPTED_SIZE	1
+#define SOCKET_INITIAL_ACCEPTED_SIZE  1
 
 /** Maximum size of the sockets for acceptance queue. */
-#define SOCKET_MAX_ACCEPTEDED_SIZE	0
+#define SOCKET_MAX_ACCEPTEDED_SIZE  0
 
 /** Listening sockets' port map key. */
-#define SOCKET_MAP_KEY_LISTENING	"L"
+#define SOCKET_MAP_KEY_LISTENING  "L"
 
 /** Type definition of the socket core.
@@ -75,6 +76,6 @@
 	/** Socket identifier. */
 	int socket_id;
-	/** Client application phone. */
-	int phone;
+	/** Client application session. */
+	async_sess_t *sess;
 	/** Bound port. */
 	int port;
@@ -108,13 +109,13 @@
 INT_MAP_DECLARE(socket_ports, socket_port_t);
 
-extern void socket_cores_release(int, socket_cores_t *, socket_ports_t *,
-    void (*)(socket_core_t *));
+extern void socket_cores_release(async_sess_t *, socket_cores_t *,
+    socket_ports_t *, void (*)(socket_core_t *));
 extern int socket_bind(socket_cores_t *, socket_ports_t *, int, void *, size_t,
     int, int, int);
 extern int socket_bind_free_port(socket_ports_t *, socket_core_t *, int, int,
     int);
-extern int socket_create(socket_cores_t *, int, void *, int *);
-extern int socket_destroy(int, int, socket_cores_t *, socket_ports_t *,
-    void (*)(socket_core_t *));
+extern int socket_create(socket_cores_t *, async_sess_t *, void *, int *);
+extern int socket_destroy(async_sess_t *, int, socket_cores_t *,
+    socket_ports_t *, void (*)(socket_core_t *));
 extern int socket_reply_packets(packet_t *, size_t *);
 extern socket_core_t *socket_port_find(socket_ports_t *, int, const uint8_t *,
Index: uspace/lib/net/include/tl_common.h
===================================================================
--- uspace/lib/net/include/tl_common.h	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/lib/net/include/tl_common.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -27,5 +27,5 @@
  */
 
-/** @addtogroup libnet 
+/** @addtogroup libnet
  * @{
  */
@@ -39,9 +39,9 @@
 
 #include <ipc/services.h>
-
 #include <net/socket_codes.h>
 #include <net/packet.h>
 #include <net/device.h>
 #include <net/inet.h>
+#include <async.h>
 
 /** Device packet dimensions.
@@ -51,5 +51,5 @@
 DEVICE_MAP_DECLARE(packet_dimensions, packet_dimension_t);
 
-extern int tl_get_ip_packet_dimension(int, packet_dimensions_t *,
+extern int tl_get_ip_packet_dimension(async_sess_t *, packet_dimensions_t *,
     device_id_t, packet_dimension_t **);
 extern int tl_get_address_port(const struct sockaddr *, int, uint16_t *);
@@ -57,6 +57,7 @@
     size_t);
 extern int tl_set_address_port(struct sockaddr *, int, uint16_t);
-extern int tl_prepare_icmp_packet(int, int, packet_t *, services_t);
-extern int tl_socket_read_packet_data(int, packet_t **, size_t,
+extern int tl_prepare_icmp_packet(async_sess_t *, async_sess_t *, packet_t *,
+    services_t);
+extern int tl_socket_read_packet_data(async_sess_t *, packet_t **, size_t,
     const packet_dimension_t *, const struct sockaddr *, socklen_t);
 
@@ -65,3 +66,2 @@
 /** @}
  */
-
Index: uspace/lib/net/include/tl_remote.h
===================================================================
--- uspace/lib/net/include/tl_remote.h	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/lib/net/include/tl_remote.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -38,12 +38,11 @@
 #define LIBNET_TL_REMOTE_H_
 
-#include <async.h>
 #include <ipc/services.h>
 #include <ipc/tl.h>
-
 #include <generic.h>
 #include <net/device.h>
 #include <net/packet.h>
 #include <packet_client.h>
+#include <async.h>
 
 /** @name Transport layer module interface
@@ -52,5 +51,5 @@
 /*@{*/
 
-extern int tl_received_msg(int, device_id_t, packet_t *, services_t,
+extern int tl_received_msg(async_sess_t *, device_id_t, packet_t *, services_t,
     services_t);
 
Index: uspace/lib/net/include/tl_skel.h
===================================================================
--- uspace/lib/net/include/tl_skel.h	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/lib/net/include/tl_skel.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -39,11 +39,10 @@
  */
 
-#include <async.h>
 #include <fibril_synch.h>
 #include <ipc/services.h>
-
 #include <adt/measured_strings.h>
 #include <net/device.h>
 #include <net/packet.h>
+#include <async.h>
 
 /** Module initialization.
@@ -51,5 +50,5 @@
  * This has to be implemented in user code.
  *
- * @param[in] net_phone Networking module phone.
+ * @param[in] sess Networking module session.
  *
  * @return EOK on success.
@@ -58,5 +57,5 @@
  *
  */
-extern int tl_initialize(int net_phone);
+extern int tl_initialize(async_sess_t *sess);
 
 /** Per-connection module initialization.
@@ -83,5 +82,5 @@
     ipc_call_t *, size_t *);
 
-extern int tl_module_start(int);
+extern int tl_module_start(sysarg_t);
 
 #endif
Index: uspace/lib/net/netif/netif_remote.c
===================================================================
--- uspace/lib/net/netif/netif_remote.c	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/lib/net/netif/netif_remote.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -38,8 +38,6 @@
 #include <packet_client.h>
 #include <generic.h>
-#include <async_obsolete.h>
 #include <ipc/services.h>
 #include <ipc/netif.h>
-
 #include <net/modules.h>
 #include <adt/measured_strings.h>
@@ -49,8 +47,8 @@
 /** Return the device local hardware address.
  *
- * @param[in]  netif_phone Network interface phone.
- * @param[in]  device_id   Device identifier.
- * @param[out] address     Device local hardware address.
- * @param[out] data        Address data.
+ * @param[in]  sess      Network interface session.
+ * @param[in]  device_id Device identifier.
+ * @param[out] address   Device local hardware address.
+ * @param[out] data      Address data.
  *
  * @return EOK on success.
@@ -61,8 +59,8 @@
  *
  */
-int netif_get_addr_req(int netif_phone, device_id_t device_id,
+int netif_get_addr_req(async_sess_t *sess, device_id_t device_id,
     measured_string_t **address, uint8_t **data)
 {
-	return generic_get_addr_req(netif_phone, NET_NETIF_GET_ADDR, device_id,
+	return generic_get_addr_req(sess, NET_NETIF_GET_ADDR, device_id,
 	    address, data);
 }
@@ -70,8 +68,8 @@
 /** Probe the existence of the device.
  *
- * @param[in] netif_phone Network interface phone.
- * @param[in] device_id   Device identifier.
- * @param[in] irq         Device interrupt number.
- * @param[in] io          Device input/output address.
+ * @param[in] sess      Network interface session.
+ * @param[in] device_id Device identifier.
+ * @param[in] irq       Device interrupt number.
+ * @param[in] io        Device input/output address.
  *
  * @return EOK on success.
@@ -80,16 +78,20 @@
  *
  */
-int netif_probe_req(int netif_phone, device_id_t device_id, int irq, void *io)
+int netif_probe_req(async_sess_t *sess, device_id_t device_id, int irq, void *io)
 {
-	return async_obsolete_req_3_0(netif_phone, NET_NETIF_PROBE, device_id, irq,
+	async_exch_t *exch = async_exchange_begin(sess);
+	int rc = async_req_3_0(exch, NET_NETIF_PROBE, device_id, (sysarg_t) irq,
 	    (sysarg_t) io);
+	async_exchange_end(exch);
+	
+	return rc;
 }
 
 /** Send the packet queue.
  *
- * @param[in] netif_phone Network interface phone.
- * @param[in] device_id   Device identifier.
- * @param[in] packet      Packet queue.
- * @param[in] sender      Sending module service.
+ * @param[in] sess      Network interface session.
+ * @param[in] device_id Device identifier.
+ * @param[in] packet    Packet queue.
+ * @param[in] sender    Sending module service.
  *
  * @return EOK on success.
@@ -98,8 +100,8 @@
  *
  */
-int netif_send_msg(int netif_phone, device_id_t device_id, packet_t *packet,
+int netif_send_msg(async_sess_t *sess, device_id_t device_id, packet_t *packet,
     services_t sender)
 {
-	return generic_send_msg_remote(netif_phone, NET_NETIF_SEND, device_id,
+	return generic_send_msg_remote(sess, NET_NETIF_SEND, device_id,
 	    packet_get_id(packet), sender, 0);
 }
@@ -107,6 +109,6 @@
 /** Start the device.
  *
- * @param[in] netif_phone Network interface phone.
- * @param[in] device_id   Device identifier.
+ * @param[in] sess      Network interface session.
+ * @param[in] device_id Device identifier.
  *
  * @return EOK on success.
@@ -117,13 +119,17 @@
  *
  */
-int netif_start_req(int netif_phone, device_id_t device_id)
+int netif_start_req(async_sess_t *sess, device_id_t device_id)
 {
-	return async_obsolete_req_1_0(netif_phone, NET_NETIF_START, device_id);
+	async_exch_t *exch = async_exchange_begin(sess);
+	int rc = async_req_1_0(exch, NET_NETIF_START, device_id);
+	async_exchange_end(exch);
+	
+	return rc;
 }
 
 /** Stop the device.
  *
- * @param[in] netif_phone Network interface phone.
- * @param[in] device_id   Device identifier.
+ * @param[in] sess      Network interface session.
+ * @param[in] device_id Device identifier.
  *
  * @return EOK on success.
@@ -134,19 +140,23 @@
  *
  */
-int netif_stop_req(int netif_phone, device_id_t device_id)
+int netif_stop_req(async_sess_t *sess, device_id_t device_id)
 {
-	return async_obsolete_req_1_0(netif_phone, NET_NETIF_STOP, device_id);
+	async_exch_t *exch = async_exchange_begin(sess);
+	int rc = async_req_1_0(exch, NET_NETIF_STOP, device_id);
+	async_exchange_end(exch);
+	
+	return rc;
 }
 
 /** Return the device usage statistics.
  *
- * @param[in] netif_phone Network interface phone.
- * @param[in] device_id   Device identifier.
- * @param[out] stats      Device usage statistics.
+ * @param[in]  sess      Network interface session.
+ * @param[in]  device_id Device identifier.
+ * @param[out] stats     Device usage statistics.
  *
  * @return EOK on success.
  *
  */
-int netif_stats_req(int netif_phone, device_id_t device_id,
+int netif_stats_req(async_sess_t *sess, device_id_t device_id,
     device_stats_t *stats)
 {
@@ -154,7 +164,9 @@
 		return EBADMEM;
 	
-	aid_t message_id = async_obsolete_send_1(netif_phone, NET_NETIF_STATS,
+	async_exch_t *exch = async_exchange_begin(sess);
+	aid_t message_id = async_send_1(exch, NET_NETIF_STATS,
 	    (sysarg_t) device_id, NULL);
-	async_obsolete_data_read_start(netif_phone, stats, sizeof(*stats));
+	async_data_read_start(exch, stats, sizeof(*stats));
+	async_exchange_end(exch);
 	
 	sysarg_t result;
@@ -169,16 +181,14 @@
  * register 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.
+ * @param[in] service   Network interface module service.
+ * @param[in] device_id Device identifier.
+ * @param[in] me        Requesting module service.
+ * @param[in] receiver  Message receiver.
  *
- * @return The phone of the needed service.
- * @return EOK on success.
- * @return Other error codes as defined for the bind_service()
- *         function.
+ * @return Session to the needed service.
+ * @return NULL on failure.
  *
  */
-int netif_bind_service(services_t service, device_id_t device_id,
+async_sess_t *netif_bind_service(services_t service, device_id_t device_id,
     services_t me, async_client_conn_t receiver)
 {
Index: uspace/lib/net/netif/netif_skel.c
===================================================================
--- uspace/lib/net/netif/netif_skel.c	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/lib/net/netif/netif_skel.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -54,7 +54,4 @@
 #include <nil_remote.h>
 
-// FIXME: remove this header
-#include <kernel/ipc/ipc_methods.h>
-
 DEVICE_MAP_IMPLEMENT(netif_device_map, netif_device_t);
 
@@ -64,5 +61,4 @@
 /** Probe the existence of the device.
  *
- * @param[in] netif_phone Network interface phone.
  * @param[in] device_id   Device identifier.
  * @param[in] irq         Device interrupt number.
@@ -74,6 +70,5 @@
  *
  */
-static int netif_probe_req_local(int netif_phone, device_id_t device_id,
-    int irq, void *io)
+static int netif_probe_req_local(device_id_t device_id, int irq, void *io)
 {
 	fibril_rwlock_write_lock(&netif_globals.lock);
@@ -86,5 +81,4 @@
 /** Send the packet queue.
  *
- * @param[in] netif_phone Network interface phone.
  * @param[in] device_id   Device identifier.
  * @param[in] packet      Packet queue.
@@ -96,6 +90,6 @@
  *
  */
-static int netif_send_msg_local(int netif_phone, device_id_t device_id,
-    packet_t *packet, services_t sender)
+static int netif_send_msg_local(device_id_t device_id, packet_t *packet,
+    services_t sender)
 {
 	fibril_rwlock_write_lock(&netif_globals.lock);
@@ -108,5 +102,4 @@
 /** Start the device.
  *
- * @param[in] netif_phone Network interface phone.
  * @param[in] device_id   Device identifier.
  *
@@ -118,5 +111,5 @@
  *
  */
-static int netif_start_req_local(int netif_phone, device_id_t device_id)
+static int netif_start_req_local(device_id_t device_id)
 {
 	fibril_rwlock_write_lock(&netif_globals.lock);
@@ -131,6 +124,5 @@
 	int result = netif_start_message(device);
 	if (result > NETIF_NULL) {
-		int phone = device->nil_phone;
-		nil_device_state_msg(phone, device_id, result);
+		nil_device_state_msg(netif_globals.nil_sess, device_id, result);
 		fibril_rwlock_write_unlock(&netif_globals.lock);
 		return EOK;
@@ -144,5 +136,4 @@
 /** Stop the device.
  *
- * @param[in] netif_phone Network interface phone.
  * @param[in] device_id   Device identifier.
  *
@@ -154,5 +145,5 @@
  *
  */
-static int netif_stop_req_local(int netif_phone, device_id_t device_id)
+static int netif_stop_req_local(device_id_t device_id)
 {
 	fibril_rwlock_write_lock(&netif_globals.lock);
@@ -167,6 +158,5 @@
 	int result = netif_stop_message(device);
 	if (result > NETIF_NULL) {
-		int phone = device->nil_phone;
-		nil_device_state_msg(phone, device_id, result);
+		nil_device_state_msg(netif_globals.nil_sess, device_id, result);
 		fibril_rwlock_write_unlock(&netif_globals.lock);
 		return EOK;
@@ -222,5 +212,5 @@
 void netif_pq_release(packet_id_t packet_id)
 {
-	pq_release_remote(netif_globals.net_phone, packet_id);
+	pq_release_remote(netif_globals.sess, packet_id);
 }
 
@@ -235,31 +225,29 @@
 packet_t *netif_packet_get_1(size_t content)
 {
-	return packet_get_1_remote(netif_globals.net_phone, content);
+	return packet_get_1_remote(netif_globals.sess, content);
 }
 
 /** Register the device notification receiver,
  *
- * Register a  network interface layer module as the device
+ * Register a network interface layer module as the device
  * notification receiver.
  *
- * @param[in] device_id Device identifier.
- * @param[in] phone     Network interface layer module phone.
- *
- * @return EOK on success.
- * @return ENOENT if there is no such device.
+ * @param[in] sess      Session to the network interface layer module.
+ *
+ * @return EOK on success.
  * @return ELIMIT if there is another module registered.
  *
  */
-static int register_message(device_id_t device_id, int phone)
-{
-	netif_device_t *device;
-	int rc = find_device(device_id, &device);
-	if (rc != EOK)
-		return rc;
-	
-	if (device->nil_phone >= 0)
+static int register_message(async_sess_t *sess)
+{
+	fibril_rwlock_write_lock(&netif_globals.lock);
+	if (netif_globals.nil_sess != NULL) {
+		fibril_rwlock_write_unlock(&netif_globals.lock);
 		return ELIMIT;
-	
-	device->nil_phone = phone;
+	}
+	
+	netif_globals.nil_sess = sess;
+	
+	fibril_rwlock_write_unlock(&netif_globals.lock);
 	return EOK;
 }
@@ -294,28 +282,25 @@
 		return EOK;
 	
+	async_sess_t *callback =
+	    async_callback_receive_start(EXCHANGE_SERIALIZE, call);
+	if (callback)
+		return register_message(callback);
+	
 	switch (IPC_GET_IMETHOD(*call)) {
 	case NET_NETIF_PROBE:
-		return netif_probe_req_local(0, IPC_GET_DEVICE(*call),
+		return netif_probe_req_local(IPC_GET_DEVICE(*call),
 		    NETIF_GET_IRQ(*call), NETIF_GET_IO(*call));
 	
-	case IPC_M_CONNECT_TO_ME:
-		fibril_rwlock_write_lock(&netif_globals.lock);
-		
-		rc = register_message(IPC_GET_DEVICE(*call), IPC_GET_PHONE(*call));
-		
-		fibril_rwlock_write_unlock(&netif_globals.lock);
-		return rc;
-	
 	case NET_NETIF_SEND:
-		rc = packet_translate_remote(netif_globals.net_phone, &packet,
+		rc = packet_translate_remote(netif_globals.sess, &packet,
 		    IPC_GET_PACKET(*call));
 		if (rc != EOK)
 			return rc;
 		
-		return netif_send_msg_local(0, IPC_GET_DEVICE(*call), packet,
+		return netif_send_msg_local(IPC_GET_DEVICE(*call), packet,
 		    IPC_GET_SENDER(*call));
 	
 	case NET_NETIF_START:
-		return netif_start_req_local(0, IPC_GET_DEVICE(*call));
+		return netif_start_req_local(IPC_GET_DEVICE(*call));
 	
 	case NET_NETIF_STATS:
@@ -343,5 +328,5 @@
 	
 	case NET_NETIF_STOP:
-		return netif_stop_req_local(0, IPC_GET_DEVICE(*call));
+		return netif_stop_req_local(IPC_GET_DEVICE(*call));
 	
 	case NET_NETIF_GET_ADDR:
@@ -412,5 +397,6 @@
 	async_set_client_connection(netif_client_connection);
 	
-	netif_globals.net_phone = connect_to_service(SERVICE_NETWORKING);
+	netif_globals.sess = connect_to_service(SERVICE_NETWORKING);
+	netif_globals.nil_sess = NULL;
 	netif_device_map_initialize(&netif_globals.device_map);
 	
Index: uspace/lib/net/nil/nil_remote.c
===================================================================
--- uspace/lib/net/nil/nil_remote.c	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/lib/net/nil/nil_remote.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -45,5 +45,5 @@
 /** Notify the network interface layer about the device state change.
  *
- * @param[in] nil_phone Network interface layer phone.
+ * @param[in] sess      Network interface layer session.
  * @param[in] device_id Device identifier.
  * @param[in] state     New device state.
@@ -54,7 +54,8 @@
  *
  */
-int nil_device_state_msg(int nil_phone, device_id_t device_id, int state)
+int nil_device_state_msg(async_sess_t *sess, device_id_t device_id,
+    sysarg_t state)
 {
-	return generic_device_state_msg_remote(nil_phone, NET_NIL_DEVICE_STATE,
+	return generic_device_state_msg_remote(sess, NET_NIL_DEVICE_STATE,
 	    device_id, state, 0);
 }
@@ -65,5 +66,5 @@
  * upper layers.
  *
- * @param[in] nil_phone Network interface layer phone.
+ * @param[in] sess      Network interface layer session.
  * @param[in] device_id Source device identifier.
  * @param[in] packet    Received packet or the received packet queue.
@@ -75,8 +76,8 @@
  *
  */
-int nil_received_msg(int nil_phone, device_id_t device_id,
+int nil_received_msg(async_sess_t *sess, device_id_t device_id,
     packet_t *packet, services_t target)
 {
-	return generic_received_msg_remote(nil_phone, NET_NIL_RECEIVED,
+	return generic_received_msg_remote(sess, NET_NIL_RECEIVED,
 	    device_id, packet_get_id(packet), target, 0);
 }
Index: uspace/lib/net/nil/nil_skel.c
===================================================================
--- uspace/lib/net/nil/nil_skel.c	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/lib/net/nil/nil_skel.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -38,10 +38,8 @@
 #include <bool.h>
 #include <errno.h>
+#include <ns.h>
 #include <nil_skel.h>
 #include <net_interface.h>
 #include <net/modules.h>
-
-// FIXME: remove this header
-#include <kernel/ipc/ipc_methods.h>
 
 /** Default thread for new connections.
@@ -99,14 +97,12 @@
  * @return Other error codes as defined for the nil_initialize()
  *         function.
- * @return Other error codes as defined for the REGISTER_ME() macro
- *         function.
  *
  */
-int nil_module_start(int service)
+int nil_module_start(sysarg_t service)
 {
 	async_set_client_connection(nil_client_connection);
-	int net_phone = net_connect_module();
-	if (net_phone < 0)
-		return net_phone;
+	async_sess_t *sess = net_connect_module();
+	if (!sess)
+		return ENOENT;
 	
 	int rc = pm_init();
@@ -114,9 +110,9 @@
 		return rc;
 	
-	rc = nil_initialize(net_phone);
+	rc = nil_initialize(sess);
 	if (rc != EOK)
 		goto out;
 	
-	rc = async_connect_to_me(PHONE_NS, service, 0, 0, NULL, NULL);
+	rc = service_register(service);
 	if (rc != EOK)
 		goto out;
Index: uspace/lib/net/tl/icmp_remote.c
===================================================================
--- uspace/lib/net/tl/icmp_remote.c	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/lib/net/tl/icmp_remote.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -39,13 +39,11 @@
 #include <net/modules.h>
 #include <packet_client.h>
-
-#include <async.h>
-#include <async_obsolete.h>
-#include <errno.h>
 #include <ipc/services.h>
 #include <ipc/icmp.h>
 #include <sys/types.h>
+#include <async.h>
+#include <errno.h>
 
-/** Sends the Destination Unreachable error notification packet.
+/** Send the Destination Unreachable error notification packet.
  *
  * Beginning of the packet is sent as the notification packet data.
@@ -53,22 +51,26 @@
  * packet.
  *
- * @param[in] icmp_phone The ICMP module phone used for (semi)remote calls.
- * @param[in] code	The error specific code.
- * @param[in] mtu	The error MTU value.
- * @param[in] packet	The original packet.
- * @return		EOK on success.
- * @return		EPERM if the ICMP error notifications are disabled.
- * @return		ENOMEM if there is not enough memory left.
+ * @param[in] sess   ICMP module session.
+ * @param[in] code   Error specific code.
+ * @param[in] mtu    Error MTU value.
+ * @param[in] packet Original packet.
+ *
+ * @return EOK on success.
+ * @return EPERM if the ICMP error notifications are disabled.
+ * @return ENOMEM if there is not enough memory left.
+ *
  */
-int
-icmp_destination_unreachable_msg(int icmp_phone, icmp_code_t code,
+int icmp_destination_unreachable_msg(async_sess_t *sess, icmp_code_t code,
     icmp_param_t mtu, packet_t *packet)
 {
-	async_obsolete_msg_3(icmp_phone, NET_ICMP_DEST_UNREACH, (sysarg_t) code,
+	async_exch_t *exch = async_exchange_begin(sess);
+	async_msg_3(exch, NET_ICMP_DEST_UNREACH, (sysarg_t) code,
 	    (sysarg_t) packet_get_id(packet), (sysarg_t) mtu);
+	async_exchange_end(exch);
+	
 	return EOK;
 }
 
-/** Sends the Source Quench error notification packet.
+/** Send the Source Quench error notification packet.
  *
  * Beginning of the packet is sent as the notification packet data.
@@ -76,18 +78,23 @@
  * packet.
  *
- * @param[in] icmp_phone The ICMP module phone used for (semi)remote calls.
- * @param[in] packet	The original packet.
- * @return		EOK on success.
- * @return		EPERM if the ICMP error notifications are disabled.
- * @return		ENOMEM if there is not enough memory left.
+ * @param[in] sess   ICMP module session.
+ * @param[in] packet Original packet.
+ *
+ * @return EOK on success.
+ * @return EPERM if the ICMP error notifications are disabled.
+ * @return ENOMEM if there is not enough memory left.
+ *
  */
-int icmp_source_quench_msg(int icmp_phone, packet_t *packet)
+int icmp_source_quench_msg(async_sess_t *sess, packet_t *packet)
 {
-	async_obsolete_msg_2(icmp_phone, NET_ICMP_SOURCE_QUENCH, 0,
+	async_exch_t *exch = async_exchange_begin(sess);
+	async_msg_2(exch, NET_ICMP_SOURCE_QUENCH, 0,
 	    (sysarg_t) packet_get_id(packet));
+	async_exchange_end(exch);
+	
 	return EOK;
 }
 
-/** Sends the Time Exceeded error notification packet.
+/** Send the Time Exceeded error notification packet.
  *
  * Beginning of the packet is sent as the notification packet data.
@@ -95,19 +102,25 @@
  * packet.
  *
- * @param[in] icmp_phone The ICMP module phone used for (semi)remote calls.
- * @param[in] code	The error specific code.
- * @param[in] packet	The original packet.
- * @return		EOK on success.
- * @return		EPERM if the ICMP error notifications are disabled.
- * @return		ENOMEM if there is not enough memory left.
+ * @param[in] sess   ICMP module session.
+ * @param[in] code   Error specific code.
+ * @param[in] packet Original packet.
+ *
+ * @return EOK on success.
+ * @return EPERM if the ICMP error notifications are disabled.
+ * @return ENOMEM if there is not enough memory left.
+ *
  */
-int icmp_time_exceeded_msg(int icmp_phone, icmp_code_t code, packet_t *packet)
+int icmp_time_exceeded_msg(async_sess_t *sess, icmp_code_t code,
+    packet_t *packet)
 {
-	async_obsolete_msg_2(icmp_phone, NET_ICMP_TIME_EXCEEDED, (sysarg_t) code,
+	async_exch_t *exch = async_exchange_begin(sess);
+	async_msg_2(exch, NET_ICMP_TIME_EXCEEDED, (sysarg_t) code,
 	    (sysarg_t) packet_get_id(packet));
+	async_exchange_end(exch);
+	
 	return EOK;
 }
 
-/** Sends the Parameter Problem error notification packet.
+/** Send the Parameter Problem error notification packet.
  *
  * Beginning of the packet is sent as the notification packet data.
@@ -115,17 +128,22 @@
  * packet.
  *
- * @param[in] icmp_phone The ICMP module phone used for (semi)remote calls.
- * @param[in] code	The error specific code.
- * @param[in] pointer	The problematic parameter offset.
- * @param[in] packet	The original packet.
- * @return		EOK on success.
- * @return		EPERM if the ICMP error notifications are disabled.
- * @return		ENOMEM if there is not enough memory left.
+ * @param[in] sess    ICMP module session.
+ * @param[in] code    Error specific code.
+ * @param[in] pointer Problematic parameter offset.
+ * @param[in] packet  Original packet.
+ *
+ * @return EOK on success.
+ * @return EPERM if the ICMP error notifications are disabled.
+ * @return ENOMEM if there is not enough memory left.
+ *
  */
-int icmp_parameter_problem_msg(int icmp_phone, icmp_code_t code,
+int icmp_parameter_problem_msg(async_sess_t *sess, icmp_code_t code,
     icmp_param_t pointer, packet_t *packet)
 {
-	async_obsolete_msg_3(icmp_phone, NET_ICMP_PARAMETERPROB, (sysarg_t) code,
+	async_exch_t *exch = async_exchange_begin(sess);
+	async_msg_3(exch, NET_ICMP_PARAMETERPROB, (sysarg_t) code,
 	    (sysarg_t) packet_get_id(packet), (sysarg_t) pointer);
+	async_exchange_end(exch);
+	
 	return EOK;
 }
@@ -133,3 +151,2 @@
 /** @}
  */
-
Index: uspace/lib/net/tl/socket_core.c
===================================================================
--- uspace/lib/net/tl/socket_core.c	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/lib/net/tl/socket_core.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -38,5 +38,4 @@
 #include <packet_client.h>
 #include <packet_remote.h>
-
 #include <net/socket_codes.h>
 #include <net/in.h>
@@ -44,9 +43,7 @@
 #include <net/packet.h>
 #include <net/modules.h>
-
 #include <stdint.h>
 #include <stdlib.h>
 #include <errno.h>
-
 #include <adt/dynamic_fifo.h>
 #include <adt/int_map.h>
@@ -56,5 +53,5 @@
  * switching to the sequence.
  */
-#define SOCKET_ID_TRIES	100
+#define SOCKET_ID_TRIES  100
 
 /** Bound port sockets.*/
@@ -72,23 +69,21 @@
 INT_MAP_IMPLEMENT(socket_ports, socket_port_t);
 
-/** Destroys the socket.
+/** Destroy the socket.
  *
  * If the socket is bound, the port is released.
- * Releases all buffered packets, calls the release function and removes the
+ * Release all buffered packets, call the release function and remove 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_t *socket,
+ * @param[in]     sess           Packet server session.
+ * @param[in]     socket         Socket to be destroyed.
+ * @param[in,out] local_sockets  Local sockets to be updated.
+ * @param[in,out] global_sockets Global sockets to be updated.
+ * @param[in]     socket_release Client release callback function.
+ *
+ */
+static void socket_destroy_core(async_sess_t *sess, socket_core_t *socket,
     socket_cores_t *local_sockets, socket_ports_t *global_sockets,
     void (* socket_release)(socket_core_t *socket))
 {
-	int packet_id;
-
 	/* If bound */
 	if (socket->port) {
@@ -98,44 +93,44 @@
 	
 	/* Release all received packets */
+	int packet_id;
 	while ((packet_id = dyn_fifo_pop(&socket->received)) >= 0)
-		pq_release_remote(packet_phone, packet_id);
-
+		pq_release_remote(sess, 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, free);
 }
 
-/** Destroys local sockets.
- *
- * Releases all buffered packets and calls the release function for each of the
+/** Destroy local sockets.
+ *
+ * Release all buffered packets and call 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_t *local_sockets,
+ * @param[in]     sess           Packet server session.
+ * @param[in]     local_sockets  Local sockets to be destroyed.
+ * @param[in,out] global_sockets Global sockets to be updated.
+ * @param[in]     socket_release Client release callback function.
+ *
+ */
+void socket_cores_release(async_sess_t *sess, socket_cores_t *local_sockets,
     socket_ports_t *global_sockets,
     void (* socket_release)(socket_core_t *socket))
 {
-	int index;
-
 	if (!socket_cores_is_valid(local_sockets))
 		return;
-
+	
 	local_sockets->magic = 0;
-
+	
+	int index;
 	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,
+				socket_destroy_core(sess,
 				    local_sockets->items[index].value,
 				    local_sockets, global_sockets,
@@ -146,5 +141,5 @@
 		}
 	}
-
+	
 	free(local_sockets->items);
 }
@@ -406,18 +401,20 @@
 }
 
-/** 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.
- * @return		EOK on success.
- * @return		EINVAL if the socket_id parameter is NULL.
- * @return		ENOMEM if there is not enough memory left.
- */
-int
-socket_create(socket_cores_t *local_sockets, int app_phone,
+/** Create a new socket.
+ *
+ * @param[in,out] local_sockets Local sockets to be updated.
+ * @param[in]     sess          Application session.
+ * @param[in]     specific_data Socket specific data.
+ * @param[in,out] socket_id     New socket identifier. A new identifier
+ *                              is chosen if set to zero or negative.
+ *                              A negative identifier is chosen if set
+ *                              to negative.
+ *
+ * @return EOK on success.
+ * @return EINVAL if the socket_id parameter is NULL.
+ * @return ENOMEM if there is not enough memory left.
+ *
+ */
+int socket_create(socket_cores_t *local_sockets, async_sess_t* sess,
     void *specific_data, int *socket_id)
 {
@@ -446,5 +443,5 @@
 	
 	/* Initialize */
-	socket->phone = app_phone;
+	socket->sess = sess;
 	socket->port = -1;
 	socket->key = NULL;
@@ -475,37 +472,37 @@
 }
 
-/** Destroys the socket.
+/** Destroy the socket.
  *
  * If the socket is bound, the port is released.
- * Releases all buffered packets, calls the release function and removes the
+ * Release all buffered packets, call the release function and remove 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.
- * @return		EOK on success.
- * @return		ENOTSOCK if the socket is not found.
+ * @param[in]     sess           Packet server session.
+ * @param[in]     socket_id      Socket identifier.
+ * @param[in,out] local_sockets  Local sockets to be updated.
+ * @param[in,out] global_sockets Global sockets to be updated.
+ * @param[in]     socket_release Client release callback function.
+ *
+ * @return EOK on success.
+ * @return ENOTSOCK if the socket is not found.
+ *
  */
 int
-socket_destroy(int packet_phone, int socket_id, socket_cores_t *local_sockets,
+socket_destroy(async_sess_t *sess, int socket_id, socket_cores_t *local_sockets,
     socket_ports_t *global_sockets,
     void (*socket_release)(socket_core_t *socket))
 {
-	socket_core_t *socket;
-	int accepted_id;
-
 	/* Find the socket */
-	socket = socket_cores_find(local_sockets, socket_id);
+	socket_core_t *socket = socket_cores_find(local_sockets, socket_id);
 	if (!socket)
 		return ENOTSOCK;
 	
 	/* Destroy all accepted sockets */
+	int accepted_id;
 	while ((accepted_id = dyn_fifo_pop(&socket->accepted)) >= 0)
-		socket_destroy(packet_phone, accepted_id, local_sockets,
+		socket_destroy(sess, accepted_id, local_sockets,
 		    global_sockets, socket_release);
 	
-	socket_destroy_core(packet_phone, socket, local_sockets, global_sockets,
+	socket_destroy_core(sess, socket, local_sockets, global_sockets,
 	    socket_release);
 	
Index: uspace/lib/net/tl/tl_common.c
===================================================================
--- uspace/lib/net/tl/tl_common.c	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/lib/net/tl/tl_common.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -43,5 +43,4 @@
 #include <ip_interface.h>
 #include <tl_remote.h>
-
 #include <net/socket_codes.h>
 #include <net/in.h>
@@ -50,5 +49,4 @@
 #include <net/device.h>
 #include <net/packet.h>
-
 #include <async.h>
 #include <ipc/services.h>
@@ -107,22 +105,21 @@
  * The reply is cached then.
  *
- * @param[in] ip_phone	The IP moduel phone for (semi)remote calls.
- * @param[in] packet_dimensions The packet dimensions cache.
- * @param[in] device_id	The device identifier.
- * @param[out] packet_dimension The IP packet dimensions.
- * @return		EOK on success.
- * @return		EBADMEM if the packet_dimension parameter is NULL.
- * @return		ENOMEM if there is not enough memory left.
- * @return		EINVAL if the packet_dimensions cache is not valid.
- * @return		Other codes as defined for the ip_packet_size_req()
- *			function.
- */
-int
-tl_get_ip_packet_dimension(int ip_phone,
+ * @param[in]  sess              IP module session.
+ * @param[in]  packet_dimensions Packet dimensions cache.
+ * @param[in]  device_id         Device identifier.
+ * @param[out] packet_dimension  IP packet dimensions.
+ *
+ * @return EOK on success.
+ * @return EBADMEM if the packet_dimension parameter is NULL.
+ * @return ENOMEM if there is not enough memory left.
+ * @return EINVAL if the packet_dimensions cache is not valid.
+ * @return Other codes as defined for the ip_packet_size_req()
+ *         function.
+ *
+ */
+int tl_get_ip_packet_dimension(async_sess_t *sess,
     packet_dimensions_t *packet_dimensions, device_id_t device_id,
     packet_dimension_t **packet_dimension)
 {
-	int rc;
-	
 	if (!packet_dimension)
 		return EBADMEM;
@@ -133,8 +130,8 @@
 		/* Ask for and remember them if not found */
 		*packet_dimension = malloc(sizeof(**packet_dimension));
-		if(!*packet_dimension)
+		if (!*packet_dimension)
 			return ENOMEM;
 		
-		rc = ip_packet_size_req(ip_phone, device_id, *packet_dimension);
+		int rc = ip_packet_size_req(sess, device_id, *packet_dimension);
 		if (rc != EOK) {
 			free(*packet_dimension);
@@ -236,30 +233,28 @@
 /** Prepares the packet for ICMP error notification.
  *
- * Keeps the first packet and releases all the others.
- * Releases all the packets on error.
- *
- * @param[in] packet_phone The packet server module phone.
- * @param[in] icmp_phone The ICMP module phone.
- * @param[in] packet	The packet to be send.
- * @param[in] error	The packet error reporting service. Prefixes the
- *			received packet.
- * @return		EOK on success.
- * @return		ENOENT if no packet may be sent.
- */
-int
-tl_prepare_icmp_packet(int packet_phone, int icmp_phone, packet_t *packet,
-    services_t error)
-{
-	packet_t *next;
+ * Keep the first packet and release all the others.
+ * Release all the packets on error.
+ *
+ * @param[in] packet_sess Packet server module session.
+ * @param[in] icmp_sess   ICMP module phone.
+ * @param[in] packet      Packet to be send.
+ * @param[in] error       Packet error reporting service. Prefixes the
+ *                        received packet.
+ *
+ * @return EOK on success.
+ * @return ENOENT if no packet may be sent.
+ *
+ */
+int tl_prepare_icmp_packet(async_sess_t *packet_sess, async_sess_t *icmp_sess,
+    packet_t *packet, services_t error)
+{
+	/* Detach the first packet and release the others */
+	packet_t *next = pq_detach(packet);
+	if (next)
+		pq_release_remote(packet_sess, packet_get_id(next));
+	
 	uint8_t *src;
-	int length;
-
-	/* Detach the first packet and release the others */
-	next = pq_detach(packet);
-	if (next)
-		pq_release_remote(packet_phone, packet_get_id(next));
-	
-	length = packet_get_addr(packet, &src, NULL);
-	if ((length > 0) && (!error) && (icmp_phone >= 0) &&
+	int length = packet_get_addr(packet, &src, NULL);
+	if ((length > 0) && (!error) && (icmp_sess) &&
 	    /*
 	     * Set both addresses to the source one (avoids the source address
@@ -269,6 +264,6 @@
 		return EOK;
 	} else
-		pq_release_remote(packet_phone, packet_get_id(packet));
-
+		pq_release_remote(packet_sess, packet_get_id(packet));
+	
 	return ENOENT;
 }
@@ -276,20 +271,21 @@
 /** Receives data from the socket into a packet.
  *
- * @param[in] packet_phone The packet server module phone.
- * @param[out] packet	The new created packet.
- * @param[in] prefix	Reserved packet data prefix length.
- * @param[in] dimension	The packet dimension.
- * @param[in] addr	The destination address.
- * @param[in] addrlen	The address length.
- * @return		Number of bytes received.
- * @return		EINVAL if the client does not send data.
- * @return		ENOMEM if there is not enough memory left.
- * @return		Other error codes as defined for the
- *			async_data_read_finalize() function.
- */
-int
-tl_socket_read_packet_data(int packet_phone, packet_t **packet, size_t prefix,
-    const packet_dimension_t *dimension, const struct sockaddr *addr,
-    socklen_t addrlen)
+ * @param[in]  sess      Packet server module session.
+ * @param[out] packet    New created packet.
+ * @param[in]  prefix    Reserved packet data prefix length.
+ * @param[in]  dimension Packet dimension.
+ * @param[in]  addr      Destination address.
+ * @param[in]  addrlen   Address length.
+ *
+ * @return Number of bytes received.
+ * @return EINVAL if the client does not send data.
+ * @return ENOMEM if there is not enough memory left.
+ * @return Other error codes as defined for the
+ *         async_data_read_finalize() function.
+ *
+ */
+int tl_socket_read_packet_data(async_sess_t *sess, packet_t **packet,
+    size_t prefix, const packet_dimension_t *dimension,
+    const struct sockaddr *addr, socklen_t addrlen)
 {
 	ipc_callid_t callid;
@@ -306,5 +302,5 @@
 
 	/* Get a new packet */
-	*packet = packet_get_4_remote(packet_phone, length, dimension->addr_len,
+	*packet = packet_get_4_remote(sess, length, dimension->addr_len,
 	    prefix + dimension->prefix, dimension->suffix);
 	if (!packet)
@@ -314,5 +310,5 @@
 	data = packet_suffix(*packet, length);
 	if (!data) {
-		pq_release_remote(packet_phone, packet_get_id(*packet));
+		pq_release_remote(sess, packet_get_id(*packet));
 		return ENOMEM;
 	}
@@ -321,5 +317,5 @@
 	rc = async_data_write_finalize(callid, data, length);
 	if (rc != EOK) {
-		pq_release_remote(packet_phone, packet_get_id(*packet));
+		pq_release_remote(sess, packet_get_id(*packet));
 		return rc;
 	}
@@ -328,5 +324,5 @@
 	rc = packet_set_addr(*packet, NULL, (uint8_t *) addr, addrlen);
 	if (rc != EOK) {
-		pq_release_remote(packet_phone, packet_get_id(*packet));
+		pq_release_remote(sess, packet_get_id(*packet));
 		return rc;
 	}
Index: uspace/lib/net/tl/tl_remote.c
===================================================================
--- uspace/lib/net/tl/tl_remote.c	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/lib/net/tl/tl_remote.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -34,22 +34,21 @@
 #include <generic.h>
 #include <packet_client.h>
-
 #include <ipc/services.h>
 #include <ipc/tl.h>
-
 #include <net/device.h>
 #include <net/packet.h>
+#include <async.h>
 
 /** Notify the remote transport layer modules about the received packet/s.
  *
- * @param[in] tl_phone  The transport layer module phone used for remote calls.
- * @param[in] device_id The device identifier.
- * @param[in] packet    The received packet or the received packet queue.
+ * @param[in] sess      Transport layer module session.
+ * @param[in] device_id Device identifier.
+ * @param[in] packet    Received packet or the received packet queue.
  *                      The packet queue is used to carry a fragmented
  *                      datagram. The first packet contains the headers,
  *                      the others contain only data.
- * @param[in] target    The target transport layer module service to be
+ * @param[in] target    Target transport layer module service to be
  *                      delivered to.
- * @param[in] error     The packet error reporting service. Prefixes the
+ * @param[in] error     Packet error reporting service. Prefixes the
  *                      received packet.
  *
@@ -57,8 +56,8 @@
  *
  */
-int tl_received_msg(int tl_phone, device_id_t device_id, packet_t *packet,
+int tl_received_msg(async_sess_t *sess, device_id_t device_id, packet_t *packet,
     services_t target, services_t error)
 {
-	return generic_received_msg_remote(tl_phone, NET_TL_RECEIVED, device_id,
+	return generic_received_msg_remote(sess, NET_TL_RECEIVED, device_id,
 	    packet_get_id(packet), target, error);
 }
Index: uspace/lib/net/tl/tl_skel.c
===================================================================
--- uspace/lib/net/tl/tl_skel.c	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/lib/net/tl/tl_skel.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -38,16 +38,14 @@
 #include <bool.h>
 #include <errno.h>
+#include <ns.h>
 #include <tl_skel.h>
 #include <net_interface.h>
 #include <net/modules.h>
 
-// FIXME: remove this header
-#include <kernel/ipc/ipc_methods.h>
-
 /** Default thread for new connections.
  *
- * @param[in] iid  	The initial message identifier.
- * @param[in] icall	The initial message call structure.
- * @param[in] arg	Local argument.
+ * @param[in] iid   The initial message identifier.
+ * @param[in] icall The initial message call structure.
+ * @param[in] arg   Local argument.
  *
  */
@@ -106,10 +104,10 @@
  *
  */
-int tl_module_start(int service)
+int tl_module_start(sysarg_t service)
 {
 	async_set_client_connection(tl_client_connection);
-	int net_phone = net_connect_module();
-	if (net_phone < 0)
-		return net_phone;
+	async_sess_t *sess = net_connect_module();
+	if (!sess)
+		return ENOENT;
 	
 	int rc = pm_init();
@@ -117,9 +115,9 @@
 		return rc;
 	
-	rc = tl_initialize(net_phone);
+	rc = tl_initialize(sess);
 	if (rc != EOK)
 		goto out;
 	
-	rc = async_connect_to_me(PHONE_NS, service, 0, 0, NULL, NULL);
+	rc = service_register(service);
 	if (rc != EOK)
 		goto out;
Index: uspace/lib/packet/generic/packet_server.c
===================================================================
--- uspace/lib/packet/generic/packet_server.c	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/lib/packet/generic/packet_server.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -36,5 +36,4 @@
 
 #include <packet_server.h>
-
 #include <align.h>
 #include <assert.h>
@@ -317,15 +316,13 @@
  *			packet_release_wrapper() function.
  */
-int
-packet_server_message(ipc_callid_t callid, ipc_call_t *call, ipc_call_t *answer,
+int packet_server_message(ipc_callid_t callid, ipc_call_t *call, ipc_call_t *answer,
     size_t *answer_count)
 {
 	packet_t *packet;
-
-	*answer_count = 0;
 	
 	if (!IPC_GET_IMETHOD(*call))
 		return EOK;
 	
+	*answer_count = 0;
 	switch (IPC_GET_IMETHOD(*call)) {
 	case NET_PACKET_CREATE_1:
Index: uspace/lib/scsi/Makefile
===================================================================
--- uspace/lib/scsi/Makefile	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
+++ uspace/lib/scsi/Makefile	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -0,0 +1,36 @@
+#
+# Copyright (c) 2011 Jiri Svoboda
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# - Redistributions of source code must retain the above copyright
+#   notice, this list of conditions and the following disclaimer.
+# - Redistributions in binary form must reproduce the above copyright
+#   notice, this list of conditions and the following disclaimer in the
+#   documentation and/or other materials provided with the distribution.
+# - The name of the author may not be used to endorse or promote products
+#   derived from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+
+USPACE_PREFIX = ../..
+EXTRA_CFLAGS = -Iinclude
+LIBRARY = libscsi
+
+SOURCES = \
+	src/spc.c
+
+include $(USPACE_PREFIX)/Makefile.common
Index: uspace/lib/scsi/include/scsi/sbc.h
===================================================================
--- uspace/lib/scsi/include/scsi/sbc.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
+++ uspace/lib/scsi/include/scsi/sbc.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -0,0 +1,152 @@
+/*
+ * Copyright (c) 2011 Jiri Svoboda
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup libscsi
+ * @{
+ */
+/**
+ * @file SCSI Block Commands.
+ */
+
+#ifndef LIBSCSI_SBC_H_
+#define LIBSCSI_SBC_H_
+
+#include <stdint.h>
+
+/** SCSI command codes defined in SCSI-SBC */
+enum scsi_cmd_sbc {
+	SCSI_CMD_READ_6			= 0x08,
+	SCSI_CMD_READ_10		= 0x28,
+	SCSI_CMD_READ_12		= 0xa8,
+	SCSI_CMD_READ_16		= 0x88,
+	SCSI_CMD_READ_32		= 0x7f,
+
+	SCSI_CMD_READ_CAPACITY_10	= 0x25,
+	SCSI_CMD_READ_CAPACITY_16	= 0x9e,
+
+	SCSI_CMD_WRITE_6		= 0x0a,
+	SCSI_CMD_WRITE_10		= 0x2a,
+	SCSI_CMD_WRITE_12		= 0xaa,
+	SCSI_CMD_WRITE_16		= 0x8a
+};
+
+/** SCSI Read (12) command */
+typedef struct {
+	/** Operation code (SCSI_CMD_READ_12) */
+	uint8_t op_code;
+	/** RdProtect, DPO, FUA, Reserved, FUA_NV, Reserved */
+	uint8_t flags;
+	/** Logical block address */
+	uint32_t lba;
+	/** Transfer length */
+	uint32_t xfer_len;
+	/** Reserved, Group Number */
+	uint8_t group_no;
+	/** Control */
+	uint8_t control;
+} __attribute__((packed)) scsi_cdb_read_12_t;
+
+/** SCSI Read (16) command */
+typedef struct {
+	/** Operation code (SCSI_CMD_READ_16) */
+	uint8_t op_code;
+	/** RdProtect, DPO, FUA, Reserved, FUA_NV, Reserved */
+	uint8_t flags;
+	/** Logical block address */
+	uint64_t lba;
+	/** Transfer length */
+	uint32_t xfer_len;
+	/** Reserved, Group Number */
+	uint8_t group_no;
+	/** Control */
+	uint8_t control;
+} __attribute__((packed)) scsi_cdb_read_16_t;
+
+/** SCSI Read Capacity (10) command */
+typedef struct {
+	/** Operation code (SCSI_CMD_READ_CAPACITY_10) */
+	uint8_t op_code;
+	/** Reserved, Obsolete */
+	uint8_t reserved_1;
+	/** Logical block address */
+	uint32_t lba;
+	/** Reserved */
+	uint32_t reserved_6;
+	/** Reserved, PM */
+	uint8_t pm;
+	/** Control */
+	uint8_t control;
+} __attribute__((packed)) scsi_cdb_read_capacity_10_t;
+
+/** Read Capacity (10) parameter data.
+ *
+ * Returned for Read Capacity (10) command.
+ */
+typedef struct {
+	/** Logical address of last block */
+	uint32_t last_lba;
+	/** Size of block in bytes */
+	uint32_t block_size;
+} scsi_read_capacity_10_data_t;
+
+/** SCSI Write (12) command */
+typedef struct {
+	/** Operation code (SCSI_CMD_WRITE_12) */
+	uint8_t op_code;
+	/** WrProtect, DPO, FUA, Reserved, FUA_NV, Reserved */
+	uint8_t flags;
+	/** Logical block address */
+	uint32_t lba;
+	/** Transfer length */
+	uint32_t xfer_len;
+	/** Reserved, Group Number */
+	uint8_t group_no;
+	/** Control */
+	uint8_t control;
+} __attribute__((packed)) scsi_cdb_write_12_t;
+
+/** SCSI Write (16) command */
+typedef struct {
+	/** Operation code (SCSI_CMD_WRITE_16) */
+	uint8_t op_code;
+	/** WrProtect, DPO, FUA, Reserved, FUA_NV, Reserved */
+	uint8_t flags;
+	/** Logical block address */
+	uint64_t lba;
+	/** Transfer length */
+	uint32_t xfer_len;
+	/** Reserved, Group Number */
+	uint8_t group_no;
+	/** Control */
+	uint8_t control;
+} __attribute__((packed)) scsi_cdb_write_16_t;
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/scsi/include/scsi/spc.h
===================================================================
--- uspace/lib/scsi/include/scsi/spc.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
+++ uspace/lib/scsi/include/scsi/spc.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -0,0 +1,216 @@
+/*
+ * Copyright (c) 2011 Jiri Svoboda
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup libscsi
+ * @{
+ */
+/**
+ * @file SCSI Primary Commands.
+ */
+
+#ifndef LIBSCSI_SPC_H_
+#define LIBSCSI_SPC_H_
+
+#include <stdint.h>
+#include <str.h>
+
+/** SCSI command codes defined in SCSI-SPC */
+enum scsi_cmd_spc {
+	SCSI_CMD_INQUIRY	= 0x12,
+	SCSI_CMD_REQUEST_SENSE	= 0x03
+};
+
+/** SCSI Inquiry command */
+typedef struct {
+	/** Operation code (SCSI_CMD_INQUIRY) */
+	uint8_t op_code;
+	/** Reserved:7-2, obsolete:1, evpd:0 */
+	uint8_t evpd;
+	/* Page Code */
+	uint8_t page_code;
+	/* Allocation Length */
+	uint16_t alloc_len;
+	/* Control */
+	uint8_t control;
+} __attribute__((packed)) scsi_cdb_inquiry_t;
+
+/** Minimum size of inquiry data required since SCSI-2 */
+#define SCSI_STD_INQUIRY_DATA_MIN_SIZE 36
+
+/** Standard inquiry data.
+ *
+ * Returned for Inquiry command with evpd bit cleared.
+ */
+typedef struct {
+	/** Peripheral qualifier, Peripheral device type */
+	uint8_t pqual_devtype;
+	/** RMB, reserved */
+	uint8_t rmb;
+	/** Version */
+	uint8_t version;
+	/** Obsolete, NormACA, HiSup, Response Data Format */
+	uint8_t aca_hisup_rdf;
+	/** Additional Length */
+	uint8_t additional_len;
+	/** SCCS, ACC, TPGS, 3PC, Reserved, Protect */
+	uint8_t cap1;
+	/** Obsolete, EncServ, VS, MuliP, Obsolete, Addr16 */
+	uint8_t cap2;
+	/** Obsolete, WBus16, Sync, Obsolete, CmdQue, VS */
+	uint8_t cap3;
+
+	/** Vendor string */
+	uint8_t vendor[8];
+	/** Product string */
+	uint8_t product[16];
+	/** Revision string */
+	uint8_t revision[4];
+
+	/* End of required data */
+} __attribute__((packed)) scsi_std_inquiry_data_t;
+
+/** Size of struct or union member. */
+#define SCSI_MEMBER_SIZE(type, member) \
+    (sizeof(((type *)0) -> member))
+
+/** Size of string buffer needed to hold converted inquiry vendor string */
+#define SCSI_INQ_VENDOR_STR_BUFSIZE \
+    SPASCII_STR_BUFSIZE(SCSI_MEMBER_SIZE(scsi_std_inquiry_data_t, vendor))
+
+/** Size of string buffer needed to hold converted inquiry product string */
+#define SCSI_INQ_PRODUCT_STR_BUFSIZE \
+    SPASCII_STR_BUFSIZE(SCSI_MEMBER_SIZE(scsi_std_inquiry_data_t, product))
+
+/** Size of string buffer needed to hold converted inquiry revision string */
+#define SCSI_INQ_REVISION_STR_BUFSIZE \
+    SPASCII_STR_BUFSIZE(SCSI_MEMBER_SIZE(scsi_std_inquiry_data_t, revision))
+
+/** Bits in scsi_std_inquiry_data_t.pqual_devtype */
+enum scsi_pqual_devtype_bits {
+	/* Peripheral qualifier */
+	SCSI_PQDT_PQUAL_h	= 7,
+	SCSI_PQDT_PQUAL_l	= 5,
+
+	/* Peripheral device type */
+	SCSI_PQDT_DEV_TYPE_h	= 4,
+	SCSI_PQDT_DEV_TYPE_l	= 0
+};
+
+/** Bits in scsi_std_inquiry_data_t.rmb */
+enum scsi_rmb_bits {
+	SCSI_RMB_RMB		= 7
+};
+
+/** SCSI peripheral device type */
+enum scsi_device_type {
+	SCSI_DEV_BLOCK		= 0x00,
+	SCSI_DEV_STREAM		= 0x01,
+	SCSI_DEV_CD_DVD		= 0x05,
+	SCSI_DEV_CHANGER	= 0x08,
+	SCSI_DEV_ENCLOSURE	= 0x0d,
+	SCSI_DEV_OSD		= 0x11,
+
+	SCSI_DEV_LIMIT		= 0x20
+};
+
+/** SCSI Request Sense command */
+typedef struct {
+	/** Operation code (SCSI_CMD_REQUEST_SENSE) */
+	uint8_t op_code;
+	/** Reserved, Desc */
+	uint8_t desc;
+	/* Reserved */
+	uint16_t res_2;
+	/* Allocation Length */
+	uint8_t alloc_len;
+	/* Control */
+	uint8_t control;
+} __attribute__((packed)) scsi_cdb_request_sense_t;
+
+/** Minimum size of sense data.
+ *
+ * If the target returns less data, the missing bytes should be considered
+ * zero.
+ */
+#define SCSI_SENSE_DATA_MIN_SIZE 18
+
+/** Maximum size of sense data */
+#define SCSI_SENSE_DATA_MAX_SIZE 252
+
+/** Fixed-format sense data.
+ *
+ * Returned for Request Sense command with Desc bit cleared.
+ */
+typedef struct {
+	/** Valid, Response Code */
+	uint8_t valid_rcode;
+	/** Peripheral qualifier, Peripheral device type */
+	uint8_t obsolete_1;
+	/** Filemark, EOM, ILI, Reserved, Sense Key */
+	uint8_t flags_key;
+	/** Information */
+	uint32_t info;
+	/** Additional Sense Length */
+	uint8_t additional_len;
+	/** Command-specific Information */
+	uint8_t cmd_spec;
+	/** Additional Sense Code */
+	uint8_t additional_code;
+	/** Additional Sense Code Qualifier */
+	uint8_t additional_cqual;
+	/** Field-replaceable Unit Code */
+	uint8_t fru_code;
+	/** SKSV, Sense-key specific */
+	uint8_t key_spec[3];
+} __attribute__((packed)) scsi_sense_data_t;
+
+/** Sense key */
+enum scsi_sense_key {
+	SCSI_SK_NO_SENSE	= 0x0,
+	SCSI_SK_RECOVERED_ERROR	= 0x1,
+	SCSI_SK_NOT_READY	= 0x2,
+	SCSI_SK_MEDIUM_ERROR	= 0x3,
+	SCSI_SK_HARDWARE_ERROR	= 0x4,
+	SCSI_SK_ILLEGAL_REQUEST	= 0x5,
+	SCSI_SK_UNIT_ATTENTION	= 0x6,
+	SCSI_SK_DATA_PROTECT	= 0x7,
+	SCSI_SK_BLANK_CHECK	= 0x8,
+	SCSI_SK_VENDOR_SPECIFIC	= 0x9,
+	SCSI_SK_COPY_ABORTED	= 0xa,
+	SCSI_SK_ABORTED_COMMAND	= 0xb,
+	SCSI_SK_VOLUME_OVERFLOW	= 0xd,
+	SCSI_SK_MISCOMPARE	= 0xe
+};
+
+extern const char *scsi_dev_type_str[SCSI_DEV_LIMIT];
+extern const char *scsi_get_dev_type_str(unsigned);
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/scsi/src/spc.c
===================================================================
--- uspace/lib/scsi/src/spc.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
+++ uspace/lib/scsi/src/spc.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2011 Jiri Svoboda
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdint.h>
+#include <stdlib.h>
+#include "scsi/spc.h"
+
+/** String descriptions for SCSI peripheral device type.
+ *
+ * Only device types that we are ever likely to encounter are listed here.
+ */
+const char *scsi_dev_type_str[SCSI_DEV_LIMIT] = {
+	[SCSI_DEV_BLOCK]	= "Direct-Access Block Device (Disk)",
+	[SCSI_DEV_STREAM]	= "Sequential-Access Device (Tape)",
+	[SCSI_DEV_CD_DVD]	= "CD/DVD",
+	[SCSI_DEV_CHANGER]	= "Media Changer",
+	[SCSI_DEV_ENCLOSURE]	= "SCSI Enclosure",
+	[SCSI_DEV_OSD]		= "Object Storage Device"
+};
+
+/** Get peripheral device type string.
+ *
+ * Return string description of SCSI peripheral device type.
+ * The returned string is valid indefinitely, the caller should
+ * not attempt to free it.
+ */
+const char *scsi_get_dev_type_str(unsigned dev_type)
+{
+	if (dev_type >= SCSI_DEV_LIMIT || scsi_dev_type_str[dev_type] == NULL)
+		return "<unknown>";
+
+	return scsi_dev_type_str[dev_type];
+}
Index: uspace/lib/softfloat/arch/mips32/include/functions.h
===================================================================
--- uspace/lib/softfloat/arch/mips32/include/functions.h	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/lib/softfloat/arch/mips32/include/functions.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -27,5 +27,5 @@
  */
 
- /** @addtogroup softfloatmips32 mips32	
+/** @addtogroup softfloatmips32 mips32
  * @ingroup sfl
  * @brief softfloat architecture dependent definitions 
@@ -72,6 +72,4 @@
 #endif
 
-
- /** @}
+/** @}
  */
-
Index: uspace/lib/softfloat/arch/mips64/include/functions.h
===================================================================
--- uspace/lib/softfloat/arch/mips64/include/functions.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
+++ uspace/lib/softfloat/arch/mips64/include/functions.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -0,0 +1,75 @@
+/*
+ * 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 softfloatmips64 mips64
+ * @ingroup sfl
+ * @brief softfloat architecture dependent definitions
+ * @{
+ */
+/** @file
+ */
+
+#ifndef __SOFTFLOAT_FUNCTIONS_H__
+#define __SOFTFLOAT_FUNCTIONS_H__
+
+#define float32_to_int(X) float32_to_int32(X);
+#define float32_to_long(X) float32_to_int64(X);
+#define float32_to_longlong(X) float32_to_int64(X);
+
+#define float64_to_int(X) float64_to_int32(X);
+#define float64_to_long(X) float64_to_int64(X);
+#define float64_to_longlong(X) float64_to_int64(X);
+
+#define float32_to_uint(X) float32_to_uint32(X);
+#define float32_to_ulong(X) float32_to_uint64(X);
+#define float32_to_ulonglong(X) float32_to_uint64(X);
+
+#define float64_to_uint(X) float64_to_uint32(X);
+#define float64_to_ulong(X) float64_to_uint64(X);
+#define float64_to_ulonglong(X) float64_to_uint64(X);
+
+#define int_to_float32(X) int32_to_float32(X);
+#define long_to_float32(X) int64_to_float32(X);
+#define longlong_to_float32(X) int64_to_float32(X);
+
+#define int_to_float64(X) int32_to_float64(X);
+#define long_to_float64(X) int64_to_float64(X);
+#define longlong_to_float64(X) int64_to_float64(X);
+
+#define uint_to_float32(X) uint32_to_float32(X);
+#define ulong_to_float32(X) uint64_to_float32(X);
+#define ulonglong_to_float32(X) uint64_to_float32(X);
+
+#define uint_to_float64(X) uint32_to_float64(X);
+#define ulong_to_float64(X) uint64_to_float64(X);
+#define ulonglong_to_float64(X) uint64_to_float64(X);
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/usbhost/src/batch.c
===================================================================
--- uspace/lib/usbhost/src/batch.c	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/lib/usbhost/src/batch.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -128,5 +128,5 @@
 	memcpy(instance->buffer, instance->data_buffer, instance->buffer_size);
 
-	usb_log_debug("Batch %p " USB_TRANSFER_BATCH_FMT " completed (%zuB): %s.\n",
+	usb_log_debug2("Batch %p " USB_TRANSFER_BATCH_FMT " completed (%zuB): %s.\n",
 	    instance, USB_TRANSFER_BATCH_ARGS(*instance),
 	    instance->transfered_size, str_error(instance->error));
@@ -145,5 +145,5 @@
 	assert(instance->callback_out);
 
-	usb_log_debug("Batch %p " USB_TRANSFER_BATCH_FMT " completed: %s.\n",
+	usb_log_debug2("Batch %p " USB_TRANSFER_BATCH_FMT " completed: %s.\n",
 	    instance, USB_TRANSFER_BATCH_ARGS(*instance),
 	    str_error(instance->error));
Index: uspace/srv/bd/ata_bd/ata_bd.c
===================================================================
--- uspace/srv/bd/ata_bd/ata_bd.c	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/srv/bd/ata_bd/ata_bd.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -80,7 +80,4 @@
  */
 static const size_t identify_data_size = 512;
-
-/** Size of the communication area. */
-static size_t comm_size;
 
 /** I/O base address of the command registers. */
@@ -281,4 +278,5 @@
 	sysarg_t method;
 	devmap_handle_t dh;
+	size_t comm_size;	/**< Size of the communication area. */
 	unsigned int flags;
 	int retval;
Index: uspace/srv/fs/ext2fs/ext2fs_ops.c
===================================================================
--- uspace/srv/fs/ext2fs/ext2fs_ops.c	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/srv/fs/ext2fs/ext2fs_ops.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -240,5 +240,5 @@
 	}
 	
-	rc = ext2_directory_iterator_init(&it, fs, eparent->inode_ref);
+	rc = ext2_directory_iterator_init(&it, fs, eparent->inode_ref, 0);
 	if (rc != EOK) {
 		return rc;
@@ -478,5 +478,5 @@
 	}
 	
-	rc = ext2_directory_iterator_init(&it, fs, enode->inode_ref);
+	rc = ext2_directory_iterator_init(&it, fs, enode->inode_ref, 0);
 	if (rc != EOK) {
 		EXT2FS_DBG("error %u", rc);
@@ -818,5 +818,5 @@
 {
 	ext2_directory_iterator_t it;
-	aoff64_t cur;
+	aoff64_t next;
 	uint8_t *buf;
 	size_t name_size;
@@ -824,5 +824,5 @@
 	bool found = false;
 	
-	rc = ext2_directory_iterator_init(&it, inst->filesystem, inode_ref);
+	rc = ext2_directory_iterator_init(&it, inst->filesystem, inode_ref, pos);
 	if (rc != EOK) {
 		async_answer_0(callid, rc);
@@ -831,11 +831,8 @@
 	}
 	
-	/* Find the index we want to read
-	 * Note that we need to iterate and count as
-	 * the underlying structure is a linked list
-	 * Moreover, we want to skip . and .. entries
+	/* Find next interesting directory entry.
+	 * We want to skip . and .. entries
 	 * as these are not used in HelenOS
 	 */
-	cur = 0;
 	while (it.current != NULL) {
 		if (it.current->inode == 0) {
@@ -851,25 +848,21 @@
 		}
 		
-		/* Is this the dir entry we want to read? */
-		if (cur == pos) {
-			/* The on-disk entry does not contain \0 at the end
-			 * end of entry name, so we copy it to new buffer
-			 * and add the \0 at the end
-			 */
-			buf = malloc(name_size+1);
-			if (buf == NULL) {
-				ext2_directory_iterator_fini(&it);
-				async_answer_0(callid, ENOMEM);
-				async_answer_0(rid, ENOMEM);
-				return;
-			}
-			memcpy(buf, &it.current->name, name_size);
-			*(buf+name_size) = 0;
-			found = true;
-			(void) async_data_read_finalize(callid, buf, name_size+1);
-			free(buf);
-			break;
-		}
-		cur++;
+		/* The on-disk entry does not contain \0 at the end
+			* end of entry name, so we copy it to new buffer
+			* and add the \0 at the end
+			*/
+		buf = malloc(name_size+1);
+		if (buf == NULL) {
+			ext2_directory_iterator_fini(&it);
+			async_answer_0(callid, ENOMEM);
+			async_answer_0(rid, ENOMEM);
+			return;
+		}
+		memcpy(buf, &it.current->name, name_size);
+		*(buf+name_size) = 0;
+		found = true;
+		(void) async_data_read_finalize(callid, buf, name_size+1);
+		free(buf);
+		break;
 		
 skip:
@@ -883,4 +876,13 @@
 	}
 	
+	if (found) {
+		rc = ext2_directory_iterator_next(&it);
+		if (rc != EOK) {
+			async_answer_0(rid, rc);
+			return;
+		}
+		next = it.current_offset;
+	}
+	
 	rc = ext2_directory_iterator_fini(&it);
 	if (rc != EOK) {
@@ -890,5 +892,5 @@
 	
 	if (found) {
-		async_answer_1(rid, EOK, 1);
+		async_answer_1(rid, EOK, next-pos);
 	}
 	else {
Index: uspace/srv/hid/console/console.c
===================================================================
--- uspace/srv/hid/console/console.c	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/srv/hid/console/console.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -357,5 +357,5 @@
 		console_serialize_end();
 		
-		if (__SYSCALL0(SYS_DEBUG_ENABLE_CONSOLE)) {
+		if (console_kcon()) {
 			prev_console = active_console;
 			active_console = kernel_console;
@@ -711,7 +711,4 @@
 			console_serialize_start();
 			continue;
-		case CONSOLE_KCON_ENABLE:
-			change_console(kernel_console);
-			break;
 		}
 		async_answer_3(callid, EOK, arg1, arg2, arg3);
@@ -833,7 +830,4 @@
 	}
 	
-	/* Disable kernel output to the console */
-	__SYSCALL0(SYS_DEBUG_DISABLE_CONSOLE);
-	
 	/* Initialize the screen */
 	console_serialize_start();
Index: uspace/srv/hid/fb/Makefile
===================================================================
--- uspace/srv/hid/fb/Makefile	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/srv/hid/fb/Makefile	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -84,11 +84,4 @@
 		EXTRA_CFLAGS += -DNIAGARA_ENABLED
 	endif
-	
-	ifeq ($(MACHINE),serengeti)
-		SOURCES += \
-			sgcn.c \
-			serial_console.c
-		EXTRA_CFLAGS += -DSGCN_ENABLED
-	endif
 endif
 
Index: uspace/srv/hid/fb/main.c
===================================================================
--- uspace/srv/hid/fb/main.c	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/srv/hid/fb/main.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -40,5 +40,4 @@
 #include "msim.h"
 #include "ski.h"
-#include "sgcn.h"
 #include "niagara.h"
 #include "main.h"
@@ -92,10 +91,4 @@
 	}
 #endif
-#ifdef SGCN_ENABLED
-	if ((!initialized) && (fb_kind == 4)) {
-		if (sgcn_init() == 0)
-			initialized = true;
-	}
-#endif
 #ifdef NIAGARA_ENABLED
 	if ((!initialized) && (fb_kind == 5)) {
Index: uspace/srv/hid/fb/niagara.c
===================================================================
--- uspace/srv/hid/fb/niagara.c	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/srv/hid/fb/niagara.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -29,5 +29,5 @@
  */
 
-/** @defgroup niagarafb SGCN
+/** @defgroup niagarafb
  * @brief	userland driver of the Niagara console output
  * @{
Index: uspace/srv/hid/fb/niagara.h
===================================================================
--- uspace/srv/hid/fb/niagara.h	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/srv/hid/fb/niagara.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -27,6 +27,6 @@
  */
 
-/** @defgroup sgcnfb SGCN
- * @brief	userland driver of the Serengeti console output
+/** @defgroup niagarafb
+ * @brief	userland driver of the Niagara console output
  * @{
  */
Index: pace/srv/hid/fb/sgcn.c
===================================================================
--- uspace/srv/hid/fb/sgcn.c	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ 	(revision )
@@ -1,150 +1,0 @@
-/*
- * Copyright (c) 2006 Ondrej Palkovsky
- * Copyright (c) 2008 Martin Decky
- * Copyright (c) 2008 Pavel Rimsky
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/** @defgroup sgcnfb SGCN
- * @brief	userland driver of the Serengeti console output
- * @{
- */ 
-/** @file
- */
-
-#include <async.h>
-#include <sysinfo.h>
-#include <as.h>
-#include <errno.h>
-#include <stdio.h>
-#include <ddi.h>
-
-#include "serial_console.h"
-#include "sgcn.h"
-
-#define WIDTH 80
-#define HEIGHT 24
-
-/**
- * Virtual address mapped to SRAM.
- */
-static uintptr_t sram_virt_addr;
-
-/**
- * SGCN buffer offset within SGCN.
- */
-static uintptr_t sram_buffer_offset;
-
-/**
- * SGCN buffer header. It is placed at the very beginning of the SGCN
- * buffer. 
- */
-typedef struct {
-	/** hard-wired to "CON" */
-	char magic[4];
-	
-	/** we don't need this */
-	char unused[24];
-
-	/** offset within the SGCN buffer of the output buffer start */
-	uint32_t out_begin;
-	
-	/** offset within the SGCN buffer of the output buffer end */
-	uint32_t out_end;
-	
-	/** offset within the SGCN buffer of the output buffer read pointer */
-	uint32_t out_rdptr;
-	
-	/** offset within the SGCN buffer of the output buffer write pointer */
-	uint32_t out_wrptr;
-} __attribute__ ((packed)) sgcn_buffer_header_t;
-
-
-/*
- * Returns a pointer to the object of a given type which is placed at the given
- * offset from the console buffer beginning.
- */
-#define SGCN_BUFFER(type, offset) \
-		((type *) (sram_virt_addr + sram_buffer_offset + (offset)))
-
-/** Returns a pointer to the console buffer header. */
-#define SGCN_BUFFER_HEADER	(SGCN_BUFFER(sgcn_buffer_header_t, 0))
-
-/**
- * Pushes the character to the SGCN serial.
- * @param c	character to be pushed
- */
-static void sgcn_putc(char c)
-{
-	uint32_t begin = SGCN_BUFFER_HEADER->out_begin;
-	uint32_t end = SGCN_BUFFER_HEADER->out_end;
-	uint32_t size = end - begin;
-	
-	/* we need pointers to volatile variables */
-	volatile char *buf_ptr = (volatile char *)
-		SGCN_BUFFER(char, SGCN_BUFFER_HEADER->out_wrptr);
-	volatile uint32_t *out_wrptr_ptr = &(SGCN_BUFFER_HEADER->out_wrptr);
-	volatile uint32_t *out_rdptr_ptr = &(SGCN_BUFFER_HEADER->out_rdptr);
-
-	uint32_t new_wrptr = (((*out_wrptr_ptr) - begin + 1) % size) + begin;
-	while (*out_rdptr_ptr == new_wrptr)
-		;
-	*buf_ptr = c;
-	*out_wrptr_ptr = new_wrptr;
-}
-
-/**
- * Initializes the SGCN serial driver.
- */
-int sgcn_init(void)
-{
-	sysarg_t sram_paddr;
-	if (sysinfo_get_value("sram.address.physical", &sram_paddr) != EOK)
-		return -1;
-	
-	sysarg_t sram_size;
-	if (sysinfo_get_value("sram.area.size", &sram_size) != EOK)
-		return -1;
-	
-	if (sysinfo_get_value("sram.buffer.offset", &sram_buffer_offset) != EOK)
-		sram_buffer_offset = 0;
-	
-	sram_virt_addr = (uintptr_t) as_get_mappable_page(sram_size);
-	
-	if (physmem_map((void *) sram_paddr, (void *) sram_virt_addr,
-	    sram_size / PAGE_SIZE, AS_AREA_READ | AS_AREA_WRITE) != 0)
-		return -1;
-	
-	serial_console_init(sgcn_putc, WIDTH, HEIGHT);
-	
-	async_set_client_connection(serial_client_connection);
-	return 0;
-}
-
-/** 
- * @}
- */
- 
Index: pace/srv/hid/fb/sgcn.h
===================================================================
--- uspace/srv/hid/fb/sgcn.h	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ 	(revision )
@@ -1,46 +1,0 @@
-/*
- * Copyright (c) 2008 Pavel Rimsky
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/** @defgroup sgcnfb SGCN
- * @brief	userland driver of the Serengeti console output
- * @{
- */
- 
-/** @file
- */
-
-#ifndef FB_SGCN_H_
-#define FB_SGCN_H_
-
-int sgcn_init(void);
-
-#endif
-
-/** 
- * @}
- */
Index: uspace/srv/hid/input/Makefile
===================================================================
--- uspace/srv/hid/input/Makefile	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/srv/hid/input/Makefile	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -49,7 +49,5 @@
 	port/ns16550.c \
 	port/pl050.c \
-	port/sgcn.c \
 	port/ski.c \
-	port/z8530.c \
 	proto/adb.c \
 	proto/mousedev.c \
Index: uspace/srv/hid/input/generic/input.c
===================================================================
--- uspace/srv/hid/input/generic/input.c	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/srv/hid/input/generic/input.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -424,9 +424,5 @@
 	kbd_add_dev(&niagara_port, &stty_ctl);
 #endif
-#if defined(UARCH_sparc64) && defined(MACHINE_serengeti)
-	kbd_add_dev(&sgcn_port, &stty_ctl);
-#endif
 #if defined(UARCH_sparc64) && defined(MACHINE_generic)
-	kbd_add_dev(&z8530_port, &sun_ctl);
 	kbd_add_dev(&ns16550_port, &sun_ctl);
 #endif
@@ -556,5 +552,4 @@
 	printf("%s: HelenOS input service\n", NAME);
 	
-	sysarg_t fhc;
 	sysarg_t obio;
 	
@@ -562,6 +557,5 @@
 	list_initialize(&mouse_devs);
 	
-	if (((sysinfo_get_value("kbd.cir.fhc", &fhc) == EOK) && (fhc))
-	    || ((sysinfo_get_value("kbd.cir.obio", &obio) == EOK) && (obio)))
+	if ((sysinfo_get_value("kbd.cir.obio", &obio) == EOK) && (obio))
 		irc_service = true;
 	
Index: uspace/srv/hid/input/include/kbd_port.h
===================================================================
--- uspace/srv/hid/input/include/kbd_port.h	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/srv/hid/input/include/kbd_port.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -56,7 +56,5 @@
 extern kbd_port_ops_t ns16550_port;
 extern kbd_port_ops_t pl050_port;
-extern kbd_port_ops_t sgcn_port;
 extern kbd_port_ops_t ski_port;
-extern kbd_port_ops_t z8530_port;
 
 #endif
Index: uspace/srv/hid/input/port/niagara.c
===================================================================
--- uspace/srv/hid/input/port/niagara.c	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/srv/hid/input/port/niagara.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -154,5 +154,5 @@
 
 /**
- * Thread to poll SGCN for keypresses.
+ * Thread to poll Niagara console for keypresses.
  */
 static void niagara_thread_impl(void *arg)
Index: pace/srv/hid/input/port/sgcn.c
===================================================================
--- uspace/srv/hid/input/port/sgcn.c	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ 	(revision )
@@ -1,205 +1,0 @@
-/*
- * Copyright (c) 2008 Pavel Rimsky
- * Copyright (c) 2011 Jiri Svoboda
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/** @addtogroup kbd_port
- * @ingroup  kbd
- * @{
- */
-/** @file
- * @brief SGCN (Serengeti Console) keyboard port driver.
- */
-
-#include <as.h>
-#include <ddi.h>
-#include <async.h>
-#include <kbd.h>
-#include <kbd_port.h>
-#include <sysinfo.h>
-#include <stdio.h>
-#include <thread.h>
-#include <bool.h>
-#include <errno.h>
-
-static int sgcn_port_init(kbd_dev_t *);
-static void sgcn_port_yield(void);
-static void sgcn_port_reclaim(void);
-static void sgcn_port_write(uint8_t data);
-
-kbd_port_ops_t sgcn_port = {
-	.init = sgcn_port_init,
-	.yield = sgcn_port_yield,
-	.reclaim = sgcn_port_reclaim,
-	.write = sgcn_port_write
-};
-
-static kbd_dev_t *kbd_dev;
-
-#define POLL_INTERVAL  10000
-
-/**
- * SGCN buffer header. It is placed at the very beginning of the SGCN
- * buffer.
- */
-typedef struct {
-	/** hard-wired to "CON" */
-	char magic[4];
-	
-	/** we don't need this */
-	char unused[8];
-	
-	/** offset within the SGCN buffer of the input buffer start */
-	uint32_t in_begin;
-	
-	/** offset within the SGCN buffer of the input buffer end */
-	uint32_t in_end;
-	
-	/** offset within the SGCN buffer of the input buffer read pointer */
-	uint32_t in_rdptr;
-	
-	/** offset within the SGCN buffer of the input buffer write pointer */
-	uint32_t in_wrptr;
-} __attribute__ ((packed)) sgcn_buffer_header_t;
-
-/*
- * Returns a pointer to the object of a given type which is placed at the given
- * offset from the console buffer beginning.
- */
-#define SGCN_BUFFER(type, offset) \
-		((type *) (sram_virt_addr + sram_buffer_offset + (offset)))
-
-/** Returns a pointer to the console buffer header. */
-#define SGCN_BUFFER_HEADER	(SGCN_BUFFER(sgcn_buffer_header_t, 0))
-
-/**
- * Virtual address mapped to SRAM.
- */
-static uintptr_t sram_virt_addr;
-
-/**
- * SGCN buffer offset within SGCN.
- */
-static uintptr_t sram_buffer_offset;
-
-/* polling thread */
-static void sgcn_thread_impl(void *arg);
-
-static volatile bool polling_disabled = false;
-
-/**
- * Initializes the SGCN driver.
- * Maps the physical memory (SRAM) and creates the polling thread. 
- */
-static int sgcn_port_init(kbd_dev_t *kdev)
-{
-	kbd_dev = kdev;
-	
-	sysarg_t sram_paddr;
-	if (sysinfo_get_value("sram.address.physical", &sram_paddr) != EOK)
-		return -1;
-	
-	sysarg_t sram_size;
-	if (sysinfo_get_value("sram.area.size", &sram_size) != EOK)
-		return -1;
-	
-	if (sysinfo_get_value("sram.buffer.offset", &sram_buffer_offset) != EOK)
-		sram_buffer_offset = 0;
-	
-	sram_virt_addr = (uintptr_t) as_get_mappable_page(sram_size);
-	
-	if (physmem_map((void *) sram_paddr, (void *) sram_virt_addr,
-	    sram_size / PAGE_SIZE, AS_AREA_READ | AS_AREA_WRITE) != 0) {
-		printf("SGCN: uspace driver could not map physical memory.");
-		return -1;
-	}
-	
-	thread_id_t tid;
-	int rc = thread_create(sgcn_thread_impl, NULL, "kbd_poll", &tid);
-	if (rc != 0)
-		return rc;
-	
-	return 0;
-}
-
-static void sgcn_port_yield(void)
-{
-	polling_disabled = true;
-}
-
-static void sgcn_port_reclaim(void)
-{
-	polling_disabled = false;
-}
-
-static void sgcn_port_write(uint8_t data)
-{
-	(void) data;
-}
-
-/**
- * Handler of the "key pressed" event. Reads codes of all the pressed keys from
- * the buffer. 
- */
-static void sgcn_key_pressed(void)
-{
-	char c;
-	
-	uint32_t begin = SGCN_BUFFER_HEADER->in_begin;
-	uint32_t end = SGCN_BUFFER_HEADER->in_end;
-	uint32_t size = end - begin;
-	
-	volatile char *buf_ptr = (volatile char *)
-		SGCN_BUFFER(char, SGCN_BUFFER_HEADER->in_rdptr);
-	volatile uint32_t *in_wrptr_ptr = &(SGCN_BUFFER_HEADER->in_wrptr);
-	volatile uint32_t *in_rdptr_ptr = &(SGCN_BUFFER_HEADER->in_rdptr);
-	
-	while (*in_rdptr_ptr != *in_wrptr_ptr) {
-		c = *buf_ptr;
-		*in_rdptr_ptr = (((*in_rdptr_ptr) - begin + 1) % size) + begin;
-		buf_ptr = (volatile char *)
-		    SGCN_BUFFER(char, SGCN_BUFFER_HEADER->in_rdptr);
-		kbd_push_data(kbd_dev, c);
-	}
-}
-
-/**
- * Thread to poll SGCN for keypresses.
- */
-static void sgcn_thread_impl(void *arg)
-{
-	(void) arg;
-
-	while (1) {
-		if (polling_disabled == false)
-			sgcn_key_pressed();
-		usleep(POLL_INTERVAL);
-	}
-}
-
-/** @}
- */
Index: pace/srv/hid/input/port/z8530.c
===================================================================
--- uspace/srv/hid/input/port/z8530.c	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ 	(revision )
@@ -1,152 +1,0 @@
-/*
- * Copyright (c) 2006 Martin Decky
- * Copyright (c) 2011 Jiri Svoboda
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/** @addtogroup kbd_port
- * @ingroup  kbd
- * @{
- */
-/** @file
- * @brief Z8530 keyboard port driver.
- */
-
-#include <ipc/irc.h>
-#include <async.h>
-#include <async_obsolete.h>
-#include <sysinfo.h>
-#include <input.h>
-#include <kbd.h>
-#include <kbd_port.h>
-#include <sys/types.h>
-#include <ddi.h>
-#include <errno.h>
-
-static int z8530_port_init(kbd_dev_t *);
-static void z8530_port_yield(void);
-static void z8530_port_reclaim(void);
-static void z8530_port_write(uint8_t data);
-
-kbd_port_ops_t z8530_port = {
-	.init = z8530_port_init,
-	.yield = z8530_port_yield,
-	.reclaim = z8530_port_reclaim,
-	.write = z8530_port_write
-};
-
-static kbd_dev_t *kbd_dev;
-
-#define CHAN_A_STATUS  4
-#define CHAN_A_DATA    6
-
-#define RR0_RCA  1
-
-static irq_cmd_t z8530_cmds[] = {
-	{
-		.cmd = CMD_PIO_READ_8,
-		.addr = (void *) 0,     /* Will be patched in run-time */
-		.dstarg = 1
-	},
-	{
-		.cmd = CMD_BTEST,
-		.value = RR0_RCA,
-		.srcarg = 1,
-		.dstarg = 3
-	},
-	{
-		.cmd = CMD_PREDICATE,
-		.value = 2,
-		.srcarg = 3
-	},
-	{
-		.cmd = CMD_PIO_READ_8,
-		.addr = (void *) 0,     /* Will be patched in run-time */
-		.dstarg = 2
-	},
-	{
-		.cmd = CMD_ACCEPT
-	}
-};
-
-static irq_code_t z8530_kbd = {
-	sizeof(z8530_cmds) / sizeof(irq_cmd_t),
-	z8530_cmds
-};
-
-static void z8530_irq_handler(ipc_callid_t iid, ipc_call_t *call);
-
-static int z8530_port_init(kbd_dev_t *kdev)
-{
-	kbd_dev = kdev;
-	
-	sysarg_t z8530;
-	if (sysinfo_get_value("kbd.type.z8530", &z8530) != EOK)
-		return -1;
-	if (!z8530)
-		return -1;
-	
-	sysarg_t kaddr;
-	if (sysinfo_get_value("kbd.address.kernel", &kaddr) != EOK)
-		return -1;
-	
-	sysarg_t inr;
-	if (sysinfo_get_value("kbd.inr", &inr) != EOK)
-		return -1;
-	
-	z8530_cmds[0].addr = (void *) kaddr + CHAN_A_STATUS;
-	z8530_cmds[3].addr = (void *) kaddr + CHAN_A_DATA;
-	
-	async_set_interrupt_received(z8530_irq_handler);
-	register_irq(inr, device_assign_devno(), inr, &z8530_kbd);
-	
-	return 0;
-}
-
-static void z8530_port_yield(void)
-{
-}
-
-static void z8530_port_reclaim(void)
-{
-}
-
-static void z8530_port_write(uint8_t data)
-{
-	(void) data;
-}
-
-static void z8530_irq_handler(ipc_callid_t iid, ipc_call_t *call)
-{
-	kbd_push_data(kbd_dev, IPC_GET_ARG2(*call));
-	
-	if (irc_service)
-		async_obsolete_msg_1(irc_phone, IRC_CLEAR_INTERRUPT,
-		    IPC_GET_IMETHOD(*call));
-}
-
-/** @}
- */
Index: pace/srv/hw/irc/fhc/Makefile
===================================================================
--- uspace/srv/hw/irc/fhc/Makefile	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ 	(revision )
@@ -1,36 +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 = ../../../..
-BINARY = fhc
-
-SOURCES = \
-	fhc.c
-
-include $(USPACE_PREFIX)/Makefile.common
Index: pace/srv/hw/irc/fhc/fhc.c
===================================================================
--- uspace/srv/hw/irc/fhc/fhc.c	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ 	(revision )
@@ -1,161 +1,0 @@
-/*
- * Copyright (c) 2009 Jakub Jermar
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/** @addtogroup fhc
- * @{
- */
-
-/**
- * @file fhc.c
- * @brief FHC bus controller driver.
- */
-
-#include <ipc/services.h>
-#include <ipc/irc.h>
-#include <ns.h>
-#include <sysinfo.h>
-#include <as.h>
-#include <ddi.h>
-#include <align.h>
-#include <bool.h>
-#include <errno.h>
-#include <async.h>
-#include <align.h>
-#include <async.h>
-#include <stdio.h>
-#include <ipc/devmap.h>
-
-#define NAME "fhc"
-
-#define FHC_UART_INR	0x39
-
-#define FHC_UART_IMAP	0x0
-#define FHC_UART_ICLR	0x4
-
-static void *fhc_uart_phys;
-static volatile uint32_t *fhc_uart_virt;
-static size_t fhc_uart_size;
-
-/** Handle one connection to fhc.
- *
- * @param iid		Hash of the request that opened the connection.
- * @param icall		Call data of the request that opened the connection.
- * @param arg		Local argument.
- */
-static void fhc_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg)
-{
-	ipc_callid_t callid;
-	ipc_call_t call;
-
-	/*
-	 * Answer the first IPC_M_CONNECT_ME_TO call.
-	 */
-	async_answer_0(iid, EOK);
-
-	while (1) {
-		int inr;
-	
-		callid = async_get_call(&call);
-		switch (IPC_GET_IMETHOD(call)) {
-		case IRC_ENABLE_INTERRUPT:
-			/* Noop */
-			async_answer_0(callid, EOK);
-			break;
-		case IRC_CLEAR_INTERRUPT:
-			inr = IPC_GET_ARG1(call);
-			switch (inr) {
-			case FHC_UART_INR:
-				fhc_uart_virt[FHC_UART_ICLR] = 0;
-				async_answer_0(callid, EOK);
-				break;
-			default:
-				async_answer_0(callid, ENOTSUP);
-				break;
-			}
-			break;
-		default:
-			async_answer_0(callid, EINVAL);
-			break;
-		}
-	}
-}
-
-/** Initialize the FHC driver.
- *
- * So far, the driver heavily depends on information provided by the kernel via
- * sysinfo. In the future, there should be a standalone FHC driver.
- */
-static bool fhc_init(void)
-{
-	sysarg_t paddr;
-
-	if ((sysinfo_get_value("fhc.uart.physical", &paddr) != EOK)
-	    || (sysinfo_get_value("fhc.uart.size", &fhc_uart_size) != EOK)) {
-		printf(NAME ": no FHC UART registers found\n");
-		return false;
-	}
-	
-	fhc_uart_phys = (void *) paddr;
-	fhc_uart_virt = as_get_mappable_page(fhc_uart_size);
-	
-	int flags = AS_AREA_READ | AS_AREA_WRITE;
-	int retval = physmem_map(fhc_uart_phys, (void *) fhc_uart_virt,
-	    ALIGN_UP(fhc_uart_size, PAGE_SIZE) >> PAGE_WIDTH, flags);
-	
-	if (retval < 0) {
-		printf("%s: Error mapping FHC UART registers\n", NAME);
-		return false;
-	}
-	
-	printf("%s: FHC UART registers at %p, %zu bytes\n", NAME,
-	    fhc_uart_phys, fhc_uart_size);
-	
-	async_set_client_connection(fhc_connection);
-	service_register(SERVICE_IRC);
-	
-	return true;
-}
-
-int main(int argc, char **argv)
-{
-	printf("%s: HelenOS FHC bus controller driver\n", NAME);
-	
-	if (!fhc_init())
-		return -1;
-	
-	printf("%s: Accepting connections\n", NAME);
-	task_retval(0);
-	async_manager();
-	
-	/* Never reached */
-	return 0;
-}
-
-/**
- * @}
- */
Index: uspace/srv/hw/netif/ne2000/ne2000.c
===================================================================
--- uspace/srv/hw/netif/ne2000/ne2000.c	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/srv/hw/netif/ne2000/ne2000.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -38,5 +38,4 @@
 #include <assert.h>
 #include <async.h>
-#include <async_obsolete.h>
 #include <ddi.h>
 #include <errno.h>
@@ -44,7 +43,6 @@
 #include <malloc.h>
 #include <sysinfo.h>
+#include <ns.h>
 #include <ipc/services.h>
-#include <ns.h>
-#include <ns_obsolete.h>
 #include <ipc/irc.h>
 #include <net/modules.h>
@@ -78,5 +76,5 @@
 
 static bool irc_service = false;
-static int irc_phone = -1;
+static async_sess_t *irc_sess = NULL;
 
 /** NE2000 kernel interrupt command sequence.
@@ -154,13 +152,14 @@
 	device_id_t device_id = IRQ_GET_DEVICE(*call);
 	netif_device_t *device;
-	int nil_phone;
+	async_sess_t *nil_sess;
 	ne2k_t *ne2k;
 	
 	fibril_rwlock_read_lock(&netif_globals.lock);
 	
-	if (find_device(device_id, &device) == EOK) {
-		nil_phone = device->nil_phone;
+	nil_sess = netif_globals.nil_sess;
+	
+	if (find_device(device_id, &device) == EOK)
 		ne2k = (ne2k_t *) device->specific;
-	} else
+	else
 		ne2k = NULL;
 	
@@ -177,6 +176,6 @@
 				
 				list_remove(&frame->link);
-				nil_received_msg(nil_phone, device_id,
-				    frame->packet, SERVICE_NONE);
+				nil_received_msg(nil_sess, device_id, frame->packet,
+				    SERVICE_NONE);
 				free(frame);
 			}
@@ -278,5 +277,4 @@
 	
 	device->device_id = device_id;
-	device->nil_phone = -1;
 	device->specific = (void *) ne2k;
 	device->state = NETIF_STOPPED;
@@ -331,6 +329,9 @@
 		change_state(device, NETIF_ACTIVE);
 		
-		if (irc_service)
-			async_obsolete_msg_1(irc_phone, IRC_ENABLE_INTERRUPT, ne2k->irq);
+		if (irc_service) {
+			async_exch_t *exch = async_exchange_begin(irc_sess);
+			async_msg_1(exch, IRC_ENABLE_INTERRUPT, ne2k->irq);
+			async_exchange_end(exch);
+		}
 	}
 	
@@ -390,6 +391,7 @@
 	
 	if (irc_service) {
-		while (irc_phone < 0)
-			irc_phone = service_obsolete_connect_blocking(SERVICE_IRC, 0, 0);
+		while (!irc_sess)
+			irc_sess = service_connect_blocking(EXCHANGE_SERIALIZE,
+			    SERVICE_IRC, 0, 0);
 	}
 	
Index: uspace/srv/net/il/arp/arp.c
===================================================================
--- uspace/srv/net/il/arp/arp.c	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/srv/net/il/arp/arp.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -164,5 +164,5 @@
 }
 
-static int arp_clean_cache_req(int arp_phone)
+static int arp_clean_cache_req(void)
 {
 	int count;
@@ -190,6 +190,6 @@
 }
 
-static int arp_clear_address_req(int arp_phone, device_id_t device_id,
-    services_t protocol, measured_string_t *address)
+static int arp_clear_address_req(device_id_t device_id, services_t protocol,
+    measured_string_t *address)
 {
 	fibril_mutex_lock(&arp_globals.lock);
@@ -218,5 +218,5 @@
 }
 
-static int arp_clear_device_req(int arp_phone, device_id_t device_id)
+static int arp_clear_device_req(device_id_t device_id)
 {
 	fibril_mutex_lock(&arp_globals.lock);
@@ -375,5 +375,5 @@
 				return rc;
 			
-			nil_send_msg(device->phone, device_id, packet,
+			nil_send_msg(device->sess, device_id, packet,
 			    SERVICE_ARP);
 			return 1;
@@ -416,5 +416,6 @@
  * @param[in]     iid   Message identifier.
  * @param[in,out] icall Message parameters.
- * @param[in]	  arg	Local argument.
+ * @param[in]     arg   Local argument.
+ *
  */
 static void arp_receiver(ipc_callid_t iid, ipc_call_t *icall, void *arg)
@@ -431,5 +432,5 @@
 		
 		case NET_IL_RECEIVED:
-			rc = packet_translate_remote(arp_globals.net_phone, &packet,
+			rc = packet_translate_remote(arp_globals.net_sess, &packet,
 			    IPC_GET_PACKET(*icall));
 			if (rc == EOK) {
@@ -439,5 +440,5 @@
 					rc = arp_receive_message(IPC_GET_DEVICE(*icall), packet);
 					if (rc != 1) {
-						pq_release_remote(arp_globals.net_phone,
+						pq_release_remote(arp_globals.net_sess,
 						    packet_get_id(packet));
 					}
@@ -564,8 +565,8 @@
 		
 		/* Bind */
-		device->phone = nil_bind_service(device->service,
+		device->sess = nil_bind_service(device->service,
 		    (sysarg_t) device->device_id, SERVICE_ARP,
 		    arp_receiver);
-		if (device->phone < 0) {
+		if (device->sess == NULL) {
 			fibril_mutex_unlock(&arp_globals.lock);
 			arp_protos_destroy(&device->protos, free);
@@ -575,5 +576,5 @@
 		
 		/* Get packet dimensions */
-		rc = nil_packet_size_req(device->phone, device_id,
+		rc = nil_packet_size_req(device->sess, device_id,
 		    &device->packet_dimension);
 		if (rc != EOK) {
@@ -585,5 +586,5 @@
 		
 		/* Get hardware address */
-		rc = nil_get_addr_req(device->phone, device_id, &device->addr,
+		rc = nil_get_addr_req(device->sess, device_id, &device->addr,
 		    &device->addr_data);
 		if (rc != EOK) {
@@ -595,5 +596,5 @@
 		
 		/* Get broadcast address */
-		rc = nil_get_broadcast_addr_req(device->phone, device_id,
+		rc = nil_get_broadcast_addr_req(device->sess, device_id,
 		    &device->broadcast_addr, &device->broadcast_data);
 		if (rc != EOK) {
@@ -627,10 +628,10 @@
 }
 
-int il_initialize(int net_phone)
+int il_initialize(async_sess_t *net_sess)
 {
 	fibril_mutex_initialize(&arp_globals.lock);
 	
 	fibril_mutex_lock(&arp_globals.lock);
-	arp_globals.net_phone = net_phone;
+	arp_globals.net_sess = net_sess;
 	int rc = arp_cache_initialize(&arp_globals.cache);
 	fibril_mutex_unlock(&arp_globals.lock);
@@ -647,5 +648,5 @@
 		return ELIMIT;
 	
-	packet_t *packet = packet_get_4_remote(arp_globals.net_phone,
+	packet_t *packet = packet_get_4_remote(arp_globals.net_sess,
 	    device->packet_dimension.addr_len, device->packet_dimension.prefix,
 	    length, device->packet_dimension.suffix);
@@ -655,5 +656,5 @@
 	arp_header_t *header = (arp_header_t *) packet_suffix(packet, length);
 	if (!header) {
-		pq_release_remote(arp_globals.net_phone, packet_get_id(packet));
+		pq_release_remote(arp_globals.net_sess, packet_get_id(packet));
 		return ENOMEM;
 	}
@@ -680,9 +681,9 @@
 	    (uint8_t *) device->broadcast_addr->value, device->addr->length);
 	if (rc != EOK) {
-		pq_release_remote(arp_globals.net_phone, packet_get_id(packet));
+		pq_release_remote(arp_globals.net_sess, packet_get_id(packet));
 		return rc;
 	}
 	
-	nil_send_msg(device->phone, device_id, packet, SERVICE_ARP);
+	nil_send_msg(device->sess, device_id, packet, SERVICE_ARP);
 	return EOK;
 }
@@ -890,5 +891,5 @@
 	
 	case NET_ARP_CLEAR_DEVICE:
-		return arp_clear_device_req(0, IPC_GET_DEVICE(*call));
+		return arp_clear_device_req(IPC_GET_DEVICE(*call));
 	
 	case NET_ARP_CLEAR_ADDRESS:
@@ -897,5 +898,5 @@
 			return rc;
 		
-		arp_clear_address_req(0, IPC_GET_DEVICE(*call),
+		arp_clear_address_req(IPC_GET_DEVICE(*call),
 		    IPC_GET_SERVICE(*call), address);
 		free(address);
@@ -904,5 +905,5 @@
 	
 	case NET_ARP_CLEAN_CACHE:
-		return arp_clean_cache_req(0);
+		return arp_clean_cache_req();
 	}
 	
Index: uspace/srv/net/il/arp/arp.h
===================================================================
--- uspace/srv/net/il/arp/arp.h	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/srv/net/il/arp/arp.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -38,4 +38,5 @@
 #define NET_ARP_H_
 
+#include <async.h>
 #include <fibril_synch.h>
 #include <ipc/services.h>
@@ -104,6 +105,6 @@
 	/** Packet dimension. */
 	packet_dimension_t packet_dimension;
-	/** Device module phone. */
-	int phone;
+	/** Device module session. */
+	async_sess_t *sess;
 	
 	/**
@@ -122,6 +123,7 @@
 	arp_cache_t cache;
 	
-	/** Networking module phone. */
-	int net_phone;
+	/** Networking module session. */
+	async_sess_t *net_sess;
+	
 	/** Safety lock. */
 	fibril_mutex_t lock;
Index: uspace/srv/net/il/ip/ip.c
===================================================================
--- uspace/srv/net/il/ip/ip.c	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/srv/net/il/ip/ip.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -77,7 +77,4 @@
 #include <il_skel.h>
 
-// FIXME: remove this header
-#include <kernel/ipc/ipc_methods.h>
-
 /** IP module name. */
 #define NAME			"ip"
@@ -125,33 +122,34 @@
 static void ip_receiver(ipc_callid_t, ipc_call_t *, void *);
 
-/** 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.
+/** Release the packet and returns the result.
+ *
+ * @param[in] packet Packet queue to be released.
+ * @param[in] result Result to be returned.
+ *
+ * @return Result parameter.
+ *
  */
 static int ip_release_and_return(packet_t *packet, int result)
 {
-	pq_release_remote(ip_globals.net_phone, packet_get_id(packet));
+	pq_release_remote(ip_globals.net_sess, packet_get_id(packet));
 	return result;
 }
 
-/** Returns the ICMP phone.
- *
- * Searches the registered protocols.
- *
- * @return		The found ICMP phone.
- * @return		ENOENT if the ICMP is not registered.
- */
-static int ip_get_icmp_phone(void)
-{
-	ip_proto_t *proto;
-	int phone;
-
+/** Return the ICMP session.
+ *
+ * Search the registered protocols.
+ *
+ * @return Found ICMP session.
+ * @return NULL if the ICMP is not registered.
+ *
+ */
+static async_sess_t *ip_get_icmp_session(void)
+{
 	fibril_rwlock_read_lock(&ip_globals.protos_lock);
-	proto = ip_protos_find(&ip_globals.protos, IPPROTO_ICMP);
-	phone = proto ? proto->phone : ENOENT;
+	ip_proto_t *proto = ip_protos_find(&ip_globals.protos, IPPROTO_ICMP);
+	async_sess_t *sess = proto ? proto->sess : NULL;
 	fibril_rwlock_read_unlock(&ip_globals.protos_lock);
-	return phone;
+	
+	return sess;
 }
 
@@ -182,5 +180,5 @@
 	next = pq_detach(packet);
 	if (next)
-		pq_release_remote(ip_globals.net_phone, packet_get_id(next));
+		pq_release_remote(ip_globals.net_sess, packet_get_id(next));
 
 	if (!header) {
@@ -221,30 +219,33 @@
 }
 
-/** Prepares the ICMP notification packet.
- *
- * Releases additional packets and keeps only the first one.
+/** Prepare the ICMP notification packet.
+ *
+ * Release additional packets and keep only the first one.
  * All packets are released on error.
  *
- * @param[in] error	The packet error service.
- * @param[in] packet	The packet or the packet queue to be reported as faulty.
- * @param[in] header	The first packet IP header. May be NULL.
- * @return		The found ICMP phone.
- * @return		EINVAL if the error parameter is set.
- * @return		EINVAL if the ICMP phone is not found.
- * @return		EINVAL if the ip_prepare_icmp() fails.
- */
-static int
-ip_prepare_icmp_and_get_phone(services_t error, packet_t *packet,
-    ip_header_t *header)
-{
-	int phone;
-
-	phone = ip_get_icmp_phone();
-	if (error || (phone < 0) || ip_prepare_icmp(packet, header))
-		return ip_release_and_return(packet, EINVAL);
-	return phone;
-}
-
-int il_initialize(int net_phone)
+ * @param[in] error  Packet error service.
+ * @param[in] packet Packet or the packet queue to be reported as faulty.
+ * @param[in] header First packet IP header. May be NULL.
+ *
+ * @return Found ICMP session.
+ * @return NULL if the error parameter is set.
+ * @return NULL if the ICMP session is not found.
+ * @return NULL if the ip_prepare_icmp() fails.
+ *
+ */
+static async_sess_t *ip_prepare_icmp_and_get_session(services_t error,
+    packet_t *packet, ip_header_t *header)
+{
+	async_sess_t *sess = ip_get_icmp_session();
+	
+	if ((error) || (!sess) || (ip_prepare_icmp(packet, header))) {
+		pq_release_remote(ip_globals.net_sess, packet_get_id(packet));
+		return NULL;
+	}
+	
+	return sess;
+}
+
+int il_initialize(async_sess_t *net_sess)
 {
 	fibril_rwlock_initialize(&ip_globals.lock);
@@ -253,5 +254,5 @@
 	fibril_rwlock_initialize(&ip_globals.netifs_lock);
 	
-	ip_globals.net_phone = net_phone;
+	ip_globals.net_sess = net_sess;
 	ip_globals.packet_counter = 0;
 	ip_globals.gateway.address.s_addr = 0;
@@ -355,5 +356,5 @@
 
 	/* Get configuration */
-	rc = net_get_device_conf_req(ip_globals.net_phone, ip_netif->device_id,
+	rc = net_get_device_conf_req(ip_globals.net_sess, ip_netif->device_id,
 	    &configuration, count, &data);
 	if (rc != EOK)
@@ -423,11 +424,11 @@
 
 	/* Bind netif service which also initializes the device */
-	ip_netif->phone = nil_bind_service(ip_netif->service,
+	ip_netif->sess = nil_bind_service(ip_netif->service,
 	    (sysarg_t) ip_netif->device_id, SERVICE_IP,
 	    ip_receiver);
-	if (ip_netif->phone < 0) {
+	if (ip_netif->sess == NULL) {
 		printf("Failed to contact the nil service %d\n",
 		    ip_netif->service);
-		return ip_netif->phone;
+		return ENOENT;
 	}
 
@@ -438,5 +439,5 @@
 			address.length = sizeof(in_addr_t);
 			
-			rc = arp_device_req(ip_netif->arp->phone,
+			rc = arp_device_req(ip_netif->arp->sess,
 			    ip_netif->device_id, SERVICE_IP, ip_netif->service,
 			    &address);
@@ -449,5 +450,5 @@
 
 	/* Get packet dimensions */
-	rc = nil_packet_size_req(ip_netif->phone, ip_netif->device_id,
+	rc = nil_packet_size_req(ip_netif->sess, ip_netif->device_id,
 	    &ip_netif->packet_dimension);
 	if (rc != EOK)
@@ -481,6 +482,5 @@
 }
 
-static int ip_device_req_local(int il_phone, device_id_t device_id,
-    services_t netif)
+static int ip_device_req_local(device_id_t device_id, services_t netif)
 {
 	ip_netif_t *ip_netif;
@@ -516,6 +516,6 @@
 
 	/* Print the settings */
-	printf("%s: Device registered (id: %d, phone: %d, ipv: %d, conf: %s)\n",
-	    NAME, ip_netif->device_id, ip_netif->phone, ip_netif->ipv,
+	printf("%s: Device registered (id: %d, ipv: %d, conf: %s)\n",
+	    NAME, ip_netif->device_id, ip_netif->ipv,
 	    ip_netif->dhcp ? "dhcp" : "static");
 	
@@ -932,5 +932,5 @@
 
 	/* Create the last fragment */
-	new_packet = packet_get_4_remote(ip_globals.net_phone, prefix, length,
+	new_packet = packet_get_4_remote(ip_globals.net_sess, prefix, length,
 	    suffix, ((addrlen > addr_len) ? addrlen : addr_len));
 	if (!new_packet)
@@ -969,5 +969,5 @@
 	/* Create middle fragments */
 	while (IP_TOTAL_LENGTH(header) > length) {
-		new_packet = packet_get_4_remote(ip_globals.net_phone, prefix,
+		new_packet = packet_get_4_remote(ip_globals.net_sess, prefix,
 		    length, suffix,
 		    ((addrlen >= addr_len) ? addrlen : addr_len));
@@ -994,21 +994,22 @@
 }
 
-/** Checks the packet queue lengths and fragments the packets if needed.
+/** Check the packet queue lengths and fragments the packets if needed.
  *
  * The ICMP_FRAG_NEEDED error notification may be sent if the packet needs to
  * be fragmented and the fragmentation is not allowed.
  *
- * @param[in,out] packet The packet or the packet queue to be checked.
- * @param[in] prefix	The minimum prefix size.
- * @param[in] content	The maximum content size.
- * @param[in] suffix	The minimum suffix size.
- * @param[in] addr_len	The minimum address length.
- * @param[in] error	The error module service.
- * @return		The packet or the packet queue of the allowed length.
- * @return		NULL if there are no packets left.
- */
-static packet_t *
-ip_split_packet(packet_t *packet, size_t prefix, size_t content, size_t suffix,
-    socklen_t addr_len, services_t error)
+ * @param[in,out] packet   Packet or the packet queue to be checked.
+ * @param[in]     prefix   Minimum prefix size.
+ * @param[in]     content  Maximum content size.
+ * @param[in]     suffix   Minimum suffix size.
+ * @param[in]     addr_len Minimum address length.
+ * @param[in]     error    Error module service.
+ *
+ * @return The packet or the packet queue of the allowed length.
+ * @return NULL if there are no packets left.
+ *
+ */
+static packet_t *ip_split_packet(packet_t *packet, size_t prefix, size_t content,
+    size_t suffix, socklen_t addr_len, services_t error)
 {
 	size_t length;
@@ -1016,6 +1017,6 @@
 	packet_t *new_packet;
 	int result;
-	int phone;
-
+	async_sess_t *sess;
+	
 	next = packet;
 	/* Check all packets */
@@ -1039,13 +1040,12 @@
 			/* Fragmentation needed? */
 			if (result == EPERM) {
-				phone = ip_prepare_icmp_and_get_phone(
-				    error, next, NULL);
-				if (phone >= 0) {
+				sess = ip_prepare_icmp_and_get_session(error, next, NULL);
+				if (sess) {
 					/* Fragmentation necessary ICMP */
-					icmp_destination_unreachable_msg(phone,
+					icmp_destination_unreachable_msg(sess,
 					    ICMP_FRAG_NEEDED, content, next);
 				}
 			} else {
-				pq_release_remote(ip_globals.net_phone,
+				pq_release_remote(ip_globals.net_sess,
 				    packet_get_id(next));
 			}
@@ -1061,20 +1061,20 @@
 }
 
-/** Sends the packet or the packet queue via the specified route.
+/** Send the packet or the packet queue via the specified route.
  *
  * The ICMP_HOST_UNREACH error notification may be sent if route hardware
  * destination address is found.
  *
- * @param[in,out] packet The packet to be sent.
- * @param[in] netif	The target network interface.
- * @param[in] route	The target route.
- * @param[in] src	The source address.
- * @param[in] dest	The destination address.
- * @param[in] error	The error module service.
- * @return		EOK on success.
- * @return		Other error codes as defined for the arp_translate_req()
- *			function.
- * @return		Other error codes as defined for the ip_prepare_packet()
- *			function.
+ * @param[in,out] packet Packet to be sent.
+ * @param[in]     netif  Target network interface.
+ * @param[in]     route  Target route.
+ * @param[in]     src    Source address.
+ * @param[in]     dest   Destination address.
+ * @param[in]     error  Error module service.
+ *
+ * @return EOK on success.
+ * @return Other error codes as defined for arp_translate_req().
+ * @return Other error codes as defined for ip_prepare_packet().
+ *
  */
 static int ip_send_route(packet_t *packet, ip_netif_t *netif,
@@ -1084,5 +1084,5 @@
 	measured_string_t *translation;
 	uint8_t *data;
-	int phone;
+	async_sess_t *sess;
 	int rc;
 
@@ -1093,8 +1093,8 @@
 		destination.length = sizeof(dest.s_addr);
 
-		rc = arp_translate_req(netif->arp->phone, netif->device_id,
+		rc = arp_translate_req(netif->arp->sess, netif->device_id,
 		    SERVICE_IP, &destination, &translation, &data);
 		if (rc != EOK) {
-			pq_release_remote(ip_globals.net_phone,
+			pq_release_remote(ip_globals.net_sess,
 			    packet_get_id(packet));
 			return rc;
@@ -1106,9 +1106,9 @@
 				free(data);
 			}
-			phone = ip_prepare_icmp_and_get_phone(error, packet,
+			sess = ip_prepare_icmp_and_get_session(error, packet,
 			    NULL);
-			if (phone >= 0) {
+			if (sess) {
 				/* Unreachable ICMP if no routing */
-				icmp_destination_unreachable_msg(phone,
+				icmp_destination_unreachable_msg(sess,
 				    ICMP_HOST_UNREACH, 0, packet);
 			}
@@ -1122,5 +1122,5 @@
 	rc = ip_prepare_packet(src, dest, packet, translation);
 	if (rc != EOK) {
-		pq_release_remote(ip_globals.net_phone, packet_get_id(packet));
+		pq_release_remote(ip_globals.net_sess, packet_get_id(packet));
 	} else {
 		packet = ip_split_packet(packet, netif->packet_dimension.prefix,
@@ -1129,5 +1129,5 @@
 		    netif->packet_dimension.addr_len, error);
 		if (packet) {
-			nil_send_msg(netif->phone, netif->device_id, packet,
+			nil_send_msg(netif->sess, netif->device_id, packet,
 			    SERVICE_IP);
 		}
@@ -1142,6 +1142,6 @@
 }
 
-static int ip_send_msg_local(int il_phone, device_id_t device_id,
-    packet_t *packet, services_t sender, services_t error)
+static int ip_send_msg_local(device_id_t device_id, packet_t *packet,
+    services_t sender, services_t error)
 {
 	int addrlen;
@@ -1152,5 +1152,5 @@
 	in_addr_t *dest;
 	in_addr_t *src;
-	int phone;
+	async_sess_t *sess;
 	int rc;
 
@@ -1197,8 +1197,8 @@
 	if (!netif || !route) {
 		fibril_rwlock_read_unlock(&ip_globals.netifs_lock);
-		phone = ip_prepare_icmp_and_get_phone(error, packet, NULL);
-		if (phone >= 0) {
+		sess = ip_prepare_icmp_and_get_session(error, packet, NULL);
+		if (sess) {
 			/* Unreachable ICMP if no routing */
-			icmp_destination_unreachable_msg(phone,
+			icmp_destination_unreachable_msg(sess,
 			    ICMP_NET_UNREACH, 0, packet);
 		}
@@ -1228,9 +1228,9 @@
 		if (!netif || !route) {
 			fibril_rwlock_read_unlock(&ip_globals.netifs_lock);
-			phone = ip_prepare_icmp_and_get_phone(error, packet,
+			sess = ip_prepare_icmp_and_get_session(error, packet,
 			    NULL);
-			if (phone >= 0) {
+			if (sess) {
 				/* Unreachable ICMP if no routing */
-				icmp_destination_unreachable_msg(phone,
+				icmp_destination_unreachable_msg(sess,
 				    ICMP_HOST_UNREACH, 0, packet);
 			}
@@ -1316,5 +1316,5 @@
 {
 	ip_proto_t *proto;
-	int phone;
+	async_sess_t *sess;
 	services_t service;
 	tl_received_msg_t received_msg;
@@ -1369,8 +1369,8 @@
 	if (!proto) {
 		fibril_rwlock_read_unlock(&ip_globals.protos_lock);
-		phone = ip_prepare_icmp_and_get_phone(error, packet, header);
-		if (phone >= 0) {
+		sess = ip_prepare_icmp_and_get_session(error, packet, header);
+		if (sess) {
 			/* Unreachable ICMP */
-			icmp_destination_unreachable_msg(phone,
+			icmp_destination_unreachable_msg(sess,
 			    ICMP_PROT_UNREACH, 0, packet);
 		}
@@ -1384,5 +1384,5 @@
 		rc = received_msg(device_id, packet, service, error);
 	} else {
-		rc = tl_received_msg(proto->phone, device_id, packet,
+		rc = tl_received_msg(proto->sess, device_id, packet,
 		    proto->service, error);
 		fibril_rwlock_read_unlock(&ip_globals.protos_lock);
@@ -1418,5 +1418,5 @@
 	in_addr_t dest;
 	ip_route_t *route;
-	int phone;
+	async_sess_t *sess;
 	struct sockaddr *addr;
 	struct sockaddr_in addr_in;
@@ -1431,8 +1431,8 @@
 	if ((header->header_checksum) &&
 	    (IP_HEADER_CHECKSUM(header) != IP_CHECKSUM_ZERO)) {
-		phone = ip_prepare_icmp_and_get_phone(0, packet, header);
-		if (phone >= 0) {
+		sess = ip_prepare_icmp_and_get_session(0, packet, header);
+		if (sess) {
 			/* Checksum error ICMP */
-			icmp_parameter_problem_msg(phone, ICMP_PARAM_POINTER,
+			icmp_parameter_problem_msg(sess, ICMP_PARAM_POINTER,
 			    ((size_t) ((void *) &header->header_checksum)) -
 			    ((size_t) ((void *) header)), packet);
@@ -1442,8 +1442,8 @@
 
 	if (header->ttl <= 1) {
-		phone = ip_prepare_icmp_and_get_phone(0, packet, header);
-		if (phone >= 0) {
+		sess = ip_prepare_icmp_and_get_session(0, packet, header);
+		if (sess) {
 			/* TTL exceeded ICMP */
-			icmp_time_exceeded_msg(phone, ICMP_EXC_TTL, packet);
+			icmp_time_exceeded_msg(sess, ICMP_EXC_TTL, packet);
 		}
 		return EINVAL;
@@ -1473,8 +1473,8 @@
 	route = ip_find_route(dest);
 	if (!route) {
-		phone = ip_prepare_icmp_and_get_phone(0, packet, header);
-		if (phone >= 0) {
+		sess = ip_prepare_icmp_and_get_session(0, packet, header);
+		if (sess) {
 			/* Unreachable ICMP */
-			icmp_destination_unreachable_msg(phone,
+			icmp_destination_unreachable_msg(sess,
 			    ICMP_HOST_UNREACH, 0, packet);
 		}
@@ -1493,8 +1493,8 @@
 	}
 
-	phone = ip_prepare_icmp_and_get_phone(0, packet, header);
-	if (phone >= 0) {
+	sess = ip_prepare_icmp_and_get_session(0, packet, header);
+	if (sess) {
 		/* Unreachable ICMP if no routing */
-		icmp_destination_unreachable_msg(phone, ICMP_HOST_UNREACH, 0,
+		icmp_destination_unreachable_msg(sess, ICMP_HOST_UNREACH, 0,
 		    packet);
 	}
@@ -1503,14 +1503,14 @@
 }
 
-/** Returns the device packet dimensions 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] addr_len	The minimum reserved address length.
- * @param[out] prefix	The minimum reserved prefix size.
- * @param[out] content	The maximum content size.
- * @param[out] suffix	The minimum reserved suffix size.
- * @return		EOK on success.
+/** Return the device packet dimensions for sending.
+ *
+ * @param[in]  device_id Device identifier.
+ * @param[out] addr_len  Minimum reserved address length.
+ * @param[out] prefix    Minimum reserved prefix size.
+ * @param[out] content   Maximum content size.
+ * @param[out] suffix    Minimum reserved suffix size.
+ *
+ * @return EOK on success.
+ *
  */
 static int ip_packet_size_message(device_id_t device_id, size_t *addr_len,
@@ -1595,4 +1595,5 @@
  * @param[in,out] icall Message parameters.
  * @param[in]     arg   Local argument.
+ *
  */
 static void ip_receiver(ipc_callid_t iid, ipc_call_t *icall, void *arg)
@@ -1610,5 +1611,5 @@
 		
 		case NET_IL_RECEIVED:
-			rc = packet_translate_remote(ip_globals.net_phone, &packet,
+			rc = packet_translate_remote(ip_globals.net_sess, &packet,
 			    IPC_GET_PACKET(*icall));
 			if (rc == EOK) {
@@ -1637,22 +1638,23 @@
 }
 
-/** Registers the transport layer protocol.
+/** Register the transport layer protocol.
  *
  * The traffic of this protocol will be supplied using either the receive
  * function or IPC message.
  *
- * @param[in] protocol	The transport layer module protocol.
- * @param[in] service	The transport layer module service.
- * @param[in] phone	The transport layer module phone.
- * @param[in] received_msg The receiving function.
- * @return		EOK on success.
- * @return		EINVAL if the protocol parameter and/or the service
- *			parameter is zero.
- * @return		EINVAL if the phone parameter is not a positive number
- *			and the tl_receive_msg is NULL.
- * @return		ENOMEM if there is not enough memory left.
- */
-static int
-ip_register(int protocol, services_t service, int phone,
+ * @param[in] protocol     Transport layer module protocol.
+ * @param[in] service      Transport layer module service.
+ * @param[in] sess         Transport layer module session.
+ * @param[in] received_msg Receiving function.
+ *
+ * @return EOK on success.
+ * @return EINVAL if the protocol parameter and/or the service
+ *         parameter is zero.
+ * @return EINVAL if the phone parameter is not a positive number
+ *         and the tl_receive_msg is NULL.
+ * @return ENOMEM if there is not enough memory left.
+ *
+ */
+static int ip_register(int protocol, services_t service, async_sess_t *sess,
     tl_received_msg_t received_msg)
 {
@@ -1660,7 +1662,7 @@
 	int index;
 
-	if (!protocol || !service || ((phone < 0) && !received_msg))
+	if ((!protocol) || (!service) || ((!sess) && (!received_msg)))
 		return EINVAL;
-
+	
 	proto = (ip_proto_t *) malloc(sizeof(ip_protos_t));
 	if (!proto)
@@ -1669,5 +1671,5 @@
 	proto->protocol = protocol;
 	proto->service = service;
-	proto->phone = phone;
+	proto->sess = sess;
 	proto->received_msg = received_msg;
 
@@ -1681,13 +1683,11 @@
 	fibril_rwlock_write_unlock(&ip_globals.protos_lock);
 
-	printf("%s: Protocol registered (protocol: %d, phone: %d)\n",
-	    NAME, proto->protocol, proto->phone);
+	printf("%s: Protocol registered (protocol: %d)\n",
+	    NAME, proto->protocol);
 
 	return EOK;
 }
 
-
-static int
-ip_add_route_req_local(int ip_phone, device_id_t device_id, in_addr_t address,
+static int ip_add_route_req_local(device_id_t device_id, in_addr_t address,
     in_addr_t netmask, in_addr_t gateway)
 {
@@ -1723,6 +1723,5 @@
 }
 
-static int
-ip_set_gateway_req_local(int ip_phone, device_id_t device_id, in_addr_t gateway)
+static int ip_set_gateway_req_local(device_id_t device_id, in_addr_t gateway)
 {
 	ip_netif_t *netif;
@@ -1748,16 +1747,15 @@
 /** Notify the IP module about the received error notification packet.
  *
- * @param[in] ip_phone	The IP module phone used for (semi)remote calls.
- * @param[in] device_id	The device identifier.
- * @param[in] packet	The received packet or the received packet queue.
- * @param[in] target	The target internetwork module service to be
- *			delivered to.
- * @param[in] error	The packet error reporting service. Prefixes the
- *			received packet.
- * @return		EOK on success.
- *
- */
-static int
-ip_received_error_msg_local(int ip_phone, device_id_t device_id,
+ * @param[in] device_id Device identifier.
+ * @param[in] packet    Received packet or the received packet queue.
+ * @param[in] target    Target internetwork module service to be
+ *                      delivered to.
+ * @param[in] error     Packet error reporting service. Prefixes the
+ *                      received packet.
+ *
+ * @return EOK on success.
+ *
+ */
+static int ip_received_error_msg_local(device_id_t device_id,
     packet_t *packet, services_t target, services_t error)
 {
@@ -1804,5 +1802,5 @@
 			address.value = (uint8_t *) &header->destination_address;
 			address.length = sizeof(header->destination_address);
-			arp_clear_address_req(netif->arp->phone,
+			arp_clear_address_req(netif->arp->sess,
 			    netif->device_id, SERVICE_IP, &address);
 		}
@@ -1818,6 +1816,5 @@
 }
 
-static int
-ip_get_route_req_local(int ip_phone, ip_protocol_t protocol,
+static int ip_get_route_req_local(ip_protocol_t protocol,
     const struct sockaddr *destination, socklen_t addrlen,
     device_id_t *device_id, void **header, size_t *headerlen)
@@ -1920,28 +1917,30 @@
 		return EOK;
 	
+	async_sess_t *callback =
+	    async_callback_receive_start(EXCHANGE_SERIALIZE, call);
+	if (callback)
+		return ip_register(IL_GET_PROTO(*call), IL_GET_SERVICE(*call),
+		    callback, NULL);
+	
 	switch (IPC_GET_IMETHOD(*call)) {
-	case IPC_M_CONNECT_TO_ME:
-		return ip_register(IL_GET_PROTO(*call), IL_GET_SERVICE(*call),
-		    IPC_GET_PHONE(*call), NULL);
-	
 	case NET_IP_DEVICE:
-		return ip_device_req_local(0, IPC_GET_DEVICE(*call),
+		return ip_device_req_local(IPC_GET_DEVICE(*call),
 		    IPC_GET_SERVICE(*call));
 	
 	case NET_IP_RECEIVED_ERROR:
-		rc = packet_translate_remote(ip_globals.net_phone, &packet,
+		rc = packet_translate_remote(ip_globals.net_sess, &packet,
 		    IPC_GET_PACKET(*call));
 		if (rc != EOK)
 			return rc;
-		return ip_received_error_msg_local(0, IPC_GET_DEVICE(*call),
+		return ip_received_error_msg_local(IPC_GET_DEVICE(*call),
 		    packet, IPC_GET_TARGET(*call), IPC_GET_ERROR(*call));
 	
 	case NET_IP_ADD_ROUTE:
-		return ip_add_route_req_local(0, IPC_GET_DEVICE(*call),
+		return ip_add_route_req_local(IPC_GET_DEVICE(*call),
 		    IP_GET_ADDRESS(*call), IP_GET_NETMASK(*call),
 		    IP_GET_GATEWAY(*call));
 
 	case NET_IP_SET_GATEWAY:
-		return ip_set_gateway_req_local(0, IPC_GET_DEVICE(*call),
+		return ip_set_gateway_req_local(IPC_GET_DEVICE(*call),
 		    IP_GET_GATEWAY(*call));
 
@@ -1952,5 +1951,5 @@
 			return rc;
 		
-		rc = ip_get_route_req_local(0, IP_GET_PROTOCOL(*call), addr,
+		rc = ip_get_route_req_local(IP_GET_PROTOCOL(*call), addr,
 		    (socklen_t) addrlen, &device_id, &header, &headerlen);
 		if (rc != EOK)
@@ -1983,10 +1982,10 @@
 	
 	case NET_IP_SEND:
-		rc = packet_translate_remote(ip_globals.net_phone, &packet,
+		rc = packet_translate_remote(ip_globals.net_sess, &packet,
 		    IPC_GET_PACKET(*call));
 		if (rc != EOK)
 			return rc;
 		
-		return ip_send_msg_local(0, IPC_GET_DEVICE(*call), packet, 0,
+		return ip_send_msg_local(IPC_GET_DEVICE(*call), packet, 0,
 		    IPC_GET_ERROR(*call));
 	}
Index: uspace/srv/net/il/ip/ip.h
===================================================================
--- uspace/srv/net/il/ip/ip.h	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/srv/net/il/ip/ip.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -38,4 +38,5 @@
 #define NET_IP_H_
 
+#include <async.h>
 #include <fibril_synch.h>
 #include <ipc/services.h>
@@ -98,6 +99,6 @@
 	/** Packet dimension. */
 	packet_dimension_t packet_dimension;
-	/** Netif module phone. */
-	int phone;
+	/** Netif module session. */
+	async_sess_t *sess;
 	/** Routing table. */
 	ip_routes_t routes;
@@ -112,6 +113,6 @@
 /** IP protocol specific data. */
 struct ip_proto {
-	/** Protocol module phone. */
-	int phone;
+	/** Protocol module session. */
+	async_sess_t *sess;
 	/** Protocol number. */
 	int protocol;
@@ -142,6 +143,6 @@
 	/** Known support modules. */
 	modules_t modules;
-	/** Networking module phone. */
-	int net_phone;
+	/** Networking module session. */
+	async_sess_t *net_sess;
 	/** Registered network interfaces. */
 	ip_netifs_t netifs;
Index: uspace/srv/net/net/net.c
===================================================================
--- uspace/srv/net/net/net.c	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/srv/net/net/net.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -36,10 +36,7 @@
  */
 
-#include "net.h"
-
 #include <async.h>
 #include <ctype.h>
 #include <ddi.h>
-#include <ns.h>
 #include <errno.h>
 #include <malloc.h>
@@ -47,5 +44,5 @@
 #include <str.h>
 #include <str_error.h>
-
+#include <ns.h>
 #include <ipc/services.h>
 #include <ipc/net.h>
@@ -53,18 +50,16 @@
 #include <ipc/il.h>
 #include <ipc/nil.h>
-
 #include <net/modules.h>
 #include <net/packet.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 <netif_remote.h>
 #include <nil_remote.h>
 #include <net_interface.h>
 #include <ip_interface.h>
+#include "net.h"
 
 /** Networking module name. */
@@ -394,5 +389,5 @@
 }
 
-int net_get_conf_req(int net_phone, measured_string_t **configuration,
+static int net_get_conf_req_local(measured_string_t **configuration,
     size_t count, uint8_t **data)
 {
@@ -403,5 +398,5 @@
 }
 
-int net_get_device_conf_req(int net_phone, device_id_t device_id,
+static int net_get_device_conf_req_local(device_id_t device_id,
     measured_string_t **configuration, size_t count, uint8_t **data)
 {
@@ -479,5 +474,5 @@
 	uintptr_t io = setting ? strtol((char *) setting->value, NULL, 16) : 0;
 	
-	rc = netif_probe_req(netif->driver->phone, netif->id, irq, (void *) io);
+	rc = netif_probe_req(netif->driver->sess, netif->id, irq, (void *) io);
 	if (rc != EOK)
 		return rc;
@@ -492,6 +487,5 @@
 		
 		int mtu = setting ? strtol((char *) setting->value, NULL, 10) : 0;
-		
-		rc = nil_device_req(netif->nil->phone, netif->id, mtu,
+		rc = nil_device_req(netif->nil->sess, netif->id, mtu,
 		    netif->driver->service);
 		if (rc != EOK)
@@ -503,16 +497,9 @@
 	
 	/* Inter-network layer startup */
-	switch (netif->il->service) {
-	case SERVICE_IP:
-		rc = ip_device_req(netif->il->phone, netif->id,
-		    internet_service);
-		if (rc != EOK)
-			return rc;
-		break;
-	default:
-		return ENOENT;
-	}
-	
-	return netif_start_req(netif->driver->phone, netif->id);
+	rc = ip_device_req(netif->il->sess, netif->id, internet_service);
+	if (rc != EOK)
+		return rc;
+	
+	return netif_start_req(netif->driver->sess, netif->id);
 }
 
@@ -649,5 +636,5 @@
 		if (rc != EOK)
 			return rc;
-		net_get_device_conf_req(0, IPC_GET_DEVICE(*call), &strings,
+		net_get_device_conf_req_local(IPC_GET_DEVICE(*call), &strings,
 		    IPC_GET_COUNT(*call), NULL);
 		
@@ -663,5 +650,5 @@
 		if (rc != EOK)
 			return rc;
-		net_get_conf_req(0, &strings, IPC_GET_COUNT(*call), NULL);
+		net_get_conf_req_local(&strings, IPC_GET_COUNT(*call), NULL);
 		
 		/* Strings should not contain received data anymore */
@@ -683,4 +670,5 @@
  * @param[in] icall The initial message call structure.
  * @param[in] arg   Local argument.
+ *
  */
 static void net_client_connection(ipc_callid_t iid, ipc_call_t *icall,
Index: uspace/srv/net/netif/lo/lo.c
===================================================================
--- uspace/srv/net/netif/lo/lo.c	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/srv/net/netif/lo/lo.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -148,5 +148,4 @@
 	null_device_stats((device_stats_t *) (*device)->specific);
 	(*device)->device_id = device_id;
-	(*device)->nil_phone = -1;
 	(*device)->state = NETIF_STOPPED;
 	int index = netif_device_map_add(&netif_globals.device_map,
@@ -202,8 +201,8 @@
 	} while (next);
 	
-	int phone = device->nil_phone;
+	async_sess_t *nil_sess = netif_globals.nil_sess;
 	fibril_rwlock_write_unlock(&netif_globals.lock);
 	
-	nil_received_msg(phone, device_id, packet, sender);
+	nil_received_msg(nil_sess, device_id, packet, sender);
 	
 	fibril_rwlock_write_lock(&netif_globals.lock);
Index: uspace/srv/net/nil/eth/eth.c
===================================================================
--- uspace/srv/net/nil/eth/eth.c	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/srv/net/nil/eth/eth.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -59,8 +59,4 @@
 #include <packet_remote.h>
 #include <nil_skel.h>
-
-// FIXME: remove this header
-#include <kernel/ipc/ipc_methods.h>
-
 #include "eth.h"
 
@@ -171,5 +167,5 @@
 INT_MAP_IMPLEMENT(eth_protos, eth_proto_t);
 
-int nil_device_state_msg_local(int nil_phone, device_id_t device_id, int state)
+int nil_device_state_msg_local(device_id_t device_id, sysarg_t state)
 {
 	int index;
@@ -180,6 +176,6 @@
 	    index--) {
 		proto = eth_protos_get_index(&eth_globals.protos, index);
-		if (proto && proto->phone) {
-			il_device_state_msg(proto->phone, device_id, state,
+		if ((proto) && (proto->sess)) {
+			il_device_state_msg(proto->sess, device_id, state,
 			    proto->service);
 		}
@@ -190,5 +186,5 @@
 }
 
-int nil_initialize(int net_phone)
+int nil_initialize(async_sess_t *sess)
 {
 	int rc;
@@ -199,5 +195,5 @@
 	fibril_rwlock_write_lock(&eth_globals.devices_lock);
 	fibril_rwlock_write_lock(&eth_globals.protos_lock);
-	eth_globals.net_phone = net_phone;
+	eth_globals.net_sess = sess;
 
 	eth_globals.broadcast_addr =
@@ -226,10 +222,11 @@
 }
 
-/** Processes IPC messages from the registered device driver modules in an
+/** Process IPC messages from the registered device driver modules in an
  * infinite loop.
  *
- * @param[in] iid	The message identifier.
- * @param[in,out] icall	The message parameters.
- * @param[in] arg	Local argument.
+ * @param[in]     iid   Message identifier.
+ * @param[in,out] icall Message parameters.
+ * @param[in]     arg   Local argument.
+ *
  */
 static void eth_receiver(ipc_callid_t iid, ipc_call_t *icall, void *arg)
@@ -241,14 +238,14 @@
 		switch (IPC_GET_IMETHOD(*icall)) {
 		case NET_NIL_DEVICE_STATE:
-			nil_device_state_msg_local(0, IPC_GET_DEVICE(*icall),
+			nil_device_state_msg_local(IPC_GET_DEVICE(*icall),
 			    IPC_GET_STATE(*icall));
 			async_answer_0(iid, EOK);
 			break;
 		case NET_NIL_RECEIVED:
-			rc = packet_translate_remote(eth_globals.net_phone,
+			rc = packet_translate_remote(eth_globals.net_sess,
 			    &packet, IPC_GET_PACKET(*icall));
 			if (rc == EOK)
-				rc = nil_received_msg_local(0,
-				    IPC_GET_DEVICE(*icall), packet, 0);
+				rc = nil_received_msg_local(IPC_GET_DEVICE(*icall),
+				    packet, 0);
 			
 			async_answer_0(iid, (sysarg_t) rc);
@@ -326,6 +323,6 @@
 			proto = eth_protos_get_index(&eth_globals.protos,
 			    index);
-			if (proto->phone) {
-				il_mtu_changed_msg(proto->phone,
+			if (proto->sess) {
+				il_mtu_changed_msg(proto->sess,
 				    device->device_id, device->mtu,
 				    proto->service);
@@ -351,5 +348,5 @@
 
 	configuration = &names[0];
-	rc = net_get_device_conf_req(eth_globals.net_phone, device->device_id,
+	rc = net_get_device_conf_req(eth_globals.net_sess, device->device_id,
 	    &configuration, count, &data);
 	if (rc != EOK) {
@@ -380,14 +377,14 @@
 	
 	/* Bind the device driver */
-	device->phone = netif_bind_service(device->service, device->device_id,
+	device->sess = netif_bind_service(device->service, device->device_id,
 	    SERVICE_ETHERNET, eth_receiver);
-	if (device->phone < 0) {
+	if (device->sess == NULL) {
 		fibril_rwlock_write_unlock(&eth_globals.devices_lock);
 		free(device);
-		return device->phone;
+		return ENOENT;
 	}
 	
 	/* Get hardware address */
-	rc = netif_get_addr_req(device->phone, device->device_id, &device->addr,
+	rc = netif_get_addr_req(device->sess, device->device_id, &device->addr,
 	    &device->addr_data);
 	if (rc != EOK) {
@@ -509,6 +506,6 @@
 }
 
-int nil_received_msg_local(int nil_phone, device_id_t device_id,
-    packet_t *packet, services_t target)
+int nil_received_msg_local(device_id_t device_id, packet_t *packet,
+    services_t target)
 {
 	eth_proto_t *proto;
@@ -532,9 +529,9 @@
 		proto = eth_process_packet(flags, packet);
 		if (proto) {
-			il_received_msg(proto->phone, device_id, packet,
+			il_received_msg(proto->sess, device_id, packet,
 			    proto->service);
 		} else {
 			/* Drop invalid/unknown */
-			pq_release_remote(eth_globals.net_phone,
+			pq_release_remote(eth_globals.net_sess,
 			    packet_get_id(packet));
 		}
@@ -615,15 +612,17 @@
 }
 
-/** Registers receiving module service.
- *
- * Passes received packets for this service.
- *
- * @param[in] service	The module service.
- * @param[in] phone	The service phone.
- * @return		EOK on success.
- * @return		ENOENT if the service is not known.
- * @return		ENOMEM if there is not enough memory left.
- */
-static int eth_register_message(services_t service, int phone)
+/** Register receiving module service.
+ *
+ * Pass received packets for this service.
+ *
+ * @param[in] service Module service.
+ * @param[in] sess    Service session.
+ *
+ * @return EOK on success.
+ * @return ENOENT if the service is not known.
+ * @return ENOMEM if there is not enough memory left.
+ *
+ */
+static int eth_register_message(services_t service, async_sess_t *sess)
 {
 	eth_proto_t *proto;
@@ -638,5 +637,5 @@
 	proto = eth_protos_find(&eth_globals.protos, protocol);
 	if (proto) {
-		proto->phone = phone;
+		proto->sess = sess;
 		fibril_rwlock_write_unlock(&eth_globals.protos_lock);
 		return EOK;
@@ -650,5 +649,5 @@
 		proto->service = service;
 		proto->protocol = protocol;
-		proto->phone = phone;
+		proto->sess = sess;
 
 		index = eth_protos_add(&eth_globals.protos, protocol, proto);
@@ -660,6 +659,6 @@
 	}
 	
-	printf("%s: Protocol registered (protocol: %d, service: %d, phone: "
-	    "%d)\n", NAME, proto->protocol, proto->service, proto->phone);
+	printf("%s: Protocol registered (protocol: %d, service: %d)\n",
+	    NAME, proto->protocol, proto->service);
 	
 	fibril_rwlock_write_unlock(&eth_globals.protos_lock);
@@ -799,5 +798,5 @@
 	ethertype = htons(protocol_map(SERVICE_ETHERNET, sender));
 	if (!ethertype) {
-		pq_release_remote(eth_globals.net_phone, packet_get_id(packet));
+		pq_release_remote(eth_globals.net_sess, packet_get_id(packet));
 		return EINVAL;
 	}
@@ -820,5 +819,5 @@
 			if (next == packet)
 				packet = tmp;
-			pq_release_remote(eth_globals.net_phone,
+			pq_release_remote(eth_globals.net_sess,
 			    packet_get_id(next));
 			next = tmp;
@@ -830,5 +829,5 @@
 	/* Send packet queue */
 	if (packet) {
-		netif_send_msg(device->phone, device_id, packet,
+		netif_send_msg(device->sess, device_id, packet,
 		    SERVICE_ETHERNET);
 	}
@@ -854,4 +853,9 @@
 		return EOK;
 	
+	async_sess_t *callback =
+	    async_callback_receive_start(EXCHANGE_SERIALIZE, call);
+	if (callback)
+		return eth_register_message(NIL_GET_PROTO(*call), callback);
+	
 	switch (IPC_GET_IMETHOD(*call)) {
 	case NET_NIL_DEVICE:
@@ -859,5 +863,5 @@
 		    IPC_GET_SERVICE(*call), IPC_GET_MTU(*call));
 	case NET_NIL_SEND:
-		rc = packet_translate_remote(eth_globals.net_phone, &packet,
+		rc = packet_translate_remote(eth_globals.net_sess, &packet,
 		    IPC_GET_PACKET(*call));
 		if (rc != EOK)
@@ -888,7 +892,4 @@
 			return EOK;
 		return measured_strings_reply(address, 1);
-	case IPC_M_CONNECT_TO_ME:
-		return eth_register_message(NIL_GET_PROTO(*call),
-		    IPC_GET_PHONE(*call));
 	}
 	
Index: uspace/srv/net/nil/eth/eth.h
===================================================================
--- uspace/srv/net/nil/eth/eth.h	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/srv/net/nil/eth/eth.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -38,7 +38,7 @@
 #define NET_ETH_H_
 
+#include <async.h>
 #include <fibril_synch.h>
 #include <ipc/services.h>
-
 #include <net/device.h>
 #include <adt/measured_strings.h>
@@ -223,6 +223,6 @@
 	/** Device driver service. */
 	services_t service;
-	/** Driver phone. */
-	int phone;
+	/** Driver session. */
+	async_sess_t *sess;
 	/** Maximal transmission unit. */
 	size_t mtu;
@@ -248,12 +248,12 @@
 	/** Protocol identifier. */
 	int protocol;
-	/** Protocol module phone. */
-	int phone;
+	/** Protocol module session. */
+	async_sess_t *sess;
 };
 
 /** Ethernet global data. */
 struct eth_globals {
-	/** Networking module phone. */
-	int net_phone;
+	/** Networking module session. */
+	async_sess_t *net_sess;
 	/** Safety lock for devices. */
 	fibril_rwlock_t devices_lock;
@@ -265,5 +265,5 @@
 	/**
 	 * Protocol map.
-	 * Service phone map for each protocol.
+	 * Service map for each protocol.
 	 */
 	eth_protos_t protos;
Index: uspace/srv/net/nil/nildummy/nildummy.c
===================================================================
--- uspace/srv/net/nil/nildummy/nildummy.c	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/srv/net/nil/nildummy/nildummy.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -44,5 +44,4 @@
 #include <ipc/net.h>
 #include <ipc/services.h>
-
 #include <net/modules.h>
 #include <net/device.h>
@@ -53,8 +52,4 @@
 #include <netif_remote.h>
 #include <nil_skel.h>
-
-// FIXME: remove this header
-#include <kernel/ipc/ipc_methods.h>
-
 #include "nildummy.h"
 
@@ -70,9 +65,9 @@
 DEVICE_MAP_IMPLEMENT(nildummy_devices, nildummy_device_t);
 
-int nil_device_state_msg_local(int nil_phone, device_id_t device_id, int state)
+int nil_device_state_msg_local(device_id_t device_id, sysarg_t state)
 {
 	fibril_rwlock_read_lock(&nildummy_globals.protos_lock);
-	if (nildummy_globals.proto.phone)
-		il_device_state_msg(nildummy_globals.proto.phone, device_id,
+	if (nildummy_globals.proto.sess)
+		il_device_state_msg(nildummy_globals.proto.sess, device_id,
 		    state, nildummy_globals.proto.service);
 	fibril_rwlock_read_unlock(&nildummy_globals.protos_lock);
@@ -81,5 +76,5 @@
 }
 
-int nil_initialize(int net_phone)
+int nil_initialize(async_sess_t *sess)
 {
 	fibril_rwlock_initialize(&nildummy_globals.devices_lock);
@@ -88,6 +83,6 @@
 	fibril_rwlock_write_lock(&nildummy_globals.protos_lock);
 	
-	nildummy_globals.net_phone = net_phone;
-	nildummy_globals.proto.phone = 0;
+	nildummy_globals.net_sess = sess;
+	nildummy_globals.proto.sess = NULL;
 	int rc = nildummy_devices_initialize(&nildummy_globals.devices);
 	
@@ -102,5 +97,6 @@
  * @param[in]     iid   Message identifier.
  * @param[in,out] icall Message parameters.
- * @param[in]     arg   Local argument.
+ * @param[in]     arg    Local argument.
+ *
  */
 static void nildummy_receiver(ipc_callid_t iid, ipc_call_t *icall, void *arg)
@@ -112,15 +108,15 @@
 		switch (IPC_GET_IMETHOD(*icall)) {
 		case NET_NIL_DEVICE_STATE:
-			rc = nil_device_state_msg_local(0,
-			    IPC_GET_DEVICE(*icall), IPC_GET_STATE(*icall));
+			rc = nil_device_state_msg_local(IPC_GET_DEVICE(*icall),
+			    IPC_GET_STATE(*icall));
 			async_answer_0(iid, (sysarg_t) rc);
 			break;
 		
 		case NET_NIL_RECEIVED:
-			rc = packet_translate_remote(nildummy_globals.net_phone,
+			rc = packet_translate_remote(nildummy_globals.net_sess,
 			    &packet, IPC_GET_PACKET(*icall));
 			if (rc == EOK)
-				rc = nil_received_msg_local(0,
-				    IPC_GET_DEVICE(*icall), packet, 0);
+				rc = nil_received_msg_local(IPC_GET_DEVICE(*icall),
+				    packet, 0);
 			
 			async_answer_0(iid, (sysarg_t) rc);
@@ -180,6 +176,6 @@
 		/* Notify the upper layer module */
 		fibril_rwlock_read_lock(&nildummy_globals.protos_lock);
-		if (nildummy_globals.proto.phone) {
-			il_mtu_changed_msg(nildummy_globals.proto.phone,
+		if (nildummy_globals.proto.sess) {
+			il_mtu_changed_msg(nildummy_globals.proto.sess,
 			    device->device_id, device->mtu,
 			    nildummy_globals.proto.service);
@@ -203,14 +199,14 @@
 
 	/* Bind the device driver */
-	device->phone = netif_bind_service(device->service, device->device_id,
+	device->sess = netif_bind_service(device->service, device->device_id,
 	    SERVICE_ETHERNET, nildummy_receiver);
-	if (device->phone < 0) {
+	if (device->sess == NULL) {
 		fibril_rwlock_write_unlock(&nildummy_globals.devices_lock);
 		free(device);
-		return device->phone;
+		return ENOENT;
 	}
 	
 	/* Get hardware address */
-	int rc = netif_get_addr_req(device->phone, device->device_id,
+	int rc = netif_get_addr_req(device->sess, device->device_id,
 	    &device->addr, &device->addr_data);
 	if (rc != EOK) {
@@ -307,13 +303,13 @@
 }
 
-int nil_received_msg_local(int nil_phone, device_id_t device_id,
-    packet_t *packet, services_t target)
+int nil_received_msg_local(device_id_t device_id, packet_t *packet,
+    services_t target)
 {
 	fibril_rwlock_read_lock(&nildummy_globals.protos_lock);
 	
-	if (nildummy_globals.proto.phone) {
+	if (nildummy_globals.proto.sess) {
 		do {
 			packet_t *next = pq_detach(packet);
-			il_received_msg(nildummy_globals.proto.phone, device_id,
+			il_received_msg(nildummy_globals.proto.sess, device_id,
 			    packet, nildummy_globals.proto.service);
 			packet = next;
@@ -331,5 +327,5 @@
  *
  * @param[in] service Module service.
- * @param[in] phone   Service phone.
+ * @param[in] sess    Service session.
  *
  * @return EOK on success.
@@ -338,12 +334,12 @@
  *
  */
-static int nildummy_register_message(services_t service, int phone)
+static int nildummy_register_message(services_t service, async_sess_t *sess)
 {
 	fibril_rwlock_write_lock(&nildummy_globals.protos_lock);
 	nildummy_globals.proto.service = service;
-	nildummy_globals.proto.phone = phone;
-	
-	printf("%s: Protocol registered (service: %d, phone: %d)\n",
-	    NAME, nildummy_globals.proto.service, nildummy_globals.proto.phone);
+	nildummy_globals.proto.sess = sess;
+	
+	printf("%s: Protocol registered (service: %d)\n",
+	    NAME, nildummy_globals.proto.service);
 	
 	fibril_rwlock_write_unlock(&nildummy_globals.protos_lock);
@@ -376,5 +372,5 @@
 	/* Send packet queue */
 	if (packet)
-		netif_send_msg(device->phone, device_id, packet,
+		netif_send_msg(device->sess, device_id, packet,
 		    SERVICE_NILDUMMY);
 	
@@ -400,4 +396,9 @@
 		return EOK;
 	
+	async_sess_t *callback =
+	    async_callback_receive_start(EXCHANGE_SERIALIZE, call);
+	if (callback)
+		return nildummy_register_message(NIL_GET_PROTO(*call), callback);
+	
 	switch (IPC_GET_IMETHOD(*call)) {
 	case NET_NIL_DEVICE:
@@ -406,5 +407,5 @@
 	
 	case NET_NIL_SEND:
-		rc = packet_translate_remote(nildummy_globals.net_phone,
+		rc = packet_translate_remote(nildummy_globals.net_sess,
 		    &packet, IPC_GET_PACKET(*call));
 		if (rc != EOK)
@@ -436,8 +437,4 @@
 			return rc;
 		return measured_strings_reply(address, 1);
-	
-	case IPC_M_CONNECT_TO_ME:
-		return nildummy_register_message(NIL_GET_PROTO(*call),
-		    IPC_GET_PHONE(*call));
 	}
 	
Index: uspace/srv/net/nil/nildummy/nildummy.h
===================================================================
--- uspace/srv/net/nil/nildummy/nildummy.h	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/srv/net/nil/nildummy/nildummy.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -38,7 +38,7 @@
 #define NET_NILDUMMY_H_
 
+#include <async.h>
 #include <fibril_synch.h>
 #include <ipc/services.h>
-
 #include <net/device.h>
 #include <adt/measured_strings.h>
@@ -81,6 +81,6 @@
 	services_t service;
 	
-	/** Driver phone. */
-	int phone;
+	/** Driver session. */
+	async_sess_t *sess;
 	
 	/** Maximal transmission unit. */
@@ -99,12 +99,12 @@
 	services_t service;
 	
-	/** Protocol module phone. */
-	int phone;
+	/** Protocol module session. */
+	async_sess_t *sess;
 };
 
 /** Dummy nil global data. */
 struct nildummy_globals {
-	/** Networking module phone. */
-	int net_phone;
+	/** Networking module session. */
+	async_sess_t *net_sess;
 	
 	/** Lock for devices. */
Index: uspace/srv/net/tl/icmp/icmp.c
===================================================================
--- uspace/srv/net/tl/icmp/icmp.c	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/srv/net/tl/icmp/icmp.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -118,6 +118,6 @@
 
 /** Global data */
-static int phone_net = -1;
-static int phone_ip = -1;
+static async_sess_t *net_sess = NULL;
+static async_sess_t *ip_sess = NULL;
 static bool error_reporting = true;
 static bool echo_replying = true;
@@ -173,5 +173,5 @@
 static void icmp_release(packet_t *packet)
 {
-	pq_release_remote(phone_net, packet_get_id(packet));
+	pq_release_remote(net_sess, packet_get_id(packet));
 }
 
@@ -225,5 +225,5 @@
 	}
 	
-	return ip_send_msg(phone_ip, -1, packet, SERVICE_ICMP, error);
+	return ip_send_msg(ip_sess, -1, packet, SERVICE_ICMP, error);
 }
 
@@ -297,5 +297,5 @@
 	size_t length = (size_t) addrlen;
 	
-	packet_t *packet = packet_get_4_remote(phone_net, size,
+	packet_t *packet = packet_get_4_remote(net_sess, size,
 	    icmp_dimension.addr_len, ICMP_HEADER_SIZE + icmp_dimension.prefix,
 	    icmp_dimension.suffix);
@@ -595,5 +595,5 @@
 	case ICMP_SKIP:
 	case ICMP_PHOTURIS:
-		ip_received_error_msg(phone_ip, -1, packet,
+		ip_received_error_msg(ip_sess, -1, packet,
 		    SERVICE_IP, SERVICE_ICMP);
 		return EOK;
@@ -609,4 +609,5 @@
  * @param[in,out] icall Message parameters.
  * @param[in]     arg   Local argument.
+ *
  */
 static void icmp_receiver(ipc_callid_t iid, ipc_call_t *icall, void *arg)
@@ -621,5 +622,5 @@
 		switch (IPC_GET_IMETHOD(*icall)) {
 		case NET_TL_RECEIVED:
-			rc = packet_translate_remote(phone_net, &packet,
+			rc = packet_translate_remote(net_sess, &packet,
 			    IPC_GET_PACKET(*icall));
 			if (rc == EOK) {
@@ -641,5 +642,5 @@
 /** Initialize the ICMP module.
  *
- * @param[in] net_phone Network module phone.
+ * @param[in] sess Network module session.
  *
  * @return EOK on success.
@@ -647,5 +648,5 @@
  *
  */
-int tl_initialize(int net_phone)
+int tl_initialize(async_sess_t *sess)
 {
 	measured_string_t names[] = {
@@ -669,11 +670,11 @@
 	atomic_set(&icmp_client, 0);
 	
-	phone_net = net_phone;
-	phone_ip = ip_bind_service(SERVICE_IP, IPPROTO_ICMP, SERVICE_ICMP,
+	net_sess = sess;
+	ip_sess = ip_bind_service(SERVICE_IP, IPPROTO_ICMP, SERVICE_ICMP,
 	    icmp_receiver);
-	if (phone_ip < 0)
-		return phone_ip;
-	
-	int rc = ip_packet_size_req(phone_ip, -1, &icmp_dimension);
+	if (ip_sess == NULL)
+		return ENOENT;
+	
+	int rc = ip_packet_size_req(ip_sess, -1, &icmp_dimension);
 	if (rc != EOK)
 		return rc;
@@ -684,5 +685,5 @@
 	/* Get configuration */
 	configuration = &names[0];
-	rc = net_get_conf_req(phone_net, &configuration, count, &data);
+	rc = net_get_conf_req(net_sess, &configuration, count, &data);
 	if (rc != EOK)
 		return rc;
@@ -762,5 +763,5 @@
 	
 	case NET_ICMP_DEST_UNREACH:
-		rc = packet_translate_remote(phone_net, &packet,
+		rc = packet_translate_remote(net_sess, &packet,
 		    IPC_GET_PACKET(*call));
 		if (rc != EOK)
@@ -771,5 +772,5 @@
 	
 	case NET_ICMP_SOURCE_QUENCH:
-		rc = packet_translate_remote(phone_net, &packet,
+		rc = packet_translate_remote(net_sess, &packet,
 		    IPC_GET_PACKET(*call));
 		if (rc != EOK)
@@ -779,5 +780,5 @@
 	
 	case NET_ICMP_TIME_EXCEEDED:
-		rc = packet_translate_remote(phone_net, &packet,
+		rc = packet_translate_remote(net_sess, &packet,
 		    IPC_GET_PACKET(*call));
 		if (rc != EOK)
@@ -787,5 +788,5 @@
 	
 	case NET_ICMP_PARAMETERPROB:
-		rc = packet_translate_remote(phone_net, &packet,
+		rc = packet_translate_remote(net_sess, &packet,
 		    IPC_GET_PACKET(*call));
 		if (rc != EOK)
Index: uspace/srv/net/tl/tcp/tcp.c
===================================================================
--- uspace/srv/net/tl/tcp/tcp.c	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/srv/net/tl/tcp/tcp.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -38,5 +38,4 @@
 #include <assert.h>
 #include <async.h>
-#include <async_obsolete.h>
 #include <fibril_synch.h>
 #include <malloc.h>
@@ -74,7 +73,4 @@
 #include "tcp_header.h"
 
-// FIXME: remove this header
-#include <kernel/ipc/ipc_methods.h>
-
 /** TCP module name. */
 #define NAME  "tcp"
@@ -210,5 +206,6 @@
 
 static int tcp_received_msg(device_id_t, packet_t *, services_t, services_t);
-static int tcp_process_client_messages(ipc_callid_t, ipc_call_t);
+static int tcp_process_client_messages(async_sess_t *, ipc_callid_t,
+    ipc_call_t);
 
 static int tcp_listen_message(socket_cores_t *, int, int);
@@ -328,7 +325,7 @@
 
 	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,
+		if (tl_prepare_icmp_packet(tcp_globals.net_sess,
+		    tcp_globals.icmp_sess, packet, error) == EOK) {
+			icmp_destination_unreachable_msg(tcp_globals.icmp_sess,
 			    ICMP_PORT_UNREACH, 0, packet);
 		}
@@ -401,9 +398,9 @@
 		fibril_rwlock_write_unlock(socket_data->local_lock);
 
-		rc = tl_prepare_icmp_packet(tcp_globals.net_phone,
-		    tcp_globals.icmp_phone, packet, error);
+		rc = tl_prepare_icmp_packet(tcp_globals.net_sess,
+		    tcp_globals.icmp_sess, packet, error);
 		if (rc == EOK) {
 			/* Checksum error ICMP */
-			icmp_parameter_problem_msg(tcp_globals.icmp_phone,
+			icmp_parameter_problem_msg(tcp_globals.icmp_sess,
 			    ICMP_PARAM_POINTER,
 			    ((size_t) ((void *) &header->checksum)) -
@@ -443,5 +440,5 @@
 		break;
 	default:
-		pq_release_remote(tcp_globals.net_phone, packet_get_id(packet));
+		pq_release_remote(tcp_globals.net_sess, packet_get_id(packet));
 	}
 
@@ -506,5 +503,5 @@
 			/* Release the acknowledged packets */
 			next_packet = pq_next(packet);
-			pq_release_remote(tcp_globals.net_phone,
+			pq_release_remote(tcp_globals.net_sess,
 			    packet_get_id(packet));
 			packet = next_packet;
@@ -565,5 +562,5 @@
 			next_packet = pq_next(next_packet);
 			pq_insert_after(tmp_packet, next_packet);
-			pq_release_remote(tcp_globals.net_phone,
+			pq_release_remote(tcp_globals.net_sess,
 			    packet_get_id(tmp_packet));
 		}
@@ -602,5 +599,5 @@
 				if (packet == socket_data->incoming)
 					socket_data->incoming = next_packet;
-				pq_release_remote(tcp_globals.net_phone,
+				pq_release_remote(tcp_globals.net_sess,
 				    packet_get_id(packet));
 				packet = next_packet;
@@ -625,5 +622,5 @@
 				if (length <= 0) {
 					/* Remove the empty packet */
-					pq_release_remote(tcp_globals.net_phone,
+					pq_release_remote(tcp_globals.net_sess,
 					    packet_get_id(packet));
 					packet = next_packet;
@@ -672,5 +669,5 @@
 				}
 				/* Remove the duplicit or corrupted packet */
-				pq_release_remote(tcp_globals.net_phone,
+				pq_release_remote(tcp_globals.net_sess,
 				    packet_get_id(packet));
 				packet = next_packet;
@@ -699,7 +696,7 @@
 		if (rc != EOK) {
 			/* Remove the corrupted packets */
-			pq_release_remote(tcp_globals.net_phone,
+			pq_release_remote(tcp_globals.net_sess,
 			    packet_get_id(packet));
-			pq_release_remote(tcp_globals.net_phone,
+			pq_release_remote(tcp_globals.net_sess,
 			    packet_get_id(next_packet));
 		} else {
@@ -712,10 +709,10 @@
 				    new_sequence_number, length);
 				if (rc != EOK) {
-					pq_release_remote(tcp_globals.net_phone,
+					pq_release_remote(tcp_globals.net_sess,
 					    packet_get_id(next_packet));
 				}
 				rc = pq_insert_after(packet, next_packet);
 				if (rc != EOK) {
-					pq_release_remote(tcp_globals.net_phone,
+					pq_release_remote(tcp_globals.net_sess,
 					    packet_get_id(next_packet));
 				}
@@ -726,5 +723,5 @@
 		printf("unexpected\n");
 		/* Release duplicite or restricted */
-		pq_release_remote(tcp_globals.net_phone, packet_get_id(packet));
+		pq_release_remote(tcp_globals.net_sess, packet_get_id(packet));
 		forced_ack = true;
 	}
@@ -794,5 +791,5 @@
 	if (rc != EOK)
 		return tcp_release_and_return(packet, rc);
-	rc = tl_get_ip_packet_dimension(tcp_globals.ip_phone,
+	rc = tl_get_ip_packet_dimension(tcp_globals.ip_sess,
 	    &tcp_globals.dimensions, socket_data->device_id, &packet_dimension);
 	if (rc != EOK)
@@ -803,9 +800,10 @@
 
 	/* Notify the destination socket */
-	async_obsolete_msg_5(socket->phone, NET_SOCKET_RECEIVED,
-	    (sysarg_t) socket->socket_id,
+	async_exch_t *exch = async_exchange_begin(socket->sess);
+	async_msg_5(exch, NET_SOCKET_RECEIVED, (sysarg_t) socket->socket_id,
 	    ((packet_dimension->content < socket_data->data_fragment_size) ?
 	    packet_dimension->content : socket_data->data_fragment_size), 0, 0,
 	    (sysarg_t) fragments);
+	async_exchange_end(exch);
 
 	return EOK;
@@ -824,8 +822,8 @@
 
 	/* Notify the destination socket */
-	async_obsolete_msg_5(socket->phone, NET_SOCKET_RECEIVED,
-	    (sysarg_t) socket->socket_id,
-	    0, 0, 0,
-	    (sysarg_t) 0 /* 0 fragments == no more data */);
+	async_exch_t *exch = async_exchange_begin(socket->sess);
+	async_msg_5(exch, NET_SOCKET_RECEIVED, (sysarg_t) socket->socket_id,
+	    0, 0, 0, (sysarg_t) 0 /* 0 fragments == no more data */);
+	async_exchange_end(exch);
 }
 
@@ -853,5 +851,5 @@
 	next_packet = pq_detach(packet);
 	if (next_packet) {
-		pq_release_remote(tcp_globals.net_phone,
+		pq_release_remote(tcp_globals.net_sess,
 		    packet_get_id(next_packet));
 	}
@@ -940,5 +938,5 @@
 	/* Create a socket */
 	socket_id = -1;
-	rc = socket_create(socket_data->local_sockets, listening_socket->phone,
+	rc = socket_create(socket_data->local_sockets, listening_socket->sess,
 	    socket_data, &socket_id);
 	if (rc != EOK) {
@@ -993,5 +991,5 @@
 	fibril_rwlock_write_unlock(&tcp_globals.lock);
 	if (rc != EOK) {
-		socket_destroy(tcp_globals.net_phone, socket->socket_id,
+		socket_destroy(tcp_globals.net_sess, socket->socket_id,
 		    socket_data->local_sockets, &tcp_globals.sockets,
 		    tcp_free_socket_data);
@@ -1005,5 +1003,5 @@
 	next_packet = pq_detach(packet);
 	if (next_packet) {
-		pq_release_remote(tcp_globals.net_phone,
+		pq_release_remote(tcp_globals.net_sess,
 		    packet_get_id(next_packet));
 	}
@@ -1014,5 +1012,5 @@
 		    packet_get_data_length(packet) - sizeof(*header));
 		if (rc != EOK) {
-			socket_destroy(tcp_globals.net_phone, socket->socket_id,
+			socket_destroy(tcp_globals.net_sess, socket->socket_id,
 			    socket_data->local_sockets, &tcp_globals.sockets,
 			    tcp_free_socket_data);
@@ -1025,5 +1023,5 @@
 	rc = tcp_queue_packet(socket, socket_data, packet, 1);
 	if (rc != EOK) {
-		socket_destroy(tcp_globals.net_phone, socket->socket_id,
+		socket_destroy(tcp_globals.net_sess, socket->socket_id,
 		    socket_data->local_sockets, &tcp_globals.sockets,
 		    tcp_free_socket_data);
@@ -1033,5 +1031,5 @@
 	packet = tcp_get_packets_to_send(socket, socket_data);
 	if (!packet) {
-		socket_destroy(tcp_globals.net_phone, socket->socket_id,
+		socket_destroy(tcp_globals.net_sess, socket->socket_id,
 		    socket_data->local_sockets, &tcp_globals.sockets,
 		    tcp_free_socket_data);
@@ -1068,5 +1066,5 @@
 
 	socket_data->next_incoming = ntohl(header->sequence_number); /* + 1; */
-	pq_release_remote(tcp_globals.net_phone, packet_get_id(packet));
+	pq_release_remote(tcp_globals.net_sess, packet_get_id(packet));
 	socket_data->state = TCP_SOCKET_ESTABLISHED;
 	listening_socket = socket_cores_find(socket_data->local_sockets,
@@ -1082,8 +1080,10 @@
 		if (rc == EOK) {
 			/* Notify the destination socket */
-			async_obsolete_msg_5(socket->phone, NET_SOCKET_ACCEPTED,
+			async_exch_t *exch = async_exchange_begin(socket->sess);
+			async_msg_5(exch, NET_SOCKET_ACCEPTED,
 			    (sysarg_t) listening_socket->socket_id,
 			    socket_data->data_fragment_size, TCP_HEADER_SIZE,
 			    0, (sysarg_t) socket->socket_id);
+			async_exchange_end(exch);
 
 			fibril_rwlock_write_unlock(socket_data->local_lock);
@@ -1181,5 +1181,5 @@
 				/* Add to acknowledged or release */
 				if (pq_add(&acknowledged, packet, 0, 0) != EOK)
-					pq_release_remote(tcp_globals.net_phone,
+					pq_release_remote(tcp_globals.net_sess,
 					    packet_get_id(packet));
 				packet = next;
@@ -1190,5 +1190,5 @@
 		/* Release acknowledged */
 		if (acknowledged) {
-			pq_release_remote(tcp_globals.net_phone,
+			pq_release_remote(tcp_globals.net_sess,
 			    packet_get_id(acknowledged));
 		}
@@ -1234,11 +1234,12 @@
 	assert(answer);
 	assert(answer_count);
-
+	
 	*answer_count = 0;
-	switch (IPC_GET_IMETHOD(*call)) {
-	case IPC_M_CONNECT_TO_ME:
-		return tcp_process_client_messages(callid, *call);
-	}
-
+	
+	async_sess_t *callback =
+	    async_callback_receive_start(EXCHANGE_SERIALIZE, call);
+	if (callback)
+		return tcp_process_client_messages(callback, callid, *call);
+	
 	return ENOTSUP;
 }
@@ -1270,9 +1271,9 @@
 }
 
-int tcp_process_client_messages(ipc_callid_t callid, ipc_call_t call)
+int tcp_process_client_messages(async_sess_t *sess, ipc_callid_t callid,
+    ipc_call_t call)
 {
 	int res;
 	socket_cores_t local_sockets;
-	int app_phone = IPC_GET_PHONE(call);
 	struct sockaddr *addr;
 	int socket_id;
@@ -1325,5 +1326,5 @@
 			fibril_rwlock_write_lock(&lock);
 			socket_id = SOCKET_GET_SOCKET_ID(call);
-			res = socket_create(&local_sockets, app_phone,
+			res = socket_create(&local_sockets, sess,
 			    socket_data, &socket_id);
 			SOCKET_SET_SOCKET_ID(answer, socket_id);
@@ -1333,5 +1334,5 @@
 				break;
 			}
-			if (tl_get_ip_packet_dimension(tcp_globals.ip_phone,
+			if (tl_get_ip_packet_dimension(tcp_globals.ip_sess,
 			    &tcp_globals.dimensions, DEVICE_INVALID_ID,
 			    &packet_dimension) == EOK) {
@@ -1508,10 +1509,10 @@
 	}
 
-	/* Release the application phone */
-	async_obsolete_hangup(app_phone);
+	/* Release the application session */
+	async_hangup(sess);
 
 	printf("release\n");
 	/* Release all local sockets */
-	socket_cores_release(tcp_globals.net_phone, &local_sockets,
+	socket_cores_release(tcp_globals.net_sess, &local_sockets,
 	    &tcp_globals.sockets, tcp_free_socket_data);
 
@@ -1621,5 +1622,5 @@
 			local_lock = socket_data->local_lock;
 			fibril_rwlock_write_lock(local_lock);
-			socket_destroy(tcp_globals.net_phone,
+			socket_destroy(tcp_globals.net_sess,
 			    timeout->socket_id, timeout->local_sockets,
 			    &tcp_globals.sockets, tcp_free_socket_data);
@@ -1754,5 +1755,5 @@
 	}
 
-	rc = ip_get_route_req(tcp_globals.ip_phone, IPPROTO_TCP,
+	rc = ip_get_route_req(tcp_globals.ip_sess, IPPROTO_TCP,
 	    addr, addrlen, &socket_data->device_id,
 	    &socket_data->pseudo_header, &socket_data->headerlen);
@@ -1902,5 +1903,5 @@
 			rc = pq_insert_after(previous, copy);
 			if (rc != EOK) {
-				pq_release_remote(tcp_globals.net_phone,
+				pq_release_remote(tcp_globals.net_sess,
 				    packet_get_id(copy));
 				return sending;
@@ -1939,5 +1940,5 @@
 	    socket_data->headerlen, packet_get_data_length(packet));
 	if (rc != EOK) {
-		pq_release_remote(tcp_globals.net_phone, packet_get_id(packet));
+		pq_release_remote(tcp_globals.net_sess, packet_get_id(packet));
 		return NULL;
 	}
@@ -1946,5 +1947,5 @@
 	header = (tcp_header_t *) packet_get_data(packet);
 	if (!header) {
-		pq_release_remote(tcp_globals.net_phone, packet_get_id(packet));
+		pq_release_remote(tcp_globals.net_sess, packet_get_id(packet));
 		return NULL;
 	}
@@ -1971,5 +1972,5 @@
 	rc = ip_client_prepare_packet(packet, IPPROTO_TCP, 0, 0, 0, 0);
 	if (rc != EOK) {
-		pq_release_remote(tcp_globals.net_phone, packet_get_id(packet));
+		pq_release_remote(tcp_globals.net_sess, packet_get_id(packet));
 		return NULL;
 	}
@@ -1978,5 +1979,5 @@
 	    sequence_number, socket_data->state, socket_data->timeout, true);
 	if (rc != EOK) {
-		pq_release_remote(tcp_globals.net_phone, packet_get_id(packet));
+		pq_release_remote(tcp_globals.net_sess, packet_get_id(packet));
 		return NULL;
 	}
@@ -1995,5 +1996,5 @@
 
 	/* Make a copy of the packet */
-	copy = packet_get_copy(tcp_globals.net_phone, packet);
+	copy = packet_get_copy(tcp_globals.net_sess, packet);
 	if (!copy)
 		return NULL;
@@ -2009,5 +2010,5 @@
 	while (packet) {
 		next = pq_detach(packet);
-		ip_send_msg(tcp_globals.ip_phone, device_id, packet,
+		ip_send_msg(tcp_globals.ip_sess, device_id, packet,
 		    SERVICE_TCP, 0);
 		packet = next;
@@ -2122,5 +2123,5 @@
 		return NO_DATA;
 
-	rc = packet_translate_remote(tcp_globals.net_phone, &packet, packet_id);
+	rc = packet_translate_remote(tcp_globals.net_sess, &packet, packet_id);
 	if (rc != EOK)
 		return rc;
@@ -2133,5 +2134,5 @@
 	/* Release the packet */
 	dyn_fifo_pop(&socket->received);
-	pq_release_remote(tcp_globals.net_phone, packet_get_id(packet));
+	pq_release_remote(tcp_globals.net_sess, packet_get_id(packet));
 
 	/* Return the total length */
@@ -2171,5 +2172,5 @@
 		return ENOTCONN;
 
-	rc = tl_get_ip_packet_dimension(tcp_globals.ip_phone,
+	rc = tl_get_ip_packet_dimension(tcp_globals.ip_sess,
 	    &tcp_globals.dimensions, socket_data->device_id, &packet_dimension);
 	if (rc != EOK)
@@ -2182,5 +2183,5 @@
 	for (index = 0; index < fragments; index++) {
 		/* Read the data fragment */
-		result = tl_socket_read_packet_data(tcp_globals.net_phone,
+		result = tl_socket_read_packet_data(tcp_globals.net_sess,
 		    &packet, TCP_HEADER_SIZE, packet_dimension,
 		    socket_data->addr, socket_data->addrlen);
@@ -2245,5 +2246,5 @@
 	default:
 		/* Just destroy */
-		rc = socket_destroy(tcp_globals.net_phone, socket_id,
+		rc = socket_destroy(tcp_globals.net_sess, socket_id,
 		    local_sockets, &tcp_globals.sockets,
 		    tcp_free_socket_data);
@@ -2293,5 +2294,5 @@
 
 	/* Get the device packet dimension */
-	rc = tl_get_ip_packet_dimension(tcp_globals.ip_phone,
+	rc = tl_get_ip_packet_dimension(tcp_globals.ip_sess,
 	    &tcp_globals.dimensions, socket_data->device_id, &packet_dimension);
 	if (rc != EOK)
@@ -2299,5 +2300,5 @@
 
 	/* Get a new packet */
-	*packet = packet_get_4_remote(tcp_globals.net_phone, TCP_HEADER_SIZE,
+	*packet = packet_get_4_remote(tcp_globals.net_sess, TCP_HEADER_SIZE,
 	    packet_dimension->addr_len, packet_dimension->prefix,
 	    packet_dimension->suffix);
@@ -2362,5 +2363,5 @@
 			if (rc != EOK)
 				return rc;
-			rc = tl_get_ip_packet_dimension(tcp_globals.ip_phone,
+			rc = tl_get_ip_packet_dimension(tcp_globals.ip_sess,
 			    &tcp_globals.dimensions, socket_data->device_id,
 			    &packet_dimension);
@@ -2434,5 +2435,5 @@
 int tcp_release_and_return(packet_t *packet, int result)
 {
-	pq_release_remote(tcp_globals.net_phone, packet_get_id(packet));
+	pq_release_remote(tcp_globals.net_sess, packet_get_id(packet));
 	return result;
 }
@@ -2443,4 +2444,5 @@
  * @param[in,out] icall Message parameters.
  * @param[in]     arg   Local argument.
+ *
  */
 static void tcp_receiver(ipc_callid_t iid, ipc_call_t *icall, void *arg)
@@ -2452,5 +2454,5 @@
 		switch (IPC_GET_IMETHOD(*icall)) {
 		case NET_TL_RECEIVED:
-			rc = packet_translate_remote(tcp_globals.net_phone, &packet,
+			rc = packet_translate_remote(tcp_globals.net_sess, &packet,
 			    IPC_GET_PACKET(*icall));
 			if (rc == EOK)
@@ -2470,5 +2472,5 @@
 /** Initialize the TCP module.
  *
- * @param[in] net_phone Network module phone.
+ * @param[in] sess Network module session.
  *
  * @return EOK on success.
@@ -2476,17 +2478,17 @@
  *
  */
-int tl_initialize(int net_phone)
+int tl_initialize(async_sess_t *sess)
 {
 	fibril_rwlock_initialize(&tcp_globals.lock);
 	fibril_rwlock_write_lock(&tcp_globals.lock);
 	
-	tcp_globals.net_phone = net_phone;
+	tcp_globals.net_sess = sess;
 	
-	tcp_globals.icmp_phone = icmp_connect_module();
-	tcp_globals.ip_phone = ip_bind_service(SERVICE_IP, IPPROTO_TCP,
+	tcp_globals.icmp_sess = icmp_connect_module();
+	tcp_globals.ip_sess = ip_bind_service(SERVICE_IP, IPPROTO_TCP,
 	    SERVICE_TCP, tcp_receiver);
-	if (tcp_globals.ip_phone < 0) {
+	if (tcp_globals.ip_sess == NULL) {
 		fibril_rwlock_write_unlock(&tcp_globals.lock);
-		return tcp_globals.ip_phone;
+		return ENOENT;
 	}
 	
Index: uspace/srv/net/tl/tcp/tcp.h
===================================================================
--- uspace/srv/net/tl/tcp/tcp.h	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/srv/net/tl/tcp/tcp.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -38,6 +38,6 @@
 #define NET_TCP_H_
 
+#include <async.h>
 #include <fibril_synch.h>
-
 #include <net/packet.h>
 #include <net/device.h>
@@ -284,10 +284,10 @@
 /** TCP global data. */
 struct tcp_globals {
-	/** Networking module phone. */
-	int net_phone;
-	/** IP module phone. */
-	int ip_phone;
-	/** ICMP module phone. */
-	int icmp_phone;
+	/** Networking module session. */
+	async_sess_t *net_sess;
+	/** IP module session. */
+	async_sess_t *ip_sess;
+	/** ICMP module session. */
+	async_sess_t *icmp_sess;
 	/** Last used free port. */
 	int last_used_port;
Index: uspace/srv/net/tl/udp/udp.c
===================================================================
--- uspace/srv/net/tl/udp/udp.c	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/srv/net/tl/udp/udp.c	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -37,5 +37,4 @@
 
 #include <async.h>
-#include <async_obsolete.h>
 #include <fibril_synch.h>
 #include <malloc.h>
@@ -71,7 +70,4 @@
 #include "udp_header.h"
 
-// FIXME: remove this header
-#include <kernel/ipc/ipc_methods.h>
-
 /** UDP module name. */
 #define NAME  "udp"
@@ -103,5 +99,5 @@
 static int udp_release_and_return(packet_t *packet, int result)
 {
-	pq_release_remote(udp_globals.net_phone, packet_get_id(packet));
+	pq_release_remote(udp_globals.net_sess, packet_get_id(packet));
 	return result;
 }
@@ -196,7 +192,7 @@
 	    ntohs(header->destination_port), (uint8_t *) 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,
+		if (tl_prepare_icmp_packet(udp_globals.net_sess,
+		    udp_globals.icmp_sess, packet, error) == EOK) {
+			icmp_destination_unreachable_msg(udp_globals.icmp_sess,
 			    ICMP_PORT_UNREACH, 0, packet);
 		}
@@ -255,5 +251,5 @@
 			while (tmp_packet) {
 				next_packet = pq_detach(tmp_packet);
-				pq_release_remote(udp_globals.net_phone,
+				pq_release_remote(udp_globals.net_sess,
 				    packet_get_id(tmp_packet));
 				tmp_packet = next_packet;
@@ -278,9 +274,9 @@
 		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 (tl_prepare_icmp_packet(udp_globals.net_sess,
+			    udp_globals.icmp_sess, packet, error) == EOK) {
 				/* Checksum error ICMP */
 				icmp_parameter_problem_msg(
-				    udp_globals.icmp_phone, ICMP_PARAM_POINTER,
+				    udp_globals.icmp_sess, ICMP_PARAM_POINTER,
 				    ((size_t) ((void *) &header->checksum)) -
 				    ((size_t) ((void *) header)), packet);
@@ -296,5 +292,5 @@
 		return udp_release_and_return(packet, rc);
 		
-	rc = tl_get_ip_packet_dimension(udp_globals.ip_phone,
+	rc = tl_get_ip_packet_dimension(udp_globals.ip_sess,
 	    &udp_globals.dimensions, device_id, &packet_dimension);
 	if (rc != EOK)
@@ -303,7 +299,9 @@
 	/* Notify the destination socket */
 	fibril_rwlock_write_unlock(&udp_globals.lock);
-	async_obsolete_msg_5(socket->phone, NET_SOCKET_RECEIVED,
-	    (sysarg_t) socket->socket_id, packet_dimension->content, 0, 0,
-	    (sysarg_t) fragments);
+	
+	async_exch_t *exch = async_exchange_begin(socket->sess);
+	async_msg_5(exch, NET_SOCKET_RECEIVED, (sysarg_t) socket->socket_id,
+	    packet_dimension->content, 0, 0, (sysarg_t) fragments);
+	async_exchange_end(exch);
 
 	return EOK;
@@ -342,4 +340,5 @@
  * @param[in,out] icall Message parameters.
  * @param[in]     arg   Local argument.
+ *
  */
 static void udp_receiver(ipc_callid_t iid, ipc_call_t *icall, void *arg)
@@ -351,5 +350,5 @@
 		switch (IPC_GET_IMETHOD(*icall)) {
 		case NET_TL_RECEIVED:
-			rc = packet_translate_remote(udp_globals.net_phone, &packet,
+			rc = packet_translate_remote(udp_globals.net_sess, &packet,
 			    IPC_GET_PACKET(*icall));
 			if (rc == EOK)
@@ -369,5 +368,5 @@
 /** Initialize the UDP module.
  *
- * @param[in] net_phone Network module phone.
+ * @param[in] sess Network module session.
  *
  * @return EOK on success.
@@ -375,5 +374,5 @@
  *
  */
-int tl_initialize(int net_phone)
+int tl_initialize(async_sess_t *sess)
 {
 	measured_string_t names[] = {
@@ -394,17 +393,16 @@
 	fibril_rwlock_write_lock(&udp_globals.lock);
 	
-	udp_globals.net_phone = net_phone;
-	
-	udp_globals.icmp_phone = icmp_connect_module();
-	
-	udp_globals.ip_phone = ip_bind_service(SERVICE_IP, IPPROTO_UDP,
-	    SERVICE_UDP, udp_receiver);
-	if (udp_globals.ip_phone < 0) {
-		fibril_rwlock_write_unlock(&udp_globals.lock);
-		return udp_globals.ip_phone;
+	udp_globals.net_sess = sess;
+	udp_globals.icmp_sess = icmp_connect_module();
+	
+	udp_globals.ip_sess = ip_bind_service(SERVICE_IP, IPPROTO_UDP,
+	     SERVICE_UDP, udp_receiver);
+	if (udp_globals.ip_sess == NULL) {
+	    fibril_rwlock_write_unlock(&udp_globals.lock);
+	    return ENOENT;
 	}
 	
 	/* Read default packet dimensions */
-	int rc = ip_packet_size_req(udp_globals.ip_phone, -1,
+	int rc = ip_packet_size_req(udp_globals.ip_sess, -1,
 	    &udp_globals.packet_dimension);
 	if (rc != EOK) {
@@ -435,5 +433,5 @@
 	/* Get configuration */
 	configuration = &names[0];
-	rc = net_get_conf_req(udp_globals.net_phone, &configuration, count,
+	rc = net_get_conf_req(udp_globals.net_sess, &configuration, count,
 	    &data);
 	if (rc != EOK) {
@@ -529,10 +527,10 @@
 
 	if (udp_globals.checksum_computing) {
-		rc = ip_get_route_req(udp_globals.ip_phone, IPPROTO_UDP, addr,
+		rc = ip_get_route_req(udp_globals.ip_sess, IPPROTO_UDP, addr,
 		    addrlen, &device_id, &ip_header, &headerlen);
 		if (rc != EOK)
 			return rc;
 		/* Get the device packet dimension */
-//		rc = tl_get_ip_packet_dimension(udp_globals.ip_phone,
+//		rc = tl_get_ip_packet_dimension(udp_globals.ip_sess,
 //		    &udp_globals.dimensions, device_id, &packet_dimension);
 //		if (rc != EOK)
@@ -541,5 +539,5 @@
 //	} else {
 		/* Do not ask all the time */
-		rc = ip_packet_size_req(udp_globals.ip_phone, -1,
+		rc = ip_packet_size_req(udp_globals.ip_sess, -1,
 		    &udp_globals.packet_dimension);
 		if (rc != EOK)
@@ -559,5 +557,5 @@
 
 	/* Read the first packet fragment */
-	result = tl_socket_read_packet_data(udp_globals.net_phone, &packet,
+	result = tl_socket_read_packet_data(udp_globals.net_sess, &packet,
 	    UDP_HEADER_SIZE, packet_dimension, addr, addrlen);
 	if (result < 0)
@@ -580,5 +578,5 @@
 	/* Read the rest of the packet fragments */
 	for (index = 1; index < fragments; index++) {
-		result = tl_socket_read_packet_data(udp_globals.net_phone,
+		result = tl_socket_read_packet_data(udp_globals.net_sess,
 		    &next_packet, 0, packet_dimension, addr, addrlen);
 		if (result < 0)
@@ -632,5 +630,5 @@
 
 	/* Send the packet */
-	ip_send_msg(udp_globals.ip_phone, device_id, packet, SERVICE_UDP, 0);
+	ip_send_msg(udp_globals.ip_sess, device_id, packet, SERVICE_UDP, 0);
 
 	return EOK;
@@ -679,5 +677,5 @@
 		return NO_DATA;
 	
-	rc = packet_translate_remote(udp_globals.net_phone, &packet, packet_id);
+	rc = packet_translate_remote(udp_globals.net_sess, &packet, packet_id);
 	if (rc != EOK) {
 		(void) dyn_fifo_pop(&socket->received);
@@ -739,19 +737,22 @@
 }
 
-/** Processes the socket client messages.
- *
- * Runs until the client module disconnects.
- *
- * @param[in] callid 	The message identifier.
- * @param[in] call	The message parameters.
- * @return		EOK on success.
- *
- * @see	socket.h
- */
-static int udp_process_client_messages(ipc_callid_t callid, ipc_call_t call)
+/** Process the socket client messages.
+ *
+ * Run until the client module disconnects.
+ *
+ * @see socket.h
+ *
+ * @param[in] sess   Callback session.
+ * @param[in] callid Message identifier.
+ * @param[in] call   Message parameters.
+ *
+ * @return EOK on success.
+ *
+ */
+static int udp_process_client_messages(async_sess_t *sess, ipc_callid_t callid,
+    ipc_call_t call)
 {
 	int res;
 	socket_cores_t local_sockets;
-	int app_phone = IPC_GET_PHONE(call);
 	struct sockaddr *addr;
 	int socket_id;
@@ -786,15 +787,15 @@
 		/* Get the next call */
 		callid = async_get_call(&call);
-		
+
+		/* Process the call */
 		if (!IPC_GET_IMETHOD(call)) {
 			res = EHANGUP;
 			break;
 		}
-
-		/* Process the call */
+		
 		switch (IPC_GET_IMETHOD(call)) {
 		case NET_SOCKET:
 			socket_id = SOCKET_GET_SOCKET_ID(call);
-			res = socket_create(&local_sockets, app_phone, NULL,
+			res = socket_create(&local_sockets, sess, NULL,
 			    &socket_id);
 			SOCKET_SET_SOCKET_ID(answer, socket_id);
@@ -804,5 +805,5 @@
 			
 			size = MAX_UDP_FRAGMENT_SIZE;
-			if (tl_get_ip_packet_dimension(udp_globals.ip_phone,
+			if (tl_get_ip_packet_dimension(udp_globals.ip_sess,
 			    &udp_globals.dimensions, DEVICE_INVALID_ID,
 			    &packet_dimension) == EOK) {
@@ -868,5 +869,5 @@
 		case NET_SOCKET_CLOSE:
 			fibril_rwlock_write_lock(&udp_globals.lock);
-			res = socket_destroy(udp_globals.net_phone,
+			res = socket_destroy(udp_globals.net_sess,
 			    SOCKET_GET_SOCKET_ID(call), &local_sockets,
 			    &udp_globals.sockets, NULL);
@@ -882,9 +883,9 @@
 	}
 
-	/* Release the application phone */
-	async_obsolete_hangup(app_phone);
+	/* Release the application session */
+	async_hangup(sess);
 
 	/* Release all local sockets */
-	socket_cores_release(udp_globals.net_phone, &local_sockets,
+	socket_cores_release(udp_globals.net_sess, &local_sockets,
 	    &udp_globals.sockets, NULL);
 
@@ -916,10 +917,10 @@
 {
 	*answer_count = 0;
-
-	switch (IPC_GET_IMETHOD(*call)) {
-	case IPC_M_CONNECT_TO_ME:
-		return udp_process_client_messages(callid, *call);
-	}
-
+	
+	async_sess_t *callback =
+	    async_callback_receive_start(EXCHANGE_SERIALIZE, call);
+	if (callback)
+		return udp_process_client_messages(callback, callid, *call);
+	
 	return ENOTSUP;
 }
Index: uspace/srv/net/tl/udp/udp.h
===================================================================
--- uspace/srv/net/tl/udp/udp.h	(revision eca52a800f89d716e768d8312dbea7309e514476)
+++ uspace/srv/net/tl/udp/udp.h	(revision f51f1938507c8e76d8166e8355d3d1d892c9dae0)
@@ -38,4 +38,5 @@
 #define NET_UDP_H_
 
+#include <async.h>
 #include <fibril_synch.h>
 #include <socket_core.h>
@@ -49,10 +50,10 @@
 /** UDP global data. */
 struct udp_globals {
-	/** Networking module phone. */
-	int net_phone;
-	/** IP module phone. */
-	int ip_phone;
-	/** ICMP module phone. */
-	int icmp_phone;
+	/** Networking module session. */
+	async_sess_t *net_sess;
+	/** IP module session. */
+	async_sess_t *ip_sess;
+	/** ICMP module session. */
+	async_sess_t *icmp_sess;
 	/** Packet dimension. */
 	packet_dimension_t packet_dimension;
