Index: boot/arch/sparc64/loader/main.c
===================================================================
--- boot/arch/sparc64/loader/main.c	(revision c049309818d0a3eca8aa6dfecad99aa1f06ee0d6)
+++ boot/arch/sparc64/loader/main.c	(revision b3e8c9027fcf0ca0f336b21b561e9afcb86c3c05)
@@ -61,8 +61,6 @@
 	bootinfo.screen.addr = ofw_translate(bootinfo.screen.addr);
 	
-	if (!ofw_keyboard(&bootinfo.keyboard)) {
-		printf("Error: unable to get keyboard properties, halting.\n");
-		halt();
-	}
+	if (!ofw_keyboard(&bootinfo.keyboard))
+		printf("Error: unable to get keyboard properties\n");
 	
 	printf("\nDevice statistics\n");
Index: kernel/arch/sparc64/include/barrier.h
===================================================================
--- kernel/arch/sparc64/include/barrier.h	(revision c049309818d0a3eca8aa6dfecad99aa1f06ee0d6)
+++ kernel/arch/sparc64/include/barrier.h	(revision b3e8c9027fcf0ca0f336b21b561e9afcb86c3c05)
@@ -55,9 +55,5 @@
 	 */
 	 
-	/*
-	 * %i7 should provide address that is always mapped in DTLB
-	 * as it is a pointer to kernel code.
-	 */
-        __asm__ volatile ("flush %i7\n");
+        __asm__ volatile ("flush %0\n" :: "r" (0x400000));
 }
 
Index: kernel/arch/sparc64/include/mm/mmu.h
===================================================================
--- kernel/arch/sparc64/include/mm/mmu.h	(revision c049309818d0a3eca8aa6dfecad99aa1f06ee0d6)
+++ kernel/arch/sparc64/include/mm/mmu.h	(revision b3e8c9027fcf0ca0f336b21b561e9afcb86c3c05)
@@ -27,5 +27,5 @@
  */
 
- /** @addtogroup sparc64mm	
+/** @addtogroup sparc64mm	
  * @{
  */
@@ -35,9 +35,4 @@
 #ifndef __sparc64_MMU_H__
 #define __sparc64_MMU_H__
-
-#include <arch/asm.h>
-#include <arch/barrier.h>
-#include <arch/types.h>
-#include <typedefs.h>
 
 /** LSU Control Register ASI. */
@@ -80,4 +75,10 @@
 #define VA_DMMU_PA_WATCHPOINT_REG	0x40	/**< DMMU PA data watchpoint register. */
 
+#ifndef __ASM__
+
+#include <arch/asm.h>
+#include <arch/barrier.h>
+#include <arch/types.h>
+#include <typedefs.h>
 
 /** LSU Control Register. */
@@ -103,35 +104,8 @@
 typedef union lsu_cr_reg lsu_cr_reg_t;
 
-
-#define immu_enable()	immu_set(true)
-#define immu_disable()	immu_set(false)
-#define dmmu_enable()	dmmu_set(true)
-#define dmmu_disable()	dmmu_set(false)
-
-/** Disable or Enable IMMU. */
-static inline void immu_set(bool enable)
-{
-	lsu_cr_reg_t cr;
-	
-	cr.value = asi_u64_read(ASI_LSU_CONTROL_REG, 0);
-	cr.im = enable;
-	asi_u64_write(ASI_LSU_CONTROL_REG, 0, cr.value);
-	membar();
-}
-
-/** Disable or Enable DMMU. */
-static inline void dmmu_set(bool enable)
-{
-	lsu_cr_reg_t cr;
-	
-	cr.value = asi_u64_read(ASI_LSU_CONTROL_REG, 0);
-	cr.dm = enable;
-	asi_u64_write(ASI_LSU_CONTROL_REG, 0, cr.value);
-	membar();
-}
+#endif /* !__ASM__ */
 
 #endif
 
- /** @}
+/** @}
  */
-
Index: kernel/arch/sparc64/include/mm/page.h
===================================================================
--- kernel/arch/sparc64/include/mm/page.h	(revision c049309818d0a3eca8aa6dfecad99aa1f06ee0d6)
+++ kernel/arch/sparc64/include/mm/page.h	(revision b3e8c9027fcf0ca0f336b21b561e9afcb86c3c05)
@@ -27,5 +27,5 @@
  */
 
