Index: arch/ia64/Makefile.inc
===================================================================
--- arch/ia64/Makefile.inc	(revision cd373bbb5fd51ad3198655cb712d3d11734ee5e1)
+++ arch/ia64/Makefile.inc	(revision b994a60c2699d4cf29d9c28497e8256a75eb2a1c)
@@ -39,7 +39,12 @@
 #
 
+INIT_ADDRESS = 0xe000000000400000
+INIT_SIZE = 0x100000
+
 CFLAGS += -mconstant-gp -fno-unwind-tables
 LFLAGS += -EL
 AFLAGS += -mconstant-gp
+
+DEFS += -DINIT_ADDRESS=$(INIT_ADDRESS) -DINIT_SIZE=$(INIT_SIZE)
 
 ## Compile with page hash table support.
Index: arch/ia64/include/asm.h
===================================================================
--- arch/ia64/include/asm.h	(revision cd373bbb5fd51ad3198655cb712d3d11734ee5e1)
+++ arch/ia64/include/asm.h	(revision b994a60c2699d4cf29d9c28497e8256a75eb2a1c)
@@ -49,4 +49,17 @@
 }
 
+/** Return Processor State Register.
+ *
+ * @return PSR.
+ */
+static inline __u64 psr_read(void)
+{
+	__u64 v;
+	
+	__asm__ volatile ("mov %0 = psr\n" : "=r" (v));
+	
+	return v;
+}
+
 /** Read IVA (Interruption Vector Address).
  *
@@ -233,9 +246,5 @@
 static inline ipl_t interrupts_read(void)
 {
-	__u64 v;
-	
-	__asm__ volatile ("mov %0 = psr\n" : "=r" (v));
-	
-	return (ipl_t) v;
+	return (ipl_t) psr_read();
 }
 
@@ -250,3 +259,5 @@
 extern void asm_delay_loop(__u32 t);
 
+extern void switch_to_userspace(__address entry, __address sp, __address bsp, __u64 ipsr, __u64 rsc);
+
 #endif
Index: arch/ia64/include/context.h
===================================================================
--- arch/ia64/include/context.h	(revision cd373bbb5fd51ad3198655cb712d3d11734ee5e1)
+++ arch/ia64/include/context.h	(revision b994a60c2699d4cf29d9c28497e8256a75eb2a1c)
@@ -31,4 +31,5 @@
 
 #include <arch/types.h>
+#include <arch/register.h>
 #include <typedefs.h>
 #include <align.h>
@@ -42,6 +43,4 @@
  */
 #define SP_DELTA	(0+ALIGN_UP(STACK_ITEM_SIZE, STACK_ALIGNMENT))
-
-#define PFM_MASK	(~0x3fffffffff)
 
 #ifdef context_set
Index: arch/ia64/include/mm/as.h
===================================================================
--- arch/ia64/include/mm/as.h	(revision cd373bbb5fd51ad3198655cb712d3d11734ee5e1)
+++ arch/ia64/include/mm/as.h	(revision b994a60c2699d4cf29d9c28497e8256a75eb2a1c)
@@ -32,12 +32,12 @@
 #include <arch/types.h>
 
-#define KERNEL_ADDRESS_SPACE_START_ARCH		(__address) 0x8000000000000000
-#define KERNEL_ADDRESS_SPACE_END_ARCH		(__address) 0xffffffffffffffff
-#define USER_ADDRESS_SPACE_START_ARCH		(__address) 0x0000000000000000
-#define USER_ADDRESS_SPACE_END_ARCH		(__address) 0x7fffffffffffffff
+#define KERNEL_ADDRESS_SPACE_START_ARCH		(__address) 0xe000000000000000ULL
+#define KERNEL_ADDRESS_SPACE_END_ARCH		(__address) 0xffffffffffffffffULL
+#define USER_ADDRESS_SPACE_START_ARCH		(__address) 0x0000000000000000ULL
+#define USER_ADDRESS_SPACE_END_ARCH		(__address) 0xdfffffffffffffffULL
 
