Index: kernel/arch/sparc64/include/arch.h
===================================================================
--- kernel/arch/sparc64/include/arch.h	(revision e0b241fd74402f055e3581549efeaa597b289645)
+++ kernel/arch/sparc64/include/arch.h	(revision ed166f71740001c3b594706d223312aeb0e52fb0)
@@ -35,6 +35,6 @@
  */
 
-#ifndef __sparc64_ARCH_H__
-#define __sparc64_ARCH_H__
+#ifndef KERN_sparc64_ARCH_H_
+#define KERN_sparc64_ARCH_H_
 
 #define ASI_AIUP	0x10	/** Access to primary context with user privileges. */
Index: kernel/arch/sparc64/include/arg.h
===================================================================
--- kernel/arch/sparc64/include/arg.h	(revision e0b241fd74402f055e3581549efeaa597b289645)
+++ kernel/arch/sparc64/include/arg.h	(revision ed166f71740001c3b594706d223312aeb0e52fb0)
@@ -27,5 +27,5 @@
  */
 
- /** @addtogroup sparc64	
+/** @addtogroup sparc64	
  * @{
  */
@@ -33,6 +33,6 @@
  */
 
-#ifndef __sparc64_ARG_H__
-#define __sparc64_ARG_H__
+#ifndef KERN_sparc64_ARG_H_
+#define KERN_sparc64_ARG_H_
 
 #include <stdarg.h>
@@ -40,5 +40,4 @@
 #endif
 
- /** @}
+/** @}
  */
-
Index: kernel/arch/sparc64/include/asm.h
===================================================================
--- kernel/arch/sparc64/include/asm.h	(revision e0b241fd74402f055e3581549efeaa597b289645)
+++ kernel/arch/sparc64/include/asm.h	(revision ed166f71740001c3b594706d223312aeb0e52fb0)
@@ -331,4 +331,6 @@
 extern void write_to_ig_g6(uint64_t val);
 
+extern void switch_to_userspace(uint64_t pc, uint64_t sp);
+
 #endif
 
Index: kernel/arch/sparc64/include/atomic.h
===================================================================
--- kernel/arch/sparc64/include/atomic.h	(revision e0b241fd74402f055e3581549efeaa597b289645)
+++ kernel/arch/sparc64/include/atomic.h	(revision ed166f71740001c3b594706d223312aeb0e52fb0)
@@ -33,6 +33,6 @@
  */
 
-#ifndef __sparc64_ATOMIC_H__
-#define __sparc64_ATOMIC_H__
+#ifndef KERN_sparc64_ATOMIC_H_
+#define KERN_sparc64_ATOMIC_H_
 
 #include <arch/types.h>
Index: kernel/arch/sparc64/include/barrier.h
===================================================================
--- kernel/arch/sparc64/include/barrier.h	(revision e0b241fd74402f055e3581549efeaa597b289645)
+++ kernel/arch/sparc64/include/barrier.h	(revision ed166f71740001c3b594706d223312aeb0e52fb0)
@@ -33,6 +33,6 @@
  */
 
-#ifndef __sparc64_BARRIER_H__
-#define __sparc64_BARRIER_H__
+#ifndef KERN_sparc64_BARRIER_H_
+#define KERN_sparc64_BARRIER_H_
 
 /*
Index: kernel/arch/sparc64/include/byteorder.h
===================================================================
--- kernel/arch/sparc64/include/byteorder.h	(revision e0b241fd74402f055e3581549efeaa597b289645)
+++ kernel/arch/sparc64/include/byteorder.h	(revision ed166f71740001c3b594706d223312aeb0e52fb0)
@@ -27,5 +27,5 @@
  */
 
- /** @addtogroup sparc64	
+/** @addtogroup sparc64	
  * @{
  */
@@ -33,6 +33,6 @@
  */
 
-#ifndef __sparc64_BYTEORDER_H__
-#define __sparc64_BYTEORDER_H__
+#ifndef KERN_sparc64_BYTEORDER_H_
+#define KERN_sparc64_BYTEORDER_H_
 
 #include <arch/types.h>
@@ -51,5 +51,4 @@
 #endif
 
- /** @}
+/** @}
  */
-
Index: kernel/arch/sparc64/include/console.h
===================================================================
--- kernel/arch/sparc64/include/console.h	(revision e0b241fd74402f055e3581549efeaa597b289645)
+++ kernel/arch/sparc64/include/console.h	(revision ed166f71740001c3b594706d223312aeb0e52fb0)
@@ -37,5 +37,4 @@
 
 extern void kkbdpoll(void *arg);
-extern void ofw_sparc64_console_init(void);
 extern void standalone_sparc64_console_init(void);
 
Index: kernel/arch/sparc64/include/context.h
===================================================================
--- kernel/arch/sparc64/include/context.h	(revision e0b241fd74402f055e3581549efeaa597b289645)
+++ kernel/arch/sparc64/include/context.h	(revision ed166f71740001c3b594706d223312aeb0e52fb0)
@@ -33,16 +33,16 @@
  */
 
