Index: kernel/arch/sparc64/include/asm.h
===================================================================
--- kernel/arch/sparc64/include/asm.h	(revision 0fa6044030c5c9175f76bf5a500b45f6f66598e6)
+++ kernel/arch/sparc64/include/asm.h	(revision e11ae91fc3a4227bcea74717abb36d585ceb5627)
@@ -322,7 +322,12 @@
 }
 
-void cpu_halt(void);
-void cpu_sleep(void);
-void asm_delay_loop(uint32_t t);
+extern void cpu_halt(void);
+extern void cpu_sleep(void);
+extern void asm_delay_loop(uint32_t t);
+
+extern uint64_t read_from_ag_g7(void);
+extern void write_to_ag_g6(uint64_t val);
+extern void write_to_ag_g7(uint64_t val);
+extern void write_to_ig_g6(uint64_t val);
 
 #endif
Index: kernel/arch/sparc64/include/context.h
===================================================================
--- kernel/arch/sparc64/include/context.h	(revision 0fa6044030c5c9175f76bf5a500b45f6f66598e6)
+++ kernel/arch/sparc64/include/context.h	(revision e11ae91fc3a4227bcea74717abb36d585ceb5627)
@@ -55,6 +55,6 @@
 
 #define context_set(c, _pc, stack, size)								\
-        (c)->pc = ((uintptr_t) _pc) - 8;								\
-        (c)->sp = ((uintptr_t) stack) + ALIGN_UP((size), STACK_ALIGNMENT) - (STACK_BIAS + SP_DELTA);	\
+	(c)->pc = ((uintptr_t) _pc) - 8;								\
+	(c)->sp = ((uintptr_t) stack) + ALIGN_UP((size), STACK_ALIGNMENT) - (STACK_BIAS + SP_DELTA);	\
 	(c)->fp = -STACK_BIAS;										\
 	(c)->cleanwin = 0
Index: kernel/arch/sparc64/include/trap/regwin.h
===================================================================
--- kernel/arch/sparc64/include/trap/regwin.h	(revision 0fa6044030c5c9175f76bf5a500b45f6f66598e6)
+++ kernel/arch/sparc64/include/trap/regwin.h	(revision e11ae91fc3a4227bcea74717abb36d585ceb5627)
@@ -42,6 +42,10 @@
 
 #define TT_CLEAN_WINDOW			0x24
-#define TT_SPILL_0_NORMAL		0x80
-#define TT_FILL_0_NORMAL		0xc0
+#define TT_SPILL_0_NORMAL		0x80	/* kernel spills */
+#define TT_SPILL_1_NORMAL		0x84	/* userspace spills */
+#define TT_SPILL_2_NORMAL		0x88	/* spills to userspace window buffer */
+#define TT_SPILL_0_OTHER		0xa0	/* spills to userspace window buffer */
+#define TT_FILL_0_NORMAL		0xc0	/* kernel fills */
+#define TT_FILL_1_NORMAL		0xc4	/* userspace fills */
 
 #define REGWIN_HANDLER_SIZE		128
@@ -99,5 +103,5 @@
  */
 .macro SPILL_NORMAL_HANDLER_USERSPACE
-	wr ASI_AIUP, %asi
+	wr %g0, ASI_AIUP, %asi
 	stxa %l0, [%sp + STACK_BIAS + L0_OFFSET] %asi
 	stxa %l1, [%sp + STACK_BIAS + L1_OFFSET] %asi
