Index: kernel/Makefile
===================================================================
--- kernel/Makefile	(revision 7038f55834b70c09d9b7e778acbd89c64f575274)
+++ kernel/Makefile	(revision 6ac14a70ed101ee9fa8379a5f9ef15a38f08aec5)
@@ -344,4 +344,7 @@
 	-rm -f kernel.bin kernel.raw kernel.map kernel.map.pre kernel.objdump kernel.disasm generic/src/debug/real_map.bin Makefile.depend* generic/include/arch generic/include/genarch arch/$(KARCH)/_link.ld
 	find generic/src/ arch/*/src/ genarch/src/ test/ -name '*.o' -follow -exec rm \{\} \;
+ifeq ($(PLATFORM),arm32)
+	rm -f arch/$(KARCH)/include/machine.h 
+endif
 	for arch in arch/* ; do \
 	    [ -e $$arch/_link.ld ] && rm $$arch/_link.ld 2>/dev/null ; \
@@ -351,4 +354,7 @@
 	ln -sfn ../../arch/$(KARCH)/include/ generic/include/arch
 	ln -sfn ../../genarch/include/ generic/include/genarch
+ifeq ($(PLATFORM),arm32)
+	ln -sfn mach/$(MACHINE)/$(MACHINE).h arch/$(KARCH)/include/machine.h 
+endif
 
 depend: archlinks
Index: kernel/arch/arm32/Makefile.inc
===================================================================
--- kernel/arch/arm32/Makefile.inc	(revision 7038f55834b70c09d9b7e778acbd89c64f575274)
+++ kernel/arch/arm32/Makefile.inc	(revision 6ac14a70ed101ee9fa8379a5f9ef15a38f08aec5)
@@ -46,5 +46,7 @@
 	arch/$(KARCH)/src/start.S \
 	arch/$(KARCH)/src/asm.S \
+	arch/$(KARCH)/src/exc_handler.S \
 	arch/$(KARCH)/src/arm32.c \
+	arch/$(KARCH)/src/machine_func.c \
 	arch/$(KARCH)/src/context.S \
 	arch/$(KARCH)/src/dummy.S \
@@ -59,4 +61,11 @@
 	arch/$(KARCH)/src/mm/page.c \
 	arch/$(KARCH)/src/mm/tlb.c \
-	arch/$(KARCH)/src/mm/page_fault.c \
-	arch/$(KARCH)/src/drivers/gxemul.c
+	arch/$(KARCH)/src/mm/page_fault.c 
+ifeq ($(MACHINE), testarm)
+        ARCH_SOURCES += arch/$(KARCH)/src/mach/testarm/testarm.c
+else ifeq ($(MACHINE), integratorcp)
+        ARCH_SOURCES += arch/$(KARCH)/src/mach/integratorcp/integratorcp.c
+endif
+ifeq ($(CONFIG_PL050), y)
+	ARCH_SOURCES += genarch/src/drivers/pl050/pl050.c
+endif
Index: kernel/arch/arm32/include/drivers/gxemul.h
===================================================================
--- kernel/arch/arm32/include/drivers/gxemul.h	(revision 7038f55834b70c09d9b7e778acbd89c64f575274)
+++ 	(revision )
@@ -1,71 +1,0 @@
-/*
- * Copyright (c) 2007 Michal Kebrt
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/** @addtogroup arm32gxemul GXemul
- *  @brief GXemul machine specific parts.
- *  @ingroup arm32
- * @{
- */
-/** @file
- *  @brief GXemul peripheries drivers declarations.
- */
-
-#ifndef KERN_arm32_GXEMUL_H_
-#define KERN_arm32_GXEMUL_H_
-
-/** Last interrupt number (beginning from 0) whose status is probed
- * from interrupt controller
- */
-#define GXEMUL_IRQC_MAX_IRQ  8
-#define GXEMUL_KBD_IRQ       2
-#define GXEMUL_TIMER_IRQ     4
-
-/** Timer frequency */
-#define GXEMUL_TIMER_FREQ  100
-
-#define GXEMUL_KBD_ADDRESS   0x10000000
-#define GXEMUL_MP_ADDRESS    0x11000000
-#define GXEMUL_FB_ADDRESS    0x12000000
-#define GXEMUL_RTC_ADDRESS   0x15000000
-#define GXEMUL_IRQC_ADDRESS  0x16000000
-
-extern void *gxemul_kbd;
-extern void *gxemul_rtc;
-extern void *gxemul_irqc;
-
-#define GXEMUL_HALT_OFFSET        0x010
-#define GXEMUL_RTC_FREQ_OFFSET    0x100
-#define GXEMUL_MP_MEMSIZE_OFFSET  0x090
-#define GXEMUL_RTC_ACK_OFFSET     0x110
-
-extern void gxemul_init(void);
-
-#endif
-
-/** @}
- */
Index: kernel/arch/arm32/include/exception.h
===================================================================
--- kernel/arch/arm32/include/exception.h	(revision 7038f55834b70c09d9b7e778acbd89c64f575274)
+++ kernel/arch/arm32/include/exception.h	(revision 6ac14a70ed101ee9fa8379a5f9ef15a38f08aec5)
@@ -137,4 +137,11 @@
 extern void exception_init(void);
 extern void print_istate(istate_t *istate);
