Index: kernel/arch/ia32xen/src/ia32xen.c
===================================================================
--- kernel/arch/ia32xen/src/ia32xen.c	(revision 8607db8973636c4d5002631c147efc77bc9fd967)
+++ kernel/arch/ia32xen/src/ia32xen.c	(revision ec04b209000b3a97373f9e45740f860a49db9a9b)
@@ -62,4 +62,5 @@
 #include <syscall/syscall.h>
 #include <console/console.h>
+#include <ddi/irq.h>
 
 start_info_t start_info;
@@ -129,12 +130,7 @@
 
 	if (config.cpu_active == 1) {
+		interrupt_init();
 //		bios_init();
 		
-		exc_register(VECTOR_SYSCALL, "syscall", (iroutine) syscall);
-		
-		#ifdef CONFIG_SMP
-		exc_register(VECTOR_TLB_SHOOTDOWN_IPI, "tlb_shootdown",
-			     (iroutine) tlb_shootdown_ipi);
-		#endif /* CONFIG_SMP */
 	}
 }
@@ -143,8 +139,13 @@
 {
 	if (config.cpu_active == 1) {
-		/* video */
+		/* Initialize IRQ routing */
+		irq_init(IRQ_COUNT, IRQ_COUNT);
+		
+		/* Video */
 		xen_console_init();
+		
 		/* Enable debugger */
 		debugger_init();
+		
 		/* Merge all memory zones to 1 big zone */
 		zone_merge_all();
Index: kernel/arch/ia32xen/src/interrupt.c
===================================================================
--- kernel/arch/ia32xen/src/interrupt.c	(revision 8607db8973636c4d5002631c147efc77bc9fd967)
+++ kernel/arch/ia32xen/src/interrupt.c	(revision ec04b209000b3a97373f9e45740f860a49db9a9b)
@@ -51,4 +51,5 @@
 #include <ipc/sysipc.h>
 #include <interrupt.h>
+#include <ddi/irq.h>
 
 /*
@@ -60,5 +61,5 @@
 void (* eoi_function)(void) = NULL;
 
-void PRINT_INFO_ERRCODE(istate_t *istate)
+void decode_istate(istate_t *istate)
 {
 	char *symbol = get_symtab_entry(istate->eip);
@@ -83,14 +84,23 @@
 }
 
-void null_interrupt(int n, istate_t *istate)
+static void trap_virtual_eoi(void)
+{
+	if (eoi_function)
+		eoi_function();
+	else
+		panic("no eoi_function\n");
+
+}
+
+static void null_interrupt(int n, istate_t *istate)
 {
 	fault_if_from_uspace(istate, "unserviced interrupt: %d", n);
 
-	PRINT_INFO_ERRCODE(istate);
+	decode_istate(istate);
 	panic("unserviced interrupt: %d\n", n);
 }
 
 /** General Protection Fault. */
-void gp_fault(int n, istate_t *istate)
+static void gp_fault(int n, istate_t *istate)
 {
 	if (TASK) {
@@ -115,17 +125,17 @@
 	}
 
-	PRINT_INFO_ERRCODE(istate);
+	decode_istate(istate);
 	panic("general protection fault\n");
 }
 
-void ss_fault(int n, istate_t *istate)
+static void ss_fault(int n, istate_t *istate)
 {
 	fault_if_from_uspace(istate, "stack fault");
 
-	PRINT_INFO_ERRCODE(istate);
+	decode_istate(istate);
 	panic("stack fault\n");
 }
 
-void simd_fp_exception(int n, istate_t *istate)
+static void simd_fp_exception(int n, istate_t *istate)
 {
 	uint32_t mxcsr;
@@ -138,10 +148,10 @@
 			     (unative_t)mxcsr);
 
-	PRINT_INFO_ERRCODE(istate);
+	decode_istate(istate);
 	printf("MXCSR: %#zx\n",(unative_t)(mxcsr));
 	panic("SIMD FP exception(19)\n");
 }
 
-void nm_fault(int n, istate_t *istate)
+static void nm_fault(int n, istate_t *istate)
 {
 #ifdef CONFIG_FPU_LAZY     
@@ -153,14 +163,60 @@
 }
 
-void syscall(int n, istate_t *istate)
-{
-	panic("Obsolete syscall handler.");
-}
-
-void tlb_shootdown_ipi(int n, istate_t *istate)
+#ifdef CONFIG_SMP
+static void tlb_shootdown_ipi(int n, istate_t *istate)
 {
 	trap_virtual_eoi();
 	tlb_shootdown_ipi_recv();
 }
+#endif
+
+/** Handler of IRQ exceptions */
+static void irq_interrupt(int n, istate_t *istate)
+{
+	ASSERT(n >= IVT_IRQBASE);
+	
+	int inum = n - IVT_IRQBASE;
+	ASSERT(inum < IRQ_COUNT);
+	ASSERT((inum != IRQ_PIC_SPUR) && (inum != IRQ_PIC1));
+
+	irq_t *irq = irq_dispatch_and_lock(inum);
+	if (irq) {
+		/*
+		 * The IRQ handler was found.
+		 */
+		irq->handler(irq, irq->arg);
+		spinlock_unlock(&irq->lock);
+	} else {
+		/*
+		 * Spurious interrupt.
+		 */
+#ifdef CONFIG_DEBUG
+		printf("cpu%d: spurious interrupt (inum=%d)\n", CPU->id, inum);
+#endif
+	}
+	trap_virtual_eoi();
+}
+
+void interrupt_init(void)
+{
+	int i;
+	
+	for (i = 0; i < IVT_ITEMS; i++)
+		exc_register(i, "null", (iroutine) null_interrupt);
+	
+	for (i = 0; i < IRQ_COUNT; i++) {
+		if ((i != IRQ_PIC_SPUR) && (i != IRQ_PIC1))
+			exc_register(IVT_IRQBASE + i, "irq", (iroutine) irq_interrupt);
+	}
+	
+	exc_register(7, "nm_fault", (iroutine) nm_fault);
+	exc_register(12, "ss_fault", (iroutine) ss_fault);
+	exc_register(13, "gp_fault", (iroutine) gp_fault);
+	exc_register(19, "simd_fp", (iroutine) simd_fp_exception);
+	
+#ifdef CONFIG_SMP
+	exc_register(VECTOR_TLB_SHOOTDOWN_IPI, "tlb_shootdown", (iroutine) tlb_shootdown_ipi);
+#endif
+}
 
 void trap_virtual_enable_irqs(uint16_t irqmask)
@@ -180,13 +236,4 @@
 }
 