@@ -121,24 +125,27 @@
 
 /*
- * Macro used by the userspace during other spills.
- */
-.macro SPILL_OTHER_HANDLER_USERSPACE
-	wr ASI_AIUS, %asi
-	stxa %l0, [%sp + STACK_BIAS + L0_OFFSET] %asi
-	stxa %l1, [%sp + STACK_BIAS + L1_OFFSET] %asi
-	stxa %l2, [%sp + STACK_BIAS + L2_OFFSET] %asi
-	stxa %l3, [%sp + STACK_BIAS + L3_OFFSET] %asi
-	stxa %l4, [%sp + STACK_BIAS + L4_OFFSET] %asi
-	stxa %l5, [%sp + STACK_BIAS + L5_OFFSET] %asi
-	stxa %l6, [%sp + STACK_BIAS + L6_OFFSET] %asi
-	stxa %l7, [%sp + STACK_BIAS + L7_OFFSET] %asi
-	stxa %i0, [%sp + STACK_BIAS + I0_OFFSET] %asi
-	stxa %i1, [%sp + STACK_BIAS + I1_OFFSET] %asi
-	stxa %i2, [%sp + STACK_BIAS + I2_OFFSET] %asi
-	stxa %i3, [%sp + STACK_BIAS + I3_OFFSET] %asi
-	stxa %i4, [%sp + STACK_BIAS + I4_OFFSET] %asi
-	stxa %i5, [%sp + STACK_BIAS + I5_OFFSET] %asi
-	stxa %i6, [%sp + STACK_BIAS + I6_OFFSET] %asi
-	stxa %i7, [%sp + STACK_BIAS + I7_OFFSET] %asi
+ * Macro used to spill userspace window to userspace window buffer.
+ * It can be either triggered from preemptible_handler doing SAVE
+ * at (TL=1) or from normal kernel code doing SAVE when OTHERWIN>0
+ * at (TL=0).
+ */
+.macro SPILL_TO_USPACE_WINDOW_BUFFER
+	stx %l0, [%g7 + L0_OFFSET]	
+	stx %l1, [%g7 + L1_OFFSET]
+	stx %l2, [%g7 + L2_OFFSET]
+	stx %l3, [%g7 + L3_OFFSET]
+	stx %l4, [%g7 + L4_OFFSET]
+	stx %l5, [%g7 + L5_OFFSET]
+	stx %l6, [%g7 + L6_OFFSET]
+	stx %l7, [%g7 + L7_OFFSET]
+	stx %i0, [%g7 + I0_OFFSET]
+	stx %i1, [%g7 + I1_OFFSET]
+	stx %i2, [%g7 + I2_OFFSET]
+	stx %i3, [%g7 + I3_OFFSET]
+	stx %i4, [%g7 + I4_OFFSET]
+	stx %i5, [%g7 + I5_OFFSET]
+	stx %i6, [%g7 + I6_OFFSET]
+	stx %i7, [%g7 + I7_OFFSET]
+	add %g7, STACK_WINDOW_SAVE_AREA_SIZE, %g7
 	saved
 	retry
@@ -174,30 +181,5 @@
  */
 .macro FILL_NORMAL_HANDLER_USERSPACE
-	wr ASI_AIUP, %asi
-	ldxa [%sp + STACK_BIAS + L0_OFFSET] %asi, %l0
-	ldxa [%sp + STACK_BIAS + L1_OFFSET] %asi, %l1
-	ldxa [%sp + STACK_BIAS + L2_OFFSET] %asi, %l2
-	ldxa [%sp + STACK_BIAS + L3_OFFSET] %asi, %l3
-	ldxa [%sp + STACK_BIAS + L4_OFFSET] %asi, %l4
-	ldxa [%sp + STACK_BIAS + L5_OFFSET] %asi, %l5
-	ldxa [%sp + STACK_BIAS + L6_OFFSET] %asi, %l6
-	ldxa [%sp + STACK_BIAS + L7_OFFSET] %asi, %l7
-	ldxa [%sp + STACK_BIAS + I0_OFFSET] %asi, %i0
-	ldxa [%sp + STACK_BIAS + I1_OFFSET] %asi, %i1
-	ldxa [%sp + STACK_BIAS + I2_OFFSET] %asi, %i2
-	ldxa [%sp + STACK_BIAS + I3_OFFSET] %asi, %i3
-	ldxa [%sp + STACK_BIAS + I4_OFFSET] %asi, %i4
-	ldxa [%sp + STACK_BIAS + I5_OFFSET] %asi, %i5
-	ldxa [%sp + STACK_BIAS + I6_OFFSET] %asi, %i6
-	ldxa [%sp + STACK_BIAS + I7_OFFSET] %asi, %i7
-	restored
-	retry
-.endm
-
-/*
- * Macro used by the userspace during other fills.
- */
-.macro FILL_OTHER_HANDLER_USERSPACE
-	wr ASI_AIUS, %asi
+	wr %g0, ASI_AIUP, %asi
 	ldxa [%sp + STACK_BIAS + L0_OFFSET] %asi, %l0
 	ldxa [%sp + STACK_BIAS + L1_OFFSET] %asi, %l1
