Index: arch/sparc64/include/mm/asid.h
===================================================================
--- arch/sparc64/include/mm/asid.h	(revision 91ef0d955c68876ca16fffef6f8e7416dfdefff5)
+++ arch/sparc64/include/mm/asid.h	(revision dbb688616f86482bdf0241f217eaf220fbbe49d7)
@@ -30,5 +30,10 @@
 #define __sparc64_ASID_H__
 
-typedef int asid_t;
+#include <arch/types.h>
+
+/*
+ * On SPARC, Context means the same thing as ASID trough out the kernel.
+ */
+typedef __u16 asid_t;
 
 #define asid_get()	0
Index: arch/sparc64/include/mm/page.h
===================================================================
--- arch/sparc64/include/mm/page.h	(revision 91ef0d955c68876ca16fffef6f8e7416dfdefff5)
+++ arch/sparc64/include/mm/page.h	(revision dbb688616f86482bdf0241f217eaf220fbbe49d7)
@@ -67,4 +67,14 @@
 #define SET_FRAME_FLAGS_ARCH(ptl3, i, x)
 
+union page_address {
+	__address address;
+	struct {
+		__u64 vpn : 51;		/**< Virtual Page Number. */
+		unsigned offset : 13;	/**< Offset. */
+	} __attribute__ ((packed));
+};
+
+typedef union page_address page_address_t;
+
 extern void page_arch_init(void);
 
Index: arch/sparc64/include/mm/tlb.h
===================================================================
--- arch/sparc64/include/mm/tlb.h	(revision 91ef0d955c68876ca16fffef6f8e7416dfdefff5)
+++ arch/sparc64/include/mm/tlb.h	(revision dbb688616f86482bdf0241f217eaf220fbbe49d7)
@@ -31,4 +31,5 @@
 
 #include <arch/mm/tte.h>
+#include <arch/mm/page.h>
 #include <arch/asm.h>
 #include <arch/barrier.h>
@@ -94,5 +95,5 @@
 	__u64 value;
 	struct {
-		__u64 va : 51;		/**< Virtual Address. */
+		__u64 vpn : 51;		/**< Virtual Address bits 63:13. */
 		unsigned context : 13;	/**< Context identifier. */
 	} __attribute__ ((packed));
@@ -101,4 +102,26 @@
 typedef union tlb_tag_read_reg tlb_tag_access_reg_t;
 
+/** TLB Demap Operation types. */
+#define TLB_DEMAP_PAGE		0
+#define TLB_DEMAP_CONTEXT	1
+
+/** TLB Demap Operation Context register encodings. */
+#define TLB_DEMAP_PRIMARY	0
+#define TLB_DEMAP_SECONDARY	1
+#define TLB_DEMAP_NUCLEUS	2
+
+/** TLB Demap Operation Address. */
+union tlb_demap_addr {
+	__u64 value;
+	struct {
+		__u64 vpn: 51;		/**< Virtual Address bits 63:13. */
+		unsigned : 6;		/**< Ignored. */
+		unsigned type : 1;	/**< The type of demap operation. */
+		unsigned context : 2;	/**< Context register selection. */
+		unsigned : 4;		/**< Zero. */
+	} __attribute__ ((packed));
+};
+typedef union tlb_demap_addr tlb_demap_addr_t;
+
 /** Read IMMU TLB Data Access Register.
  *
@@ -116,4 +139,19 @@
 }
 
+/** Write IMMU TLB Data Access Register.
+ *
+ * @param entry TLB Entry index.
+ * @param value Value to be written.
+ */
+static inline __u64 itlb_data_access_write(index_t entry, __u64 value)
+{
+	tlb_data_access_addr_t reg;
+	
+	reg.value = 0;
+	reg.tlb_entry = entry;
+	asi_u64_write(ASI_ITLB_DATA_ACCESS_REG, reg.value, value);
+	flush();
+}
+
 /** Read DMMU TLB Data Access Register.
  *
@@ -131,4 +169,19 @@
 }
 
+/** Write DMMU TLB Data Access Register.
+ *
+ * @param entry TLB Entry index.
+ * @param value Value to be written.
+ */
+static inline __u64 dtlb_data_access_write(index_t entry, __u64 value)
+{
+	tlb_data_access_addr_t reg;
+	
+	reg.value = 0;
+	reg.tlb_entry = entry;
+	asi_u64_write(ASI_DTLB_DATA_ACCESS_REG, reg.value, value);
+	flush();
+}
+
 /** Read IMMU TLB Tag Read Register.
  *
@@ -201,3 +254,47 @@
 }
 
+/** Perform IMMU TLB Demap Operation.
+ *
+ * @param type Selects between context and page demap.
+ * @param context_encoding Specifies which Context register has Context ID for demap.
+ * @param page Address which is on the page to be demapped.
+ */
+static inline void itlb_demap(int type, int context_encoding, __address page)
+{
+	tlb_demap_addr_t da;
+	page_address_t pg;
+	
+	da.value = 0;
+	pg.address = page;
+	
+	da.type = type;
+	da.context = context_encoding;
+	da.vpn = pg.vpn;
+	
+	asi_u64_write(ASI_IMMU_DEMAP, da.value, 0);
+	flush();
+}
+
+/** Perform DMMU TLB Demap Operation.
+ *
+ * @param type Selects between context and page demap.
+ * @param context_encoding Specifies which Context register has Context ID for demap.
+ * @param page Address which is on the page to be demapped.
+ */
+static inline void dtlb_demap(int type, int context_encoding, __address page)
+{
+	tlb_demap_addr_t da;
+	page_address_t pg;
+	
+	da.value = 0;
+	pg.address = page;
+	
+	da.type = type;
+	da.context = context_encoding;
+	da.vpn = pg.vpn;
+	
+	asi_u64_write(ASI_DMMU_DEMAP, da.value, 0);
+	flush();
+}
+
 #endif
