Index: kernel/arch/amd64/include/interrupt.h
===================================================================
--- kernel/arch/amd64/include/interrupt.h	(revision 78595d6da1d919a9ecacafa878d040aaf6b4ce80)
+++ kernel/arch/amd64/include/interrupt.h	(revision 282f2c9ca4f0625d5823e8a836d38f8d4f100b43)
@@ -46,27 +46,26 @@
 
 #define IVT_EXCBASE		0
-#define IVT_IRQBASE		(IVT_EXCBASE+EXC_COUNT)
-#define IVT_FREEBASE		(IVT_IRQBASE+IRQ_COUNT)
+#define IVT_IRQBASE		(IVT_EXCBASE + EXC_COUNT)
+#define IVT_FREEBASE	(IVT_IRQBASE + IRQ_COUNT)
 
-#define IRQ_CLK		0
-#define IRQ_KBD		1
-#define IRQ_PIC1	2
+#define IRQ_CLK			0
+#define IRQ_KBD			1
+#define IRQ_PIC1		2
 #define IRQ_PIC_SPUR	7
+#define IRQ_MOUSE		12
 
 /* this one must have four least significant bits set to ones */
-#define VECTOR_APIC_SPUR	(IVT_ITEMS-1)
+#define VECTOR_APIC_SPUR	(IVT_ITEMS - 1)
 
-#if (((VECTOR_APIC_SPUR + 1)%16) || VECTOR_APIC_SPUR >= IVT_ITEMS)
+#if (((VECTOR_APIC_SPUR + 1) % 16) || VECTOR_APIC_SPUR >= IVT_ITEMS)
 #error Wrong definition of VECTOR_APIC_SPUR
 #endif
 
-#define VECTOR_DEBUG            1
-#define VECTOR_PIC_SPUR		(IVT_IRQBASE+IRQ_PIC_SPUR)
-#define VECTOR_CLK		(IVT_IRQBASE+IRQ_CLK)
-#define VECTOR_KBD		(IVT_IRQBASE+IRQ_KBD)
-
-#define VECTOR_TLB_SHOOTDOWN_IPI	(IVT_FREEBASE+0)
-#define VECTOR_WAKEUP_IPI		(IVT_FREEBASE+1)
-#define VECTOR_DEBUG_IPI                (IVT_FREEBASE+2)
+#define VECTOR_DEBUG				1
+#define VECTOR_CLK					(IVT_IRQBASE + IRQ_CLK)
+#define VECTOR_PIC_SPUR				(IVT_IRQBASE + IRQ_PIC_SPUR)
+#define VECTOR_SYSCALL				IVT_FREEBASE
+#define VECTOR_TLB_SHOOTDOWN_IPI	(IVT_FREEBASE + 1)
+#define VECTOR_DEBUG_IPI			(IVT_FREEBASE + 2)
 
 /** This is passed to interrupt handlers */
@@ -113,16 +112,8 @@
 extern void (* eoi_function)(void);
 
-extern void print_info_errcode(int n, istate_t *istate);
-extern void null_interrupt(int n, istate_t *istate);
-extern void gp_fault(int n, istate_t *istate);
-extern void nm_fault(int n, istate_t *istate);
-extern void ss_fault(int n, istate_t *istate);
-extern void page_fault(int n, istate_t *istate);
-extern void syscall(int n, istate_t *istate);
-extern void tlb_shootdown_ipi(int n, istate_t *istate);
-
+extern void decode_istate(int n, istate_t *istate);
+extern void interrupt_init(void);
 extern void trap_virtual_enable_irqs(uint16_t irqmask);
 extern void trap_virtual_disable_irqs(uint16_t irqmask);
-extern void trap_virtual_eoi(void);
 /* AMD64 - specific page handler */
 extern void ident_page_fault(int n, istate_t *istate);
Index: kernel/arch/amd64/include/mm/page.h
===================================================================
--- kernel/arch/amd64/include/mm/page.h	(revision 78595d6da1d919a9ecacafa878d040aaf6b4ce80)
+++ kernel/arch/amd64/include/mm/page.h	(revision 282f2c9ca4f0625d5823e8a836d38f8d4f100b43)
@@ -191,4 +191,5 @@
 
 extern void page_arch_init(void);
+extern void page_fault(int n, istate_t *istate);
 
 #endif /* __ASM__ */
Index: kernel/arch/amd64/src/amd64.c
===================================================================
--- kernel/arch/amd64/src/amd64.c	(revision 78595d6da1d919a9ecacafa878d040aaf6b4ce80)
+++ kernel/arch/amd64/src/amd64.c	(revision 282f2c9ca4f0625d5823e8a836d38f8d4f100b43)
@@ -62,4 +62,6 @@
 #include <syscall/syscall.h>
 #include <console/console.h>
+#include <ddi/irq.h>
+#include <ddi/device.h>
 
 
@@ -131,12 +133,9 @@
 
 	if (config.cpu_active == 1) {
+		interrupt_init();
 		bios_init();
-		i8259_init();	/* PIC */
-		i8254_init();	/* hard clock */
-
-		#ifdef CONFIG_SMP
-		exc_register(VECTOR_TLB_SHOOTDOWN_IPI, "tlb_shootdown",
-			     tlb_shootdown_ipi);
-		#endif /* CONFIG_SMP */
+		
+		/* PIC */
+		i8259_init();
 	}
 }