Index: kernel/arch/sparc64/src/asm.S
===================================================================
--- kernel/arch/sparc64/src/asm.S	(revision 0fa6044030c5c9175f76bf5a500b45f6f66598e6)
+++ kernel/arch/sparc64/src/asm.S	(revision e11ae91fc3a4227bcea74717abb36d585ceb5627)
@@ -107,2 +107,39 @@
 	b _memsetb
 	nop
+
+
+.macro WRITE_ALTERNATE_REGISTER reg, bit
+	save %sp, -STACK_WINDOW_SAVE_AREA_SIZE, %sp
+	rdpr %pstate, %l0
+	wrpr %l0, \bit, %pstate
+	mov %i0, \reg
+	wrpr %l0, 0, %pstate
+	ret
+	restore
+.endm
+
+.macro READ_ALTERNATE_REGISTER reg, bit
+	save %sp, -STACK_WINDOW_SAVE_AREA_SIZE, %sp
+	rdpr %pstate, %l0
+	wrpr %l0, \bit, %pstate
+	mov \reg, %i0
+	wrpr %l0, 0, %pstate
+	ret
+	restore
+.endm
+
+.global write_to_ag_g6
+write_to_ag_g6:
+	WRITE_ALTERNATE_REGISTER %g6, PSTATE_AG_BIT
+
+.global write_to_ag_g7
+write_to_ag_g7:
+	WRITE_ALTERNATE_REGISTER %g7, PSTATE_AG_BIT
+
+.global write_to_ig_g6
+write_to_ig_g6:
+	WRITE_ALTERNATE_REGISTER %g6, PSTATE_IG_BIT
+
+.global read_from_ag_g7
+read_from_ag_g7:
+	READ_ALTERNATE_REGISTER %g7, PSTATE_AG_BIT
Index: kernel/arch/sparc64/src/proc/scheduler.c
===================================================================
--- kernel/arch/sparc64/src/proc/scheduler.c	(revision 0fa6044030c5c9175f76bf5a500b45f6f66598e6)
+++ kernel/arch/sparc64/src/proc/scheduler.c	(revision e11ae91fc3a4227bcea74717abb36d585ceb5627)
@@ -37,4 +37,6 @@
 #include <arch.h>
 #include <arch/asm.h>
+#include <arch/regdef.h>
+#include <arch/stack.h>
 #include <arch/mm/tlb.h>
 #include <arch/mm/page.h>
@@ -52,4 +54,6 @@
  * Ensure that thread's kernel stack, as well as userspace window
  * buffer for userspace threads, are locked in DTLB.
+ * For userspace threads, initialize reserved global registers
+ * in the alternate and interrupt sets.
  */
 void before_thread_runs_arch(void)
@@ -83,4 +87,12 @@
 			dtlb_insert_mapping(uw_buf, KA2PA(uw_buf), PAGESIZE_8K, true, true);
 		}
