Index: kernel/arch/ia32/include/interrupt.h
===================================================================
--- kernel/arch/ia32/include/interrupt.h	(revision 8c84448b86410a212184bf076ceb45995c717df0)
+++ kernel/arch/ia32/include/interrupt.h	(revision cea12e9203af33ad68db110556123a714b9bc77d)
@@ -46,27 +46,25 @@
 
 #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
 
 /* 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_SYSCALL			(IVT_FREEBASE+0)
-#define VECTOR_TLB_SHOOTDOWN_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)
 
 struct istate {
@@ -111,16 +109,8 @@
 extern void (* eoi_function)(void);
 
-extern void PRINT_INFO_ERRCODE(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 simd_fp_exception(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(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);
 
 #endif
Index: kernel/arch/ia32/src/drivers/i8254.c
===================================================================
--- kernel/arch/ia32/src/drivers/i8254.c	(revision 8c84448b86410a212184bf076ceb45995c717df0)
+++ kernel/arch/ia32/src/drivers/i8254.c	(revision cea12e9203af33ad68db110556123a714b9bc77d)
@@ -50,5 +50,6 @@
 #include <arch.h>
 #include <time/delay.h>
-#include <interrupt.h>
+#include <ddi/irq.h>
+#include <ddi/device.h>
 
 #define CLK_PORT1	0x40
@@ -58,8 +59,25 @@
 #define MAGIC_NUMBER	1194
 
-static void i8254_interrupt(int n, istate_t *istate);
+static irq_t i8254_irq;
+
+static irq_ownership_t i8254_claim(void)
+{
+	return IRQ_ACCEPT;
+}
+
+static void i8254_irq_handler(irq_t *irq, void *arg, ...)
+{
+	clock();
+}
 
 void i8254_init(void)
 {
+	irq_initialize(&i8254_irq);
+	i8254_irq.devno = device_assign_devno();
+	i8254_irq.inr = IRQ_CLK;
+	i8254_irq.claim = i8254_claim;
+	i8254_irq.handler = i8254_irq_handler;
+	irq_register(&i8254_irq);
+	
 	i8254_normal_operation();
 }
@@ -68,9 +86,8 @@
 {
 	outb(CLK_PORT4, 0x36);
-	pic_disable_irqs(1<<IRQ_CLK);
-	outb(CLK_PORT1, (CLK_CONST/HZ) & 0xf);
-	outb(CLK_PORT1, (CLK_CONST/HZ) >> 8);
-	pic_enable_irqs(1<<IRQ_CLK);
-	exc_register(VECTOR_CLK, "i8254_clock", (iroutine) i8254_interrupt);
+	pic_disable_irqs(1 << IRQ_CLK);
+	outb(CLK_PORT1, (CLK_CONST / HZ) & 0xf);
+	outb(CLK_PORT1, (CLK_CONST / HZ) >> 8);
+	pic_enable_irqs(1 << IRQ_CLK);
 }
 
@@ -130,10 +147,4 @@
 }
 
-void i8254_interrupt(int n, istate_t *istate)
-{
-	trap_virtual_eoi();
-	clock();
-}
-
 /** @}
  */
Index: kernel/arch/ia32/src/ia32.c
===================================================================
--- kernel/arch/ia32/src/ia32.c	(revision 8c84448b86410a212184bf076ceb45995c717df0)
+++ kernel/arch/ia32/src/ia32.c	(revision cea12e9203af33ad68db110556123a714b9bc77d)
@@ -58,8 +58,10 @@
 #include <arch/mm/memory_init.h>
 #include <interrupt.h>
+#include <ddi/irq.h>
 #include <arch/debugger.h>
 #include <proc/thread.h>
 #include <syscall/syscall.h>
 #include <console/console.h>
+#include <ddi/device.h>
 
 #ifdef CONFIG_SMP
@@ -72,14 +74,9 @@
 
 	if (config.cpu_active == 1) {
+		interrupt_init();
 		bios_init();
-		i8259_init();	/* PIC */
-		i8254_init();	/* hard clock */
 		
-		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 */
+		/* PIC */
+		i8259_init();
 	}
 }
