Index: kernel/arch/arm32/src/arm32.c
===================================================================
--- kernel/arch/arm32/src/arm32.c	(revision f74bbaf20e8d8be55495c56affc5b17ef6ea2bf0)
+++ kernel/arch/arm32/src/arm32.c	(revision 341140c181e949962d7871bd75d6e9f74ba669d1)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2003-2004 Jakub Jermar
+ * Copyright (c) 2007 Michal Kebrt
  * All rights reserved.
  *
@@ -31,60 +31,132 @@
  */
 /** @file
+ *  @brief ARM32 architecture specific functions.
  */
 
+#include <arch.h>
+#include <arch/boot.h>
+#include <config.h>
+#include <arch/console.h>
+#include <ddi/device.h>
+#include <genarch/fb/fb.h>
+#include <genarch/fb/visuals.h>
+#include <ddi/irq.h>
+#include <arch/debug/print.h>
+#include <print.h>
+#include <config.h>
+#include <interrupt.h>
+#include <arch/regutils.h>
+#include <arch/machine.h>
+#include <userspace.h>
 
-#include <arch.h>
+/** Information about loaded tasks. */
+bootinfo_t bootinfo;
 
+/** Performs arm32 specific initialization before main_bsp() is called. */
 void arch_pre_main(void)
 {
-	/* TODO */
+	int i;
+
+	init.cnt = bootinfo.cnt;
+
+	for (i = 0; i < bootinfo.cnt; ++i) {
+		init.tasks[i].addr = bootinfo.tasks[i].addr;
+		init.tasks[i].size = bootinfo.tasks[i].size;
+	}
+	
 }
 
+/** Performs arm32 specific initialization before mm is initialized. */
 void arch_pre_mm_init(void)
 {
-	/* TODO */
+	/* It is not assumed by default */
+	interrupts_disable();
 }
 
+/** Performs arm32 specific initialization afterr mm is initialized. */
 void arch_post_mm_init(void)
 {
-	/* TODO */
+	machine_hw_map_init();
+
+	/* Initialize exception dispatch table */
+	exception_init();
+
+	interrupt_init();
+	
+	console_init(device_assign_devno());
+
+#ifdef CONFIG_FB
+	fb_init(machine_get_fb_address(), 640, 480, 1920, VISUAL_RGB_8_8_8);
+#endif
 }
 
+/** Performs arm32 specific tasks needed after cpu is initialized.
+ *
+ * Currently the function is empty.
+ */
 void arch_post_cpu_init(void)
 {
-	/* TODO */
 }
 
+
+/** Performs arm32 specific tasks needed before the multiprocessing is
+ * initialized.
+ *
+ * Currently the function is empty because SMP is not supported.
+ */
 void arch_pre_smp_init(void)
 {
-	/* TODO */
 }
 
+
+/** Performs arm32 specific tasks needed after the multiprocessing is
+ * initialized.
+ *
+ * Currently the function is empty because SMP is not supported.
+ */
 void arch_post_smp_init(void)
 {
-	/* TODO */
 }
 
-/** Perform arm32 specific tasks needed before the new task is run. */
+
+/** Performs arm32 specific tasks needed before the new task is run. */
 void before_task_runs_arch(void)
 {
-	/* TODO */
+	tlb_invalidate_all();
 }
 
-/** Perform arm32 specific tasks needed before the new thread is scheduled. */
+
+/** Performs arm32 specific tasks needed before the new thread is scheduled.
+ *
+ * It sets supervisor_sp.
+ */
 void before_thread_runs_arch(void)
 {
-	/* TODO */
+	uint8_t *stck;
+	
+	stck = &THREAD->kstack[THREAD_STACK_SIZE - SP_DELTA];
+	supervisor_sp = (uintptr_t) stck;
 }
 
+/** Performs arm32 specific tasks before a thread stops running.
+ *
+ * Currently the function is empty.
+ */
 void after_thread_ran_arch(void)
 {
-	/* TODO */
 }
 
-void arch_reboot(void)
+/** Halts CPU. */
+void cpu_halt(void)
 {
-	// TODO
-	while (1);
+	machine_cpu_halt();
+}
+
+/** Reboot. */
+void arch_reboot()
+{
+	/* not implemented */
+	for (;;)
+		;
 }
 
Index: kernel/arch/arm32/src/asm.S
===================================================================
--- kernel/arch/arm32/src/asm.S	(revision 341140c181e949962d7871bd75d6e9f74ba669d1)
+++ kernel/arch/arm32/src/asm.S	(revision 341140c181e949962d7871bd75d6e9f74ba669d1)
@@ -0,0 +1,98 @@
+#
+# 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.
+#
+
+	
+.text
+
+.global memsetb
+.global memcpy
+.global memcpy_from_uspace
+.global memcpy_to_uspace
+.global memcpy_from_uspace_failover_address
+.global memcpy_to_uspace_failover_address
+
+memsetb:
+	b _memsetb
+
+memcpy:
+memcpy_from_uspace:
+memcpy_to_uspace:
+	add     r3, r1, #3
+	bic     r3, r3, #3
+	cmp     r1, r3
+	stmdb   sp!, {r4, lr}
+	beq     4f
+1:
+	cmp     r2, #0
+	movne   ip, #0
+	beq     3f
+2:
+	ldrb    r3, [ip, r1]
+	strb    r3, [ip, r0]
+	add     ip, ip, #1
+	cmp     ip, r2
+	bne     2b
+3:
+	mov     r0, r1
+	ldmia   sp!, {r4, pc}
+4:
+	add     r3, r0, #3
+	bic     r3, r3, #3
+	cmp     r0, r3
+	bne     1b
+	movs    r4, r2, lsr #2
+	moveq   lr, r4
+	beq     6f
+	mov     lr, #0
+	mov     ip, lr
+5:
+	ldr     r3, [ip, r1]
+	add     lr, lr, #1
+	cmp     lr, r4
+	str     r3, [ip, r0]
+	add     ip, ip, #4
+	bne     5b
+6:
+	ands    r4, r2, #3
+	beq     3b
+	mov     r3, lr, lsl #2
+	add     r0, r3, r0
+	add     ip, r3, r1
+	mov     r2, #0
+7:
+	ldrb    r3, [r2, ip]
+	strb    r3, [r2, r0]
+	add     r2, r2, #1
+	cmp     r2, r4
+	bne     7b
+	b       3b
+
+memcpy_from_uspace_failover_address:
+memcpy_to_uspace_failover_address:
+	mov		r0, #0
+	ldmia   sp!, {r4, pc}
Index: kernel/arch/arm32/src/console.c
===================================================================
--- kernel/arch/arm32/src/console.c	(revision 341140c181e949962d7871bd75d6e9f74ba669d1)
+++ kernel/arch/arm32/src/console.c	(revision 341140c181e949962d7871bd75d6e9f74ba669d1)
@@ -0,0 +1,58 @@
+/*
+ * 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 arm32	
+ * @{
+ */
+/** @file 
+ *  @brief Console.
+ */
+
+#include <console/console.h>
+#include <arch/console.h>
+#include <arch/machine.h>
+
+void console_init(devno_t devno)
+{
+	machine_console_init(devno);
+}
+
+/** Acquire console back for kernel. */
+void arch_grab_console(void)
+{
+	machine_grab_console();
+}
+
+/** Return console to userspace. */
+void arch_release_console(void)
+{
+	machine_release_console();
+}
+
+/** @}
+ */
Index: kernel/arch/arm32/src/context.S
===================================================================
--- kernel/arch/arm32/src/context.S	(revision f74bbaf20e8d8be55495c56affc5b17ef6ea2bf0)
+++ kernel/arch/arm32/src/context.S	(revision 341140c181e949962d7871bd75d6e9f74ba669d1)
@@ -1,4 +1,4 @@
 #
