Index: kernel/arch/sparc32/Makefile.inc
===================================================================
--- kernel/arch/sparc32/Makefile.inc	(revision 2955bb9354df3f00667b00860d6fd3f3bf41ae3f)
+++ kernel/arch/sparc32/Makefile.inc	(revision 382fb4baf834128321f258a0f8461ee068e40f55)
@@ -48,4 +48,5 @@
 	arch/$(KARCH)/src/context.S \
 	arch/$(KARCH)/src/debug/stacktrace.c \
+        arch/$(KARCH)/src/debug/stacktrace_asm.S \
 	arch/$(KARCH)/src/proc/scheduler.c \
 	arch/$(KARCH)/src/proc/task.c \
Index: kernel/arch/sparc32/include/arch/interrupt.h
===================================================================
--- kernel/arch/sparc32/include/arch/interrupt.h	(revision 2955bb9354df3f00667b00860d6fd3f3bf41ae3f)
+++ kernel/arch/sparc32/include/arch/interrupt.h	(revision 382fb4baf834128321f258a0f8461ee068e40f55)
@@ -39,5 +39,5 @@
 #include <arch/istate.h>
 
-#define IVT_ITEMS  0
+#define IVT_ITEMS  32
 #define IVT_FIRST  0
 
Index: kernel/arch/sparc32/include/arch/mm/page.h
===================================================================
--- kernel/arch/sparc32/include/arch/mm/page.h	(revision 2955bb9354df3f00667b00860d6fd3f3bf41ae3f)
+++ kernel/arch/sparc32/include/arch/mm/page.h	(revision 382fb4baf834128321f258a0f8461ee068e40f55)
@@ -37,4 +37,6 @@
 #define KERN_sparc32_PAGE_H_
 
+#ifndef __ASM__
+
 #include <arch/mm/frame.h>
 #include <trace.h>
@@ -268,4 +270,6 @@
 #endif
 
+#endif
+
 /** @}
  */
Index: kernel/arch/sparc32/src/debug/stacktrace.c
===================================================================
--- kernel/arch/sparc32/src/debug/stacktrace.c	(revision 2955bb9354df3f00667b00860d6fd3f3bf41ae3f)
+++ kernel/arch/sparc32/src/debug/stacktrace.c	(revision 382fb4baf834128321f258a0f8461ee068e40f55)
@@ -1,4 +1,5 @@
 /*
  * Copyright (c) 2010 Jakub Jermar
+ * Copyright (c) 2013 Jakub Klama
  * All rights reserved.
  *
@@ -27,5 +28,5 @@
  */
 
-/** @addtogroup abs32le
+/** @addtogroup sparc32
  * @{
  */
@@ -37,11 +38,30 @@
 #include <typedefs.h>
 
+#include <arch.h>
+#include <arch/stack.h>
+
+#define FRAME_OFFSET_FP_PREV	14
+#define FRAME_OFFSET_RA		15
+
+extern void alloc_window_and_flush(void);
+
 bool kernel_stack_trace_context_validate(stack_trace_context_t *ctx)
 {
-	return true;
+	uintptr_t kstack;
+        uint32_t l1, l2;
+	
+        read_from_invalid(&kstack, &l1, &l2);
+	kstack -= 128;
+
+	if (THREAD && (ctx->fp == kstack))
+		return false;
+	return ctx->fp != 0;
 }
 
 bool kernel_frame_pointer_prev(stack_trace_context_t *ctx, uintptr_t *prev)
 {
+	uint64_t *stack = (void *) ctx->fp;
+	alloc_window_and_flush();
+	*prev = stack[FRAME_OFFSET_FP_PREV];
 	return true;
 }
@@ -49,4 +69,7 @@
 bool kernel_return_address_get(stack_trace_context_t *ctx, uintptr_t *ra)
 {
+	uint64_t *stack = (void *) ctx->fp;
+	alloc_window_and_flush();
+	*ra = stack[FRAME_OFFSET_RA];
 	return true;
 }