Index: arch/sparc64/include/mm/tte.h
===================================================================
--- arch/sparc64/include/mm/tte.h	(revision 91ef0d955c68876ca16fffef6f8e7416dfdefff5)
+++ arch/sparc64/include/mm/tte.h	(revision dbb688616f86482bdf0241f217eaf220fbbe49d7)
@@ -56,5 +56,5 @@
 		unsigned soft2 : 9;	/**< Software defined field. */
 		unsigned diag : 9;	/**< Diagnostic data. */
-		unsigned pa : 28;	/**< Physical page number. */
+		unsigned pfn : 28;	/**< Physical Address bits, bits 40:13. */
 		unsigned soft : 6;	/**< Software defined field. */
 		unsigned l : 1;		/**< Lock. */
Index: arch/sparc64/src/mm/tlb.c
===================================================================
--- arch/sparc64/src/mm/tlb.c	(revision 91ef0d955c68876ca16fffef6f8e7416dfdefff5)
+++ arch/sparc64/src/mm/tlb.c	(revision dbb688616f86482bdf0241f217eaf220fbbe49d7)
@@ -30,4 +30,6 @@
 #include <mm/tlb.h>
 #include <print.h>
+#include <arch/types.h>
+#include <typedefs.h>
 
 void tlb_arch_init(void)
@@ -47,6 +49,6 @@
 		t.value = itlb_tag_read_read(i);
 		
-		printf("%d: va=%Q, context=%d, v=%d, size=%d, nfo=%d, ie=%d, soft2=%X, diag=%X, pa=%X, soft=%X, l=%d, cp=%d, cv=%d, e=%d, p=%d, w=%d, g=%d\n",
-			i, t.va, t.context, d.v, d.size, d.nfo, d.ie, d.soft2, d.diag, d.pa, d.soft, d.l, d.cp, d.cv, d.e, d.p, d.w, d.g);
+		printf("%d: vpn=%Q, context=%d, v=%d, size=%d, nfo=%d, ie=%d, soft2=%X, diag=%X, pfn=%X, soft=%X, l=%d, cp=%d, cv=%d, e=%d, p=%d, w=%d, g=%d\n",
+			i, t.vpn, t.context, d.v, d.size, d.nfo, d.ie, d.soft2, d.diag, d.pfn, d.soft, d.l, d.cp, d.cv, d.e, d.p, d.w, d.g);
 	}
 
@@ -56,7 +58,60 @@
 		t.value = dtlb_tag_read_read(i);
 		
-		printf("%d: va=%Q, context=%d, v=%d, size=%d, nfo=%d, ie=%d, soft2=%X, diag=%X, pa=%X, soft=%X, l=%d, cp=%d, cv=%d, e=%d, p=%d, w=%d, g=%d\n",
-			i, t.va, t.context, d.v, d.size, d.nfo, d.ie, d.soft2, d.diag, d.pa, d.soft, d.l, d.cp, d.cv, d.e, d.p, d.w, d.g);
+		printf("%d: vpn=%Q, context=%d, v=%d, size=%d, nfo=%d, ie=%d, soft2=%X, diag=%X, pfn=%X, soft=%X, l=%d, cp=%d, cv=%d, e=%d, p=%d, w=%d, g=%d\n",
+			i, t.vpn, t.context, d.v, d.size, d.nfo, d.ie, d.soft2, d.diag, d.pfn, d.soft, d.l, d.cp, d.cv, d.e, d.p, d.w, d.g);
 	}
 
 }
+
+/** Invalidate all unlocked ITLB and DTLB entries. */
+void tlb_invalidate_all(void)
+{
+	int i;
+	tlb_data_t d;
+	tlb_tag_read_reg_t t;
+
+	for (i = 0; i < ITLB_ENTRY_COUNT; i++) {
+		d.value = itlb_data_access_read(i);
+		if (!d.l) {
+			printf("invalidating ");
+			t.value = itlb_tag_read_read(i);
+			d.v = false;
+			itlb_tag_access_write(t.value);
+			itlb_data_access_write(i, d.value);
+		}
+	}
+	
+	for (i = 0; i < DTLB_ENTRY_COUNT; i++) {
+		d.value = dtlb_data_access_read(i);
+		if (!d.l) {
+			t.value = dtlb_tag_read_read(i);
+			d.v = false;
+			dtlb_tag_access_write(t.value);
+			dtlb_data_access_write(i, d.value);
+		}
+	}
+	
+}
+
+/** Invalidate all ITLB and DTLB entries that belong to specified ASID (Context).
+ *
+ * @param asid Address Space ID.
+ */
+void tlb_invalidate_asid(asid_t asid)
+{
+	/* TODO: write asid to some Context register and encode the register in second parameter below. */
+	itlb_demap(TLB_DEMAP_CONTEXT, TLB_DEMAP_NUCLEUS, 0);
+	dtlb_demap(TLB_DEMAP_CONTEXT, TLB_DEMAP_NUCLEUS, 0);
+}
+
+/** Invalidate all ITLB and DLTB entries for specified page in specified address space.
+ *
+ * @param asid Address Space ID.
+ * @param page Page which to sweep out from ITLB and DTLB.
+ */
+void tlb_invalidate_page(asid_t asid, __address page)
+{
+	/* TODO: write asid to some Context register and encode the register in second parameter below. */
+	itlb_demap(TLB_DEMAP_PAGE, TLB_DEMAP_NUCLEUS, page);
+	dtlb_demap(TLB_DEMAP_PAGE, TLB_DEMAP_NUCLEUS, page);
+}