-#ifndef __sparc64_CONTEXT_H__
-#define __sparc64_CONTEXT_H__
+#ifndef KERN_sparc64_CONTEXT_H_
+#define KERN_sparc64_CONTEXT_H_
 
-#ifndef __sparc64_STACK_H__
+#ifndef KERN_sparc64_STACK_H_
 # include <arch/stack.h>
 #endif
 
-#ifndef __sparc64_TYPES_H__
+#ifndef KERN_sparc64_TYPES_H_
 # include <arch/types.h>
 #endif
 
-#ifndef __ALIGN_H__
+#ifndef KERN_ALIGN_H_
 # include <align.h>
 #endif
Index: kernel/arch/sparc64/include/cpu.h
===================================================================
--- kernel/arch/sparc64/include/cpu.h	(revision e0b241fd74402f055e3581549efeaa597b289645)
+++ kernel/arch/sparc64/include/cpu.h	(revision ed166f71740001c3b594706d223312aeb0e52fb0)
@@ -33,6 +33,6 @@
  */
 
-#ifndef __sparc64_CPU_H__
-#define __sparc64_CPU_H__
+#ifndef KERN_sparc64_CPU_H_
+#define KERN_sparc64_CPU_H_
 
 #include <arch/register.h>
Index: kernel/arch/sparc64/include/debug.h
===================================================================
--- kernel/arch/sparc64/include/debug.h	(revision e0b241fd74402f055e3581549efeaa597b289645)
+++ kernel/arch/sparc64/include/debug.h	(revision ed166f71740001c3b594706d223312aeb0e52fb0)
@@ -27,5 +27,5 @@
  */
 
- /** @addtogroup sparc64debug
+/** @addtogroup sparc64debug
  * @{
  */
@@ -33,10 +33,9 @@
  */
 
-#ifndef __sparc64_DEBUG_H__
-#define __sparc64_DEBUG_H__
+#ifndef KERN_sparc64_DEBUG_H_
+#define KERN_sparc64_DEBUG_H_
 
 #endif
 
- /** @}
+/** @}
  */
-
Index: kernel/arch/sparc64/include/drivers/tick.h
===================================================================
--- kernel/arch/sparc64/include/drivers/tick.h	(revision e0b241fd74402f055e3581549efeaa597b289645)
+++ kernel/arch/sparc64/include/drivers/tick.h	(revision ed166f71740001c3b594706d223312aeb0e52fb0)
@@ -33,6 +33,6 @@
  */
 
-#ifndef __sparc64_TICK_H__
-#define __sparc64_TICK_H__
+#ifndef KERN_sparc64_TICK_H_
+#define KERN_sparc64_TICK_H_
 
 #include <typedefs.h>
Index: kernel/arch/sparc64/include/elf.h
===================================================================
--- kernel/arch/sparc64/include/elf.h	(revision e0b241fd74402f055e3581549efeaa597b289645)
+++ kernel/arch/sparc64/include/elf.h	(revision ed166f71740001c3b594706d223312aeb0e52fb0)
@@ -33,6 +33,6 @@
  */
 
-#ifndef __sparc64_ELF_H__
-#define __sparc64_ELF_H__
+#ifndef KERN_sparc64_ELF_H_
+#define KERN_sparc64_ELF_H_
 
 #define	ELF_MACHINE		EM_SPARCV9
Index: kernel/arch/sparc64/include/faddr.h
===================================================================
--- kernel/arch/sparc64/include/faddr.h	(revision e0b241fd74402f055e3581549efeaa597b289645)
+++ kernel/arch/sparc64/include/faddr.h	(revision ed166f71740001c3b594706d223312aeb0e52fb0)
@@ -27,5 +27,5 @@
  */
 
- /** @addtogroup sparc64	
+/** @addtogroup sparc64	
  * @{
  */
@@ -33,6 +33,6 @@
  */
 
-#ifndef __sparc64_FADDR_H__
-#define __sparc64_FADDR_H__
+#ifndef KERN_sparc64_FADDR_H_
+#define KERN_sparc64_FADDR_H_
 
 #include <arch/types.h>
@@ -42,5 +42,4 @@
 #endif
 
- /** @}
+/** @}
  */
-
Index: kernel/arch/sparc64/include/fpu_context.h
===================================================================
--- kernel/arch/sparc64/include/fpu_context.h	(revision e0b241fd74402f055e3581549efeaa597b289645)
+++ kernel/arch/sparc64/include/fpu_context.h	(revision ed166f71740001c3b594706d223312aeb0e52fb0)
@@ -27,5 +27,5 @@
  */
 
- /** @addtogroup sparc64	
+/** @addtogroup sparc64	
  * @{
  */
@@ -33,6 +33,6 @@
  */
 