@@ -54,25 +77,15 @@
 bool uspace_stack_trace_context_validate(stack_trace_context_t *ctx)
 {
-	return true;
+	return false;
 }
 
 bool uspace_frame_pointer_prev(stack_trace_context_t *ctx, uintptr_t *prev)
 {
-	return true;
+	return false;
 }
 
-bool uspace_return_address_get(stack_trace_context_t *ctx, uintptr_t *ra)
+bool uspace_return_address_get(stack_trace_context_t *ctx , uintptr_t *ra)
 {
-	return true;
-}
-
-uintptr_t frame_pointer_get(void)
-{
-	return 0;
-}
-
-uintptr_t program_counter_get(void)
-{
-	return 0;
+	return false;
 }
 
Index: kernel/arch/sparc32/src/mm/page.c
===================================================================
--- kernel/arch/sparc32/src/mm/page.c	(revision 2955bb9354df3f00667b00860d6fd3f3bf41ae3f)
+++ kernel/arch/sparc32/src/mm/page.c	(revision 382fb4baf834128321f258a0f8461ee068e40f55)
@@ -74,5 +74,5 @@
 	as_switch(NULL, AS_KERNEL);
 
-	printf("as_context_table=0x%08x\n", as_context_table);
+//	printf("as_context_table=0x%08x\n", as_context_table);
 
 	/* Switch MMU to new context table */
@@ -89,5 +89,5 @@
 	mmu_fault_type_t type = (mmu_fault_type_t)fault->at;
 
-	printf("page fault on address 0x%08x, status 0x%08x, type %d\n", fault_address, fault_status, type);
+//	printf("page fault on address 0x%08x, status 0x%08x, type %d\n", fault_address, fault_status, type);
 
 	if (type == FAULT_TYPE_LOAD_USER_DATA ||
@@ -101,5 +101,6 @@
 	if (type == FAULT_TYPE_STORE_USER_DATA ||
 	    type == FAULT_TYPE_STORE_USER_INSTRUCTION ||
-	    type == FAULT_TYPE_STORE_SUPERVISOR_INSTRUCTION)
+	    type == FAULT_TYPE_STORE_SUPERVISOR_INSTRUCTION ||
+	    type == FAULT_TYPE_STORE_SUPERVISOR_DATA)
 		as_page_fault(fault_address, PF_ACCESS_WRITE, istate);
 }