- /** @addtogroup sparc64mm	
+/** @addtogroup sparc64mm	
  * @{
  */
@@ -66,5 +66,4 @@
 #endif
 
- /** @}
+/** @}
  */
-
Index: kernel/arch/sparc64/include/mm/tlb.h
===================================================================
--- kernel/arch/sparc64/include/mm/tlb.h	(revision c049309818d0a3eca8aa6dfecad99aa1f06ee0d6)
+++ kernel/arch/sparc64/include/mm/tlb.h	(revision b3e8c9027fcf0ca0f336b21b561e9afcb86c3c05)
@@ -27,5 +27,5 @@
  */
 
- /** @addtogroup sparc64mm	
+/** @addtogroup sparc64mm	
  * @{
  */
@@ -228,5 +228,5 @@
 	reg.tlb_entry = entry;
 	asi_u64_write(ASI_DTLB_DATA_ACCESS_REG, reg.value, value);
-	flush();
+	membar();
 }
 
@@ -287,5 +287,5 @@
 {
 	asi_u64_write(ASI_DMMU, VA_DMMU_TAG_ACCESS, v);
-	flush();
+	membar();
 }
 
@@ -317,5 +317,5 @@
 {
 	asi_u64_write(ASI_DTLB_DATA_IN_REG, 0, v);
-	flush();
+	membar();
 }
 
@@ -355,5 +355,5 @@
 {
 	asi_u64_write(ASI_DMMU, VA_DMMU_SFSR, v);
-	flush();
+	membar();
 }
 
@@ -408,5 +408,5 @@
 	
 	asi_u64_write(ASI_DMMU_DEMAP, da.value, 0);
-	flush();
+	membar();
 }
 
@@ -419,5 +419,4 @@
 #endif
 
- /** @}
- */
-
+/** @}
+ */
Index: kernel/arch/sparc64/include/mm/tte.h
===================================================================
--- kernel/arch/sparc64/include/mm/tte.h	(revision c049309818d0a3eca8aa6dfecad99aa1f06ee0d6)
+++ kernel/arch/sparc64/include/mm/tte.h	(revision b3e8c9027fcf0ca0f336b21b561e9afcb86c3c05)
@@ -27,5 +27,5 @@
  */
 
- /** @addtogroup sparc64mm	
+/** @addtogroup sparc64mm	
  * @{
  */
@@ -78,5 +78,4 @@
 #endif
 
- /** @}
+/** @}
  */
-
Index: kernel/arch/sparc64/src/console.c
===================================================================
--- kernel/arch/sparc64/src/console.c	(revision c049309818d0a3eca8aa6dfecad99aa1f06ee0d6)
+++ kernel/arch/sparc64/src/console.c	(revision b3e8c9027fcf0ca0f336b21b561e9afcb86c3c05)
@@ -55,5 +55,7 @@
 	stdin = NULL;
 
-	kbd_init();
+	if (bootinfo.keyboard.addr)
+		kbd_init();
+		
 	fb_init(bootinfo.screen.addr, bootinfo.screen.width, bootinfo.screen.height,
 		bootinfo.screen.bpp, bootinfo.screen.scanline);