@@ -145,4 +144,10 @@
 {
 	if (config.cpu_active == 1) {
+		/* Initialize IRQ routing */
+		irq_init(IRQ_COUNT, IRQ_COUNT);
+		
+		/* hard clock */
+		i8254_init();
+
 #ifdef CONFIG_FB
 		if (vesa_present()) 
@@ -151,4 +156,5 @@
 #endif
 			ega_init();	/* video */
+		
 		/* Enable debugger */
 		debugger_init();
@@ -184,5 +190,6 @@
 void arch_post_smp_init(void)
 {
-	i8042_init();	/* keyboard controller */
+	/* keyboard controller */
+	i8042_init(device_assign_devno(), IRQ_KBD, device_assign_devno(), IRQ_MOUSE);
 }
 
@@ -190,5 +197,11 @@
 {
 	i8254_calibrate_delay_loop();
-	i8254_normal_operation();
+	if (config.cpu_active == 1) {
+		/*
+		 * This has to be done only on UP.
+		 * On SMP, i8254 is not used for time keeping and its interrupt pin remains masked.
+		 */
+		i8254_normal_operation();
+	}
 }
 
Index: kernel/arch/amd64/src/interrupt.c
===================================================================
--- kernel/arch/amd64/src/interrupt.c	(revision 78595d6da1d919a9ecacafa878d040aaf6b4ce80)
+++ kernel/arch/amd64/src/interrupt.c	(revision 282f2c9ca4f0625d5823e8a836d38f8d4f100b43)
@@ -52,7 +52,15 @@
 #include <arch/ddi/ddi.h>
 #include <interrupt.h>
-#include <ipc/irq.h>
-
-void print_info_errcode(int n, istate_t *istate)
+#include <ddi/irq.h>
+
+/*
+ * Interrupt and exception dispatching.
+ */
+
+void (* disable_irqs_function)(uint16_t irqmask) = NULL;
+void (* enable_irqs_function)(uint16_t irqmask) = NULL;
+void (* eoi_function)(void) = NULL;
+
+void decode_istate(int n, istate_t *istate)
 {
 	char *symbol;
@@ -76,21 +84,22 @@
 }
 
-/*
- * Interrupt and exception dispatching.
- */
-
-void (* disable_irqs_function)(uint16_t irqmask) = NULL;
-void (* enable_irqs_function)(uint16_t irqmask) = NULL;
-void (* eoi_function)(void) = NULL;
-
-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(n, istate);
+	decode_istate(n, istate);
 	panic("unserviced interrupt\n");
 }
 
 /** General Protection Fault. */
-void gp_fault(int n, istate_t *istate)
+static void gp_fault(int n, istate_t *istate)
 {
 	if (TASK) {
@@ -115,16 +124,16 @@
 	}
 
-	print_info_errcode(n, istate);
+	decode_istate(n, 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(n, istate);
+	decode_istate(n, istate);
 	panic("stack fault\n");
 }
 
-void nm_fault(int n, istate_t *istate)
+static void nm_fault(int n, istate_t *istate)
 {
 #ifdef CONFIG_FPU_LAZY     
@@ -136,8 +145,57 @@
 }
 
-void tlb_shootdown_ipi(int n, istate_t *istate)
+static void tlb_shootdown_ipi(int n, istate_t *istate)
 {
 	trap_virtual_eoi();
 	tlb_shootdown_ipi_recv();
+}
+
+/** 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(14, "ident_mapper", (iroutine) ident_page_fault);
+	
+#ifdef CONFIG_SMP
+	exc_register(VECTOR_TLB_SHOOTDOWN_IPI, "tlb_shootdown", (iroutine) tlb_shootdown_ipi);
+#endif
 }
 
@@ -158,13 +216,4 @@
 }
 
-void trap_virtual_eoi(void)
-{
-	if (eoi_function)
-		eoi_function();
-	else
-		panic("no eoi_function\n");
-
-}
-
 /** @}
  */
Index: kernel/arch/amd64/src/mm/page.c
===================================================================
--- kernel/arch/amd64/src/mm/page.c	(revision 78595d6da1d919a9ecacafa878d040aaf6b4ce80)
+++ kernel/arch/amd64/src/mm/page.c	(revision 282f2c9ca4f0625d5823e8a836d38f8d4f100b43)
@@ -111,5 +111,5 @@
 		}
 
-		exc_register(14, "page_fault", (iroutine)page_fault);
+		exc_register(14, "page_fault", (iroutine) page_fault);
 		write_cr3((uintptr_t) AS_KERNEL->page_table);
 	}
@@ -194,5 +194,5 @@
 		fault_if_from_uspace(istate, "Page fault: %#x", page);
 
-		print_info_errcode(n, istate);
+		decode_istate(n, istate);
 		printf("Page fault address: %llx\n", page);
 		panic("page fault\n");
Index: kernel/arch/amd64/src/pm.c
===================================================================
--- kernel/arch/amd64/src/pm.c	(revision 78595d6da1d919a9ecacafa878d040aaf6b4ce80)
+++ kernel/arch/amd64/src/pm.c	(revision 282f2c9ca4f0625d5823e8a836d38f8d4f100b43)
@@ -181,11 +181,5 @@
 
 		idt_setoffset(d, ((uintptr_t) interrupt_handlers) + i*interrupt_handler_size);
-		exc_register(i, "undef", (iroutine)null_interrupt);
 	}
-
-	exc_register( 7, "nm_fault", nm_fault);
-	exc_register(12, "ss_fault", ss_fault);
-	exc_register(13, "gp_fault", gp_fault);
-	exc_register(14, "ident_mapper", ident_page_fault);
 }
 