-#ifndef __sparc64_FPU_CONTEXT_H__
-#define __sparc64_FPU_CONTEXT_H__
+#ifndef KERN_sparc64_FPU_CONTEXT_H_
+#define KERN_sparc64_FPU_CONTEXT_H_
 
 #include <arch/types.h>
@@ -43,5 +43,4 @@
 #endif
 
- /** @}
+/** @}
  */
-
Index: kernel/arch/sparc64/include/interrupt.h
===================================================================
--- kernel/arch/sparc64/include/interrupt.h	(revision e0b241fd74402f055e3581549efeaa597b289645)
+++ kernel/arch/sparc64/include/interrupt.h	(revision ed166f71740001c3b594706d223312aeb0e52fb0)
@@ -34,9 +34,10 @@
  */
 
-#ifndef __sparc64_INTERRUPT_H__
-#define __sparc64_INTERRUPT_H__
+#ifndef KERN_sparc64_INTERRUPT_H_
+#define KERN_sparc64_INTERRUPT_H_
 
 #include <typedefs.h>
 #include <arch/types.h>
+#include <arch/regdef.h>
 
 #define IRQ_COUNT	1	/* TODO */
@@ -53,15 +54,15 @@
 static inline void istate_set_retaddr(istate_t *istate, uintptr_t retaddr)
 {
-	/* TODO */
+	istate->tpc = retaddr;
 }
+
 static inline int istate_from_uspace(istate_t *istate)
 {
-	/* TODO */
-	return 0;
+	return !(istate->tstate & TSTATE_PRIV_BIT);
 }
+
 static inline unative_t istate_get_pc(istate_t *istate)
 {
-	/* TODO */
-	return 0;
+	return istate->tpc;
 }
 
Index: kernel/arch/sparc64/include/memstr.h
===================================================================
--- kernel/arch/sparc64/include/memstr.h	(revision e0b241fd74402f055e3581549efeaa597b289645)
+++ kernel/arch/sparc64/include/memstr.h	(revision ed166f71740001c3b594706d223312aeb0e52fb0)
@@ -27,5 +27,5 @@
  */
 
- /** @addtogroup sparc64	
+/** @addtogroup sparc64	
  * @{
  */
@@ -33,6 +33,6 @@
  */
 
-#ifndef __sparc64_MEMSTR_H__
-#define __sparc64_MEMSTR_H__
+#ifndef KERN_sparc64_MEMSTR_H_
+#define KERN_sparc64_MEMSTR_H_
 
 #define memcpy(dst, src, cnt)  __builtin_memcpy((dst), (src), (cnt))
@@ -45,5 +45,4 @@
 #endif
 
- /** @}
+/** @}
  */
-
Index: kernel/arch/sparc64/include/mm/as.h
===================================================================
--- kernel/arch/sparc64/include/mm/as.h	(revision e0b241fd74402f055e3581549efeaa597b289645)
+++ kernel/arch/sparc64/include/mm/as.h	(revision ed166f71740001c3b594706d223312aeb0e52fb0)
@@ -27,5 +27,5 @@
  */
 
- /** @addtogroup sparc64mm	
+/** @addtogroup sparc64mm	
  * @{
  */
@@ -33,6 +33,6 @@
  */
 
-#ifndef __sparc64_AS_H__
-#define __sparc64_AS_H__
+#ifndef KERN_sparc64_AS_H_
+#define KERN_sparc64_AS_H_
 
 #define KERNEL_ADDRESS_SPACE_SHADOWED_ARCH	1
@@ -45,11 +45,9 @@
 #define USTACK_ADDRESS_ARCH	(0x7fffffffffffffff-(PAGE_SIZE-1))
 
-#define as_install_arch(as)
-
 extern void as_arch_init(void);
 
 #endif
 
- /** @}
+/** @}
  */
 
Index: kernel/arch/sparc64/include/mm/frame.h
===================================================================
--- kernel/arch/sparc64/include/mm/frame.h	(revision e0b241fd74402f055e3581549efeaa597b289645)
+++ kernel/arch/sparc64/include/mm/frame.h	(revision ed166f71740001c3b594706d223312aeb0e52fb0)
@@ -48,6 +48,6 @@
 	struct {
 		unsigned : 23;
-		uint64_t pfn : 28;	/**< Physical Frame Number. */
-		unsigned offset : 13;	/**< Offset. */
+		uint64_t pfn : 28;		/**< Physical Frame Number. */
+		unsigned offset : 13;		/**< Offset. */
 	} __attribute__ ((packed));
 };
Index: kernel/arch/sparc64/include/mm/memory_init.h
===================================================================
--- kernel/arch/sparc64/include/mm/memory_init.h	(revision e0b241fd74402f055e3581549efeaa597b289645)
+++ kernel/arch/sparc64/include/mm/memory_init.h	(revision ed166f71740001c3b594706d223312aeb0e52fb0)
@@ -27,5 +27,5 @@
  */
 
