Index: arch/ia64/include/asm.h
===================================================================
--- arch/ia64/include/asm.h	(revision 0259524e4c4af1fc9ac4849be90ccddd7677fc58)
+++ arch/ia64/include/asm.h	(revision 05d9dd8969ef809eb2bed88c6d5318076c2c4899)
@@ -93,7 +93,20 @@
 }
 
+/** Read ITV (Interval Timer Vector) register.
+ *
+ * @return Current vector and mask bit.
+ */
+static inline __u64 itv_read(void)
+{
+	__u64 v;
+	
+	__asm__ volatile ("mov %0 = cr.itv\n" : "=r" (v));
+	
+	return v;
+}
+
 /** Write ITV (Interval Timer Vector) register.
  *
- * @param New vector and masked bit.
+ * @param New vector and mask bit.
  */
 static inline void itv_write(__u64 v)
Index: arch/ia64/include/interrupt.h
===================================================================
--- arch/ia64/include/interrupt.h	(revision 0259524e4c4af1fc9ac4849be90ccddd7677fc58)
+++ arch/ia64/include/interrupt.h	(revision 05d9dd8969ef809eb2bed88c6d5318076c2c4899)
@@ -30,4 +30,7 @@
 #define __ia64_INTERRUPT_H__
 
+#define INTERRUPT_TIMER		0
+#define INTERRUPT_SPURIOUS	15
+
 extern void external_interrupt(void);
 
Index: arch/ia64/include/register.h
===================================================================
--- arch/ia64/include/register.h	(revision 0259524e4c4af1fc9ac4849be90ccddd7677fc58)
+++ arch/ia64/include/register.h	(revision 05d9dd8969ef809eb2bed88c6d5318076c2c4899)
@@ -33,6 +33,40 @@
 
 #define CR_IVR_MASK	0xf
-
 #define PSR_I_MASK	0x4000
 
+/** External Interrupt Vector Register */
+union cr_ivr {
+	__u8  vector;
+	__u64 value;
+};
+
+typedef union cr_ivr cr_ivr_t;
+
+/** Task Priority Register */
+union cr_tpr {
+	struct {
+		unsigned : 4;
+		unsigned mic: 4;		/**< Mask Interrupt Class. */
+		unsigned : 8;
+		unsigned mmi: 1;		/**< Mask Maskable Interrupts. */
+	} __attribute__ ((packed));
+	__u64 value;
+};
+
+typedef union cr_tpr cr_tpr_t;
+
+/** Interval Timer Vector */
+union cr_itv {
+	struct {
+		unsigned vector : 8;
+		unsigned : 4;
+		unsigned : 1;
+		unsigned : 3;
+		unsigned m : 1;			/**< Mask. */
+	} __attribute__ ((packed));
+	__u64 value;
+};
+
+typedef union cr_itv cr_itv_t;
+
 #endif
Index: arch/ia64/include/types.h
===================================================================
--- arch/ia64/include/types.h	(revision 0259524e4c4af1fc9ac4849be90ccddd7677fc58)
+++ arch/ia64/include/types.h	(revision 05d9dd8969ef809eb2bed88c6d5318076c2c4899)
@@ -36,6 +36,6 @@
 typedef unsigned char __u8;
 typedef unsigned short __u16;
-typedef unsigned long __u32;
-typedef long long __u64;
+typedef unsigned int __u32;
+typedef unsigned long __u64;
 
 typedef __u64 __address;
Index: arch/ia64/src/ia64.c
===================================================================
--- arch/ia64/src/ia64.c	(revision 0259524e4c4af1fc9ac4849be90ccddd7677fc58)
+++ arch/ia64/src/ia64.c	(revision 05d9dd8969ef809eb2bed88c6d5318076c2c4899)
@@ -29,4 +29,11 @@
 #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
 
 void arch_pre_mm_init(void)
@@ -37,3 +44,19 @@
 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 0259524e4c4af1fc9ac4849be90ccddd7677fc58)
+++ arch/ia64/src/interrupt.c	(revision 05d9dd8969ef809eb2bed88c6d5318076c2c4899)
@@ -30,20 +30,28 @@
 #include <arch/interrupt.h>
 #include <panic.h>
+#include <print.h>
 #include <arch/types.h>
 #include <arch/asm.h>
 #include <arch/barrier.h>
 #include <arch/register.h>
+#include <arch.h>
 
 void external_interrupt(void)
 {
-	__u8 ivr;
+	cr_ivr_t ivr;
 	
-	srlz_d();
-	ivr = ivr_read() & CR_IVR_MASK;
+	ivr.value = ivr_read();
 	srlz_d();
 	
-	switch(ivr) {
+	switch(ivr.value) {
+	    case INTERRUPT_TIMER:
+	    	panic("cpu%d: timer interrupt\n", CPU->id);
+	    	break;
+	    case INTERRUPT_SPURIOUS:
+	    	printf("cpu%d: spurious interrupt\n", CPU->id);
+		break;
 	    default:
-		panic("\nUnhandled External Interrupt Vector %d\n", ivr);
+		panic("\nUnhandled External Interrupt Vector %d\n", ivr.vector);
+		break;
 	}
 }
