Index: arch/amd64/include/mm/asid.h
===================================================================
--- arch/amd64/include/mm/asid.h	(revision 1084a7848bafa4813443a91f16a7fc9514ecd5d9)
+++ arch/amd64/include/mm/asid.h	(revision 1084a7848bafa4813443a91f16a7fc9514ecd5d9)
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2005 Jakub Jermar
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __amd64_ASID_H__
+#define __amd64_ASID_H__
+
+typedef int asid_t;
+
+#define asid_get()	0
+
+#endif
Index: arch/amd64/include/mm/page.h
===================================================================
--- arch/amd64/include/mm/page.h	(revision 8e3f47b39ca2e552e1a80721744728dc6811ce38)
+++ arch/amd64/include/mm/page.h	(revision 1084a7848bafa4813443a91f16a7fc9514ecd5d9)
@@ -75,6 +75,4 @@
 #ifndef __ASM__
 
-typedef struct page_specifier pte_t;
-
 struct page_specifier {
 	unsigned present : 1;
Index: arch/amd64/include/mm/vm.h
===================================================================
--- arch/amd64/include/mm/vm.h	(revision 8e3f47b39ca2e552e1a80721744728dc6811ce38)
+++ arch/amd64/include/mm/vm.h	(revision 1084a7848bafa4813443a91f16a7fc9514ecd5d9)
@@ -41,3 +41,5 @@
 #define UDATA_ADDRESS_ARCH	0x21000000
 
+#define vm_install_arch(vm)
+
 #endif
Index: arch/amd64/include/types.h
===================================================================
--- arch/amd64/include/types.h	(revision 8e3f47b39ca2e552e1a80721744728dc6811ce38)
+++ arch/amd64/include/types.h	(revision 1084a7848bafa4813443a91f16a7fc9514ecd5d9)
@@ -46,3 +46,5 @@
 typedef __u64 __native;
 
+typedef struct page_specifier pte_t;
+
 #endif
Index: arch/amd64/src/cpu/cpu.c
===================================================================
--- arch/amd64/src/cpu/cpu.c	(revision 8e3f47b39ca2e552e1a80721744728dc6811ce38)
+++ arch/amd64/src/cpu/cpu.c	(revision 1084a7848bafa4813443a91f16a7fc9514ecd5d9)
@@ -35,4 +35,5 @@
 #include <print.h>
 #include <typedefs.h>
+#include <fpu_context.h>
 
 /*
Index: arch/amd64/src/interrupt.c
===================================================================
--- arch/amd64/src/interrupt.c	(revision 8e3f47b39ca2e552e1a80721744728dc6811ce38)
+++ arch/amd64/src/interrupt.c	(revision 1084a7848bafa4813443a91f16a7fc9514ecd5d9)
@@ -40,4 +40,5 @@
 #include <arch/asm.h>
 #include <proc/scheduler.h>
+#include <proc/thread.h>
 
 
Index: arch/ia32/include/mm/asid.h
===================================================================
--- arch/ia32/include/mm/asid.h	(revision 1084a7848bafa4813443a91f16a7fc9514ecd5d9)
+++ arch/ia32/include/mm/asid.h	(revision 1084a7848bafa4813443a91f16a7fc9514ecd5d9)
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2005 Jakub Jermar
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __ia32_ASID_H__
+#define __ia32_ASID_H__
+
+typedef int asid_t;
+
+#define asid_get()	0
+
+#endif
Index: arch/ia32/include/mm/page.h
===================================================================
--- arch/ia32/include/mm/page.h	(revision 8e3f47b39ca2e552e1a80721744728dc6811ce38)
+++ arch/ia32/include/mm/page.h	(revision 1084a7848bafa4813443a91f16a7fc9514ecd5d9)
@@ -91,6 +91,4 @@
 } __attribute__ ((packed));
 
-typedef struct page_specifier pte_t;
-
 static inline int get_pt_flags(pte_t *pt, index_t i)
 {
Index: arch/ia32/include/mm/vm.h
===================================================================
--- arch/ia32/include/mm/vm.h	(revision 8e3f47b39ca2e552e1a80721744728dc6811ce38)
+++ arch/ia32/include/mm/vm.h	(revision 1084a7848bafa4813443a91f16a7fc9514ecd5d9)
@@ -41,3 +41,5 @@
 #define UDATA_ADDRESS_ARCH	0x21000000
 
+#define vm_install_arch(vm)
+
 #endif
Index: arch/ia32/include/types.h
===================================================================
--- arch/ia32/include/types.h	(revision 8e3f47b39ca2e552e1a80721744728dc6811ce38)
+++ arch/ia32/include/types.h	(revision 1084a7848bafa4813443a91f16a7fc9514ecd5d9)
@@ -45,3 +45,5 @@
 typedef __u32 __native;
 
+typedef struct page_specifier pte_t;
+
 #endif
Index: arch/ia32/src/cpu/cpu.c
===================================================================
--- arch/ia32/src/cpu/cpu.c	(revision 8e3f47b39ca2e552e1a80721744728dc6811ce38)
+++ arch/ia32/src/cpu/cpu.c	(revision 1084a7848bafa4813443a91f16a7fc9514ecd5d9)
@@ -35,4 +35,5 @@
 #include <print.h>
 #include <typedefs.h>
+#include <fpu_context.h>
 
 #include <arch/smp/apic.h>
Index: arch/ia32/src/interrupt.c
===================================================================
--- arch/ia32/src/interrupt.c	(revision 8e3f47b39ca2e552e1a80721744728dc6811ce38)
+++ arch/ia32/src/interrupt.c	(revision 1084a7848bafa4813443a91f16a7fc9514ecd5d9)
@@ -38,4 +38,5 @@
 #include <arch.h>
 #include <symtab.h>
+#include <proc/thread.h>
 
 /*
Index: arch/ia64/include/mm/asid.h
===================================================================
--- arch/ia64/include/mm/asid.h	(revision 1084a7848bafa4813443a91f16a7fc9514ecd5d9)
+++ arch/ia64/include/mm/asid.h	(revision 1084a7848bafa4813443a91f16a7fc9514ecd5d9)
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2005 Jakub Jermar
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __ia64_ASID_H__
+#define __ia64_ASID_H__
+
+typedef int asid_t;
+
+#define asid_get()	0
+
+#endif
Index: arch/ia64/include/mm/page.h
===================================================================
--- arch/ia64/include/mm/page.h	(revision 8e3f47b39ca2e552e1a80721744728dc6811ce38)
+++ arch/ia64/include/mm/page.h	(revision 1084a7848bafa4813443a91f16a7fc9514ecd5d9)
@@ -71,5 +71,3 @@
 #define SET_FRAME_FLAGS_ARCH(ptl3, i, x)
 
-typedef __u64 pte_t;
-
 #endif
Index: arch/ia64/include/mm/vm.h
===================================================================
--- arch/ia64/include/mm/vm.h	(revision 8e3f47b39ca2e552e1a80721744728dc6811ce38)
+++ arch/ia64/include/mm/vm.h	(revision 1084a7848bafa4813443a91f16a7fc9514ecd5d9)
@@ -41,3 +41,5 @@
 #define UDATA_ADDRESS_ARCH	0x0000000001001000
 
+#define vm_install_arch(vm)
+
 #endif
Index: arch/ia64/include/types.h
===================================================================
--- arch/ia64/include/types.h	(revision 8e3f47b39ca2e552e1a80721744728dc6811ce38)
+++ arch/ia64/include/types.h	(revision 1084a7848bafa4813443a91f16a7fc9514ecd5d9)
@@ -45,3 +45,5 @@
 typedef __u64 __native;
 
+typedef __u64 pte_t;
+
 #endif
Index: arch/mips32/Makefile.inc
===================================================================
--- arch/mips32/Makefile.inc	(revision 8e3f47b39ca2e552e1a80721744728dc6811ce38)
+++ arch/mips32/Makefile.inc	(revision 1084a7848bafa4813443a91f16a7fc9514ecd5d9)
@@ -11,6 +11,6 @@
 
 DEFS=-DARCH=$(ARCH) -DMACHINE=${MACHINE} -DKERNEL_LOAD_ADDRESS=${KERNEL_LOAD_ADDRESS}
-CFLAGS=$(DEFS) -mno-abicalls -G 0 -nostdlib -fno-builtin -O2  -fno-zero-initialized-in-bss 
-LFLAGS=-M -N
+CFLAGS=$(DEFS) -mno-abicalls -G 0 -nostdlib -fno-builtin -O2  -fno-zero-initialized-in-bss
+LFLAGS=
 BFD_ARCH=mips
 
@@ -87,7 +87,9 @@
 	src/arch/cache.c \
 	src/arch/cpu/cpu.c \
+	src/arch/mm/asid.c \
 	src/arch/mm/frame.c \
 	src/arch/mm/page.c \
 	src/arch/mm/tlb.c \
+	src/arch/mm/vm.c \
 	src/arch/fpu_context.c \
 	src/arch/fmath.c \
Index: arch/mips32/include/cp0.h
===================================================================
--- arch/mips32/include/cp0.h	(revision 8e3f47b39ca2e552e1a80721744728dc6811ce38)
+++ arch/mips32/include/cp0.h	(revision 1084a7848bafa4813443a91f16a7fc9514ecd5d9)
@@ -31,4 +31,5 @@
 
 #include <arch/types.h>
+#include <arch/mm/tlb.h>
 
 #define cp0_status_ie_enabled_bit	(1<<0)
Index: arch/mips32/include/mm/asid.h
===================================================================
--- arch/mips32/include/mm/asid.h	(revision 8e3f47b39ca2e552e1a80721744728dc6811ce38)
+++ arch/mips32/include/mm/asid.h	(revision 1084a7848bafa4813443a91f16a7fc9514ecd5d9)
@@ -1,4 +1,4 @@
 /*
- * Copyright (C) 2005 Matrin Decky
+ * Copyright (C) 2005 Martin Decky
  * All rights reserved.
  *
@@ -30,5 +30,10 @@
 #define __mips32_ASID_H__
 
-extern void asid_bitmap_reset(void);
+#include <arch/types.h>
+
+typedef __u8 asid_t;
+
+extern asid_t asid_get(void);
+extern void asid_put(asid_t asid);
 
 #endif
Index: arch/mips32/include/mm/page.h
===================================================================
--- arch/mips32/include/mm/page.h	(revision 8e3f47b39ca2e552e1a80721744728dc6811ce38)
+++ arch/mips32/include/mm/page.h	(revision 1084a7848bafa4813443a91f16a7fc9514ecd5d9)
@@ -57,18 +57,18 @@
 #define PTL1_INDEX_ARCH(vaddr)  0
 #define PTL2_INDEX_ARCH(vaddr)  0
-#define PTL3_INDEX_ARCH(vaddr)  (((vaddr)>>14)&0xfff)
+#define PTL3_INDEX_ARCH(vaddr)  (((vaddr)>>12)&0xfff)
 
 #define GET_PTL0_ADDRESS_ARCH()			(PTL0)
 #define SET_PTL0_ADDRESS_ARCH(ptl0)		(PTL0 = (pte_t *)(ptl0))
 
-#define GET_PTL1_ADDRESS_ARCH(ptl0, i)		(((pte_t *)(ptl0))[(i)].pfn<<14)
+#define GET_PTL1_ADDRESS_ARCH(ptl0, i)		(((pte_t *)(ptl0))[(i)].pfn<<12)
 #define GET_PTL2_ADDRESS_ARCH(ptl1, i)		(ptl1)
 #define GET_PTL3_ADDRESS_ARCH(ptl2, i)		(ptl2)
-#define GET_FRAME_ADDRESS_ARCH(ptl3, i)		(((pte_t *)(ptl3))[(i)].pfn<<14)
+#define GET_FRAME_ADDRESS_ARCH(ptl3, i)		(((pte_t *)(ptl3))[(i)].pfn<<12)
 
-#define SET_PTL1_ADDRESS_ARCH(ptl0, i, a)	(((pte_t *)(ptl0))[(i)].pfn = (a)>>14)
+#define SET_PTL1_ADDRESS_ARCH(ptl0, i, a)	(((pte_t *)(ptl0))[(i)].pfn = (a)>>12)
 #define SET_PTL2_ADDRESS_ARCH(ptl1, i, a)
 #define SET_PTL3_ADDRESS_ARCH(ptl2, i, a)
-#define SET_FRAME_ADDRESS_ARCH(ptl3, i, a)	(((pte_t *)(ptl3))[(i)].pfn = (a)>>14)
+#define SET_FRAME_ADDRESS_ARCH(ptl3, i, a)	(((pte_t *)(ptl3))[(i)].pfn = (a)>>12)
 
 #define GET_PTL1_FLAGS_ARCH(ptl0, i)		get_pt_flags((pte_t *)(ptl0), (index_t)(i))
Index: arch/mips32/include/mm/tlb.h
===================================================================
--- arch/mips32/include/mm/tlb.h	(revision 8e3f47b39ca2e552e1a80721744728dc6811ce38)
+++ arch/mips32/include/mm/tlb.h	(revision 1084a7848bafa4813443a91f16a7fc9514ecd5d9)
@@ -53,6 +53,5 @@
 struct entry_hi {
 	unsigned asid : 8;
-	unsigned : 4;
-	unsigned g : 1;
+	unsigned : 5;
 	unsigned vpn2 : 19;
 } __attribute__ ((packed));
@@ -71,5 +70,4 @@
 } __attribute__ ((packed));
 
-typedef struct entry_lo pte_t;
 
 /** Read Indexed TLB Entry
Index: arch/mips32/include/mm/vm.h
===================================================================
--- arch/mips32/include/mm/vm.h	(revision 8e3f47b39ca2e552e1a80721744728dc6811ce38)
+++ arch/mips32/include/mm/vm.h	(revision 1084a7848bafa4813443a91f16a7fc9514ecd5d9)
@@ -31,4 +31,5 @@
 
 #include <arch/types.h>
+#include <typedefs.h>
 
 #define KERNEL_ADDRESS_SPACE_START_ARCH		(__address) 0x80000000
@@ -41,3 +42,5 @@
 #define UDATA_ADDRESS_ARCH	0x01001000
 
+extern void vm_install_arch(vm_t *vm);
+
 #endif
Index: arch/mips32/include/types.h
===================================================================
--- arch/mips32/include/types.h	(revision 8e3f47b39ca2e552e1a80721744728dc6811ce38)
+++ arch/mips32/include/types.h	(revision 1084a7848bafa4813443a91f16a7fc9514ecd5d9)
@@ -50,3 +50,5 @@
 typedef __u32 __native;
 
+typedef struct entry_lo pte_t;
+
 #endif
Index: arch/mips32/src/exception.c
===================================================================
--- arch/mips32/src/exception.c	(revision 8e3f47b39ca2e552e1a80721744728dc6811ce38)
+++ arch/mips32/src/exception.c	(revision 1084a7848bafa4813443a91f16a7fc9514ecd5d9)
@@ -34,4 +34,5 @@
 #include <arch.h>
 #include <debug.h>
+#include <proc/thread.h>
 
 void exception(struct exception_regdump *pstate)
Index: arch/mips32/src/mips32.c
===================================================================
--- arch/mips32/src/mips32.c	(revision 8e3f47b39ca2e552e1a80721744728dc6811ce38)
+++ arch/mips32/src/mips32.c	(revision 1084a7848bafa4813443a91f16a7fc9514ecd5d9)
@@ -38,5 +38,5 @@
 #include <arch/interrupt.h>
 #include <arch/drivers/arc.h>
-
+#include <proc/thread.h>
 #include <print.h>
 
Index: arch/mips32/src/mm/asid.c
===================================================================
--- arch/mips32/src/mm/asid.c	(revision 8e3f47b39ca2e552e1a80721744728dc6811ce38)
+++ arch/mips32/src/mm/asid.c	(revision 1084a7848bafa4813443a91f16a7fc9514ecd5d9)
@@ -27,30 +27,65 @@
  */
 
+#include <arch/mm/asid.h>
+#include <synch/spinlock.h>
 #include <arch.h>
-#include <memstr.h>
+#include <debug.h>
 
-/**< Array of threads that have currently some ASID assigned,
-     NULL means no thread have ASID with number of that index assigned */
-struct thread * asids[256];
-int last_asid; /**< The number of last assigned ASID */
-int asid_bitmap[32]; /**< Bitmap of ASIDs currently in TLB */
+#define ASIDS	256
 
+static spinlock_t asid_usage_lock;
+static count_t asid_usage[ASIDS];	/**< Usage tracking array for ASIDs */
 
-/** Cleanup asid_bitmap
+/** Get ASID
  *
+ * Get the least used ASID.
+ *
+ * @return ASID
  */
-void asid_bitmap_reset(void)
+asid_t asid_get(void)
 {
-	memsetb(asid_bitmap, sizeof(asid_bitmap), 0);
+	pri_t pri;
+	int i, j;
+	count_t min;
+	
+	min = (unsigned) -1;
+	
+	pri = cpu_priority_high();
+	spinlock_lock(&asid_usage_lock);
+	
+	for (i=0, j = 0; (i<ASIDS); i++) {
+		if (asid_usage[i] < min) {
+			j = i;
+			min = asid_usage[i];
+			if (!min)
+				break;
+		}
+	}
+
+	asid_usage[i]++;
+
+	spinlock_unlock(&asid_usage_lock);
+	cpu_priority_restore(pri);
+
+	return i;
 }
 
+/** Release ASID
+ *
+ * Release ASID by decrementing its usage count.
+ *
+ * @param asid ASID.
+ */
+void asid_put(asid_t asid)
+{
+	pri_t pri;
 
-/** Initialize manipulating with ASIDs
- *
- */
-void init_asids(void)
-{
-	memsetb(asids, sizeof(asids), 0);
-	asid_bitmap_reset();
-	last_asid = 0;
+	pri = cpu_priority_high();
+	spinlock_lock(&asid_usage_lock);
+
+	ASSERT(asid_usage[asid] > 0);
+	asid_usage[asid]--;
+
+	spinlock_unlock(&asid_usage_lock);
+	cpu_priority_restore(pri);
 }
Index: arch/mips32/src/mm/tlb.c
===================================================================
--- arch/mips32/src/mm/tlb.c	(revision 8e3f47b39ca2e552e1a80721744728dc6811ce38)
+++ arch/mips32/src/mm/tlb.c	(revision 1084a7848bafa4813443a91f16a7fc9514ecd5d9)
@@ -30,9 +30,22 @@
 #include <arch/mm/asid.h>
 #include <mm/tlb.h>
+#include <mm/page.h>
+#include <mm/vm.h>
 #include <arch/cp0.h>
 #include <panic.h>
 #include <arch.h>
 #include <symtab.h>
+#include <synch/spinlock.h>
+#include <print.h>
 
+static void tlb_refill_fail(struct exception_regdump *pstate);
+static void tlb_invalid_fail(struct exception_regdump *pstate);
+static void tlb_modified_fail(struct exception_regdump *pstate);
+
+/** Initialize TLB
+ *
+ * Initialize TLB.
+ * Invalidate all entries and mark wired entries.
+ */
 void tlb_init_arch(void)
 {
@@ -48,5 +61,5 @@
 	 */
 	for (i = 0; i < TLB_SIZE; i++) {
-		cp0_index_write(0);
+		cp0_index_write(i);
 		tlbwi();
 	}
@@ -54,10 +67,79 @@
 	/*
 	 * The kernel is going to make use of some wired
-	 * entries (e.g. mapping kernel stacks).
+	 * entries (e.g. mapping kernel stacks in kseg3).
 	 */
 	cp0_wired_write(TLB_WIRED);
 }
 
+/** Process TLB Refill Exception
+ *
+ * Process TLB Refill Exception.
+ *
+ * @param pstate Interrupted register context.
+ */
 void tlb_refill(struct exception_regdump *pstate)
+{
+	struct entry_hi hi;
+	__address badvaddr;
+	pte_t *pte;
+	
+	*((__u32 *) &hi) = cp0_entry_hi_read();
+	badvaddr = cp0_badvaddr_read();
+	
+	spinlock_lock(&VM->lock);
+
+	/*
+	 * Refill cannot succeed if the ASIDs don't match.
+	 */
+	if (hi.asid != VM->asid)
+		goto fail;
+
+	/*
+	 * Refill cannot succeed if badvaddr is not
+	 * associated with any mapping.
+	 */
+	pte = find_mapping(badvaddr, 0);
+	if (!pte)
+		goto fail;
+		
+	/*
+	 * Refill cannot succeed if the mapping is marked as invalid.
+	 */
+	if (!pte->v)
+		goto fail;
+
+	/*
+	 * New entry is to be inserted into TLB
+	 */
+	cp0_pagemask_write(TLB_PAGE_MASK_16K);
+	if ((badvaddr/PAGE_SIZE) % 2 == 0) {
+		cp0_entry_lo0_write(*((__u32 *) pte));
+		cp0_entry_lo1_write(0);
+	}
+	else {
+		cp0_entry_lo0_write(0);
+		cp0_entry_lo1_write(*((__u32 *) pte));
+	}
+	tlbwr();
+
+	spinlock_unlock(&VM->lock);
+	return;
+	
+fail:
+	spinlock_unlock(&VM->lock);
+	tlb_refill_fail(pstate);
+}
+
+void tlb_invalid(struct exception_regdump *pstate)
+{
+	tlb_invalid_fail(pstate);
+}
+
+void tlb_modified(struct exception_regdump *pstate)
+{
+	tlb_modified_fail(pstate);
+}
+
+void tlb_refill_fail(struct exception_regdump *pstate)
 {
 	char *symbol = "";
@@ -70,9 +152,9 @@
 	if (s)
 		sym2 = s;
-	panic("%X: TLB Refill Exception at %X(%s<-%s)\n", cp0_badvaddr_read(),
-	      pstate->epc, symbol, sym2);
+	panic("%X: TLB Refill Exception at %X(%s<-%s)\n", cp0_badvaddr_read(), pstate->epc, symbol, sym2);
 }
 
-void tlb_invalid(struct exception_regdump *pstate)
+
+void tlb_invalid_fail(struct exception_regdump *pstate)
 {
 	char *symbol = "";
@@ -85,5 +167,5 @@
 }
 
-void tlb_modified(struct exception_regdump *pstate)
+void tlb_modified_fail(struct exception_regdump *pstate)
 {
 	char *symbol = "";
@@ -103,6 +185,4 @@
 	pri = cpu_priority_high();
 	
-//	asid_bitmap_reset();
-	
 	// TODO
 	
Index: arch/mips32/src/mm/vm.c
===================================================================
--- arch/mips32/src/mm/vm.c	(revision 1084a7848bafa4813443a91f16a7fc9514ecd5d9)
+++ arch/mips32/src/mm/vm.c	(revision 1084a7848bafa4813443a91f16a7fc9514ecd5d9)
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2005 Jakub Jermar
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <arch/mm/vm.h>
+#include <arch/mm/tlb.h>
+#include <mm/vm.h>
+#include <arch/cp0.h>
+#include <arch.h>
+#include <print.h>
+
+/** Install ASID of the current VM
+ *
+ * Install ASID of the current VM.
+ *
+ * @param vm VM structure.
+ */
+void vm_install_arch(vm_t *vm)
+{
+	struct entry_hi hi;
+	pri_t pri;
+	
+	*((__u32 *) &hi) = cp0_entry_hi_read();
+
+	pri = cpu_priority_high();
+	spinlock_lock(&vm->lock);
+	hi.asid = vm->asid;
+	cp0_entry_hi_write(*((__u32 *) &hi));	
+	spinlock_lock(&vm->unlock);
+	cpu_priority_restore(pri);
+}
Index: arch/ppc32/include/mm/asid.h
===================================================================
--- arch/ppc32/include/mm/asid.h	(revision 1084a7848bafa4813443a91f16a7fc9514ecd5d9)
+++ arch/ppc32/include/mm/asid.h	(revision 1084a7848bafa4813443a91f16a7fc9514ecd5d9)
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2005 Jakub Jermar
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __ppc32_ASID_H__
+#define __ppc32_ASID_H__
+
+typedef int asid_t;
+
+#define asid_get()	0
+
+#endif
Index: arch/ppc32/include/mm/page.h
===================================================================
--- arch/ppc32/include/mm/page.h	(revision 8e3f47b39ca2e552e1a80721744728dc6811ce38)
+++ arch/ppc32/include/mm/page.h	(revision 1084a7848bafa4813443a91f16a7fc9514ecd5d9)
@@ -69,5 +69,3 @@
 extern void page_arch_init(void);
 
-typedef __u32 pte_t;
-
 #endif
Index: arch/ppc32/include/mm/vm.h
===================================================================
--- arch/ppc32/include/mm/vm.h	(revision 8e3f47b39ca2e552e1a80721744728dc6811ce38)
+++ arch/ppc32/include/mm/vm.h	(revision 1084a7848bafa4813443a91f16a7fc9514ecd5d9)
@@ -41,3 +41,5 @@
 #define UDATA_ADDRESS_ARCH	0x21000000
 
+#define vm_install_arch(vm)
+
 #endif
Index: arch/ppc32/include/types.h
===================================================================
--- arch/ppc32/include/types.h	(revision 8e3f47b39ca2e552e1a80721744728dc6811ce38)
+++ arch/ppc32/include/types.h	(revision 1084a7848bafa4813443a91f16a7fc9514ecd5d9)
@@ -45,3 +45,5 @@
 typedef __u32 __native;
 
+typedef __u32 pte_t;
+
 #endif
Index: include/arch.h
===================================================================
--- include/arch.h	(revision 8e3f47b39ca2e552e1a80721744728dc6811ce38)
+++ include/arch.h	(revision 1084a7848bafa4813443a91f16a7fc9514ecd5d9)
@@ -37,10 +37,8 @@
 #include <arch/asm.h> 
 
-#include <proc/thread.h>
-#include <proc/task.h>
-
 #define CPU			THE->cpu
 #define THREAD			THE->thread
 #define TASK			THE->task
+#define VM			THE->vm
 #define PREEMPTION_DISABLED	THE->preemption_disabled
 
@@ -59,4 +57,5 @@
 	task_t *task;			/* current task */
 	cpu_t *cpu;			/* executing cpu */
+	vm_t *vm;			/* current vm */
 };
 
Index: include/mm/page.h
===================================================================
--- include/mm/page.h	(revision 8e3f47b39ca2e552e1a80721744728dc6811ce38)
+++ include/mm/page.h	(revision 1084a7848bafa4813443a91f16a7fc9514ecd5d9)
@@ -109,4 +109,5 @@
 extern void page_init(void);
 extern void map_page_to_frame(__address page, __address frame, int flags, __address root);
+extern pte_t *find_mapping(__address page, __address root);
 extern void map_structure(__address s, size_t size);
 
Index: include/mm/vm.h
===================================================================
--- include/mm/vm.h	(revision 8e3f47b39ca2e552e1a80721744728dc6811ce38)
+++ include/mm/vm.h	(revision 1084a7848bafa4813443a91f16a7fc9514ecd5d9)
@@ -32,4 +32,5 @@
 #include <arch/mm/page.h>
 #include <arch/mm/vm.h>
+#include <arch/mm/asid.h>
 #include <arch/types.h>
 #include <typedefs.h>
@@ -75,4 +76,5 @@
 	link_t vm_area_head;
 	pte_t *ptl0;
+	asid_t asid;
 };
 
Index: src/main/kinit.c
===================================================================
--- src/main/kinit.c	(revision 8e3f47b39ca2e552e1a80721744728dc6811ce38)
+++ src/main/kinit.c	(revision 1084a7848bafa4813443a91f16a7fc9514ecd5d9)
@@ -54,4 +54,6 @@
 #include <test.h>
 #endif /* __TEST__ */
+
+#include <mm/frame.h>
 
 void kinit(void *arg)
Index: src/mm/page.c
===================================================================
--- src/mm/page.c	(revision 8e3f47b39ca2e552e1a80721744728dc6811ce38)
+++ src/mm/page.c	(revision 1084a7848bafa4813443a91f16a7fc9514ecd5d9)
@@ -34,5 +34,4 @@
 #include <arch/asm.h>
 #include <memstr.h>
-
 
 void page_init(void)
@@ -110,2 +109,35 @@
 	SET_FRAME_FLAGS(ptl3, PTL3_INDEX(page), flags);
 }