@@ -88,4 +85,9 @@
 {
 	if (config.cpu_active == 1) {
+		/* Initialize IRQ routing */
+		irq_init(IRQ_COUNT, IRQ_COUNT);
+		
+		/* hard clock */
+		i8254_init();
 
 #ifdef CONFIG_FB
@@ -95,5 +97,4 @@
 #endif
 			ega_init();	/* video */
-		
 		
 		/* Enable debugger */
@@ -127,5 +128,6 @@
 void arch_post_smp_init(void)
 {
-	i8042_init();	/* keyboard controller */
+	/* keyboard controller */
+	i8042_init(device_assign_devno(), IRQ_KBD);
 }
 
Index: kernel/arch/ia32/src/interrupt.c
===================================================================
--- kernel/arch/ia32/src/interrupt.c	(revision 8c84448b86410a212184bf076ceb45995c717df0)
+++ kernel/arch/ia32/src/interrupt.c	(revision cea12e9203af33ad68db110556123a714b9bc77d)
@@ -52,4 +52,5 @@
 #include <ipc/sysipc.h>
 #include <interrupt.h>
+#include <ddi/irq.h>
 
 /*
@@ -61,5 +62,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);
@@ -84,14 +85,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) {
@@ -116,17 +126,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;
@@ -139,10 +149,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     
@@ -154,14 +164,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)
@@ -181,13 +237,4 @@
 }
 
-void trap_virtual_eoi(void)
-{
-	if (eoi_function)
-		eoi_function();
-	else
-		panic("no eoi_function\n");
-
-}
-
 /** @}
  */
Index: kernel/arch/ia32/src/mm/page.c
===================================================================
--- kernel/arch/ia32/src/mm/page.c	(revision 8c84448b86410a212184bf076ceb45995c717df0)
+++ kernel/arch/ia32/src/mm/page.c	(revision cea12e9203af33ad68db110556123a714b9bc77d)
@@ -112,5 +112,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/ia32/src/pm.c
===================================================================
--- kernel/arch/ia32/src/pm.c	(revision 8c84448b86410a212184bf076ceb45995c717df0)
+++ kernel/arch/ia32/src/pm.c	(revision cea12e9203af33ad68db110556123a714b9bc77d)
@@ -140,11 +140,6 @@
 		}
 		
-		idt_setoffset(d, ((uintptr_t) interrupt_handlers) + i*interrupt_handler_size);
-		exc_register(i, "undef", (iroutine) null_interrupt);
+		idt_setoffset(d, ((uintptr_t) interrupt_handlers) + i * interrupt_handler_size);
 	}
-	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);
 }
 
Index: kernel/genarch/include/kbd/i8042.h
===================================================================
--- kernel/genarch/include/kbd/i8042.h	(revision 8c84448b86410a212184bf076ceb45995c717df0)
+++ kernel/genarch/include/kbd/i8042.h	(revision cea12e9203af33ad68db110556123a714b9bc77d)
@@ -38,5 +38,5 @@
 #include <typedefs.h>
 
-extern void i8042_init(void);
+extern void i8042_init(devno_t devno, inr_t inr);
 extern void i8042_poll(void);
 extern void i8042_grab(void);
Index: kernel/genarch/src/kbd/i8042.c
===================================================================
--- kernel/genarch/src/kbd/i8042.c	(revision 8c84448b86410a212184bf076ceb45995c717df0)
+++ kernel/genarch/src/kbd/i8042.c	(revision cea12e9203af33ad68db110556123a714b9bc77d)
@@ -42,5 +42,4 @@
 #include <genarch/kbd/scanc_pc.h>
 #include <arch/drivers/i8042.h>
-#include <arch/interrupt.h>
 #include <cpu.h>
 #include <arch/asm.h>
@@ -50,4 +49,6 @@
 #include <console/console.h>
 #include <interrupt.h>
+#include <sysinfo/sysinfo.h>
+#include <ddi/irq.h>
 
 /* Keyboard commands. */
@@ -87,12 +88,18 @@
 };
 
