Index: kernel/arch/amd64/Makefile.inc
===================================================================
--- kernel/arch/amd64/Makefile.inc	(revision 3714e798ef2924b952664a38e4d79dd5605f73b8)
+++ kernel/arch/amd64/Makefile.inc	(revision 6a44ee4a35beb95618457c456010a40522d2996a)
@@ -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 3714e798ef2924b952664a38e4d79dd5605f73b8)
+++ kernel/arch/arm32/src/mach/gta02/gta02.c	(revision 6a44ee4a35beb95618457c456010a40522d2996a)
@@ -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 3714e798ef2924b952664a38e4d79dd5605f73b8)
+++ kernel/arch/arm32/src/mach/integratorcp/integratorcp.c	(revision 6a44ee4a35beb95618457c456010a40522d2996a)
@@ -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 3714e798ef2924b952664a38e4d79dd5605f73b8)
+++ kernel/arch/ia32/src/boot/vesa_real.inc	(revision 6a44ee4a35beb95618457c456010a40522d2996a)
@@ -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/src/drivers/ski.c
===================================================================
--- kernel/arch/ia64/src/drivers/ski.c	(revision 3714e798ef2924b952664a38e4d79dd5605f73b8)
+++ kernel/arch/ia64/src/drivers/ski.c	(revision 6a44ee4a35beb95618457c456010a40522d2996a)
@@ -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/mips32/Makefile.inc
===================================================================
--- kernel/arch/mips32/Makefile.inc	(revision 3714e798ef2924b952664a38e4d79dd5605f73b8)
+++ kernel/arch/mips32/Makefile.inc	(revision 6a44ee4a35beb95618457c456010a40522d2996a)
@@ -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 3714e798ef2924b952664a38e4d79dd5605f73b8)
+++ kernel/arch/mips32/include/cycle.h	(revision 6a44ee4a35beb95618457c456010a40522d2996a)
@@ -27,5 +27,5 @@
  */
 
-/** @addtogroup mips2
+/** @addtogroup mips32
  * @{
  */
Index: kernel/arch/mips32/include/debug.h
===================================================================
--- kernel/arch/mips32/include/debug.h	(revision 3714e798ef2924b952664a38e4d79dd5605f73b8)
+++ kernel/arch/mips32/include/debug.h	(revision 6a44ee4a35beb95618457c456010a40522d2996a)
@@ -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 3714e798ef2924b952664a38e4d79dd5605f73b8)
+++ kernel/arch/mips32/include/mm/frame.h	(revision 6a44ee4a35beb95618457c456010a40522d2996a)
@@ -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 3714e798ef2924b952664a38e4d79dd5605f73b8)
+++ kernel/arch/mips32/include/stack.h	(revision 6a44ee4a35beb95618457c456010a40522d2996a)
@@ -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 3714e798ef2924b952664a38e4d79dd5605f73b8)
+++ kernel/arch/mips32/src/cache.c	(revision 6a44ee4a35beb95618457c456010a40522d2996a)
@@ -27,5 +27,5 @@
  */
 
-/** @addtogroup mips32	
+/** @addtogroup mips32
  * @{
  */
Index: kernel/arch/mips32/src/cpu/cpu.c
===================================================================
--- kernel/arch/mips32/src/cpu/cpu.c	(revision 3714e798ef2924b952664a38e4d79dd5605f73b8)
+++ kernel/arch/mips32/src/cpu/cpu.c	(revision 6a44ee4a35beb95618457c456010a40522d2996a)
@@ -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 3714e798ef2924b952664a38e4d79dd5605f73b8)
+++ kernel/arch/mips32/src/fpu_context.c	(revision 6a44ee4a35beb95618457c456010a40522d2996a)
@@ -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 3714e798ef2924b952664a38e4d79dd5605f73b8)
+++ kernel/arch/mips32/src/mm/as.c	(revision 6a44ee4a35beb95618457c456010a40522d2996a)
@@ -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 3714e798ef2924b952664a38e4d79dd5605f73b8)
+++ kernel/arch/mips32/src/mm/tlb.c	(revision 6a44ee4a35beb95618457c456010a40522d2996a)
@@ -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 3714e798ef2924b952664a38e4d79dd5605f73b8)
+++ kernel/arch/mips32/src/start.S	(revision 6a44ee4a35beb95618457c456010a40522d2996a)
@@ -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 6a44ee4a35beb95618457c456010a40522d2996a)
+++ kernel/arch/mips64/Makefile.inc	(revision 6a44ee4a35beb95618457c456010a40522d2996a)
@@ -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 6a44ee4a35beb95618457c456010a40522d2996a)
+++ kernel/arch/mips64/_link.ld.in	(revision 6a44ee4a35beb95618457c456010a40522d2996a)
@@ -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 6a44ee4a35beb95618457c456010a40522d2996a)
+++ kernel/arch/mips64/include/arch.h	(revision 6a44ee4a35beb95618457c456010a40522d2996a)
@@ -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 6a44ee4a35beb95618457c456010a40522d2996a)
+++ kernel/arch/mips64/include/asm.h	(revision 6a44ee4a35beb95618457c456010a40522d2996a)
@@ -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 6a44ee4a35beb95618457c456010a40522d2996a)
+++ kernel/arch/mips64/include/asm/boot.h	(revision 6a44ee4a35beb95618457c456010a40522d2996a)
@@ -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 6a44ee4a35beb95618457c456010a40522d2996a)
+++ kernel/arch/mips64/include/asm/regname.h	(revision 6a44ee4a35beb95618457c456010a40522d2996a)
@@ -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 6a44ee4a35beb95618457c456010a40522d2996a)
+++ kernel/arch/mips64/include/atomic.h	(revision 6a44ee4a35beb95618457c456010a40522d2996a)
@@ -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 6a44ee4a35beb95618457c456010a40522d2996a)
+++ kernel/arch/mips64/include/barrier.h	(revision 6a44ee4a35beb95618457c456010a40522d2996a)
@@ -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 6a44ee4a35beb95618457c456010a40522d2996a)
+++ kernel/arch/mips64/include/cache.h	(revision 6a44ee4a35beb95618457c456010a40522d2996a)
@@ -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 6a44ee4a35beb95618457c456010a40522d2996a)
+++ kernel/arch/mips64/include/context.h	(revision 6a44ee4a35beb95618457c456010a40522d2996a)
@@ -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 6a44ee4a35beb95618457c456010a40522d2996a)
+++ kernel/arch/mips64/include/context_offset.h	(revision 6a44ee4a35beb95618457c456010a40522d2996a)
@@ -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 6a44ee4a35beb95618457c456010a40522d2996a)
+++ kernel/arch/mips64/include/cp0.h	(revision 6a44ee4a35beb95618457c456010a40522d2996a)
@@ -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 6a44ee4a35beb95618457c456010a40522d2996a)
+++ kernel/arch/mips64/include/cpu.h	(revision 6a44ee4a35beb95618457c456010a40522d2996a)
@@ -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 6a44ee4a35beb95618457c456010a40522d2996a)
+++ kernel/arch/mips64/include/cycle.h	(revision 6a44ee4a35beb95618457c456010a40522d2996a)
@@ -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 6a44ee4a35beb95618457c456010a40522d2996a)
+++ kernel/arch/mips64/include/debug.h	(revision 6a44ee4a35beb95618457c456010a40522d2996a)
@@ -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 6a44ee4a35beb95618457c456010a40522d2996a)
+++ kernel/arch/mips64/include/debugger.h	(revision 6a44ee4a35beb95618457c456010a40522d2996a)
@@ -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 6a44ee4a35beb95618457c456010a40522d2996a)
+++ kernel/arch/mips64/include/drivers/msim.h	(revision 6a44ee4a35beb95618457c456010a40522d2996a)
@@ -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 6a44ee4a35beb95618457c456010a40522d2996a)
+++ kernel/arch/mips64/include/elf.h	(revision 6a44ee4a35beb95618457c456010a40522d2996a)
@@ -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 6a44ee4a35beb95618457c456010a40522d2996a)
+++ kernel/arch/mips64/include/exception.h	(revision 6a44ee4a35beb95618457c456010a40522d2996a)
@@ -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 6a44ee4a35beb95618457c456010a40522d2996a)
+++ kernel/arch/mips64/include/faddr.h	(revision 6a44ee4a35beb95618457c456010a40522d2996a)
@@ -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 6a44ee4a35beb95618457c456010a40522d2996a)
+++ kernel/arch/mips64/include/fpu_context.h	(revision 6a44ee4a35beb95618457c456010a40522d2996a)
@@ -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 6a44ee4a35beb95618457c456010a40522d2996a)
+++ kernel/arch/mips64/include/interrupt.h	(revision 6a44ee4a35beb95618457c456010a40522d2996a)
@@ -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 6a44ee4a35beb95618457c456010a40522d2996a)
+++ kernel/arch/mips64/include/istate.h	(revision 6a44ee4a35beb95618457c456010a40522d2996a)
@@ -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 6a44ee4a35beb95618457c456010a40522d2996a)
+++ kernel/arch/mips64/include/mm/as.h	(revision 6a44ee4a35beb95618457c456010a40522d2996a)
@@ -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 6a44ee4a35beb95618457c456010a40522d2996a)
+++ kernel/arch/mips64/include/mm/asid.h	(revision 6a44ee4a35beb95618457c456010a40522d2996a)
@@ -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 6a44ee4a35beb95618457c456010a40522d2996a)
+++ kernel/arch/mips64/include/mm/frame.h	(revision 6a44ee4a35beb95618457c456010a40522d2996a)
@@ -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 6a44ee4a35beb95618457c456010a40522d2996a)
+++ kernel/arch/mips64/include/mm/page.h	(revision 6a44ee4a35beb95618457c456010a40522d2996a)
@@ -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 6a44ee4a35beb95618457c456010a40522d2996a)
+++ kernel/arch/mips64/include/mm/tlb.h	(revision 6a44ee4a35beb95618457c456010a40522d2996a)
@@ -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 6a44ee4a35beb95618457c456010a40522d2996a)
+++ kernel/arch/mips64/include/proc/task.h	(revision 6a44ee4a35beb95618457c456010a40522d2996a)
@@ -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 6a44ee4a35beb95618457c456010a40522d2996a)
+++ kernel/arch/mips64/include/proc/thread.h	(revision 6a44ee4a35beb95618457c456010a40522d2996a)
@@ -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 6a44ee4a35beb95618457c456010a40522d2996a)
+++ kernel/arch/mips64/include/smp/dorder.h	(revision 6a44ee4a35beb95618457c456010a40522d2996a)
@@ -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 6a44ee4a35beb95618457c456010a40522d2996a)
+++ kernel/arch/mips64/include/stack.h	(revision 6a44ee4a35beb95618457c456010a40522d2996a)
@@ -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 6a44ee4a35beb95618457c456010a40522d2996a)
+++ kernel/arch/mips64/include/types.h	(revision 6a44ee4a35beb95618457c456010a40522d2996a)
@@ -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 6a44ee4a35beb95618457c456010a40522d2996a)
+++ kernel/arch/mips64/src/asm.S	(revision 6a44ee4a35beb95618457c456010a40522d2996a)
@@ -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 6a44ee4a35beb95618457c456010a40522d2996a)
+++ kernel/arch/mips64/src/cache.c	(revision 6a44ee4a35beb95618457c456010a40522d2996a)
@@ -0,0 +1,1 @@
+../../mips32/src/cache.c
Index: kernel/arch/mips64/src/context.S
===================================================================
--- kernel/arch/mips64/src/context.S	(revision 6a44ee4a35beb95618457c456010a40522d2996a)
+++ kernel/arch/mips64/src/context.S	(revision 6a44ee4a35beb95618457c456010a40522d2996a)
@@ -0,0 +1,1 @@
+../../mips32/src/context.S
Index: kernel/arch/mips64/src/cpu
===================================================================
--- kernel/arch/mips64/src/cpu	(revision 6a44ee4a35beb95618457c456010a40522d2996a)
+++ kernel/arch/mips64/src/cpu	(revision 6a44ee4a35beb95618457c456010a40522d2996a)
@@ -0,0 +1,1 @@
+../../mips32/src/cpu
Index: kernel/arch/mips64/src/ddi
===================================================================
--- kernel/arch/mips64/src/ddi	(revision 6a44ee4a35beb95618457c456010a40522d2996a)
+++ kernel/arch/mips64/src/ddi	(revision 6a44ee4a35beb95618457c456010a40522d2996a)
@@ -0,0 +1,1 @@
+../../mips32/src/ddi
Index: kernel/arch/mips64/src/debug
===================================================================
--- kernel/arch/mips64/src/debug	(revision 6a44ee4a35beb95618457c456010a40522d2996a)
+++ kernel/arch/mips64/src/debug	(revision 6a44ee4a35beb95618457c456010a40522d2996a)
@@ -0,0 +1,1 @@
+../../mips32/src/debug
Index: kernel/arch/mips64/src/debugger.c
===================================================================
--- kernel/arch/mips64/src/debugger.c	(revision 6a44ee4a35beb95618457c456010a40522d2996a)
+++ kernel/arch/mips64/src/debugger.c	(revision 6a44ee4a35beb95618457c456010a40522d2996a)
@@ -0,0 +1,1 @@
+../../mips32/src/debugger.c
Index: kernel/arch/mips64/src/exception.c
===================================================================
--- kernel/arch/mips64/src/exception.c	(revision 6a44ee4a35beb95618457c456010a40522d2996a)
+++ kernel/arch/mips64/src/exception.c	(revision 6a44ee4a35beb95618457c456010a40522d2996a)
@@ -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 6a44ee4a35beb95618457c456010a40522d2996a)
+++ kernel/arch/mips64/src/fpu_context.c	(revision 6a44ee4a35beb95618457c456010a40522d2996a)
@@ -0,0 +1,1 @@
+../../mips32/src/fpu_context.c
Index: kernel/arch/mips64/src/interrupt.c
===================================================================
--- kernel/arch/mips64/src/interrupt.c	(revision 6a44ee4a35beb95618457c456010a40522d2996a)
+++ kernel/arch/mips64/src/interrupt.c	(revision 6a44ee4a35beb95618457c456010a40522d2996a)
@@ -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 6a44ee4a35beb95618457c456010a40522d2996a)
+++ kernel/arch/mips64/src/mips64.c	(revision 6a44ee4a35beb95618457c456010a40522d2996a)
@@ -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 6a44ee4a35beb95618457c456010a40522d2996a)
+++ kernel/arch/mips64/src/mm/as.c	(revision 6a44ee4a35beb95618457c456010a40522d2996a)
@@ -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 6a44ee4a35beb95618457c456010a40522d2996a)
+++ kernel/arch/mips64/src/mm/frame.c	(revision 6a44ee4a35beb95618457c456010a40522d2996a)
@@ -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 6a44ee4a35beb95618457c456010a40522d2996a)
+++ kernel/arch/mips64/src/mm/page.c	(revision 6a44ee4a35beb95618457c456010a40522d2996a)
@@ -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 6a44ee4a35beb95618457c456010a40522d2996a)
+++ kernel/arch/mips64/src/mm/tlb.c	(revision 6a44ee4a35beb95618457c456010a40522d2996a)
@@ -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 6a44ee4a35beb95618457c456010a40522d2996a)
+++ kernel/arch/mips64/src/smp/dorder.c	(revision 6a44ee4a35beb95618457c456010a40522d2996a)
@@ -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 6a44ee4a35beb95618457c456010a40522d2996a)
+++ kernel/arch/mips64/src/smp/smp.c	(revision 6a44ee4a35beb95618457c456010a40522d2996a)
@@ -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 6a44ee4a35beb95618457c456010a40522d2996a)
+++ kernel/arch/mips64/src/start.S	(revision 6a44ee4a35beb95618457c456010a40522d2996a)
@@ -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 3714e798ef2924b952664a38e4d79dd5605f73b8)
+++ kernel/arch/sparc64/Makefile.inc	(revision 6a44ee4a35beb95618457c456010a40522d2996a)
@@ -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: kernel/arch/sparc64/include/drivers/fhc.h
===================================================================
--- kernel/arch/sparc64/include/drivers/fhc.h	(revision 3714e798ef2924b952664a38e4d79dd5605f73b8)
+++ 	(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: kernel/arch/sparc64/include/drivers/sgcn.h
===================================================================
--- kernel/arch/sparc64/include/drivers/sgcn.h	(revision 3714e798ef2924b952664a38e4d79dd5605f73b8)
+++ 	(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 3714e798ef2924b952664a38e4d79dd5605f73b8)
+++ kernel/arch/sparc64/src/console.c	(revision 6a44ee4a35beb95618457c456010a40522d2996a)
@@ -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: kernel/arch/sparc64/src/drivers/fhc.c
===================================================================
--- kernel/arch/sparc64/src/drivers/fhc.c	(revision 3714e798ef2924b952664a38e4d79dd5605f73b8)
+++ 	(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 3714e798ef2924b952664a38e4d79dd5605f73b8)
+++ kernel/arch/sparc64/src/drivers/kbd.c	(revision 6a44ee4a35beb95618457c456010a40522d2996a)
@@ -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 3714e798ef2924b952664a38e4d79dd5605f73b8)
+++ kernel/arch/sparc64/src/drivers/niagara.c	(revision 6a44ee4a35beb95618457c456010a40522d2996a)
@@ -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: kernel/arch/sparc64/src/drivers/sgcn.c
===================================================================
--- kernel/arch/sparc64/src/drivers/sgcn.c	(revision 3714e798ef2924b952664a38e4d79dd5605f73b8)
+++ 	(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/arch/sparc64/src/drivers/tick.c
===================================================================
--- kernel/arch/sparc64/src/drivers/tick.c	(revision 3714e798ef2924b952664a38e4d79dd5605f73b8)
+++ kernel/arch/sparc64/src/drivers/tick.c	(revision 6a44ee4a35beb95618457c456010a40522d2996a)
@@ -44,6 +44,4 @@
 #include <debug.h>
 
-#define TICK_RESTART_TIME	50	/* Worst case estimate. */
-
 /** Initialize tick and stick interrupt. */
 void tick_init(void)
@@ -51,4 +49,5 @@
 	/* initialize TICK interrupt */
 	tick_compare_reg_t compare;
+	softint_reg_t clear;
 
 	interrupt_register(14, "tick_int", tick_interrupt);
@@ -59,8 +58,11 @@
 	tick_compare_write(compare.value);
 
+	clear.value = 0;
+	clear.tick_int = 1;
+	clear_softint_write(clear.value);
+
 #if defined (US3) || defined (SUN4V)
 	/* disable STICK interrupts and clear any pending ones */
 	tick_compare_reg_t stick_compare;
-	softint_reg_t clear;
 
 	stick_compare.value = stick_compare_read();
Index: kernel/genarch/Makefile.inc
===================================================================
--- kernel/genarch/Makefile.inc	(revision 3714e798ef2924b952664a38e4d79dd5605f73b8)
+++ kernel/genarch/Makefile.inc	(revision 6a44ee4a35beb95618457c456010a40522d2996a)
@@ -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 3714e798ef2924b952664a38e4d79dd5605f73b8)
+++ kernel/genarch/include/drivers/s3c24xx_uart/s3c24xx_uart.h	(revision 6a44ee4a35beb95618457c456010a40522d2996a)
@@ -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: kernel/genarch/include/drivers/z8530/z8530.h
===================================================================
--- kernel/genarch/include/drivers/z8530/z8530.h	(revision 3714e798ef2924b952664a38e4d79dd5605f73b8)
+++ 	(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: kernel/genarch/include/ofw/fhc.h
===================================================================
--- kernel/genarch/include/ofw/fhc.h	(revision 3714e798ef2924b952664a38e4d79dd5605f73b8)
+++ 	(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 3714e798ef2924b952664a38e4d79dd5605f73b8)
+++ kernel/genarch/src/drivers/dsrln/dsrlnout.c	(revision 6a44ee4a35beb95618457c456010a40522d2996a)
@@ -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 3714e798ef2924b952664a38e4d79dd5605f73b8)
+++ kernel/genarch/src/drivers/ega/ega.c	(revision 6a44ee4a35beb95618457c456010a40522d2996a)
@@ -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 3714e798ef2924b952664a38e4d79dd5605f73b8)
+++ kernel/genarch/src/drivers/s3c24xx_uart/s3c24xx_uart.c	(revision 6a44ee4a35beb95618457c456010a40522d2996a)
@@ -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: kernel/genarch/src/drivers/z8530/z8530.c
===================================================================
--- kernel/genarch/src/drivers/z8530/z8530.c	(revision 3714e798ef2924b952664a38e4d79dd5605f73b8)
+++ 	(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 3714e798ef2924b952664a38e4d79dd5605f73b8)
+++ kernel/genarch/src/fb/fb.c	(revision 6a44ee4a35beb95618457c456010a40522d2996a)
@@ -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: kernel/genarch/src/mm/asid.c
===================================================================
--- kernel/genarch/src/mm/asid.c	(revision 3714e798ef2924b952664a38e4d79dd5605f73b8)
+++ kernel/genarch/src/mm/asid.c	(revision 6a44ee4a35beb95618457c456010a40522d2996a)
@@ -97,6 +97,6 @@
 		 * inactive address space.
 		 */