-#define UTEXT_ADDRESS_ARCH	0x0000000000001000
-#define USTACK_ADDRESS_ARCH	(0x7fffffffffffffff-(PAGE_SIZE-1))
-#define UDATA_ADDRESS_ARCH	0x0000000001001000
+#define UTEXT_ADDRESS_ARCH	0x0000000000010000ULL
+#define USTACK_ADDRESS_ARCH	0x0000000ff0000000ULL
+#define UDATA_ADDRESS_ARCH	0x0000000001010000ULL
 
 extern void as_arch_init(void);
Index: arch/ia64/include/register.h
===================================================================
--- arch/ia64/include/register.h	(revision cd373bbb5fd51ad3198655cb712d3d11734ee5e1)
+++ arch/ia64/include/register.h	(revision b994a60c2699d4cf29d9c28497e8256a75eb2a1c)
@@ -30,8 +30,4 @@
 #define __ia64_REGISTER_H__
 
-#ifndef __ASM__
-#include <arch/types.h>
-#endif
-
 #define CR_IVR_MASK	0xf
 #define PSR_IC_MASK	0x2000
@@ -45,4 +41,9 @@
 #define PSR_CPL_SHIFT		32
 #define PSR_CPL_MASK_SHIFTED	3
+
+#define PFM_MASK        (~0x3fffffffff)
+
+#define RSC_MODE_MASK	3
+#define RSC_PL_MASK	12
 
 /** Application registers. */
@@ -121,4 +122,63 @@
 
 #ifndef __ASM__
+
+#include <arch/types.h>
+
+/** Processor Status Register. */
+union psr {
+	__u64 value;
+	struct {
+		unsigned : 1;
+		unsigned be : 1;	/**< Big-Endian data accesses. */
+		unsigned up : 1;	/**< User Performance monitor enable. */
+		unsigned ac : 1;	/**< Alignment Check. */
+		unsigned mfl : 1;	/**< Lower floating-point register written. */
+		unsigned mfh : 1;	/**< Upper floating-point register written. */
+		unsigned : 7;
+		unsigned ic : 1;	/**< Interruption Collection. */
+		unsigned i : 1;		/**< Interrupt Bit. */
+		unsigned pk : 1;	/**< Protection Key enable. */
+		unsigned : 1;
+		unsigned dt : 1;	/**< Data address Translation. */
+		unsigned dfl : 1;	/**< Disabled Floating-point Low register set. */
+		unsigned dfh : 1;	/**< Disabled Floating-point High register set. */
+		unsigned sp : 1;	/**< Secure Performance monitors. */
+		unsigned pp : 1;	/**< Privileged Performance monitor enable. */
+		unsigned di : 1;	/**< Disable Instruction set transition. */
+		unsigned si : 1;	/**< Secure Interval timer. */
+		unsigned db : 1;	/**< Debug Breakpoint fault. */
+		unsigned lp : 1;	/**< Lower Privilege transfer trap. */
+		unsigned tb : 1;	/**< Taken Branch trap. */
+		unsigned rt : 1;	/**< Register Stack Translation. */
+		unsigned : 4;
+		unsigned cpl : 2;	/**< Current Privilege Level. */
+		unsigned is : 1;	/**< Instruction Set. */
+		unsigned mc : 1;	/**< Machine Check abort mask. */
+		unsigned it : 1;	/**< Instruction address Translation. */
+		unsigned id : 1;	/**< Instruction Debug fault disable. */
+		unsigned da : 1;	/**< Disable Data Access and Dirty-bit faults. */
+		unsigned dd : 1;	/**< Data Debug fault disable. */
+		unsigned ss : 1;	/**< Single Step enable. */
+		unsigned ri : 2;	/**< Restart Instruction. */
+		unsigned ed : 1;	/**< Exception Deferral. */
+		unsigned bn : 1;	/**< Register Bank. */
+		unsigned ia : 1;	/**< Disable Instruction Access-bit faults. */
+	} __attribute__ ((packed));
+};
+typedef union psr psr_t;
+
+/** Register Stack Configuration Register */
+union rsc {
+	__u64 value;
+	struct {
+		unsigned mode : 2;
+		unsigned pl : 2;	/**< Privilege Level. */
+		unsigned be : 1;	/**< Big-endian. */
+		unsigned : 11;
+		unsigned loadrs : 14;
+	} __attribute__ ((packed));
+};
+typedef union rsc rsc_t;
+
 /** External Interrupt Vector Register */
 union cr_ivr {
Index: arch/ia64/src/asm.S
===================================================================
--- arch/ia64/src/asm.S	(revision cd373bbb5fd51ad3198655cb712d3d11734ee5e1)
+++ arch/ia64/src/asm.S	(revision b994a60c2699d4cf29d9c28497e8256a75eb2a1c)
@@ -27,4 +27,6 @@
 #
 
+#include <arch/register.h>
+
 .text
 
@@ -47,2 +49,41 @@
 	}
 	br halt