-void trap_virtual_eoi(void)
-{
-	if (eoi_function)
-		eoi_function();
-	else
-		panic("no eoi_function\n");
-
-}
-
 /** @}
  */
Index: kernel/arch/ia32xen/src/mm/page.c
===================================================================
--- kernel/arch/ia32xen/src/mm/page.c	(revision 8607db8973636c4d5002631c147efc77bc9fd967)
+++ kernel/arch/ia32xen/src/mm/page.c	(revision ec04b209000b3a97373f9e45740f860a49db9a9b)
@@ -77,5 +77,5 @@
 		fault_if_from_uspace(istate, "Page fault: %#x", page);
 		
-		PRINT_INFO_ERRCODE(istate);
+		decode_istate(istate);
 		printf("page fault address: %#x\n", page);
 		panic("page fault\n");
Index: kernel/arch/ia32xen/src/pm.c
===================================================================
--- kernel/arch/ia32xen/src/pm.c	(revision 8607db8973636c4d5002631c147efc77bc9fd967)
+++ kernel/arch/ia32xen/src/pm.c	(revision ec04b209000b3a97373f9e45740f860a49db9a9b)
@@ -122,5 +122,4 @@
 		traps[i].cs = XEN_CS;
 		traps[i].address = trap;
-		exc_register(i, "undef", (iroutine) null_interrupt);
 	}
 	traps[IDT_ITEMS].vector = 0;
@@ -128,9 +127,4 @@
 	traps[IDT_ITEMS].cs = 0;
 	traps[IDT_ITEMS].address = NULL;
-	
-	exc_register(13, "gp_fault", (iroutine) gp_fault);
-	exc_register( 7, "nm_fault", (iroutine) nm_fault);
-	exc_register(12, "ss_fault", (iroutine) ss_fault);
-	exc_register(19, "simd_fp", (iroutine) simd_fp_exception);
 }
 
