Index: arch/mips32/src/mm/asid.c
===================================================================
--- arch/mips32/src/mm/asid.c	(revision bca1b4709513d451ac751917139b9d420745f27f)
+++ arch/mips32/src/mm/asid.c	(revision cc205f1f38b5517610765fe3a34396d52e75eca2)
@@ -1,4 +1,5 @@
 /*
  * Copyright (C) 2005 Martin Decky
+ * Copyright (C) 2005 Jakub Jermar
  * All rights reserved.
  *
@@ -31,6 +32,5 @@
 #include <arch.h>
 #include <debug.h>
-
-#define ASIDS	256
+#include <typedefs.h>
 
 static spinlock_t asid_usage_lock;
@@ -54,5 +54,5 @@
 	spinlock_lock(&asid_usage_lock);
 	
-	for (i=0, j = 0; (i<ASIDS); i++) {
+	for (i = ASID_START, j = ASID_START; i < ASIDS; i++) {
 		if (asid_usage[i] < min) {
 			j = i;
@@ -63,5 +63,5 @@
 	}
 
-	asid_usage[i]++;
+	asid_usage[j]++;
 
 	spinlock_unlock(&asid_usage_lock);
@@ -84,4 +84,6 @@
 	spinlock_lock(&asid_usage_lock);
 
+	ASSERT(asid != ASID_INVALID);
+	
 	ASSERT(asid_usage[asid] > 0);
 	asid_usage[asid]--;
@@ -90,2 +92,29 @@
 	cpu_priority_restore(pri);
 }
+
+/** Find out whether ASID is used by more address spaces
+ *
+ * Find out whether ASID is used by more address spaces.
+ *
+ * @param asid ASID in question.
+ *
+ * @return True if 'asid' is used by more address spaces, false otherwise.
+ */
+bool asid_has_conflicts(asid_t asid)
+{
+	bool has_conflicts = false;
+	pri_t pri;
+
+	ASSERT(asid != ASID_INVALID);
+
+	pri = cpu_priority_high();
+	spinlock_lock(&asid_usage_lock);
+
+	if (asid_usage[asid] > 1)
+		has_conflicts = true;
+
+	spinlock_unlock(&asid_usage_lock);
+	cpu_priority_restore(pri);
+
+	return has_conflicts;
+}
Index: arch/mips32/src/mm/tlb.c
===================================================================
--- arch/mips32/src/mm/tlb.c	(revision bca1b4709513d451ac751917139b9d420745f27f)
+++ arch/mips32/src/mm/tlb.c	(revision cc205f1f38b5517610765fe3a34396d52e75eca2)
@@ -38,4 +38,5 @@
 #include <synch/spinlock.h>
 #include <print.h>
+#include <debug.h>
 
 static void tlb_refill_fail(struct exception_regdump *pstate);
@@ -44,5 +45,5 @@
 
 static pte_t *find_mapping_and_check(__address badvaddr);
-static void prepare_entry_lo(struct entry_lo *lo, bool g, bool v, bool d, int c, __address pfn);
+static void prepare_entry_lo(entry_lo_t *lo, bool g, bool v, bool d, int c, __address pfn);
 
 /** Initialize TLB
@@ -83,5 +84,5 @@
 void tlb_refill(struct exception_regdump *pstate)
 {
-	struct entry_lo lo;
+	entry_lo_t lo;
 	__address badvaddr;
 	pte_t *pte;
@@ -105,10 +106,10 @@
 	 */
 	if ((badvaddr/PAGE_SIZE) % 2 == 0) {
-		cp0_entry_lo0_write(*((__u32 *) &lo));
+		cp0_entry_lo0_write(lo.value);
 		cp0_entry_lo1_write(0);
 	}
 	else {
 		cp0_entry_lo0_write(0);
-		cp0_entry_lo1_write(*((__u32 *) &lo));
+		cp0_entry_lo1_write(lo.value);
 	}
 	tlbwr();