+
+/** Switch to userspace - low level code.
+ *
+ * @param in0 Userspace entry point address.
+ * @param in1 Userspace stack pointer address.
+ * @param in2 Userspace register stack pointer address.
+ * @param in3 Value to be stored in IPSR.
+ * @param in4 Value to be stored in RSC.
+ */
+.global switch_to_userspace
+switch_to_userspace:
+	alloc loc0 = ar.pfs, 5, 3, 0, 0
+	rsm (PSR_IC_MASK | PSR_I_MASK)		/* disable interruption collection  and interrupts */
+	srlz.d ;;
+	srlz.i ;;
+	
+	mov cr.ipsr = in3
+	mov cr.iip = in0
+	mov r12 = in1
+
+	xor r1 = r1, r1
+	
+	mov loc1 = cr.ifs
+	movl loc2 = PFM_MASK ;;
+	and loc1 = loc2, loc1 ;;
+	mov cr.ifs = loc1 ;;			/* prevent decrementing BSP by rfi */
+
+	invala
+	
+	mov loc1 = ar.rsc ;;
+	and loc1 = ~3, loc1 ;;			
+	mov ar.rsc = loc1 ;;			/* put RSE into enforced lazy mode */
+
+	flushrs ;;
+	
+	mov ar.bspstore = in2 ;;
+	mov ar.rsc = in4 ;;
+	
+	rfi ;;
Index: arch/ia64/src/dummy.s
===================================================================
--- arch/ia64/src/dummy.s	(revision cd373bbb5fd51ad3198655cb712d3d11734ee5e1)
+++ arch/ia64/src/dummy.s	(revision b994a60c2699d4cf29d9c28497e8256a75eb2a1c)
@@ -31,5 +31,4 @@
 .global calibrate_delay_loop
 .global asm_delay_loop
-.global userspace
 .global cpu_sleep
 .global dummy
@@ -38,5 +37,4 @@
 .global fpu_init
 
-userspace:
 calibrate_delay_loop:
 asm_delay_loop:
Index: arch/ia64/src/ia64.c
===================================================================
--- arch/ia64/src/ia64.c	(revision cd373bbb5fd51ad3198655cb712d3d11734ee5e1)
+++ arch/ia64/src/ia64.c	(revision b994a60c2699d4cf29d9c28497e8256a75eb2a1c)
@@ -32,6 +32,12 @@
 #include <arch/interrupt.h>
 #include <arch/barrier.h>
+#include <arch/asm.h>
+#include <arch/register.h>
 #include <arch/types.h>
-
+#include <arch/context.h>
+#include <arch/mm/page.h>
+#include <mm/as.h>
+#include <config.h>
+#include <userspace.h>
 #include <console/console.h>
 
@@ -44,4 +50,6 @@
 	ski_init_console();
 	it_init();
+	config.init_addr = INIT_ADDRESS;
+	config.init_size = INIT_SIZE;
 }
 
@@ -54,6 +62,30 @@
 }
 
-
 void arch_post_smp_init(void)
 {
 }
+
+/** Enter userspace and never return. */
+void userspace(void)
+{
+	psr_t psr;
+	rsc_t rsc;
+
+	psr.value = psr_read();
+	psr.cpl = PL_USER;
+	psr.i = true;				/* start with interrupts enabled */
+	psr.ic = true;
+	psr.ri = 0;				/* start with instruction #0 */
+
+	__asm__ volatile ("mov %0 = ar.rsc\n" : "=r" (rsc.value));
+	rsc.loadrs = 0;
+	rsc.be = false;
+	rsc.pl = PL_USER;
+	rsc.mode = 3;				/* eager mode */
+
+	switch_to_userspace(UTEXT_ADDRESS, USTACK_ADDRESS+PAGE_SIZE-1, USTACK_ADDRESS, psr.value, rsc.value);
+
+	while (1) {
+		;
+	}
+}
Index: arch/ia64/src/ivt.S
===================================================================
--- arch/ia64/src/ivt.S	(revision cd373bbb5fd51ad3198655cb712d3d11734ee5e1)
+++ arch/ia64/src/ivt.S	(revision b994a60c2699d4cf29d9c28497e8256a75eb2a1c)
@@ -137,6 +137,7 @@
 	st8 [r31] = r26, -8		/* save ar.ifs */
 	