Index: kernel/arch/sparc32/src/proc/scheduler.c
===================================================================
--- kernel/arch/sparc32/src/proc/scheduler.c	(revision 2955bb9354df3f00667b00860d6fd3f3bf41ae3f)
+++ kernel/arch/sparc32/src/proc/scheduler.c	(revision 382fb4baf834128321f258a0f8461ee068e40f55)
@@ -44,5 +44,4 @@
 void before_thread_runs_arch(void)
 {
-	printf("before_thread_runs_arch(uspace=%d, kernel_sp=0x%08x\n", THREAD->uspace, (uintptr_t)THREAD->kstack + STACK_SIZE);
 	if (THREAD->uspace) {
 		uint32_t kernel_sp = (uint32_t) THREAD->kstack + STACK_SIZE - 8;
@@ -54,4 +53,11 @@
 void after_thread_ran_arch(void)
 {
+	if (THREAD->uspace) {
+		uint32_t kernel_sp;
+		uint32_t uspace_wbuf;
+		uint32_t l7;
+		read_from_invalid(&kernel_sp, &uspace_wbuf, &l7);
+		THREAD->arch.uspace_window_buffer = (uint8_t *)uspace_wbuf;
+	}
 }
 
Index: kernel/arch/sparc32/src/sparc32.c
===================================================================
--- kernel/arch/sparc32/src/sparc32.c	(revision 2955bb9354df3f00667b00860d6fd3f3bf41ae3f)
+++ kernel/arch/sparc32/src/sparc32.c	(revision 382fb4baf834128321f258a0f8461ee068e40f55)
@@ -165,5 +165,5 @@
 {
 	memcpy(dst, uspace_src, size);
-	return size;
+	return 1;
 }
 
@@ -171,5 +171,5 @@
 {
 	memcpy(uspace_dst, src, size);
-	return size;
+	return 1;
 }
 
Index: kernel/arch/sparc32/src/trap_table.S
===================================================================
--- kernel/arch/sparc32/src/trap_table.S	(revision 2955bb9354df3f00667b00860d6fd3f3bf41ae3f)
+++ kernel/arch/sparc32/src/trap_table.S	(revision 382fb4baf834128321f258a0f8461ee068e40f55)
@@ -279,5 +279,21 @@
 	restore
 	mov %g5, %wim
+
+	/* Check beginning of %sp */
 	and %g4, 0xfffff000, %l4
+	lda [%l4] 0x18, %l4
+	cmp %l4, 0
+	bne 1f
+	nop
+
+	/* prepare args for preemptible handler */
+	mov %g4, %o0
+	set preemptible_save_uspace, %o2
+	b preemptible_trap
+	nop
+
+	/* Check end of %sp */
+	add %g4, 56, %g4
+	and %l4, 0xfffff000, %l4
 	lda [%l4] 0x18, %l4
 	cmp %l4, 0
@@ -532,4 +548,52 @@
 	nop
 
+	/* Get UWB address */
+//	switch_to_invalid %g5, %g6
+//	mov %l6, %g1
+//	switch_back %g5, %g6
+
+#	/* Flush windows to stack */
+	call flush_windows
+	nop
+/*
+	get_wim_number %g2
+	get_cwp %g5
+	mov %psr, %g6
+
+	sub %g2, 1, %g4
+	and %g4, 0x7, %g4
+0:	mov %g0, %wim
+	cmp %g5, %g4
+	be 0f
+	nop
+
+	restore
+	add %g1, 64, %g1
+	std %l0, [%g1  + 0]
+	std %l2, [%g1 +  8]
+	std %l4, [%g1 + 16]
+	std %l6, [%g1 + 24]
+	std %i0, [%g1 + 32]
+	std %l2, [%g1 + 40]
+	std %l4, [%g1 + 48]
+	std %l6, [%g1 + 56]
+	inc %g5
+	and %g5, 0x7, %g5
+	ba 0b
+	nop
+
+0:	inc %g4
+	and %g4, 0x7, %g4
+	clr %g5
+	inc %g5
+	sll %g5, %g4, %g5
+
+	* Write values to invalid window and switch back *
+	mov %g7, %l5
+	mov %g1, %l6
+	clr %l7
+	switch_back %g5, %g6
+*/
+
 	/* Jump to actual subroutine */
 	call %o2
@@ -548,5 +612,5 @@
 
 	/* If trap originated from uspace, clear uspace window mark and save uwb address for future use */
-	if_from_kernel 6f
+	if_from_kernel 9f
 	switch_to_invalid %g5, %g6
 	clr %l7
@@ -594,107 +658,25 @@
 	switch_back %g5, %g6
 
-	/* If next window is invalid, do inline restore */
-6:	get_wim_number %g6
-	get_cwp %g7
-	inc %g7
-	and %g7, 0x7, %g7
-	cmp %g6, %g7
-	bne 8f
-
-	if_from_kernel 7f
-
-	inline_restore_uspace %g1
-	switch_to_invalid %g5, %g6
-	mov %g1, %l6
-	switch_back %g5, %g6
-	b 8f
-	nop
-
-7:	inline_restore_kernel
-
-8:	ld [%sp + 104], %g1
+	mov %sp, %l3
+	sub %g2, 128, %sp
+	ld [%sp + 104], %g1
 	ld [%sp + 108], %g2
 	ld [%sp + 112], %g3
 	ld [%sp + 116], %g4
 	ld [%sp + 120], %g7
-	jmp %l1
+	mov %l3, %sp
+	b 10f
+	nop
+
+9:	ld [%sp + 104], %g1
+	ld [%sp + 108], %g2
+	ld [%sp + 112], %g3
+	ld [%sp + 116], %g4
+	ld [%sp + 120], %g7
+
+10:	jmp %l1
 	rett %l2
 
 interrupt_trap:
-	mov %psr, %l0
-
-	/* Check whether previous mode was usermode */
-	and %l0, (1 << 6), %l0
-	cmp %l0, 0
-	bne 1f
-	nop
-
-	/* Set up stack */
-	set kernel_sp, %l4
-	ld [%l4], %sp
-	mov %sp, %fp
-1:	sub %sp, 112, %sp
-
-	/* Save trap data on stack */
-	mov %psr, %l0
-	st %l1, [%fp - 4]
-	st %l2, [%fp - 8]
-	st %l0, [%fp - 12]
-
-	/* Enable traps */
-	mov %psr, %l0
-	or %l0, (1 << 5), %l0
-	mov %l0, %psr
-	nop
-	nop
-	nop
-	nop
-
-	/* Jump to actual subroutine */
-	mov %g2, %o0
-	call exc_dispatch
-	sub %fp, 12, %o1
-
-	/* Return from handler */
-	ld [%fp - 4], %l1
-	ld [%fp - 8], %l2
-	ld [%fp - 12], %l0
-	mov %l0, %psr
-	nop
-	nop
-	nop
-	nop
-	nop
-
-	/* If trap originated from uspace, clear uspace window mark and save uwb address for future use */
-	if_from_kernel 6f
-	switch_to_invalid %g5, %g6
-	clr %l7
-	mov %l6, %g7
-	switch_back %g5, %g6
-	mov %g7, %g1
-
-	/* If next window is invalid, do inline restore */
-6:	get_wim_number %g6
-	get_cwp %g7
-	inc %g7
-	cmp %g6, %g7
-	bne 8f
-
-	if_from_kernel 7f
-
-	inline_restore_uspace %g1
-	switch_to_invalid %g5, %g6
-	mov %g1, %l6
-	switch_back %g5, %g6
-	b 8f
-	nop
-
-7:	inline_restore_kernel
-
-8:	jmp %l1
-	rett %l2
-
-syscall_trap:
 	/* Save %g7 */
 	mov %g7, %l0
@@ -766,14 +748,12 @@
 	nop
 
+	/* Flush windows to stack */
+	call flush_windows
+	nop
+
 	/* Jump to actual subroutine */
-	sub %o0, 0x80, %o0
-	st %o0, [ %sp + 92 ]
-	mov %i0, %o0
-	mov %i1, %o1
-	mov %i2, %o2
-	mov %i3, %o3
-	mov %i4, %o4
-	call syscall
-	mov %i5, %o5
+	mov %g2, %o0
+	call exc_dispatch
+	add %sp, 128, %o1
 
 	/* Return from handler */
@@ -781,9 +761,4 @@
 	ld [%sp + 96], %l2
 	ld [%sp + 100], %l0
-	mov %o0, %i0
-	mov %psr, %l1
-	and %l1, 0xf, %l1
-	and %l0, 0xfffffff0, %l0
-	or %l0, %l1, %l0
 	mov %l0, %psr
 	nop
@@ -864,4 +839,163 @@
 	ld [%sp + 116], %g4
 	ld [%sp + 120], %g7
+	jmp %l1
+	rett %l2
+
+
+syscall_trap:
+	/* Save %g7 */
+	mov %g7, %l0
+
+	/* Check whether we landed in invalid window */
+	get_wim_number %g6
+	get_cwp %g7
+	cmp %g6, %g7
+	bne 4f
+	nop
+
+	/* We are in invalid window. Check whether previous mode was usermode */
+	if_from_kernel 3f
+
+	/* Trap originated from uspace */
+	/* Kernel stack pointer is at %l5, uwb is at %l6 */
+	inline_save_uspace %l6
+
+	/* set uspace window mark */
+	mov %psr, %l7
+	inc %l7
+	and %l7, 0x7, %l7
+	or %l7, 0x10, %l7
+	b 4f
+	nop
+
+3:	/* Trap originated from kernel */
+	inline_save_kernel 
+
+4:	/* Check whether previous mode was usermode */
+	if_from_kernel 5f
+
+	/* Load kernel stack pointer from invalid window */
+	switch_to_invalid %g5, %g6
+
+	/* set uspace window mark */
+	mov %g6, %l7
+	inc %l7
+	and %l7, 0x7, %l7
+	or %l7, 0x10, %l7
+
+	/* Save stack pointer */
+	mov %l5, %g7
+	switch_back %g5, %g6
+	mov %g7, %sp
+//	mov %sp, %fp
+
+5:	/* Set up stack frame */
+	sub %sp, 128, %sp
+
+	/* Save trap data on stack */
+	mov %psr, %l5
+	st %l1, [%sp + 92]
+	st %l2, [%sp + 96]
+	st %l5, [%sp + 100]
+	st %g1, [%sp + 104]
+	st %g2, [%sp + 108]
+	st %g3, [%sp + 112]
+	st %g4, [%sp + 116]
+	st %l0, [%sp + 120]
+
+	/* Enable traps */
+	mov %psr, %l0
+	or %l0, (1 << 5), %l0
+	mov %l0, %psr
+	nop
+	nop
+	nop
+	nop
+
+	/* Flush windows */
+	call flush_windows
+	nop
+
+	/* Jump to actual subroutine */
+	sub %o0, 0x80, %o0
+	st %o0, [ %sp + 92 ]
+	mov %i0, %o0
+	mov %i1, %o1
+	mov %i2, %o2
+	mov %i3, %o3
+	mov %i4, %o4
+	call syscall
+	mov %i5, %o5
+
+	/* Return from handler */
+	ld [%sp + 92], %l1
+	ld [%sp + 96], %l2
+	ld [%sp + 100], %l0
+	mov %o0, %i0
+	mov %psr, %l1
+	and %l1, 0xf, %l1
+	and %l0, 0xfffffff0, %l0
+	or %l0, %l1, %l0
+	mov %l0, %psr
+	nop
+	nop
+	nop
+	nop
+	nop
+
+	/* If trap originated from uspace, clear uspace window mark and save uwb address for future use */
+	if_from_kernel 8f
+	switch_to_invalid %g5, %g6
+	mov %l5, %g2
+	mov %l6, %g1
+	mov %l7, %g7
+	switch_back %g5, %g6
+	
+	/* If trap originated from uspace, restore all windows from UWB */
+	/* UWB pointer is at %g1 */
+0:	mov %g0, %wim
+	clr %g5
+	andcc %g1, UWB_ALIGNMENT - 1, %g0
+	bz 0f
+	nop
+
+	restore
+	sub %g1, 64, %g1
+	ldd [%g1 +  0], %l0
+	ldd [%g1 +  8], %l2
+	ldd [%g1 + 16], %l4
+	ldd [%g1 + 24], %l6
+	ldd [%g1 + 32], %i0
+	ldd [%g1 + 40], %i2
+	ldd [%g1 + 48], %i4
+	ldd [%g1 + 56], %i6
+	inc %g5
+	and %g5, 0x7, %g5
+	ba 0b
+	nop
+
+	/* We've restored all uspace windows. Now time to
+	 * fix CWP and WIM
+	 */
+0:	restore
+	get_cwp %g7
+	clr %g5
+	inc %g5
+	sll %g5, %g7, %g5
+
+	/* Write values to invalid window and switch back */
+	mov %g2, %l5
+	mov %g1, %l6
+	clr %l7
+	switch_back %g5, %g6
+
+8:	mov %sp, %l1
+	sub %g2, 128, %sp
+	ld [%sp + 104], %g1
+	ld [%sp + 108], %g2
+	ld [%sp + 112], %g3
+	ld [%sp + 116], %g4
+	ld [%sp + 120], %g7
+	mov %l1, %sp
 	jmp %l2
 	rett %l2 + 4
