Index: kernel/arch/mips32/include/console.h
===================================================================
--- kernel/arch/mips32/include/console.h	(revision 26678e5a1f0f0a6dda91a9e89a03aa3ca86e447c)
+++ kernel/arch/mips32/include/console.h	(revision a000fd71083ee6c3d075fc87d57f7801ca6dd58b)
@@ -36,5 +36,5 @@
 #define KERN_mips32_CONSOLE_H_
 
-void console_init(void);
+extern void console_init(devno_t devno);
 
 #endif
Index: kernel/arch/mips32/include/drivers/msim.h
===================================================================
--- kernel/arch/mips32/include/drivers/msim.h	(revision 26678e5a1f0f0a6dda91a9e89a03aa3ca86e447c)
+++ kernel/arch/mips32/include/drivers/msim.h	(revision a000fd71083ee6c3d075fc87d57f7801ca6dd58b)
@@ -38,10 +38,5 @@
 #include <console/chardev.h>
 
-#define MSIM_VIDEORAM            	0xB0000000
-/** Address of 'keyboard' device. */
-#define MSIM_KBD_ADDRESS		0xB0000000
-#define MSIM_KBD_IRQ	2
-
-void msim_console(void);
+void msim_console(devno_t devno);
 void msim_kbd_release(void);
 void msim_kbd_grab(void);
Index: kernel/arch/mips32/include/drivers/serial.h
===================================================================
--- kernel/arch/mips32/include/drivers/serial.h	(revision 26678e5a1f0f0a6dda91a9e89a03aa3ca86e447c)
+++ kernel/arch/mips32/include/drivers/serial.h	(revision a000fd71083ee6c3d075fc87d57f7801ca6dd58b)
@@ -63,6 +63,6 @@
 }serial_t;
 
-void serial_console(void);
-int serial_init(void);
+extern void serial_console(devno_t devno);
+extern int serial_init(void);
 
 #endif
Index: kernel/arch/mips32/include/interrupt.h
===================================================================
--- kernel/arch/mips32/include/interrupt.h	(revision 26678e5a1f0f0a6dda91a9e89a03aa3ca86e447c)
+++ kernel/arch/mips32/include/interrupt.h	(revision a000fd71083ee6c3d075fc87d57f7801ca6dd58b)
@@ -38,15 +38,8 @@
 #include <arch/exception.h>
 
-#define IVT_ITEMS   40
-#define INT_OFFSET  32
-#define IRQ_COUNT   8
+#define IVT_ITEMS 32
+#define IVT_FIRST 0
 
-#define int_register(it, name, handler) exc_register(((it)+INT_OFFSET),name,handler)
-
-#define IRQ2	2
-#define IRQ3	3
-#define IRQ7	7
-
-#define TIMER_IRQ   	IRQ7
+extern function timer_fnc;
 
 extern void interrupt_init(void);
Index: kernel/arch/mips32/src/console.c
===================================================================
--- kernel/arch/mips32/src/console.c	(revision 26678e5a1f0f0a6dda91a9e89a03aa3ca86e447c)
+++ kernel/arch/mips32/src/console.c	(revision a000fd71083ee6c3d075fc87d57f7801ca6dd58b)
@@ -39,12 +39,12 @@
 #include <arch/drivers/msim.h>
 
-void console_init(void)
+void console_init(devno_t devno)
 {
 	if (arc_enabled()) {
 		arc_console();
 	} else if (serial_init()) {
-		serial_console();
+		serial_console(devno);
 	} else {
-		msim_console();
+		msim_console(devno);
 	}
 }
@@ -57,4 +57,5 @@
 	msim_kbd_grab();
 }
