Index: kernel/arch/mips32/src/asm.S
===================================================================
--- kernel/arch/mips32/src/asm.S	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
+++ kernel/arch/mips32/src/asm.S	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
@@ -0,0 +1,299 @@
+#
+# 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>
+	
+.text
+
+.macro cp0_read reg
+	mfc0 $2,\reg
+	j $31
+	nop
+.endm
+
+.macro cp0_write reg
+	mtc0 $4,\reg
+	j $31
+	nop
+.endm
+
+.set noat
+.set noreorder
+.set nomacro
+
+.global cpu_halt
+cpu_halt:
+	j cpu_halt
+	nop
+
+
+.global memsetb
+memsetb:
+	j _memsetb
+	nop
+
+
+.global memcpy
+.global memcpy_from_uspace
+.global memcpy_to_uspace
+.global memcpy_from_uspace_failover_address
+.global memcpy_to_uspace_failover_address
+memcpy:
+memcpy_from_uspace:
+memcpy_to_uspace:
+	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,$a1
+
+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,$a1
+
+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 ARCH_HAS_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 ARCH_HAS_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
Index: kernel/arch/mips32/src/cache.c
===================================================================
--- kernel/arch/mips32/src/cache.c	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
+++ kernel/arch/mips32/src/cache.c	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
@@ -0,0 +1,47 @@
+/*
+ * 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 mips32	
+ * @{
+ */
+/** @file
+ */
+
+#include <arch/cache.h>
+#include <arch/exception.h>
+#include <typedefs.h>
+#include <panic.h>
+
+void cache_error(istate_t *istate)
+{
+	panic("cache_error exception (epc=%p)\n", istate->epc);
+}
+
+/** @}
+ */
+
Index: kernel/arch/mips32/src/console.c
===================================================================
--- kernel/arch/mips32/src/console.c	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
+++ kernel/arch/mips32/src/console.c	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
@@ -0,0 +1,69 @@
+/*
+ * 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 mips32	
+ * @{
+ */
+/** @file
+ */
+
+#include <console/console.h>
+#include <arch/console.h>
+#include <arch/drivers/arc.h>
+#include <arch/drivers/serial.h>
+#include <arch/drivers/msim.h>
+
+void console_init(void)
+{
+	if (arc_enabled()) {
+		arc_console();
+	} else if (serial_init()) {
+		serial_console();
+	} else {
+		msim_console();
+	}
+}
+
+/** Acquire console back for kernel
+ *
+ */
+void arch_grab_console(void)
+{
+	msim_kbd_grab();
+}
+/** Return console to userspace
+ *
+ */
+void arch_release_console(void)
+{
+	msim_kbd_release();
+}
+
+ /** @}
+ */
+
Index: kernel/arch/mips32/src/context.S
===================================================================
--- kernel/arch/mips32/src/context.S	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
+++ kernel/arch/mips32/src/context.S	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
@@ -0,0 +1,86 @@
+#
+# 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/context_offset.h>
+	
+.text   
+
+.set noat
+.set noreorder
+.set nomacro
+
+.global context_save_arch
+.global context_restore_arch
+
+.macro CONTEXT_STORE r
+	sw $s0,OFFSET_S0(\r)
+	sw $s1,OFFSET_S1(\r)
+	sw $s2,OFFSET_S2(\r)
+	sw $s3,OFFSET_S3(\r)
+	sw $s4,OFFSET_S4(\r)
+	sw $s5,OFFSET_S5(\r)
+	sw $s6,OFFSET_S6(\r)
+	sw $s7,OFFSET_S7(\r)
+	sw $s8,OFFSET_S8(\r)
+	sw $gp,OFFSET_GP(\r)
+	
+	sw $ra,OFFSET_PC(\r)
+	sw $sp,OFFSET_SP(\r)
+.endm
+
+.macro CONTEXT_LOAD r
+	lw $s0,OFFSET_S0(\r)
+	lw $s1,OFFSET_S1(\r)
+	lw $s2,OFFSET_S2(\r)
+	lw $s3,OFFSET_S3(\r)
+	lw $s4,OFFSET_S4(\r)
+	lw $s5,OFFSET_S5(\r)
+	lw $s6,OFFSET_S6(\r)
+	lw $s7,OFFSET_S7(\r)
+	lw $s8,OFFSET_S8(\r)
+	lw $gp,OFFSET_GP(\r)
+	
+	lw $ra,OFFSET_PC(\r)
+	lw $sp,OFFSET_SP(\r)
+.endm
+
+	
+context_save_arch:
+	CONTEXT_STORE $a0
+
+	# context_save returns 1
+	j $31
+	li $2, 1	
+	
+context_restore_arch:
+	CONTEXT_LOAD $a0
+
+	# context_restore returns 0
+	j $31
+	xor $2, $2	
Index: kernel/arch/mips32/src/cpu/cpu.c
===================================================================
--- kernel/arch/mips32/src/cpu/cpu.c	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
+++ kernel/arch/mips32/src/cpu/cpu.c	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
@@ -0,0 +1,138 @@
+/*
+ * 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 mips32
+ * @{
+ */
+/** @file
+ */
+
+#include <arch/cpu.h>
+#include <cpu.h>
+
+#include <arch.h>
+
+#include <arch/cp0.h>
+
+#include <typedefs.h>
+#include <print.h>	
+
+struct data_t {
+	char *vendor;
+	char *model;
+};
+
+static struct data_t imp_data[] = {
+	{ "Invalid", "Invalid" },	/* 0x00 */
+	{ "MIPS", "R2000" },		/* 0x01 */
+	{ "MIPS", "R3000" },		/* 0x02 */
+	{ "MIPS", "R6000" },		/* 0x03 */
+	{ "MIPS", " R4000/R4400" }, 	/* 0x04 */
+	{ "LSI Logic", "R3000" },	/* 0x05 */
+	{ "MIPS", "R6000A" },		/* 0x06 */
+	{ "IDT", "3051/3052" },		/* 0x07 */
+	{ "Invalid", "Invalid" },	/* 0x08 */
+	{ "MIPS", "R10000/T5" },	/* 0x09 */
+	{ "MIPS", "R4200" },		/* 0x0a */
+	{ "Unknown", "Unknown" },	/* 0x0b */
+	{ "Unknown", "Unknown" },	/* 0x0c */
+	{ "Invalid", "Invalid" },	/* 0x0d */
+	{ "Invalid", "Invalid" },	/* 0x0e */
+	{ "Invalid", "Invalid" },	/* 0x0f */
+	{ "MIPS", "R8000" },		/* 0x10 */
+	{ "Invalid", "Invalid" },	/* 0x11 */
+	{ "Invalid", "Invalid" },	/* 0x12 */
+	{ "Invalid", "Invalid" },	/* 0x13 */
+	{ "Invalid", "Invalid" },	/* 0x14 */
+	{ "Invalid", "Invalid" },	/* 0x15 */
+	{ "Invalid", "Invalid" },	/* 0x16 */
+	{ "Invalid", "Invalid" },	/* 0x17 */
+	{ "Invalid", "Invalid" },	/* 0x18 */
+	{ "Invalid", "Invalid" },	/* 0x19 */
+	{ "Invalid", "Invalid" },  	/* 0x1a */
+	{ "Invalid", "Invalid" },	/* 0x1b */
+	{ "Invalid", "Invalid" },	/* 0x1c */
+	{ "Invalid", "Invalid" },	/* 0x1d */
+	{ "Invalid", "Invalid" },	/* 0x1e */
+	{ "Invalid", "Invalid" },	/* 0x1f */
+	{ "QED", "R4600" },		/* 0x20 */
+	{ "Sony", "R3000" },		/* 0x21 */
+	{ "Toshiba", "R3000" },		/* 0x22 */
+	{ "NKK", "R3000" },		/* 0x23 */
+	{ NULL, NULL }
+};
+
+static struct data_t imp_data80[] = {
+	{ "MIPS", "4Kc" },  /* 0x80 */
+	{"Invalid","Invalid"}, /* 0x81 */
+	{"Invalid","Invalid"}, /* 0x82 */
+	{"MIPS","4Km & 4Kp"}, /* 0x83 */
+	{ NULL, NULL}
+};
+
+void cpu_arch_init(void)
+{
+}
+
+void cpu_identify(void)
+{
+	CPU->arch.rev_num = cp0_prid_read() & 0xff;
+	CPU->arch.imp_num = (cp0_prid_read() >> 8) & 0xff;
+}
+
+void cpu_print_report(cpu_t *m)
+{
+	struct data_t *data;
+	int i;
+
+	if (m->arch.imp_num & 0x80) {
+		/* Count records */
+		for (i=0;imp_data80[i].vendor;i++)
+			;
+		if ((m->arch.imp_num & 0x7f) >= i) {
+			printf("imp=%d\n",m->arch.imp_num);
+			return;
+		}
+		data = &imp_data80[m->arch.imp_num & 0x7f];
+	} else {
+		for (i=0;imp_data[i].vendor;i++)
+			;
+		if (m->arch.imp_num >= i) {
+			printf("imp=%d\n",m->arch.imp_num);
+			return;
+		}
+		data = &imp_data[m->arch.imp_num];
+	}
+
+	printf("cpu%d: %s %s (rev=%d.%d, imp=%d)\n",
+		m->id, data->vendor, data->model, m->arch.rev_num >> 4, 
+	       m->arch.rev_num & 0xf, m->arch.imp_num);
+}
+
+/** @}
+ */
Index: kernel/arch/mips32/src/ddi/ddi.c
===================================================================
--- kernel/arch/mips32/src/ddi/ddi.c	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
+++ kernel/arch/mips32/src/ddi/ddi.c	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
@@ -0,0 +1,60 @@
+/*
+ * 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 mips32ddi
+ * @{
+ */
+/** @file
+ */
+
+#include <ddi/ddi.h>
+#include <proc/task.h>
+#include <arch/types.h>
+#include <typedefs.h>
+#include <security/cap.h>
+#include <arch.h>
+#include <arch/cp0.h>
+
+/** Enable I/O space range for task.
+ *
+ * Interrupts are disabled and task is locked.
+ *
+ * @param task Task.
+ * @param ioaddr Startign I/O space address.
+ * @param size Size of the enabled I/O range.
+ *
+ * @return 0 on success or an error code from errno.h.
+ */
+int ddi_iospace_enable_arch(task_t *task, uintptr_t ioaddr, size_t size)
+{
+	return 0;
+}
+
+ /** @}
+ */
+
Index: kernel/arch/mips32/src/debugger.c
===================================================================
--- kernel/arch/mips32/src/debugger.c	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
+++ kernel/arch/mips32/src/debugger.c	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
@@ -0,0 +1,388 @@
+/*
+ * 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 mips32debug
+ * @{
+ */
+/** @file
+ */
+
+#include <arch/debugger.h>
+#include <memstr.h>
+#include <console/kconsole.h>
+#include <console/cmd.h>
+#include <symtab.h>
+#include <print.h>
+#include <panic.h>
+#include <arch.h>
+#include <arch/cp0.h>
+#include <func.h>
+
+bpinfo_t breakpoints[BKPOINTS_MAX];
+SPINLOCK_INITIALIZE(bkpoint_lock);
+
+static int cmd_print_breakpoints(cmd_arg_t *argv);
+static cmd_info_t bkpts_info = {
+	.name = "bkpts",
+	.description = "Print breakpoint table.",
+	.func = cmd_print_breakpoints,
+	.argc = 0,
+};
+
+static int cmd_del_breakpoint(cmd_arg_t *argv);
+static cmd_arg_t del_argv = {
+	.type = ARG_TYPE_INT
+};
+static cmd_info_t delbkpt_info = {
+	.name = "delbkpt",
+	.description = "delbkpt <number> - Delete breakpoint.",
+	.func = cmd_del_breakpoint,
+	.argc = 1,
+	.argv = &del_argv
+};
+
+static int cmd_add_breakpoint(cmd_arg_t *argv);
+static cmd_arg_t add_argv = {
+	.type = ARG_TYPE_INT
+};
+static cmd_info_t addbkpt_info = {
+	.name = "addbkpt",
+	.description = "addbkpt <&symbol> - new bkpoint. Break on J/Branch insts unsupported.",
+	.func = cmd_add_breakpoint,
+	.argc = 1,
+	.argv = &add_argv
+};
+
+static cmd_arg_t adde_argv[] = {
+	{ .type = ARG_TYPE_INT },
+	{ .type = ARG_TYPE_INT }
+};
+static cmd_info_t addbkpte_info = {
+	.name = "addbkpte",
+	.description = "addebkpte <&symbol> <&func> - new bkpoint. Call func(or Nothing if 0).",
+	.func = cmd_add_breakpoint,
+	.argc = 2,
+	.argv = adde_argv
+};
+
+static struct {
+	uint32_t andmask;
+	uint32_t value;
+}jmpinstr[] = {
+	{0xf3ff0000, 0x41000000}, /* BCzF */
+	{0xf3ff0000, 0x41020000}, /* BCzFL */
+	{0xf3ff0000, 0x41010000}, /* BCzT */
+	{0xf3ff0000, 0x41030000}, /* BCzTL */
+	{0xfc000000, 0x10000000}, /* BEQ */
+	{0xfc000000, 0x50000000}, /* BEQL */
+	{0xfc1f0000, 0x04010000}, /* BEQL */
+	{0xfc1f0000, 0x04110000}, /* BGEZAL */
+	{0xfc1f0000, 0x04130000}, /* BGEZALL */
+	{0xfc1f0000, 0x04030000}, /* BGEZL */
+	{0xfc1f0000, 0x1c000000}, /* BGTZ */
+	{0xfc1f0000, 0x5c000000}, /* BGTZL */
+	{0xfc1f0000, 0x18000000}, /* BLEZ */
+	{0xfc1f0000, 0x58000000}, /* BLEZL */
+	{0xfc1f0000, 0x04000000}, /* BLTZ */
+	{0xfc1f0000, 0x04100000}, /* BLTZAL */
+	{0xfc1f0000, 0x04120000}, /* BLTZALL */
+	{0xfc1f0000, 0x04020000}, /* BLTZL */
+	{0xfc000000, 0x14000000}, /* BNE */
+	{0xfc000000, 0x54000000}, /* BNEL */
+	{0xfc000000, 0x08000000}, /* J */
+	{0xfc000000, 0x0c000000}, /* JAL */
+	{0xfc1f07ff, 0x00000009}, /* JALR */
+	{0,0} /* EndOfTable */
+};
+
+/** Test, if the given instruction is a jump or branch instruction
+ *
+ * @param instr Instruction code
+ * @return true - it is jump instruction, false otherwise
+ */
+static bool is_jump(unative_t instr)
+{
+	int i;
+
+	for (i=0;jmpinstr[i].andmask;i++) {
+		if ((instr & jmpinstr[i].andmask) == jmpinstr[i].value)
+			return true;
+	}
+
+	return false;
+}
+
+/** Add new breakpoint to table */
+int cmd_add_breakpoint(cmd_arg_t *argv)
+{
+	bpinfo_t *cur = NULL;
+	ipl_t ipl;
+	int i;
+
+	if (argv->intval & 0x3) {
+		printf("Not aligned instruction, forgot to use &symbol?\n");
+		return 1;
+	}
+	ipl = interrupts_disable();
+	spinlock_lock(&bkpoint_lock);
+
+	/* Check, that the breakpoints do not conflict */
+	for (i=0; i<BKPOINTS_MAX; i++) {
+		if (breakpoints[i].address == (uintptr_t)argv->intval) {
+			printf("Duplicate breakpoint %d.\n", i);
+			spinlock_unlock(&bkpoints_lock);
+			return 0;
+		} else if (breakpoints[i].address == (uintptr_t)argv->intval + sizeof(unative_t) || \
+			   breakpoints[i].address == (uintptr_t)argv->intval - sizeof(unative_t)) {
+			printf("Adjacent breakpoints not supported, conflict with %d.\n", i);
+			spinlock_unlock(&bkpoints_lock);
+			return 0;
+		}
+			
+	}
+
+	for (i=0; i<BKPOINTS_MAX; i++)
+		if (!breakpoints[i].address) {
+			cur = &breakpoints[i];
+			break;
+		}
+	if (!cur) {
+		printf("Too many breakpoints.\n");
+		spinlock_unlock(&bkpoint_lock);
+		interrupts_restore(ipl);
+		return 0;
+	}
+	cur->address = (uintptr_t) argv->intval;
+	printf("Adding breakpoint on address: %p\n", argv->intval);
+	cur->instruction = ((unative_t *)cur->address)[0];
+	cur->nextinstruction = ((unative_t *)cur->address)[1];
+	if (argv == &add_argv) {
+		cur->flags = 0;
+	} else { /* We are add extended */
+		cur->flags = BKPOINT_FUNCCALL;
+		cur->bkfunc = 	(void (*)(void *, istate_t *)) argv[1].intval;
+	}
+	if (is_jump(cur->instruction))
+		cur->flags |= BKPOINT_ONESHOT;
+	cur->counter = 0;
+
+	/* Set breakpoint */
+	*((unative_t *)cur->address) = 0x0d;
+
+	spinlock_unlock(&bkpoint_lock);
+	interrupts_restore(ipl);
+
+	return 1;
+}
+
+
+
+/** Remove breakpoint from table */
+int cmd_del_breakpoint(cmd_arg_t *argv)
+{
+	bpinfo_t *cur;
+	ipl_t ipl;
+
+	if (argv->intval < 0 || argv->intval > BKPOINTS_MAX) {
+		printf("Invalid breakpoint number.\n");
+		return 0;
+	}
+	ipl = interrupts_disable();
+	spinlock_lock(&bkpoint_lock);
+
+	cur = &breakpoints[argv->intval];
+	if (!cur->address) {
+		printf("Breakpoint does not exist.\n");
+		spinlock_unlock(&bkpoint_lock);
+		interrupts_restore(ipl);
+		return 0;
+	}
+	if ((cur->flags & BKPOINT_INPROG) && (cur->flags & BKPOINT_ONESHOT)) {
+		printf("Cannot remove one-shot breakpoint in-progress\n");
+		spinlock_unlock(&bkpoint_lock);
+		interrupts_restore(ipl);
+		return 0;
+	}
+	((uint32_t *)cur->address)[0] = cur->instruction;
+	((uint32_t *)cur->address)[1] = cur->nextinstruction;
+
+	cur->address = NULL;
+
+	spinlock_unlock(&bkpoint_lock);
+	interrupts_restore(ipl);
+	return 1;
+}
+
+/** Print table of active breakpoints */
+int cmd_print_breakpoints(cmd_arg_t *argv)
+{
+	int i;
+	char *symbol;
+
+	printf("Breakpoint table.\n");
+	for (i=0; i < BKPOINTS_MAX; i++)
+		if (breakpoints[i].address) {
+			symbol = get_symtab_entry(breakpoints[i].address);
+			printf("%d. %p in %s\n",i,
+			       breakpoints[i].address, symbol);
+			printf("     Count(%d) ", breakpoints[i].counter);
+			if (breakpoints[i].flags & BKPOINT_INPROG)
+				printf("INPROG ");
+			if (breakpoints[i].flags & BKPOINT_ONESHOT)
+				printf("ONESHOT ");
+			if (breakpoints[i].flags & BKPOINT_FUNCCALL)
+				printf("FUNCCALL ");
+			printf("\n");
+		}
+	return 1;
+}
+
+/** Initialize debugger */
+void debugger_init()
+{
+	int i;
+
+	for (i=0; i<BKPOINTS_MAX; i++)
+		breakpoints[i].address = NULL;
+	
+	cmd_initialize(&bkpts_info);
+	if (!cmd_register(&bkpts_info))
+		panic("could not register command %s\n", bkpts_info.name);
+
+	cmd_initialize(&delbkpt_info);
+	if (!cmd_register(&delbkpt_info))
+		panic("could not register command %s\n", delbkpt_info.name);
+
+	cmd_initialize(&addbkpt_info);
+	if (!cmd_register(&addbkpt_info))
+		panic("could not register command %s\n", addbkpt_info.name);
+
+	cmd_initialize(&addbkpte_info);
+	if (!cmd_register(&addbkpte_info))
+		panic("could not register command %s\n", addbkpte_info.name);
+}
+
+/** Handle breakpoint
+ *
+ * Find breakpoint in breakpoint table. 
+ * If found, call kconsole, set break on next instruction and reexecute.
+ * If we are on "next instruction", set it back on the first and reexecute.
+ * If breakpoint not found in breakpoint table, call kconsole and start
+ * next instruction.
+ */
+void debugger_bpoint(istate_t *istate)
+{
+	bpinfo_t *cur = NULL;
+	uintptr_t fireaddr = istate->epc;
+	int i;
+
+	/* test branch delay slot */
+	if (cp0_cause_read() & 0x80000000)
+		panic("Breakpoint in branch delay slot not supported.\n");
+
+	spinlock_lock(&bkpoint_lock);
+	for (i=0; i<BKPOINTS_MAX; i++) {
+		/* Normal breakpoint */
+		if (fireaddr == breakpoints[i].address \
+		    && !(breakpoints[i].flags & BKPOINT_REINST)) {
+			cur = &breakpoints[i];
+			break;
+		}
+		/* Reinst only breakpoint */
+		if ((breakpoints[i].flags & BKPOINT_REINST) \
+		    && (fireaddr ==breakpoints[i].address+sizeof(unative_t))) {
+			cur = &breakpoints[i];
+			break;
+		}
+	}
+	if (cur) {
+		if (cur->flags & BKPOINT_REINST) {
+			/* Set breakpoint on first instruction */
+			((uint32_t *)cur->address)[0] = 0x0d;
+			/* Return back the second */
+			((uint32_t *)cur->address)[1] = cur->nextinstruction;
+			cur->flags &= ~BKPOINT_REINST;
+			spinlock_unlock(&bkpoint_lock);
+			return;
+		} 
+		if (cur->flags & BKPOINT_INPROG)
+			printf("Warning: breakpoint recursion\n");
+		
+		if (!(cur->flags & BKPOINT_FUNCCALL))
+			printf("***Breakpoint %d: %p in %s.\n", i, 
+			       fireaddr, get_symtab_entry(istate->epc));
+
+		/* Return first instruction back */
+		((uint32_t *)cur->address)[0] = cur->instruction;
+
+		if (! (cur->flags & BKPOINT_ONESHOT)) {
+			/* Set Breakpoint on next instruction */
+			((uint32_t *)cur->address)[1] = 0x0d;
+			cur->flags |= BKPOINT_REINST;
+		} 
+		cur->flags |= BKPOINT_INPROG;
+	} else {
+		printf("***Breakpoint %p in %s.\n", fireaddr, 
+		       get_symtab_entry(fireaddr));
+		/* Move on to next instruction */
+		istate->epc += 4;
+	}
+	if (cur)
+		cur->counter++;
+	if (cur && (cur->flags & BKPOINT_FUNCCALL)) {
+		/* Allow zero bkfunc, just for counting */
+		if (cur->bkfunc)
+			cur->bkfunc(cur, istate);
+	} else {
+		printf("***Type 'exit' to exit kconsole.\n");
+		/* This disables all other processors - we are not SMP,
+		 * actually this gets us to cpu_halt, if scheduler() is run
+		 * - we generally do not want scheduler to be run from debug,
+		 *   so this is a good idea
+		 */	
+		atomic_set(&haltstate,1);
+		spinlock_unlock(&bkpoint_lock);
+
+		kconsole("debug");
+
+		spinlock_lock(&bkpoint_lock);
+		atomic_set(&haltstate,0);
+	}
+	if (cur && cur->address == fireaddr && (cur->flags & BKPOINT_INPROG)) {
+		/* Remove one-shot breakpoint */
+		if ((cur->flags & BKPOINT_ONESHOT))
+			cur->address = NULL;
+		/* Remove in-progress flag */
+		cur->flags &= ~BKPOINT_INPROG;
+	} 
+	spinlock_unlock(&bkpoint_lock);
+}
+
+ /** @}
+ */
+
Index: kernel/arch/mips32/src/drivers/arc.c
===================================================================
--- kernel/arch/mips32/src/drivers/arc.c	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
+++ kernel/arch/mips32/src/drivers/arc.c	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
@@ -0,0 +1,413 @@
+/*
+ * 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 mips32	
+ * @{
+ */
+/** @file
+ */
+
+#include <arch/drivers/arc.h>
+#include <arch/mm/page.h>
+#include <print.h>
+#include <arch.h>
+#include <arch/byteorder.h>
+#include <arch/mm/frame.h>
+#include <mm/frame.h>
+#include <interrupt.h>
+#include <align.h>
+#include <console/console.h>
+#include <console/kconsole.h>
+#include <console/cmd.h>
+#include <mm/slab.h>
+
+/* This is a good joke, SGI HAS different types than NT bioses... */
+/* Here is the SGI type */
+static char *basetypes[] = {
+	"ExceptionBlock",
+	"SystemParameterBlock",
+	"FreeContiguous",
+	"FreeMemory",
+	"BadMemory",
+	"LoadedProgram",
+	"FirmwareTemporary",
+	"FirmwarePermanent"
+};
+
+static char *ctypes[] = {
+	"ARC_type",
+	"CPU_type",
+	"FPU_type",
+	"PrimaryICache",
+	"PrimaryDCache",
+	"SecondaryICache",
+	"SecondaryDCache",
+	"SecondaryCache",
+	"Memory",
+	"EISAAdapter",
+	"TCAdapter",
+	"SCSIAdapter",
+	"DTIAdapter",
+	"MultiFunctionAdapter",
+	"DiskController",
+	"TapeController",
+	"CDROMController",
+	"WORMController",
+	"SerialController",
+	"NetworkController",
+	"DisplayController",
+	"ParallelController",
+	"PointerController",
+	"KeyboardController",
+	"AudioController",
+	"OtherController",
+	"DiskPeripheral",
+	"FloppyDiskPeripheral",
+	"TapePeripheral",
+	"ModemPeripheral",
+	"MonitorPeripheral",
+	"PrinterPeripheral",
+	"PointerPeripheral",
+	"KeyboardPeripheral",
+	"TerminalPeripheral",
+	"OtherPeripheral",
+	"LinePeripheral",
+	"NetworkPeripheral"
+	"OtherPeripheral",
+	"XTalkAdapter",
+	"PCIAdapter",
+	"GIOAdapter",
+	"TPUAdapter",
+	"Anonymous"
+};
+
+static arc_sbp *sbp = (arc_sbp *)PA2KA(0x1000);
+static arc_func_vector_t *arc_entry; 
+
+
+static void arc_putchar(char ch);
+
+/** Return true if ARC is available */
+int arc_enabled(void)
+{
+	return sbp != NULL;
+}
+
+
+/** Print configuration data that ARC reports about component */
+static void arc_print_confdata(arc_component *c)
+{
+	cm_resource_list *configdata;
+	int i;
+
+	if (!c->configdatasize)
+		return; /* No configuration data */
+
+	configdata = malloc(c->configdatasize, 0);
+
+	if (arc_entry->getconfigurationdata(configdata, c)) {
+		free(configdata);
+		return;
+	}
+	/* Does not seem to return meaningful data, don't use now */
+	free(configdata);
+	return;
+	
+	for (i=0; i < configdata->count; i++) {
+		switch (configdata->descr[i].type) {
+		case CmResourceTypePort:
+			printf("Port: %p-size:%d ",
+			       (uintptr_t)configdata->descr[i].u.port.start,
+			       configdata->descr[i].u.port.length);
+			break;
+		case CmResourceTypeInterrupt:
+			printf("Irq: level(%d) vector(%d) ",
+			       configdata->descr[i].u.interrupt.level,
+			       configdata->descr[i].u.interrupt.vector);
+			break;
+		case CmResourceTypeMemory:
+			printf("Memory: %p-size:%d ",
+			       (uintptr_t)configdata->descr[i].u.port.start,
+			       configdata->descr[i].u.port.length);
+			break;
+		default:
+			break;
+		}
+	}
+
+	free(configdata);
+}
+
+/** Print information about component */
+static void arc_print_component(arc_component *c)
+{
+	int i;
+
+	printf("%s: ",ctypes[c->type]);
+	for (i=0;i < c->identifier_len;i++)
+		printf("%c",c->identifier[i]);
+
+	printf(" ");
+	arc_print_confdata(c);
+	printf("\n");
+}
+
+/**
+ * Read from ARC bios configuration data and print it
+ */
+static int cmd_arc_print_devices(cmd_arg_t *argv)
+{
+	arc_component *c,*next;
+
+	c = arc_entry->getchild(NULL);
+	while (c) {
+		arc_print_component(c);
+		next = arc_entry->getchild(c);
+		while (!next) {
+			next = arc_entry->getpeer(c);
+			if (!next)
+				c = arc_entry->getparent(c);
+			if (!c)
+				return 0;
+		}
+		c = next;
+	}
+	return 1;
+}
+static cmd_info_t devlist_info = {
+	.name = "arcdevlist",
+	.description = "Print arc device list",
+	.func = cmd_arc_print_devices,
+	.argc = 0
+};
+
+
+/** Read from arc bios memory map and print it
+ *
+ */
+static int cmd_arc_print_memmap(cmd_arg_t *argv)
+{
+	arc_memdescriptor_t *desc;
+
+	printf("Memory map:\n");
+
+	desc = arc_entry->getmemorydescriptor(NULL);
+	while (desc) {
+		printf("%s: %d(%p) (size: %dKB)\n",basetypes[desc->type],
+		       desc->basepage * ARC_FRAME,
+		       desc->basepage * ARC_FRAME,
+		       desc->basecount*ARC_FRAME/1024);
+		desc = arc_entry->getmemorydescriptor(desc);
+	}
+	return 1;
+}
+static cmd_info_t memmap_info = {
+	.name = "arcmemmap",
+	.description = "Print arc memory map",
+	.func = cmd_arc_print_memmap,
+	.argc = 0
+};
+
+/** Print charactor to console */
+static void arc_putchar(char ch)
+{
+	uint32_t cnt;
+	ipl_t ipl;
+
+	/* TODO: Should be spinlock? */
+	ipl = interrupts_disable();
+	arc_entry->write(1, &ch, 1, &cnt);
+	interrupts_restore(ipl);
+	
+}
+
+static int cmd_reboot(cmd_arg_t *argv)
+{
+	arc_entry->reboot();
+	return 0;
+}
+static cmd_info_t reboot_info = {
+	.name = "reboot",
+	.description = "Reboot computer",
+	.func = cmd_reboot,
+	.argc = 0
+};
+
+/** Initialize ARC structure
+ *
+ * @return 0 - ARC OK, -1 - ARC does not exist
+ */
+int arc_init(void)
+{
+	if (sbp->signature != ARC_MAGIC) {
+		sbp = NULL;
+		return -1;
+	}
+	arc_entry = sbp->firmwarevector;
+
+	arc_putchar('A');
+	arc_putchar('R');
+	arc_putchar('C');
+	arc_putchar('\n');
+
+	/* Add command for resetting the computer */
+	cmd_initialize(&reboot_info);
+	cmd_register(&reboot_info);
+	cmd_initialize(&memmap_info);
+	cmd_register(&memmap_info);
+	cmd_initialize(&devlist_info);
+	cmd_register(&devlist_info);
+
+	return 0;
+}
+
+static bool kbd_polling_enabled;
+static chardev_t console;
+
+/** Try to get character, return character or -1 if not available */
+static void arc_keyboard_poll(void)
+{
+	char ch;
+	uint32_t count;
+	long result;
+	
+	if (! kbd_polling_enabled)
+		return;
+
+	if (arc_entry->getreadstatus(0))
+		return;
+	result = arc_entry->read(0, &ch, 1, &count);
+	if (result || count!=1) {
+		return;
+	}
+	if (ch == '\r')
+		ch = '\n';
+	if (ch == 0x7f)
+		ch = '\b';
+	
+	chardev_push_character(&console, ch);
+}
+
+static char arc_read(chardev_t *dev)
+{
+	char ch;
+	uint32_t count;
+	long result;
+
+	result = arc_entry->read(0, &ch, 1, &count);
+	if (result || count!=1) {
+		printf("Error reading from ARC keyboard.\n");
+		cpu_halt();
+	}
+	if (ch == '\r')
+		return '\n';
+	if (ch == 0x7f)
+		return '\b';
+	return ch;
+}
+
+static void arc_write(chardev_t *dev, const char ch)
+{
+	arc_putchar(ch);
+}
+
+static void arc_enable(chardev_t *dev)
+{
+	kbd_polling_enabled = true;
+}
+
+static void arc_disable(chardev_t *dev)
+{
+	kbd_polling_enabled = false;
+}
+
+static chardev_operations_t arc_ops = {
+	.resume = arc_enable,
+	.suspend = arc_disable,
+	.write = arc_write,
+	.read = arc_read
+};
+
+iroutine old_timer;
+/** Do polling on timer interrupt */
+static void timer_replace(int n, istate_t *istate)
+{
+	arc_keyboard_poll();
+	old_timer(n, istate);
+	arc_keyboard_poll();
+}
+
+void arc_console(void)
+{
+	kbd_polling_enabled = true;
+	
+	chardev_initialize("arc_console", &console, &arc_ops);
+	old_timer = int_register(TIMER_IRQ, "arc_kb_poll", timer_replace);
+	stdin = &console;
+	stdout = &console;
+}
+
+/* Initialize frame zones from ARC firmware. 
+ * In the future we may use even the FirmwareTemporary regions,
+ * currently we use the FreeMemory (what about the LoadedProgram?)
+ */
+void arc_frame_init(void)
+{
+	arc_memdescriptor_t *desc;
+	int total = 0;
+	uintptr_t base;
+	size_t basesize;
+
+	desc = arc_entry->getmemorydescriptor(NULL);
+	while (desc) {
+		if (desc->type == FreeMemory ||
+		    desc->type == FreeContiguous) {
+			base = desc->basepage*ARC_FRAME;
+			basesize = desc->basecount*ARC_FRAME;
+
+			if (base % FRAME_SIZE ) {
+				basesize -= FRAME_SIZE - (base % FRAME_SIZE);
+				base = ALIGN_UP(base, FRAME_SIZE);
+			}
+			basesize = ALIGN_DOWN(basesize, FRAME_SIZE);
+
+			total += basesize;
+			
+			zone_create(ADDR2PFN(base), SIZE2FRAMES(basesize),
+				    ADDR2PFN(base), 0);
+		}
+		desc = arc_entry->getmemorydescriptor(desc);
+	}
+
+	config.memory_size = total;
+}
+
+
+ /** @}
+ */
+
Index: kernel/arch/mips32/src/drivers/msim.c
===================================================================
--- kernel/arch/mips32/src/drivers/msim.c	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
+++ kernel/arch/mips32/src/drivers/msim.c	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
@@ -0,0 +1,131 @@
+/*
+ * 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 mips32	
+ * @{
+ */
+/** @file
+ */
+
+#include <interrupt.h>
+#include <console/chardev.h>
+#include <arch/drivers/msim.h>
+#include <arch/cp0.h>
+#include <console/console.h>
+
+static chardev_t console;
+
+static void msim_write(chardev_t *dev, const char ch);
+static void msim_enable(chardev_t *dev);
+static void msim_disable(chardev_t *dev);
+static char msim_do_read(chardev_t *dev);
+
+static chardev_operations_t msim_ops = {
+	.resume = msim_enable,
+	.suspend = msim_disable,
+	.write = msim_write,
+	.read = msim_do_read,
+};
+
+/** Putchar that works with MSIM & gxemul */
+void msim_write(chardev_t *dev, const char ch)
+{
+	*((char *) MSIM_VIDEORAM) = ch;
+}
+
+/* Called from getc(). */
+void msim_enable(chardev_t *dev)
+{
+	cp0_unmask_int(MSIM_KBD_IRQ);
+}
+
+/* Called from getc(). */
+void msim_disable(chardev_t *dev)
+{
+	cp0_mask_int(MSIM_KBD_IRQ);
+}
+
+#include <print.h>
+/** Read character using polling, assume interrupts disabled */
+static char msim_do_read(chardev_t *dev)
+{
+	char ch;
+
+	while (1) {
+		ch = *((volatile char *) MSIM_KBD_ADDRESS);
+		if (ch) {
+			if (ch == '\r')
+				return '\n';
+			if (ch == 0x7f)
+				return '\b';
+			return ch;
+		}
+	}
+}
+
+/** Process keyboard interrupt. */
+static void msim_interrupt(int n, istate_t *istate)
+{
+	char ch = 0;
+
+	ch = *((char *) MSIM_KBD_ADDRESS);
+	if (ch =='\r')
+		ch = '\n';
+	if (ch == 0x7f)
+		ch = '\b';
+	chardev_push_character(&console, ch);
+}
+
+
+/* Return console object representing msim console */
+void msim_console(void)
+{
+	chardev_initialize("msim_console", &console, &msim_ops);
+
+	int_register(MSIM_KBD_IRQ, "msim_kbd", msim_interrupt);
+
+	cp0_unmask_int(MSIM_KBD_IRQ);
+
+	stdin = &console;
+	stdout = &console;
+}
+
+static iroutine oldvector;
+void msim_kbd_grab(void)
+{
+	oldvector = int_register(MSIM_KBD_IRQ, "msim_kbd", msim_interrupt);
+}
+void msim_kbd_release(void)
+{
+	if (oldvector)
+		int_register(MSIM_KBD_IRQ, "user_interrupt", oldvector);
+}
+
+ /** @}
+ */
+
Index: kernel/arch/mips32/src/drivers/serial.c
===================================================================
--- kernel/arch/mips32/src/drivers/serial.c	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
+++ kernel/arch/mips32/src/drivers/serial.c	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
@@ -0,0 +1,148 @@
+/*
+ * 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 mips32	
+ * @{
+ */
+/** @file
+ */
+
+#include <interrupt.h>
+#include <arch/cp0.h>
+#include <arch/drivers/serial.h>
+#include <console/chardev.h>
+#include <console/console.h>
+
+static chardev_t console;
+static serial_t sconf[SERIAL_MAX];
+static bool kb_enabled;
+
+static void serial_write(chardev_t *d, const char ch)
+{
+	serial_t *sd = (serial_t *)d->data;
+
+	if (ch == '\n')
+		serial_write(d, '\r');
+	/* Wait until transmit buffer empty */
+	while (! (SERIAL_READ_LSR(sd->port) & (1<<TRANSMIT_EMPTY_BIT)))
+		;
+	SERIAL_WRITE(sd->port, ch);
+}
+
+static void serial_enable(chardev_t *d)
+{
+	kb_enabled = true;
+}
+
+static void serial_disable(chardev_t *d)
+{
+	kb_enabled = false;
+}
+
+int serial_init(void)
+{
+	int i = 0;
+	if (SERIAL_READ_LSR(SERIAL_COM1) == 0x60) {
+		sconf[i].port = SERIAL_COM1;
+		sconf[i].irq = SERIAL_COM1_IRQ;
+		/* Enable interrupt on available data */
+		i++;
+	}
+	return i;
+}
+
+/** Read character from serial port, wait until available */
+static char serial_do_read(chardev_t *dev)
+{
+	serial_t *sd = (serial_t *)dev->data;
+	char ch;
+
+	while (!(SERIAL_READ_LSR(sd->port) & 1))
+		;
+	ch = SERIAL_READ(sd->port);
+
+	if (ch =='\r')
+		ch = '\n';
+	return ch;
+}
+
+
+/** Process keyboard interrupt. Does not work in simics? */
+static void serial_interrupt(int n, void *stack)
+{
+	serial_t *sd = (serial_t *)console.data;
+	char ch;
+
+	if (!(SERIAL_READ_LSR(sd->port) & 1))
+		return;
+	ch = SERIAL_READ(sd->port);
+
+	if (ch =='\r')
+		ch = '\n';
+	chardev_push_character(&console, ch);
+}
+
+
+
+static chardev_operations_t serial_ops = {
+	.resume = serial_enable,
+	.suspend = serial_disable,
+	.write = serial_write,
+	.read = serial_do_read
+};
+
+iroutine old_timer;
+/** Do polling on timer interrupt */
+static void timer_replace(int n, istate_t *istate)
+{
+	old_timer(n, istate);
+	serial_interrupt(n, istate);
+}
+
+void serial_console(void)
+{
+	serial_t *sd = &sconf[0];
+
+
+	chardev_initialize("serial_console", &console, &serial_ops);
+	console.data = sd;
+	kb_enabled = true;
+
+//	int_register(2, "serial_drvr", serial_interrupt);
+	/* I don't know why, but the serial interrupts simply
+	 * don't work on simics
+	 */
+	old_timer = int_register(TIMER_IRQ, "serial_drvr_poll", timer_replace);
+	
+	stdin = &console;
+	stdout = &console;
+}
+
+ /** @}
+ */
+
Index: kernel/arch/mips32/src/dummy.S
===================================================================
--- kernel/arch/mips32/src/dummy.S	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
+++ kernel/arch/mips32/src/dummy.S	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
@@ -0,0 +1,41 @@
+#
+# Copyright (C) 2003-2004 Jakub Jermar
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# - Redistributions of source code must retain the above copyright
+#   notice, this list of conditions and the following disclaimer.
+# - Redistributions in binary form must reproduce the above copyright
+#   notice, this list of conditions and the following disclaimer in the
+#   documentation and/or other materials provided with the distribution.
+# - The name of the author may not be used to endorse or promote products
+#   derived from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+
+.text
+.set noat
+
+.global calibrate_delay_loop
+.global asm_delay_loop
+.global dummy
+	
+calibrate_delay_loop:
+asm_delay_loop:
+
+dummy:
+	j $31
+	nop
Index: kernel/arch/mips32/src/exception.c
===================================================================
--- kernel/arch/mips32/src/exception.c	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
+++ kernel/arch/mips32/src/exception.c	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
@@ -0,0 +1,179 @@
+/*
+ * 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 mips32	
+ * @{
+ */
+/** @file
+ */
+
+#include <arch/exception.h>
+#include <arch/interrupt.h>
+#include <panic.h>
+#include <arch/cp0.h>
+#include <arch/types.h>
+#include <arch.h>
+#include <debug.h>
+#include <proc/thread.h>
+#include <symtab.h>
+#include <print.h>
+#include <interrupt.h>
+#include <func.h>
+#include <console/kconsole.h>
+#include <arch/debugger.h>
+
+static 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",
+};
+
+static void print_regdump(istate_t *istate)
+{
+	char *pcsymbol = "";
+	char *rasymbol = "";
+
+	char *s = get_symtab_entry(istate->epc);
+	if (s)
+		pcsymbol = s;
+	s = get_symtab_entry(istate->ra);
+	if (s)
+		rasymbol = s;
+	
+	printf("PC: %#x(%s) RA: %#x(%s), SP(%p)\n", istate->epc, pcsymbol, istate->ra, rasymbol, istate->sp);
+}
+
+static void unhandled_exception(int n, istate_t *istate)
+{
+	fault_if_from_uspace(istate, "unhandled exception %s", exctable[n]);
+	
+	print_regdump(istate);
+	panic("unhandled exception %s\n", exctable[n]);
+}
+
+static void reserved_instr_exception(int n, istate_t *istate)
+{
+	if (*((uint32_t *)istate->epc) == 0x7c03e83b) {
+		ASSERT(THREAD);
+		istate->epc += 4;
+		istate->v1 = istate->k1;
+	} else 
+		unhandled_exception(n, istate);
+}
+
+static void breakpoint_exception(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(int n, istate_t *istate)
+{
+	tlb_modified(istate);
+}
+
+static void tlbinv_exception(int n, istate_t *istate)
+{
+	tlb_invalid(istate);
+}
+
+#ifdef CONFIG_FPU_LAZY
+static void cpuns_exception(int n, istate_t *istate)
+{
+	if (cp0_cause_coperr(cp0_cause_read()) == fpu_cop_id)
+		scheduler_fpu_lazy_request();
+	else {
+		fault_if_from_uspace(istate, "unhandled Coprocessor Unusable Exception");
+		panic("unhandled Coprocessor Unusable Exception\n");
+	}
+}
+#endif
+
+static void interrupt_exception(int n, istate_t *istate)
+{
+	uint32_t cause;
+	int i;
+	
+	/* decode interrupt number and process the interrupt */
+	cause = (cp0_cause_read() >> 8) &0xff;
+	
+	for (i = 0; i < 8; i++)
+		if (cause & (1 << i))
+			exc_dispatch(i+INT_OFFSET, istate);
+}
+
+/** Handle syscall userspace call */
+static void syscall_exception(int n, istate_t *istate)
+{
+	panic("Syscall is handled through shortcut");
+}
+
+void exception_init(void)
+{
+	int i;
+
+	/* Clear exception table */
+	for (i=0;i < IVT_ITEMS; i++)
+		exc_register(i, "undef", (iroutine) unhandled_exception);
+	exc_register(EXC_Bp, "bkpoint", (iroutine) breakpoint_exception);
+	exc_register(EXC_RI, "resinstr", (iroutine) reserved_instr_exception);
+	exc_register(EXC_Mod, "tlb_mod", (iroutine) tlbmod_exception);
+	exc_register(EXC_TLBL, "tlbinvl", (iroutine) tlbinv_exception);
+	exc_register(EXC_TLBS, "tlbinvl", (iroutine) tlbinv_exception);
+	exc_register(EXC_Int, "interrupt", (iroutine) interrupt_exception);
+#ifdef CONFIG_FPU_LAZY
+	exc_register(EXC_CpU, "cpunus", (iroutine) cpuns_exception);
+#endif
+	exc_register(EXC_Sys, "syscall", (iroutine) syscall_exception);
+}
+
+/** @}
+ */
Index: kernel/arch/mips32/src/fpu_context.c
===================================================================
--- kernel/arch/mips32/src/fpu_context.c	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
+++ kernel/arch/mips32/src/fpu_context.c	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
@@ -0,0 +1,62 @@
+/*
+ * 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 mips32	
+ * @{
+ */
+/** @file
+ *
+ */
+
+#include <fpu_context.h>
+#include <arch.h>
+#include <arch/cp0.h>
+#include <proc/thread.h>
+
+void fpu_disable(void)
+{	
+#ifdef ARCH_HAS_FPU
+	cp0_status_write(cp0_status_read() & ~cp0_status_fpu_bit);
+#endif
+}
+
+void fpu_enable(void)
+{
+#ifdef ARCH_HAS_FPU
+	cp0_status_write(cp0_status_read() | cp0_status_fpu_bit);
+#endif
+}
+
+void fpu_init()
+{
+	/* TODO: Zero all registers */
+}
+
+ /** @}
+ */
+
Index: kernel/arch/mips32/src/interrupt.c
===================================================================
--- kernel/arch/mips32/src/interrupt.c	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
+++ kernel/arch/mips32/src/interrupt.c	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
@@ -0,0 +1,146 @@
+/*
+ * 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 mips32interrupt
+ * @{
+ */
+/** @file
+ */
+
+#include <interrupt.h>
+#include <arch/interrupt.h>
+#include <arch/types.h>
+#include <arch.h>
+#include <arch/cp0.h>
+#include <time/clock.h>
+#include <arch/drivers/arc.h>
+
+#include <ipc/sysipc.h>
+
+/** 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();
+}
+
+/* TODO: This is SMP unsafe!!! */
+static unsigned long nextcount;
+/** Start hardware clock */
+static void timer_start(void)
+{
+	nextcount = cp0_compare_value + cp0_count_read();
+	cp0_compare_write(nextcount);
+}
+
+static void timer_exception(int n, istate_t *istate)
+{
+	unsigned long drift;
+
+	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);
+	clock();
+}
+
+static void swint0(int n, istate_t *istate)
+{
+	cp0_cause_write(cp0_cause_read() & ~(1 << 8)); /* clear SW0 interrupt */
+	ipc_irq_send_notif(0);
+}
+
+static void swint1(int n, istate_t *istate)
+{
+	cp0_cause_write(cp0_cause_read() & ~(1 << 9)); /* clear SW1 interrupt */
+	ipc_irq_send_notif(1);
+}
+
+/* Initialize basic tables for exception dispatching */
+void interrupt_init(void)
+{
+	int_register(TIMER_IRQ, "timer", timer_exception);
+	int_register(0, "swint0", swint0);
+	int_register(1, "swint1", swint1);
+	timer_start();
+}
+
+static void ipc_int(int n, istate_t *istate)
+{
+	ipc_irq_send_notif(n-INT_OFFSET);
+}
+
+/* Reregister irq to be IPC-ready */
+void irq_ipc_bind_arch(unative_t irq)
+{
+	/* Do not allow to redefine timer */
+	/* Swint0, Swint1 are already handled */
+	if (irq == TIMER_IRQ || irq < 2)
+		return;
+	int_register(irq, "ipc_int", ipc_int);
+}
+
+ /** @}
+ */
+
Index: kernel/arch/mips32/src/mips32.c
===================================================================
--- kernel/arch/mips32/src/mips32.c	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
+++ kernel/arch/mips32/src/mips32.c	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
@@ -0,0 +1,185 @@
+/*
+ * 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 mips32
+ * @{
+ */
+/** @file
+ */
+
+
+#include <arch.h>
+#include <arch/boot.h>
+#include <arch/cp0.h>
+#include <arch/exception.h>
+#include <arch/asm.h>
+#include <mm/as.h>
+
+#include <userspace.h>
+#include <arch/console.h>
+#include <memstr.h>
+#include <proc/thread.h>
+#include <proc/uarg.h>
+#include <print.h>
+#include <syscall/syscall.h>
+#include <sysinfo/sysinfo.h>
+
+#include <arch/interrupt.h>
+#include <arch/drivers/arc.h>
+#include <console/chardev.h>
+#include <arch/debugger.h>
+#include <genarch/fb/fb.h>
+#include <debug.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 *) 0x80000000)
+#define NORM_EXC ((char *) 0x80000180)
+#define CACHE_EXC ((char *) 0x80000100)
+
+
+/* Why the linker moves the variable 64K away in assembler
+ * when not in .text section ????????
+ */
+uintptr_t supervisor_sp __attribute__ ((section (".text")));
+/* Stack pointer saved when entering user mode */
+/* TODO: How do we do it on SMP system???? */
+bootinfo_t bootinfo __attribute__ ((section (".text")));
+
+void arch_pre_main(void)
+{
+	/* Setup usermode */
+	init.cnt = bootinfo.cnt;
+	
+	uint32_t i;
+	
+	for (i = 0; i < bootinfo.cnt; i++) {
+		init.tasks[i].addr = bootinfo.tasks[i].addr;
+		init.tasks[i].size = bootinfo.tasks[i].size;
+	}
+}
+
+void arch_pre_mm_init(void)
+{
+	/* It is not assumed by default */
+	interrupts_disable();
+	
+	/* Initialize dispatch table */
+	exception_init();
+	arc_init();
+
+	/* Copy the exception vectors to the right places */
+	memcpy(TLB_EXC, (char *)tlb_refill_entry, EXCEPTION_JUMP_SIZE);
+	memcpy(NORM_EXC, (char *)exception_entry, EXCEPTION_JUMP_SIZE);
+	memcpy(CACHE_EXC, (char *)cache_error_entry, EXCEPTION_JUMP_SIZE);
+
+	interrupt_init();
+	/*
+	 * 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();
+
+	/*
+	 * Unmask hardware clock interrupt.
+	 */
+	cp0_unmask_int(TIMER_IRQ);
+
+	console_init();
+	debugger_init();
+}
+
+void arch_post_mm_init(void)
+{
+#ifdef CONFIG_FB
+	fb_init(0x12000000, 640, 480, 24, 1920); // gxemul framebuffer
+#endif
+	sysinfo_set_item_val("machine." STRING(MACHINE),NULL,1);
+}
+
+void arch_pre_smp_init(void)
+{
+}
+
+void arch_post_smp_init(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+PAGE_SIZE), 
+		      (uintptr_t) kernel_uarg->uspace_uarg,
+		      (uintptr_t) kernel_uarg->uspace_entry);
+	while (1)
+		;
+}
+
+/** Perform mips32 specific tasks needed before the new task is run. */
+void before_task_runs_arch(void)
+{
+}
+
+/** Perform mips32 specific tasks needed before the new thread is scheduled. */
+void before_thread_runs_arch(void)
+{
+	supervisor_sp = (uintptr_t) &THREAD->kstack[THREAD_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.
+ */
+unative_t sys_tls_set(unative_t addr)
+{
+	return 0;
+}
+
+
+ /** @}
+ */
+
Index: kernel/arch/mips32/src/mm/as.c
===================================================================
--- kernel/arch/mips32/src/mm/as.c	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
+++ kernel/arch/mips32/src/mm/as.c	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
@@ -0,0 +1,78 @@
+/*
+ * 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 mips32mm
+ * @{
+ */
+/** @file
+ */
+
+#include <arch/mm/as.h>
+#include <genarch/mm/as_pt.h>
+#include <genarch/mm/asid_fifo.h>
+#include <arch/mm/tlb.h>
+#include <mm/tlb.h>
+#include <mm/as.h>
+#include <arch/cp0.h>
+#include <arch.h>
+
+/** Architecture dependent address space init. */
+void as_arch_init(void)
+{
+        as_operations = &as_pt_operations;
+	asid_fifo_init();
+}
+
+/** Install address space.
+ *
+ * Install ASID.
+ *
+ * @param as Address space structure.
+ */
+void as_install_arch(as_t *as)
+{
+	entry_hi_t hi;
+	ipl_t ipl;
+
+	/*
+	 * Install ASID.
+	 */	
+	hi.value = cp0_entry_hi_read();
+
+	ipl = interrupts_disable();
+	spinlock_lock(&as->lock);
+	hi.asid = as->asid;
+	cp0_entry_hi_write(hi.value);	
+	spinlock_unlock(&as->lock);
+	interrupts_restore(ipl);
+}
+
+
+ /** @}
+ */
+
Index: kernel/arch/mips32/src/mm/frame.c
===================================================================
--- kernel/arch/mips32/src/mm/frame.c	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
+++ kernel/arch/mips32/src/mm/frame.c	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
@@ -0,0 +1,60 @@
+/*
+ * 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 mips32mm	
+ * @{
+ */
+/** @file
+ */
+
+#include <arch/mm/frame.h>
+#include <mm/frame.h>
+#include <config.h>
+#include <arch/drivers/arc.h>
+
+/** Create memory zones
+ *
+ * If ARC is known, read information from ARC, otherwise
+ * assume some defaults. 
+ * - blacklist first FRAME because there is an exception vector
+ */
+void frame_arch_init(void)
+{
+	if (arc_enabled())
+		arc_frame_init();
+	else {
+		zone_create(0, ADDR2PFN(config.memory_size), 1, 0);
+		/*
+		 * Blacklist interrupt vector
+		 */
+		frame_mark_unavailable(0, 1);
+	}
+}
+
+/** @}
+ */
Index: kernel/arch/mips32/src/mm/page.c
===================================================================
--- kernel/arch/mips32/src/mm/page.c	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
+++ kernel/arch/mips32/src/mm/page.c	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
@@ -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 mips32mm	
+ * @{
+ */
+/** @file
+ */
+
+#include <arch/mm/page.h>
+#include <genarch/mm/page_pt.h>
+#include <mm/page.h>
+
+void page_arch_init(void)
+{
+	page_mapping_operations = &pt_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 + 0xa0000000;
+}
+
+ /** @}
+ */
+
Index: kernel/arch/mips32/src/mm/tlb.c
===================================================================
--- kernel/arch/mips32/src/mm/tlb.c	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
+++ kernel/arch/mips32/src/mm/tlb.c	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
@@ -0,0 +1,613 @@
+/*
+ * 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 mips32mm	
+ * @{
+ */
+/** @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 <symtab.h>
+#include <synch/spinlock.h>
+#include <print.h>
+#include <debug.h>
+#include <align.h>
+#include <interrupt.h>
+
+static void tlb_refill_fail(istate_t *istate);
+static void tlb_invalid_fail(istate_t *istate);
+static void tlb_modified_fail(istate_t *istate);
+
+static pte_t *find_mapping_and_check(uintptr_t badvaddr, int access, istate_t *istate, int *pfrc);
+
+static void prepare_entry_lo(entry_lo_t *lo, bool g, bool v, bool d, bool cacheable, uintptr_t pfn);
+static void prepare_entry_hi(entry_hi_t *hi, asid_t asid, uintptr_t addr);
+
+/** Initialize TLB
+ *
+ * Initialize TLB.
+ * Invalidate all entries and mark wired entries.
+ */
+void tlb_arch_init(void)
+{
+	int i;
+
+	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 (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);
+}
+
+/** Process TLB Refill Exception
+ *
+ * Process TLB Refill Exception.
+ *
+ * @param istate Interrupted register context.
+ */
+void tlb_refill(istate_t *istate)
+{
+	entry_lo_t lo;
+	entry_hi_t hi;
+	asid_t asid;
+	uintptr_t badvaddr;
+	pte_t *pte;
+	int pfrc;
+
+	badvaddr = cp0_badvaddr_read();
+
+	spinlock_lock(&AS->lock);
+	asid = AS->asid;
+	spinlock_unlock(&AS->lock);
+
+	page_table_lock(AS, true);
+
+	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().
+			 */
+			page_table_unlock(AS, true);
+			return;
+		default:
+			panic("unexpected pfrc (%d)\n", pfrc);
+		}
+	}
+
+	/*
+	 * Record access to PTE.
+	 */
+	pte->a = 1;
+
+	prepare_entry_hi(&hi, asid, badvaddr);
+	prepare_entry_lo(&lo, pte->g, pte->p, pte->d, pte->cacheable, pte->pfn);
+
+	/*
+	 * 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();
+
+	page_table_unlock(AS, true);
+	return;
+	
+fail:
+	page_table_unlock(AS, true);
+	tlb_refill_fail(istate);
+}
+
+/** Process TLB Invalid Exception
+ *
+ * Process TLB Invalid Exception.
+ *
+ * @param istate Interrupted register context.
+ */
+void tlb_invalid(istate_t *istate)
+{
+	tlb_index_t index;
+	uintptr_t badvaddr;
+	entry_lo_t lo;
+	entry_hi_t hi;
+	pte_t *pte;
+	int pfrc;
+
+	badvaddr = cp0_badvaddr_read();
+
+	/*
+	 * Locate the faulting entry in TLB.
+	 */
+	hi.value = cp0_entry_hi_read();
+	prepare_entry_hi(&hi, hi.asid, badvaddr);
+	cp0_entry_hi_write(hi.value);
+	tlbp();
+	index.value = cp0_index_read();
+
+	page_table_lock(AS, true);	
+	
+	/*
+	 * Fail if the entry is not in TLB.
+	 */
+	if (index.p) {
+		printf("TLB entry not found.\n");
+		goto fail;
+	}
+
+	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().
+			 */
+			page_table_unlock(AS, true);			 
+			return;
+		default:
+			panic("unexpected pfrc (%d)\n", pfrc);
+		}
+	}
+
+	/*
+	 * Read the faulting TLB entry.
+	 */
+	tlbr();
+
+	/*
+	 * Record access to PTE.
+	 */
+	pte->a = 1;
+
+	prepare_entry_lo(&lo, pte->g, pte->p, pte->d, pte->cacheable, pte->pfn);
+
+	/*
+	 * 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();
+
+	page_table_unlock(AS, true);
+	return;
+	
+fail:
+	page_table_unlock(AS, true);
+	tlb_invalid_fail(istate);
+}
+
+/** Process TLB Modified Exception
+ *
+ * Process TLB Modified Exception.
+ *
+ * @param istate Interrupted register context.
+ */
+void tlb_modified(istate_t *istate)
+{
+	tlb_index_t index;
+	uintptr_t badvaddr;
+	entry_lo_t lo;
+	entry_hi_t hi;
+	pte_t *pte;
+	int pfrc;
+
+	badvaddr = cp0_badvaddr_read();
+
+	/*
+	 * Locate the faulting entry in TLB.
+	 */
+	hi.value = cp0_entry_hi_read();
+	prepare_entry_hi(&hi, hi.asid, badvaddr);
+	cp0_entry_hi_write(hi.value);
+	tlbp();
+	index.value = cp0_index_read();
+
+	page_table_lock(AS, true);	
+	
+	/*
+	 * Fail if the entry is not in TLB.
+	 */
+	if (index.p) {
+		printf("TLB entry not found.\n");
+		goto fail;
+	}
+
+	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().
+			 */
+			page_table_unlock(AS, true);			 
+			return;
+		default:
+			panic("unexpected pfrc (%d)\n", pfrc);
+		}
+	}
+
+	/*
+	 * Fail if the page is not writable.
+	 */
+	if (!pte->w)
+		goto fail;
+
+	/*
+	 * Read the faulting TLB entry.
+	 */
+	tlbr();
+
+	/*
+	 * Record access and write to PTE.
+	 */
+	pte->a = 1;
+	pte->d = 1;
+
+	prepare_entry_lo(&lo, pte->g, pte->p, pte->w, pte->cacheable, pte->pfn);
+
+	/*
+	 * 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();
+
+	page_table_unlock(AS, true);
+	return;
+	
+fail:
+	page_table_unlock(AS, true);
+	tlb_modified_fail(istate);
+}
+
+void tlb_refill_fail(istate_t *istate)
+{
+	char *symbol = "";
+	char *sym2 = "";
+
+	char *s = get_symtab_entry(istate->epc);
+	if (s)
+		symbol = s;
+	s = get_symtab_entry(istate->ra);
+	if (s)
+		sym2 = s;
+
+	fault_if_from_uspace(istate, "TLB Refill Exception on %p", cp0_badvaddr_read());
+	panic("%x: TLB Refill Exception at %x(%s<-%s)\n", cp0_badvaddr_read(), istate->epc, symbol, sym2);
+}
+
+
+void tlb_invalid_fail(istate_t *istate)
+{
+	char *symbol = "";
+
+	char *s = get_symtab_entry(istate->epc);
+	if (s)
+		symbol = s;
+	fault_if_from_uspace(istate, "TLB Invalid Exception on %p", cp0_badvaddr_read());
+	panic("%x: TLB Invalid Exception at %x(%s)\n", cp0_badvaddr_read(), istate->epc, symbol);
+}
+
+void tlb_modified_fail(istate_t *istate)
+{
+	char *symbol = "";
+
+	char *s = get_symtab_entry(istate->epc);
+	if (s)
+		symbol = s;
+	fault_if_from_uspace(istate, "TLB Modified Exception on %p", cp0_badvaddr_read());
+	panic("%x: TLB Modified Exception at %x(%s)\n", cp0_badvaddr_read(), istate->epc, symbol);
+}
+
+/** Try to find PTE for faulting address
+ *
+ * Try to find PTE for faulting address.
+ * The AS->lock must be held on entry to this function.
+ *
+ * @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.
+ */
+pte_t *find_mapping_and_check(uintptr_t badvaddr, int access, istate_t *istate, int *pfrc)
+{
+	entry_hi_t hi;
+	pte_t *pte;
+
+	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 = page_mapping_find(AS, badvaddr);
+	if (pte && pte->p) {
+		/*
+		 * 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.
+		 */
+		page_table_unlock(AS, true);
+		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.
+			 */
+			page_table_lock(AS, true);
+			pte = page_mapping_find(AS, badvaddr);
+			ASSERT(pte && pte->p);
+			return pte;
+			break;
+		case AS_PF_DEFER:
+			page_table_lock(AS, true);
+			*pfrc = AS_PF_DEFER;
+			return NULL;
+			break;
+		case AS_PF_FAULT:
+			page_table_lock(AS, true);
+			printf("Page fault.\n");
+			*pfrc = AS_PF_FAULT;
+			return NULL;
+			break;
+		default:
+			panic("unexpected rc (%d)\n", rc);
+		}
+		
+	}
+}
+
+void prepare_entry_lo(entry_lo_t *lo, bool g, bool v, bool d, bool cacheable, uintptr_t pfn)
+{
+	lo->value = 0;
+	lo->g = g;
+	lo->v = v;
+	lo->d = d;
+	lo->c = cacheable ? PAGE_CACHEABLE_EXC_WRITE : PAGE_UNCACHED;
+	lo->pfn = pfn;
+}
+
+void prepare_entry_hi(entry_hi_t *hi, asid_t asid, uintptr_t addr)
+{
+	hi->value = ALIGN_DOWN(addr, PAGE_SIZE * 2);
+	hi->asid = asid;
+}
+
+/** Print contents of TLB. */
+void tlb_print(void)
+{
+	page_mask_t mask;
+	entry_lo_t lo0, lo1;
+	entry_hi_t hi, hi_save;
+	int i;
+
+	hi_save.value = cp0_entry_hi_read();
+
+	printf("TLB:\n");
+	for (i = 0; i < TLB_ENTRY_COUNT; i++) {
+		cp0_index_write(i);
+		tlbr();
+		
+		mask.value = cp0_pagemask_read();
+		hi.value = cp0_entry_hi_read();
+		lo0.value = cp0_entry_lo0_read();
+		lo1.value = cp0_entry_lo1_read();
+		
+		printf("%d: asid=%d, vpn2=%d, mask=%d\tg[0]=%d, v[0]=%d, d[0]=%d, c[0]=%hhd, pfn[0]=%d\n"
+		       "\t\t\t\tg[1]=%d, v[1]=%d, d[1]=%d, c[1]=%hhd, pfn[1]=%d\n",
+		       i, hi.asid, hi.vpn2, mask.mask, lo0.g, lo0.v, lo0.d, lo0.c, lo0.pfn,
+		       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)
+{
+	ipl_t ipl;
+	entry_lo_t lo0, lo1;
+	entry_hi_t hi_save;
+	int i;
+
+	hi_save.value = cp0_entry_hi_read();
+	ipl = interrupts_disable();
+
+	for (i = TLB_WIRED; i < TLB_ENTRY_COUNT; i++) {
+		cp0_index_write(i);
+		tlbr();
+
+		lo0.value = cp0_entry_lo0_read();
+		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)
+{
+	ipl_t ipl;
+	entry_lo_t lo0, lo1;
+	entry_hi_t hi, hi_save;
+	int i;
+
+	ASSERT(asid != ASID_INVALID);
+
+	hi_save.value = cp0_entry_hi_read();
+	ipl = interrupts_disable();
+	
+	for (i = 0; i < TLB_ENTRY_COUNT; i++) {
+		cp0_index_write(i);
+		tlbr();
+		
+		hi.value = cp0_entry_hi_read();
+		
+		if (hi.asid == asid) {
+			lo0.value = cp0_entry_lo0_read();
+			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, count_t cnt)
+{
+	int i;
+	ipl_t ipl;
+	entry_lo_t lo0, lo1;
+	entry_hi_t hi, hi_save;
+	tlb_index_t index;
+
+	ASSERT(asid != ASID_INVALID);
+
+	hi_save.value = cp0_entry_hi_read();
+	ipl = interrupts_disable();
+
+	for (i = 0; i < cnt+1; i+=2) {
+		hi.value = 0;
+		prepare_entry_hi(&hi, asid, page + i * PAGE_SIZE);
+		cp0_entry_hi_write(hi.value);
+
+		tlbp();
+		index.value = cp0_index_read();
+
+		if (!index.p) {
+			/* Entry was found, index register contains valid index. */
+			tlbr();
+
+			lo0.value = cp0_entry_lo0_read();
+			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/mips32/src/panic.S
===================================================================
--- kernel/arch/mips32/src/panic.S	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
+++ kernel/arch/mips32/src/panic.S	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
@@ -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.
+#
+
+.text   
+
+.set noat
+.set noreorder
+.set nomacro
+
+#include <arch/asm/regname.h>
+	
+.global panic_printf
+
+/* From printf return directly to halt() */	
+panic_printf:
+	jal printf
+	nop
+	j halt
+	nop
+/* This code does not work, god knows why */		
+/*	lui $ra, %hi(halt)
+	j printf
+	ori $ra, %lo(halt) */
Index: kernel/arch/mips32/src/start.S
===================================================================
--- kernel/arch/mips32/src/start.S	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
+++ kernel/arch/mips32/src/start.S	(revision 1167520724b9b526c27b67f2d4bc447ef626240c)
@@ -0,0 +1,337 @@
+#
+# 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>
+	
+.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 should are thread-local
+#define REG_SAVE_MASK 0x1f # KSU(UM), EXL, ERL, IE
+	
+# Save registers to space defined by \r
+# We will change status: Disable ERL,EXL,UM,IE
+# These changes will be automatically reversed in REGISTER_LOAD
+# SP is NOT saved as part of these registers
+.macro REGISTERS_STORE_AND_EXC_RESET r
+	sw $at,EOFFSET_AT(\r)
+	sw $v0,EOFFSET_V0(\r)
+	sw $v1,EOFFSET_V1(\r)
+	sw $a0,EOFFSET_A0(\r)
+	sw $a1,EOFFSET_A1(\r)
+	sw $a2,EOFFSET_A2(\r)
+	sw $a3,EOFFSET_A3(\r)
+	sw $t0,EOFFSET_T0(\r)
+	sw $t1,EOFFSET_T1(\r)
+	sw $t2,EOFFSET_T2(\r)
+	sw $t3,EOFFSET_T3(\r)
+	sw $t4,EOFFSET_T4(\r)
+	sw $t5,EOFFSET_T5(\r)
+	sw $t6,EOFFSET_T6(\r)
+	sw $t7,EOFFSET_T7(\r)
+	sw $t8,EOFFSET_T8(\r)
+	sw $t9,EOFFSET_T9(\r)
+
+	mflo $at
+	sw $at, EOFFSET_LO(\r)
+	mfhi $at
+	sw $at, EOFFSET_HI(\r)
+	
+#ifdef CONFIG_DEBUG_ALLREGS	
+	sw $s0,EOFFSET_S0(\r)
+	sw $s1,EOFFSET_S1(\r)
+	sw $s2,EOFFSET_S2(\r)
+	sw $s3,EOFFSET_S3(\r)
+	sw $s4,EOFFSET_S4(\r)
+	sw $s5,EOFFSET_S5(\r)
+	sw $s6,EOFFSET_S6(\r)
+	sw $s7,EOFFSET_S7(\r)
+	sw $s8,EOFFSET_S8(\r)
+#endif
+	
+	sw $gp,EOFFSET_GP(\r)
+	sw $ra,EOFFSET_RA(\r)
+	sw $k1,EOFFSET_K1(\r)
+
+	mfc0 $t0, $status
+	mfc0 $t1, $epc
+	
+	and $t2, $t0, REG_SAVE_MASK  # Save only KSU,EXL,ERL,IE
+	li $t3, ~(0x1f)
+	and $t0, $t0, $t3           # Clear KSU,EXL,ERL,IE
+	
+	sw $t2,EOFFSET_STATUS(\r)
+	sw $t1,EOFFSET_EPC(\r)
+	mtc0 $t0, $status
+.endm
+
+.macro REGISTERS_LOAD r
+	# Update only UM,EXR,IE from status, the rest
+	# is controlled by OS and not bound to task
+	mfc0 $t0, $status
+	lw $t1,EOFFSET_STATUS(\r)
+
+	li $t2, ~REG_SAVE_MASK    # Mask UM,EXL,ERL,IE
+	and $t0, $t0, $t2
+	
+	or $t0, $t0, $t1   # Copy UM,EXL,ERL,IE from saved status
+	mtc0 $t0, $status
+	
+	lw $v0,EOFFSET_V0(\r)
+	lw $v1,EOFFSET_V1(\r)
+	lw $a0,EOFFSET_A0(\r)
+	lw $a1,EOFFSET_A1(\r)
+	lw $a2,EOFFSET_A2(\r)
+	lw $a3,EOFFSET_A3(\r)
+	lw $t0,EOFFSET_T0(\r)
+	lw $t1,EOFFSET_T1(\r)
+	lw $t2,EOFFSET_T2(\r)
+	lw $t3,EOFFSET_T3(\r)
+	lw $t4,EOFFSET_T4(\r)
+	lw $t5,EOFFSET_T5(\r)
+	lw $t6,EOFFSET_T6(\r)
+	lw $t7,EOFFSET_T7(\r)
+	lw $t8,EOFFSET_T8(\r)
+	lw $t9,EOFFSET_T9(\r)
+	
+#ifdef CONFIG_DEBUG_ALLREGS	
+	lw $s0,EOFFSET_S0(\r)
+	lw $s1,EOFFSET_S1(\r)
+	lw $s2,EOFFSET_S2(\r)
+	lw $s3,EOFFSET_S3(\r)
+	lw $s4,EOFFSET_S4(\r)
+	lw $s5,EOFFSET_S5(\r)
+	lw $s6,EOFFSET_S6(\r)
+	lw $s7,EOFFSET_S7(\r)
+	lw $s8,EOFFSET_S8(\r)
+#endif
+	lw $gp,EOFFSET_GP(\r)
+	lw $ra,EOFFSET_RA(\r)
+	lw $k1,EOFFSET_K1(\r)
+	
+	lw $at,EOFFSET_LO(\r)
+	mtlo $at
+	lw $at,EOFFSET_HI(\r)
+	mthi $at
+
+	lw $at,EOFFSET_EPC(\r)
+	mtc0 $at, $epc
+	
+	lw $at,EOFFSET_AT(\r)
+	lw $sp,EOFFSET_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
+	mfc0 $k0, $status
+	andi $k0, 0x10
+	
+	beq $k0, $0, 1f
+	add $k0, $sp, 0
+	
+	# Move $k0 pointer to kernel stack
+	lui $k0, %hi(supervisor_sp)
+	ori $k0, $k0, %lo(supervisor_sp)
+	# Move $k0 (superveisor_sp)
+	lw $k0, 0($k0)
+1:		
+.endm
+		
+.org 0x0
+kernel_image_start:
+	/* Load temporary stack */
+	lui $sp, %hi(end_stack)
+	ori $sp, $sp, %lo(end_stack)
+	
+	/* $a1 contains physical address of bootinfo_t */
+	/* $a2 contains size of bootinfo_t */
+	
+	beq $a2, $0, bootinfo_end
+	
+	/* Not sure about this, but might be needed for PIC code???? */
+	lui $gp, 0x8000
+	
+	lui $a3, %hi(bootinfo)
+	ori $a3, $a3, %lo(bootinfo)
+	
+	bootinfo_loop:
+		
+		lw $v0, 0($a1)
+		sw $v0, 0($a3)
+		
+		addi $a1, $a1, 4
+		addi $a3, $a3, 4
+		addi $a2, $a2, -4
+		
+		bgtz $a2, bootinfo_loop
+		nop
+		
+	bootinfo_end:
+	
+	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	
+
+	
+	
+exception_handler:
+	KERNEL_STACK_TO_K0
+	sub $k0, REGISTER_SPACE
+	sw $sp,EOFFSET_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
+
+# it seems that mips reserves some space on stack for varfuncs???
+#define SS_ARG4   16
+#define SS_SP     EOFFSET_SP
+#define SS_STATUS EOFFSET_STATUS
+#define SS_EPC    EOFFSET_EPC
+#define SS_K1     EOFFSET_K1
+syscall_shortcut:
+	# We have a lot of space on the stack, with free use
+	mfc0 $t1, $epc
+	mfc0 $t0, $status
+	sw $t1,SS_EPC($sp)  # Save EPC
+	sw $k1,SS_K1($sp)   # Save k1, which is not saved during context switch
+	
+	and $t2, $t0, REG_SAVE_MASK # Save only KSU,EXL,ERL,IE
+	li $t3, ~(0x1f)
+	and $t0, $t0, $t3           # Clear KSU,EXL,ERL
+	ori $t0, $t0, 0x1           # Set IE
+
+	sw $t2,SS_STATUS($sp)
+	mtc0 $t0, $status
+
+	# CALL Syscall handler
+	jal syscall_handler
+	sw $v0, SS_ARG4($sp)        # save v0 - arg4 to stack
+
+	# restore status
+	mfc0 $t0, $status
+	lw $t1,SS_STATUS($sp)
+
+	# Change back to EXL=1(from last exception), otherwise
+	# an interrupt could rewrite the CP0-EPC
+	li $t2, ~REG_SAVE_MASK      # Mask UM,EXL,ERL,IE
+	and $t0, $t0, $t2
+	or $t0, $t0, $t1            # Copy UM,EXL,ERL,IE from saved status
+	mtc0 $t0, $status
+			
+	# restore epc+4
+	lw $t0,SS_EPC($sp)
+	lw $k1,SS_K1($sp)
+	addi $t0, $t0, 4
+	mtc0 $t0, $epc
+	
+	lw $sp,SS_SP($sp) # restore sp
+	
+	eret
+		
+tlb_refill_handler:
+	KERNEL_STACK_TO_K0
+	sub $k0, REGISTER_SPACE
+	REGISTERS_STORE_AND_EXC_RESET $k0
+	sw $sp,EOFFSET_SP($k0)
+	add $sp, $k0, 0
+
+	jal tlb_refill
+	add $a0, $sp, 0 
+
+	REGISTERS_LOAD $sp
+
+	eret
+
+cache_error_handler:
+	KERNEL_STACK_TO_K0
+	sub $k0, REGISTER_SPACE
+	REGISTERS_STORE_AND_EXC_RESET $k0
+	sw $sp,EOFFSET_SP($k0)
+	add $sp, $k0, 0
+
+	jal cache_error
+	add $a0, $sp, 0 
+
+	REGISTERS_LOAD $sp
+
+	eret
+
+userspace_asm:
+	add $sp, $a0, 0
+	add $v0, $a1, 0 
+	add $t9, $a2, 0   # Set up correct entry into PIC code 
+	eret