- /** @addtogroup sparc64mm	
+/** @addtogroup sparc64mm	
  * @{
  */
@@ -33,6 +33,6 @@
  */
 
-#ifndef __sparc64_MEMORY_INIT_H__
-#define __sparc64_MEMORY_INIT_H__
+#ifndef KERN_sparc64_MEMORY_INIT_H_
+#define KERN_sparc64_MEMORY_INIT_H_
 
 #include <typedefs.h>
@@ -42,5 +42,4 @@
 #endif
 
- /** @}
+/** @}
  */
-
Index: kernel/arch/sparc64/include/mm/mmu.h
===================================================================
--- kernel/arch/sparc64/include/mm/mmu.h	(revision e0b241fd74402f055e3581549efeaa597b289645)
+++ kernel/arch/sparc64/include/mm/mmu.h	(revision ed166f71740001c3b594706d223312aeb0e52fb0)
@@ -33,6 +33,6 @@
  */
 
-#ifndef __sparc64_MMU_H__
-#define __sparc64_MMU_H__
+#ifndef KERN_sparc64_MMU_H_
+#define KERN_sparc64_MMU_H_
 
 /* LSU Control Register ASI. */
Index: kernel/arch/sparc64/include/mm/tlb.h
===================================================================
--- kernel/arch/sparc64/include/mm/tlb.h	(revision e0b241fd74402f055e3581549efeaa597b289645)
+++ kernel/arch/sparc64/include/mm/tlb.h	(revision ed166f71740001c3b594706d223312aeb0e52fb0)
@@ -33,7 +33,6 @@
  */
 
-#ifndef __sparc64_TLB_H__
-#define __sparc64_TLB_H__
-
+#ifndef KERN_sparc64_TLB_H_
+#define KERN_sparc64_TLB_H_
 
 #define ITLB_ENTRY_COUNT		64
Index: kernel/arch/sparc64/include/mm/tte.h
===================================================================
--- kernel/arch/sparc64/include/mm/tte.h	(revision e0b241fd74402f055e3581549efeaa597b289645)
+++ kernel/arch/sparc64/include/mm/tte.h	(revision ed166f71740001c3b594706d223312aeb0e52fb0)
@@ -33,6 +33,6 @@
  */
 
-#ifndef __sparc64_TTE_H__
-#define __sparc64_TTE_H__
+#ifndef KERN_sparc64_TTE_H_
+#define KERN_sparc64_TTE_H_
 
 #define TTE_G		(1<<0)
Index: kernel/arch/sparc64/include/proc/task.h
===================================================================
--- kernel/arch/sparc64/include/proc/task.h	(revision e0b241fd74402f055e3581549efeaa597b289645)
+++ kernel/arch/sparc64/include/proc/task.h	(revision ed166f71740001c3b594706d223312aeb0e52fb0)
@@ -27,5 +27,5 @@
  */
 
- /** @addtogroup sparc64proc
+/** @addtogroup sparc64proc
  * @{
  */
@@ -33,6 +33,6 @@
  */
 
