Index: arch/ia64/src/context.S
===================================================================
--- arch/ia64/src/context.S	(revision dd118f0903fffeb33ec2a6a79435f5fe2b9e425c)
+++ arch/ia64/src/context.S	(revision 2c457e89e009478a9eb0fb1e49cb0128fbedb3bf)
@@ -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 2c457e89e009478a9eb0fb1e49cb0128fbedb3bf)
+++ arch/ia64/src/drivers/it.c	(revision 2c457e89e009478a9eb0fb1e49cb0128fbedb3bf)
@@ -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 2c457e89e009478a9eb0fb1e49cb0128fbedb3bf)
@@ -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 2c457e89e009478a9eb0fb1e49cb0128fbedb3bf)
@@ -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 2c457e89e009478a9eb0fb1e49cb0128fbedb3bf)
@@ -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