+
+/** Find mapping for virtual page
+ *
+ * Find mapping for virtual page.
+ *
+ * @param page Virtual page.
+ * @param root PTL0 address if non-zero.
+ *
+ * @return NULL if there is no such mapping; entry from PTL3 describing the mapping otherwise.
+ */
+pte_t *find_mapping(__address page, __address root)
+{
+	pte_t *ptl0, *ptl1, *ptl2, *ptl3;
+
+	ptl0 = (pte_t *) PA2KA(root ? root : (__address) GET_PTL0_ADDRESS());
+
+	if (GET_PTL1_FLAGS(ptl0, PTL0_INDEX(page)) & PAGE_NOT_PRESENT)
+		return NULL;
+
+	ptl1 = (pte_t *) PA2KA(GET_PTL1_ADDRESS(ptl0, PTL0_INDEX(page)));
+
+	if (GET_PTL2_FLAGS(ptl1, PTL1_INDEX(page)) & PAGE_NOT_PRESENT)
+		return NULL;
+
+	ptl2 = (pte_t *) PA2KA(GET_PTL2_ADDRESS(ptl1, PTL1_INDEX(page)));
+
+	if (GET_PTL3_FLAGS(ptl2, PTL2_INDEX(page)) & PAGE_NOT_PRESENT)
+		return NULL;
+
+	ptl3 = (pte_t *) PA2KA(GET_PTL3_ADDRESS(ptl2, PTL2_INDEX(page)));
+
+	return &ptl3[PTL3_INDEX(page)];
+}
Index: src/mm/vm.c
===================================================================
--- src/mm/vm.c	(revision 8e3f47b39ca2e552e1a80721744728dc6811ce38)
+++ src/mm/vm.c	(revision 1084a7848bafa4813443a91f16a7fc9514ecd5d9)
@@ -33,4 +33,6 @@
 #include <mm/heap.h>
 #include <arch/mm/page.h>