+extern void reset_exception_entry(void);
+extern void irq_exception_entry(void);
+extern void fiq_exception_entry(void);
+extern void undef_instr_exception_entry(void);
+extern void prefetch_abort_exception_entry(void);
+extern void data_abort_exception_entry(void);
+extern void swi_exception_entry(void);
 
 
Index: kernel/arch/arm32/include/mach/integratorcp/integratorcp.h
===================================================================
--- kernel/arch/arm32/include/mach/integratorcp/integratorcp.h	(revision 6ac14a70ed101ee9fa8379a5f9ef15a38f08aec5)
+++ kernel/arch/arm32/include/mach/integratorcp/integratorcp.h	(revision 6ac14a70ed101ee9fa8379a5f9ef15a38f08aec5)
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 2009 Vineeth Pillai
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup arm32integratorcp
+ *  @brief Integratorcp machine specific parts.
+ *  @ingroup arm32
+ * @{
+ */
+/** @file
+ *  @brief Integratorcp peripheries drivers declarations.
+ */
+
+#ifndef KERN_arm32_ICP_H_
+#define KERN_arm32_ICP_H_
+
+#include <arch/machine_func.h>
+
+/** Last interrupt number (beginning from 0) whose status is probed
+ * from interrupt controller
+ */
+#define ICP_IRQC_MAX_IRQ  8
+#define ICP_KBD_IRQ       3
+#define ICP_TIMER_IRQ    6
+
+/** Timer frequency */
+#define ICP_TIMER_FREQ  10000
+
+#define ICP_UART			0x16000000
+#define ICP_KBD				0x18000000
+#define ICP_KBD_STAT			0x04
+#define ICP_KBD_DATA			0x08
+#define ICP_KBD_INTR_STAT		0x10
+#define ICP_RTC				0x13000000
+#define ICP_RTC1_LOAD_OFFSET		0x100
+#define ICP_RTC1_READ_OFFSET		0x104
+#define ICP_RTC1_CTL_OFFSET		0x108
+#define ICP_RTC1_INTRCLR_OFFSET		0x10C
+#define ICP_RTC1_INTRSTAT_OFFSET	0x114
+#define ICP_RTC1_BGLOAD_OFFSET		0x118
+#define ICP_RTC_CTL_VALUE		0x00E2
+#define ICP_IRQC			0x14000000
+#define ICP_IRQC_MASK_OFFSET		0xC
+#define ICP_IRQC_UNMASK_OFFSET		0x8
+#define ICP_FB				0x00800000
+#define ICP_FB_FRAME			(ICP_FB >> 12)
+#define ICP_FB_NUM_FRAME		512
+#define ICP_VGA				0xC0000000
+#define ICP_CMCR			0x10000000
+#define ICP_SDRAM_MASK			0x1C
+#define ICP_SDRAMCR_OFFSET		0x20
+
+typedef struct {
+        uintptr_t uart;
+        uintptr_t kbd_ctrl;
+        uintptr_t kbd_stat;
+        uintptr_t kbd_data;
+        uintptr_t kbd_intstat;
+        uintptr_t rtc;
+        uintptr_t rtc1_load;
+        uintptr_t rtc1_read;
+        uintptr_t rtc1_ctl;
+        uintptr_t rtc1_intrclr;
+        uintptr_t rtc1_intrstat;
+        uintptr_t rtc1_bgload;
+        uintptr_t irqc;
+        uintptr_t irqc_mask;
+        uintptr_t irqc_unmask;
+        uintptr_t vga;
+        uintptr_t cmcr;
+        uintptr_t sdramcr;
+} icp_hw_map_t;
+
+
+extern void icp_init(void);
+extern void icp_fb_init(void);
+extern void icp_output_init(void);
+extern void icp_input_init(void);
+extern void icp_release_console(void);
+extern void icp_grab_console(void);
+extern void icp_timer_irq_start(void);
+extern void icp_cpu_halt(void);
+extern void icp_irq_exception(int exc_no, istate_t *istate);
+extern uintptr_t icp_get_memory_size(void);
+extern uintptr_t icp_get_fb_address(void);
+extern void icp_fb_init(void);
+extern void icp_frame_init(void);
+
+#endif
+
+/** @}
+ */
Index: kernel/arch/arm32/include/mach/testarm/testarm.h
===================================================================
--- kernel/arch/arm32/include/mach/testarm/testarm.h	(revision 6ac14a70ed101ee9fa8379a5f9ef15a38f08aec5)
+++ kernel/arch/arm32/include/mach/testarm/testarm.h	(revision 6ac14a70ed101ee9fa8379a5f9ef15a38f08aec5)
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2007 Michal Kebrt
+ * Copyright (c) 2009 Vineeth Pillai
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup arm32gxemul GXemul
+ *  @brief GXemul machine specific parts.
+ *  @ingroup arm32
+ * @{
+ */
+/** @file
+ *  @brief GXemul peripheries drivers declarations.
+ */
+
+#ifndef KERN_arm32_GXEMUL_H_
+#define KERN_arm32_GXEMUL_H_
+
+#include <arch/machine_func.h>
+
+/** Last interrupt number (beginning from 0) whose status is probed
+ * from interrupt controller
+ */
+#define GXEMUL_IRQC_MAX_IRQ  8
+#define GXEMUL_KBD_IRQ       2
+#define GXEMUL_TIMER_IRQ     4
+
+/** Timer frequency */
+#define GXEMUL_TIMER_FREQ  100
+
+#define GXEMUL_KBD_ADDRESS   0x10000000
+#define GXEMUL_MP_ADDRESS    0x11000000
+#define GXEMUL_FB_ADDRESS    0x12000000
+#define GXEMUL_RTC_ADDRESS   0x15000000
+#define GXEMUL_IRQC_ADDRESS  0x16000000
+
+extern void *gxemul_kbd;
+extern void *gxemul_rtc;
+extern void *gxemul_irqc;
+
+#define GXEMUL_HALT_OFFSET        0x010
+#define GXEMUL_RTC_FREQ_OFFSET    0x100
+#define GXEMUL_MP_MEMSIZE_OFFSET  0x090
+#define GXEMUL_RTC_ACK_OFFSET     0x110
+
+extern void gxemul_init(void);
+extern void gxemul_fb_init(void);
+extern void gxemul_output_init(void);
+extern void gxemul_input_init(void);
+extern void gxemul_release_console(void);
+extern void gxemul_grab_console(void);
+extern void gxemul_timer_irq_start(void);
+extern void gxemul_cpu_halt(void);
+extern void gxemul_irq_exception(int exc_no, istate_t *istate);
+extern uintptr_t gxemul_get_memory_size(void);
+extern uintptr_t gxemul_get_fb_address(void);
+extern void gxemul_fb_init(void);
+extern void gxemul_frame_init(void);
+
+
+#endif
+
+/** @}
+ */
Index: kernel/arch/arm32/include/machine_func.h
===================================================================
--- kernel/arch/arm32/include/machine_func.h	(revision 6ac14a70ed101ee9fa8379a5f9ef15a38f08aec5)
+++ kernel/arch/arm32/include/machine_func.h	(revision 6ac14a70ed101ee9fa8379a5f9ef15a38f08aec5)
@@ -0,0 +1,132 @@
+/*
+ * Copyright (c) 2007 Michal Kebrt
+ * Copyright (c) 2009 Vineeth Pillai
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup arm32
+ * @{
+ */
+/** @file
+ *  @brief Declarations of machine specific functions.
+ *
+ *  These functions enable to differentiate more kinds of ARM emulators
+ *  or CPUs. It's the same concept as "arch" functions on the architecture
+ *  level.
+ */
+
+#ifndef KERN_arm32_MACHINE_FUNC_H_
+#define KERN_arm32_MACHINE_FUNC_H_
+
+#include <console/console.h>
+#include <arch/types.h>
+#include <arch/exception.h>
+
+#define MACHINE_GENFUNC	machine_genfunc
+
+struct arm_machine_ops {
+	void		(*machine_grab_console)(void);
+	void		(*machine_release_console)(void);
+	void		(*machine_init)(void);
+	void		(*machine_timer_irq_start)(void);
+	void		(*machine_cpu_halt)(void);
+	uintptr_t	(*machine_get_memory_size)(void);
+	void		(*machine_fb_init)(void);
+	void		(*machine_irq_exception)(int, istate_t*);
+	uintptr_t	(*machine_get_fb_address)(void);
+	void		(*machine_frame_init)(void);
+	void		(*machine_output_init)(void);
+	void		(*machine_input_init)(void);
+};
+
+extern struct arm_machine_ops machine_ops;
+
+
+/** Acquire console back for kernel. */
+extern void machine_grab_console(void);
+
+/** Return console to userspace. */
+extern void machine_release_console(void);
+
+
+/** Maps HW devices to the kernel address space using #hw_map. */
+extern void machine_init(void);
+
+
+/** Starts timer. */
+extern void machine_timer_irq_start(void);
+
+
+/** Halts CPU. */
+extern void machine_cpu_halt(void);
+
+
+/** Returns size of available memory.
+ *
+ *  @return Size of available memory.
+ */
+extern uintptr_t machine_get_memory_size(void);
+
+/** Initializes the Frame Buffer
+ *
+ */
+extern void machine_fb_init(void);
+
+
+/** Interrupt exception handler.
+ *
+ * @param exc_no Interrupt exception number.
+ * @param istate Saved processor state.
+ */
+extern void machine_irq_exception(int exc_no, istate_t *istate);
+
+
+/** Returns address of framebuffer device.
+ *
+ *  @return Address of framebuffer device.
+ */
+extern uintptr_t machine_get_fb_address(void);
+
+/*
+ * Machine specific frame initialization
+ */
+extern void machine_frame_init(void);
+
+/*
+ * configure the serial line output device.
+ */
+extern void machine_output_init(void);
+
+/*
+ * configure the serial line input device.
+ */
+extern void machine_input_init(void);
+
+extern void machine_genfunc(void);
+#endif
+
+/** @}
+ */
Index: kernel/arch/arm32/src/arm32.c
===================================================================
--- kernel/arch/arm32/src/arm32.c	(revision 7038f55834b70c09d9b7e778acbd89c64f575274)
+++ kernel/arch/arm32/src/arm32.c	(revision 6ac14a70ed101ee9fa8379a5f9ef15a38f08aec5)
@@ -38,11 +38,8 @@
 #include <genarch/fb/fb.h>
 #include <genarch/fb/visuals.h>
-#include <genarch/drivers/dsrln/dsrlnin.h>
-#include <genarch/drivers/dsrln/dsrlnout.h>
-#include <genarch/srln/srln.h>
 #include <sysinfo/sysinfo.h>
 #include <console/console.h>
 #include <ddi/irq.h>
-#include <arch/drivers/gxemul.h>
+#include <arch/machine.h>
 #include <print.h>
 #include <config.h>
@@ -78,5 +75,5 @@
 void arch_post_mm_init(void)
 {
-	gxemul_init();
+	machine_init();
 	
 	/* Initialize exception dispatch table */
@@ -85,16 +82,8 @@
 	
 #ifdef CONFIG_FB
-	fb_properties_t prop = {
-		.addr = GXEMUL_FB_ADDRESS,
-		.offset = 0,
-		.x = 640,
-		.y = 480,
-		.scan = 1920,
-		.visual = VISUAL_BGR_8_8_8,
-	};
-	fb_init(&prop);
+	machine_fb_init();
 #else
 #ifdef CONFIG_ARM_PRN
-	dsrlnout_init((ioport8_t *) gxemul_kbd);
+	machine_output_init();
 #endif /* CONFIG_ARM_PRN */
 #endif /* CONFIG_FB */
@@ -127,28 +116,5 @@
 void arch_post_smp_init(void)
 {
-#ifdef CONFIG_ARM_KBD
-	/*
-	 * Initialize the GXemul keyboard port. Then initialize the serial line
-	 * module and connect it to the GXemul keyboard.
-	 */
-	dsrlnin_instance_t *dsrlnin_instance
-	    = dsrlnin_init((dsrlnin_t *) gxemul_kbd, GXEMUL_KBD_IRQ);
-	if (dsrlnin_instance) {
-		srln_instance_t *srln_instance = srln_init();
-		if (srln_instance) {
-			indev_t *sink = stdin_wire();
-			indev_t *srln = srln_wire(srln_instance, sink);
-			dsrlnin_wire(dsrlnin_instance, srln);
-		}
-	}
-	
-	/*
-	 * This is the necessary evil until the userspace driver is entirely
-	 * self-sufficient.
-	 */
-	sysinfo_set_item_val("kbd", NULL, true);
-	sysinfo_set_item_val("kbd.inr", NULL, GXEMUL_KBD_IRQ);
-	sysinfo_set_item_val("kbd.address.virtual", NULL, (unative_t) gxemul_kbd);
-#endif
+	machine_input_init();
 }
 
@@ -157,5 +123,4 @@
 void before_task_runs_arch(void)
 {
-	tlb_invalidate_all();
 }
 
@@ -169,4 +134,5 @@
 	uint8_t *stck;
 	
+	tlb_invalidate_all();
 	stck = &THREAD->kstack[THREAD_STACK_SIZE - SP_DELTA];
 	supervisor_sp = (uintptr_t) stck;
@@ -184,6 +150,5 @@
 void cpu_halt(void)
 {
-	*((char *) (gxemul_kbd + GXEMUL_HALT_OFFSET))
-		= 0;
+	machine_cpu_halt();
 }
 
@@ -212,4 +177,5 @@
 void arch_grab_console(void)
 {
+	machine_grab_console();
 #ifdef CONFIG_FB
 	fb_redraw();
@@ -220,4 +186,5 @@
 void arch_release_console(void)
 {
+	machine_release_console();
 }
 
Index: kernel/arch/arm32/src/drivers/gxemul.c
===================================================================
--- kernel/arch/arm32/src/drivers/gxemul.c	(revision 7038f55834b70c09d9b7e778acbd89c64f575274)
+++ 	(revision )
@@ -1,51 +1,0 @@
-/*
- * Copyright (c) 2007 Michal Kebrt, Petr Stepan
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/** @addtogroup arm32gxemul
- * @{
- */
-/** @file
- *  @brief GXemul drivers.
- */
-
-#include <arch/drivers/gxemul.h>
-#include <mm/page.h>
-
-void *gxemul_kbd;
-void *gxemul_rtc;
-void *gxemul_irqc;
-
-void gxemul_init(void)
-{
-	gxemul_kbd = (void *) hw_map(GXEMUL_KBD_ADDRESS, PAGE_SIZE);
-	gxemul_rtc = (void *) hw_map(GXEMUL_RTC_ADDRESS, PAGE_SIZE);
-	gxemul_irqc = (void *) hw_map(GXEMUL_IRQC_ADDRESS, PAGE_SIZE);
-}
-
-/** @}
- */
Index: kernel/arch/arm32/src/exc_handler.S
===================================================================
--- kernel/arch/arm32/src/exc_handler.S	(revision 6ac14a70ed101ee9fa8379a5f9ef15a38f08aec5)
+++ kernel/arch/arm32/src/exc_handler.S	(revision 6ac14a70ed101ee9fa8379a5f9ef15a38f08aec5)
@@ -0,0 +1,199 @@
+#
+# Copyright (c) 2009 Vineeth Pillai
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# - Redistributions of source code must retain the above copyright
+#   notice, this list of conditions and the following disclaimer.
+# - Redistributions in binary form must reproduce the above copyright
+#   notice, this list of conditions and the following disclaimer in the
+#   documentation and/or other materials provided with the distribution.
+# - The name of the author may not be used to endorse or promote products
+#   derived from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+
+.text   
+
+.global irq_exception_entry
+.global fiq_exception_entry
+.global data_abort_exception_entry
+.global prefetch_abort_exception_entry
+.global undef_instr_exception_entry
+.global swi_exception_entry
+.global reset_exception_entry
+
+
+# Switches to kernel stack and saves all registers there.
+#
+#  The stack frame created by the function looks like:
+#
+#              |_________________|
+#              |                 |
+#              |     SPSR        |
+#              |                 |
+#              |_________________|
+#              | Stack Pointer   |
+#              |      of         |
+#              | Previous Mode   |
+#              |_________________|
+#              | Return address  |
+#              |      of         |
+#              | Previous Mode   |
+#              |_________________|
+#              |   R0  - R12     |
+#              |      of         |
+#              | Previous Mode   |
+#              |_________________|
+#              | Return address  |
+#              |     from        |
+#              |Exception Handler|
+#              |_________________|
+#              |                 |
+#
+#
+
+.macro SAVE_REGS_TO_STACK
+	stmfd r13!, {r0-r3}
+	mov r3, sp
+	add sp, sp, #16
+	mrs r1, cpsr
+	bic r1, r1, #0x1f
+	mrs r2, spsr
+	and r0, r2, #0x1f
+	cmp r0, #0x10
+	bne 1f
+
+	# prev mode was usermode
+	mov r0, lr
+
+	# Switch to supervisor mode
+	orr r1, r1, #0x13
+	msr cpsr_c, r1
+
+	# Load sp with [supervisor_sp]
+	ldr r13, =supervisor_sp
+	ldr r13, [r13]
+
+	# Populate the stack frame
+	msr spsr, r2
+	mov lr, r0
+	stmfd r13!, {lr}
+	stmfd r13!, {r4-r12}
+	ldmfd r3!, {r4-r7}
+	stmfd r13!, {r4-r7}
+	stmfd r13!, {r13, lr}^
+	stmfd r13!, {r2}
+	b 2f
+
+	# mode was not usermode
+1:
+	# Switch to previous mode which is undoubtedly the supervisor mode
+	orr r1, r1, r0
+	mov r0, lr
+	msr cpsr_c, r1
+
+	# Populate the stack frame
+	mov r1, sp
+	stmfd r13!, {r0}
+	stmfd r13!, {r4-r12}
+
+	# Store r0-r3 in r4-r7 and then push it on to stack
+	ldmfd r3!, {r4-r7}
+	stmfd r13!, {r4-r7}
+
+	# Push return address and stack pointer on to stack
+	stmfd r13!, {lr}
+	stmfd r13!, {r1}
+	mov lr, r0
+	msr spsr, r2
+	stmfd r13!, {r2}
+2:
+.endm
+
+.macro LOAD_REGS_FROM_STACK
+	ldmfd r13!, {r0}
+	msr spsr, r0
+	and r0, r0, #0x1f
+	cmp r0, #0x10
+	bne 1f
+
+	# return to user mode
+	ldmfd r13!, {r13, lr}^
+	b 2f
+
+	# return to non-user mode
+1:
+	ldmfd r13!, {r1, lr}
+
+2:
+	ldmfd r13!, {r0-r12, pc}^
+.endm
+
+reset_exception_entry:
+	SAVE_REGS_TO_STACK
+	mov r0, #0
+	mov r1, r13
+	bl exc_dispatch
+	LOAD_REGS_FROM_STACK
+
+irq_exception_entry:
+	sub lr, lr, #4
+	SAVE_REGS_TO_STACK
+	mov r0, #5
+	mov r1, r13
+	bl exc_dispatch
+	LOAD_REGS_FROM_STACK
+
+fiq_exception_entry:
+	sub lr, lr, #4
+	SAVE_REGS_TO_STACK
+	mov r0, #6
+	mov r1, r13
+	bl exc_dispatch
+	LOAD_REGS_FROM_STACK
+
+undef_instr_exception_entry:
+	SAVE_REGS_TO_STACK
+	mov r0, #1
+	mov r1, r13
+	bl exc_dispatch
+	LOAD_REGS_FROM_STACK
+
+prefetch_abort_exception_entry:
+	sub lr, lr, #4
+	SAVE_REGS_TO_STACK
+	mov r0, #3
+	mov r1, r13
+	bl exc_dispatch
+	LOAD_REGS_FROM_STACK
+
+data_abort_exception_entry:
+	sub lr, lr, #8
+	SAVE_REGS_TO_STACK
+	mov r0, #4
+	mov r1, r13
+	bl exc_dispatch
+	LOAD_REGS_FROM_STACK
+
+swi_exception_entry:
+	ldr r13, =exc_stack
+	SAVE_REGS_TO_STACK
+	mov r0, #2
+	mov r1, r13
+	bl exc_dispatch
+	LOAD_REGS_FROM_STACK
+
Index: kernel/arch/arm32/src/exception.c
===================================================================
--- kernel/arch/arm32/src/exception.c	(revision 7038f55834b70c09d9b7e778acbd89c64f575274)
+++ kernel/arch/arm32/src/exception.c	(revision 6ac14a70ed101ee9fa8379a5f9ef15a38f08aec5)
@@ -40,5 +40,5 @@
 #include <arch/mm/page_fault.h>
 #include <arch/barrier.h>
-#include <arch/drivers/gxemul.h>
+#include <arch/machine.h>
 #include <print.h>
 #include <syscall/syscall.h>
@@ -58,157 +58,4 @@
 /** Size of memory block occupied by exception vectors. */
 #define EXC_VECTORS_SIZE     (EXC_VECTORS * 4)
-
-/** Switches to kernel stack and saves all registers there.
- *
- * Temporary exception stack is used to save a few registers
- * before stack switch takes place.
- *
- */
-inline static void setup_stack_and_save_regs()
-{
-	asm volatile (
-		"ldr r13, =exc_stack\n"
-		"stmfd r13!, {r0}\n"
-		"mrs r0, spsr\n"
-		"and r0, r0, #0x1f\n"
-		"cmp r0, #0x10\n"
-		"bne 1f\n"
-		
-		/* prev mode was usermode */
-		"ldmfd r13!, {r0}\n"
-		"ldr r13, =supervisor_sp\n"
-		"ldr r13, [r13]\n"
-		"stmfd r13!, {lr}\n"
-		"stmfd r13!, {r0-r12}\n"
-		"stmfd r13!, {r13, lr}^\n"
-		"mrs r0, spsr\n"
-		"stmfd r13!, {r0}\n"
-		"b 2f\n"
-		
-		/* mode was not usermode */
-		"1:\n"
-			"stmfd r13!, {r1, r2, r3}\n"
-			"mrs r1, cpsr\n"
-			"mov r2, lr\n"
-			"bic r1, r1, #0x1f\n"
-			"orr r1, r1, r0\n"
-			"mrs r0, cpsr\n"
-			"msr cpsr_c, r1\n"
-			
-			"mov r3, r13\n"
-			"stmfd r13!, {r2}\n"
-			"mov r2, lr\n"
-			"stmfd r13!, {r4-r12}\n"
-			"mov r1, r13\n"
-			
-			/* the following two lines are for debugging */
-			"mov sp, #0\n"
-			"mov lr, #0\n"
-			"msr cpsr_c, r0\n"
-			
-			"ldmfd r13!, {r4, r5, r6, r7}\n"
-			"stmfd r1!, {r4, r5, r6}\n"
-			"stmfd r1!, {r7}\n"
-			"stmfd r1!, {r2}\n"
-			"stmfd r1!, {r3}\n"
-			"mrs r0, spsr\n"
-			"stmfd r1!, {r0}\n"
-			"mov r13, r1\n"
-			
-		"2:\n"
-	);
-}
-
-/** Returns from exception mode.
- * 
- * Previously saved state of registers (including control register)
- * is restored from the stack.
- */
-inline static void load_regs()
-{
-	asm volatile(
-		"ldmfd r13!, {r0}		\n"
-		"msr spsr, r0			\n"
-		"and r0, r0, #0x1f		\n"
-		"cmp r0, #0x10			\n"
-		"bne 1f				\n"
-
-		/* return to user mode */
-		"ldmfd r13!, {r13, lr}^		\n"
-		"b 2f				\n"
-
-		/* return to non-user mode */
-	"1:\n"
-		"ldmfd r13!, {r1, r2}		\n"
-		"mrs r3, cpsr			\n"
-		"bic r3, r3, #0x1f		\n"
-		"orr r3, r3, r0			\n"
-		"mrs r0, cpsr			\n"
-		"msr cpsr_c, r3			\n"
-
-		"mov r13, r1			\n"
-		"mov lr, r2			\n"
-		"msr cpsr_c, r0			\n"
-
-		/* actual return */
-	"2:\n"
-		"ldmfd r13, {r0-r12, pc}^\n"
-	);
-}
-
-
-/** Switch CPU to mode in which interrupts are serviced (currently it 
- * is Undefined mode).
- *
- * The default mode for interrupt servicing (Interrupt Mode)
- * can not be used because of nested interrupts (which can occur
- * because interrupts are enabled in higher levels of interrupt handler).
- */
-inline static void switch_to_irq_servicing_mode()
-{
-	/* switch to Undefined mode */
-	asm volatile(
-		/* save regs used during switching */
-		"stmfd sp!, {r0-r3}		\n"
-
-		/* save stack pointer and link register to r1, r2 */
-		"mov r1, sp			\n"
-		"mov r2, lr			\n"
-
-		/* mode switch */
-		"mrs r0, cpsr			\n"
-		"bic r0, r0, #0x1f		\n"
-		"orr r0, r0, #0x1b		\n"
-		"msr cpsr_c, r0			\n"
-
-		/* restore saved sp and lr */
-		"mov sp, r1			\n"
-		"mov lr, r2			\n"
-
-		/* restore original regs */
-		"ldmfd sp!, {r0-r3}		\n"
-	);
-}
-
-/** Calls exception dispatch routine. */
-#define CALL_EXC_DISPATCH(exception) \
-	asm volatile ( \
-		"mov r0, %[exc]\n" \
-		"mov r1, r13\n" \
-		"bl exc_dispatch\n" \
-		:: [exc] "i" (exception) \
-	);\
-
-/** General exception handler.
- *
- *  Stores registers, dispatches the exception,
- *  and finally restores registers and returns from exception processing.
- *
- *  @param exception Exception number.
- */
-#define PROCESS_EXCEPTION(exception) \
-	setup_stack_and_save_regs(); \
-	CALL_EXC_DISPATCH(exception) \
-	load_regs();
 
 /** Updates specified exception vector to jump to given handler.
@@ -233,69 +80,4 @@
 }
 
-/** Low-level Reset Exception handler. */
-static void reset_exception_entry(void)
-{
-	PROCESS_EXCEPTION(EXC_RESET);
-}
-
-/** Low-level Software Interrupt Exception handler. */
-static void swi_exception_entry(void)
-{
-	PROCESS_EXCEPTION(EXC_SWI);
-}
-
-/** Low-level Undefined Instruction Exception handler. */
-static void undef_instr_exception_entry(void)
-{
-	PROCESS_EXCEPTION(EXC_UNDEF_INSTR);
-}
-
-/** Low-level Fast Interrupt Exception handler. */
-static void fiq_exception_entry(void)
-{
-	PROCESS_EXCEPTION(EXC_FIQ);
-}
-
-/** Low-level Prefetch Abort Exception handler. */
-static void prefetch_abort_exception_entry(void)
-{
-	asm volatile (
-		"sub lr, lr, #4"
-	);
-	
-	PROCESS_EXCEPTION(EXC_PREFETCH_ABORT);
-} 
-
-/** Low-level Data Abort Exception handler. */
-static void data_abort_exception_entry(void)
-{
-	asm volatile (
-		"sub lr, lr, #8"
-	);
-	
-	PROCESS_EXCEPTION(EXC_DATA_ABORT);
-}
-
-/** Low-level Interrupt Exception handler.
- *
- * CPU is switched to Undefined mode before further interrupt processing
- * because of possible occurence of nested interrupt exception, which
- * would overwrite (and thus spoil) stack pointer.
- */
-static void irq_exception_entry(void)
-{
-	asm volatile (
-		"sub lr, lr, #4"
-	);
-	
-	setup_stack_and_save_regs();
-	
-	switch_to_irq_servicing_mode();
-	
-	CALL_EXC_DISPATCH(EXC_IRQ)
-
-	load_regs();
-}
-
 /** Software Interrupt handler.
  *
@@ -306,35 +88,4 @@
 	istate->r0 = syscall_handler(istate->r0, istate->r1, istate->r2,
 	    istate->r3, istate->r4, istate->r5, istate->r6);
-}
-
-/** Returns the mask of active interrupts. */
-static inline uint32_t gxemul_irqc_get_sources(void)
-{
-	return *((uint32_t *) gxemul_irqc);
-}
-
-/** Interrupt Exception handler.
- *
- * Determines the sources of interrupt and calls their handlers.
- */
-static void irq_exception(int exc_no, istate_t *istate)
-{
-	uint32_t sources = gxemul_irqc_get_sources();
-	unsigned int i;
-	
-	for (i = 0; i < GXEMUL_IRQC_MAX_IRQ; i++) {
-		if (sources & (1 << i)) {
-			irq_t *irq = irq_dispatch_and_lock(i);
-			if (irq) {
-				/* The IRQ handler was found. */
-				irq->handler(irq);
-				spinlock_unlock(&irq->lock);
-			} else {
-				/* Spurious interrupt.*/
-				printf("cpu%d: spurious interrupt (inum=%d)\n",
-				    CPU->id, i);
-			}
-		}
-	}
 }
 
@@ -385,4 +136,13 @@
 #endif
 
+/** Interrupt Exception handler.
+ *
+ * Determines the sources of interrupt and calls their handlers.
+ */
+static void irq_exception(int exc_no, istate_t *istate)
+{
+	machine_irq_exception(exc_no, istate);
+}
+
 /** Initializes exception handling.
  *
Index: kernel/arch/arm32/src/interrupt.c
===================================================================
--- kernel/arch/arm32/src/interrupt.c	(revision 7038f55834b70c09d9b7e778acbd89c64f575274)
+++ kernel/arch/arm32/src/interrupt.c	(revision 6ac14a70ed101ee9fa8379a5f9ef15a38f08aec5)
@@ -36,5 +36,5 @@
 #include <arch/asm.h>
 #include <arch/regutils.h>
-#include <arch/drivers/gxemul.h>
+#include <arch/machine.h>
 #include <ddi/irq.h>
 #include <ddi/device.h>
@@ -43,6 +43,4 @@
 /** Initial size of a table holding interrupt handlers. */
 #define IRQ_COUNT 8
-
-static irq_t gxemul_timer_irq;
 
 /** Disable interrupts.
@@ -53,5 +51,5 @@
 {
 	ipl_t ipl = current_status_reg_read();
-	
+
 	current_status_reg_control_write(STATUS_REG_IRQ_DISABLED_BIT | ipl);
 	
@@ -66,5 +64,5 @@
 {
 	ipl_t ipl = current_status_reg_read();
-	
+
 	current_status_reg_control_write(ipl & ~STATUS_REG_IRQ_DISABLED_BIT);
 	
@@ -92,39 +90,4 @@
 }
 
-/** Starts gxemul Real Time Clock device, which asserts regular interrupts.
- *
- * @param frequency Interrupts frequency (0 disables RTC).
- */
-static void gxemul_timer_start(uint32_t frequency)
-{
-	*((uint32_t *) (gxemul_rtc + GXEMUL_RTC_FREQ_OFFSET))
-	    = frequency;
-}
-
-static irq_ownership_t gxemul_timer_claim(irq_t *irq)
-{
-	return IRQ_ACCEPT;
-}
-
-/** Timer interrupt handler.
- *
- * @param irq Interrupt information.
- * @param arg Not used.
- */
-static void gxemul_timer_irq_handler(irq_t *irq)
-{
-	/*
-	* We are holding a lock which prevents preemption.
-	* Release the lock, call clock() and reacquire the lock again.
-	*/
-	spinlock_unlock(&irq->lock);
-	clock();
-	spinlock_lock(&irq->lock);
-	
-	/* acknowledge tick */
-	*((uint32_t *) (gxemul_rtc + GXEMUL_RTC_ACK_OFFSET))
-	    = 0;
-}
-
 /** Initialize basic tables for exception dispatching
  * and starts the timer.
@@ -133,14 +96,6 @@
 {
 	irq_init(IRQ_COUNT, IRQ_COUNT);
+	machine_timer_irq_start();
 	
-	irq_initialize(&gxemul_timer_irq);
-	gxemul_timer_irq.devno = device_assign_devno();
-	gxemul_timer_irq.inr = GXEMUL_TIMER_IRQ;
-	gxemul_timer_irq.claim = gxemul_timer_claim;
-	gxemul_timer_irq.handler = gxemul_timer_irq_handler;
-	
-	irq_register(&gxemul_timer_irq);
-	
-	gxemul_timer_start(GXEMUL_TIMER_FREQ);
 }
 
Index: kernel/arch/arm32/src/mach/integratorcp/integratorcp.c
===================================================================
--- kernel/arch/arm32/src/mach/integratorcp/integratorcp.c	(revision 6ac14a70ed101ee9fa8379a5f9ef15a38f08aec5)
+++ kernel/arch/arm32/src/mach/integratorcp/integratorcp.c	(revision 6ac14a70ed101ee9fa8379a5f9ef15a38f08aec5)
@@ -0,0 +1,360 @@
+/*
+ * Copyright (c) 2009 Vineeth Pillai
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup arm32integratorcp
+ * @{
+ */
+/** @file
+ *  @brief ICP drivers.
+ */
+
+#include <interrupt.h>
+#include <ipc/irq.h>
+#include <console/chardev.h>
+#include <genarch/drivers/pl050/pl050.h>
+#include <genarch/kbrd/kbrd.h>
+#include <console/console.h>
+#include <sysinfo/sysinfo.h>
+#include <print.h>
+#include <ddi/device.h>
+#include <mm/page.h>
+#include <mm/frame.h>
+#include <arch/mm/frame.h>
+#include <arch/mach/integratorcp/integratorcp.h>
+#include <genarch/fb/fb.h>
+#include <genarch/fb/visuals.h>
+#include <ddi/ddi.h>
+#include <print.h>
+
+#define SDRAM_SIZE	(sdram[((*(uint32_t *)(ICP_CMCR+ICP_SDRAMCR_OFFSET) & ICP_SDRAM_MASK) >> 2)])
+static parea_t fb_parea;
+static icp_hw_map_t icp_hw_map;
+static irq_t icp_timer_irq;
+struct arm_machine_ops machine_ops = {
+	MACHINE_GENFUNC,
+	MACHINE_GENFUNC,
+	icp_init,
+	icp_timer_irq_start,
+	icp_cpu_halt,
+	icp_get_memory_size,
+	icp_fb_init,
+	icp_irq_exception,
+	icp_get_fb_address,
+	icp_frame_init,
+	icp_output_init,
+	icp_input_init
+};
+
+static bool hw_map_init_called = false;
+static bool vga_init = false;
+uint32_t sdram[8] = {
+	16777216,	/* 16mb */
+	33554432,	/* 32mb */
+	67108864,	/* 64mb */
+	134217728,	/* 128mb */
+	268435456,	/* 256mb */
+	0,		/* Reserverd */
+	0,		/* Reserverd */
+	0		/* Reserverd */
+	};
+
+void icp_vga_init(void);
+
+/** Initializes the vga
+ *
+ */
+void icp_vga_init(void)
+{
+	*(uint32_t*)((char *)(icp_hw_map.cmcr)+0x14) = 0xA05F0000;
+	*(uint32_t*)((char *)(icp_hw_map.cmcr)+0x1C) = 0x12C11000;
+	*(uint32_t*)icp_hw_map.vga = 0x3F1F3F9C;
+	*(uint32_t*)((char *)(icp_hw_map.vga) + 0x4) = 0x080B61DF;
+	*(uint32_t*)((char *)(icp_hw_map.vga) + 0x8) = 0x067F3800;
+	*(uint32_t*)((char *)(icp_hw_map.vga) + 0x10) = ICP_FB;
+	*(uint32_t *)((char *)(icp_hw_map.vga) + 0x1C) = 0x182B;
+	*(uint32_t*)((char *)(icp_hw_map.cmcr)+0xC) = 0x33805000;
+	
+}
+
+/** Returns the mask of active interrupts. */
+static inline uint32_t icp_irqc_get_sources(void)
+{
+	return *((uint32_t *) icp_hw_map.irqc);
+}
+
+
+/** Masks interrupt.
+ * 
+ * @param irq interrupt number
+ */
+static inline void icp_irqc_mask(uint32_t irq)
+{
+	*((uint32_t *) icp_hw_map.irqc_mask) = (1 << irq);
+}
+
+
+/** Unmasks interrupt.
+ * 
+ * @param irq interrupt number
+ */
+static inline void icp_irqc_unmask(uint32_t irq)
+{
+	*((uint32_t *) icp_hw_map.irqc_unmask) |= (1 << irq);
+}
+
+/** Initializes the icp frame buffer */
+void icp_fb_init(void)
+{
+	fb_properties_t prop = {
+		.addr = 0,
+		.offset = 0,
+		.x = 640,
+		.y = 480,
+		.scan = 2560,
+		.visual = VISUAL_RGB_8_8_8_0,
+	};
+	prop.addr = icp_get_fb_address();
+	fb_init(&prop);
+	fb_parea.pbase = ICP_FB;
+	fb_parea.frames = 300;
+	ddi_parea_register(&fb_parea);
+}
+
+/** Initializes icp_hw_map. */
+void icp_init(void)
+{
+	icp_hw_map.uart = hw_map(ICP_UART, PAGE_SIZE);
+	icp_hw_map.kbd_ctrl = hw_map(ICP_KBD, PAGE_SIZE);
+	icp_hw_map.kbd_stat = icp_hw_map.kbd_ctrl + ICP_KBD_STAT;
+	icp_hw_map.kbd_data = icp_hw_map.kbd_ctrl + ICP_KBD_DATA;
+	icp_hw_map.kbd_intstat = icp_hw_map.kbd_ctrl + ICP_KBD_INTR_STAT;
+	icp_hw_map.rtc = hw_map(ICP_RTC, PAGE_SIZE);
+	icp_hw_map.rtc1_load = icp_hw_map.rtc + ICP_RTC1_LOAD_OFFSET;
+	icp_hw_map.rtc1_read = icp_hw_map.rtc + ICP_RTC1_READ_OFFSET;
+	icp_hw_map.rtc1_ctl = icp_hw_map.rtc + ICP_RTC1_CTL_OFFSET;
+	icp_hw_map.rtc1_intrclr = icp_hw_map.rtc + ICP_RTC1_INTRCLR_OFFSET;
+	icp_hw_map.rtc1_bgload = icp_hw_map.rtc + ICP_RTC1_BGLOAD_OFFSET;
+	icp_hw_map.rtc1_intrstat = icp_hw_map.rtc + ICP_RTC1_INTRSTAT_OFFSET;
+
+	icp_hw_map.irqc = hw_map(ICP_IRQC, PAGE_SIZE);
+	icp_hw_map.irqc_mask = icp_hw_map.irqc + ICP_IRQC_MASK_OFFSET;
+	icp_hw_map.irqc_unmask = icp_hw_map.irqc + ICP_IRQC_UNMASK_OFFSET;
+	icp_hw_map.cmcr = hw_map(ICP_CMCR, PAGE_SIZE);
+	icp_hw_map.sdramcr = icp_hw_map.cmcr + ICP_SDRAMCR_OFFSET;
+	icp_hw_map.vga = hw_map(ICP_VGA, PAGE_SIZE);
+
+	hw_map_init_called = true;
+}
+
+
+/** Acquire console back for kernel. */
+void icp_grab_console(void)
+{
+}
+
+/** Return console to userspace. */
+void icp_release_console(void)
+{
+}
+
+/** Starts icp Real Time Clock device, which asserts regular interrupts.
+ * 
+ * @param frequency Interrupts frequency (0 disables RTC).
+ */
+static void icp_timer_start(uint32_t frequency)
+{
+	icp_irqc_mask(ICP_TIMER_IRQ);
+	*((uint32_t*) icp_hw_map.rtc1_load) = frequency;
+	*((uint32_t*) icp_hw_map.rtc1_bgload) = frequency;
+	*((uint32_t*) icp_hw_map.rtc1_ctl) = ICP_RTC_CTL_VALUE;
+	icp_irqc_unmask(ICP_TIMER_IRQ);
+}
+
+static irq_ownership_t icp_timer_claim(irq_t *irq)
+{
+	if (icp_hw_map.rtc1_intrstat) {
+		*((uint32_t*) icp_hw_map.rtc1_intrclr) = 1;
+		return IRQ_ACCEPT;
+	} else
+		return IRQ_DECLINE;
+}
+
+/** Timer interrupt handler.
+ *
+ * @param irq Interrupt information.
+ * @param arg Not used.
+ */
+static void icp_timer_irq_handler(irq_t *irq)
+{
+	/*
+	* We are holding a lock which prevents preemption.
+	* Release the lock, call clock() and reacquire the lock again.
+	*/
+
+	spinlock_unlock(&irq->lock);
+	clock();
+	spinlock_lock(&irq->lock);
+
+}
+
+/** Initializes and registers timer interrupt handler. */
+static void icp_timer_irq_init(void)
+{
+	irq_initialize(&icp_timer_irq);
+	icp_timer_irq.devno = device_assign_devno();
+	icp_timer_irq.inr = ICP_TIMER_IRQ;
+	icp_timer_irq.claim = icp_timer_claim;
+	icp_timer_irq.handler = icp_timer_irq_handler;
+
+	irq_register(&icp_timer_irq);
+}
+
+
+/** Starts timer.
+ *
+ * Initiates regular timer interrupts after initializing
+ * corresponding interrupt handler.
+ */
+void icp_timer_irq_start(void)
+{
+	icp_timer_irq_init();
+	icp_timer_start(ICP_TIMER_FREQ);
+}
+
+/** Returns the size of emulated memory.
+ *
+ * @return Size in bytes.
+ */
+size_t icp_get_memory_size(void) 
+{
+	if (hw_map_init_called) {
+		return (sdram[((*(uint32_t *)icp_hw_map.sdramcr & ICP_SDRAM_MASK) >> 2)]);
+	} else {
+		return SDRAM_SIZE;
+	}
+	
+}
+
+/** Stops icp. */
+void icp_cpu_halt(void)
+{
+	while (1);
+}
+
+/** interrupt exception handler.
+ *
+ * Determines sources of the interrupt from interrupt controller and
+ * calls high-level handlers for them.
+ *
+ * @param exc_no Interrupt exception number.
+ * @param istate Saved processor state.
+ */
+void icp_irq_exception(int exc_no, istate_t *istate)
+{
+	uint32_t sources = icp_irqc_get_sources();
+	int i;
+	
+	for (i = 0; i < ICP_IRQC_MAX_IRQ; i++) {
+		if (sources & (1 << i)) {
+			irq_t *irq = irq_dispatch_and_lock(i);
+			if (irq) {
+				/* The IRQ handler was found. */
+				irq->handler(irq);
+				spinlock_unlock(&irq->lock);
+			} else {
+				/* Spurious interrupt.*/
+				printf("cpu%d: spurious interrupt (inum=%d)\n",
+				    CPU->id, i);
+			}
+		}
+	}
+}
+
+/** Returns address of framebuffer device.
+ *
+ *  @return Address of framebuffer device.
+ */
+uintptr_t icp_get_fb_address(void)
+{
+	if (!vga_init) {
+		icp_vga_init();
+		vga_init = true;
+	}
+	return (uintptr_t) ICP_FB;
+}
+
+/*
+ * Integrator specific frame initialization
+ */
+void
+icp_frame_init(void)
+{
+	frame_mark_unavailable(ICP_FB_FRAME, ICP_FB_NUM_FRAME);
+	frame_mark_unavailable(0, 256);
+}
+
+void icp_output_init(void)
+{
+}
+
+void icp_input_init(void)
+{
+
+	pl050_t *pl050 = malloc(sizeof(pl050_t), FRAME_ATOMIC);
+	pl050->status = (ioport8_t *)icp_hw_map.kbd_stat;
+	pl050->data = (ioport8_t *)icp_hw_map.kbd_data;
+	pl050->ctrl = (ioport8_t *)icp_hw_map.kbd_ctrl;
+		
+	pl050_instance_t *pl050_instance = pl050_init(pl050, ICP_KBD_IRQ);
+	if (pl050_instance) {
+		kbrd_instance_t *kbrd_instance = kbrd_init();
+		if (kbrd_instance) {
+			icp_irqc_mask(ICP_KBD_IRQ);
+			indev_t *sink = stdin_wire();
+			indev_t *kbrd = kbrd_wire(kbrd_instance, sink);
+			pl050_wire(pl050_instance, kbrd);
+			icp_irqc_unmask(ICP_KBD_IRQ);
+		}
+	}
+
+	/*
+	 * This is the necessary evil until the userspace driver is entirely
+	 * self-sufficient.
+	 */
+	sysinfo_set_item_val("kbd", NULL, true);
+	sysinfo_set_item_val("kbd.inr", NULL, ICP_KBD_IRQ);
+	sysinfo_set_item_val("kbd.address.status", NULL,
+	    (uintptr_t) icp_hw_map.kbd_stat);
+	sysinfo_set_item_val("kbd.address.data", NULL,
+	    (uintptr_t) icp_hw_map.kbd_data);
+
+}
+
+
+/** @}
+ */
Index: kernel/arch/arm32/src/mach/testarm/testarm.c
===================================================================
--- kernel/arch/arm32/src/mach/testarm/testarm.c	(revision 6ac14a70ed101ee9fa8379a5f9ef15a38f08aec5)
+++ kernel/arch/arm32/src/mach/testarm/testarm.c	(revision 6ac14a70ed101ee9fa8379a5f9ef15a38f08aec5)
@@ -0,0 +1,242 @@
+/*
+ * Copyright (c) 2007 Michal Kebrt, Petr Stepan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup arm32gxemul
+ * @{
+ */
+/** @file
+ *  @brief GXemul drivers.
+ */
+
+#include <arch/exception.h>
+#include <arch/mach/testarm/testarm.h>
+#include <mm/page.h>
+#include <genarch/fb/fb.h>
+#include <genarch/fb/visuals.h>
+#include <genarch/drivers/dsrln/dsrlnin.h>
+#include <genarch/drivers/dsrln/dsrlnout.h>
+#include <genarch/srln/srln.h>
+#include <console/console.h>
+#include <ddi/irq.h>
+#include <ddi/device.h>
+#include <config.h>
+#include <sysinfo/sysinfo.h>
+#include <interrupt.h>
+#include <print.h>
+
+
+void *gxemul_kbd;
+void *gxemul_rtc;
+void *gxemul_irqc;
+static irq_t gxemul_timer_irq;
+
+struct arm_machine_ops machine_ops = {
+	MACHINE_GENFUNC,
+	MACHINE_GENFUNC,
+	gxemul_init,
+	gxemul_timer_irq_start,
+	gxemul_cpu_halt,
+	gxemul_get_memory_size,
+	gxemul_fb_init,
+	gxemul_irq_exception,
+	gxemul_get_fb_address,
+	gxemul_frame_init,
+	gxemul_output_init,
+	gxemul_input_init
+};
+
+void gxemul_init(void)
+{
+	gxemul_kbd = (void *) hw_map(GXEMUL_KBD_ADDRESS, PAGE_SIZE);
+	gxemul_rtc = (void *) hw_map(GXEMUL_RTC_ADDRESS, PAGE_SIZE);
+	gxemul_irqc = (void *) hw_map(GXEMUL_IRQC_ADDRESS, PAGE_SIZE);
+}
+
+void gxemul_fb_init(void)
+{
+	fb_properties_t prop = {
+		.addr = GXEMUL_FB_ADDRESS,
+		.offset = 0,
+		.x = 640,
+		.y = 480,
+		.scan = 1920,
+		.visual = VISUAL_BGR_8_8_8,
+	};
+	fb_init(&prop);
+}
+
+void gxemul_output_init(void)
+{
+	dsrlnout_init((ioport8_t *) gxemul_kbd);
+}
+
+void gxemul_input_init(void)
+{
+#ifdef CONFIG_ARM_KBD
+	/*
+	 * Initialize the GXemul keyboard port. Then initialize the serial line
+	 * module and connect it to the GXemul keyboard.
+	 */
+	dsrlnin_instance_t *dsrlnin_instance
+	    = dsrlnin_init((dsrlnin_t *) gxemul_kbd, GXEMUL_KBD_IRQ);
+	if (dsrlnin_instance) {
+		srln_instance_t *srln_instance = srln_init();
+		if (srln_instance) {
+			indev_t *sink = stdin_wire();
+			indev_t *srln = srln_wire(srln_instance, sink);
+			dsrlnin_wire(dsrlnin_instance, srln);
+		}
+	}
+
+	/*
+	 * This is the necessary evil until the userspace driver is entirely
+	 * self-sufficient.
+	 */
+	sysinfo_set_item_val("kbd", NULL, true);
+	sysinfo_set_item_val("kbd.inr", NULL, GXEMUL_KBD_IRQ);
+	sysinfo_set_item_val("kbd.address.virtual", NULL, (unative_t) gxemul_kbd);
+#endif
+}
+
+/** Starts gxemul Real Time Clock device, which asserts regular interrupts.
+ *
+ * @param frequency Interrupts frequency (0 disables RTC).
+ */
+static void gxemul_timer_start(uint32_t frequency)
+{
+	*((uint32_t *) (gxemul_rtc + GXEMUL_RTC_FREQ_OFFSET))
+	    = frequency;
+}
+
+static irq_ownership_t gxemul_timer_claim(irq_t *irq)
+{
+	return IRQ_ACCEPT;
+}
+
+/** Timer interrupt handler.
+ *
+ * @param irq Interrupt information.
+ * @param arg Not used.
+ */
+static void gxemul_timer_irq_handler(irq_t *irq)
+{
+	/*
+	* We are holding a lock which prevents preemption.
+	* Release the lock, call clock() and reacquire the lock again.
+	*/
+	spinlock_unlock(&irq->lock);
+	clock();
+	spinlock_lock(&irq->lock);
+
+	/* acknowledge tick */
+	*((uint32_t *) (gxemul_rtc + GXEMUL_RTC_ACK_OFFSET))
+	    = 0;
+}
+
+/** Initializes and registers timer interrupt handler. */
+static void gxemul_timer_irq_init(void)
+{
+        irq_initialize(&gxemul_timer_irq);
+        gxemul_timer_irq.devno = device_assign_devno();
+        gxemul_timer_irq.inr = GXEMUL_TIMER_IRQ;
+        gxemul_timer_irq.claim = gxemul_timer_claim;
+        gxemul_timer_irq.handler = gxemul_timer_irq_handler;
+
+        irq_register(&gxemul_timer_irq);
+}
+
+
+/** Starts timer.
+ *
+ * Initiates regular timer interrupts after initializing
+ * corresponding interrupt handler.
+ */
+void gxemul_timer_irq_start(void)
+{
+        gxemul_timer_irq_init();
+        gxemul_timer_start(GXEMUL_TIMER_FREQ);
+}
+
+/** Returns the size of emulated memory.
+ *
+ * @return Size in bytes.
+ */
+uintptr_t gxemul_get_memory_size(void)
+{
+        return  *((uintptr_t *) (GXEMUL_MP_ADDRESS + GXEMUL_MP_MEMSIZE_OFFSET));
+}
+
+
+/** Returns the mask of active interrupts. */
+static inline uint32_t gxemul_irqc_get_sources(void)
+{
+	return *((uint32_t *) gxemul_irqc);
+}
+
+/** Interrupt Exception handler.
+ *
+ * Determines the sources of interrupt and calls their handlers.
+ */
+void gxemul_irq_exception(int exc_no, istate_t *istate)
+{
+	uint32_t sources = gxemul_irqc_get_sources();
+	unsigned int i;
+
+	for (i = 0; i < GXEMUL_IRQC_MAX_IRQ; i++) {
+		if (sources & (1 << i)) {
+			irq_t *irq = irq_dispatch_and_lock(i);
+			if (irq) {
+				/* The IRQ handler was found. */
+				irq->handler(irq);
+				spinlock_unlock(&irq->lock);
+			} else {
+				/* Spurious interrupt.*/
+				printf("cpu%d: spurious interrupt (inum=%d)\n",
+				    CPU->id, i);
+			}
+		}
+	}
+}
+
+void gxemul_cpu_halt(void)
+{
+	*((char *) (gxemul_kbd + GXEMUL_HALT_OFFSET)) = 0;
+}
+
+void gxemul_frame_init(void)
+{
+}
+
+uintptr_t gxemul_get_fb_address()
+{
+	return ((uintptr_t)GXEMUL_FB_ADDRESS);
+}
+
+
+/** @}
+ */
Index: kernel/arch/arm32/src/machine_func.c
===================================================================
--- kernel/arch/arm32/src/machine_func.c	(revision 6ac14a70ed101ee9fa8379a5f9ef15a38f08aec5)
+++ kernel/arch/arm32/src/machine_func.c	(revision 6ac14a70ed101ee9fa8379a5f9ef15a38f08aec5)
@@ -0,0 +1,147 @@
+/*
+ * Copyright (c) 2009 Vineeth Pillai
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup arm32
+ * @{
+ */
+/** @file
+ *  @brief Definitions of machine specific functions.
+ *
+ *  These functions enable to differentiate more kinds of ARM emulators
+ *  or CPUs. It's the same concept as "arch" functions on the architecture
+ *  level.
+ */
+
+#include <arch/machine_func.h>
+
+
+/** Acquire console back for kernel. */
+void machine_grab_console(void)
+{
+	(machine_ops.machine_grab_console)();
+}
+
+/** Return console to userspace. */
+void machine_release_console(void)
+{
+	(machine_ops.machine_release_console)();
+}
+
+
+/** Maps HW devices to the kernel address space using #hw_map. */
+void machine_init(void)
+{
+	(machine_ops.machine_init)();
+}
+
+
+/** Starts timer. */
+void machine_timer_irq_start(void)
+{
+	(machine_ops.machine_timer_irq_start)();
+}
+
+
+/** Halts CPU. */
+void machine_cpu_halt(void)
+{
+	(machine_ops.machine_cpu_halt)();
+}
+
+
+/** Returns size of available memory.
+ *
+ *  @return Size of available memory.
+ */
+uintptr_t machine_get_memory_size(void)
+{
+	return (machine_ops.machine_get_memory_size)();
+}
+
+/** Initializes the Frame Buffer
+ *
+ */
+void machine_fb_init(void)
+{
+	(machine_ops.machine_fb_init)();
+}
+
+
+/** Interrupt exception handler.
+ *
+ * @param exc_no Interrupt exception number.
+ * @param istate Saved processor state.
+ */
+void machine_irq_exception(int exc_no, istate_t *istate)
+{
+	(machine_ops.machine_irq_exception)(exc_no, istate);
+}
+
+
+/** Returns address of framebuffer device.
+ *
+ *  @return Address of framebuffer device.
+ */
+uintptr_t machine_get_fb_address(void)
+{
+	return (machine_ops.machine_get_fb_address)();
+}
+
+/*
+ * Machine specific frame initialization
+ */
+void machine_frame_init(void)
+{
+	(machine_ops.machine_frame_init)();
+}
+
+/*
+ * configure the output device.
+ */
+void machine_output_init(void)
+{
+	(machine_ops.machine_output_init)();
+}
+
+/*
+ * configure the input device.
+ */
+void machine_input_init(void)
+{
+	(machine_ops.machine_input_init)();
+}
+
+/*
+ * Generic function to use, if sepcific function doesn't define any of the above functions.
+ */
+void machine_genfunc()
+{
+}
+
+/** @}
+ */
Index: kernel/arch/arm32/src/mm/frame.c
===================================================================
--- kernel/arch/arm32/src/mm/frame.c	(revision 7038f55834b70c09d9b7e778acbd89c64f575274)
+++ kernel/arch/arm32/src/mm/frame.c	(revision 6ac14a70ed101ee9fa8379a5f9ef15a38f08aec5)
@@ -36,5 +36,5 @@
 #include <mm/frame.h>
 #include <arch/mm/frame.h>
-#include <arch/drivers/gxemul.h>
+#include <arch/machine.h>
 #include <config.h>
 
@@ -45,5 +45,5 @@
 void frame_arch_init(void)
 {
-	last_frame = *((uintptr_t *) (GXEMUL_MP_ADDRESS + GXEMUL_MP_MEMSIZE_OFFSET));
+	last_frame = machine_get_memory_size();
 	
 	/* All memory as one zone */
@@ -54,4 +54,6 @@
 	frame_mark_unavailable(BOOT_PAGE_TABLE_START_FRAME,
 	    BOOT_PAGE_TABLE_SIZE_IN_FRAMES);
+
+	machine_frame_init();
 }
 
Index: kernel/arch/arm32/src/start.S
===================================================================
--- kernel/arch/arm32/src/start.S	(revision 7038f55834b70c09d9b7e778acbd89c64f575274)
+++ kernel/arch/arm32/src/start.S	(revision 6ac14a70ed101ee9fa8379a5f9ef15a38f08aec5)
@@ -36,9 +36,31 @@
 
 kernel_image_start:
-	
+
+	# initialize Stack pointer for exception modes
+	mrs r4, cpsr
+	bic r4, r4, #0x1f
+
+	#FIQ Mode
+	orr r3, r4, #0x11
+	msr cpsr_c, r3
+	ldr sp, =exc_stack
+
+	#IRQ Mode
+	orr r3, r4, #0x12
+	msr cpsr_c, r3
+	ldr sp, =exc_stack
+
+	#ABORT Mode
+	orr r3, r4, #0x17
+	msr cpsr_c, r3
+	ldr sp, =exc_stack
+
+	#UNDEFINED Mode
+	orr r3, r4, #0x1b
+	msr cpsr_c, r3
+	ldr sp, =exc_stack
+
 	# switch to supervisor mode
-	mrs r3, cpsr
-	bic r3, r3, #0x1f
-	orr r3, r3, #0x13
+	orr r3, r4, #0x13
 	msr cpsr_c, r3
 	
Index: kernel/genarch/Makefile.inc
===================================================================
--- kernel/genarch/Makefile.inc	(revision 7038f55834b70c09d9b7e778acbd89c64f575274)
+++ kernel/genarch/Makefile.inc	(revision 6ac14a70ed101ee9fa8379a5f9ef15a38f08aec5)
@@ -111,4 +111,10 @@
 endif
 
+ifeq ($(CONFIG_PL050),y)
+	GENARCH_SOURCES += \
+		genarch/src/kbrd/kbrd_pl050.c \
+		genarch/src/kbrd/scanc_pl050.c
+endif
+
 ifeq ($(CONFIG_MAC_KBD),y)
 	GENARCH_SOURCES += \
Index: kernel/genarch/include/drivers/pl050/pl050.h
===================================================================
--- kernel/genarch/include/drivers/pl050/pl050.h	(revision 6ac14a70ed101ee9fa8379a5f9ef15a38f08aec5)
+++ kernel/genarch/include/drivers/pl050/pl050.h	(revision 6ac14a70ed101ee9fa8379a5f9ef15a38f08aec5)
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2009 Vineeth Pillai
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup genarch		
+ * @{
+ */
+/** @file
+ * @brief	Describes the pl050 keyboard/mouse controller
+ */
+
+/**
+ * This file implements pl050 specific functions for keyboard and mouse
+ */
+
+#ifndef KERN_genarch_PL050_H
+#define KERN_genarch_PL050_H
+
+#include <ddi/irq.h>
+#include <arch/types.h>
+#include <console/chardev.h>
+#include <typedefs.h>
+
+
+/*
+ * pl050 register offsets from the base address
+ */
+#define PL050_CR	0x00
+#define PL050_STAT	0x04
+#define PL050_DATA	0x08
+#define PL050_CLOCKDIV	0x0C
+#define PL050_INTRSTAT	0x10
+
+/*
+ * Control Register Bits
+ */
+#define PL050_CR_TYPE	(1 << 5)	/* Type 0: PS2/AT mode, 1: No Line control bit mode */
+#define PL050_CR_RXINTR	(1 << 4)	/* Recieve Interrupt Enable */
+#define PL050_CR_TXINTR	(1 << 3)	/* Transmit Interrupt Enable */
+#define PL050_CR_INTR	(1 << 2)	/* Interrupt Enable */
+#define PL050_CR_FKMID	(1 << 1)	/* Force KMI Data Low */
+#define PL050_CR_FKMIC	1		/* Force KMI Clock Low */
+
+/*
+ * Status register bits
+ */
+#define PL050_STAT_TXEMPTY	(1 << 6)	/* 1: Transmit register empty */
+#define PL050_STAT_TXBUSY	(1 << 5)	/* 1: Busy, sending data */
+#define PL050_STAT_RXFULL	(1 << 4)	/* 1: register Full */
+#define PL050_STAT_RXBUSY	(1 << 3)	/* 1: Busy, recieving Data */
+#define PL050_STAT_RXPARITY	(1 << 2)	/* odd parity of the last bit recieved */
+#define PL050_STAT_KMIC		(1 << 1)	/* status of KMICLKIN */
+#define PL050_STAT_KMID		1		/* status of KMIDATAIN */
+
+/*
+ * Interrupt status register bits.
+ */
+#define PL050_TX_INTRSTAT	(1 << 1)	/* Transmit intr asserted */
+#define PL050_RX_INTRSTAT	1		/* Recieve intr asserted */
+
+typedef struct {
+	ioport8_t *base;
+	ioport8_t *data;
+	ioport8_t *status;
+	ioport8_t *ctrl;
+} pl050_t;
+
+typedef struct {
+	irq_t	irq;
+	pl050_t *pl050;
+	indev_t *kbrdin;
+} pl050_instance_t;
+
+extern pl050_instance_t *pl050_init(pl050_t *, inr_t);
+extern void pl050_wire(pl050_instance_t *, indev_t *);
+
+
+#endif
+
+/** @}
+ */
Index: kernel/genarch/include/kbrd/scanc_pl050.h
===================================================================
--- kernel/genarch/include/kbrd/scanc_pl050.h	(revision 6ac14a70ed101ee9fa8379a5f9ef15a38f08aec5)
+++ kernel/genarch/include/kbrd/scanc_pl050.h	(revision 6ac14a70ed101ee9fa8379a5f9ef15a38f08aec5)
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2009 Vineeth Pillai
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup genarch	
+ * @{
+ */
+/**
+ * @file
+ * @brief	Scan codes for pl050 keyboards.
+ */
+
+#ifndef KERN_SCANC_PL050_H_
+#define KERN_SCANC_PL050_H_
+
+#define SC_SCAN_ESCAPE	0xE0
+#define SC_ESC		0x76
+#define SC_BACKSPACE	0x66
+#define SC_LSHIFT       0x12
+#define SC_RSHIFT       0x59
+#define SC_CAPSLOCK     0x58
+#define SC_SPEC_ESCAPE  0xe0
+#define SC_LEFTARR      0x6b
+#define SC_RIGHTARR     0x74
+#define SC_UPARR        0x75
+#define SC_DOWNARR      0x72
+#define SC_DELETE       0x70
+#define SC_HOME         0x6C
+#define SC_END          0x69
+
+#endif
+
+/** @}
+ */
Index: kernel/genarch/src/drivers/pl050/pl050.c
===================================================================
--- kernel/genarch/src/drivers/pl050/pl050.c	(revision 6ac14a70ed101ee9fa8379a5f9ef15a38f08aec5)
+++ kernel/genarch/src/drivers/pl050/pl050.c	(revision 6ac14a70ed101ee9fa8379a5f9ef15a38f08aec5)
@@ -0,0 +1,117 @@
+/*
+ * Copyright (c) 2009 Vineeth Pillai
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup genarch	
+ * @{
+ */
+/**
+ * @file
+ * @brief	pl050 keyboard/mouse driver.
+ *
+ * It takes care of low-level keyboard functions.
+ */
+
+#include <genarch/drivers/pl050/pl050.h>
+#include <arch/asm.h>
+#include <console/chardev.h>
+#include <mm/slab.h>
+#include <ddi/device.h>
+
+#define PL050_KEY_RELEASE 0xF0
+#define PL050_ESC_KEY	0xE0
+#define PL050_CAPS_SCAN_CODE   0x58
+
+/** Structure for pl050's IRQ. */
+static pl050_t *pl050;
+
+static irq_ownership_t pl050_claim(irq_t *irq)
+{
+	uint8_t status;
+	if ((status = pio_read_8(pl050->status)) & PL050_STAT_RXFULL)
+		return IRQ_ACCEPT;
+	else {
+		return IRQ_DECLINE;
+	}
+}
+
+static void pl050_irq_handler(irq_t *irq)
+{
+	uint8_t data;
+	uint8_t status;
+	pl050_instance_t *instance = irq->instance;
+	
+	while ((status = pio_read_8(pl050->status)) & PL050_STAT_RXFULL) {
+		data = pio_read_8(pl050->data);
+		indev_push_character(instance->kbrdin, data);
+
+	}
+}
+
+/** Initialize pl050. */
+pl050_instance_t *pl050_init(pl050_t *dev, inr_t inr)
+{
+
+	pl050_instance_t *instance =
+	    malloc(sizeof(pl050_instance_t), FRAME_ATOMIC);
+
+	pl050 = dev;
+
+	if (instance) {	
+		instance->pl050 = dev;
+		instance->kbrdin = NULL;
+
+		irq_initialize(&instance->irq);
+		instance->irq.devno = device_assign_devno();
+		instance->irq.inr = inr;
+		instance->irq.claim = pl050_claim;
+		instance->irq.handler = pl050_irq_handler;
+		instance->irq.instance = instance;
+	}
+
+	return instance;
+}
+
+void pl050_wire(pl050_instance_t *instance, indev_t *kbrdin)
+{
+	uint8_t val;
+	
+	instance->kbrdin = kbrdin;
+	irq_register(&instance->irq);
+
+	val = PL050_CR_RXINTR | PL050_CR_INTR;
+
+	pio_write_8(pl050->ctrl, val);
+
+	/* reset the data buffer */	
+	pio_read_8(pl050->data);
+	
+}
+
+
+/** @}
+ */
Index: kernel/genarch/src/fb/fb.c
===================================================================
--- kernel/genarch/src/fb/fb.c	(revision 7038f55834b70c09d9b7e778acbd89c64f575274)
+++ kernel/genarch/src/fb/fb.c	(revision 6ac14a70ed101ee9fa8379a5f9ef15a38f08aec5)
@@ -115,4 +115,11 @@
 	*((uint32_t *) dst)
 	    = (BLUE(rgb, 8) << 16) | (GREEN(rgb, 8) << 8) | RED(rgb, 8);
+}
+
+static void rgb_8880(void *dst, uint32_t rgb)
+{
+	*((uint32_t *) dst)
+	   = (RED(rgb, 8) << 24) | (GREEN(rgb, 8) << 16) | (BLUE(rgb, 8) << 8);
+
 }
 
@@ -471,5 +478,5 @@
 		break;
 	case VISUAL_RGB_8_8_8_0:
-		rgb_conv = rgb_888;
+		rgb_conv = rgb_8880;
 		pixelbytes = 4;
 		break;
Index: kernel/genarch/src/kbrd/kbrd_pl050.c
===================================================================
--- kernel/genarch/src/kbrd/kbrd_pl050.c	(revision 6ac14a70ed101ee9fa8379a5f9ef15a38f08aec5)
+++ kernel/genarch/src/kbrd/kbrd_pl050.c	(revision 6ac14a70ed101ee9fa8379a5f9ef15a38f08aec5)
@@ -0,0 +1,209 @@
+/*
+ * Copyright (c) 2009 Vineeth Pillai
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup genarch
+ * @{
+ */
+/**
+ * @file
+ * @brief pl050 Keyboard processing.
+ */
+
+#include <genarch/kbrd/kbrd.h>
+#include <genarch/kbrd/scanc.h>
+
+#include <genarch/kbrd/scanc_pl050.h>
+
+#include <synch/spinlock.h>
+#include <console/chardev.h>
+#include <console/console.h>
+#include <proc/thread.h>
+#include <arch.h>
+#include <macros.h>
+
+#define PRESSED_SHIFT     (1 << 0)
+#define PRESSED_CAPSLOCK  (1 << 1)
+#define LOCKED_CAPSLOCK   (1 << 0)
+
+#define PL050_KEY_RELEASE 0xF0
+#define PL050_ESC_KEY   0xE0
+#define PL050_CAPS_SCAN_CODE   0x58
+#define PL050_NUM_SCAN_CODE   0x77
+#define PL050_SCROLL_SCAN_CODE   0x7E
+
+static bool is_lock_key(wchar_t);
+
+static indev_operations_t kbrd_raw_ops = {
+	.poll = NULL
+};
+
+/** Process release of key.
+ *
+ * @param sc Scancode of the key being released.
+ */
+static void key_released(kbrd_instance_t *instance, wchar_t sc)
+{
+	spinlock_lock(&instance->keylock);
+	
+	switch (sc) {
+	case SC_LSHIFT:
+	case SC_RSHIFT:
+		instance->keyflags &= ~PRESSED_SHIFT;
+		break;
+	case SC_CAPSLOCK:
+		instance->keyflags &= ~PRESSED_CAPSLOCK;
+		if (instance->lockflags & LOCKED_CAPSLOCK)
+			instance->lockflags &= ~LOCKED_CAPSLOCK;
+		else
+			instance->lockflags |= LOCKED_CAPSLOCK;
+		break;
+	default:
+		break;
+	}
+	
+	spinlock_unlock(&instance->keylock);
+}
+
+/** Process keypress.
+ *
+ * @param sc Scancode of the key being pressed.
+ */
+static void key_pressed(kbrd_instance_t *instance, wchar_t sc)
+{
+	bool letter;
+	bool shift;
+	bool capslock;
+	
+	spinlock_lock(&instance->keylock);
+	
+	switch (sc) {
+	case SC_LSHIFT:
+	case SC_RSHIFT:
+		instance->keyflags |= PRESSED_SHIFT;
+		break;
+	case SC_CAPSLOCK:
+		instance->keyflags |= PRESSED_CAPSLOCK;
+		break;
+	case SC_SCAN_ESCAPE:
+		break;
+	default:
+		letter = islower(sc_primary_map[sc]);
+		shift = instance->keyflags & PRESSED_SHIFT;
+		capslock = (instance->keyflags & PRESSED_CAPSLOCK) ||
+		    (instance->lockflags & LOCKED_CAPSLOCK);
+		
+		if ((letter) && (capslock))
+			shift = !shift;
+		
+		if (shift)
+			indev_push_character(instance->sink, sc_secondary_map[sc]);
+		else
+			indev_push_character(instance->sink, sc_primary_map[sc]);
+		break;
+	}
+	
+	spinlock_unlock(&instance->keylock);
+}
+
+static void kkbrd(void *arg)
+{
+	static int key_released_flag = 0;
+	static int is_locked = 0;
+	kbrd_instance_t *instance = (kbrd_instance_t *) arg;
+	
+	while (true) {
+		wchar_t sc = indev_pop_character(&instance->raw);
+
+		if (sc == PL050_KEY_RELEASE) {
+			key_released_flag = 1;
+		} else {
+			if (key_released_flag) {
+				key_released_flag = 0;
+				if (is_lock_key(sc)) {
+					if (!is_locked) {
+						is_locked = 1;
+					} else {
+						is_locked = 0;
+						continue;
+					}
+				}
+				key_released(instance, sc);
+
+			} else {
+				if (is_lock_key(sc) && is_locked)
+					continue;
+				key_pressed(instance, sc);
+			}
+		}
+		
+	}
+}
+
+kbrd_instance_t *kbrd_init(void)
+{
+	kbrd_instance_t *instance
+	    = malloc(sizeof(kbrd_instance_t), FRAME_ATOMIC);
+	if (instance) {
+		instance->thread
+			= thread_create(kkbrd, (void *) instance, TASK, 0, "kkbrd", false);
+		
+		if (!instance->thread) {
+			free(instance);
+			return NULL;
+		}
+		
+		instance->sink = NULL;
+		indev_initialize("kbrd", &instance->raw, &kbrd_raw_ops);
+		
+		spinlock_initialize(&instance->keylock, "instance_keylock");
+		instance->keyflags = 0;
+		instance->lockflags = 0;
+	}
+	
+	return instance;
+}
+
+indev_t *kbrd_wire(kbrd_instance_t *instance, indev_t *sink)
+{
+	ASSERT(instance);
+	ASSERT(sink);
+	
+	instance->sink = sink;
+	thread_ready(instance->thread);
+	
+	return &instance->raw;
+}
+
+static bool is_lock_key(wchar_t sc)
+{
+	return ((sc == PL050_CAPS_SCAN_CODE) || (sc == PL050_NUM_SCAN_CODE) ||
+		(sc == PL050_SCROLL_SCAN_CODE));
+}
+
+/** @}
+ */
Index: kernel/genarch/src/kbrd/scanc_pl050.c
===================================================================
--- kernel/genarch/src/kbrd/scanc_pl050.c	(revision 6ac14a70ed101ee9fa8379a5f9ef15a38f08aec5)
+++ kernel/genarch/src/kbrd/scanc_pl050.c	(revision 6ac14a70ed101ee9fa8379a5f9ef15a38f08aec5)
@@ -0,0 +1,234 @@
+/*
+ * Copyright (c) 2009 Vineeth Pillai
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, U_SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup genarch	
+ * @{
+ */
+/**
+ * @file
+ * @brief	Scan codes for pl050 keyboards.
+ */
+#include <genarch/kbrd/scanc.h>
+#include <typedefs.h>
+#include <string.h>
+
+
+/** Primary meaning of scancodes. */
+wchar_t sc_primary_map[] = {
+	U_NULL, /* 0x00 */
+	U_SPECIAL, /* 0x01 - F9 */
+	U_SPECIAL, /* 0x02 - F7 */
+	U_SPECIAL, /* 0x03 - F5 */
+	U_SPECIAL, /* 0x04 - F3 */
+	U_SPECIAL, /* 0x05 - F1 */
+	U_SPECIAL, /* 0x06 - F2 */
+	U_SPECIAL, /* 0x07 - F12 */
+	U_SPECIAL, /* 0x08 -  */
+	U_SPECIAL, /* 0x09 - F10 */
+	U_SPECIAL, /* 0x0A - F8 */
+	U_SPECIAL, /* 0x0B - F10 */
+	U_SPECIAL, /* 0x0C - F4 */
+	'\t', /* 0x0D - Tab */
+	'`',
+	U_SPECIAL, /* 0x0F */
+	U_SPECIAL, /* 0x10 */
+	U_SPECIAL, /* 0x11 - LAlt */
+	U_SPECIAL, /* 0x12 - LShift */
+	U_SPECIAL, /* ox13 */
+	U_SPECIAL, /* 0x14 Ctrl */
+	'q', '1',
+	U_SPECIAL, /* 0x17 */
+	U_SPECIAL, /* 0x18 */
+	U_SPECIAL, /* 0x19 */
+	'z', 's', 'a', 'w', '2',
+	U_SPECIAL, /* 0x1F */
+	U_SPECIAL, /* 0x20 */
+	'c', 'x', 'd', 'e', '4', '3',
+	U_SPECIAL, /* 0x27 */
+	U_SPECIAL, /* 0x28 */
+	' ', 'v', 'f', 't', 'r', '5',
+	U_SPECIAL, /* 0x2F */
+	U_SPECIAL, /* 0x30 */
+	'n', 'b', 'h', 'g', 'y', '6',
+	U_SPECIAL, /* 0x37 */
+	U_SPECIAL, /* 0x38 */
+	U_SPECIAL, /* 0x39 */
+	'm', 'j', 'u', '7', '8',
+	U_SPECIAL, /* 0x3F */
+	U_SPECIAL, /* 0x40 */
+	',', 'k', 'i', 'o', '0', '9',
+	U_SPECIAL, /* 0x47 */
+	U_SPECIAL, /* 0x48 */
+	'.', '/', 'l', ';', 'p', '-',
+	U_SPECIAL, /* 0x4F */
+	U_SPECIAL, /* 0x50 */
+	U_SPECIAL, /* 0x51 */
+	'\'',
+	U_SPECIAL, /* 0x53 */
+	'[', '=',
+	U_SPECIAL, /* 0x56 */
+	U_SPECIAL, /* 0x57 */
+	U_SPECIAL, /* 0x58 - Caps Lock */
+	U_SPECIAL, /* 0x59 - RShift */
+	'\n', ']',
+	U_SPECIAL, /* 0x5C */
+	'\\',
+	U_SPECIAL, /* 0x5E */
+	U_SPECIAL, /* 0x5F */
+	U_SPECIAL, /* 0x60 */
+	U_SPECIAL, /* 0x61 */
+	U_SPECIAL, /* 0x62 */
+	U_SPECIAL, /* 0x63 */
+	U_SPECIAL, /* 0x64 */
+	U_SPECIAL, /* 0x65 */
+	'\b', /* 0x66  - backspace*/
+	U_SPECIAL, /* 0x67 */
+	U_SPECIAL, /* 0x68 */
+	U_END_ARROW, /* 0x69 */
+	U_SPECIAL, /* 0x6a */
+	U_LEFT_ARROW, /* 0x6b - Left Arrow */
+	U_SPECIAL, /* 0x6c */
+	U_SPECIAL, /* 0x6d */
+	U_SPECIAL, /* 0x6e */
+	U_SPECIAL, /* 0x6f */
+	U_SPECIAL, /* 0x70 */
+	U_DELETE, /* 0x71 - Del*/
+	U_DOWN_ARROW, /* 0x72 Down Arrow */
+	U_SPECIAL, /* 0x73 */
+	U_RIGHT_ARROW, /* 0x74  - Right Arrow */
+	U_UP_ARROW, /* 0x75  Up Arrow */
+	U_ESCAPE, /* 0x76 Esc */
+	U_SPECIAL, /* 0x77 - NumLock*/
+	U_SPECIAL, /* 0x78  F11*/
+	U_SPECIAL, /* 0x79 */
+	U_PAGE_DOWN, /* 0x7a */
+	U_SPECIAL, /* 0x7b */
+	U_SPECIAL, /* 0x7c */
+	U_PAGE_UP, /* 0x7d */
+	U_SPECIAL, /* 0x7e */
+	U_SPECIAL /* 0x7f */
+};
+
+/** Secondary meaning of scancodes. */
+wchar_t sc_secondary_map[] = {
+	U_NULL, /* 0x00 */
+	U_SPECIAL, /* 0x01 - F9 */
+	U_SPECIAL, /* 0x02 - F7 */
+	U_SPECIAL, /* 0x03 - F5 */
+	U_SPECIAL, /* 0x04 - F3 */
+	U_SPECIAL, /* 0x05 - F1 */
+	U_SPECIAL, /* 0x06 - F2 */
+	U_SPECIAL, /* 0x07 - F12 */
+	U_SPECIAL, /* 0x08 -  */
+	U_SPECIAL, /* 0x09 - F10 */
+	U_SPECIAL, /* 0x0A - F8 */
+	U_SPECIAL, /* 0x0B - F10 */
+	U_SPECIAL, /* 0x0C - F4 */
+	'\t', /* 0x0D - Tab */
+	'~',
+	U_SPECIAL, /* 0x0F */
+	U_SPECIAL, /* 0x10 */
+	U_SPECIAL, /* 0x11 - LAlt */
+	U_SPECIAL, /* 0x12 - LShift */
+	U_SPECIAL, /* ox13 */
+	U_SPECIAL, /* 0x14 Ctrl */
+	'Q', '!',
+	U_SPECIAL, /* 0x17 */
+	U_SPECIAL, /* 0x18 */
+	U_SPECIAL, /* 0x19 */
+	'Z', 'S', 'A', 'W', '@',
+	U_SPECIAL, /* 0x1F */
+	U_SPECIAL, /* 0x20 */
+	'C', 'X', 'D', 'E', '$', '#',
+	U_SPECIAL, /* 0x27 */
+	U_SPECIAL, /* 0x28 */
+	' ', 'V', 'F', 'T', 'R', '%',
+	U_SPECIAL, /* 0x2F */
+	U_SPECIAL, /* 0x30 */
+	'N', 'B', 'H', 'G', 'Y', '^',
+	U_SPECIAL, /* 0x37 */
+	U_SPECIAL, /* 0x38 */
+	U_SPECIAL, /* 0x39 */
+	'M', 'J', 'U', '&', '*',
+	U_SPECIAL, /* 0x3F */
+	U_SPECIAL, /* 0x40 */
+	'<', 'K', 'I', 'O', ')', '(',
+	U_SPECIAL, /* 0x47 */
+	U_SPECIAL, /* 0x48 */
+	'>', '?', 'L', ':', 'P', '_',
+	U_SPECIAL, /* 0x4F */
+	U_SPECIAL, /* 0x50 */
+	U_SPECIAL, /* 0x51 */
+	'"',
+	U_SPECIAL, /* 0x53 */
+	'{', '+',
+	U_SPECIAL, /* 0x56 */
+	U_SPECIAL, /* 0x57 */
+	U_SPECIAL, /* 0x58 - Caps Lock */
+	U_SPECIAL, /* 0x59 - RShift */
+	'\n', '}',
+	U_SPECIAL, /* 0x5C */
+	'|',
+	U_SPECIAL, /* 0x5E */
+	U_SPECIAL, /* 0x5F */
+	U_SPECIAL, /* 0x60 */
+	U_SPECIAL, /* 0x61 */
+	U_SPECIAL, /* 0x62 */
+	U_SPECIAL, /* 0x63 */
+	U_SPECIAL, /* 0x64 */
+	U_SPECIAL, /* 0x65 */
+	'\b', /* 0x66  - backspace*/
+	U_SPECIAL, /* 0x67 */
+	U_SPECIAL, /* 0x68 */
+	U_END_ARROW, /* 0x69 */
+	U_SPECIAL, /* 0x6a */
+	U_LEFT_ARROW, /* 0x6b - Left Arrow */
+	U_SPECIAL, /* 0x6c */
+	U_SPECIAL, /* 0x6d */
+	U_SPECIAL, /* 0x6e */
+	U_SPECIAL, /* 0x6f */
+	U_SPECIAL, /* 0x70 */
+	U_DELETE, /* 0x71 - Del*/
+	U_DOWN_ARROW, /* 0x72 Down Arrow */
+	U_SPECIAL, /* 0x73 */
+	U_RIGHT_ARROW, /* 0x74  - Right Arrow */
+	U_UP_ARROW, /* 0x75  Up Arrow */
+	U_ESCAPE, /* 0x76 Esc */
+	U_SPECIAL, /* 0x77 - NumLock*/
+	U_SPECIAL, /* 0x78  F11*/
+	U_SPECIAL, /* 0x79 */
+	U_PAGE_DOWN, /* 0x7a */
+	U_SPECIAL, /* 0x7b */
+	U_SPECIAL, /* 0x7c */
+	U_PAGE_UP, /* 0x7d */
+	U_SPECIAL, /* 0x7e */
+	U_SPECIAL /* 0x7f */
+};
+
+/** @}
+ */