+
 /** Return console to userspace
  *
Index: kernel/arch/mips32/src/drivers/arc.c
===================================================================
--- kernel/arch/mips32/src/drivers/arc.c	(revision 26678e5a1f0f0a6dda91a9e89a03aa3ca86e447c)
+++ kernel/arch/mips32/src/drivers/arc.c	(revision a000fd71083ee6c3d075fc87d57f7801ca6dd58b)
@@ -354,13 +354,4 @@
 };
 
-iroutine old_timer;
-/** Do polling on timer interrupt */
-static void timer_replace(int n, istate_t *istate)
-{
-	arc_keyboard_poll();
-	old_timer(n, istate);
-	arc_keyboard_poll();
-}
-
 void arc_console(void)
 {
@@ -368,5 +359,5 @@
 	
 	chardev_initialize("arc_console", &console, &arc_ops);
-	old_timer = int_register(TIMER_IRQ, "arc_kb_poll", timer_replace);
+	timer_fnc = &arc_keyboard_poll;
 	stdin = &console;
 	stdout = &console;
Index: kernel/arch/mips32/src/drivers/msim.c
===================================================================
--- kernel/arch/mips32/src/drivers/msim.c	(revision 26678e5a1f0f0a6dda91a9e89a03aa3ca86e447c)
+++ kernel/arch/mips32/src/drivers/msim.c	(revision a000fd71083ee6c3d075fc87d57f7801ca6dd58b)
@@ -38,6 +38,14 @@
 #include <arch/cp0.h>
 #include <console/console.h>
+#include <ddi/irq.h>
+#include <sysinfo/sysinfo.h>
+
+/** Address of devices. */
+#define MSIM_VIDEORAM		0xB0000000
+#define MSIM_KBD_ADDRESS	0xB0000000
+#define MSIM_KBD_IRQ 		2
 
 static chardev_t console;
+static irq_t msim_irq;
 
 static void msim_write(chardev_t *dev, const char ch);
@@ -90,39 +98,57 @@
 
 /** Process keyboard interrupt. */
-static void msim_interrupt(int n, istate_t *istate)
+static void msim_irq_handler(irq_t *irq, void *arg, ...)
 {
-	char ch = 0;
+	if ((irq->notif_cfg.notify) && (irq->notif_cfg.answerbox))
+		ipc_irq_send_notif(irq);
+	else {
+		char ch = 0;
+		
+			ch = *((char *) MSIM_KBD_ADDRESS);
+			if (ch =='\r')
+				ch = '\n';
+			if (ch == 0x7f)
+				ch = '\b';
+			chardev_push_character(&console, ch);
+	}
+}
 
-	ch = *((char *) MSIM_KBD_ADDRESS);
-	if (ch =='\r')
-		ch = '\n';
-	if (ch == 0x7f)
-		ch = '\b';
-	chardev_push_character(&console, ch);
+static irq_ownership_t msim_claim(void)
+{
+	return IRQ_ACCEPT;
+}
+
+void msim_kbd_grab(void)
+{
+	msim_irq.notif_cfg.notify = false;
+}
+
+void msim_kbd_release(void)
+{
+	if (msim_irq.notif_cfg.answerbox)
+		msim_irq.notif_cfg.notify = true;
 }
 
 
 /* Return console object representing msim console */
-void msim_console(void)
+void msim_console(devno_t devno)
 {
 	chardev_initialize("msim_console", &console, &msim_ops);
-
-	int_register(MSIM_KBD_IRQ, "msim_kbd", msim_interrupt);
-
-	cp0_unmask_int(MSIM_KBD_IRQ);
-
 	stdin = &console;
 	stdout = &console;
-}
-
-static iroutine oldvector;
-void msim_kbd_grab(void)
-{
-	oldvector = int_register(MSIM_KBD_IRQ, "msim_kbd", msim_interrupt);
-}
-void msim_kbd_release(void)
-{
-	if (oldvector)
-		int_register(MSIM_KBD_IRQ, "user_interrupt", oldvector);
+	
+	irq_initialize(&msim_irq);
+	msim_irq.devno = devno;
+	msim_irq.inr = MSIM_KBD_IRQ;
+	msim_irq.claim = msim_claim;
+	msim_irq.handler = msim_irq_handler;
+	irq_register(&msim_irq);
+	
+	cp0_unmask_int(MSIM_KBD_IRQ);
+	
+	sysinfo_set_item_val("kbd", NULL, true);
+	sysinfo_set_item_val("kbd.devno", NULL, devno);
+	sysinfo_set_item_val("kbd.inr", NULL, MSIM_KBD_IRQ);
+	sysinfo_set_item_val("kbd.address.virtual", NULL, MSIM_KBD_ADDRESS);
 }
 
Index: kernel/arch/mips32/src/drivers/serial.c
===================================================================
--- kernel/arch/mips32/src/drivers/serial.c	(revision 26678e5a1f0f0a6dda91a9e89a03aa3ca86e447c)
+++ kernel/arch/mips32/src/drivers/serial.c	(revision a000fd71083ee6c3d075fc87d57f7801ca6dd58b)
@@ -38,5 +38,9 @@
 #include <console/chardev.h>
 #include <console/console.h>
+#include <ddi/irq.h>
 
+#define SERIAL_IRQ 2
+
+static irq_t serial_irq;
 static chardev_t console;
 static serial_t sconf[SERIAL_MAX];
@@ -92,9 +96,7 @@
 }
 
