Index: kernel/arch/sparc32/include/arch/exception.h
===================================================================
--- kernel/arch/sparc32/include/arch/exception.h	(revision e76fed96517738d2f3284f47ca00c2237183ff11)
+++ kernel/arch/sparc32/include/arch/exception.h	(revision 13c94f72bf34f8a9e3b97905dfe64392001645d6)
@@ -67,4 +67,5 @@
 extern void data_store_error(int n, istate_t *istate);
 extern void mem_address_not_aligned(int n, istate_t *istate);
+extern void syscall(sysarg_t a1, sysarg_t a2, sysarg_t a3, sysarg_t a4, sysarg_t a5, sysarg_t a6, sysarg_t id);
 
 #endif /* !__ASM__ */
Index: kernel/arch/sparc32/src/exception.c
===================================================================
--- kernel/arch/sparc32/src/exception.c	(revision e76fed96517738d2f3284f47ca00c2237183ff11)
+++ kernel/arch/sparc32/src/exception.c	(revision 13c94f72bf34f8a9e3b97905dfe64392001645d6)
@@ -39,4 +39,5 @@
 #include <arch/istate.h>
 #include <arch/exception.h>
+#include <syscall/syscall.h>
 #include <interrupt.h>
 #include <arch/asm.h>
@@ -139,4 +140,10 @@
 }
 
+void syscall(sysarg_t a1, sysarg_t a2, sysarg_t a3, sysarg_t a4, sysarg_t a5, sysarg_t a6, sysarg_t id)
+{
+	printf("syscall %d\n", id);
+	syscall_handler(a1, a2, a3, a4, a5, a6, id);
+}
+
 /** @}
  */
Index: kernel/arch/sparc32/src/mm/page.c
===================================================================
--- kernel/arch/sparc32/src/mm/page.c	(revision e76fed96517738d2f3284f47ca00c2237183ff11)
+++ kernel/arch/sparc32/src/mm/page.c	(revision 13c94f72bf34f8a9e3b97905dfe64392001645d6)
@@ -87,15 +87,15 @@
 	uintptr_t fault_address = asi_u32_read(ASI_MMUREGS, MMU_FAULT_ADDRESS);
 	mmu_fault_status_t *fault = (mmu_fault_status_t *)&fault_status;
-	mmu_fault_type_t type = (mmu_fault_type_t)fault->ft;
+	mmu_fault_type_t type = (mmu_fault_type_t)fault->at;
 
-	printf("page fault on address 0x%08x, status 0x%08x\n", fault_address, fault_status);
+	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)	
+	if (type == FAULT_TYPE_LOAD_USER_DATA || type == FAULT_TYPE_LOAD_SUPERVISOR_DATA)	
 		as_page_fault(fault_address, PF_ACCESS_READ, istate);
 
-	if (type == FAULT_TYPE_EXECUTE_USER)
+	if (type == FAULT_TYPE_EXECUTE_USER || type == FAULT_TYPE_EXECUTE_SUPERVISOR)
 		as_page_fault(fault_address, PF_ACCESS_EXEC, istate);
 
-	if (type == FAULT_TYPE_STORE_USER_DATA || type == FAULT_TYPE_STORE_USER_INSTRUCTION)
+	if (type == FAULT_TYPE_STORE_USER_DATA || type == FAULT_TYPE_STORE_USER_INSTRUCTION || type == FAULT_TYPE_STORE_SUPERVISOR_INSTRUCTION)
 		as_page_fault(fault_address, PF_ACCESS_WRITE, istate);
 }
Index: kernel/arch/sparc32/src/trap_table.S
===================================================================
--- kernel/arch/sparc32/src/trap_table.S	(revision e76fed96517738d2f3284f47ca00c2237183ff11)
+++ kernel/arch/sparc32/src/trap_table.S	(revision 13c94f72bf34f8a9e3b97905dfe64392001645d6)
@@ -34,4 +34,5 @@
 .global reset_trap
 .global preemptible_trap
+.global syscall_trap
 .global window_overflow_trap
 .global window_underflow_trap
@@ -44,38 +45,60 @@
 
 window_overflow_trap:
