Index: kernel/arch/sparc32/include/arch/arch.h
===================================================================
--- kernel/arch/sparc32/include/arch/arch.h	(revision d78314585b84d27c6872ccb1a4322113515b7907)
+++ kernel/arch/sparc32/include/arch/arch.h	(revision 817d939a2821130ad692b3cdf9c705fefb2b3f0b)
@@ -72,8 +72,6 @@
 } bootinfo_t;
 
-extern uintptr_t kernel_sp;
-extern uintptr_t uspace_wbuf;
-
 extern void arch_pre_main(void *unused, bootinfo_t *bootinfo);
+extern void write_to_invalid(uint32_t l0, uint32_t l1, uint32_t l2);
 
 #endif
Index: kernel/arch/sparc32/src/mm/frame.c
===================================================================
--- kernel/arch/sparc32/src/mm/frame.c	(revision d78314585b84d27c6872ccb1a4322113515b7907)
+++ kernel/arch/sparc32/src/mm/frame.c	(revision 817d939a2821130ad692b3cdf9c705fefb2b3f0b)
@@ -46,7 +46,5 @@
 	size_t size;
 
-	//machine_get_memory_extents(&base, &size);
-	base = 0x40000000;
-	size = 0x4000000;
+	machine_get_memory_extents(&base, &size);
 
 	base = ALIGN_UP(base, FRAME_SIZE);
Index: kernel/arch/sparc32/src/mm/page.c
===================================================================
--- kernel/arch/sparc32/src/mm/page.c	(revision d78314585b84d27c6872ccb1a4322113515b7907)
+++ kernel/arch/sparc32/src/mm/page.c	(revision 817d939a2821130ad692b3cdf9c705fefb2b3f0b)
@@ -91,11 +91,15 @@
 	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 || type == FAULT_TYPE_LOAD_SUPERVISOR_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 || type == FAULT_TYPE_EXECUTE_SUPERVISOR)
+	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 || type == FAULT_TYPE_STORE_SUPERVISOR_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/proc/scheduler.c
===================================================================
--- kernel/arch/sparc32/src/proc/scheduler.c	(revision d78314585b84d27c6872ccb1a4322113515b7907)
+++ kernel/arch/sparc32/src/proc/scheduler.c	(revision 817d939a2821130ad692b3cdf9c705fefb2b3f0b)
@@ -44,6 +44,7 @@
 void before_thread_runs_arch(void)
 {
-	kernel_sp = (uintptr_t) THREAD->kstack + STACK_SIZE;
-	uspace_wbuf = (uintptr_t) THREAD->arch.uspace_window_buffer;
+	uint32_t kernel_sp = (uint32_t) THREAD->kstack + STACK_SIZE;
+	uint32_t uspace_wbuf = (uint32_t) THREAD->arch.uspace_window_buffer;
+	write_to_invalid(kernel_sp, uspace_wbuf, 0xdeadbeef);
 }
 
Index: kernel/arch/sparc32/src/sparc32.c
===================================================================
--- kernel/arch/sparc32/src/sparc32.c	(revision d78314585b84d27c6872ccb1a4322113515b7907)
+++ kernel/arch/sparc32/src/sparc32.c	(revision 817d939a2821130ad692b3cdf9c705fefb2b3f0b)
@@ -37,4 +37,5 @@
 #include <arch/interrupt.h>
 #include <arch/asm.h>
+#include <arch/machine_func.h>
 
 #include <func.h>
@@ -55,9 +56,11 @@
 char memcpy_from_uspace_failover_address;
 char memcpy_to_uspace_failover_address;
+bootinfo_t machine_bootinfo;
 
 void arch_pre_main(void *unused, bootinfo_t *bootinfo)
 {
 	init.cnt = min3(bootinfo->cnt, TASKMAP_MAX_RECORDS, CONFIG_INIT_TASKS);
-	
+	memcpy(&machine_bootinfo, bootinfo, sizeof(machine_bootinfo));
+
 	size_t i;
 	for (i = 0; i < init.cnt; i++) {
@@ -67,4 +70,6 @@
 		    bootinfo->tasks[i].name);
 	}
+
+	machine_ops_init();
 }
 
@@ -75,12 +80,17 @@
 void arch_post_mm_init(void)
 {
+	machine_init(&machine_bootinfo);
+
 	if (config.cpu_active == 1) {
 		/* Initialize IRQ routing */
-		irq_init(0, 0);
+		irq_init(16, 16);
 		
 		/* Merge all memory zones to 1 big zone */
 		zone_merge_all();
 	}
+
+	machine_output_init();
 }
+
 
 void arch_post_cpu_init()
@@ -94,4 +104,5 @@
 void arch_post_smp_init(void)
 {
+	machine_input_init();
 }
 
Index: kernel/arch/sparc32/src/trap_table.S
===================================================================
--- kernel/arch/sparc32/src/trap_table.S	(revision d78314585b84d27c6872ccb1a4322113515b7907)
+++ kernel/arch/sparc32/src/trap_table.S	(revision 817d939a2821130ad692b3cdf9c705fefb2b3f0b)
@@ -34,7 +34,124 @@
 .global reset_trap
 .global preemptible_trap
+.global interrupt_trap
 .global syscall_trap
 .global window_overflow_trap
 .global window_underflow_trap