-#ifndef __sparc64_TASK_H__
-#define __sparc64_TASK_H__
+#ifndef KERN_sparc64_TASK_H_
+#define KERN_sparc64_TASK_H_
 
 typedef struct {
@@ -44,5 +44,4 @@
 #endif
 
- /** @}
+/** @}
  */
-
Index: kernel/arch/sparc64/include/regdef.h
===================================================================
--- kernel/arch/sparc64/include/regdef.h	(revision e0b241fd74402f055e3581549efeaa597b289645)
+++ kernel/arch/sparc64/include/regdef.h	(revision ed166f71740001c3b594706d223312aeb0e52fb0)
@@ -47,4 +47,5 @@
 #define TSTATE_PSTATE_SHIFT	8
 #define TSTATE_PRIV_BIT		(PSTATE_PRIV_BIT<<TSTATE_PSTATE_SHIFT)
+#define TSTATE_IE_BIT		(PSTATE_IE_BIT<<TSTATE_PSTATE_SHIFT)
 
 #define TSTATE_CWP_MASK		0x1f
Index: kernel/arch/sparc64/include/trap/exception.h
===================================================================
--- kernel/arch/sparc64/include/trap/exception.h	(revision e0b241fd74402f055e3581549efeaa597b289645)
+++ kernel/arch/sparc64/include/trap/exception.h	(revision ed166f71740001c3b594706d223312aeb0e52fb0)
@@ -34,6 +34,6 @@
  */
 
-#ifndef __sparc64_EXCEPTION_H__
-#define __sparc64_EXCEPTION_H__
+#ifndef KERN_sparc64_EXCEPTION_H_
+#define KERN_sparc64_EXCEPTION_H_
 
 #define TT_INSTRUCTION_ACCESS_EXCEPTION		0x08
Index: kernel/arch/sparc64/include/trap/interrupt.h
===================================================================
--- kernel/arch/sparc64/include/trap/interrupt.h	(revision e0b241fd74402f055e3581549efeaa597b289645)
+++ kernel/arch/sparc64/include/trap/interrupt.h	(revision ed166f71740001c3b594706d223312aeb0e52fb0)
@@ -35,6 +35,6 @@
  */
 
-#ifndef __sparc64_TRAP_INTERRUPT_H__
-#define __sparc64_TRAP_INTERRUPT_H__
+#ifndef KERN_sparc64_TRAP_INTERRUPT_H_
+#define KERN_sparc64_TRAP_INTERRUPT_H_
 
 #include <arch/trap/trap_table.h>
Index: kernel/arch/sparc64/include/trap/mmu.h
===================================================================
--- kernel/arch/sparc64/include/trap/mmu.h	(revision e0b241fd74402f055e3581549efeaa597b289645)
+++ kernel/arch/sparc64/include/trap/mmu.h	(revision ed166f71740001c3b594706d223312aeb0e52fb0)
@@ -43,4 +43,5 @@
 #include <arch/mm/mmu.h>
 #include <arch/mm/tte.h>
+#include <arch/trap/regwin.h>
 
 #define TT_FAST_INSTRUCTION_ACCESS_MMU_MISS	0x64
@@ -51,8 +52,9 @@
 
 #ifdef __ASM__
+
 .macro FAST_INSTRUCTION_ACCESS_MMU_MISS_HANDLER
-	/*
-	 * First, try to refill TLB from TSB.
-	 */
+	!
+	! First, try to refill TLB from TSB.
+	!
 	! TODO
 
@@ -75,5 +77,5 @@
 	 * Note that branch-delay slots are used in order to save space.
 	 */
-0:
+
 	mov VA_DMMU_TAG_ACCESS, %g1
 	ldxa [%g1] ASI_DMMU, %g1			! read the faulting Context and VPN
@@ -85,7 +87,7 @@
 
 	or %g3, (TTE_CP|TTE_P|TTE_W), %g2		! 8K pages are the default (encoded as 0)
-        set 1, %g3
-        sllx %g3, TTE_V_SHIFT, %g3
-        or %g2, %g3, %g2
+	mov 1, %g3
+	sllx %g3, TTE_V_SHIFT, %g3
+	or %g2, %g3, %g2
 	stxa %g2, [%g0] ASI_DTLB_DATA_IN_REG		! identity map the kernel page
 	retry
@@ -93,10 +95,12 @@
 	/*
 	 * Third, catch and handle special cases when the trap is caused by
-	 * some register window trap handler.
+	 * the userspace register window spill or fill handler. In case
+	 * one of these two traps caused this trap, we just lower the trap
+	 * level and service the DTLB miss. In the end, we restart
+	 * the offending SAVE or RESTORE.
 	 */
 0:
-	! TODO
+	HANDLE_MMU_TRAPS_FROM_SPILL_OR_FILL
 
-0:
 	wrpr %g0, PSTATE_PRIV_BIT | PSTATE_AG_BIT, %pstate
 	PREEMPTIBLE_HANDLER fast_data_access_mmu_miss
@@ -104,7 +108,38 @@
 
 .macro FAST_DATA_ACCESS_PROTECTION_HANDLER
+	/*
+	 * First, try to refill TLB from TSB.
+	 */
+	! TODO
+
+	/*
+	 * The same special case as in FAST_DATA_ACCESS_MMU_MISS_HANDLER.
+	 */
+	HANDLE_MMU_TRAPS_FROM_SPILL_OR_FILL
+
 	wrpr %g0, PSTATE_PRIV_BIT | PSTATE_AG_BIT, %pstate
 	PREEMPTIBLE_HANDLER fast_data_access_protection
 .endm
+
+/*
+ * Macro used to lower TL when a MMU trap is caused by
+ * the userspace register window spill or fill handler.
+ */
+.macro HANDLE_MMU_TRAPS_FROM_SPILL_OR_FILL
+	rdpr %tl, %g1
+	dec %g1
+	brz %g1, 0f			! if TL was 1, skip
+	nop
+	wrpr %g1, 0, %tl		! TL--
+	rdpr %tt, %g2
+	cmp %g2, TT_SPILL_1_NORMAL
+	be 0f				! trap from spill_1_normal
+	cmp %g2, TT_FILL_1_NORMAL
+	be 0f				! trap from fill_1_normal
+	inc %g1
+	wrpr %g1, 0, %tl		! another trap, TL++
+0:
+.endm
+
 #endif /* __ASM__ */
 
Index: kernel/arch/sparc64/include/trap/regwin.h
===================================================================
--- kernel/arch/sparc64/include/trap/regwin.h	(revision e0b241fd74402f055e3581549efeaa597b289645)
+++ kernel/arch/sparc64/include/trap/regwin.h	(revision ed166f71740001c3b594706d223312aeb0e52fb0)
@@ -35,6 +35,6 @@
  */
 
-#ifndef __sparc64_REGWIN_H__
-#define __sparc64_REGWIN_H__
+#ifndef KERN_sparc64_REGWIN_H_
+#define KERN_sparc64_REGWIN_H_
 
 #include <arch/stack.h>
Index: kernel/arch/sparc64/include/trap/trap.h
===================================================================
--- kernel/arch/sparc64/include/trap/trap.h	(revision e0b241fd74402f055e3581549efeaa597b289645)
+++ kernel/arch/sparc64/include/trap/trap.h	(revision ed166f71740001c3b594706d223312aeb0e52fb0)
@@ -33,6 +33,6 @@
  */
 
-#ifndef __sparc64_TRAP_H__
-#define __sparc64_TRAP_H__
+#ifndef KERN_sparc64_TRAP_H_
+#define KERN_sparc64_TRAP_H_
 
 extern void trap_init(void);
Index: kernel/arch/sparc64/include/trap/trap_table.h
===================================================================
--- kernel/arch/sparc64/include/trap/trap_table.h	(revision e0b241fd74402f055e3581549efeaa597b289645)
+++ kernel/arch/sparc64/include/trap/trap_table.h	(revision ed166f71740001c3b594706d223312aeb0e52fb0)
@@ -33,10 +33,6 @@
  */
 
-#ifndef __sparc64_TRAP_TABLE_H__
-#define __sparc64_TRAP_TABLE_H__
-
-#ifndef __ASM__
-#include <arch/types.h>
-#endif /* __ASM__ */
+#ifndef KERN_sparc64_TRAP_TABLE_H_
+#define KERN_sparc64_TRAP_TABLE_H_
 
 #include <arch/stack.h>
@@ -47,4 +43,7 @@
 
 #ifndef __ASM__
+
+#include <arch/types.h>
+
 struct trap_table_entry {
 	uint8_t octets[TRAP_TABLE_ENTRY_SIZE];
Index: kernel/arch/sparc64/include/types.h
===================================================================
--- kernel/arch/sparc64/include/types.h	(revision e0b241fd74402f055e3581549efeaa597b289645)
+++ kernel/arch/sparc64/include/types.h	(revision ed166f71740001c3b594706d223312aeb0e52fb0)
@@ -27,5 +27,5 @@
  */
 
- /** @addtogroup sparc64	
+/** @addtogroup sparc64	
  * @{
  */
@@ -33,6 +33,6 @@
  */
 
-#ifndef __sparc64_TYPES_H__
-#define __sparc64_TYPES_H__
+#ifndef KERN_sparc64_TYPES_H_
+#define KERN_sparc64_TYPES_H_
 
 #define NULL	0
@@ -62,5 +62,4 @@
 #endif
 
- /** @}
+/** @}
  */
-
Index: kernel/arch/sparc64/src/asm.S
===================================================================
--- kernel/arch/sparc64/src/asm.S	(revision e0b241fd74402f055e3581549efeaa597b289645)
+++ kernel/arch/sparc64/src/asm.S	(revision ed166f71740001c3b594706d223312aeb0e52fb0)
@@ -29,4 +29,5 @@
 #include <arch/stack.h>
 #include <arch/regdef.h>
+#include <arch/mm/mmu.h>
 
 .text
@@ -144,2 +145,38 @@
 read_from_ag_g7:
 	READ_ALTERNATE_REGISTER %g7, PSTATE_AG_BIT
+
+
+/** Switch to userspace.
+ *
+ * %o0	Userspace entry address.
+ * %o1	Userspace stack pointer address.
+ */
+.global switch_to_userspace
+switch_to_userspace:
+	flushw
+	wrpr %g0, 0, %cleanwin		! avoid information leak
+	save %o1, -STACK_WINDOW_SAVE_AREA_SIZE, %sp
+
+	clr %i2
+	clr %i3
+	clr %i4
+	clr %i5
+	clr %i6
+
+	wrpr %g0, 1, %tl		! enforce mapping via nucleus
+
+	rdpr %cwp, %g1
+	wrpr %g1, TSTATE_IE_BIT, %tstate
+	wrpr %i0, 0, %tnpc
+	
+	/*
+	 * Set primary context according to secondary context.
+	 * Secondary context has been already installed by
+	 * higher-level functions.
+	 */
+	wr %g0, ASI_DMMU, %asi
+	ldxa [VA_SECONDARY_CONTEXT_REG] %asi, %g1
+	stxa %g1, [VA_PRIMARY_CONTEXT_REG] %asi
+	flush %i7
+	
+	done				! jump to userspace
Index: kernel/arch/sparc64/src/ddi/ddi.c
===================================================================
--- kernel/arch/sparc64/src/ddi/ddi.c	(revision e0b241fd74402f055e3581549efeaa597b289645)
+++ kernel/arch/sparc64/src/ddi/ddi.c	(revision ed166f71740001c3b594706d223312aeb0e52fb0)
@@ -27,5 +27,5 @@
  */
 
- /** @addtogroup sparc64ddi
+/** @addtogroup sparc64ddi
  * @{
  */
@@ -53,5 +53,4 @@
 }
 
- /** @}
+/** @}
  */
-
Index: kernel/arch/sparc64/src/dummy.s
===================================================================
--- kernel/arch/sparc64/src/dummy.s	(revision e0b241fd74402f055e3581549efeaa597b289645)
+++ kernel/arch/sparc64/src/dummy.s	(revision ed166f71740001c3b594706d223312aeb0e52fb0)
@@ -40,5 +40,4 @@
 .global fpu_enable
 .global fpu_init
-.global userspace
 .global sys_tls_set
 
@@ -56,5 +55,4 @@
 fpu_enable:
 fpu_init:
-userspace:
 sys_tls_set:
 
Index: kernel/arch/sparc64/src/mm/as.c
===================================================================
--- kernel/arch/sparc64/src/mm/as.c	(revision e0b241fd74402f055e3581549efeaa597b289645)
+++ kernel/arch/sparc64/src/mm/as.c	(revision ed166f71740001c3b594706d223312aeb0e52fb0)
@@ -27,5 +27,5 @@
  */
 
- /** @addtogroup sparc64mm
+/** @addtogroup sparc64mm
  * @{
  */
@@ -34,4 +34,5 @@
 
 #include <arch/mm/as.h>
+#include <arch/mm/tlb.h>
 #include <genarch/mm/as_ht.h>
 #include <genarch/mm/asid_fifo.h>
@@ -44,5 +45,21 @@
 }
 