+		
+		/*
+		 * Write kernel stack address to %g6 and a pointer to the last item
+		 * 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);
+		write_to_ag_g7((uintptr_t) THREAD->arch.uspace_window_buffer);
 	}
 }
@@ -124,4 +136,7 @@
 			dtlb_demap(TLB_DEMAP_PAGE, TLB_DEMAP_NUCLEUS, (uintptr_t) uw_buf);
 		}
+	
+		/* sample the state of the userspace window buffer */	
+		THREAD->arch.uspace_window_buffer = (uint8_t *) read_from_ag_g7();
 	}
 }
Index: kernel/arch/sparc64/src/trap/trap_table.S
===================================================================
--- kernel/arch/sparc64/src/trap/trap_table.S	(revision 0fa6044030c5c9175f76bf5a500b45f6f66598e6)
+++ kernel/arch/sparc64/src/trap/trap_table.S	(revision e11ae91fc3a4227bcea74717abb36d585ceb5627)
@@ -204,4 +204,16 @@
 	SPILL_NORMAL_HANDLER_KERNEL
 
+/* TT = 0x84, TL = 0, spill_1_normal handler */
+.org trap_table + TT_SPILL_1_NORMAL*ENTRY_SIZE
+.global spill_1_normal
+spill_1_normal:
+	SPILL_NORMAL_HANDLER_USERSPACE
+
+/* TT = 0x88, TL = 0, spill_2_normal handler */
+.org trap_table + TT_SPILL_2_NORMAL*ENTRY_SIZE
+.global spill_2_normal
+spill_2_normal:
+	SPILL_TO_USPACE_WINDOW_BUFFER
+
 /* TT = 0xc0, TL = 0, fill_0_normal handler */
 .org trap_table + TT_FILL_0_NORMAL*ENTRY_SIZE
@@ -210,4 +222,10 @@
 	FILL_NORMAL_HANDLER_KERNEL
 
+/* TT = 0xc4, TL = 0, fill_1_normal handler */
+.org trap_table + TT_FILL_1_NORMAL*ENTRY_SIZE
+.global fill_1_normal
+fill_1_normal:
+	FILL_NORMAL_HANDLER_USERSPACE
+
 /*
  * Handlers for TL>0.
@@ -267,4 +285,16 @@
 spill_0_normal_high:
 	SPILL_NORMAL_HANDLER_KERNEL
+
+/* TT = 0x88, TL > 0, spill_2_normal handler */
+.org trap_table + (TT_SPILL_2_NORMAL+512)*ENTRY_SIZE
+.global spill_2_normal_high
+spill_2_normal_high:
+	SPILL_TO_USPACE_WINDOW_BUFFER
+
+/* TT = 0xa0, TL > 0, spill_0_other handler */
+.org trap_table + (TT_SPILL_0_OTHER+512)*ENTRY_SIZE
+.global spill_0_other_high
+spill_0_other_high:
+	SPILL_TO_USPACE_WINDOW_BUFFER
 
 /* TT = 0xc0, TL > 0, fill_0_normal handler */
@@ -290,5 +320,5 @@
  * 	%g2	 	Argument for the function.
  *	%g6		Pre-set as kernel stack base if trap from userspace.
- *	%g7		Reserved.
+ *	%g7		Pre-set as address of the userspace window buffer.
  */
 .global preemptible_handler
Index: kernel/generic/include/config.h
===================================================================
--- kernel/generic/include/config.h	(revision 0fa6044030c5c9175f76bf5a500b45f6f66598e6)
+++ kernel/generic/include/config.h	(revision e11ae91fc3a4227bcea74717abb36d585ceb5627)
@@ -64,5 +64,5 @@
 	size_t kernel_size;		/**< Size of memory in bytes taken by kernel and stack */
 	
-	uintptr_t stack_base;	/**< Base adddress of initial stack */
+	uintptr_t stack_base;		/**< Base adddress of initial stack */
 	size_t stack_size;		/**< Size of initial stack */
 } config_t;