-
-/** Process keyboard interrupt. Does not work in simics? */
-static void serial_interrupt(int n, void *stack)
+static void serial_handler(void)
 {
-	serial_t *sd = (serial_t *)console.data;
+	serial_t *sd = (serial_t *) console.data;
 	char ch;
 
@@ -108,5 +110,17 @@
 }
 
+/** Process keyboard interrupt. Does not work in simics? */
+static void serial_irq_handler(irq_t *irq, void *arg, ...)
+{
+	if ((irq->notif_cfg.notify) && (irq->notif_cfg.answerbox))
+		ipc_irq_send_notif(irq);
+	else
+		serial_handler();
+}
 
+static irq_ownership_t serial_claim(void)
+{
+	return IRQ_ACCEPT;
+}
 
 static chardev_operations_t serial_ops = {
@@ -117,13 +131,5 @@
 };
 
-iroutine old_timer;
-/** Do polling on timer interrupt */
-static void timer_replace(int n, istate_t *istate)
-{
-	old_timer(n, istate);
-	serial_interrupt(n, istate);
-}
-
-void serial_console(void)
+void serial_console(devno_t devno)
 {
 	serial_t *sd = &sconf[0];
@@ -133,10 +139,16 @@
 	console.data = sd;
 	kb_enabled = true;
+	
+	irq_initialize(&serial_irq);
+	serial_irq.devno = devno;
+	serial_irq.inr = SERIAL_IRQ;
+	serial_irq.claim = serial_claim;
+	serial_irq.handler = serial_irq_handler;
+	irq_register(&serial_irq);
 
-//	int_register(2, "serial_drvr", serial_interrupt);
 	/* I don't know why, but the serial interrupts simply
 	 * don't work on simics
 	 */
-	old_timer = int_register(TIMER_IRQ, "serial_drvr_poll", timer_replace);
+	timer_fnc = &serial_handler;
 	
 	stdin = &console;
Index: kernel/arch/mips32/src/exception.c
===================================================================
--- kernel/arch/mips32/src/exception.c	(revision 26678e5a1f0f0a6dda91a9e89a03aa3ca86e447c)
+++ kernel/arch/mips32/src/exception.c	(revision a000fd71083ee6c3d075fc87d57f7801ca6dd58b)
@@ -46,4 +46,5 @@
 #include <func.h>
 #include <console/kconsole.h>
+#include <ddi/irq.h>
 #include <arch/debugger.h>
 
@@ -146,7 +147,23 @@
 	cause = (cp0_cause_read() >> 8) &0xff;
 	
-	for (i = 0; i < 8; i++)
-		if (cause & (1 << i))
-			exc_dispatch(i+INT_OFFSET, istate);
+	for (i = 0; i < 8; i++) {
+		if (cause & (1 << i)) {
+			irq_t *irq = irq_dispatch_and_lock(i);
+			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, i);
+#endif
+			}
+		}
+	}
 }
 
@@ -162,6 +179,7 @@
 
 	/* Clear exception table */
-	for (i=0;i < IVT_ITEMS; i++)
+	for (i = 0; i < IVT_ITEMS; i++)
 		exc_register(i, "undef", (iroutine) unhandled_exception);
+	
 	exc_register(EXC_Bp, "bkpoint", (iroutine) breakpoint_exception);
 	exc_register(EXC_RI, "resinstr", (iroutine) reserved_instr_exception);
Index: kernel/arch/mips32/src/interrupt.c
===================================================================
--- kernel/arch/mips32/src/interrupt.c	(revision 26678e5a1f0f0a6dda91a9e89a03aa3ca86e447c)
+++ kernel/arch/mips32/src/interrupt.c	(revision a000fd71083ee6c3d075fc87d57f7801ca6dd58b)
@@ -40,6 +40,13 @@
 #include <time/clock.h>
 #include <arch/drivers/arc.h>
+#include <ipc/sysipc.h>
+#include <ddi/device.h>
+#include <ddi/irq.h>
 
