Index: arch/ia64/Makefile.inc
===================================================================
--- arch/ia64/Makefile.inc	(revision dd118f0903fffeb33ec2a6a79435f5fe2b9e425c)
+++ arch/ia64/Makefile.inc	(revision 154049ecd82e431339be436cce47de8033b9e298)
@@ -35,3 +35,4 @@
 	generic/src/arch/interrupt_handler.c \
 	generic/src/arch/fmath.c \
-	generic/src/arch/mm/frame.c
+	generic/src/arch/mm/frame.c \
+	generic/src/arch/drivers/it.c
Index: arch/ia64/include/drivers/it.h
===================================================================
--- arch/ia64/include/drivers/it.h	(revision 154049ecd82e431339be436cce47de8033b9e298)
+++ arch/ia64/include/drivers/it.h	(revision 154049ecd82e431339be436cce47de8033b9e298)
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2005 Jakub Jermar
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __ia64_IT_H__
+#define __ia64_IT_H__
+
+/*
+ * Unfortunately, Ski does not emulate PAL,
+ * so we can't read the real frequency ratios
+ * from firmware.
+ *
+ */
+#define IT_DELTA        1000
+
+extern void it_init(void);
+extern void it_interrupt(void);
+
+#endif
Index: arch/ia64/include/interrupt.h
===================================================================
--- arch/ia64/include/interrupt.h	(revision dd118f0903fffeb33ec2a6a79435f5fe2b9e425c)
+++ arch/ia64/include/interrupt.h	(revision 154049ecd82e431339be436cce47de8033b9e298)
@@ -33,4 +33,6 @@
 #define INTERRUPT_SPURIOUS	15
 
+#define EOI	0		/**< The actual value doesn't matter. */
+
 extern void external_interrupt(void);
 
Index: arch/ia64/include/pal/pal.h
===================================================================
--- arch/ia64/include/pal/pal.h	(revision 154049ecd82e431339be436cce47de8033b9e298)
+++ arch/ia64/include/pal/pal.h	(revision 154049ecd82e431339be436cce47de8033b9e298)
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2005 Jakub Jermar
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __ia64_PAL_H__
+#define __ia64_PAL_H__
+
+#define PAL_OK		 0	/**< Call completed without error. */
+#define PAL_UNIMPL	-1	/**< Unimplemented procedure. */
+#define PAL_INVARG	-2	/**< Invalid argument. */
+#define PAL_ERR		-3	/**< Can not compete call without error. */
+
+/** These are the indices for PAL_PROC. */
+#define PAL_CACHE_FLUSH		1
+#define PAL_CACHE_INFO		2
+#define PAL_CACHE_INIT		3
+#define PAL_CACHE_PROT_INFO	38
+#define PAL_CACHE_SHARED_INFO	43
+#define PAL_CACHE_SUMMARY	4
+
+#define PAL_MEM_ATTRIB		5
+#define PAL_PREFETCH_VISIBILITY	41
+#define PAL_PTCE_INFO		6
+#define PAL_VM_INFO		7
+#define PAL_VM_PAGE_SIZE	34
+#define PAL_VM_SUMMARY		8
+#define PAL_VM_TR_READ		261
+
+#define PAL_BUS_GET_FEATURES	9
+#define PAL_BUS_SET_FEATURES	10
+#define PAL_DEBUG_INFO		11
+#define PAL_FIXED_ADDR		12
+#define PAL_FREQ_BASE		13
+#define PAL_FREQ_RATIOS		14
+#define PAL_LOGICAL_TO_PHYSICAL	42
+#define PAL_PERF_MON_INFO	15
+#define PAL_PLATFORM_ADDR	16
+#define PAL_PROC_GET_FEATURES	17
+#define PAL_PROC_SET_FEATURES	18
+#define PAL_REGISTER_INFO	39
+#define PAL_RSE_INFO		19
+#define PAL_VERSION		20
+
+#define PAL_MC_CLEAR_LOG	21
+#define PAL_MC_DRAIN		22
+#define PAL_MC_DYNAMIC_STATE	24
+#define PAL_MC_ERROR_INFO	25
+#define PAL_MC_EXPECTED		23
+#define PAL_MC_REGISTER_MEM	27
+#define PAL_MC_RESUME		26
+
+#define PAL_HALT		28
+#define PAL_HALT_INFO		257
+#define PAL_HALT_LIGHT		29
+
+#define PAL_CACHE_LINE_INIT	31
+#define PAL_CACHE_READ		259
+#define PAL_CACHE_WRITE		260
+#define PAL_TEST_INFO		37
+#define PAL_TEST_PROC		258
+
+#define PAL_COPY_INFO		30
+#define PAL_COPY_PAL		256
+#define PAL_ENTER_IA_32_ENV	33
+#define PAL_PMI_ENTRYPOINT	32
+
+#endif
Index: arch/ia64/src/context.S
===================================================================
--- arch/ia64/src/context.S	(revision dd118f0903fffeb33ec2a6a79435f5fe2b9e425c)
+++ arch/ia64/src/context.S	(revision 154049ecd82e431339be436cce47de8033b9e298)
@@ -51,6 +51,5 @@
 	 * So that ar.rnat can be read.
 	 */