-	and r30 = ~3, r24 ;;
-	mov ar.rsc = r30 ;;		/* place RSE in enforced lazy mode */
+	and r24 = ~(RSC_PL_MASK), r24 ;;
+	and r30 = ~(RSC_MODE_MASK), r24 ;;
+	mov ar.rsc = r30 ;;		/* update RSE state */
 	
 	mov r27 = ar.rnat
@@ -163,5 +164,5 @@
 	st8 [r31] = r29, -8 		/* save ar.bsp */
 	
-	mov ar.rsc = r24		/* restore RSE's setting */
+	mov ar.rsc = r24		/* restore RSE's setting + kernel privileges */
 	
     /* steps 6 - 15 are done by heavyweight_handler_inner() */
@@ -301,4 +302,6 @@
 
     /* 10. call handler */
+    	movl r1 = _hardcoded_load_address
+    
     	mov b1 = loc2
 	br.call.sptk.many b0 = b1
Index: arch/ia64/src/mm/tlb.c
===================================================================
--- arch/ia64/src/mm/tlb.c	(revision cd373bbb5fd51ad3198655cb712d3d11734ee5e1)
+++ arch/ia64/src/mm/tlb.c	(revision b994a60c2699d4cf29d9c28497e8256a75eb2a1c)
@@ -64,5 +64,6 @@
  * @param entry The rest of TLB entry as required by TLB insertion format.
  */
-void dtc_mapping_insert(__address va, asid_t asid, tlb_entry_t entry) {
+void dtc_mapping_insert(__address va, asid_t asid, tlb_entry_t entry)
+{
 	tc_mapping_insert(va, asid, entry, true);
 }
@@ -74,5 +75,6 @@
  * @param entry The rest of TLB entry as required by TLB insertion format.
  */
-void itc_mapping_insert(__address va, asid_t asid, tlb_entry_t entry) {
+void itc_mapping_insert(__address va, asid_t asid, tlb_entry_t entry)
+{
 	tc_mapping_insert(va, asid, entry, false);
 }
@@ -336,5 +338,5 @@
 		}
 	}
-	
+
 	t = page_mapping_find(AS, va);
 	if (t) {
Index: arch/ia64/src/start.S
===================================================================
--- arch/ia64/src/start.S	(revision cd373bbb5fd51ad3198655cb712d3d11734ee5e1)
+++ arch/ia64/src/start.S	(revision b994a60c2699d4cf29d9c28497e8256a75eb2a1c)
@@ -125,5 +125,5 @@
 
 	# initialize gp (Global Pointer) register
-	movl r1 = _hardcoded_load_address	;;
+	movl r1 = _hardcoded_load_address
 
 	/*
@@ -132,5 +132,5 @@
 	movl r14 = _hardcoded_ktext_size
 	movl r15 = _hardcoded_kdata_size
-	movl r16 = _hardcoded_load_address
+	movl r16 = _hardcoded_load_address ;;
 	addl r17 = @gprel(hardcoded_ktext_size), gp
 	addl r18 = @gprel(hardcoded_kdata_size), gp
Index: contrib/conf/ski.conf
===================================================================
--- contrib/conf/ski.conf	(revision cd373bbb5fd51ad3198655cb712d3d11734ee5e1)
+++ contrib/conf/ski.conf	(revision b994a60c2699d4cf29d9c28497e8256a75eb2a1c)
@@ -1,2 +1,2 @@
-load SPARTAN/kernel.bin
-load SPARTAN/load.bin
+load HelenOS/boot/kernel.bin
+romload HelenOS/boot/init 0x400000