@@ -66,4 +68,7 @@
 void kkbdpoll(void *arg)
 {
+	if (!bootinfo.keyboard.addr)
+		return;
+		
 	while (1) {
 		i8042_poll();		
Index: kernel/arch/sparc64/src/sparc64.c
===================================================================
--- kernel/arch/sparc64/src/sparc64.c	(revision c049309818d0a3eca8aa6dfecad99aa1f06ee0d6)
+++ kernel/arch/sparc64/src/sparc64.c	(revision b3e8c9027fcf0ca0f336b21b561e9afcb86c3c05)
@@ -97,12 +97,11 @@
  * trap table.
  *
- * The goal of this function is to disable MMU
- * so that both TLBs can be purged and new
- * kernel 4M locked entry can be installed.
- * After TLB is initialized, MMU is enabled
- * again.
+ * First, demap context 0 and install the
+ * global 4M locked kernel mapping.
  *
- * Switching MMU off imposes the requirement for
- * the kernel to run in identity mapped environment.
+ * Second, prepare a temporary IMMU mapping in
+ * context 1, switch to it, demap context 0,
+ * install the global 4M locked kernel mapping
+ * in context 0 and switch back to context 0.
  *
  * @param base Base address that will be hardwired in both TLBs.
@@ -115,24 +114,18 @@
 	page_address_t pg;
 
+	/*
+	 * Switch to the kernel trap table.
+	 */
+	trap_switch_trap_table();
+
 	fr.address = base;
 	pg.address = base;
 
-	immu_disable();
-	dmmu_disable();
-
-	/*
-	 * Demap everything, especially OpenFirmware.
-	 */
-	itlb_demap(TLB_DEMAP_CONTEXT, TLB_DEMAP_NUCLEUS, 0);
-	dtlb_demap(TLB_DEMAP_CONTEXT, TLB_DEMAP_NUCLEUS, 0);
-	
 	/*
 	 * We do identity mapping of 4M-page at 4M.
 	 */
-	tag.value = ASID_KERNEL;
+	tag.value = 0;
+	tag.context = 0;
 	tag.vpn = pg.vpn;
-
-	itlb_tag_access_write(tag.value);
-	dtlb_tag_access_write(tag.value);
 
 	data.value = 0;
@@ -142,23 +135,41 @@
 	data.l = true;
 	data.cp = 1;
-	data.cv = 1;
+	data.cv = 0;
 	data.p = true;
 	data.w = true;
 	data.g = true;
 
-	itlb_data_in_write(data.value);
+	/*
+	 * Straightforwardly demap DMUU context 0,
+	 * and replace it with the locked kernel mapping.
+	 */
+	dtlb_demap(TLB_DEMAP_CONTEXT, TLB_DEMAP_NUCLEUS, 0);
+	dtlb_tag_access_write(tag.value);
 	dtlb_data_in_write(data.value);
 
 	/*
-	 * Register window traps can occur before MMU is enabled again.
-	 * This ensures that any such traps will be handled from 
-	 * kernel identity mapped trap handler.
+	 * Install kernel code mapping in context 1
+	 * and switch to it.
 	 */
-	trap_switch_trap_table();
+	tag.context = 1;
+	data.g = false;
+	itlb_tag_access_write(tag.value);
+	itlb_data_in_write(data.value);
+	mmu_primary_context_write(1);
 	
-	tlb_invalidate_all();
-
-	dmmu_enable();
-	immu_enable();
+	/*
+	 * Demap old context 0.
+	 */
+	itlb_demap(TLB_DEMAP_CONTEXT, TLB_DEMAP_NUCLEUS, 0);
+	
+	/*
+	 * Install the locked kernel mapping in context 0
+	 * and switch to it.
+	 */
+	tag.context = 0;
+	data.g = true;
+	itlb_tag_access_write(tag.value);
+	itlb_data_in_write(data.value);
+	mmu_primary_context_write(0);
 }
 
Index: kernel/arch/sparc64/src/start.S
===================================================================
--- kernel/arch/sparc64/src/start.S	(revision c049309818d0a3eca8aa6dfecad99aa1f06ee0d6)
+++ kernel/arch/sparc64/src/start.S	(revision b3e8c9027fcf0ca0f336b21b561e9afcb86c3c05)
@@ -72,12 +72,12 @@
 	nop
 
+	set kernel_image_start, %o0
 	/*
-	 * Take over control of identity mapping.
-	 * Take over control of trap table.
+	 * Take over control of MMU.
 	 *
-	 * After this call, the kernel is entirely self-sufficient
-	 * and independent on OpenFirmware.
+	 * First, take over DMMU for which we don't need to issue
+	 * any FLUSH instructions. Because of that, we can
+	 * demap the old DTLB pretty straightforwardly.
 	 */
-	set kernel_image_start, %o0
 	call take_over_tlb_and_tt
 	nop
Index: kernel/generic/src/syscall/copy.c
===================================================================
--- kernel/generic/src/syscall/copy.c	(revision c049309818d0a3eca8aa6dfecad99aa1f06ee0d6)
+++ kernel/generic/src/syscall/copy.c	(revision b3e8c9027fcf0ca0f336b21b561e9afcb86c3c05)
@@ -27,5 +27,5 @@
  */
     
- /** @addtogroup generic
+/** @addtogroup generic
  * @{
  */
@@ -129,5 +129,4 @@
 }
 
- /** @}
+/** @}
  */
-