-	movl loc5 = ~3
-	and loc5 = loc3, loc5
+	and loc5 = ~3, loc3
 	mov ar.rsc = loc5
 	mov loc5 = ar.rnat
Index: arch/ia64/src/drivers/it.c
===================================================================
--- arch/ia64/src/drivers/it.c	(revision 154049ecd82e431339be436cce47de8033b9e298)
+++ arch/ia64/src/drivers/it.c	(revision 154049ecd82e431339be436cce47de8033b9e298)
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2005 Jakub Jermar
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** Interval Timer driver. */
+ 
+#include <arch/drivers/it.h>
+#include <arch/interrupt.h>
+#include <arch/register.h>
+#include <arch/asm.h>
+#include <arch/barrier.h>
+#include <time/clock.h>
+
+/** Initialize Interval Timer. */
+void it_init(void)
+{
+	cr_itv_t itv;
+
+	/* initialize Interval Timer external interrupt vector */
+	itv.value = itv_read();
+	itv.vector = INTERRUPT_TIMER;
+	itv.m = 0;
+	itv_write(itv.value);
+	srlz_d();
+
+	/* set Interval Timer Counter to zero */
+	itc_write(0);
+	srlz_d();
+	
+	/* generate first Interval Timer interrupt in IT_DELTA ticks */
+	itm_write(IT_DELTA);
+	srlz_d();
+}
+
+/** Process Interval Timer interrupt. */
+void it_interrupt(void)
+{
+	eoi_write(EOI);
+	itm_write(itc_read() + IT_DELTA);	/* program next interruption */
+	clock();
+}
Index: arch/ia64/src/ia64.c
===================================================================
--- arch/ia64/src/ia64.c	(revision dd118f0903fffeb33ec2a6a79435f5fe2b9e425c)
+++ arch/ia64/src/ia64.c	(revision 154049ecd82e431339be436cce47de8033b9e298)
@@ -29,34 +29,13 @@
 #include <arch.h>
 #include <arch/ski/ski.h>
-#include <arch/asm.h>
-#include <arch/register.h>
-#include <arch/barrier.h>
-#include <arch/interrupt.h>
-
-/** TODO: read ticks per second from firmware */
-#define IT_DELTA	50000000
+#include <arch/drivers/it.h>
 
 void arch_pre_mm_init(void)
 {
 	ski_init_console();
+	it_init();
 }
 
 void arch_post_mm_init(void)
 {
-	cr_itv_t itv;
-
-	/* initialize Interval Timer external interrupt vector */
-	itv.value = itv_read();
-	itv.vector = INTERRUPT_TIMER;
-	itv.m = 0;
-	itv_write(itv.value);
-	srlz_d();
-
-	/* set Interval Timer Counter to zero */
-	itc_write(0);
-	srlz_d();
-	
-	/* generate first Interval Timer interrupt in IT_DELTA ticks */
-	itm_write(IT_DELTA);
-	srlz_d();
 }
Index: arch/ia64/src/interrupt.c
===================================================================
--- arch/ia64/src/interrupt.c	(revision dd118f0903fffeb33ec2a6a79435f5fe2b9e425c)
+++ arch/ia64/src/interrupt.c	(revision 154049ecd82e431339be436cce47de8033b9e298)
@@ -35,4 +35,5 @@
 #include <arch/barrier.h>
 #include <arch/register.h>
+#include <arch/drivers/it.h>
 #include <arch.h>
 