- /** @}
+void as_install_arch(as_t *as)
+{
+	tlb_context_reg_t ctx;
+	
+	/*
+	 * Write ASID to secondary context register.
+	 * The primary context register has to be set
+	 * from TL>0 so it will be filled from the
+	 * secondary context register from the TL=1
+	 * code just before switch to userspace.
+	 */
+	ctx.v = 0;
+	ctx.context = as->asid;
+	mmu_secondary_context_write(ctx.v);
+}
+
+/** @}
  */
 
Index: kernel/arch/sparc64/src/mm/tlb.c
===================================================================
--- kernel/arch/sparc64/src/mm/tlb.c	(revision e0b241fd74402f055e3581549efeaa597b289645)
+++ kernel/arch/sparc64/src/mm/tlb.c	(revision ed166f71740001c3b594706d223312aeb0e52fb0)
@@ -375,7 +375,14 @@
 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);
+	tlb_context_reg_t sc_save, ctx;
+	
+	ctx.v = sc_save.v = mmu_secondary_context_read();
+	ctx.context = asid;
+	mmu_secondary_context_write(ctx.v);
+	
+	itlb_demap(TLB_DEMAP_CONTEXT, TLB_DEMAP_SECONDARY, 0);
+	dtlb_demap(TLB_DEMAP_CONTEXT, TLB_DEMAP_SECONDARY, 0);
+	
+	mmu_secondary_context_write(sc_save.v);
 }
 