-# Copyright (c) 2003-2004 Jakub Jermar
+# Copyright (c) 2007 Petr Stepan
 # All rights reserved.
 #
@@ -33,6 +33,27 @@
 
 context_save_arch:
-	/* TODO */
+	stmfd sp!, {r1}
+	mrs r1, cpsr
+	and r1, r1, #0x1f
+	stmia r0!, {r1}
+	ldmfd sp!, {r1}
+
+	stmia r0!, {sp, lr}
+	stmia r0!, {r4-r11}
+
+	mov r0, #1
+	mov pc, lr
+
+
+context_restore_arch:
+	ldmia r0!, {r4}
+	mrs r5, cpsr
+	bic r5, r5, #0x1f
+	orr r5, r5, r4
+	msr cpsr_c, r5
+
+	ldmia r0!, {sp, lr}
+	ldmia r0!, {r4-r11}
 	
-context_restore_arch:
-	/* TODO */
+	mov r0, #0
+	mov pc, lr
Index: kernel/arch/arm32/src/cpu/cpu.c
===================================================================
--- kernel/arch/arm32/src/cpu/cpu.c	(revision f74bbaf20e8d8be55495c56affc5b17ef6ea2bf0)
+++ kernel/arch/arm32/src/cpu/cpu.c	(revision 341140c181e949962d7871bd75d6e9f74ba669d1)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2003-2004 Jakub Jermar
+ * Copyright (c) 2007 Michal Kebrt
  * All rights reserved.
  *
@@ -31,21 +31,99 @@
  */
 /** @file
+ *  @brief CPU identification.
  */
 
+#include <arch/cpu.h>
 #include <cpu.h>
+#include <arch.h>
 #include <print.h>	
 
+/** Number of indexes left out in the #imp_data array */
+#define IMP_DATA_START_OFFSET 0x40
+
+/** Implementators (vendor) names */
+static char *imp_data[] = {
+	"?",					/* IMP_DATA_START_OFFSET */
+	"ARM Ltd",				/* 0x41 */
+	"",					/* 0x42 */
+	"",                             	/* 0x43 */
+	"Digital Equipment Corporation",	/* 0x44 */
+	"", "", "", "", "", "", "", "", "", "",	/* 0x45 - 0x4e */
+	"", "", "", "", "", "", "", "", "", "", /* 0x4f - 0x58 */
+	"", "", "", "", "", "", "", "", "", "", /* 0x59 - 0x62 */
+	"", "", "", "", "", "",			/* 0x63 - 0x68 */
+	"Intel Corporation"			/* 0x69 */
+};
+
+/** Length of the #imp_data array */
+static int imp_data_length = sizeof(imp_data) / sizeof(char *);
+
+/** Architecture names */
+static char *arch_data[] = {
+	"?",       /* 0x0 */
+	"4",       /* 0x1 */
+	"4T",      /* 0x2 */
+	"5",       /* 0x3 */
+	"5T",      /* 0x4 */
+	"5TE",     /* 0x5 */
+	"5TEJ",    /* 0x6 */
+	"6"        /* 0x7 */
+};
+
+/** Length of the #arch_data array */
+static int arch_data_length = sizeof(arch_data) / sizeof(char *);
+
+
+/** Retrieves processor identification from CP15 register 0.
+ * 
+ * @param cpu Structure for storing CPU identification.
+ */
+static void arch_cpu_identify(cpu_arch_t *cpu)
+{
+	uint32_t ident;
+	asm volatile (
+		"mrc p15, 0, %0, c0, c0, 0\n"
+		: "=r" (ident)
+	);
+
+	cpu->imp_num = ident >> 24;
+	cpu->variant_num = (ident << 8) >> 28;
+	cpu->arch_num = (ident << 12) >> 28;
+	cpu->prim_part_num = (ident << 16) >> 20;
+	cpu->rev_num = (ident << 28) >> 28;
+}
+
+/** Does nothing on ARM. */
 void cpu_arch_init(void)
 {
 }
 
-void cpu_identify(void)
+/** Retrieves processor identification and stores it to #CPU.arch */
+void cpu_identify(void) 
 {
-	/* TODO */
+	arch_cpu_identify(&CPU->arch);
 }
 
+/** Prints CPU identification. */
 void cpu_print_report(cpu_t *m)
 {
-	/* TODO */
+	char * vendor = imp_data[0];
+	char * architecture = arch_data[0];
+	cpu_arch_t * cpu_arch = &m->arch;
+
+	if ((cpu_arch->imp_num) > 0 &&
+	    (cpu_arch->imp_num < (imp_data_length + IMP_DATA_START_OFFSET))) {
+		vendor = imp_data[cpu_arch->imp_num - IMP_DATA_START_OFFSET];
+	}
+
+	if ((cpu_arch->arch_num) > 0 &&
+	    (cpu_arch->arch_num < arch_data_length)) {
+		architecture = arch_data[cpu_arch->arch_num];
+	}
+
+	printf("cpu%d: vendor=%s, architecture=ARM%s, part number=%x, "
+	    "variant=%x, revision=%x\n",
+	    m->id, vendor, architecture, cpu_arch->prim_part_num,
+	    cpu_arch->variant_num, cpu_arch->rev_num);
 }
 
Index: kernel/arch/arm32/src/ddi/ddi.c
===================================================================
--- kernel/arch/arm32/src/ddi/ddi.c	(revision f74bbaf20e8d8be55495c56affc5b17ef6ea2bf0)
+++ kernel/arch/arm32/src/ddi/ddi.c	(revision 341140c181e949962d7871bd75d6e9f74ba669d1)
@@ -31,4 +31,5 @@
  */
 /** @file
+ *  @brief DDI.
  */
 