@@ -130,7 +131,7 @@
 void tlb_invalid(struct exception_regdump *pstate)
 {
-	struct index index;
+	tlb_index_t index;
 	__address badvaddr;
-	struct entry_lo lo;
+	entry_lo_t lo;
 	pte_t *pte;
 
@@ -141,5 +142,5 @@
 	 */
 	tlbp();
-	*((__u32 *) &index) = cp0_index_read();
+	index.value = cp0_index_read();
 	
 	spinlock_lock(&VM->lock);	
@@ -148,6 +149,8 @@
 	 * Fail if the entry is not in TLB.
 	 */
-	if (index.p)
-		goto fail;
+	if (index.p) {
+		printf("TLB entry not found.\n");
+		goto fail;
+	}
 
 	pte = find_mapping_and_check(badvaddr);
@@ -171,7 +174,7 @@
 	 */
 	if ((badvaddr/PAGE_SIZE) % 2 == 0)
-		cp0_entry_lo0_write(*((__u32 *) &lo));
+		cp0_entry_lo0_write(lo.value);
 	else
-		cp0_entry_lo1_write(*((__u32 *) &lo));
+		cp0_entry_lo1_write(lo.value);
 	tlbwi();
 
@@ -190,10 +193,9 @@
  * @param pstate Interrupted register context.
  */
-
 void tlb_modified(struct exception_regdump *pstate)
 {
-	struct index index;
+	tlb_index_t index;
 	__address badvaddr;
-	struct entry_lo lo;
+	entry_lo_t lo;
 	pte_t *pte;
 
@@ -204,5 +206,5 @@
 	 */
 	tlbp();
-	*((__u32 *) &index) = cp0_index_read();
+	index.value = cp0_index_read();
 	
 	spinlock_lock(&VM->lock);	
@@ -211,6 +213,8 @@
 	 * Fail if the entry is not in TLB.
 	 */
-	if (index.p)
-		goto fail;
+	if (index.p) {
+		printf("TLB entry not found.\n");
+		goto fail;
+	}
 
 	pte = find_mapping_and_check(badvaddr);
@@ -241,7 +245,7 @@
 	 */
 	if ((badvaddr/PAGE_SIZE) % 2 == 0)
-		cp0_entry_lo0_write(*((__u32 *) &lo));
+		cp0_entry_lo0_write(lo.value);
 	else
-		cp0_entry_lo1_write(*((__u32 *) &lo));
+		cp0_entry_lo1_write(lo.value);
 	tlbwi();
 
@@ -289,12 +293,33 @@
 }
 
-
-void tlb_invalidate(int asid)
-{
+/** Invalidate TLB entries with specified ASID
+ *
+ * Invalidate TLB entries with specified ASID.
+ *
+ * @param asid ASID.
+ */
+void tlb_invalidate(asid_t asid)
+{
+	entry_hi_t hi;
 	pri_t pri;
-	
+	int i;	
+	
+	ASSERT(asid != ASID_INVALID);
+
 	pri = cpu_priority_high();
 	
-	// TODO
+	for (i = 0; i < TLB_SIZE; i++) {
+		cp0_index_write(i);
+		tlbr();
+		
+		hi.value = cp0_entry_hi_read();
+		if (hi.asid == asid) {
+			cp0_pagemask_write(TLB_PAGE_MASK_16K);
+			cp0_entry_hi_write(0);
+			cp0_entry_lo0_write(0);
+			cp0_entry_lo1_write(0);
+			tlbwi();
+		}
+	}
 	
 	cpu_priority_restore(pri);
@@ -312,14 +337,16 @@
 pte_t *find_mapping_and_check(__address badvaddr)
 {
-	struct entry_hi hi;
+	entry_hi_t hi;
 	pte_t *pte;
 
-	*((__u32 *) &hi) = cp0_entry_hi_read();
+	hi.value = cp0_entry_hi_read();
 
 	/*
 	 * Handler cannot succeed if the ASIDs don't match.
 	 */
-	if (hi.asid != VM->asid)
+	if (hi.asid != VM->asid) {
+		printf("EntryHi.asid=%d, VM->asid=%d\n", hi.asid, VM->asid);
 		return NULL;
+	}
 	
 	/*
@@ -327,17 +354,21 @@
 	 */
 	pte = find_mapping(badvaddr, 0);
-	if (!pte)
+	if (!pte) {
+		printf("No such mapping.\n");
 		return NULL;
+	}
 
 	/*
 	 * Handler cannot succeed if the mapping is marked as invalid.
 	 */
-	if (!pte->v)
+	if (!pte->v) {
+		printf("Invalid mapping.\n");
 		return NULL;
+	}
 
 	return pte;
 }
 
-void prepare_entry_lo(struct entry_lo *lo, bool g, bool v, bool d, int c, __address pfn)
+void prepare_entry_lo(entry_lo_t *lo, bool g, bool v, bool d, int c, __address pfn)
 {
 	lo->g = g;
Index: arch/mips32/src/mm/vm.c
===================================================================
--- arch/mips32/src/mm/vm.c	(revision bca1b4709513d451ac751917139b9d420745f27f)
+++ arch/mips32/src/mm/vm.c	(revision cc205f1f38b5517610765fe3a34396d52e75eca2)
@@ -32,5 +32,4 @@
 #include <arch/cp0.h>
 #include <arch.h>
-#include <print.h>
 
 /** Install ASID of the current VM
@@ -42,8 +41,8 @@
 void vm_install_arch(vm_t *vm)
 {
-	struct entry_hi hi;
+	entry_hi_t hi;
 	pri_t pri;
 	
-	*((__u32 *) &hi) = cp0_entry_hi_read();
+	hi.value = cp0_entry_hi_read();
 
 	pri = cpu_priority_high();