-#include <ipc/sysipc.h>
+#define IRQ_COUNT 8
+#define TIMER_IRQ 7
+
+function timer_fnc = NULL;
+static irq_t timer_irq;
 
 /** Disable interrupts.
@@ -92,5 +99,10 @@
 }
 
-static void timer_exception(int n, istate_t *istate)
+static irq_ownership_t timer_claim(void)
+{
+	return IRQ_ACCEPT;
+}
+
+static void timer_irq_handler(irq_t *irq, void *arg, ...)
 {
 	unsigned long drift;
@@ -104,16 +116,7 @@
 	cp0_compare_write(nextcount);
 	clock();
-}
-
-static void swint0(int n, istate_t *istate)
-{
-	cp0_cause_write(cp0_cause_read() & ~(1 << 8)); /* clear SW0 interrupt */
-	ipc_irq_send_notif(0);
-}
-
-static void swint1(int n, istate_t *istate)
-{
-	cp0_cause_write(cp0_cause_read() & ~(1 << 9)); /* clear SW1 interrupt */
-	ipc_irq_send_notif(1);
+	
+	if (timer_fnc != NULL)
+		timer_fnc();
 }
 
@@ -121,23 +124,15 @@
 void interrupt_init(void)
 {
-	int_register(TIMER_IRQ, "timer", timer_exception);
-	int_register(0, "swint0", swint0);
-	int_register(1, "swint1", swint1);
+	irq_init(IRQ_COUNT, IRQ_COUNT);
+	
+	irq_initialize(&timer_irq);
+	timer_irq.devno = device_assign_devno();
+	timer_irq.inr = TIMER_IRQ;
+	timer_irq.claim = timer_claim;
+	timer_irq.handler = timer_irq_handler;
+	irq_register(&timer_irq);
+	
 	timer_start();
-}
-
-static void ipc_int(int n, istate_t *istate)
-{
-	ipc_irq_send_notif(n-INT_OFFSET);
-}
-
-/* Reregister irq to be IPC-ready */
-void irq_ipc_bind_arch(unative_t irq)
-{
-	/* Do not allow to redefine timer */
-	/* Swint0, Swint1 are already handled */
-	if (irq == TIMER_IRQ || irq < 2)
-		return;
-	int_register(irq, "ipc_int", ipc_int);
+	cp0_unmask_int(TIMER_IRQ);
 }
 
Index: kernel/arch/mips32/src/mips32.c
===================================================================
--- kernel/arch/mips32/src/mips32.c	(revision 26678e5a1f0f0a6dda91a9e89a03aa3ca86e447c)
+++ kernel/arch/mips32/src/mips32.c	(revision a000fd71083ee6c3d075fc87d57f7801ca6dd58b)
@@ -55,4 +55,5 @@
 #include <genarch/fb/fb.h>
 #include <macros.h>
+#include <ddi/device.h>
 
 #include <arch/asm/regname.h>
@@ -99,9 +100,8 @@
 
 	/* Copy the exception vectors to the right places */
-	memcpy(TLB_EXC, (char *)tlb_refill_entry, EXCEPTION_JUMP_SIZE);
-	memcpy(NORM_EXC, (char *)exception_entry, EXCEPTION_JUMP_SIZE);
-	memcpy(CACHE_EXC, (char *)cache_error_entry, EXCEPTION_JUMP_SIZE);
-
-	interrupt_init();
+	memcpy(TLB_EXC, (char *) tlb_refill_entry, EXCEPTION_JUMP_SIZE);
+	memcpy(NORM_EXC, (char *) exception_entry, EXCEPTION_JUMP_SIZE);
+	memcpy(CACHE_EXC, (char *) cache_error_entry, EXCEPTION_JUMP_SIZE);
+	
 	/*
 	 * Switch to BEV normal level so that exception vectors point to the kernel.
@@ -114,11 +114,5 @@
 	 */
 	cp0_mask_all_int();
-
-	/*
-	 * Unmask hardware clock interrupt.
-	 */
-	cp0_unmask_int(TIMER_IRQ);
-
-	console_init();
+		
 	debugger_init();
 }
@@ -126,8 +120,10 @@
 void arch_post_mm_init(void)
 {
+	interrupt_init();
+	console_init(device_assign_devno());
 #ifdef CONFIG_FB
 	fb_init(0x12000000, 640, 480, 24, 1920, false); // gxemul framebuffer
 #endif
-	sysinfo_set_item_val("machine." STRING(MACHINE),NULL,1);
+	sysinfo_set_item_val("machine." STRING(MACHINE), NULL, 1);
 }
 