Index: kernel/arch/arm32/src/debug/print.c
===================================================================
--- kernel/arch/arm32/src/debug/print.c	(revision 341140c181e949962d7871bd75d6e9f74ba669d1)
+++ kernel/arch/arm32/src/debug/print.c	(revision 341140c181e949962d7871bd75d6e9f74ba669d1)
@@ -0,0 +1,97 @@
+/*
+ * 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 arm32
+ * @{
+ */
+/** @file
+ *  @brief Debug print functions.
+ */
+
+#include <printf/printf_core.h>
+#include <arch/debug/print.h>
+#include <arch/machine.h>
+
+/** Prints a character to the console.
+ *
+ * @param ch Character to be printed.
+ */
+static void putc(char ch) 
+{
+	machine_debug_putc(ch);
+}
+
+/** Prints a string to the console. 
+ *
+ * @param str    String to be printed.
+ * @param count  Number of characters to be printed.
+ * @param unused Unused parameter.
+ *
+ * @return Number of printed characters.
+ */
+static int debug_write(const char *str, size_t count, void *unused)
+{
+	int i;
+	for (i = 0; i < count; ++i) {
+		putc(str[i]);
+	}
+	return i;
+}
+
+/** Prints a formated string.
+ *
+ * @param fmt "Printf-like" format.
+ */
+void debug_printf(const char *fmt, ...)
+{
+	va_list args;
+	va_start (args, fmt);
+
+	struct printf_spec ps = {
+		(int (*)(void *, size_t, void *)) debug_write,
+		NULL
+	};
+	printf_core(fmt, &ps, args);
+
+	va_end(args);
+}
+
+/** Prints a string.
+ *
+ * @param str String to print.
+ */
+void debug_puts(const char *str)
+{
+	while (*str) {
+		putc(*str);
+		str++;
+	}
+}
+
+/** @}
+ */
Index: kernel/arch/arm32/src/drivers/gxemul.c
===================================================================
--- kernel/arch/arm32/src/drivers/gxemul.c	(revision 341140c181e949962d7871bd75d6e9f74ba669d1)
+++ kernel/arch/arm32/src/drivers/gxemul.c	(revision 341140c181e949962d7871bd75d6e9f74ba669d1)
@@ -0,0 +1,393 @@
+/*
+ * 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 <interrupt.h>
+#include <ipc/irq.h>
+#include <console/chardev.h>
+#include <arch/drivers/gxemul.h>
+#include <console/console.h>
+#include <sysinfo/sysinfo.h>
+#include <print.h>
+#include <ddi/device.h>
+#include <mm/page.h>
+#include <arch/machine.h>
+#include <arch/debug/print.h>
+
+/* Addresses of devices. */
+#define GXEMUL_VIDEORAM            0x10000000
+#define GXEMUL_KBD                 0x10000000
+#define GXEMUL_HALT_OFFSET         0x10
+#define GXEMUL_RTC                 0x15000000
+#define GXEMUL_RTC_FREQ_OFFSET     0x100
+#define GXEMUL_RTC_ACK_OFFSET      0x110
+#define GXEMUL_IRQC                0x16000000
+#define GXEMUL_IRQC_MASK_OFFSET    0x4
+#define GXEMUL_IRQC_UNMASK_OFFSET  0x8
+#define GXEMUL_MP                  0x11000000
+#define GXEMUL_MP_MEMSIZE_OFFSET   0x0090
+#define GXEMUL_FB                  0x12000000
+
+/* IRQs */
+#define GXEMUL_KBD_IRQ		2
+#define GXEMUL_TIMER_IRQ	4
+
+static gxemul_hw_map_t gxemul_hw_map;
+static chardev_t console;
+static irq_t gxemul_console_irq;
+static irq_t gxemul_timer_irq;
+
+static bool hw_map_init_called = false;
+
+static void gxemul_kbd_enable(chardev_t *dev);
+static void gxemul_kbd_disable(chardev_t *dev);
+static void gxemul_write(chardev_t *dev, const char ch);
+static char gxemul_do_read(chardev_t *dev);
+
+static chardev_operations_t gxemul_ops = {
+	.resume = gxemul_kbd_enable,
+	.suspend = gxemul_kbd_disable,
+	.write = gxemul_write,
+	.read = gxemul_do_read,
+};
+
+
+/** Returns the mask of active interrupts. */
+static inline uint32_t gxemul_irqc_get_sources(void)
+{
+	return *((uint32_t *) gxemul_hw_map.irqc);
+}
+
+
+/** Masks interrupt.
+ * 
+ * @param irq interrupt number
+ */
+static inline void gxemul_irqc_mask(uint32_t irq)
+{
+	*((uint32_t *) gxemul_hw_map.irqc_mask) = irq;
+}
+
+
+/** Unmasks interrupt.
+ * 
+ * @param irq interrupt number
+ */
+static inline void gxemul_irqc_unmask(uint32_t irq)
+{
+	*((uint32_t *) gxemul_hw_map.irqc_unmask) = irq;
+}
+
+
+/** Initializes #gxemul_hw_map. */
+void gxemul_hw_map_init(void)
+{
+	gxemul_hw_map.videoram = hw_map(GXEMUL_VIDEORAM, PAGE_SIZE);
+	gxemul_hw_map.kbd = hw_map(GXEMUL_KBD, PAGE_SIZE);
+	gxemul_hw_map.rtc = hw_map(GXEMUL_RTC, PAGE_SIZE);
+	gxemul_hw_map.irqc = hw_map(GXEMUL_IRQC, PAGE_SIZE);
+
+	gxemul_hw_map.rtc_freq = gxemul_hw_map.rtc + GXEMUL_RTC_FREQ_OFFSET;
+	gxemul_hw_map.rtc_ack = gxemul_hw_map.rtc + GXEMUL_RTC_ACK_OFFSET;
+	gxemul_hw_map.irqc_mask = gxemul_hw_map.irqc + GXEMUL_IRQC_MASK_OFFSET;
+	gxemul_hw_map.irqc_unmask = gxemul_hw_map.irqc +
+	    GXEMUL_IRQC_UNMASK_OFFSET;
+
+	hw_map_init_called = true;
+}
+
+
+/** Putchar that works with gxemul. 
+ *
+ * @param dev Not used.
+ * @param ch Characted to be printed.
+ */
+static void gxemul_write(chardev_t *dev, const char ch)
+{
+	*((char *) gxemul_hw_map.videoram) = ch;
+}
+
+/** Enables gxemul keyboard (interrupt unmasked).
+ *
+ * @param dev Not used.
+ *
+ * Called from getc(). 
+ */
+static void gxemul_kbd_enable(chardev_t *dev)
+{
+	gxemul_irqc_unmask(GXEMUL_KBD_IRQ);
+}
+
+/** Disables gxemul keyboard (interrupt masked).
+ *
+ * @param dev not used
+ *
+ * Called from getc().
+ */
+static void gxemul_kbd_disable(chardev_t *dev)
+{
+	gxemul_irqc_mask(GXEMUL_KBD_IRQ);
+}
+
+/** Read character using polling, assume interrupts disabled.
+ *
+ *  @param dev Not used.
+ */
+static char gxemul_do_read(chardev_t *dev)
+{
+	char ch;
+
+	while (1) {
+		ch = *((volatile char *) gxemul_hw_map.kbd);
+		if (ch) {
+			if (ch == '\r')
+				return '\n';
+			if (ch == 0x7f)
+				return '\b';
+			return ch;
+		}
+	}
+}
+
+/** Process keyboard interrupt. 
+ *  
+ *  @param irq IRQ information.
+ *  @param arg Not used.
+ */
+static void gxemul_irq_handler(irq_t *irq, void *arg, ...)
+{
+	if ((irq->notif_cfg.notify) && (irq->notif_cfg.answerbox)) {
+		ipc_irq_send_notif(irq);
+	} else {
+		char ch = 0;
+		
+		ch = *((char *) gxemul_hw_map.kbd);
+		if (ch == '\r') {
+			ch = '\n';
+		}
+		if (ch == 0x7f) {
+			ch = '\b';
+		}
+		chardev_push_character(&console, ch);
+	}
+}
+
+static irq_ownership_t gxemul_claim(void)
+{
+	return IRQ_ACCEPT;
+}
+
+
+/** Acquire console back for kernel. */
+void gxemul_grab_console(void)
+{
+	ipl_t ipl = interrupts_disable();
+	spinlock_lock(&gxemul_console_irq.lock);
+	gxemul_console_irq.notif_cfg.notify = false;
+	spinlock_unlock(&gxemul_console_irq.lock);
+	interrupts_restore(ipl);
+}
+
+/** Return console to userspace. */
+void gxemul_release_console(void)
+{
+	ipl_t ipl = interrupts_disable();
+	spinlock_lock(&gxemul_console_irq.lock);
+	if (gxemul_console_irq.notif_cfg.answerbox) {
+		gxemul_console_irq.notif_cfg.notify = true;
+	}
+	spinlock_unlock(&gxemul_console_irq.lock);
+	interrupts_restore(ipl);
+}
+
+/** Initializes console object representing gxemul console.
+ *
+ *  @param devno device number.
+ */
+void gxemul_console_init(devno_t devno)
+{
+	chardev_initialize("gxemul_console", &console, &gxemul_ops);
+	stdin = &console;
+	stdout = &console;
+	
+	irq_initialize(&gxemul_console_irq);
+	gxemul_console_irq.devno = devno;
+	gxemul_console_irq.inr = GXEMUL_KBD_IRQ;
+	gxemul_console_irq.claim = gxemul_claim;
+	gxemul_console_irq.handler = gxemul_irq_handler;
+	irq_register(&gxemul_console_irq);
+	
+	gxemul_irqc_unmask(GXEMUL_KBD_IRQ);
+	
+	sysinfo_set_item_val("kbd", NULL, true);
+	sysinfo_set_item_val("kbd.devno", NULL, devno);
+	sysinfo_set_item_val("kbd.inr", NULL, GXEMUL_KBD_IRQ);
+	sysinfo_set_item_val("kbd.address.virtual", NULL, gxemul_hw_map.kbd);
+}
+
+/** 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_hw_map.rtc_freq) = frequency;
+}
+
+static irq_ownership_t gxemul_timer_claim(void)
+{
+	return IRQ_ACCEPT;
+}
+
+/** Timer interrupt handler.
+ *
+ * @param irq Interrupt information.
+ * @param arg Not used.
+ */
+static void gxemul_timer_irq_handler(irq_t *irq, void *arg, ...)
+{
+	/*
+	* 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_hw_map.rtc_ack) = 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.
+ */
+size_t gxemul_get_memory_size(void) 
+{
+	return  *((int *) (GXEMUL_MP + GXEMUL_MP_MEMSIZE_OFFSET));
+}
+
+/** Prints a character. 
+ *
+ *  @param ch Character to be printed.
+ */
+void gxemul_debug_putc(char ch)
+{
+	char *addr = 0;
+	if (!hw_map_init_called) {
+	 	addr = (char *) GXEMUL_KBD;
+	} else {
+		addr = (char *) gxemul_hw_map.videoram;
+	}
+
+	*(addr) = ch;
+}
+
+/** Stops gxemul. */
+void gxemul_cpu_halt(void)
+{
+	char * addr = 0;
+	if (!hw_map_init_called) {
+	 	addr = (char *) GXEMUL_KBD;
+	} else {
+		addr = (char *) gxemul_hw_map.videoram;
+	}
+	
+	*(addr + GXEMUL_HALT_OFFSET) = '\0';
+}
+
+/** Gxemul specific 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 gxemul_irq_exception(int exc_no, istate_t *istate)
+{
+	uint32_t sources = gxemul_irqc_get_sources();
+	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, irq->arg);
+				spinlock_unlock(&irq->lock);
+			} else {
+				/* Spurious interrupt.*/
+				dprintf("cpu%d: spurious interrupt (inum=%d)\n",
+				    CPU->id, i);
+			}
+		}
+	}
+}
+
+/** Returns address of framebuffer device.
+ *
+ *  @return Address of framebuffer device.
+ */
+uintptr_t gxemul_get_fb_address(void)
+{
+	return (uintptr_t) GXEMUL_FB;
+}
+
+/** @}
+ */
Index: kernel/arch/arm32/src/dummy.S
===================================================================
--- kernel/arch/arm32/src/dummy.S	(revision f74bbaf20e8d8be55495c56affc5b17ef6ea2bf0)
+++ kernel/arch/arm32/src/dummy.S	(revision 341140c181e949962d7871bd75d6e9f74ba669d1)
@@ -1,4 +1,4 @@
 #
