Index: kernel/arch/ppc32/include/drivers/cuda.h
===================================================================
--- kernel/arch/ppc32/include/drivers/cuda.h	(revision d95f1e24a3ed2800461f743a8f9c97803cacd0a1)
+++ kernel/arch/ppc32/include/drivers/cuda.h	(revision 79f30e4f9ac9fbe8dece9d8d97a63496370dc290)
@@ -39,7 +39,5 @@
 #include <typedefs.h>
 
-#define CUDA_IRQ 10
-
-extern void cuda_init(uintptr_t base, size_t size);
+extern void cuda_init(devno_t devno, uintptr_t base, size_t size);
 extern int cuda_get_scancode(void);
 extern void cuda_grab(void);
Index: kernel/arch/ppc32/include/interrupt.h
===================================================================
--- kernel/arch/ppc32/include/interrupt.h	(revision d95f1e24a3ed2800461f743a8f9c97803cacd0a1)
+++ kernel/arch/ppc32/include/interrupt.h	(revision 79f30e4f9ac9fbe8dece9d8d97a63496370dc290)
@@ -38,10 +38,6 @@
 #include <arch/exception.h>
 
-#define IRQ_COUNT	64
-
-#define IVT_ITEMS   (16 + IRQ_COUNT)
-#define INT_OFFSET  16
-
-#define int_register(it, name, handler) exc_register(((it) + INT_OFFSET), name, handler)
+#define IVT_ITEMS 16
+#define IVT_FIRST 0
 
 #define VECTOR_DATA_STORAGE 2
Index: kernel/arch/ppc32/src/drivers/cuda.c
===================================================================
--- kernel/arch/ppc32/src/drivers/cuda.c	(revision d95f1e24a3ed2800461f743a8f9c97803cacd0a1)
+++ kernel/arch/ppc32/src/drivers/cuda.c	(revision 79f30e4f9ac9fbe8dece9d8d97a63496370dc290)
@@ -34,4 +34,5 @@
 
 #include <arch/drivers/cuda.h>
+#include <ddi/irq.h>
 #include <arch/asm.h>
 #include <console/console.h>
@@ -42,4 +43,5 @@
 #include <stdarg.h>
 
+#define CUDA_IRQ 10
 #define SPECIAL		'?'
 
@@ -61,5 +63,7 @@
 
 static volatile uint8_t *cuda = NULL;
-static iroutine vector;
+static irq_t cuda_irq;		/**< Cuda's IRQ. */
+
+static ipc_notif_cfg_t saved_notif_cfg;
 
 
@@ -249,13 +253,22 @@
 }
 