@@ -389,10 +396,16 @@
 {
 	int i;
+	tlb_context_reg_t sc_save, ctx;
+	
+	ctx.v = sc_save.v = mmu_secondary_context_read();
+	ctx.context = asid;
+	mmu_secondary_context_write(ctx.v);
 	
 	for (i = 0; i < cnt; i++) {
-		/* TODO: write asid to some Context register and encode the register in second parameter below. */
-		itlb_demap(TLB_DEMAP_PAGE, TLB_DEMAP_NUCLEUS, page + i * PAGE_SIZE);
-		dtlb_demap(TLB_DEMAP_PAGE, TLB_DEMAP_NUCLEUS, page + i * PAGE_SIZE);
-	}
+		itlb_demap(TLB_DEMAP_PAGE, TLB_DEMAP_SECONDARY, page + i * PAGE_SIZE);
+		dtlb_demap(TLB_DEMAP_PAGE, TLB_DEMAP_SECONDARY, page + i * PAGE_SIZE);
+	}
+	
+	mmu_secondary_context_write(sc_save.v);
 }
 
Index: kernel/arch/sparc64/src/proc/scheduler.c
===================================================================
--- kernel/arch/sparc64/src/proc/scheduler.c	(revision e0b241fd74402f055e3581549efeaa597b289645)
+++ kernel/arch/sparc64/src/proc/scheduler.c	(revision ed166f71740001c3b594706d223312aeb0e52fb0)
@@ -92,6 +92,8 @@
 		 * in the userspace window buffer to %g7 in the alternate and interrupt sets.
 		 */