+#include <arch/mm/asid.h>
+#include <arch/mm/vm.h>
 #include <arch/types.h>
 #include <typedefs.h>
@@ -56,4 +58,6 @@
 		spinlock_initialize(&m->lock);
 		list_initialize(&m->vm_area_head);
+
+		m->asid = asid_get();
 
 		/*
@@ -200,3 +204,7 @@
 
 	cpu_priority_restore(pri);
-}
+
+	vm_install_arch(m);
+	
+	VM = m;
+}
Index: src/proc/the.c
===================================================================
--- src/proc/the.c	(revision 8e3f47b39ca2e552e1a80721744728dc6811ce38)
+++ src/proc/the.c	(revision 1084a7848bafa4813443a91f16a7fc9514ecd5d9)
@@ -44,4 +44,5 @@
 	the->thread = NULL;
 	the->task = NULL;
+	the->vm = NULL;
 }
 
Index: src/time/clock.c
===================================================================
--- src/time/clock.c	(revision 8e3f47b39ca2e552e1a80721744728dc6811ce38)
+++ src/time/clock.c	(revision 1084a7848bafa4813443a91f16a7fc9514ecd5d9)
@@ -40,4 +40,5 @@
 #include <list.h>
 #include <arch/atomic.h>
+#include <proc/thread.h>
 
 /** Clock routine