-static void i8042_interrupt(int n, istate_t *istate);
-static void i8042_wait(void);
-
-static iroutine oldvector;
-/** Initialize keyboard and service interrupts using kernel routine */
+/** Structure for i8042's IRQ. */
+static irq_t i8042_irq;
+
+/** Wait until the controller reads its data. */
+static void i8042_wait(void) {
+	while (i8042_status_read() & i8042_WAIT_MASK) {
+		/* wait */
+	}
+}
+
 void i8042_grab(void)
 {
-	oldvector = exc_register(VECTOR_KBD, "i8042_interrupt", (iroutine) i8042_interrupt);
+	ipl_t ipl = interrupts_disable();
+	
 	i8042_wait();
 	i8042_command_write(i8042_SET_COMMAND);
@@ -100,65 +107,77 @@
 	i8042_data_write(i8042_COMMAND);
 	i8042_wait();
-}
-/** Resume the former interrupt vector */
+
+	spinlock_lock(&i8042_irq.lock);
+	i8042_irq.notif_cfg.notify = false;
+	spinlock_unlock(&i8042_irq.lock);
+	interrupts_restore(ipl);
+}
+
 void i8042_release(void)
 {
-	if (oldvector)
-		exc_register(VECTOR_KBD, "user_interrupt", oldvector);
+	ipl_t ipl = interrupts_disable();
+	spinlock_lock(&i8042_irq.lock);
+	if (i8042_irq.notif_cfg.answerbox)
+		i8042_irq.notif_cfg.notify = true;
+	spinlock_unlock(&i8042_irq.lock);
+	interrupts_restore(ipl);
+}
+
+static irq_ownership_t i8042_claim(void)
+{
+	return IRQ_ACCEPT;
+}
+
+static void i8042_irq_handler(irq_t *irq, void *arg, ...)
+{
+	if (irq->notif_cfg.notify && irq->notif_cfg.answerbox)
+		ipc_irq_send_notif(irq);
+	else {
+		uint8_t x;
+		uint8_t status;
+		
+		while (((status = i8042_status_read()) & i8042_BUFFER_FULL_MASK)) {
+			x = i8042_data_read();
+			
+			if ((status & i8042_MOUSE_DATA))
+				continue;
+			
+			if (x & KEY_RELEASE)
+				key_released(x ^ KEY_RELEASE);
+			else
+				key_pressed(x);
+		}
+	}
 }
 
 /** Initialize i8042. */
-void i8042_init(void)
-{
-	int i;
-
-	i8042_grab();
-        /* Prevent user from accidentaly releasing calling i8042_resume
-	 * and disabling keyboard 
-	 */
-	oldvector = NULL; 
-
-	trap_virtual_enable_irqs(1<<IRQ_KBD);
+void i8042_init(devno_t devno, inr_t inr)
+{
 	chardev_initialize("i8042_kbd", &kbrd, &ops);
 	stdin = &kbrd;
-
+	
+	irq_initialize(&i8042_irq);
+	i8042_irq.devno = devno;
+	i8042_irq.inr = inr;
+	i8042_irq.claim = i8042_claim;
+	i8042_irq.handler = i8042_irq_handler;
+	irq_register(&i8042_irq);
+	
+	trap_virtual_enable_irqs(1 << inr);
+	
 	/*
 	 * Clear input buffer.
 	 * Number of iterations is limited to prevent infinite looping.
 	 */
+	int i;
 	for (i = 0; (i8042_status_read() & i8042_BUFFER_FULL_MASK) && i < 100; i++) {
 		i8042_data_read();
-	}  
-}
-
-/** Process i8042 interrupt.
- *
- * @param n Interrupt vector.
- * @param istate Interrupted state.
- */
-void i8042_interrupt(int n, istate_t *istate)
-{
-	uint8_t x;
-	uint8_t status;
-
-	while (((status=i8042_status_read()) & i8042_BUFFER_FULL_MASK)) {
-		x = i8042_data_read();
-
-		if ((status & i8042_MOUSE_DATA))
-			continue;
-
-		if (x & KEY_RELEASE)
-			key_released(x ^ KEY_RELEASE);
-		else
-			key_pressed(x);
-	}
-	trap_virtual_eoi();
-}
-
-/** Wait until the controller reads its data. */
-void i8042_wait(void) {
-	while (i8042_status_read() & i8042_WAIT_MASK) {
-		/* wait */
-	}
+	}
+	
+	sysinfo_set_item_val("kbd", NULL, true);
+	sysinfo_set_item_val("kbd.devno", NULL, devno);
+	sysinfo_set_item_val("kbd.inr", NULL, inr);
+	
+	i8042_grab();
 }
 