-		ASSERT(!list_empty(&inactive_as_with_asid_head));
-		tmp = inactive_as_with_asid_head.next;
+		tmp = list_first(&inactive_as_with_asid_list);
+		ASSERT(tmp != NULL);
 		list_remove(tmp);
 		
Index: kernel/genarch/src/ofw/fhc.c
===================================================================
--- kernel/genarch/src/ofw/fhc.c	(revision 3714e798ef2924b952664a38e4d79dd5605f73b8)
+++ 	(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/adt/btree.h
===================================================================
--- kernel/generic/include/adt/btree.h	(revision 3714e798ef2924b952664a38e4d79dd5605f73b8)
+++ kernel/generic/include/adt/btree.h	(revision 6a44ee4a35beb95618457c456010a40522d2996a)
@@ -89,5 +89,5 @@
 typedef struct {
 	btree_node_t *root;	/**< B-tree root node pointer. */
-	link_t leaf_head;	/**< Leaf-level list head. */
+	list_t leaf_list;	/**< List of leaves. */
 } btree_t;
 
Index: kernel/generic/include/adt/hash_table.h
===================================================================
--- kernel/generic/include/adt/hash_table.h	(revision 3714e798ef2924b952664a38e4d79dd5605f73b8)
+++ kernel/generic/include/adt/hash_table.h	(revision 6a44ee4a35beb95618457c456010a40522d2996a)
@@ -68,5 +68,5 @@
 /** Hash table structure. */
 typedef struct {
-	link_t *entry;
+	list_t *entry;
 	size_t entries;
 	size_t max_keys;
Index: kernel/generic/include/adt/list.h
===================================================================
--- kernel/generic/include/adt/list.h	(revision 3714e798ef2924b952664a38e4d79dd5605f73b8)
+++ kernel/generic/include/adt/list.h	(revision 6a44ee4a35beb95618457c456010a40522d2996a)
@@ -1,4 +1,5 @@
 /*
  * Copyright (c) 2001-2004 Jakub Jermar
+ * Copyright (c) 2011 Jiri Svoboda
  * All rights reserved.
  *
@@ -39,5 +40,5 @@
 #include <trace.h>
 
-/** Doubly linked list head and link type. */
+/** Doubly linked list link. */
 typedef struct link {
 	struct link *prev;  /**< Pointer to the previous item in the list. */
@@ -45,4 +46,9 @@
 } link_t;
 
+/** Doubly linked list. */
+typedef struct list {
+	link_t head;  /**< List head. Does not have any data. */
+} list_t;
+
 /** Declare and initialize statically allocated list.
  *
@@ -51,7 +57,9 @@
  */
 #define LIST_INITIALIZE(name) \
-	link_t name = { \
-		.prev = &name, \
-		.next = &name \
+	list_t name = { \
+		.head = { \
+			.prev = &(name).head, \
+			.next = &(name).head \
+		} \
 	}
 
@@ -60,6 +68,9 @@
 
 #define list_foreach(list, iterator) \
-	for (link_t *iterator = (list).next; \
-	    iterator != &(list); iterator = iterator->next)
+	for (link_t *iterator = (list).head.next; \
+	    iterator != &(list).head; iterator = iterator->next)
+
+#define assert_link_not_used(link) \
+	ASSERT((link)->prev == NULL && (link)->next == NULL)
 
 /** Initialize doubly-linked circular list link
@@ -80,11 +91,33 @@
  * Initialize doubly-linked circular list.
  *
- * @param list Pointer to link_t structure representing the list.
- *
- */
-NO_TRACE static inline void list_initialize(link_t *list)
-{
-	list->prev = list;
-	list->next = list;
+ * @param list Pointer to list_t structure.
+ *
+ */
+NO_TRACE static inline void list_initialize(list_t *list)
+{
+	list->head.prev = &list->head;
+	list->head.next = &list->head;
+}
+
+/** Insert item before another item in doubly-linked circular list.
+ *
+ */
+static inline void list_insert_before(link_t *lnew, link_t *lold)
+{
+	lnew->next = lold;
+	lnew->prev = lold->prev;
+	lold->prev->next = lnew;
+	lold->prev = lnew;
+}
+
+/** Insert item after another item in doubly-linked circular list.
+ *
+ */
+static inline void list_insert_after(link_t *lnew, link_t *lold)
+{
+	lnew->prev = lold;
+	lnew->next = lold->next;
+	lold->next->prev = lnew;
+	lold->next = lnew;
 }
 
@@ -94,13 +127,10 @@
  *
  * @param link Pointer to link_t structure to be added.
- * @param list Pointer to link_t structure representing the list.
- *
- */
-NO_TRACE static inline void list_prepend(link_t *link, link_t *list)
-{
-	link->next = list->next;
-	link->prev = list;
-	list->next->prev = link;
-	list->next = link;
+ * @param list Pointer to list_t structure.
+ *
+ */
+NO_TRACE static inline void list_prepend(link_t *link, list_t *list)
+{
+	list_insert_after(link, &list->head);
 }
 
@@ -110,29 +140,10 @@
  *
  * @param link Pointer to link_t structure to be added.
- * @param list Pointer to link_t structure representing the list.
- *
- */
-NO_TRACE static inline void list_append(link_t *link, link_t *list)
-{
-	link->prev = list->prev;
-	link->next = list;
-	list->prev->next = link;
-	list->prev = link;
-}
-
-/** Insert item before another item in doubly-linked circular list.
- *
- */
-static inline void list_insert_before(link_t *link, link_t *list)
-{
-	list_append(link, list);
-}
-
-/** Insert item after another item in doubly-linked circular list.
- *
- */
-static inline void list_insert_after(link_t *link, link_t *list)
-{
-	list_prepend(list, link);
+ * @param list Pointer to list_t structure.
+ *
+ */
+NO_TRACE static inline void list_append(link_t *link, list_t *list)
+{
+	list_insert_before(link, &list->head);
 }
 
@@ -156,15 +167,15 @@
  * Query emptiness of doubly-linked circular list.
  *
- * @param list Pointer to link_t structure representing the list.
- *
- */
-NO_TRACE static inline int list_empty(link_t *list)
-{
-	return (list->next == list);
-}
-
-/** Get head item of a list.
- *
- * @param list Pointer to link_t structure representing the list.
+ * @param list Pointer to lins_t structure.
+ *
+ */
+NO_TRACE static inline int list_empty(list_t *list)
+{
+	return (list->head.next == &list->head);
+}
+
+/** Get first item in list.
+ *
+ * @param list Pointer to list_t structure.
  *
  * @return Head item of the list.
@@ -172,7 +183,20 @@
  *
  */
-static inline link_t *list_head(link_t *list)
-{
-	return ((list->next == list) ? NULL : list->next);
+static inline link_t *list_first(list_t *list)
+{
+	return ((list->head.next == &list->head) ? NULL : list->head.next);
+}
+
+/** Get last item in list.
+ *
+ * @param list Pointer to list_t structure.
+ *
+ * @return Head item of the list.
+ * @return NULL if the list is empty.
+ *
+ */
+static inline link_t *list_last(list_t *list)
+{
+	return ((list->head.prev == &list->head) ? NULL : list->head.prev);
 }
 
@@ -231,5 +255,5 @@
 }
 
-/** Get n-th item of a list.
+/** Get n-th item in a list.
  *
  * @param list Pointer to link_t structure representing the list.
@@ -240,5 +264,5 @@
  *
  */
-static inline link_t *list_nth(link_t *list, unsigned int n)
+static inline link_t *list_nth(list_t *list, unsigned int n)
 {
 	unsigned int cnt = 0;
@@ -254,7 +278,7 @@
 }
 
-extern int list_member(const link_t *, const link_t *);
-extern void list_concat(link_t *, link_t *);
-extern unsigned int list_count(const link_t *);
+extern int list_member(const link_t *, const list_t *);
+extern void list_concat(list_t *, list_t *);
+extern unsigned int list_count(const list_t *);
 
 #endif
Index: kernel/generic/include/console/chardev.h
===================================================================
--- kernel/generic/include/console/chardev.h	(revision 3714e798ef2924b952664a38e4d79dd5605f73b8)
+++ kernel/generic/include/console/chardev.h	(revision 6a44ee4a35beb95618457c456010a40522d2996a)
@@ -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. */
@@ -88,5 +88,5 @@
 	/** Fields suitable for multiplexing. */
 	link_t link;
-	link_t list;
+	list_t list;
 	
 	/** Implementation of outdev operations. */
Index: kernel/generic/include/console/console.h
===================================================================
--- kernel/generic/include/console/console.h	(revision 3714e798ef2924b952664a38e4d79dd5605f73b8)
+++ kernel/generic/include/console/console.h	(revision 6a44ee4a35beb95618457c456010a40522d2996a)
@@ -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/console/kconsole.h
===================================================================
--- kernel/generic/include/console/kconsole.h	(revision 3714e798ef2924b952664a38e4d79dd5605f73b8)
+++ kernel/generic/include/console/kconsole.h	(revision 6a44ee4a35beb95618457c456010a40522d2996a)
@@ -91,5 +91,5 @@
 
 SPINLOCK_EXTERN(cmd_lock);
-extern link_t cmd_head;
+extern list_t cmd_list;
 
 extern void kconsole_init(void);
Index: kernel/generic/include/cpu.h
===================================================================
--- kernel/generic/include/cpu.h	(revision 3714e798ef2924b952664a38e4d79dd5605f73b8)
+++ kernel/generic/include/cpu.h	(revision 6a44ee4a35beb95618457c456010a40522d2996a)
@@ -59,5 +59,5 @@
 	
 	IRQ_SPINLOCK_DECLARE(timeoutlock);
-	link_t timeout_active_head;
+	list_t timeout_active_list;
 	
 	/**
Index: kernel/generic/include/ddi/ddi.h
===================================================================
--- kernel/generic/include/ddi/ddi.h	(revision 3714e798ef2924b952664a38e4d79dd5605f73b8)
+++ kernel/generic/include/ddi/ddi.h	(revision 6a44ee4a35beb95618457c456010a40522d2996a)
@@ -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/ddi/irq.h
===================================================================
--- kernel/generic/include/ddi/irq.h	(revision 3714e798ef2924b952664a38e4d79dd5605f73b8)
+++ kernel/generic/include/ddi/irq.h	(revision 6a44ee4a35beb95618457c456010a40522d2996a)
@@ -77,5 +77,26 @@
 	 */
 	CMD_PIO_WRITE_A_32,
-	
+
+	/** Read 1 byte from the memory space. */
+	CMD_MEM_READ_8,
+	/** Read 2 bytes from the memory space. */
+	CMD_MEM_READ_16,
+	/** Read 4 bytes from the memory space. */
+	CMD_MEM_READ_32,
+
+	/** Write 1 byte to the memory space. */
+	CMD_MEM_WRITE_8,
+	/** Write 2 bytes to the memory space. */
+	CMD_MEM_WRITE_16,
+	/** Write 4 bytes to the memory space. */
+	CMD_MEM_WRITE_32,
+
+	/** Write 1 byte from the source argument to the memory space. */
+	CMD_MEM_WRITE_A_8,
+	/** Write 2 bytes from the source argument to the memory space. */
+	CMD_MEM_WRITE_A_16,
+	/** Write 4 bytes from the source argument to the memory space. */
+	CMD_MEM_WRITE_A_32,
+
 	/**
 	 * Perform a bit masking on the source argument
@@ -203,4 +224,6 @@
 	/** Notification configuration structure. */
 	ipc_notif_cfg_t notif_cfg; 
+
+	as_t *driver_as;
 } irq_t;
 
Index: kernel/generic/include/ipc/ipc.h
===================================================================
--- kernel/generic/include/ipc/ipc.h	(revision 3714e798ef2924b952664a38e4d79dd5605f73b8)
+++ kernel/generic/include/ipc/ipc.h	(revision 6a44ee4a35beb95618457c456010a40522d2996a)
@@ -100,7 +100,4 @@
 #define IPC_GET_ARG5(data)  ((data).args[5])
 
-/* Well known phone descriptors */
-#define PHONE_NS  0
-
 /* Forwarding flags. */
 #define IPC_FF_NONE  0
@@ -117,150 +114,10 @@
 
 /* Data transfer flags. */
-#define IPC_XF_NONE		0
+#define IPC_XF_NONE  0
 
 /** Restrict the transfer size if necessary. */
-#define IPC_XF_RESTRICT		(1 << 0)
-
-/** Kernel IPC interfaces
- *
- */
-#define IPC_IF_KERNEL  0
-
-/** System-specific methods - only through special syscalls
- *
- * These methods have special behaviour. These methods also
- * have the implicit kernel interface 0.
- *
- */
-
-/** Clone connection.
- *
- * The calling task clones one of its phones for the callee.
- *
- * - ARG1 - The caller sets ARG1 to the phone of the cloned connection.
- *        - The callee gets the new phone from ARG1.
- *
- * - on answer, the callee acknowledges the new connection by sending EOK back
- *   or the kernel closes it
- *
- */
-#define IPC_M_CONNECTION_CLONE  1
-
-/** Protocol for CONNECT - ME
- *
- * Through this call, the recipient learns about the new cloned connection. 
- *
- * - ARG5 - the kernel sets ARG5 to contain the hash of the used phone
- * - on asnwer, the callee acknowledges the new connection by sending EOK back
- *   or the kernel closes it
- *
- */
-#define IPC_M_CONNECT_ME  2
-
-/** Protocol for CONNECT - TO - ME
- *
- * Calling process asks the callee to create a callback connection,
- * so that it can start initiating new messages.
- *
- * The protocol for negotiating is:
- * - sys_connect_to_me - sends a message IPC_M_CONNECT_TO_ME
- * - recipient         - upon receipt tries to allocate new phone
- *                       - if it fails, responds with ELIMIT
- *                     - passes call to userspace. If userspace
- *                       responds with error, phone is deallocated and
- *                       error is sent back to caller. Otherwise 
- *                       the call is accepted and the response is sent back.
- *                     - the hash of the client task is passed to userspace
- *                       (on the receiving side) as ARG4 of the call.
- *                     - the hash of the allocated phone is passed to userspace
- *                       (on the receiving side) as ARG5 of the call.
- *
- */
-#define IPC_M_CONNECT_TO_ME  3
-
-/** Protocol for CONNECT - ME - TO
- *
- * Calling process asks the callee to create for him a new connection.
- * E.g. the caller wants a name server to connect him to print server.
- *
- * The protocol for negotiating is:
- * - sys_connect_me_to - send a synchronous message to name server
- *                       indicating that it wants to be connected to some
- *                       service
- *                     - arg1/2/3 are user specified, arg5 contains
- *                       address of the phone that should be connected
- *                       (TODO: it leaks to userspace)
- *  - recipient        -  if ipc_answer == 0, then accept connection
- *                     -  otherwise connection refused
- *                     -  recepient may forward message.
- *
- */
-#define IPC_M_CONNECT_ME_TO  4
-
-/** This message is sent to answerbox when the phone is hung up
- *
- */
-#define IPC_M_PHONE_HUNGUP  5
-
-/** Send as_area over IPC.
- * - ARG1 - source as_area base address
- * - ARG2 - size of source as_area (filled automatically by kernel)
- * - ARG3 - flags of the as_area being sent
- *
- * on answer, the recipient must set:
- * - ARG1 - dst as_area base adress
- *
- */
-#define IPC_M_SHARE_OUT  6
-
-/** Receive as_area over IPC.
- * - ARG1 - destination as_area base address
- * - ARG2 - destination as_area size
- * - ARG3 - user defined argument
- *
- * on answer, the recipient must set:
- *
- * - ARG1 - source as_area base address
- * - ARG2 - flags that will be used for sharing
- *
- */
-#define IPC_M_SHARE_IN  7
-
-/** Send data to another address space over IPC.
- * - ARG1 - source address space virtual address
- * - ARG2 - size of data to be copied, may be overriden by the recipient
- *
- * on answer, the recipient must set:
- *
- * - ARG1 - final destination address space virtual address
- * - ARG2 - final size of data to be copied
- *
- */
-#define IPC_M_DATA_WRITE  8
-
-/** Receive data from another address space over IPC.
- * - ARG1 - destination virtual address in the source address space
- * - ARG2 - size of data to be received, may be cropped by the recipient 
- *
- * on answer, the recipient must set:
- *
- * - ARG1 - source virtual address in the destination address space
- * - ARG2 - final size of data to be copied
- *
- */
-#define IPC_M_DATA_READ  9
-
-/** Debug the recipient.
- * - ARG1 - specifies the debug method (from udebug_method_t)
- * - other arguments are specific to the debug method
- *
- */
-#define IPC_M_DEBUG_ALL  10
-
-/* Well-known methods */
-#define IPC_M_LAST_SYSTEM  511
-#define IPC_M_PING         512
-
-/* User methods */
+#define IPC_XF_RESTRICT  (1 << 0)
+
+/** User-defined IPC methods */
 #define IPC_FIRST_USER_METHOD  1024
 
@@ -309,18 +166,18 @@
 	
 	/** Phones connected to this answerbox. */
-	link_t connected_phones;
+	list_t connected_phones;
 	/** Received calls. */
-	link_t calls;
-	link_t dispatched_calls;  /* Should be hash table in the future */
+	list_t calls;
+	list_t dispatched_calls;  /* Should be hash table in the future */
 	
 	/** Answered calls. */
-	link_t answers;
+	list_t answers;
 	
 	IRQ_SPINLOCK_DECLARE(irq_lock);
 	
 	/** Notifications from IRQ handlers. */
-	link_t irq_notifs;
+	list_t irq_notifs;
 	/** IRQs with notifications to this answerbox. */
-	link_t irq_head;
+	list_t irq_list;
 } answerbox_t;
 
@@ -386,5 +243,5 @@
 extern void ipc_backsend_err(phone_t *, call_t *, sysarg_t);
 extern void ipc_answerbox_slam_phones(answerbox_t *, bool);
-extern void ipc_cleanup_call_list(link_t *);
+extern void ipc_cleanup_call_list(list_t *);
 
 extern void ipc_print_task(task_id_t);
Index: kernel/generic/include/ipc/ipc_methods.h
===================================================================
--- kernel/generic/include/ipc/ipc_methods.h	(revision 6a44ee4a35beb95618457c456010a40522d2996a)
+++ kernel/generic/include/ipc/ipc_methods.h	(revision 6a44ee4a35beb95618457c456010a40522d2996a)
@@ -0,0 +1,186 @@
+/*
+ * 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 genericipc
+ * @{
+ */
+/** @file
+ */
+
+#ifndef KERN_IPC_METHODS_H_
+#define KERN_IPC_METHODS_H_
+
+/* Well known phone descriptors */
+#define PHONE_NS  0
+
+/** Kernel IPC interfaces
+ *
+ */
+#define IPC_IF_KERNEL  0
+
+/** System-specific IPC methods
+ *
+ * These methods have special behaviour. These methods also
+ * have the implicit kernel interface zero (0).
+ *
+ */
+
+/** This message is sent to answerbox when the phone is hung up
+ *
+ * The numerical value zero (0) of this method is important,
+ * so as the value can be easily tested in conditions.
+ *
+ */
+#define IPC_M_PHONE_HUNGUP  0
+
+/** Clone connection.
+ *
+ * The calling task clones one of its phones for the callee.
+ *
+ * - ARG1 - The caller sets ARG1 to the phone of the cloned connection.
+ *        - The callee gets the new phone from ARG1.
+ *
+ * - on answer, the callee acknowledges the new connection by sending EOK back
+ *   or the kernel closes it
+ *
+ */
+#define IPC_M_CONNECTION_CLONE  1
+
+/** Protocol for CONNECT - ME
+ *
+ * Through this call, the recipient learns about the new cloned connection.
+ *
+ * - ARG5 - the kernel sets ARG5 to contain the hash of the used phone
+ * - on answer, the callee acknowledges the new connection by sending EOK back
+ *   or the kernel closes it
+ *
+ */
+#define IPC_M_CONNECT_ME  2
+
+/** Protocol for CONNECT - TO - ME
+ *
+ * Calling process asks the callee to create a callback connection,
+ * so that it can start initiating new messages.
+ *
+ * The protocol for negotiating is:
+ * - sys_connect_to_me - sends a message IPC_M_CONNECT_TO_ME
+ * - recipient         - upon receipt tries to allocate new phone
+ *                       - if it fails, responds with ELIMIT
+ *                     - passes call to userspace. If userspace
+ *                       responds with error, phone is deallocated and
+ *                       error is sent back to caller. Otherwise 
+ *                       the call is accepted and the response is sent back.
+ *                     - the hash of the client task is passed to userspace
+ *                       (on the receiving side) as ARG4 of the call.
+ *                     - the hash of the allocated phone is passed to userspace
+ *                       (on the receiving side) as ARG5 of the call.
+ *
+ */
+#define IPC_M_CONNECT_TO_ME  3
+
+/** Protocol for CONNECT - ME - TO
+ *
+ * Calling process asks the callee to create for him a new connection.
+ * E.g. the caller wants a name server to connect him to print server.
+ *
+ * The protocol for negotiating is:
+ * - sys_connect_me_to - send a synchronous message to name server
+ *                       indicating that it wants to be connected to some
+ *                       service
+ *                     - arg1/2/3 are user specified, arg5 contains
+ *                       address of the phone that should be connected
+ *                       (TODO: it leaks to userspace)
+ *  - recipient        -  if ipc_answer == 0, then accept connection
+ *                     -  otherwise connection refused
+ *                     -  recepient may forward message.
+ *
+ */
+#define IPC_M_CONNECT_ME_TO  4
+
+/** Send as_area over IPC.
+ * - ARG1 - source as_area base address
+ * - ARG2 - size of source as_area (filled automatically by kernel)
+ * - ARG3 - flags of the as_area being sent
+ *
+ * on answer, the recipient must set:
+ * - ARG1 - dst as_area base adress
+ *
+ */
+#define IPC_M_SHARE_OUT  5
+
+/** Receive as_area over IPC.
+ * - ARG1 - destination as_area base address
+ * - ARG2 - destination as_area size
+ * - ARG3 - user defined argument
+ *
+ * on answer, the recipient must set:
+ *
+ * - ARG1 - source as_area base address
+ * - ARG2 - flags that will be used for sharing
+ *
+ */
+#define IPC_M_SHARE_IN  6
+
+/** Send data to another address space over IPC.
+ * - ARG1 - source address space virtual address
+ * - ARG2 - size of data to be copied, may be overriden by the recipient
+ *
+ * on answer, the recipient must set:
+ *
+ * - ARG1 - final destination address space virtual address
+ * - ARG2 - final size of data to be copied
+ *
+ */
+#define IPC_M_DATA_WRITE  7
+
+/** Receive data from another address space over IPC.
+ * - ARG1 - destination virtual address in the source address space
+ * - ARG2 - size of data to be received, may be cropped by the recipient 
+ *
+ * on answer, the recipient must set:
+ *
+ * - ARG1 - source virtual address in the destination address space
+ * - ARG2 - final size of data to be copied
+ *
+ */
+#define IPC_M_DATA_READ  8
+
+/** Debug the recipient.
+ * - ARG1 - specifies the debug method (from udebug_method_t)
+ * - other arguments are specific to the debug method
+ *
+ */
+#define IPC_M_DEBUG  9
+
+/** Last system IPC method */
+#define IPC_M_LAST_SYSTEM  511
+
+#endif
+
+/** @}
+ */
Index: kernel/generic/include/mm/as.h
===================================================================
--- kernel/generic/include/mm/as.h	(revision 3714e798ef2924b952664a38e4d79dd5605f73b8)
+++ kernel/generic/include/mm/as.h	(revision 6a44ee4a35beb95618457c456010a40522d2996a)
@@ -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>
@@ -254,5 +255,5 @@
 
 extern as_operations_t *as_operations;
-extern link_t inactive_as_with_asid_head;
+extern list_t inactive_as_with_asid_list;
 
 extern void as_init(void);
Index: kernel/generic/include/mm/buddy.h
===================================================================
--- kernel/generic/include/mm/buddy.h	(revision 3714e798ef2924b952664a38e4d79dd5605f73b8)
+++ kernel/generic/include/mm/buddy.h	(revision 6a44ee4a35beb95618457c456010a40522d2996a)
@@ -72,5 +72,5 @@
 	/** Maximal order of block which can be stored by buddy system. */
 	uint8_t max_order;
-	link_t *order;
+	list_t *order;
 	buddy_system_operations_t *op;
 	/** Pointer to be used by the implementation. */
Index: kernel/generic/include/mm/page.h
===================================================================
--- kernel/generic/include/mm/page.h	(revision 3714e798ef2924b952664a38e4d79dd5605f73b8)
+++ kernel/generic/include/mm/page.h	(revision 6a44ee4a35beb95618457c456010a40522d2996a)
@@ -37,4 +37,5 @@
 
 #include <typedefs.h>
+#include <proc/task.h>
 #include <mm/as.h>
 #include <arch/mm/page.h>
@@ -65,4 +66,6 @@
 extern uintptr_t hw_map(uintptr_t, size_t);
 
+extern sysarg_t sys_page_find_mapping(uintptr_t, uintptr_t *);
+
 #endif
 
Index: kernel/generic/include/mm/slab.h
===================================================================
--- kernel/generic/include/mm/slab.h	(revision 3714e798ef2924b952664a38e4d79dd5605f73b8)
+++ kernel/generic/include/mm/slab.h	(revision 6a44ee4a35beb95618457c456010a40522d2996a)
@@ -111,9 +111,9 @@
 	
 	/* Slabs */
-	link_t full_slabs;     /**< List of full slabs */
-	link_t partial_slabs;  /**< List of partial slabs */
+	list_t full_slabs;     /**< List of full slabs */
+	list_t partial_slabs;  /**< List of partial slabs */
 	SPINLOCK_DECLARE(slablock);
 	/* Magazines */
-	link_t magazines;  /**< List o full magazines */
+	list_t magazines;  /**< List o full magazines */
 	SPINLOCK_DECLARE(maglock);
 	
Index: kernel/generic/include/panic.h
===================================================================
--- kernel/generic/include/panic.h	(revision 3714e798ef2924b952664a38e4d79dd5605f73b8)
+++ kernel/generic/include/panic.h	(revision 6a44ee4a35beb95618457c456010a40522d2996a)
@@ -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/proc/scheduler.h
===================================================================
--- kernel/generic/include/proc/scheduler.h	(revision 3714e798ef2924b952664a38e4d79dd5605f73b8)
+++ kernel/generic/include/proc/scheduler.h	(revision 6a44ee4a35beb95618457c456010a40522d2996a)
@@ -48,6 +48,6 @@
 typedef struct {
 	IRQ_SPINLOCK_DECLARE(lock);
-	link_t rq_head;              /**< List of ready threads. */
-	size_t n;                    /**< Number of threads in rq_ready. */
+	list_t rq;			/**< List of ready threads. */
+	size_t n;			/**< Number of threads in rq_ready. */
 } runq_t;
 
Index: kernel/generic/include/proc/task.h
===================================================================
--- kernel/generic/include/proc/task.h	(revision 3714e798ef2924b952664a38e4d79dd5605f73b8)
+++ kernel/generic/include/proc/task.h	(revision 6a44ee4a35beb95618457c456010a40522d2996a)
@@ -73,5 +73,5 @@
 	char name[TASK_NAME_BUFLEN];
 	/** List of threads contained in this task. */
-	link_t th_head;
+	list_t threads;
 	/** Address space. */
 	as_t *as;
@@ -94,5 +94,5 @@
 	stats_ipc_t ipc_info;   /**< IPC statistics */
 	/** List of synchronous answerboxes. */
-	link_t sync_box_head;
+	list_t sync_boxes;
 	
 #ifdef CONFIG_UDEBUG
Index: kernel/generic/include/proc/thread.h
===================================================================
--- kernel/generic/include/proc/thread.h	(revision 3714e798ef2924b952664a38e4d79dd5605f73b8)
+++ kernel/generic/include/proc/thread.h	(revision 6a44ee4a35beb95618457c456010a40522d2996a)
@@ -156,4 +156,7 @@
 	int fpu_context_engaged;
 	
+	/* The thread will not be migrated if nomigrate is non-zero. */
+	int nomigrate;
+	
 	/** Thread's state. */
 	state_t state;
@@ -245,4 +248,7 @@
 extern bool thread_exists(thread_t *);
 
+extern void thread_migration_disable(void);
+extern void thread_migration_enable(void);
+
 #ifdef CONFIG_UDEBUG
 extern void thread_stack_trace(thread_id_t);
@@ -258,4 +264,5 @@
 extern sysarg_t sys_thread_get_id(thread_id_t *);
 extern sysarg_t sys_thread_usleep(uint32_t);
+extern sysarg_t sys_thread_udelay(uint32_t);
 
 #endif
Index: kernel/generic/include/synch/waitq.h
===================================================================
--- kernel/generic/include/synch/waitq.h	(revision 3714e798ef2924b952664a38e4d79dd5605f73b8)
+++ kernel/generic/include/synch/waitq.h	(revision 6a44ee4a35beb95618457c456010a40522d2996a)
@@ -63,5 +63,5 @@
 	
 	/** List of sleeping threads for which there was no missed_wakeup. */
-	link_t head;
+	list_t sleepers;
 } waitq_t;
 
Index: kernel/generic/include/syscall/syscall.h
===================================================================
--- kernel/generic/include/syscall/syscall.h	(revision 3714e798ef2924b952664a38e4d79dd5605f73b8)
+++ kernel/generic/include/syscall/syscall.h	(revision 6a44ee4a35beb95618457c456010a40522d2996a)
@@ -44,4 +44,5 @@
 	SYS_THREAD_GET_ID,
 	SYS_THREAD_USLEEP,
+	SYS_THREAD_UDELAY,
 	
 	SYS_TASK_GET_ID,
@@ -60,4 +61,6 @@
 	SYS_AS_AREA_DESTROY,
 	SYS_AS_GET_UNMAPPED_AREA,
+	
+	SYS_PAGE_FIND_MAPPING,
 	
 	SYS_IPC_CALL_SYNC_FAST,
@@ -91,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/adt/btree.c
===================================================================
--- kernel/generic/src/adt/btree.c	(revision 3714e798ef2924b952664a38e4d79dd5605f73b8)
+++ kernel/generic/src/adt/btree.c	(revision 6a44ee4a35beb95618457c456010a40522d2996a)
@@ -108,8 +108,8 @@
 void btree_create(btree_t *t)
 {
-	list_initialize(&t->leaf_head);
+	list_initialize(&t->leaf_list);
 	t->root = (btree_node_t *) slab_alloc(btree_node_slab, 0);
 	node_initialize(t->root);
-	list_append(&t->root->leaf_link, &t->leaf_head);
+	list_append(&t->root->leaf_link, &t->leaf_list);
 }
 
@@ -588,5 +588,5 @@
 		
 		if (LEAF_NODE(node)) {
-			list_prepend(&rnode->leaf_link, &node->leaf_link);
+			list_insert_after(&rnode->leaf_link, &node->leaf_link);
 		}
 		
@@ -953,5 +953,5 @@
 	ASSERT(LEAF_NODE(node));
 	
-	if (node->leaf_link.prev != &t->leaf_head)
+	if (node->leaf_link.prev != &t->leaf_list.head)
 		return list_get_instance(node->leaf_link.prev, btree_node_t, leaf_link);
 	else
@@ -972,5 +972,5 @@
 	ASSERT(LEAF_NODE(node));
 	
-	if (node->leaf_link.next != &t->leaf_head)
+	if (node->leaf_link.next != &t->leaf_list.head)
 		return list_get_instance(node->leaf_link.next, btree_node_t, leaf_link);
 	else
@@ -987,9 +987,9 @@
 	size_t i;
 	int depth = t->root->depth;
-	link_t head, *cur;
+	list_t list;
 	
 	printf("Printing B-tree:\n");
-	list_initialize(&head);
-	list_append(&t->root->bfs_link, &head);
+	list_initialize(&list);
+	list_append(&t->root->bfs_link, &list);
 	
 	/*
@@ -997,10 +997,10 @@
 	 * Levels are distinguished from one another by node->depth.
 	 */
-	while (!list_empty(&head)) {
+	while (!list_empty(&list)) {
 		link_t *hlp;
 		btree_node_t *node;
 		
-		hlp = head.next;
-		ASSERT(hlp != &head);
+		hlp = list_first(&list);
+		ASSERT(hlp != NULL);
 		node = list_get_instance(hlp, btree_node_t, bfs_link);
 		list_remove(hlp);
@@ -1018,10 +1018,10 @@
 			printf("%" PRIu64 "%s", node->key[i], i < node->keys - 1 ? "," : "");
 			if (node->depth && node->subtree[i]) {
-				list_append(&node->subtree[i]->bfs_link, &head);
+				list_append(&node->subtree[i]->bfs_link, &list);
 			}
 		}
 		
 		if (node->depth && node->subtree[i])
-			list_append(&node->subtree[i]->bfs_link, &head);
+			list_append(&node->subtree[i]->bfs_link, &list);
 		
 		printf(")");
@@ -1031,5 +1031,5 @@
 	
 	printf("Printing list of leaves:\n");
-	for (cur = t->leaf_head.next; cur != &t->leaf_head; cur = cur->next) {
+	list_foreach(t->leaf_list, cur) {
 		btree_node_t *node;
 		
Index: kernel/generic/src/adt/hash_table.c
===================================================================
--- kernel/generic/src/adt/hash_table.c	(revision 3714e798ef2924b952664a38e4d79dd5605f73b8)
+++ kernel/generic/src/adt/hash_table.c	(revision 6a44ee4a35beb95618457c456010a40522d2996a)
@@ -62,9 +62,9 @@
 	ASSERT(max_keys > 0);
 	
-	h->entry = (link_t *) malloc(m * sizeof(link_t), 0);
+	h->entry = (list_t *) malloc(m * sizeof(list_t), 0);
 	if (!h->entry)
 		panic("Cannot allocate memory for hash table.");
 	
-	memsetb(h->entry, m * sizeof(link_t), 0);
+	memsetb(h->entry, m * sizeof(list_t), 0);
 	
 	for (i = 0; i < m; i++)
@@ -107,5 +107,4 @@
 link_t *hash_table_find(hash_table_t *h, sysarg_t key[])
 {
-	link_t *cur;
 	size_t chain;
 	
@@ -118,5 +117,5 @@
 	ASSERT(chain < h->entries);
 	
-	for (cur = h->entry[chain].next; cur != &h->entry[chain]; cur = cur->next) {
+	list_foreach(h->entry[chain], cur) {
 		if (h->op->compare(key, h->max_keys, cur)) {
 			/*
@@ -141,5 +140,4 @@
 {
 	size_t chain;
-	link_t *cur;
 	
 	ASSERT(h);
@@ -149,6 +147,8 @@
 	ASSERT(keys <= h->max_keys);
 	
+	
 	if (keys == h->max_keys) {
-	
+		link_t *cur;
+		
 		/*
 		 * All keys are known, hash_table_find() can be used to find the entry.
@@ -169,5 +169,7 @@
 	 */
 	for (chain = 0; chain < h->entries; chain++) {
-		for (cur = h->entry[chain].next; cur != &h->entry[chain]; cur = cur->next) {
+		link_t *cur;
+		for (cur = h->entry[chain].head.next; cur != &h->entry[chain].head;
+		    cur = cur->next) {
 			if (h->op->compare(key, keys, cur)) {
 				link_t *hlp;
Index: kernel/generic/src/adt/list.c
===================================================================
--- kernel/generic/src/adt/list.c	(revision 3714e798ef2924b952664a38e4d79dd5605f73b8)
+++ kernel/generic/src/adt/list.c	(revision 6a44ee4a35beb95618457c456010a40522d2996a)
@@ -43,19 +43,19 @@
 /** Check for membership
  *
- * Check whether link is contained in the list head.
- * The membership is defined as pointer equivalence.
+ * Check whether link is contained in a list.
+ * Membership is defined as pointer equivalence.
  *
- * @param link Item to look for.
- * @param head List to look in.
+ * @param link	Item to look for.
+ * @param list	List to look in.
  *
  * @return true if link is contained in head, false otherwise.
  *
  */
-int list_member(const link_t *link, const link_t *head)
+int list_member(const link_t *link, const list_t *list)
 {
 	bool found = false;
-	link_t *hlp = head->next;
+	link_t *hlp = list->head.next;
 	
-	while (hlp != head) {
+	while (hlp != &list->head) {
 		if (hlp == link) {
 			found = true;
@@ -68,25 +68,42 @@
 }
 
-
 /** Concatenate two lists
  *
- * Concatenate lists head1 and head2, producing a single
- * list head1 containing items from both (in head1, head2
- * order) and empty list head2.
+ * Concatenate lists @a list1 and @a list2, producing a single
+ * list @a list1 containing items from both (in @a list1, @a list2
+ * order) and empty list @a list2.
  *
- * @param head1 First list and concatenated output
- * @param head2 Second list and empty output.
+ * @param list1		First list and concatenated output
+ * @param list2 	Second list and empty output.
  *
  */
-void list_concat(link_t *head1, link_t *head2)
+void list_concat(list_t *list1, list_t *list2)
 {
-	if (list_empty(head2))
+	if (list_empty(list2))
 		return;
 
-	head2->next->prev = head1->prev;
-	head2->prev->next = head1;	
-	head1->prev->next = head2->next;
-	head1->prev = head2->prev;
-	list_initialize(head2);
+	list2->head.next->prev = list1->head.prev;
+	list2->head.prev->next = &list1->head;
+	list1->head.prev->next = list2->head.next;
+	list1->head.prev = list2->head.prev;
+	list_initialize(list2);
+}
+
+/** Count list items
+ *
+ * Return the number of items in the list.
+ *
+ * @param list		List to count.
+ * @return		Number of items in the list.
+ */
+unsigned int list_count(const list_t *list)
+{
+	unsigned int count = 0;
+	
+	list_foreach(*list, link) {
+		count++;
+	}
+	
+	return count;
 }
 
Index: kernel/generic/src/console/cmd.c
===================================================================
--- kernel/generic/src/console/cmd.c	(revision 3714e798ef2924b952664a38e4d79dd5605f73b8)
+++ kernel/generic/src/console/cmd.c	(revision 6a44ee4a35beb95618457c456010a40522d2996a)
@@ -573,7 +573,6 @@
 	spinlock_lock(&cmd_lock);
 	
-	link_t *cur;
 	size_t len = 0;
-	for (cur = cmd_head.next; cur != &cmd_head; cur = cur->next) {
+	list_foreach(cmd_list, cur) {
 		cmd_info_t *hlp;
 		hlp = list_get_instance(cur, cmd_info_t, link);
@@ -591,5 +590,5 @@
 	}
 	
-	for (cur = cmd_head.next; cur != &cmd_head; cur = cur->next) {
+	list_foreach(cmd_list, cur) {
 		cmd_info_t *hlp;
 		hlp = list_get_instance(cur, cmd_info_t, link);
@@ -646,9 +645,7 @@
 int cmd_desc(cmd_arg_t *argv)
 {
-	link_t *cur;
-	
 	spinlock_lock(&cmd_lock);
 	
-	for (cur = cmd_head.next; cur != &cmd_head; cur = cur->next) {
+	list_foreach(cmd_list, cur) {
 		cmd_info_t *hlp;
 		
Index: kernel/generic/src/console/console.c
===================================================================
--- kernel/generic/src/console/console.c	(revision 3714e798ef2924b952664a38e4d79dd5605f73b8)
+++ kernel/generic/src/console/console.c	(revision 6a44ee4a35beb95618457c456010a40522d2996a)
@@ -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,12 +122,10 @@
 }
 
-static void stdout_write(outdev_t *dev, wchar_t ch, bool silent)
-{
-	link_t *cur;
-	
-	for (cur = dev->list.next; cur != &dev->list; cur = cur->next) {
+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);
 	}
 }
@@ -135,7 +133,5 @@
 static void stdout_redraw(outdev_t *dev)
 {
-	link_t *cur;
-	
-	for (cur = dev->list.next; cur != &dev->list; cur = cur->next) {
+	list_foreach(dev->list, cur) {
 		outdev_t *sink = list_get_instance(cur, outdev_t, link);
 		if ((sink) && (sink->op->redraw))
@@ -160,4 +156,5 @@
 	klog_parea.frames = SIZE2FRAMES(sizeof(klog));
 	klog_parea.unpriv = false;
+	klog_parea.mapped = false;
 	ddi_parea_register(&klog_parea);
 	
@@ -171,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.
@@ -187,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
@@ -200,11 +196,4 @@
 	return false;
 #endif
-}
-
-/** Tell kernel to relinquish keyboard/console access */
-sysarg_t sys_debug_disable_console(void)
-{
-	release_console();
-	return true;
 }
 
@@ -293,5 +282,5 @@
 			 */
 			spinlock_unlock(&klog_lock);
-			stdout->op->write(stdout, tmp, silent);
+			stdout->op->write(stdout, tmp);
 			spinlock_lock(&klog_lock);
 		}
@@ -321,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/console/kconsole.c
===================================================================
--- kernel/generic/src/console/kconsole.c	(revision 3714e798ef2924b952664a38e4d79dd5605f73b8)
+++ kernel/generic/src/console/kconsole.c	(revision 6a44ee4a35beb95618457c456010a40522d2996a)
@@ -84,5 +84,5 @@
 
 SPINLOCK_INITIALIZE(cmd_lock);  /**< Lock protecting command list. */
-LIST_INITIALIZE(cmd_head);      /**< Command list. */
+LIST_INITIALIZE(cmd_list);      /**< Command list. */
 
 static wchar_t history[KCONSOLE_HISTORY][MAX_CMDLINE] = {};
@@ -113,6 +113,4 @@
 bool cmd_register(cmd_info_t *cmd)
 {
-	link_t *cur;
-	
 	spinlock_lock(&cmd_lock);
 	
@@ -120,5 +118,5 @@
 	 * Make sure the command is not already listed.
 	 */
-	for (cur = cmd_head.next; cur != &cmd_head; cur = cur->next) {
+	list_foreach(cmd_list, cur) {
 		cmd_info_t *hlp = list_get_instance(cur, cmd_info_t, link);
 		
@@ -153,5 +151,5 @@
 	 * Now the command can be added.
 	 */
-	list_append(&cmd->link, &cmd_head);
+	list_append(&cmd->link, &cmd_list);
 	
 	spinlock_unlock(&cmd_lock);
@@ -176,7 +174,7 @@
 	
 	if (*startpos == NULL)
-		*startpos = cmd_head.next;
-	
-	for (; *startpos != &cmd_head; *startpos = (*startpos)->next) {
+		*startpos = cmd_list.head.next;
+	
+	for (; *startpos != &cmd_list.head; *startpos = (*startpos)->next) {
 		cmd_info_t *hlp = list_get_instance(*startpos, cmd_info_t, link);
 		
@@ -559,7 +557,6 @@
 	
 	cmd_info_t *cmd = NULL;
-	link_t *cur;
-	
-	for (cur = cmd_head.next; cur != &cmd_head; cur = cur->next) {
+	
+	list_foreach(cmd_list, cur) {
 		cmd_info_t *hlp = list_get_instance(cur, cmd_info_t, link);
 		spinlock_lock(&hlp->lock);
Index: kernel/generic/src/cpu/cpu.c
===================================================================
--- kernel/generic/src/cpu/cpu.c	(revision 3714e798ef2924b952664a38e4d79dd5605f73b8)
+++ kernel/generic/src/cpu/cpu.c	(revision 6a44ee4a35beb95618457c456010a40522d2996a)
@@ -82,5 +82,5 @@
 			for (j = 0; j < RQ_COUNT; j++) {
 				irq_spinlock_initialize(&cpus[i].rq[j].lock, "cpus[].rq[].lock");
-				list_initialize(&cpus[i].rq[j].rq_head);
+				list_initialize(&cpus[i].rq[j].rq);
 			}
 		}
Index: kernel/generic/src/ddi/ddi.c
===================================================================
--- kernel/generic/src/ddi/ddi.c	(revision 3714e798ef2924b952664a38e4d79dd5605f73b8)
+++ kernel/generic/src/ddi/ddi.c	(revision 6a44ee4a35beb95618457c456010a40522d2996a)
@@ -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 3714e798ef2924b952664a38e4d79dd5605f73b8)
+++ kernel/generic/src/ddi/irq.c	(revision 6a44ee4a35beb95618457c456010a40522d2996a)
@@ -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 3714e798ef2924b952664a38e4d79dd5605f73b8)
+++ kernel/generic/src/debug/panic.c	(revision 6a44ee4a35beb95618457c456010a40522d2996a)
@@ -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/ipc/ipc.c
===================================================================
--- kernel/generic/src/ipc/ipc.c	(revision 3714e798ef2924b952664a38e4d79dd5605f73b8)
+++ kernel/generic/src/ipc/ipc.c	(revision 6a44ee4a35beb95618457c456010a40522d2996a)
@@ -44,4 +44,5 @@
 #include <synch/synch.h>
 #include <ipc/ipc.h>
+#include <ipc/ipc_methods.h>
 #include <ipc/kbox.h>
 #include <ipc/event.h>
@@ -127,5 +128,5 @@
 	list_initialize(&box->answers);
 	list_initialize(&box->irq_notifs);
-	list_initialize(&box->irq_head);
+	list_initialize(&box->irq_list);
 	box->task = task;
 }
@@ -182,5 +183,5 @@
 	 */
 	irq_spinlock_lock(&TASK->lock, true);
-	list_append(&sync_box->sync_box_link, &TASK->sync_box_head);
+	list_append(&sync_box->sync_box_link, &TASK->sync_boxes);
 	irq_spinlock_unlock(&TASK->lock, true);
 	
@@ -449,5 +450,6 @@
 		irq_spinlock_lock(&box->irq_lock, false);
 		
-		request = list_get_instance(box->irq_notifs.next, call_t, link);
+		request = list_get_instance(list_first(&box->irq_notifs),
+		    call_t, link);
 		list_remove(&request->link);
 		
@@ -458,5 +460,6 @@
 		
 		/* Handle asynchronous answers */
-		request = list_get_instance(box->answers.next, call_t, link);
+		request = list_get_instance(list_first(&box->answers),
+		    call_t, link);
 		list_remove(&request->link);
 		atomic_dec(&request->data.phone->active_calls);
@@ -466,5 +469,6 @@
 		
 		/* Handle requests */
-		request = list_get_instance(box->calls.next, call_t, link);
+		request = list_get_instance(list_first(&box->calls),
+		    call_t, link);
 		list_remove(&request->link);
 		
@@ -493,8 +497,8 @@
  *
  */
-void ipc_cleanup_call_list(link_t *lst)
+void ipc_cleanup_call_list(list_t *lst)
 {
 	while (!list_empty(lst)) {
-		call_t *call = list_get_instance(lst->next, call_t, link);
+		call_t *call = list_get_instance(list_first(lst), call_t, link);
 		if (call->buffer)
 			free(call->buffer);
@@ -525,5 +529,5 @@
 	irq_spinlock_lock(&box->lock, true);
 	while (!list_empty(&box->connected_phones)) {
-		phone = list_get_instance(box->connected_phones.next,
+		phone = list_get_instance(list_first(&box->connected_phones),
 		    phone_t, link);
 		if (SYNCH_FAILED(mutex_trylock(&phone->lock))) {
@@ -605,7 +609,7 @@
 	/* Wait for all answers to interrupted synchronous calls to arrive */
 	ipl_t ipl = interrupts_disable();
-	while (!list_empty(&TASK->sync_box_head)) {
-		answerbox_t *box = list_get_instance(TASK->sync_box_head.next,
-		    answerbox_t, sync_box_link);
+	while (!list_empty(&TASK->sync_boxes)) {
+		answerbox_t *box = list_get_instance(
+		    list_first(&TASK->sync_boxes), answerbox_t, sync_box_link);
 		
 		list_remove(&box->sync_box_link);
@@ -742,9 +746,6 @@
 #endif
 	
-	link_t *cur;
-	
 	printf(" --- incomming calls ---\n");
-	for (cur = task->answerbox.calls.next; cur != &task->answerbox.calls;
-	    cur = cur->next) {
+	list_foreach(task->answerbox.calls, cur) {
 		call_t *call = list_get_instance(cur, call_t, link);
 		
@@ -766,7 +767,5 @@
 	
 	printf(" --- dispatched calls ---\n");
-	for (cur = task->answerbox.dispatched_calls.next;
-	    cur != &task->answerbox.dispatched_calls;
-	    cur = cur->next) {
+	list_foreach(task->answerbox.dispatched_calls, cur) {
 		call_t *call = list_get_instance(cur, call_t, link);
 		
@@ -788,7 +787,5 @@
 	
 	printf(" --- incoming answers ---\n");
-	for (cur = task->answerbox.answers.next;
-	    cur != &task->answerbox.answers;
-	    cur = cur->next) {
+	list_foreach(task->answerbox.answers, cur) {
 		call_t *call = list_get_instance(cur, call_t, link);
 		
Index: kernel/generic/src/ipc/ipcrsc.c
===================================================================
--- kernel/generic/src/ipc/ipcrsc.c	(revision 3714e798ef2924b952664a38e4d79dd5605f73b8)
+++ kernel/generic/src/ipc/ipcrsc.c	(revision 6a44ee4a35beb95618457c456010a40522d2996a)
@@ -146,10 +146,9 @@
 call_t *get_call(sysarg_t callid)
 {
-	link_t *lst;
 	call_t *result = NULL;
 	
 	irq_spinlock_lock(&TASK->answerbox.lock, true);
-	for (lst = TASK->answerbox.dispatched_calls.next;
-	    lst != &TASK->answerbox.dispatched_calls; lst = lst->next) {
+	
+	list_foreach(TASK->answerbox.dispatched_calls, lst) {
 		call_t *call = list_get_instance(lst, call_t, link);
 		if ((sysarg_t) call == callid) {
Index: kernel/generic/src/ipc/irq.c
===================================================================
--- kernel/generic/src/ipc/irq.c	(revision 3714e798ef2924b952664a38e4d79dd5605f73b8)
+++ kernel/generic/src/ipc/irq.c	(revision 6a44ee4a35beb95618457c456010a40522d2996a)
@@ -174,4 +174,5 @@
 	irq->notif_cfg.code = code;
 	irq->notif_cfg.counter = 0;
+	irq->driver_as = AS;
 	
 	/*
@@ -199,5 +200,5 @@
 	
 	hash_table_insert(&irq_uspace_hash_table, key, &irq->link);
-	list_append(&irq->notif_cfg.link, &box->irq_head);
+	list_append(&irq->notif_cfg.link, &box->irq_list);
 	
 	irq_spinlock_unlock(&box->irq_lock, false);
@@ -281,8 +282,8 @@
 	irq_spinlock_lock(&box->irq_lock, false);
 	
-	while (box->irq_head.next != &box->irq_head) {
+	while (!list_empty(&box->irq_list)) {
 		DEADLOCK_PROBE_INIT(p_irqlock);
 		
-		irq_t *irq = list_get_instance(box->irq_head.next, irq_t,
+		irq_t *irq = list_get_instance(list_first(&box->irq_list), irq_t,
 		    notif_cfg.link);
 		
@@ -364,4 +365,23 @@
 		return IRQ_DECLINE;
 	
+#define CMD_MEM_READ(target) \
+do { \
+	void *va = code->cmds[i].addr; \
+	if (AS != irq->driver_as) \
+		as_switch(AS, irq->driver_as); \
+	memcpy_from_uspace(&target, va, (sizeof(target))); \
+	if (dstarg) \
+		scratch[dstarg] = target; \
+} while(0)
+
+#define CMD_MEM_WRITE(val) \
+do { \
+	void *va = code->cmds[i].addr; \
+	if (AS != irq->driver_as) \
+		as_switch(AS, irq->driver_as); \
+	memcpy_to_uspace(va, &val, sizeof(val)); \
+} while (0)
+
+	as_t *current_as = AS;
 	size_t i;
 	for (i = 0; i < code->cmdcount; i++) {
@@ -422,4 +442,52 @@
 			}
 			break;
+		case CMD_MEM_READ_8: {
+			uint8_t val;
+			CMD_MEM_READ(val);
+			break;
+			}
+		case CMD_MEM_READ_16: {
+			uint16_t val;
+			CMD_MEM_READ(val);
+			break;
+			}
+		case CMD_MEM_READ_32: {
+			uint32_t val;
+			CMD_MEM_READ(val);
+			break;
+			}
+		case CMD_MEM_WRITE_8: {
+			uint8_t val = code->cmds[i].value;
+			CMD_MEM_WRITE(val);
+			break;
+			}
+		case CMD_MEM_WRITE_16: {
+			uint16_t val = code->cmds[i].value;
+			CMD_MEM_WRITE(val);
+			break;
+			}
+		case CMD_MEM_WRITE_32: {
+			uint32_t val = code->cmds[i].value;
+			CMD_MEM_WRITE(val);
+			break;
+			}
+		case CMD_MEM_WRITE_A_8:
+			if (srcarg) {
+				uint8_t val = scratch[srcarg];
+				CMD_MEM_WRITE(val);
+			}
+			break;
+		case CMD_MEM_WRITE_A_16:
+			if (srcarg) {
+				uint16_t val = scratch[srcarg];
+				CMD_MEM_WRITE(val);
+			}
+			break;
+		case CMD_MEM_WRITE_A_32:
+			if (srcarg) {
+				uint32_t val = scratch[srcarg];
+				CMD_MEM_WRITE(val);
+			}
+			break;
 		case CMD_BTEST:
 			if ((srcarg) && (dstarg)) {
@@ -435,10 +503,16 @@
 			break;
 		case CMD_ACCEPT:
+			if (AS != current_as)
+				as_switch(AS, current_as);
 			return IRQ_ACCEPT;
 		case CMD_DECLINE:
 		default:
+			if (AS != current_as)
+				as_switch(AS, current_as);
 			return IRQ_DECLINE;
 		}
 	}
+	if (AS != current_as)
+		as_switch(AS, current_as);
 	
 	return IRQ_DECLINE;
Index: kernel/generic/src/ipc/kbox.c
===================================================================
--- kernel/generic/src/ipc/kbox.c	(revision 3714e798ef2924b952664a38e4d79dd5605f73b8)
+++ kernel/generic/src/ipc/kbox.c	(revision 6a44ee4a35beb95618457c456010a40522d2996a)
@@ -37,4 +37,5 @@
 #include <synch/mutex.h>
 #include <ipc/ipc.h>
+#include <ipc/ipc_methods.h>
 #include <ipc/ipcrsc.h>
 #include <arch.h>
@@ -169,5 +170,5 @@
 		switch (IPC_GET_IMETHOD(call->data)) {
 		
-		case IPC_M_DEBUG_ALL:
+		case IPC_M_DEBUG:
 			/* Handle debug call. */
 			udebug_call_receive(call);
Index: kernel/generic/src/ipc/sysipc.c
===================================================================
--- kernel/generic/src/ipc/sysipc.c	(revision 3714e798ef2924b952664a38e4d79dd5605f73b8)
+++ kernel/generic/src/ipc/sysipc.c	(revision 6a44ee4a35beb95618457c456010a40522d2996a)
@@ -40,4 +40,5 @@
 #include <debug.h>
 #include <ipc/ipc.h>
+#include <ipc/ipc_methods.h>
 #include <ipc/sysipc.h>
 #include <ipc/irq.h>
@@ -460,5 +461,5 @@
 	}
 #ifdef CONFIG_UDEBUG
-	case IPC_M_DEBUG_ALL:
+	case IPC_M_DEBUG:
 		return udebug_request_preprocess(call, phone);
 #endif
@@ -495,5 +496,5 @@
 		/*
 		 * This must be an affirmative answer to IPC_M_DATA_READ
-		 * or IPC_M_DEBUG_ALL/UDEBUG_M_MEM_READ...
+		 * or IPC_M_DEBUG/UDEBUG_M_MEM_READ...
 		 *
 		 */
@@ -531,5 +532,5 @@
 	
 	switch (IPC_GET_IMETHOD(call->data)) {
-	case IPC_M_DEBUG_ALL:
+	case IPC_M_DEBUG:
 		return -1;
 	default:
Index: kernel/generic/src/lib/rd.c
===================================================================
--- kernel/generic/src/lib/rd.c	(revision 3714e798ef2924b952664a38e4d79dd5605f73b8)
+++ kernel/generic/src/lib/rd.c	(revision 6a44ee4a35beb95618457c456010a40522d2996a)
@@ -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/main/version.c
===================================================================
--- kernel/generic/src/main/version.c	(revision 3714e798ef2924b952664a38e4d79dd5605f73b8)
+++ kernel/generic/src/main/version.c	(revision 6a44ee4a35beb95618457c456010a40522d2996a)
@@ -38,5 +38,5 @@
 
 static const char *project = "SPARTAN kernel";
-static const char *copyright = "Copyright (c) 2001-2010 HelenOS project";
+static const char *copyright = "Copyright (c) 2001-2011 HelenOS project";
 static const char *release = STRING(RELEASE);
 static const char *name = STRING(NAME);
Index: kernel/generic/src/mm/as.c
===================================================================
--- kernel/generic/src/mm/as.c	(revision 3714e798ef2924b952664a38e4d79dd5605f73b8)
+++ kernel/generic/src/mm/as.c	(revision 6a44ee4a35beb95618457c456010a40522d2996a)
@@ -94,5 +94,5 @@
  *
  * This lock protects:
- * - inactive_as_with_asid_head list
+ * - inactive_as_with_asid_list
  * - as->asid for each as of the as_t type
  * - asids_allocated counter
@@ -105,5 +105,5 @@
  * that have valid ASID.
  */
-LIST_INITIALIZE(inactive_as_with_asid_head);
+LIST_INITIALIZE(inactive_as_with_asid_list);
 
 /** Kernel address space. */
@@ -235,8 +235,8 @@
 	bool cond = true;
 	while (cond) {
-		ASSERT(!list_empty(&as->as_area_btree.leaf_head));
+		ASSERT(!list_empty(&as->as_area_btree.leaf_list));
 		
 		btree_node_t *node =
-		    list_get_instance(as->as_area_btree.leaf_head.next,
+		    list_get_instance(list_first(&as->as_area_btree.leaf_list),
 		    btree_node_t, leaf_link);
 		
@@ -602,8 +602,8 @@
 		bool cond = true;
 		while (cond) {
-			ASSERT(!list_empty(&area->used_space.leaf_head));
+			ASSERT(!list_empty(&area->used_space.leaf_list));
 			
 			btree_node_t *node =
-			    list_get_instance(area->used_space.leaf_head.prev,
+			    list_get_instance(list_last(&area->used_space.leaf_list),
 			    btree_node_t, leaf_link);
 			
@@ -727,5 +727,4 @@
 	if (--sh_info->refcount == 0) {
 		dealloc = true;
-		link_t *cur;
 		
 		/*
@@ -733,6 +732,5 @@
 		 * reference from all frames found there.
 		 */
-		for (cur = sh_info->pagemap.leaf_head.next;
-		    cur != &sh_info->pagemap.leaf_head; cur = cur->next) {
+		list_foreach(sh_info->pagemap.leaf_list, cur) {
 			btree_node_t *node
 			    = list_get_instance(cur, btree_node_t, leaf_link);
@@ -786,7 +784,5 @@
 	 * Visit only the pages mapped by used_space B+tree.
 	 */
-	link_t *cur;
-	for (cur = area->used_space.leaf_head.next;
-	    cur != &area->used_space.leaf_head; cur = cur->next) {
+	list_foreach(area->used_space.leaf_list, cur) {
 		btree_node_t *node;
 		btree_key_t i;
@@ -1065,8 +1061,6 @@
 	 */
 	size_t used_pages = 0;
-	link_t *cur;
-	
-	for (cur = area->used_space.leaf_head.next;
-	    cur != &area->used_space.leaf_head; cur = cur->next) {
+	
+	list_foreach(area->used_space.leaf_list, cur) {
 		btree_node_t *node
 		    = list_get_instance(cur, btree_node_t, leaf_link);
@@ -1094,6 +1088,5 @@
 	size_t frame_idx = 0;
 	
-	for (cur = area->used_space.leaf_head.next;
-	    cur != &area->used_space.leaf_head; cur = cur->next) {
+	list_foreach(area->used_space.leaf_list, cur) {
 		btree_node_t *node = list_get_instance(cur, btree_node_t,
 		    leaf_link);
@@ -1147,6 +1140,5 @@
 	frame_idx = 0;
 	
-	for (cur = area->used_space.leaf_head.next;
-	    cur != &area->used_space.leaf_head; cur = cur->next) {
+	list_foreach(area->used_space.leaf_list, cur) {
 		btree_node_t *node
 		    = list_get_instance(cur, btree_node_t, leaf_link);
@@ -1292,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.
@@ -1334,5 +1326,5 @@
 			
 			list_append(&old_as->inactive_as_with_asid_link,
-			    &inactive_as_with_asid_head);
+			    &inactive_as_with_asid_list);
 		}
 		
@@ -2027,8 +2019,8 @@
 	
 	/* Eventually check the addresses behind each area */
-	link_t *cur;
-	for (cur = AS->as_area_btree.leaf_head.next;
-	    (ret == 0) && (cur != &AS->as_area_btree.leaf_head);
-	    cur = cur->next) {
+	list_foreach(AS->as_area_btree.leaf_list, cur) {
+		if (ret != 0)
+			break;
+
 		btree_node_t *node =
 		    list_get_instance(cur, btree_node_t, leaf_link);
@@ -2072,8 +2064,6 @@
 	
 	size_t area_cnt = 0;
-	link_t *cur;
-	
-	for (cur = as->as_area_btree.leaf_head.next;
-	    cur != &as->as_area_btree.leaf_head; cur = cur->next) {
+	
+	list_foreach(as->as_area_btree.leaf_list, cur) {
 		btree_node_t *node =
 		    list_get_instance(cur, btree_node_t, leaf_link);
@@ -2088,6 +2078,5 @@
 	size_t area_idx = 0;
 	
-	for (cur = as->as_area_btree.leaf_head.next;
-	    cur != &as->as_area_btree.leaf_head; cur = cur->next) {
+	list_foreach(as->as_area_btree.leaf_list, cur) {
 		btree_node_t *node =
 		    list_get_instance(cur, btree_node_t, leaf_link);
@@ -2125,7 +2114,5 @@
 	
 	/* Print out info about address space areas */
-	link_t *cur;
-	for (cur = as->as_area_btree.leaf_head.next;
-	    cur != &as->as_area_btree.leaf_head; cur = cur->next) {
+	list_foreach(as->as_area_btree.leaf_list, cur) {
 		btree_node_t *node
 		    = list_get_instance(cur, btree_node_t, leaf_link);
Index: kernel/generic/src/mm/backend_anon.c
===================================================================
--- kernel/generic/src/mm/backend_anon.c	(revision 3714e798ef2924b952664a38e4d79dd5605f73b8)
+++ kernel/generic/src/mm/backend_anon.c	(revision 6a44ee4a35beb95618457c456010a40522d2996a)
@@ -97,6 +97,4 @@
 void anon_share(as_area_t *area)
 {
-	link_t *cur;
-
 	ASSERT(mutex_locked(&area->as->lock));
 	ASSERT(mutex_locked(&area->lock));
@@ -106,6 +104,5 @@
 	 */
 	mutex_lock(&area->sh_info->lock);
-	for (cur = area->used_space.leaf_head.next;
-	    cur != &area->used_space.leaf_head; cur = cur->next) {
+	list_foreach(area->used_space.leaf_list, cur) {
 		btree_node_t *node;
 		unsigned int i;
Index: kernel/generic/src/mm/backend_elf.c
===================================================================
--- kernel/generic/src/mm/backend_elf.c	(revision 3714e798ef2924b952664a38e4d79dd5605f73b8)
+++ kernel/generic/src/mm/backend_elf.c	(revision 6a44ee4a35beb95618457c456010a40522d2996a)
@@ -139,5 +139,5 @@
 	 */
 	if (area->flags & AS_AREA_WRITE) {
-		node = list_get_instance(area->used_space.leaf_head.next,
+		node = list_get_instance(list_first(&area->used_space.leaf_list),
 		    btree_node_t, leaf_link);
 	} else {
@@ -153,5 +153,5 @@
 	 */
 	mutex_lock(&area->sh_info->lock);
-	for (cur = &node->leaf_link; cur != &area->used_space.leaf_head;
+	for (cur = &node->leaf_link; cur != &area->used_space.leaf_list.head;
 	    cur = cur->next) {
 		unsigned int i;
Index: kernel/generic/src/mm/buddy.c
===================================================================
--- kernel/generic/src/mm/buddy.c	(revision 3714e798ef2924b952664a38e4d79dd5605f73b8)
+++ kernel/generic/src/mm/buddy.c	(revision 6a44ee4a35beb95618457c456010a40522d2996a)
@@ -82,5 +82,5 @@
 	 * Use memory after our own structure.
 	 */
-	b->order = (link_t *) (&b[1]);
+	b->order = (list_t *) (&b[1]);
 	
 	for (i = 0; i <= max_order; i++)
@@ -176,6 +176,6 @@
 	 * the request can be immediatelly satisfied.
 	 */
-	if (!list_empty(&b->order[i])) {
-		res = b->order[i].next;
+	res = list_first(&b->order[i]);
+	if (res != NULL) {
 		list_remove(res);
 		b->op->mark_busy(b, res);
Index: kernel/generic/src/mm/page.c
===================================================================
--- kernel/generic/src/mm/page.c	(revision 3714e798ef2924b952664a38e4d79dd5605f73b8)
+++ kernel/generic/src/mm/page.c	(revision 6a44ee4a35beb95618457c456010a40522d2996a)
@@ -60,4 +60,6 @@
 
 #include <mm/page.h>
+#include <genarch/mm/page_ht.h>
+#include <genarch/mm/page_pt.h>
 #include <arch/mm/page.h>
 #include <arch/mm/asid.h>
@@ -70,4 +72,6 @@
 #include <debug.h>
 #include <arch.h>
+#include <syscall/copy.h>
+#include <errno.h>
 
 /** Virtual operations for page subsystem. */
@@ -172,4 +176,35 @@
 }
 
+/** Syscall wrapper for getting mapping of a virtual page.
+ * 
+ * @retval EOK Everything went find, @p uspace_frame and @p uspace_node
+ *             contains correct values.
+ * @retval ENOENT Virtual address has no mapping.
+ */
+sysarg_t sys_page_find_mapping(uintptr_t virt_address,
+    uintptr_t *uspace_frame)
+{
+	mutex_lock(&AS->lock);
+	
+	pte_t *pte = page_mapping_find(AS, virt_address, false);
+	if (!PTE_VALID(pte) || !PTE_PRESENT(pte)) {
+		mutex_unlock(&AS->lock);
+		
+		return (sysarg_t) ENOENT;
+	}
+	
+	uintptr_t phys_address = PTE_GET_FRAME(pte);
+	
+	mutex_unlock(&AS->lock);
+	
+	int rc = copy_to_uspace(uspace_frame,
+	    &phys_address, sizeof(phys_address));
+	if (rc != EOK) {
+		return (sysarg_t) rc;
+	}
+	
+	return EOK;
+}
+
 /** @}
  */
Index: kernel/generic/src/mm/slab.c
===================================================================
--- kernel/generic/src/mm/slab.c	(revision 3714e798ef2924b952664a38e4d79dd5605f73b8)
+++ kernel/generic/src/mm/slab.c	(revision 6a44ee4a35beb95618457c456010a40522d2996a)
@@ -317,6 +317,6 @@
 		spinlock_lock(&cache->slablock);
 	} else {
-		slab = list_get_instance(cache->partial_slabs.next, slab_t,
-		    link);
+		slab = list_get_instance(list_first(&cache->partial_slabs),
+		    slab_t, link);
 		list_remove(&slab->link);
 	}
@@ -360,7 +360,7 @@
 	if (!list_empty(&cache->magazines)) {
 		if (first)
-			cur = cache->magazines.next;
+			cur = list_first(&cache->magazines);
 		else
-			cur = cache->magazines.prev;
+			cur = list_last(&cache->magazines);
 		
 		mag = list_get_instance(cur, slab_magazine_t, link);
@@ -812,7 +812,5 @@
 	
 	size_t frames = 0;
-	link_t *cur;
-	for (cur = slab_cache_list.next; cur != &slab_cache_list;
-	    cur = cur->next) {
+	list_foreach(slab_cache_list, cur) {
 		slab_cache_t *cache = list_get_instance(cur, slab_cache_t, link);
 		frames += _slab_reclaim(cache, flags);
@@ -861,9 +859,9 @@
 		link_t *cur;
 		size_t i;
-		for (i = 0, cur = slab_cache_list.next;
-		    (i < skip) && (cur != &slab_cache_list);
+		for (i = 0, cur = slab_cache_list.head.next;
+		    (i < skip) && (cur != &slab_cache_list.head);
 		    i++, cur = cur->next);
 		
-		if (cur == &slab_cache_list) {
+		if (cur == &slab_cache_list.head) {
 			irq_spinlock_unlock(&slab_cache_lock, true);
 			break;
@@ -940,7 +938,5 @@
 	irq_spinlock_lock(&slab_cache_lock, false);
 	
-	link_t *cur;
-	for (cur = slab_cache_list.next; cur != &slab_cache_list;
-	    cur = cur->next) {
+	list_foreach(slab_cache_list, cur) {
 		slab_cache_t *slab = list_get_instance(cur, slab_cache_t, link);
 		if ((slab->flags & SLAB_CACHE_MAGDEFERRED) !=
Index: kernel/generic/src/proc/scheduler.c
===================================================================
--- kernel/generic/src/proc/scheduler.c	(revision 3714e798ef2924b952664a38e4d79dd5605f73b8)
+++ kernel/generic/src/proc/scheduler.c	(revision 6a44ee4a35beb95618457c456010a40522d2996a)
@@ -237,6 +237,6 @@
 		 * Take the first thread from the queue.
 		 */
-		thread_t *thread =
-		    list_get_instance(CPU->rq[i].rq_head.next, thread_t, rq_link);
+		thread_t *thread = list_get_instance(
+		    list_first(&CPU->rq[i].rq), thread_t, rq_link);
 		list_remove(&thread->rq_link);
 		
@@ -273,7 +273,7 @@
 static void relink_rq(int start)
 {
-	link_t head;
-	
-	list_initialize(&head);
+	list_t list;
+	
+	list_initialize(&list);
 	irq_spinlock_lock(&CPU->lock, false);
 	
@@ -284,5 +284,5 @@
 			
 			irq_spinlock_lock(&CPU->rq[i + 1].lock, false);
-			list_concat(&head, &CPU->rq[i + 1].rq_head);
+			list_concat(&list, &CPU->rq[i + 1].rq);
 			size_t n = CPU->rq[i + 1].n;
 			CPU->rq[i + 1].n = 0;
@@ -292,5 +292,5 @@
 			
 			irq_spinlock_lock(&CPU->rq[i].lock, false);
-			list_concat(&CPU->rq[i].rq_head, &head);
+			list_concat(&CPU->rq[i].rq, &list);
 			CPU->rq[i].n += n;
 			irq_spinlock_unlock(&CPU->rq[i].lock, false);
@@ -586,5 +586,4 @@
 	 * Searching least priority queues on all CPU's first and most priority
 	 * queues on all CPU's last.
-	 *
 	 */
 	size_t acpu;
@@ -617,26 +616,27 @@
 			
 			/* Search rq from the back */
-			link_t *link = cpu->rq[rq].rq_head.prev;
-			
-			while (link != &(cpu->rq[rq].rq_head)) {
-				thread = (thread_t *) list_get_instance(link, thread_t, rq_link);
+			link_t *link = cpu->rq[rq].rq.head.prev;
+			
+			while (link != &(cpu->rq[rq].rq.head)) {
+				thread = (thread_t *) list_get_instance(link,
+				    thread_t, rq_link);
 				
 				/*
-				 * We don't want to steal CPU-wired threads
-				 * neither threads already stolen. The latter
-				 * prevents threads from migrating between CPU's
-				 * without ever being run. We don't want to
-				 * steal threads whose FPU context is still in
-				 * CPU.
-				 *
+				 * Do not steal CPU-wired threads, threads
+				 * already stolen, threads for which migration
+				 * was temporarily disabled or threads whose
+				 * FPU context is still in the CPU.
 				 */
 				irq_spinlock_lock(&thread->lock, false);
 				
-				if ((!(thread->flags & (THREAD_FLAG_WIRED | THREAD_FLAG_STOLEN)))
-				    && (!(thread->fpu_context_engaged))) {
+				if (!(thread->flags & THREAD_FLAG_WIRED) &&
+				    !(thread->flags & THREAD_FLAG_STOLEN) &&
+				    !thread->nomigrate &&
+				    !thread->fpu_context_engaged) {
 					/*
 					 * Remove thread from ready queue.
 					 */
-					irq_spinlock_unlock(&thread->lock, false);
+					irq_spinlock_unlock(&thread->lock,
+					    false);
 					
 					atomic_dec(&cpu->nrdy);
@@ -660,5 +660,6 @@
 				 */
 				
-				irq_spinlock_pass(&(cpu->rq[rq].lock), &thread->lock);
+				irq_spinlock_pass(&(cpu->rq[rq].lock),
+				    &thread->lock);
 				
 #ifdef KCPULB_VERBOSE
@@ -739,9 +740,7 @@
 			
 			printf("\trq[%u]: ", i);
-			link_t *cur;
-			for (cur = cpus[cpu].rq[i].rq_head.next;
-			    cur != &(cpus[cpu].rq[i].rq_head);
-			    cur = cur->next) {
-				thread_t *thread = list_get_instance(cur, thread_t, rq_link);
+			list_foreach(cpus[cpu].rq[i].rq, cur) {
+				thread_t *thread = list_get_instance(cur,
+				    thread_t, rq_link);
 				printf("%" PRIu64 "(%s) ", thread->tid,
 				    thread_states[thread->state]);
Index: kernel/generic/src/proc/task.c
===================================================================
--- kernel/generic/src/proc/task.c	(revision 3714e798ef2924b952664a38e4d79dd5605f73b8)
+++ kernel/generic/src/proc/task.c	(revision 6a44ee4a35beb95618457c456010a40522d2996a)
@@ -155,6 +155,6 @@
 	mutex_initialize(&task->futexes_lock, MUTEX_PASSIVE);
 	
-	list_initialize(&task->th_head);
-	list_initialize(&task->sync_box_head);
+	list_initialize(&task->threads);
+	list_initialize(&task->sync_boxes);
 	
 	ipc_answerbox_init(&task->answerbox, task);
@@ -435,6 +435,5 @@
 	
 	/* Current values of threads */
-	link_t *cur;
-	for (cur = task->th_head.next; cur != &task->th_head; cur = cur->next) {
+	list_foreach(task->threads, cur) {
 		thread_t *thread = list_get_instance(cur, thread_t, th_link);
 		
@@ -468,6 +467,5 @@
 	 */
 	
-	link_t *cur;
-	for (cur = task->th_head.next; cur != &task->th_head; cur = cur->next) {
+	list_foreach(task->threads, cur) {
 		thread_t *thread = list_get_instance(cur, thread_t, th_link);
 		bool sleeping = false;
Index: kernel/generic/src/proc/thread.c
===================================================================
--- kernel/generic/src/proc/thread.c	(revision 3714e798ef2924b952664a38e4d79dd5605f73b8)
+++ kernel/generic/src/proc/thread.c	(revision 6a44ee4a35beb95618457c456010a40522d2996a)
@@ -55,4 +55,5 @@
 #include <time/clock.h>
 #include <time/timeout.h>
+#include <time/delay.h>
 #include <config.h>
 #include <arch/interrupt.h>
@@ -259,5 +260,5 @@
 	 */
 	
-	list_append(&thread->rq_link, &cpu->rq[i].rq_head);
+	list_append(&thread->rq_link, &cpu->rq[i].rq);
 	cpu->rq[i].n++;
 	irq_spinlock_unlock(&(cpu->rq[i].lock), true);
@@ -321,4 +322,5 @@
 	thread->cpu = NULL;
 	thread->flags = flags;
+	thread->nomigrate = 0;
 	thread->state = Entering;
 	
@@ -421,5 +423,5 @@
 		atomic_inc(&task->lifecount);
 	
-	list_append(&thread->th_link, &task->th_head);
+	list_append(&thread->th_link, &task->threads);
 	
 	irq_spinlock_pass(&task->lock, &threads_lock);
@@ -481,4 +483,21 @@
 	/* Not reached */
 	while (true);
+}
+
+/** Prevent the current thread from being migrated to another processor. */
+void thread_migration_disable(void)
+{
+	ASSERT(THREAD);
+
+	THREAD->nomigrate++;
+}
+
+/** Allow the current thread to be migrated to another processor. */
+void thread_migration_enable(void)
+{
+	ASSERT(THREAD);
+	ASSERT(THREAD->nomigrate > 0);
+
+	THREAD->nomigrate--;
 }
 
@@ -912,4 +931,10 @@
 }
 
+sysarg_t sys_thread_udelay(uint32_t usec)
+{
+	delay(usec);
+	return 0;
+}
+
 /** @}
  */
Index: kernel/generic/src/synch/futex.c
===================================================================
--- kernel/generic/src/synch/futex.c	(revision 3714e798ef2924b952664a38e4d79dd5605f73b8)
+++ kernel/generic/src/synch/futex.c	(revision 6a44ee4a35beb95618457c456010a40522d2996a)
@@ -272,11 +272,8 @@
 void futex_cleanup(void)
 {
-	link_t *cur;
-	
 	mutex_lock(&futex_ht_lock);
 	mutex_lock(&TASK->futexes_lock);
 
-	for (cur = TASK->futexes.leaf_head.next;
-	    cur != &TASK->futexes.leaf_head; cur = cur->next) {
+	list_foreach(TASK->futexes.leaf_list, cur) {
 		btree_node_t *node;
 		unsigned int i;
Index: kernel/generic/src/synch/waitq.c
===================================================================
--- kernel/generic/src/synch/waitq.c	(revision 3714e798ef2924b952664a38e4d79dd5605f73b8)
+++ kernel/generic/src/synch/waitq.c	(revision 6a44ee4a35beb95618457c456010a40522d2996a)
@@ -69,5 +69,5 @@
 {
 	irq_spinlock_initialize(&wq->lock, "wq.lock");
-	list_initialize(&wq->head);
+	list_initialize(&wq->sleepers);
 	wq->missed_wakeups = 0;
 }
@@ -196,6 +196,7 @@
 	irq_spinlock_lock(&wq->lock, true);
 	
-	if (!list_empty(&wq->head)) {
-		thread_t *thread = list_get_instance(wq->head.next, thread_t, wq_link);
+	if (!list_empty(&wq->sleepers)) {
+		thread_t *thread = list_get_instance(list_first(&wq->sleepers),
+		    thread_t, wq_link);
 		
 		irq_spinlock_lock(&thread->lock, false);
@@ -407,5 +408,5 @@
 	}
 	
-	list_append(&THREAD->wq_link, &wq->head);
+	list_append(&THREAD->wq_link, &wq->sleepers);
 	
 	/*
@@ -464,5 +465,5 @@
 	
 loop:
-	if (list_empty(&wq->head)) {
+	if (list_empty(&wq->sleepers)) {
 		wq->missed_wakeups++;
 		if ((count) && (mode == WAKEUP_ALL))
@@ -473,5 +474,6 @@
 	
 	count++;
-	thread_t *thread = list_get_instance(wq->head.next, thread_t, wq_link);
+	thread_t *thread = list_get_instance(list_first(&wq->sleepers),
+	    thread_t, wq_link);
 	
 	/*
Index: kernel/generic/src/syscall/syscall.c
===================================================================
--- kernel/generic/src/syscall/syscall.c	(revision 3714e798ef2924b952664a38e4d79dd5605f73b8)
+++ kernel/generic/src/syscall/syscall.c	(revision 6a44ee4a35beb95618457c456010a40522d2996a)
@@ -41,4 +41,5 @@
 #include <proc/program.h>
 #include <mm/as.h>
+#include <mm/page.h>
 #include <print.h>
 #include <arch.h>
@@ -118,4 +119,5 @@
 
 syshandler_t syscall_table[SYSCALL_END] = {
+	/* System management syscalls. */
 	(syshandler_t) sys_klog,
 	(syshandler_t) sys_tls_set,
@@ -126,4 +128,5 @@
 	(syshandler_t) sys_thread_get_id,
 	(syshandler_t) sys_thread_usleep,
+	(syshandler_t) sys_thread_udelay,
 	
 	(syshandler_t) sys_task_get_id,
@@ -144,4 +147,7 @@
 	(syshandler_t) sys_as_area_destroy,
 	(syshandler_t) sys_as_get_unmapped_area,
+	
+	/* Page mapping related syscalls. */
+	(syshandler_t) sys_page_find_mapping,
 	
 	/* IPC related syscalls. */
@@ -174,5 +180,5 @@
 	(syshandler_t) sys_unregister_irq,
 	
-	/* Sysinfo syscalls */
+	/* Sysinfo syscalls. */
 	(syshandler_t) sys_sysinfo_get_tag,
 	(syshandler_t) sys_sysinfo_get_value,
@@ -180,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/sysinfo/stats.c
===================================================================
--- kernel/generic/src/sysinfo/stats.c	(revision 3714e798ef2924b952664a38e4d79dd5605f73b8)
+++ kernel/generic/src/sysinfo/stats.c	(revision 6a44ee4a35beb95618457c456010a40522d2996a)
@@ -173,7 +173,5 @@
 	
 	/* Walk the B+ tree and count pages */
-	link_t *cur;
-	for (cur = as->as_area_btree.leaf_head.next;
-	    cur != &as->as_area_btree.leaf_head; cur = cur->next) {
+	list_foreach(as->as_area_btree.leaf_list, cur) {
 		btree_node_t *node =
 		    list_get_instance(cur, btree_node_t, leaf_link);
@@ -218,7 +216,5 @@
 	
 	/* Walk the B+ tree and count pages */
-	link_t *cur;
-	for (cur = as->as_area_btree.leaf_head.next;
-	    cur != &as->as_area_btree.leaf_head; cur = cur->next) {
+	list_foreach(as->as_area_btree.leaf_list, cur) {
 		btree_node_t *node =
 		    list_get_instance(cur, btree_node_t, leaf_link);
Index: kernel/generic/src/time/clock.c
===================================================================
--- kernel/generic/src/time/clock.c	(revision 3714e798ef2924b952664a38e4d79dd5605f73b8)
+++ kernel/generic/src/time/clock.c	(revision 6a44ee4a35beb95618457c456010a40522d2996a)
@@ -94,4 +94,5 @@
 	clock_parea.frames = 1;
 	clock_parea.unpriv = true;
+	clock_parea.mapped = false;
 	ddi_parea_register(&clock_parea);
 	
@@ -163,6 +164,7 @@
 		
 		link_t *cur;
-		while ((cur = CPU->timeout_active_head.next) != &CPU->timeout_active_head) {
-			timeout_t *timeout = list_get_instance(cur, timeout_t, link);
+		while ((cur = list_first(&CPU->timeout_active_list)) != NULL) {
+			timeout_t *timeout = list_get_instance(cur, timeout_t,
+			    link);
 			
 			irq_spinlock_lock(&timeout->lock, false);
Index: kernel/generic/src/time/delay.c
===================================================================
--- kernel/generic/src/time/delay.c	(revision 3714e798ef2924b952664a38e4d79dd5605f73b8)
+++ kernel/generic/src/time/delay.c	(revision 6a44ee4a35beb95618457c456010a40522d2996a)
@@ -37,4 +37,5 @@
  
 #include <time/delay.h>
+#include <proc/thread.h>
 #include <typedefs.h>
 #include <cpu.h>
@@ -42,9 +43,7 @@
 #include <arch.h>
 
-/** Active delay
+/** Delay the execution for the given number of microseconds (or slightly more).
  *
- * Delay the execution for the given number
- * of microseconds (or slightly more). The delay
- * is implemented as CPU calibrated active loop.
+ * The delay is implemented as active delay loop.
  *
  * @param usec Number of microseconds to sleep.
@@ -52,15 +51,14 @@
 void delay(uint32_t usec)
 {
-	ipl_t ipl;
-	
 	/* 
-	 * The delay loop is calibrated for each and every
-	 * CPU in the system. Therefore it is necessary to
-	 * call interrupts_disable() before calling the
-	 * asm_delay_loop().
+	 * The delay loop is calibrated for each and every CPU in the system.
+	 * If running in a thread context, it is therefore necessary to disable
+	 * thread migration. We want to do this in a lightweight manner.
 	 */
-	ipl = interrupts_disable();
+	if (THREAD)
+		thread_migration_disable();
 	asm_delay_loop(usec * CPU->delay_loop_const);
-	interrupts_restore(ipl);
+	if (THREAD)
+		thread_migration_enable();
 }
 
Index: kernel/generic/src/time/timeout.c
===================================================================
--- kernel/generic/src/time/timeout.c	(revision 3714e798ef2924b952664a38e4d79dd5605f73b8)
+++ kernel/generic/src/time/timeout.c	(revision 6a44ee4a35beb95618457c456010a40522d2996a)
@@ -54,5 +54,5 @@
 {
 	irq_spinlock_initialize(&CPU->timeoutlock, "cpu.timeoutlock");
-	list_initialize(&CPU->timeout_active_head);
+	list_initialize(&CPU->timeout_active_list);
 }
 
@@ -119,6 +119,6 @@
 	timeout_t *target = NULL;
 	link_t *cur;
-	for (cur = CPU->timeout_active_head.next;
-	    cur != &CPU->timeout_active_head; cur = cur->next) {
+	for (cur = CPU->timeout_active_list.head.next;
+	    cur != &CPU->timeout_active_list.head; cur = cur->next) {
 		target = list_get_instance(cur, timeout_t, link);
 		irq_spinlock_lock(&target->lock, false);
@@ -135,5 +135,5 @@
 	/* Avoid using cur->prev directly */
 	link_t *prev = cur->prev;
-	list_prepend(&timeout->link, prev);
+	list_insert_after(&timeout->link, prev);
 	
 	/*
@@ -146,5 +146,5 @@
 	 * Decrease ticks of timeout's immediate succesor by timeout->ticks.
 	 */
-	if (cur != &CPU->timeout_active_head) {
+	if (cur != &CPU->timeout_active_list.head) {
 		irq_spinlock_lock(&target->lock, false);
 		target->ticks -= timeout->ticks;
@@ -184,9 +184,9 @@
 	/*
 	 * Now we know for sure that timeout hasn't been activated yet
-	 * and is lurking in timeout->cpu->timeout_active_head queue.
+	 * and is lurking in timeout->cpu->timeout_active_list.
 	 */
 	
 	link_t *cur = timeout->link.next;
-	if (cur != &timeout->cpu->timeout_active_head) {
+	if (cur != &timeout->cpu->timeout_active_list.head) {
 		timeout_t *tmp = list_get_instance(cur, timeout_t, link);
 		irq_spinlock_lock(&tmp->lock, false);
Index: kernel/generic/src/udebug/udebug.c
===================================================================
--- kernel/generic/src/udebug/udebug.c	(revision 3714e798ef2924b952664a38e4d79dd5605f73b8)
+++ kernel/generic/src/udebug/udebug.c	(revision 6a44ee4a35beb95618457c456010a40522d2996a)
@@ -406,6 +406,5 @@
 	
 	/* Finish debugging of all userspace threads */
-	link_t *cur;
-	for (cur = task->th_head.next; cur != &task->th_head; cur = cur->next) {
+	list_foreach(task->threads, cur) {
 		thread_t *thread = list_get_instance(cur, thread_t, th_link);
 		
Index: kernel/generic/src/udebug/udebug_ops.c
===================================================================
--- kernel/generic/src/udebug/udebug_ops.c	(revision 3714e798ef2924b952664a38e4d79dd5605f73b8)
+++ kernel/generic/src/udebug/udebug_ops.c	(revision 6a44ee4a35beb95618457c456010a40522d2996a)
@@ -196,6 +196,5 @@
 	/* Set udebug.active on all of the task's userspace threads. */
 	
-	link_t *cur;
-	for (cur = TASK->th_head.next; cur != &TASK->th_head; cur = cur->next) {
+	list_foreach(TASK->threads, cur) {
 		thread_t *thread = list_get_instance(cur, thread_t, th_link);
 		
@@ -390,6 +389,5 @@
 	
 	/* FIXME: make sure the thread isn't past debug shutdown... */
-	link_t *cur;
-	for (cur = TASK->th_head.next; cur != &TASK->th_head; cur = cur->next) {
+	list_foreach(TASK->threads, cur) {
 		thread_t *thread = list_get_instance(cur, thread_t, th_link);
 		