+.global write_to_invalid
+
+.macro get_wim_number reg
+	clr \reg
+	mov %wim, %g5
+1:	inc \reg
+	srl %g5, 1, %g5
+	andcc %g5, 1, %g0
+	bne 1b
+	nop
+.endm
+
+.macro get_cwp reg
+	mov %psr, \reg
+	and \reg, 0x7, \reg
+.endm
+
+.macro switch_to_invalid saved_wim, saved_psr
+	get_wim_number %g6
+	mov %wim, \saved_wim	! save WIM
+	mov %g0, %wim		! clear WIM
+	mov %psr, \saved_psr	! read PSR
+	or \saved_psr, %g6, %g6	! set CWP
+	mov %g6, %psr		! write PSR
+	nop
+	nop
+	nop
+	nop			! wait for PSR to be effective
+.endm	
+
+.macro switch_back wim, psr
+	mov \wim, %wim		! saved WIM
+	mov \psr, %psr		! saved PSR
+	nop
+	nop
+	nop
+	nop
+.endm
+
+/* Save next window to kernel stack or UWB */
+.macro inline_save_kernel
+	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]
+	restore
+.endm
+
+.macro inline_save_uspace uwb
+	save
+	ld [\uwb], %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 \uwb, 64, \uwb
+	restore
+.endm
+
+/* Restore window from kernel stack or UWB */
+.macro inline_restore_kernel
+	save
+        ldd [%sp +  0], %l0
+        ldd [%sp +  8], %l2
+        ldd [%sp + 16], %l4
+        ldd [%sp + 24], %l6
+        ldd [%sp + 32], %i0
+        ldd [%sp + 40], %i2
+        ldd [%sp + 48], %i4
+        ldd [%sp + 56], %i6
+	restore
+.endm
+
+.macro inline_restore_uspace uwb
+	save
+	ld [\uwb], %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]
+	sub \uwb, 64, \uwb
+	restore
+.endm
+
+.macro if_from_kernel label
+	mov %psr, %g2
+	and %g2, (1 << 6), %g2
+	cmp %g2, 0
+	bne \label
+	nop
+.endm
+
+write_to_invalid:
+	mov %o0, %g5
+	mov %o1, %g6
+	mov %o2, %g7
+	switch_to_invalid %g3, %g4
+	mov %g5, %l5
+	mov %g6, %l6
+	mov %g7, %l7
+	switch_back %g3, %g4
+	retl
+	nop
 
 reset_trap:
@@ -62,4 +179,9 @@
 	beq 1f
 	nop
+
+	/* Save invalid window data */
+	mov %l5, %g5		! kernel stack pointer
+	mov %l6, %g6		! kernel wbuf
+	mov %l7, %g7
 
 	/* dump registers to stack */
@@ -78,19 +200,19 @@
 	/* 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
+	std %l0, [%g4 +  0]
+	std %l2, [%g4 +  8]
+	std %l4, [%g4 + 16]
+	std %l6, [%g4 + 24]
+	std %i0, [%g4 + 32]
+	std %i2, [%g4 + 40]
+	std %i4, [%g4 + 48]
+	std %i6, [%g4 + 56]
+	add %g4, 64, %g4
+
+2:	/* back to where we should be */
+	mov %g5, %l5
+	mov %g6, %l6
+	mov %g7, %l7
+	restore
 
 	/* set new value of window */
@@ -120,4 +242,9 @@
 	beq 1f
 	nop
+
+	/* Save invalid window data */
+	mov %l5, %g5		! kernel stack pointer
+	mov %l6, %g6		! kernel wbuf
+	mov %l7, %g7
 
         /* load registers from stack */
@@ -151,6 +278,9 @@
 	st %g1, [%g2]
 
-        /* back to where we should be */
-2:	save
+2:	/* back to where we should be */
+	mov %g5, %l5
+	mov %g6, %l6
+	mov %g7, %l7
+	save
 	save
 
@@ -164,4 +294,62 @@
 
 preemptible_trap:
+	/* 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
+
+	/* Kernel stack pointer is at %l5, uwb is at %l6 */
+	inline_save_uspace %l6
+3:	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
+	mov %l5, %g7		! stack pointer
+	switch_back %g5, %g6
+	mov %g7, %sp
+	mov %sp, %fp
+5:	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 */
+	call %o2
+	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
+	jmp %l1
+	rett %l2
+
+interrupt_trap:
 	mov %psr, %l0
 
@@ -195,5 +383,5 @@
 	/* Jump to actual subroutine */
 	mov %g2, %o0
-	call %g1
+	call exc_dispatch
 	sub %fp, 12, %o1
 
@@ -268,8 +456,8 @@
 #define	TRAP(_vector, _handler) \
 	.org trap_table + _vector * TRAP_ENTRY_SIZE; \
-	set _vector, %g2 ; \
-	sethi %hi(_handler), %g1 ; \
+	set _vector, %o0 ; \
+	sethi %hi(_handler), %o2 ; \
 	b preemptible_trap ; \
-	or %g1, %lo(_handler), %g1 ;
+	or %o2, %lo(_handler), %o2 ;
 
 #define	SYSCALL(_vector) \
@@ -283,5 +471,5 @@
 	mov %psr, %l0 ; \
 	mov _priority, %g2 ; \
-	call exc_dispatch ; \
+	b interrupt_trap ; \
 	nop ;
 
@@ -292,5 +480,5 @@
 .align TRAP_TABLE_SIZE
 trap_table:
-	TRAP(0x0, reset_trap)
+	STRAP(0x0, reset_trap)
 	TRAP(0x1, instruction_access_exception)
 	TRAP(0x2, illegal_instruction)