-# Copyright (c) 2003-2004 Jakub Jermar
+# Copyright (c) 2007 Michal Kebry, Pavel Jancik, Petr Stepan
 # All rights reserved.
 #
@@ -31,54 +31,34 @@
 .global calibrate_delay_loop
 .global asm_delay_loop
-.global dummy
-.global arch_grab_console
-.global arch_release_console
-.global cpu_halt
+
 .global fpu_context_restore
 .global fpu_context_save
 .global fpu_enable
 .global fpu_init
-.global interrupts_disable
-.global interrupts_enable
-.global interrupts_read
-.global interrupts_restore
-.global memcpy
-.global memcpy_from_uspace
-.global memcpy_to_uspace
-.global memsetb
-.global panic_printf
-.global symbol_table
+
 .global sys_tls_set
-.global tlb_invalidate_asid
-.global tlb_invalidate_pages
-.global userspace
-	
+.global dummy
+
 calibrate_delay_loop:
+	mov	pc, lr
+
 asm_delay_loop:
+	mov	pc, lr
 
-arch_grab_console:
-arch_release_console:
-cpu_halt:
 fpu_context_restore:
+	mov	pc, lr
+    
 fpu_context_save:
+	mov	pc, lr
+    
 fpu_enable:
+	mov	pc, lr
+
 fpu_init:
-interrupts_disable:
-interrupts_enable:
-interrupts_read:
-interrupts_restore:
-memcpy:
-memcpy_from_uspace:
-memcpy_to_uspace:
-memsetb:
-panic_printf:
-symbol_table:
+	mov	pc, lr
+    
+# not used on ARM
 sys_tls_set:
-tlb_invalidate_asid:
-tlb_invalidate_pages:
-userspace:
 
 dummy:
-
-0:
-	b 0b
+	mov pc, lr
Index: kernel/arch/arm32/src/exception.c
===================================================================
--- kernel/arch/arm32/src/exception.c	(revision 341140c181e949962d7871bd75d6e9f74ba669d1)
+++ kernel/arch/arm32/src/exception.c	(revision 341140c181e949962d7871bd75d6e9f74ba669d1)
@@ -0,0 +1,387 @@
+/*
+ * Copyright (c) 2007 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 arm32
+ * @{
+ */
+/** @file
+ *  @brief Exception handlers and exception initialization routines.
+ */
+
+#include <arch/exception.h>
+#include <arch/debug/print.h>
+#include <arch/memstr.h>
+#include <arch/regutils.h>
+#include <interrupt.h>
+#include <arch/machine.h>
+#include <arch/mm/page_fault.h>
+#include <print.h>
+#include <syscall/syscall.h>
+
+/** Offset used in calculation of exception handler's relative address.
+ *
+ * @see install_handler()
+ */
+#define PREFETCH_OFFSET      0x8
+
+/** LDR instruction's code */
+#define LDR_OPCODE           0xe59ff000
+
+/** Number of exception vectors. */
+#define EXC_VECTORS          8
+
+/** 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("mov r0, %0" : : "i" (exception));	\
+	asm("mov r1, r13");			\
+	asm("bl exc_dispatch");		
+
+/** 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.
+ *
+ *  Addresses of handlers are stored in memory following exception vectors.
+ */
+static void install_handler (unsigned handler_addr, unsigned* vector)
+{
+	/* relative address (related to exc. vector) of the word
+	 * where handler's address is stored
+	*/
+	volatile uint32_t handler_address_ptr = EXC_VECTORS_SIZE - PREFETCH_OFFSET;
+	
+	/* make it LDR instruction and store at exception vector */
+	*vector = handler_address_ptr | LDR_OPCODE;
+	
+	/* store handler's address */
+	*(vector + EXC_VECTORS) = handler_addr;
+
+}
+
+/** Low-level Reset Exception handler. */
+static void reset_exception_entry()
+{
+	PROCESS_EXCEPTION(EXC_RESET);
+}
+
+/** Low-level Software Interrupt Exception handler. */
+static void swi_exception_entry()
+{
+	PROCESS_EXCEPTION(EXC_SWI);
+}
+
+/** Low-level Undefined Instruction Exception handler. */
+static void undef_instr_exception_entry()
+{
+	PROCESS_EXCEPTION(EXC_UNDEF_INSTR);
+}
+
+/** Low-level Fast Interrupt Exception handler. */
+static void fiq_exception_entry()
+{
+	PROCESS_EXCEPTION(EXC_FIQ);
+}
+
+/** Low-level Prefetch Abort Exception handler. */
+static void prefetch_abort_exception_entry()
+{
+	asm("sub lr, lr, #4");
+	PROCESS_EXCEPTION(EXC_PREFETCH_ABORT);
+} 
+
+/** Low-level Data Abort Exception handler. */
+static void data_abort_exception_entry()
+{
+	asm("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()
+{
+	asm("sub lr, lr, #4");
+	setup_stack_and_save_regs();
+	
+	switch_to_irq_servicing_mode();
+	
+	CALL_EXC_DISPATCH(EXC_IRQ)
+
+	load_regs();
+}
+
+/** Software Interrupt handler.
+ *
+ * Dispatches the syscall.
+ */
+static void swi_exception(int exc_no, istate_t *istate)
+{
+	/*
+	dprintf("SYSCALL: r0-r4: %x, %x, %x, %x, %x; pc: %x\n", istate->r0, 
+		istate->r1, istate->r2, istate->r3, istate->r4, istate->pc);
+	*/
+
+	istate->r0 = syscall_handler(istate->r0, istate->r1, istate->r2,
+	    istate->r3, istate->r4);
+}
+
+/** 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);
+}
+
+/** Fills exception vectors with appropriate exception handlers. */
+void install_exception_handlers(void)
+{
+	install_handler((unsigned) reset_exception_entry,
+	    (unsigned *) EXC_RESET_VEC);
+	
+	install_handler((unsigned) undef_instr_exception_entry,
+	    (unsigned *) EXC_UNDEF_INSTR_VEC);
+	
+	install_handler((unsigned) swi_exception_entry,
+	    (unsigned *) EXC_SWI_VEC);
+	
+	install_handler((unsigned) prefetch_abort_exception_entry,
+	    (unsigned *) EXC_PREFETCH_ABORT_VEC);
+	
+	install_handler((unsigned) data_abort_exception_entry,
+	    (unsigned *) EXC_DATA_ABORT_VEC);
+	
+	install_handler((unsigned) irq_exception_entry,
+	    (unsigned *) EXC_IRQ_VEC);
+	
+	install_handler((unsigned)fiq_exception_entry,
+	    (unsigned *) EXC_FIQ_VEC);
+}
+
+#ifdef HIGH_EXCEPTION_VECTORS
+/** Activates use of high exception vectors addresses. */
+static void high_vectors(void)
+{
+	uint32_t control_reg;
+	
+	asm volatile("mrc p15, 0, %0, c1, c1" : "=r" (control_reg));
+	
+	/* switch on the high vectors bit */
+	control_reg |= CP15_R1_HIGH_VECTORS_BIT;
+	
+	asm volatile("mcr p15, 0, %0, c1, c1" : : "r" (control_reg));
+}
+#endif
+
+/** Initializes exception handling.
+ * 
+ * Installs low-level exception handlers and then registers
+ * exceptions and their handlers to kernel exception dispatcher.
+ */
+void exception_init(void)
+{
+#ifdef HIGH_EXCEPTION_VECTORS
+	high_vectors();
+#endif
+	install_exception_handlers();
+	
+	exc_register(EXC_IRQ, "interrupt", (iroutine) irq_exception);
+	exc_register(EXC_PREFETCH_ABORT, "prefetch abort",
+	    (iroutine) prefetch_abort);
+	exc_register(EXC_DATA_ABORT, "data abort", (iroutine) data_abort);
+	exc_register(EXC_SWI, "software interrupt", (iroutine) swi_exception);
+}
+
+/** Prints #istate_t structure content.
+ *
+ * @param istate Structure to be printed.
+ */
+void print_istate(istate_t *istate)
+{
+	dprintf("istate dump:\n");
+
+	dprintf(" r0: %x    r1: %x    r2: %x    r3: %x\n",
+	    istate->r0, istate->r1, istate->r2, istate->r3);
+	dprintf(" r4: %x    r5: %x    r6: %x    r7: %x\n", 
+	    istate->r4, istate->r5, istate->r6, istate->r7);
+	dprintf(" r8: %x    r8: %x   r10: %x   r11: %x\n", 
+	    istate->r8, istate->r9, istate->r10, istate->r11);
+	dprintf(" r12: %x    sp: %x    lr: %x  spsr: %x\n",
+	    istate->r12, istate->sp, istate->lr, istate->spsr);
+
+	dprintf(" pc: %x\n", istate->pc);
+}
+
+/** @}
+ */
Index: kernel/arch/arm32/src/interrupt.c
===================================================================
--- kernel/arch/arm32/src/interrupt.c	(revision 341140c181e949962d7871bd75d6e9f74ba669d1)
+++ kernel/arch/arm32/src/interrupt.c	(revision 341140c181e949962d7871bd75d6e9f74ba669d1)
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2007 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 arm32
+ * @{
+ */
+/** @file
+ *  @brief Interrupts controlling routines.
+ */
+
+#include <arch/asm.h>
+#include <arch/regutils.h>
+#include <ddi/irq.h>
+#include <arch/machine.h>
+#include <interrupt.h>
+
+/** Initial size of a table holding interrupt handlers. */
+#define IRQ_COUNT 8
+
+/** Disable interrupts.
+ *
+ * @return Old interrupt priority level.
+ */
+ipl_t interrupts_disable(void)
+{
+	ipl_t ipl = current_status_reg_read();
+
+	current_status_reg_control_write(STATUS_REG_IRQ_DISABLED_BIT | ipl);
+	
+	return ipl;
+}
+
+/** Enable interrupts.
+ *
+ * @return Old interrupt priority level.
+ */
+ipl_t interrupts_enable(void)
+{
+	ipl_t ipl = current_status_reg_read();
+
+	current_status_reg_control_write(ipl & ~STATUS_REG_IRQ_DISABLED_BIT);
+
+	return ipl;
+}
+
+/** Restore interrupt priority level.
+ *
+ * @param ipl Saved interrupt priority level.
+ */
+void interrupts_restore(ipl_t ipl)
+{
+	current_status_reg_control_write(
+	    (current_status_reg_read() & ~STATUS_REG_IRQ_DISABLED_BIT) | 
+	    (ipl & STATUS_REG_IRQ_DISABLED_BIT));
+}
+
+/** Read interrupt priority level.
+ *
+ * @return Current interrupt priority level.
+ */
+ipl_t interrupts_read(void)
+{
+	return current_status_reg_read();
+}
+
+/** Initialize basic tables for exception dispatching
+ * and starts the timer.
+ */
+void interrupt_init(void)
+{
+	irq_init(IRQ_COUNT, IRQ_COUNT);
+	machine_timer_irq_start();
+}
+
+/** @}
+ */
Index: kernel/arch/arm32/src/mm/as.c
===================================================================
--- kernel/arch/arm32/src/mm/as.c	(revision f74bbaf20e8d8be55495c56affc5b17ef6ea2bf0)
+++ kernel/arch/arm32/src/mm/as.c	(revision 341140c181e949962d7871bd75d6e9f74ba669d1)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2005 Jakub Jermar
+ * Copyright (c) 2007 Pavel Jancik, Michal Kebrt
  * All rights reserved.
  *
@@ -31,4 +31,5 @@
  */
 /** @file
+ *  @brief Address space functions.
  */
 
@@ -39,20 +40,11 @@
 #include <arch.h>
 
-/** Architecture dependent address space init. */
+/** Architecture dependent address space init.
+ *  
+ *  Since ARM supports page tables, #as_pt_operations are used.
+ */
 void as_arch_init(void)
 {
-        as_operations = &as_pt_operations;
-	asid_fifo_init();
-}
-
-/** Install address space.
- *
- * Install ASID.
- *
- * @param as Address space structure.
- */
-void as_install_arch(as_t *as)
-{
-	/* TODO */
+	as_operations = &as_pt_operations;
 }
 
Index: kernel/arch/arm32/src/mm/frame.c
===================================================================
--- kernel/arch/arm32/src/mm/frame.c	(revision f74bbaf20e8d8be55495c56affc5b17ef6ea2bf0)
+++ kernel/arch/arm32/src/mm/frame.c	(revision 341140c181e949962d7871bd75d6e9f74ba669d1)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2005 Jakub Jermar
+ * Copyright (c) 2007 Pavel Jancik, Michal Kebrt
  * All rights reserved.
  *
@@ -31,12 +31,35 @@
  */
 /** @file
+ *  @brief Frame related functions.
  */
 
 #include <mm/frame.h>
+#include <arch/mm/frame.h>
+#include <config.h>
+#include <arch/debug/print.h>
 
-/** Create memory zones. */
+/** Address of the last frame in the memory. */
+uintptr_t last_frame = 0;
+
+/** Creates memory zones. */
 void frame_arch_init(void)
 {
-	/* TODO */
+	/* all memory as one zone */
+	zone_create(0, ADDR2PFN(config.memory_size),
+	    BOOT_PAGE_TABLE_START_FRAME + BOOT_PAGE_TABLE_SIZE_IN_FRAMES, 0);
+	last_frame = config.memory_size;
+
+	/* blacklist boot page table */
+	frame_mark_unavailable(BOOT_PAGE_TABLE_START_FRAME,
+	    BOOT_PAGE_TABLE_SIZE_IN_FRAMES);
+}
+
+/** Frees the boot page table. */
+void boot_page_table_free(void)
+{
+	int i;
+	for (i = 0; i < BOOT_PAGE_TABLE_SIZE_IN_FRAMES; i++) {
+		frame_free(i * FRAME_SIZE + BOOT_PAGE_TABLE_ADDRESS);
+	}
 }
 
Index: kernel/arch/arm32/src/mm/memory_init.c
===================================================================
--- kernel/arch/arm32/src/mm/memory_init.c	(revision 341140c181e949962d7871bd75d6e9f74ba669d1)
+++ kernel/arch/arm32/src/mm/memory_init.c	(revision 341140c181e949962d7871bd75d6e9f74ba669d1)
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2007 Pavel Jancik
+ * 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 arm32mm	
+ * @{
+ */
+/** @file
+ *  @brief Memory information functions.
+ */
+
+#include <arch/mm/memory_init.h>
+#include <arch/mm/page.h>
+#include <arch/machine.h>
+
+/** Returns memory size.
+ *
+ * @return Memory size in bytes
+ */
+size_t get_memory_size(void) 
+{
+	return  machine_get_memory_size();
+}
+
+/** @}
+ */
Index: kernel/arch/arm32/src/mm/page.c
===================================================================
--- kernel/arch/arm32/src/mm/page.c	(revision f74bbaf20e8d8be55495c56affc5b17ef6ea2bf0)
+++ kernel/arch/arm32/src/mm/page.c	(revision 341140c181e949962d7871bd75d6e9f74ba669d1)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2003-2004 Jakub Jermar
+ * Copyright (c) 2007 Pavel Jancik, Michal Kebrt
  * All rights reserved.
  *
@@ -31,4 +31,5 @@
  */
 /** @file
+ *  @brief Paging related functions.
  */
 
@@ -36,15 +37,72 @@
 #include <genarch/mm/page_pt.h>
 #include <mm/page.h>
+#include <align.h>
+#include <config.h>
+#include <arch/exception.h>
+#include <typedefs.h>
+#include <arch/types.h>
+#include <interrupt.h>
+#include <arch/mm/frame.h>
 
+/** Initializes page tables.
+ *
+ * 1:1 virtual-physical mapping is created in kernel address space. Mapping
+ * for table with exception vectors is also created.
+ */
 void page_arch_init(void)
 {
+	uintptr_t cur;
+	int flags;
+
 	page_mapping_operations = &pt_mapping_operations;
+
+	flags = PAGE_CACHEABLE;
+
+	/* PA2KA(identity) mapping for all frames until last_frame */
+	for (cur = 0; cur < last_frame; cur += FRAME_SIZE) {
+		page_mapping_insert(AS_KERNEL, PA2KA(cur), cur, flags);
+	}
+	
+	/* create mapping for exception table at high offset */
+#ifdef HIGH_EXCEPTION_VECTORS
+	void *virtaddr = frame_alloc(ONE_FRAME, FRAME_KA);
+	page_mapping_insert(AS_KERNEL, EXC_BASE_ADDRESS, KA2PA(virtaddr), flags);
+#else
+#error "Only high exception vector supported now"
+#endif
+
+	as_switch(NULL, AS_KERNEL);
+
+	boot_page_table_free();
 }
 
-/** Map device into kernel space. */
+/** Maps device into the kernel space.
+ *
+ * Maps physical address of device into kernel virtual address space (so it can
+ * be accessed only by kernel through virtual address).
+ *
+ * @param physaddr Physical address where device is connected.
+ * @param size Length of area where device is present.
+ *
+ * @return Virtual address where device will be accessible.
+ */
 uintptr_t hw_map(uintptr_t physaddr, size_t size)
 {
-	/* TODO */
-	return NULL;
+	if (last_frame + ALIGN_UP(size, PAGE_SIZE) >
+	    KA2PA(KERNEL_ADDRESS_SPACE_END_ARCH)) {
+		panic("Unable to map physical memory %p (%d bytes)",
+		    physaddr, size)
+	}
+
+	uintptr_t virtaddr = PA2KA(last_frame);
+	pfn_t i;
+	for (i = 0; i < ADDR2PFN(ALIGN_UP(size, PAGE_SIZE)); i++) {
+		page_mapping_insert(AS_KERNEL, virtaddr + PFN2ADDR(i),
+		    physaddr + PFN2ADDR(i),
+		    PAGE_NOT_CACHEABLE | PAGE_READ | PAGE_WRITE | PAGE_KERNEL);
+	}
+
+	last_frame = ALIGN_UP(last_frame + size, FRAME_SIZE);
+	return virtaddr;
 }
 
Index: kernel/arch/arm32/src/mm/page_fault.c
===================================================================
--- kernel/arch/arm32/src/mm/page_fault.c	(revision 341140c181e949962d7871bd75d6e9f74ba669d1)
+++ kernel/arch/arm32/src/mm/page_fault.c	(revision 341140c181e949962d7871bd75d6e9f74ba669d1)
@@ -0,0 +1,212 @@
+/*
+ * Copyright (c) 2007 Pavel Jancik, 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 arm32mm
+ * @{
+ */
+/** @file
+ *  @brief Page fault related functions.
+ */
+#include <panic.h>
+#include <arch/exception.h>
+#include <arch/debug/print.h>
+#include <arch/mm/page_fault.h>
+#include <mm/as.h>
+#include <genarch/mm/page_pt.h>
+#include <arch.h>
+#include <interrupt.h>
+
+/** Returns value stored in fault status register.
+ *
+ *  @return Value stored in CP15 fault status register (FSR).
+ */
+static inline fault_status_t read_fault_status_register(void)
+{
+	fault_status_union_t fsu;
+
+	/* fault status is stored in CP15 register 5 */
+	asm volatile (
+		"mrc p15, 0, %0, c5, c0, 0"
+		: "=r"(fsu.dummy)
+	);
+	return fsu.fs;
+}
+
+/** Returns FAR (fault address register) content.
+ *
+ * @return FAR (fault address register) content (address that caused a page
+ * 	   fault)
+ */
+static inline uintptr_t read_fault_address_register(void)
+{
+	uintptr_t ret;
+
+	/* fault adress is stored in CP15 register 6 */
+	asm volatile (
+		"mrc p15, 0, %0, c6, c0, 0"
+		: "=r"(ret)
+	);
+	return ret;
+}
+
+/** Decides whether the instruction is load/store or not.
+ *
+ * @param instr Instruction
+ *
+ * @return true when instruction is load/store, false otherwise
+ */
+static inline bool is_load_store_instruction(instruction_t instr)
+{
+	/* load store immediate offset */
+	if (instr.type == 0x2) {
+		return true;
+	}
+
+	/* load store register offset */
+	if (instr.type == 0x3 && instr.bit4 == 0) {
+		return true;
+	}
+
+	/* load store multiple */
+	if (instr.type == 0x4) {
+		return true;
+	}
+
+	/* oprocessor load/store */
+	if (instr.type == 0x6) {
+		return true;
+	}
+
+	return false;
+}
+
+/** Decides whether the instruction is swap or not.
+ *
+ * @param instr Instruction
+ *
+ * @return true when instruction is swap, false otherwise
+ */
+static inline bool is_swap_instruction(instruction_t instr)
+{
+	/* swap, swapb instruction */
+	if (instr.type == 0x0 &&
+	    (instr.opcode == 0x8 || instr.opcode == 0xa) &&
+	    instr.access == 0x0 && instr.bits567 == 0x4 && instr.bit4 == 1) {
+		return true;
+	}
+
+	return false;
+}
+
+/** Decides whether read or write into memory is requested.
+ *
+ * @param instr_addr   Address of instruction which tries to access memory.
+ * @param badvaddr     Virtual address the instruction tries to access.
+ *
+ * @return Type of access into memory, PF_ACCESS_EXEC if no memory access is
+ * 	   requested.
+ */
+static pf_access_t get_memory_access_type(uint32_t instr_addr,
+    uintptr_t badvaddr)
+{
+	instruction_union_t instr_union;
+	instr_union.pc = instr_addr;
+
+	instruction_t instr = *(instr_union.instr);
+
+	/* undefined instructions */
+	if (instr.condition == 0xf) {
+		panic("page_fault - instruction doesn't access memory "
+		    "(instr_code: %x, badvaddr:%x)", instr, badvaddr);
+		return PF_ACCESS_EXEC;
+	}
+
+	/* load store instructions */
+	if (is_load_store_instruction(instr)) {
+		if (instr.access == 1) {
+			return PF_ACCESS_READ;
+		} else {
+			return PF_ACCESS_WRITE;
+		}
+	}
+
+	/* swap, swpb instruction */
+	if (is_swap_instruction(instr)) {
+		return PF_ACCESS_WRITE;
+	}
+
+	panic("page_fault - instruction doesn't access memory "
+	    "(instr_code: %x, badvaddr:%x)", instr, badvaddr);
+
+	return PF_ACCESS_EXEC;
+}
+
+/** Handles "data abort" exception (load or store at invalid address).
+ *
+ * @param exc_no	Exception number.
+ * @param istate	CPU state when exception occured.
+ */
+void data_abort(int exc_no, istate_t *istate)
+{
+	fault_status_t fsr = read_fault_status_register();
+	uintptr_t badvaddr = read_fault_address_register();
+
+	pf_access_t access = get_memory_access_type(istate->pc, badvaddr);
+
+	int ret = as_page_fault(badvaddr, access, istate);
+
+	if (ret == AS_PF_FAULT) {
+		print_istate(istate);
+		dprintf("page fault - pc: %x, va: %x, status: %x(%x), "
+		    "access:%d\n", istate->pc, badvaddr, fsr.status, fsr,
+		    access);
+
+		fault_if_from_uspace(istate, "Page fault: %#x", badvaddr);
+		panic("page fault\n");
+	}
+}
+
+/** Handles "prefetch abort" exception (instruction couldn't be executed).
+ *
+ * @param exc_no	Exception number.
+ * @param istate	CPU state when exception occured.
+ */
+void prefetch_abort(int exc_no, istate_t *istate)
+{
+	int ret = as_page_fault(istate->pc, PF_ACCESS_EXEC, istate);
+
+	if (ret == AS_PF_FAULT) {
+		dprintf("prefetch_abort\n");
+		print_istate(istate);
+		panic("page fault - prefetch_abort at address: %x\n",
+		    istate->pc);
+	}
+}
+
+/** @}
+ */
Index: kernel/arch/arm32/src/mm/tlb.c
===================================================================
--- kernel/arch/arm32/src/mm/tlb.c	(revision 341140c181e949962d7871bd75d6e9f74ba669d1)
+++ kernel/arch/arm32/src/mm/tlb.c	(revision 341140c181e949962d7871bd75d6e9f74ba669d1)
@@ -0,0 +1,93 @@
+/*
+ * 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 arm32mm	
+ * @{
+ */
+/** @file
+ *  @brief TLB related functions.
+ */
+
+#include <mm/tlb.h>
+#include <arch/mm/asid.h>
+#include <arch/asm.h>
+#include <arch/types.h>
+#include <arch/mm/page.h>
+
+/** Invalidate all entries in TLB.
+ *
+ * @note See ARM Architecture reference section 3.7.7 for details.
+ */
+void tlb_invalidate_all(void)
+{
+	asm volatile (
+		"eor r1, r1\n"
+		"mcr p15, 0, r1, c8, c7, 0\n"
+		: : : "r1"
+	);
+}
+
+/** Invalidate all entries in TLB that belong to specified address space.
+ *
+ * @param asid Ignored as the ARM architecture doesn't support ASIDs.
+ */
+void tlb_invalidate_asid(asid_t asid)
+{
+	tlb_invalidate_all();
+}
+
+/** Invalidate single entry in TLB
+ *
+ * @param page Virtual adress of the page
+ */ 
+static inline void invalidate_page(uintptr_t page)
+{
+	asm volatile (
+		"mcr p15, 0, %0, c8, c7, 1"		
+		:
+		: "r" (page)
+	);
+}
+
+/** Invalidate TLB entries for specified page range belonging to specified
+ * address space.
+ *
+ * @param asid Ignored as the ARM architecture doesn't support it.
+ * @param page Address of the first page whose entry is to be invalidated.
+ * @param cnt Number of entries to invalidate.
+ */
+void tlb_invalidate_pages(asid_t asid, uintptr_t page, count_t cnt)
+{
+	unsigned int i;
+
+	for (i = 0; i < cnt; i++)
+		invalidate_page(page + i * PAGE_SIZE);
+}
+
+/** @}
+ */
Index: kernel/arch/arm32/src/panic.S
===================================================================
--- kernel/arch/arm32/src/panic.S	(revision 341140c181e949962d7871bd75d6e9f74ba669d1)
+++ kernel/arch/arm32/src/panic.S	(revision 341140c181e949962d7871bd75d6e9f74ba669d1)
@@ -0,0 +1,35 @@
+#
+# 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.
+#
+
+.text
+
+.global panic_printf
+
+panic_printf:
+	bl debug_printf
+	bl cpu_halt
Index: kernel/arch/arm32/src/start.S
===================================================================
--- kernel/arch/arm32/src/start.S	(revision f74bbaf20e8d8be55495c56affc5b17ef6ea2bf0)
+++ kernel/arch/arm32/src/start.S	(revision 341140c181e949962d7871bd75d6e9f74ba669d1)
@@ -1,4 +1,4 @@
 #
-# Copyright (c) 2003-2007 Jakub Jermar
+# Copyright (c) 2007 Michal Kebrt
 # All rights reserved.
 #
@@ -27,9 +27,51 @@
 #
 
+#include <arch/asm/boot.h>
+
+.text
+
 .global kernel_image_start
+.global exc_stack
+.global supervisor_sp
+
 kernel_image_start:
+	
+	# switch to supervisor mode
+	mrs r3, cpsr
+	bic r3, r3, #0x1f
+	orr r3, r3, #0x13
+	msr cpsr_c, r3	
+	
+	ldr sp, =temp_stack
 
-	/* TODO */
+	cmp r2, #0
+	beq bootinfo_end
+
+	ldr r3, =bootinfo
+
+	bootinfo_loop:
+		ldr r4, [r1]
+		str r4, [r3]
+
+		add r1, r1, #4
+		add r3, r3, #4
+		add r2, r2, #-4
+
+		cmp r2, #0
+		bne bootinfo_loop
 	
-0:
-	b 0b
+	bootinfo_end:
+
+	bl arch_pre_main
+
+	bl main_bsp
+
+	.space TEMP_STACK_SIZE
+temp_stack:
+
+	.space 1024
+exc_stack:
+
+supervisor_sp:
+	.space 4
+
Index: kernel/arch/arm32/src/userspace.c
===================================================================
--- kernel/arch/arm32/src/userspace.c	(revision 341140c181e949962d7871bd75d6e9f74ba669d1)
+++ kernel/arch/arm32/src/userspace.c	(revision 341140c181e949962d7871bd75d6e9f74ba669d1)
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2007 Petr Stepan, Pavel Jancik
+ * 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 Userspace switch.
+ */
+
+#include <userspace.h>
+
+/** Struct for holding all general purpose registers.
+ *  
+ *  Used to set registers when going to userspace.
+ */
+typedef struct {
+	uint32_t r0;
+	uint32_t r1;
+	uint32_t r2;
+	uint32_t r3;
+	uint32_t r4;
+	uint32_t r5;
+	uint32_t r6;
+	uint32_t r7;
+	uint32_t r8;
+	uint32_t r9;
+	uint32_t r10;
+	uint32_t r11;
+	uint32_t r12;
+	uint32_t sp;
+	uint32_t lr;
+	uint32_t pc;
+} ustate_t;
+
+/** Changes processor mode and jumps to the address specified in the first
+ * parameter.
+ *
+ *  @param kernel_uarg	 Userspace settings (entry point, stack, ...).
+ */
+void userspace(uspace_arg_t *kernel_uarg)
+{
+	volatile ustate_t ustate;
+
+	/* set first parameter */
+	ustate.r0 = (uintptr_t) kernel_uarg->uspace_uarg;
+
+	/* clear other registers */
+	ustate.r1 = ustate.r2  = ustate.r3  = ustate.r4  = ustate.r5 =
+	    ustate.r6  = ustate.r7  = ustate.r8  = ustate.r9 = ustate.r10 = 
+	    ustate.r11 = ustate.r12 = ustate.lr = 0;
+
+	/* set user stack */
+	ustate.sp = ((uint32_t)kernel_uarg->uspace_stack) + PAGE_SIZE;
+
+	/* set where uspace execution starts */
+	ustate.pc = (uintptr_t) kernel_uarg->uspace_entry;
+
+	/* status register in user mode */
+	ipl_t user_mode = current_status_reg_read() &
+	    (~STATUS_REG_MODE_MASK | USER_MODE);
+
+	/* set user mode, set registers, jump */
+	asm volatile (
+		"mov r0, %0			\n"
+		"msr spsr_c, %1			\n"
+		"ldmfd r0!, {r0-r12, sp, lr}^	\n"
+		"ldmfd r0!, {pc}^\n"
+		:
+		: "r" (&ustate), "r" (user_mode)
+		: "r0", "r1"
+	);
+
+	/* unreachable */
+	while(1)
+		;
+}
+
+/** @}
+ */