@@ -46,4 +47,5 @@
 	switch(ivr.vector) {
 	    case INTERRUPT_TIMER:
+		it_interrupt();
 	    	panic("cpu%d: timer interrupt\n", CPU->id);
 	    	break;
Index: arch/ia64/src/ivt.S
===================================================================
--- arch/ia64/src/ivt.S	(revision dd118f0903fffeb33ec2a6a79435f5fe2b9e425c)
+++ arch/ia64/src/ivt.S	(revision 154049ecd82e431339be436cce47de8033b9e298)
@@ -28,5 +28,111 @@
 
 
-
+/*
+ * This macro roughly follows steps from 1 to 19 described in
+ * Intel Itanium Architecture Software Developer's Manual, Chapter 3.4.2.
+ *
+ * Some steps are skipped (enabling and disabling interrupts).
+ * Some steps are not fully supported yet (e.g. interruptions
+ * from user space and floating-point context).
+ */
+.macro HEAVYWEIGHT_HANDLER offs handler
+    .org IVT + \offs
+	SAVE_INTERRUPTED_CONTEXT		/* steps 1 - 9 */
+	br.call.sptk.many rp = \handler		/* steps 10 - 11 */
+	br restore_interrupted_context		/* steps 12 - 19 */
+.endm
+
+.macro SAVE_INTERRUPTED_CONTEXT
+    /* 1. copy interrupt registers into bank 0 */
+	mov r24 = cr.iip
+	mov r25 = cr.ipsr
+	mov r26 = cr.iipa
+	mov r27 = cr.isr
+	mov r28 = cr.ifa
+	
+    /* 2. preserve predicate register into bank 0 */
+	mov r29 = pr ;;
+	
+	/* 3. switch to kernel memory stack */
+	/* TODO: support interruptions from userspace */
+	/* assume kernel stack */
+	
+    /* 4. allocate memory stack for registers saved in bank 0 */
+	st8 [r12] = r29, -8 ;;	/* save predicate registers */
+	st8 [r12] = r28, -8 ;;	/* save cr.ifa */
+	st8 [r12] = r27, -8 ;;	/* save cr.isr */
+	st8 [r12] = r26, -8 ;;	/* save cr.iipa */
+	st8 [r12] = r25, -8 ;;	/* save cr.ipsr */
+	st8 [r12] = r24, -8 ;;	/* save cr.iip */
+	
+    /* 5. RSE switch */
+    	.auto
+	mov r24 = ar.rsc
+	mov r25 = ar.pfs
+	cover
+	mov r26 = cr.ifs
+	
+	st8 [r12] = r24, -8	/* save ar.rsc */
+	st8 [r12] = r25, -8	/* save ar.pfs */
+	st8 [r12] = r26, -8	/* save ar.ifs */
+	
+	and r30 = ~3, r24
+	mov ar.rsc = r30	/* place RSE in enforced lazy mode */
+	
+	mov r27 = ar.rnat
+	mov r28 = ar.bspstore
+	
+	/* assume kernel backing store */
+	mov ar.bspstore = r28
+	
+	mov r29 = ar.bsp
+	
+	st8 [r12] = r27, -8	/* save ar.rnat */
+	st8 [r12] = r28, -8	/* save ar.bspstore */
+	st8 [r12] = r29, -8	/* save ar.bsp */
+	
+	mov ar.rsc = r24	/* restore RSE's setting */
+	.explicit
+	
+    /* 6. switch to bank 1 and reenable PSR.ic */
+	ssm 0x2000
+	bsw.1 ;;
+	srlz.d
+	
+    /* 7. preserve branch and application registers */
+	
+    /* 8. preserve general and floating-point registers */
+	/* TODO: save floating-point context */
+	
+    /* 9. skipped (will not enable interrupts) */
+.endm
+
+.macro RESTORE_INTERRUPTED_CONTEXT
+    /* 12. skipped (will not disable interrupts) */
+	
+    /* 13. restore general and floating-point registers */
+	/* TODO: restore floating-point context */
+	
+    /* 14. restore branch and application registers */
+	
+    /* 15. disable PSR.ic and switch to bank 0 */
+	rsm 0x2000
+	bsw.0 ;;
+	srlz.d
+	
+    /* 16. RSE switch */
+	
+    /* 17. restore interruption state from memory stack */
+	
+    /* 18. restore predicate registers from memory stack */
+	
+    /* 19. return from interruption */
+	rfi
+.endm
+
+.global restore_interrupted_context
+restore_interrupted_context:
+	RESTORE_INTERRUPTED_CONTEXT
+	/* not reached */
 
 dump_gregs:
@@ -386,5 +492,5 @@
 Handler2 0x2800
 Handler 0x2c00 break_instruction
-Handler 0x3000 external_interrupt
+HEAVYWEIGHT_HANDLER 0x3000 external_interrupt	/* For external interrupt, heavyweight handler is used. */
 Handler2 0x3400
 Handler2 0x3800