-        /* rotate WIM on bit right, we have 8 windows */
-        mov %wim,%l3
-        sll %l3,7,%l4
-        srl %l3,1,%l3
-        or  %l3,%l4,%l3
-        and %l3,0xff,%l3
-
-        /* disable WIM traps */
-        mov %g0,%wim
-        nop; nop; nop
-
-        /* point to correct window */
-        save
-
-        /* dump registers to stack */
-        std %l0, [%sp +  0]
-        std %l2, [%sp +  8]
-        std %l4, [%sp + 16]
-        std %l6, [%sp + 24]
-        std %i0, [%sp + 32]
-        std %i2, [%sp + 40]
-        std %i4, [%sp + 48]
-        std %i6, [%sp + 56]
-
-        /* back to where we should be */
-        restore
-
-        /* set new value of window */
-        mov %l3,%wim
-        nop; nop; nop
-
-        /* go home */
-        jmp %l1
-        rett %l2
+	/* rotate WIM on bit right, we have 8 windows */
+	mov %wim, %l3
+	sll %l3, 7, %l4
+	srl %l3, 1, %l3
+	or  %l3, %l4, %l3
+	and %l3, 0xff, %l3
+
+	/* disable WIM traps */
+	mov %g0,%wim
+	nop; nop; nop
+
+	/* Check whether previous mode was usermode */
+	mov %psr, %l0
+	and %l0, (1 << 6), %l0
+	cmp %l0, 0
+	beq 1f
+	nop
+
+	/* dump registers to stack */
+	save
+	std %l0, [%sp +  0]
+	std %l2, [%sp +  8]
+	std %l4, [%sp + 16]
+	std %l6, [%sp + 24]
+	std %i0, [%sp + 32]
+	std %i2, [%sp + 40]
+	std %i4, [%sp + 48]
+	std %i6, [%sp + 56]
+	b 2f
+	nop
+
+	/* dump registers to uwb */
+1:	save
+	set uspace_wbuf, %g2
+	ld [%g1], %g1
+	std %l0, [%g1 +  0]
+	std %l2, [%g1 +  8]
+	std %l4, [%g1 + 16]
+	std %l6, [%g1 + 24]
+	std %i0, [%g1 + 32]
+	std %i2, [%g1 + 40]
+	std %i4, [%g1 + 48]
+	std %i6, [%g1 + 56]
+	add %g1, 64, %g1
+	st %g1, [%g2]
+
+	/* back to where we should be */
+2:	restore
+
+	/* set new value of window */
+	mov %l3,%wim
+	nop; nop; nop
+
+	/* go home */
+	jmp %l1
+	rett %l2
 
 window_underflow_trap:
@@ -91,9 +114,14 @@
         nop; nop; nop
 
-        /* point to correct window */
-        restore
-        restore
-
-        /* dump registers to stack */
+	/* Check whether previous mode was usermode */
+	mov %psr, %l0
+	and %l0, (1 << 6), %l0
+	cmp %l0, 0
+	beq 1f
+	nop
+
+        /* load registers from stack */
+	restore
+	restore
         ldd [%sp +  0], %l0
         ldd [%sp +  8], %l2
@@ -104,8 +132,26 @@
         ldd [%sp + 48], %i4
         ldd [%sp + 56], %i6
+	b 2f
+	nop
+
+	/* load registers from uwb */
+1:	restore
+	restore
+	set uspace_wbuf, %g2
+	ld [%g2], %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
+	sub %g1, 64, %g1
+	st %g1, [%g2]
 
         /* back to where we should be */
-        save
-        save
+2:	save
+	save
 
         /* set new value of window */
@@ -118,8 +164,5 @@
 
 preemptible_trap:
-	/* Enable traps */
-	mov %psr, %l0
-	or %l0, (1 << 5), %l0
-	mov %l0, %psr
+	mov %psr, %l0
 
 	/* Check whether previous mode was usermode */
