Index: kernel/arch/sparc64/src/mm/tlb.c
===================================================================
--- kernel/arch/sparc64/src/mm/tlb.c	(revision f47fd19f9885f194c0b816b7814357789c9565e2)
+++ kernel/arch/sparc64/src/mm/tlb.c	(revision beb3926abd13d8632e1c3093c0d2bef995372dee)
@@ -51,6 +51,8 @@
 #include <symtab.h>
 
-static void dtlb_pte_copy(pte_t *t);
+static void dtlb_pte_copy(pte_t *t, bool ro);
+static void itlb_pte_copy(pte_t *t);
 static void do_fast_data_access_mmu_miss_fault(istate_t *istate, const char *str);
+static void do_fast_instruction_access_mmu_miss_fault(istate_t *istate, const char *str);
 
 char *context_encoding[] = {
@@ -106,6 +108,67 @@
 }
 
-void dtlb_pte_copy(pte_t *t)
-{
+/** Copy PTE to TLB.
+ *
+ * @param t Page Table Entry to be copied.
+ * @param ro If true, the entry will be created read-only, regardless of its w field.
+ */
+void dtlb_pte_copy(pte_t *t, bool ro)
+{
+	tlb_tag_access_reg_t tag;
+	tlb_data_t data;
+	page_address_t pg;
+	frame_address_t fr;
+
+	pg.address = t->page;
+	fr.address = t->frame;
+
+	tag.value = 0;
+	tag.context = t->as->asid;
+	tag.vpn = pg.vpn;
+	
+	dtlb_tag_access_write(tag.value);
+	
+	data.value = 0;
+	data.v = true;
+	data.size = PAGESIZE_8K;
+	data.pfn = fr.pfn;
+	data.l = false;
+	data.cp = t->c;
+	data.cv = t->c;
+	data.p = t->p;
+	data.w = ro ? false : t->w;
+	data.g = t->g;
+	
+	dtlb_data_in_write(data.value);
+}
+
+void itlb_pte_copy(pte_t *t)
+{
+	tlb_tag_access_reg_t tag;
+	tlb_data_t data;
+	page_address_t pg;
+	frame_address_t fr;
+
+	pg.address = t->page;
+	fr.address = t->frame;
+
+	tag.value = 0;
+	tag.context = t->as->asid;
+	tag.vpn = pg.vpn;
+	
+	itlb_tag_access_write(tag.value);
+	
+	data.value = 0;
+	data.v = true;
+	data.size = PAGESIZE_8K;
+	data.pfn = fr.pfn;
+	data.l = false;
+	data.cp = t->c;
+	data.cv = t->c;
+	data.p = t->p;
+	data.w = false;
+	data.g = t->g;
+	
+	itlb_data_in_write(data.value);
 }
 
@@ -113,5 +176,26 @@
 void fast_instruction_access_mmu_miss(int n, istate_t *istate)
 {
-	panic("%s\n", __FUNCTION__);
+	uintptr_t va = ALIGN_DOWN(istate->tpc, PAGE_SIZE);
+	pte_t *t;
+
+	page_table_lock(AS, true);
+	t = page_mapping_find(AS, va);
+	if (t && PTE_EXECUTABLE(t)) {
+		/*
+		 * The mapping was found in the software page hash table.
+		 * Insert it into ITLB.
+		 */
+		t->a = true;
+		itlb_pte_copy(t);
+		page_table_unlock(AS, true);
+	} else {
+		/*
+		 * Forward the page fault to the address space page fault handler.
+		 */		
+		page_table_unlock(AS, true);
+		if (as_page_fault(va, PF_ACCESS_EXEC, istate) == AS_PF_FAULT) {
+			do_fast_instruction_access_mmu_miss_fault(istate, __FUNCTION__);
+		}
+	}
 }
 
@@ -145,5 +229,6 @@
 		 * Insert it into DTLB.
 		 */
-		dtlb_pte_copy(t);
+		t->a = true;
+		dtlb_pte_copy(t, true);
 		page_table_unlock(AS, true);
 	} else {
@@ -191,4 +276,12 @@
 }
 
+void do_fast_instruction_access_mmu_miss_fault(istate_t *istate, const char *str)
+{
+	char *tpc_str = get_symtab_entry(istate->tpc);
+
+	printf("TPC=%p, (%s)\n", istate->tpc, tpc_str);
+	panic("%s\n", str);
+}
+
 void do_fast_data_access_mmu_miss_fault(istate_t *istate, const char *str)
 {
