Index: kernel/arch/arm32/src/arm32.c
===================================================================
--- kernel/arch/arm32/src/arm32.c	(revision 98000fb4ea6015506f059c9b121e417ce991ecfd)
+++ kernel/arch/arm32/src/arm32.c	(revision 87bedd1cbe679b447c12df73b2c8e154cd0a0d55)
@@ -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 98000fb4ea6015506f059c9b121e417ce991ecfd)
+++ 	(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 87bedd1cbe679b447c12df73b2c8e154cd0a0d55)
+++ kernel/arch/arm32/src/exc_handler.S	(revision 87bedd1cbe679b447c12df73b2c8e154cd0a0d55)
@@ -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 98000fb4ea6015506f059c9b121e417ce991ecfd)
+++ kernel/arch/arm32/src/exception.c	(revision 87bedd1cbe679b447c12df73b2c8e154cd0a0d55)
@@ -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 98000fb4ea6015506f059c9b121e417ce991ecfd)
+++ kernel/arch/arm32/src/interrupt.c	(revision 87bedd1cbe679b447c12df73b2c8e154cd0a0d55)
@@ -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 87bedd1cbe679b447c12df73b2c8e154cd0a0d55)
+++ kernel/arch/arm32/src/mach/integratorcp/integratorcp.c	(revision 87bedd1cbe679b447c12df73b2c8e154cd0a0d55)
@@ -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 87bedd1cbe679b447c12df73b2c8e154cd0a0d55)
+++ kernel/arch/arm32/src/mach/testarm/testarm.c	(revision 87bedd1cbe679b447c12df73b2c8e154cd0a0d55)
@@ -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 87bedd1cbe679b447c12df73b2c8e154cd0a0d55)
+++ kernel/arch/arm32/src/machine_func.c	(revision 87bedd1cbe679b447c12df73b2c8e154cd0a0d55)
@@ -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 98000fb4ea6015506f059c9b121e417ce991ecfd)
+++ kernel/arch/arm32/src/mm/frame.c	(revision 87bedd1cbe679b447c12df73b2c8e154cd0a0d55)
@@ -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 98000fb4ea6015506f059c9b121e417ce991ecfd)
+++ kernel/arch/arm32/src/start.S	(revision 87bedd1cbe679b447c12df73b2c8e154cd0a0d55)
@@ -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
 	