-		write_to_ig_g6((uintptr_t) THREAD->kstack + STACK_SIZE - STACK_BIAS);
-		write_to_ag_g6((uintptr_t) THREAD->kstack + STACK_SIZE - STACK_BIAS);
+		uint64_t sp = (uintptr_t) THREAD->kstack + STACK_SIZE
+			- (STACK_BIAS + ALIGN_UP(STACK_ITEM_SIZE, STACK_ALIGNMENT));
+		write_to_ig_g6(sp);
+		write_to_ag_g6(sp);
 		write_to_ag_g7((uintptr_t) THREAD->arch.uspace_window_buffer);
 	}
Index: kernel/arch/sparc64/src/sparc64.c
===================================================================
--- kernel/arch/sparc64/src/sparc64.c	(revision e0b241fd74402f055e3581549efeaa597b289645)
+++ kernel/arch/sparc64/src/sparc64.c	(revision ed166f71740001c3b594706d223312aeb0e52fb0)
@@ -35,4 +35,5 @@
 #include <arch.h>
 #include <debug.h>
+#include <config.h>
 #include <arch/trap/trap.h>
 #include <arch/console.h>
@@ -42,6 +43,7 @@
 #include <arch/boot/boot.h>
 #include <arch/arch.h>
-#include <arch/mm/tlb.h>
-#include <mm/asid.h>
+#include <arch/mm/page.h>
+#include <arch/stack.h>
+#include <userspace.h>
 
 bootinfo_t bootinfo;
@@ -92,4 +94,16 @@
 }
 
+/** Switch to userspace. */
+void userspace(uspace_arg_t *kernel_uarg)
+{
+	switch_to_userspace((uintptr_t) kernel_uarg->uspace_entry,
+		((uintptr_t) kernel_uarg->uspace_stack) + STACK_SIZE
+		- (ALIGN_UP(STACK_ITEM_SIZE, STACK_ALIGNMENT) + STACK_BIAS));
+
+	for (;;)
+		;
+	/* not reached */
+}
+
 /** @}
  */
Index: kernel/arch/sparc64/src/start.S
===================================================================
--- kernel/arch/sparc64/src/start.S	(revision e0b241fd74402f055e3581549efeaa597b289645)
+++ kernel/arch/sparc64/src/start.S	(revision ed166f71740001c3b594706d223312aeb0e52fb0)
@@ -69,5 +69,5 @@
 	wrpr %g1, 0, %pstate
 
-	wrpr %r0, 0, %pil		! intialize %pil
+	wrpr %g0, 0, %pil		! intialize %pil
 
 	/*
Index: kernel/arch/sparc64/src/trap/trap_table.S
===================================================================
--- kernel/arch/sparc64/src/trap/trap_table.S	(revision e0b241fd74402f055e3581549efeaa597b289645)
+++ kernel/arch/sparc64/src/trap/trap_table.S	(revision ed166f71740001c3b594706d223312aeb0e52fb0)
@@ -41,4 +41,5 @@
 #include <arch/trap/exception.h>
 #include <arch/trap/mmu.h>
+#include <arch/mm/mmu.h>
 #include <arch/mm/page.h>
 #include <arch/stack.h>
@@ -349,5 +350,5 @@
 	wrpr %l0, %otherwin
 	wrpr %g0, %cansave
-	wrpr %g0, NWINDOW-1, %cleanwin
+	wrpr %g0, NWINDOW - 1, %cleanwin
 
 	/*
@@ -355,7 +356,7 @@
 	 */
 	mov VA_PRIMARY_CONTEXT_REG, %l0
-        stxa %g0, [%l0] ASI_DMMU
-	set kernel_image_start, %l0
-        flush %l0
+	stxa %g0, [%l0] ASI_DMMU
+	rd %pc, %l0
+	flush %l0
 
 	ba 1f
@@ -498,4 +499,12 @@
 	 */
 	wrpr %g0, WSTATE_OTHER(0) | WSTATE_NORMAL(1), %wstate
+
+	/*
+	 * Set primary context according to secondary context.
+	 */
+	wr %g0, ASI_DMMU, %asi
+	ldxa [VA_SECONDARY_CONTEXT_REG] %asi, %g1
+	stxa %g1, [VA_PRIMARY_CONTEXT_REG] %asi
+	flush %o7
 	
 	rdpr %cwp, %g1
Index: kernel/generic/include/align.h
===================================================================
--- kernel/generic/include/align.h	(revision e0b241fd74402f055e3581549efeaa597b289645)
+++ kernel/generic/include/align.h	(revision ed166f71740001c3b594706d223312aeb0e52fb0)
@@ -27,14 +27,15 @@
  */
 
-
 /** @addtogroup generic	
  * @ingroup others
  * @{
  */
-/** @file
+/**
+ * @file
+ * @brief	Macros for making values and addresses aligned.
  */
 
-#ifndef __ALIGN_H__
-#define __ALIGN_H__
+#ifndef KERN_ALIGN_H_
+#define KERN_ALIGN_H_
 
 /** Align to the nearest lower address.