-static void cuda_irq(int n, istate_t *istate)
-{
-	int scan_code = cuda_get_scancode();
-	
-	if (scan_code != -1) {
-		uint8_t scancode = (uint8_t) scan_code;
-		if ((scancode & 0x80) != 0x80)
-			chardev_push_character(&kbrd, lchars[scancode & 0x7f]);
+static void cuda_irq_handler(irq_t *irq, void *arg, ...)
+{
+	if (irq->notif_cfg.answerbox)
+		ipc_irq_send_notif(irq);
+	else {
+		int scan_code = cuda_get_scancode();
+		
+		if (scan_code != -1) {
+			uint8_t scancode = (uint8_t) scan_code;
+			if ((scancode & 0x80) != 0x80)
+				chardev_push_character(&kbrd, lchars[scancode & 0x7f]);
+		}
 	}
+}
+
+static irq_ownership_t cuda_claim(void)
+{
+	return IRQ_ACCEPT;
 }
 
@@ -264,5 +277,11 @@
 void cuda_grab(void)
 {
-	vector = int_register(CUDA_IRQ, "cuda", cuda_irq);
+	if (cuda_irq.notif_cfg.answerbox) {
+		saved_notif_cfg = cuda_irq.notif_cfg;
+		cuda_irq.notif_cfg.answerbox = NULL;
+		cuda_irq.notif_cfg.code = NULL;
+		cuda_irq.notif_cfg.method = 0;
+		cuda_irq.notif_cfg.counter = 0;
+	}
 }
 
@@ -271,21 +290,31 @@
 void cuda_release(void)
 {
-	if (vector)
-		int_register(CUDA_IRQ, "user_interrupt", vector);
-}
-
-
-void cuda_init(uintptr_t base, size_t size)
-{
-	cuda = (uint8_t *) hw_map(base, size);
-	
-	int_register(CUDA_IRQ, "cuda", cuda_irq);
-	pic_enable_interrupt(CUDA_IRQ);
+	if (saved_notif_cfg.answerbox)
+		cuda_irq.notif_cfg = saved_notif_cfg;
+}
+
+
+void cuda_init(devno_t devno, uintptr_t base, size_t size)
+{
+	cuda = (uint8_t *) hw_map(base, size);	
 	
 	chardev_initialize("cuda_kbd", &kbrd, &ops);
 	stdin = &kbrd;
 	
-	sysinfo_set_item_val("cuda", NULL, true);
-	sysinfo_set_item_val("cuda.irq", NULL, CUDA_IRQ);
+	irq_initialize(&cuda_irq);
+	cuda_irq.devno = devno;
+	cuda_irq.inr = CUDA_IRQ;
+	cuda_irq.claim = cuda_claim;
+	cuda_irq.handler = cuda_irq_handler;
+	irq_register(&cuda_irq);
+	
+	pic_enable_interrupt(CUDA_IRQ);
+
+	sysinfo_set_item_val("kbd", NULL, true);
+	sysinfo_set_item_val("kbd.devno", NULL, devno);
+	sysinfo_set_item_val("kbd.inr", NULL, CUDA_IRQ);
+	sysinfo_set_item_val("kbd.address.virtual", NULL, base);
+
+	cuda_grab();
 }
 
Index: kernel/arch/ppc32/src/drivers/pic.c
===================================================================
--- kernel/arch/ppc32/src/drivers/pic.c	(revision d95f1e24a3ed2800461f743a8f9c97803cacd0a1)
+++ kernel/arch/ppc32/src/drivers/pic.c	(revision 79f30e4f9ac9fbe8dece9d8d97a63496370dc290)
@@ -81,11 +81,11 @@
 
 	pending = pic[PIC_PENDING_LOW];
-	if (pending) {
+	if (pending)
 		return fnzb32(pending);
-	}
+	
 	pending = pic[PIC_PENDING_HIGH];
-	if (pending) {
+	if (pending)
 		return fnzb32(pending) + 32;
-	}
+	
 	return -1;
 }
Index: kernel/arch/ppc32/src/interrupt.c
===================================================================
--- kernel/arch/ppc32/src/interrupt.c	(revision d95f1e24a3ed2800461f743a8f9c97803cacd0a1)
+++ kernel/arch/ppc32/src/interrupt.c	(revision 79f30e4f9ac9fbe8dece9d8d97a63496370dc290)
@@ -33,4 +33,5 @@
  */
 
+#include <ddi/irq.h>
 #include <interrupt.h>
 #include <arch/interrupt.h>
@@ -41,4 +42,5 @@
 #include <arch/drivers/pic.h>
 #include <arch/mm/tlb.h>
+#include <print.h>
 
 
@@ -57,7 +59,21 @@
 {
 	int inum;
-
+	
 	while ((inum = pic_get_pending()) != -1) {
-		exc_dispatch(inum + INT_OFFSET, istate);
+		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
+		}
 		pic_ack_interrupt(inum);
 	}
Index: kernel/arch/ppc32/src/ppc32.c
===================================================================
--- kernel/arch/ppc32/src/ppc32.c	(revision d95f1e24a3ed2800461f743a8f9c97803cacd0a1)
+++ kernel/arch/ppc32/src/ppc32.c	(revision 79f30e4f9ac9fbe8dece9d8d97a63496370dc290)
@@ -42,5 +42,9 @@
 #include <proc/uarg.h>
 #include <console/console.h>
+#include <ddi/device.h>
+#include <ddi/irq.h>
 #include <arch/drivers/pic.h>
+
+#define IRQ_COUNT	64
 
 bootinfo_t bootinfo;
@@ -71,10 +75,15 @@
 {
 	if (config.cpu_active == 1) {
+		/* Initialize framebuffer */
 		fb_init(bootinfo.screen.addr, bootinfo.screen.width, bootinfo.screen.height, bootinfo.screen.bpp, bootinfo.screen.scanline, false);
+		
+		/* Initialize IRQ routing */
+		irq_init(IRQ_COUNT, IRQ_COUNT);
 	
 		/* Initialize PIC */
 		pic_init(bootinfo.keyboard.addr, PAGE_SIZE);
 		
-		cuda_init(bootinfo.keyboard.addr + 0x16000, 2 * PAGE_SIZE);
+		/* Initialize I/O controller */
+		cuda_init(device_assign_devno(), bootinfo.keyboard.addr + 0x16000, 2 * PAGE_SIZE);
 		
 		/* Merge all zones to 1 big zone */