@@ -136,11 +179,21 @@
 
 	/* 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 1, %o0
-	jmp %g1
+	mov %g2, %o0
+	call %g1
 	sub %fp, 12, %o1
 
@@ -148,6 +201,61 @@
 	ld [%fp - 4], %l1
 	ld [%fp - 8], %l2
+	ld [%fp - 12], %l0
+	mov %l0, %psr
+	nop
+	nop
+	nop
+	nop
+	nop
 	jmp %l1
 	rett %l2
+
+syscall_trap:
+	mov %psr, %l0
+
+	/* Set up stack */
+	set kernel_sp, %l4
+	ld [%l4], %sp
+	mov %sp, %fp
+	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 */
+	sub %g2, 0x80, %g2
+	st %g2, [ %sp + 92 ]
+	mov %i0, %o1
+	mov %i1, %o1
+	mov %i2, %o2
+	mov %i3, %o3
+	mov %i4, %o4
+	call syscall
+	mov %i5, %o5
+
+	/* Return from handler */
+	ld [%fp - 4], %l1
+	ld [%fp - 8], %l2
+	ld [%fp - 12], %l0
+	mov %l0, %psr
+	nop
+	nop
+	nop
+	nop
+	nop
+	jmp %l2
+	rett %l2 + 4
 
 #define	STRAP(_vector, _handler) \
@@ -160,7 +268,14 @@
 #define	TRAP(_vector, _handler) \
 	.org trap_table + _vector * TRAP_ENTRY_SIZE; \
+	set _vector, %g2 ; \
 	sethi %hi(_handler), %g1 ; \
 	b preemptible_trap ; \
 	or %g1, %lo(_handler), %g1 ;
+
+#define	SYSCALL(_vector) \
+	.org trap_table + _vector * TRAP_ENTRY_SIZE; \
+	set _vector, %g2 ; \
+	b syscall_trap ; \
+	nop ;
 
 #define	INTERRUPT(_vector, _priority) \
@@ -304,3 +419,44 @@
 	BADTRAP(0x7e)
 	BADTRAP(0x7f)
-
+	SYSCALL(0x80)
+	SYSCALL(0x81)
+	SYSCALL(0x82)
+	SYSCALL(0x83)
+	SYSCALL(0x84)
+	SYSCALL(0x85)
+	SYSCALL(0x86)
+	SYSCALL(0x87)
+	SYSCALL(0x88)
+	SYSCALL(0x89)
+	SYSCALL(0x8a)
+	SYSCALL(0x8b)
+	SYSCALL(0x8c)
+	SYSCALL(0x8d)
+	SYSCALL(0x8e)
+	SYSCALL(0x8f)
+	SYSCALL(0x90)
+	SYSCALL(0x91)
+	SYSCALL(0x92)
+	SYSCALL(0x93)
+	SYSCALL(0x94)
+	SYSCALL(0x95)
+	SYSCALL(0x96)
+	SYSCALL(0x97)
+	SYSCALL(0x98)
+	SYSCALL(0x99)
+	SYSCALL(0x9a)
+	SYSCALL(0x9b)
+	SYSCALL(0x9c)
+	SYSCALL(0x9d)
+	SYSCALL(0x9e)
+	SYSCALL(0x9f)
+	SYSCALL(0xa0)
+	SYSCALL(0xa1)
+	SYSCALL(0xa2)
+	SYSCALL(0xa3)
+	SYSCALL(0xa4)
+	SYSCALL(0xa5)
+	SYSCALL(0xa6)
+	SYSCALL(0xa7)
+	SYSCALL(0xa8)
+	SYSCALL(0xa9)
Index: kernel/arch/sparc32/src/userspace.c
===================================================================
--- kernel/arch/sparc32/src/userspace.c	(revision e76fed96517738d2f3284f47ca00c2237183ff11)
+++ kernel/arch/sparc32/src/userspace.c	(revision 13c94f72bf34f8a9e3b97905dfe64392001645d6)
@@ -53,8 +53,6 @@
 	asm volatile (
 		"mov %[stack], %%sp\n"
-		"mov %[psr], %%psr\n"
-		"nop\n"
 		"jmp %[entry]\n"
-		"nop\n" :: [entry] "r" (kernel_uarg->uspace_entry),
+		"mov %[psr], %%psr\n" :: [entry] "r" (kernel_uarg->uspace_entry),
 			   [psr] "r" (psr),
 			   [stack] "r" (kernel_uarg->uspace_stack + kernel_uarg->uspace_stack_size));
