Index: kernel/arch/amd64/include/mm/page.h
===================================================================
--- kernel/arch/amd64/include/mm/page.h	(revision 3ee8a07528aa466b40a362672714a05e936d396e)
+++ kernel/arch/amd64/include/mm/page.h	(revision 6b781c0c856d94b3114ccd6375bc6667a19e9bfe)
@@ -82,4 +82,9 @@
 #define PTL2_ENTRIES_ARCH	512
 #define PTL3_ENTRIES_ARCH	512
+
+#define PTL0_SIZE_ARCH       ONE_FRAME
+#define PTL1_SIZE_ARCH       ONE_FRAME
+#define PTL2_SIZE_ARCH       ONE_FRAME
+#define PTL3_SIZE_ARCH       ONE_FRAME
 
 #define PTL0_INDEX_ARCH(vaddr)	(((vaddr)>>39)&0x1ff)
Index: kernel/arch/arm32/Makefile.inc
===================================================================
--- kernel/arch/arm32/Makefile.inc	(revision 3ee8a07528aa466b40a362672714a05e936d396e)
+++ kernel/arch/arm32/Makefile.inc	(revision 6b781c0c856d94b3114ccd6375bc6667a19e9bfe)
@@ -1,5 +1,4 @@
 #
-# Copyright (c) 2005 Martin Decky
-# Copyright (c) 2007 Jakub Jermar
+# Copyright (c) 2007 Jakub Jermar, Michal Kebrt
 # All rights reserved.
 #
@@ -33,11 +32,23 @@
 BFD_NAME = elf32-little
 BFD_ARCH = arm
-BFD = elf32-little
+BFD = binary
 TARGET = arm-linux-gnu
 TOOLCHAIN_DIR = /usr/local/arm
 
-GCC_CFLAGS += 
+KERNEL_LOAD_ADDRESS = 0x80200000
 
-DEFS += -D__32_BITS__ -DMACHINE=$(MACHINE)
+ifeq ($(MACHINE), gxemul_testarm)
+	DMACHINE = MACHINE_GXEMUL_TESTARM
+endif
+
+GCC_CFLAGS += -fno-zero-initialized-in-bss
+
+DEFS += -D__32_BITS__ -DKERNEL_LOAD_ADDRESS=$(KERNEL_LOAD_ADDRESS) -D$(DMACHINE)
+
+# Compile with framebuffer support
+
+ifeq ($(CONFIG_FB), y)
+	DEFS += -DCONFIG_FB -DFB_INVERT_ENDIAN
+endif
 
 ## Compile with hierarchical page tables support.
@@ -49,7 +60,7 @@
 ## Compile with support for address space identifiers.
 #
-
-CONFIG_ASID = y
-CONFIG_ASID_FIFO = y
+# no HW support for ASIDs
+#CONFIG_ASID = y
+#CONFIG_ASID_FIFO = y 
 
 ## Compile with support with software division and multiplication.
@@ -59,12 +70,26 @@
 
 ARCH_SOURCES = \
+	arch/$(ARCH)/src/start.S \
+	arch/$(ARCH)/src/asm.S \
 	arch/$(ARCH)/src/arm32.c \
-	arch/$(ARCH)/src/start.S \
 	arch/$(ARCH)/src/context.S \
 	arch/$(ARCH)/src/dummy.S \
+	arch/$(ARCH)/src/panic.S \
 	arch/$(ARCH)/src/cpu/cpu.c \
 	arch/$(ARCH)/src/ddi/ddi.c \
+	arch/$(ARCH)/src/interrupt.c \
+	arch/$(ARCH)/src/debug/print.c \
+	arch/$(ARCH)/src/console.c \
+	arch/$(ARCH)/src/exception.c \
+	arch/$(ARCH)/src/userspace.c \
 	arch/$(ARCH)/src/mm/as.c \
 	arch/$(ARCH)/src/mm/frame.c \
-	arch/$(ARCH)/src/mm/page.c
-	
+	arch/$(ARCH)/src/mm/page.c \
+	arch/$(ARCH)/src/mm/tlb.c \
+	arch/$(ARCH)/src/mm/memory_init.c \
+	arch/$(ARCH)/src/mm/page_fault.c
+
+ifeq ($(MACHINE), gxemul_testarm)
+	ARCH_SOURCES += arch/$(ARCH)/src/drivers/gxemul.c
+endif
+
Index: kernel/arch/arm32/_link.ld.in
===================================================================
--- kernel/arch/arm32/_link.ld.in	(revision 3ee8a07528aa466b40a362672714a05e936d396e)
+++ kernel/arch/arm32/_link.ld.in	(revision 6b781c0c856d94b3114ccd6375bc6667a19e9bfe)
@@ -7,7 +7,10 @@
  */
 
+OUTPUT_ARCH(arm)
 ENTRY(kernel_image_start) 
 
+
 SECTIONS {
+	. = KERNEL_LOAD_ADDRESS;
 	.text : {
 		ktext_start = .;
@@ -23,20 +26,17 @@
 		LONG(kdata_end - kdata_start);
 		hardcoded_load_address = .;
-		LONG(0);		/* TODO */
+		LONG(KERNEL_LOAD_ADDRESS);
+		*(.bss);		/* uninitialized static variables */
+		*(COMMON); 		/* global variables */
+
 		*(.rodata*);
 		*(.sdata);
 		*(.reginfo);
+		symbol_table = .;
 		*(symtab.*);             
 	}
-	_gp = . + 0x8000;
-	.lit8 : { *(.lit8) }
-	.lit4 : { *(.lit4) }
 	.sbss : {
 		*(.sbss);
 		*(.scommon);
-	}
-	.bss : {
-		*(.bss);		/* uninitialized static variables */
-		*(COMMON); 		/* global variables */
 	}
 
@@ -49,3 +49,4 @@
 	  *(.note);
 	}
+
 }
Index: kernel/arch/arm32/include/arch.h
===================================================================
--- kernel/arch/arm32/include/arch.h	(revision 3ee8a07528aa466b40a362672714a05e936d396e)
+++ kernel/arch/arm32/include/arch.h	(revision 6b781c0c856d94b3114ccd6375bc6667a19e9bfe)
@@ -31,4 +31,5 @@
  */
 /** @file
+ *  @brief Empty.
  */
 
Index: kernel/arch/arm32/include/arg.h
===================================================================
--- kernel/arch/arm32/include/arg.h	(revision 3ee8a07528aa466b40a362672714a05e936d396e)
+++ kernel/arch/arm32/include/arg.h	(revision 6b781c0c856d94b3114ccd6375bc6667a19e9bfe)
@@ -31,4 +31,5 @@
  */
 /** @file
+ *  @brief Empty.
  */
 
Index: kernel/arch/arm32/include/asm.h
===================================================================
--- kernel/arch/arm32/include/asm.h	(revision 3ee8a07528aa466b40a362672714a05e936d396e)
+++ kernel/arch/arm32/include/asm.h	(revision 6b781c0c856d94b3114ccd6375bc6667a19e9bfe)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2003-2004 Jakub Jermar
+ * Copyright (c) 2007 Michal Kebrt
  * All rights reserved.
  *
@@ -30,5 +30,6 @@
  * @{
  */
-/** @file
+/** @file 
+ *  @brief Declarations of functions implemented in assembly.
  */
 
@@ -37,11 +38,14 @@
 
 #include <arch/types.h>
+#include <arch/stack.h>
+#include <config.h>
+#include <arch/interrupt.h>
 
+/** No such instruction on ARM to sleep CPU. */
 static inline void cpu_sleep(void)
 {
-	/* TODO */
 }
 
-/** Return base address of current stack
+/** Return base address of current stack.
  * 
  * Return the base address of the current stack.
@@ -51,6 +55,11 @@
 static inline uintptr_t get_stack_base(void)
 {
-	/* TODO */	
-	return NULL;
+	uintptr_t v;
+	asm volatile (
+		"and %0, sp, %1\n" 
+		: "=r" (v) 
+		: "r" (~(STACK_SIZE - 1))
+	);
+	return v;
 }
 
@@ -60,9 +69,4 @@
     uintptr_t entry);
 
-extern ipl_t interrupts_disable(void);
-extern ipl_t interrupts_enable(void);
-extern void interrupts_restore(ipl_t ipl);
-extern ipl_t interrupts_read(void);
-
 #endif
 
Index: kernel/arch/arm32/include/asm/boot.h
===================================================================
--- kernel/arch/arm32/include/asm/boot.h	(revision 6b781c0c856d94b3114ccd6375bc6667a19e9bfe)
+++ kernel/arch/arm32/include/asm/boot.h	(revision 6b781c0c856d94b3114ccd6375bc6667a19e9bfe)
@@ -0,0 +1,62 @@
+/*
+ * 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 Initial kernel start.
+ */
+
+#ifndef KERN_arm32_ASM_BOOT_H_
+#define KERN_arm32_ASM_BOOT_H_
+
+/** Size of a temporary stack used for initial kernel start. */
+#define TEMP_STACK_SIZE 0x100
+
+#ifndef __ASM__
+
+/** Kernel entry point.
+ *
+ * Implemented in assembly. Copies boot_bootinfo (declared as bootinfo in 
+ * boot/arch/arm32/loader/main.c) to #bootinfo struct. Then jumps to
+ * #arch_pre_main and #main_bsp.
+ *
+ * @param entry          Entry point address (not used).
+ * @param boot_bootinfo  Struct holding information about loaded tasks.
+ * @param bootinfo_size  Size of the bootinfo structure.
+ */
+extern void kernel_image_start(void *entry, void *boot_bootinfo,
+    unsigned int bootinfo_size);
+
+#endif
+
+#endif
+
+/** @}
+ */
Index: kernel/arch/arm32/include/atomic.h
===================================================================
--- kernel/arch/arm32/include/atomic.h	(revision 3ee8a07528aa466b40a362672714a05e936d396e)
+++ kernel/arch/arm32/include/atomic.h	(revision 6b781c0c856d94b3114ccd6375bc6667a19e9bfe)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2005 Ondrej Palkovsky
+ * Copyright (c) 2007 Michal Kebrt
  * All rights reserved.
  *
@@ -30,5 +30,6 @@
  * @{
  */
-/** @file
+/** @file 
+ *  @brief Atomic operations.
  */
 
@@ -36,17 +37,8 @@
 #define KERN_arm32_ATOMIC_H_
 
-#define atomic_inc(x)	((void) atomic_add(x, 1))
-#define atomic_dec(x)	((void) atomic_add(x, -1))
-
-#define atomic_postinc(x) (atomic_add(x, 1) - 1)
-#define atomic_postdec(x) (atomic_add(x, -1) + 1)
-
-#define atomic_preinc(x) atomic_add(x, 1)
-#define atomic_predec(x) atomic_add(x, -1)
-
-/* Atomic addition of immediate value.
+/** Atomic addition.
  *
- * @param val Memory location to which will be the immediate value added.
- * @param i Signed immediate that will be added to *val.
+ * @param val Where to add.
+ * @param i   Value to be added.
  *
  * @return Value after addition.
@@ -54,6 +46,79 @@
 static inline long atomic_add(atomic_t *val, int i)
 {
-	/* TODO */
-	return (val->count += i);
+	int ret;
+	volatile long *mem = &(val->count);
+
+	asm volatile (
+	"1:\n"
+		"ldr r2, [%1]       \n"
+		"add r3, r2, %2     \n"
+		"str r3, %0         \n"
+		"swp r3, r3, [%1]   \n"
+		"cmp r3, r2         \n"
+		"bne 1b             \n"
+
+		: "=m" (ret)
+		: "r" (mem), "r" (i)
+		: "r3", "r2"
+	);
+
+	return ret;
+}
+
+/** Atomic increment.
+ *
+ * @param val Variable to be incremented.
+ */
+static inline void atomic_inc(atomic_t *val)
+{
+	atomic_add(val, 1);
+}
+
+/** Atomic decrement.
+ *
+ * @param val Variable to be decremented.
+ */
+static inline void atomic_dec(atomic_t *val) {
+	atomic_add(val, -1);
+}
+
+/** Atomic pre-increment.
+ *
+ * @param val Variable to be incremented.
+ * @return    Value after incrementation.
+ */
+static inline long atomic_preinc(atomic_t *val)
+{
+	return atomic_add(val, 1);
+}
+
+/** Atomic pre-decrement.
+ *
+ * @param val Variable to be decremented.
+ * @return    Value after decrementation.
+ */
+static inline long atomic_predec(atomic_t *val)
+{
+	return atomic_add(val, -1);
+}
+
+/** Atomic post-increment.
+ *
+ * @param val Variable to be incremented.
+ * @return    Value before incrementation.
+ */
+static inline long atomic_postinc(atomic_t *val)
+{
+	return atomic_add(val, 1) - 1;
+}
+
+/** Atomic post-decrement.
+ *
+ * @param val Variable to be decremented.
+ * @return    Value before decrementation.
+ */
+static inline long atomic_postdec(atomic_t *val)
+{
+	return atomic_add(val, -1) + 1;
 }
 
Index: kernel/arch/arm32/include/barrier.h
===================================================================
--- kernel/arch/arm32/include/barrier.h	(revision 3ee8a07528aa466b40a362672714a05e936d396e)
+++ kernel/arch/arm32/include/barrier.h	(revision 6b781c0c856d94b3114ccd6375bc6667a19e9bfe)
@@ -31,4 +31,5 @@
  */
 /** @file
+ *  @brief Memory barriers.
  */
 
Index: kernel/arch/arm32/include/boot.h
===================================================================
--- kernel/arch/arm32/include/boot.h	(revision 6b781c0c856d94b3114ccd6375bc6667a19e9bfe)
+++ kernel/arch/arm32/include/boot.h	(revision 6b781c0c856d94b3114ccd6375bc6667a19e9bfe)
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2006 Martin Decky
+ * 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 Bootinfo declarations.
+ *
+ *  Reflects boot/arch/arm32/loader/main.h.
+ */
+
+#ifndef KERN_arm32_BOOT_H_
+#define KERN_arm32_BOOT_H_
+
+#include <arch/types.h>
+
+/** Maximum number of tasks in the #bootinfo_t struct. */
+#define TASKMAP_MAX_RECORDS 32
+
+
+/** Struct holding information about single loaded uspace task. */
+typedef struct {
+
+	/** Address where the task was placed. */
+	uintptr_t addr;
+
+	/** Size of the task's binary. */
+	uint32_t size;
+} utask_t;
+
+
+/** Struct holding information about loaded uspace tasks. */
+typedef struct {
+
+	/** Number of loaded tasks. */
+	uint32_t cnt;
+
+	/** Array of loaded tasks. */	
+	utask_t tasks[TASKMAP_MAX_RECORDS];
+} bootinfo_t;
+
+
+/** Bootinfo that is filled in #kernel_image_start. */ 
+extern bootinfo_t bootinfo;
+
+
+#endif
+
+/** @}
+ */
Index: kernel/arch/arm32/include/byteorder.h
===================================================================
--- kernel/arch/arm32/include/byteorder.h	(revision 3ee8a07528aa466b40a362672714a05e936d396e)
+++ kernel/arch/arm32/include/byteorder.h	(revision 6b781c0c856d94b3114ccd6375bc6667a19e9bfe)
@@ -31,4 +31,5 @@
  */
 /** @file
+ *  @brief Endianness definitions.
  */
 
Index: kernel/arch/arm32/include/console.h
===================================================================
--- kernel/arch/arm32/include/console.h	(revision 6b781c0c856d94b3114ccd6375bc6667a19e9bfe)
+++ kernel/arch/arm32/include/console.h	(revision 6b781c0c856d94b3114ccd6375bc6667a19e9bfe)
@@ -0,0 +1,49 @@
+/*
+ * 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.
+ */
+
+#ifndef KERN_arm32_CONSOLE_H_
+#define KERN_arm32_CONSOLE_H_
+
+
+/** Initializes console.
+ *
+ * @param devno Console device number.
+ */
+extern void console_init(devno_t devno);
+
+#endif
+
+/** @}
+ */
Index: kernel/arch/arm32/include/context.h
===================================================================
--- kernel/arch/arm32/include/context.h	(revision 3ee8a07528aa466b40a362672714a05e936d396e)
+++ kernel/arch/arm32/include/context.h	(revision 6b781c0c856d94b3114ccd6375bc6667a19e9bfe)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2003-2004 Jakub Jermar
+ * Copyright (c) 2007 Michal Kebrt
  * All rights reserved.
  *
@@ -31,4 +31,5 @@
  */
 /** @file
+ *  @brief Thread context.
  */
 
@@ -36,9 +37,9 @@
 #define KERN_arm32_CONTEXT_H_
 
-/*
- * Put one item onto the stack to support get_stack_base() and align it up.
- */
-#define SP_DELTA	0	/* TODO */
+#include <align.h>
+#include <arch/stack.h>
 
+/* Put one item onto the stack to support get_stack_base() and align it up. */
+#define SP_DELTA  (0 + ALIGN_UP(STACK_ITEM_SIZE, STACK_ALIGNMENT))
 
 #ifndef __ASM__
@@ -46,12 +47,24 @@
 #include <arch/types.h>
 
-/*
- * Only save registers that must be preserved across function calls.
+/** Thread context containing registers that must be preserved across function
+ * calls.
  */
 typedef struct {
+	uint32_t cpu_mode;
 	uintptr_t sp;
 	uintptr_t pc;
+	
+	uint32_t r4;
+	uint32_t r5;
+	uint32_t r6;
+	uint32_t r7;
+	uint32_t r8;
+	uint32_t r9;
+	uint32_t r10;
+	uint32_t r11;
+	
 	ipl_t ipl;
 } context_t;
+
 
 #endif /* __ASM__ */
Index: kernel/arch/arm32/include/cpu.h
===================================================================
--- kernel/arch/arm32/include/cpu.h	(revision 3ee8a07528aa466b40a362672714a05e936d396e)
+++ kernel/arch/arm32/include/cpu.h	(revision 6b781c0c856d94b3114ccd6375bc6667a19e9bfe)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2003-2004 Jakub Jermar
+ * Copyright (c) 2007 Michal Kebrt
  * All rights reserved.
  *
@@ -31,4 +31,5 @@
  */
 /** @file
+ *  @brief CPU identification.
  */
 
@@ -39,7 +40,23 @@
 #include <arch/asm.h>
 
+
+/** Struct representing ARM CPU identifiaction. */
 typedef struct {
+	/** Implementator (vendor) number. */
+	uint32_t imp_num;
+
+	/** Variant number. */
+	uint32_t variant_num;
+
+	/** Architecture number. */
+	uint32_t arch_num;
+
+	/** Primary part number. */
+	uint32_t prim_part_num;
+
+	/** Revision number. */
+	uint32_t rev_num;
 } cpu_arch_t;
-	
+
 #endif
 
Index: kernel/arch/arm32/include/cycle.h
===================================================================
--- kernel/arch/arm32/include/cycle.h	(revision 3ee8a07528aa466b40a362672714a05e936d396e)
+++ kernel/arch/arm32/include/cycle.h	(revision 6b781c0c856d94b3114ccd6375bc6667a19e9bfe)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2006 Martin Decky
+ * Copyright (c) 2007 Michal Kebrt
  * All rights reserved.
  *
@@ -31,4 +31,5 @@
  */
 /** @file
+ *  @brief Count of CPU cycles.
  */
 
@@ -36,7 +37,12 @@
 #define KERN_arm32_CYCLE_H_
 
+/** Returns count of CPU cycles.
+ *
+ *  No such instruction on ARM to get count of cycles.
+ *
+ *  @return Count of CPU cycles.
+ */
 static inline uint64_t get_cycle(void)
 {
-	/* TODO */
 	return 0;
 }
Index: kernel/arch/arm32/include/debug.h
===================================================================
--- kernel/arch/arm32/include/debug.h	(revision 3ee8a07528aa466b40a362672714a05e936d396e)
+++ kernel/arch/arm32/include/debug.h	(revision 6b781c0c856d94b3114ccd6375bc6667a19e9bfe)
@@ -31,4 +31,5 @@
  */
 /** @file
+ *  @brief Empty.
  */
 
Index: kernel/arch/arm32/include/debug/print.h
===================================================================
--- kernel/arch/arm32/include/debug/print.h	(revision 6b781c0c856d94b3114ccd6375bc6667a19e9bfe)
+++ kernel/arch/arm32/include/debug/print.h	(revision 6b781c0c856d94b3114ccd6375bc6667a19e9bfe)
@@ -0,0 +1,56 @@
+/*
+ * 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 printing functions.
+ */
+
+#ifndef KERN_arm32_DEBUG_PRINT_H_
+#define KERN_arm32_DEBUG_PRINT_H_
+
+#include <stdarg.h>
+#include <arch/types.h>
+
+extern void debug_puts(const char *str);
+extern void debug_printf(const char *fmt, ...);
+
+#ifdef CONFIG_DEBUG
+#	define dprintf(arg1...) debug_printf(arg1)
+#	define dputs(arg1) debug_puts(arg1)
+#else
+#	define dprintf(arg1...)
+#	define dputs(arg1)
+#endif
+
+#endif
+
+/** @}
+ */
Index: kernel/arch/arm32/include/drivers/gxemul.h
===================================================================
--- kernel/arch/arm32/include/drivers/gxemul.h	(revision 6b781c0c856d94b3114ccd6375bc6667a19e9bfe)
+++ kernel/arch/arm32/include/drivers/gxemul.h	(revision 6b781c0c856d94b3114ccd6375bc6667a19e9bfe)
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2007 Michal Kebrt
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup arm32gxemul GXemul
+ *  @brief GXemul machine specific parts.
+ *  @ingroup arm32
+ * @{
+ */
+/** @file
+ *  @brief GXemul peripheries drivers declarations.
+ */
+
+#ifndef KERN_arm32_GXEMUL_H_
+#define KERN_arm32_GXEMUL_H_
+
+#include <console/chardev.h>
+
+/** Last interrupt number (beginning from 0) whose status is probed 
+ * from interrupt controller
+ */
+#define GXEMUL_IRQC_MAX_IRQ		8
+
+/** Timer frequency */
+#define GXEMUL_TIMER_FREQ		100
+
+/** Struct containing mappings of gxemul HW devices into kernel part 
+ *  of virtual address space.
+ */
+typedef struct {
+	uintptr_t videoram;
+	uintptr_t kbd;
+	uintptr_t rtc;
+	uintptr_t rtc_freq;
+	uintptr_t rtc_ack;
+	uintptr_t irqc;
+	uintptr_t irqc_mask;
+	uintptr_t irqc_unmask;
+} gxemul_hw_map_t;
+
+extern void gxemul_hw_map_init(void);
+extern void gxemul_console_init(devno_t devno);
+extern void gxemul_release_console(void);
+extern void gxemul_grab_console(void);
+extern void gxemul_timer_irq_start(void);
+extern void gxemul_debug_putc(char ch);
+extern void gxemul_cpu_halt(void);
+extern void gxemul_irq_exception(int exc_no, istate_t *istate);
+extern size_t gxemul_get_memory_size(void);
+extern uintptr_t gxemul_get_fb_address(void);
+
+#endif
+
+/** @}
+ */
Index: kernel/arch/arm32/include/elf.h
===================================================================
--- kernel/arch/arm32/include/elf.h	(revision 3ee8a07528aa466b40a362672714a05e936d396e)
+++ kernel/arch/arm32/include/elf.h	(revision 6b781c0c856d94b3114ccd6375bc6667a19e9bfe)
@@ -31,4 +31,5 @@
  */
 /** @file
+ *  @brief ARM ELF constants.
  */
 
Index: kernel/arch/arm32/include/exception.h
===================================================================
--- kernel/arch/arm32/include/exception.h	(revision 3ee8a07528aa466b40a362672714a05e936d396e)
+++ kernel/arch/arm32/include/exception.h	(revision 6b781c0c856d94b3114ccd6375bc6667a19e9bfe)
@@ -1,4 +1,5 @@
 /*
- * Copyright (c) 2003-2004 Jakub Jermar
+ * Copyright (c) 2007 Michal Kebrt, Petr Stepan
+ *
  * All rights reserved.
  *
@@ -31,4 +32,5 @@
  */
 /** @file
+ *  @brief Exception declarations.
  */
 
@@ -37,25 +39,103 @@
 
 #include <arch/types.h>
+#include <arch/regutils.h>
 
+/** If defined, forces using of high exception vectors. */
+#define HIGH_EXCEPTION_VECTORS
+
+#ifdef HIGH_EXCEPTION_VECTORS
+	#define EXC_BASE_ADDRESS	0xffff0000
+#else
+	#define EXC_BASE_ADDRESS	0x0
+#endif
+
+/* Exception Vectors */
+#define EXC_RESET_VEC          (EXC_BASE_ADDRESS + 0x0)
+#define EXC_UNDEF_INSTR_VEC    (EXC_BASE_ADDRESS + 0x4)
+#define EXC_SWI_VEC            (EXC_BASE_ADDRESS + 0x8)
+#define EXC_PREFETCH_ABORT_VEC (EXC_BASE_ADDRESS + 0xc)
+#define EXC_DATA_ABORT_VEC     (EXC_BASE_ADDRESS + 0x10)
+#define EXC_IRQ_VEC            (EXC_BASE_ADDRESS + 0x18)
+#define EXC_FIQ_VEC            (EXC_BASE_ADDRESS + 0x1c)
+
+/* Exception numbers */
+#define EXC_RESET           0
+#define EXC_UNDEF_INSTR     1
+#define EXC_SWI             2
+#define EXC_PREFETCH_ABORT  3
+#define EXC_DATA_ABORT      4
+#define EXC_IRQ             5
+#define EXC_FIQ             6
+
+
+/** Kernel stack pointer.
+ *
+ * It is set when thread switches to user mode,
+ * and then used for exception handling.
+ */
+extern uintptr_t supervisor_sp;
+
+
+/** Temporary exception stack pointer.
+ *
+ * Temporary stack is used in exceptions handling routines
+ * before switching to thread's kernel stack.
+ */
+extern uintptr_t exc_stack;
+
+
+/** Struct representing CPU state saved when an exception occurs. */
 typedef struct {
-	/* TODO */
+	uint32_t spsr;
+	uint32_t sp;
+	uint32_t lr;
+
+	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 pc;
 } istate_t;
 
+
+/** Sets Program Counter member of given istate structure.
+ *
+ * @param istate istate structure
+ * @param retaddr new value of istate's PC member
+ */
 static inline void istate_set_retaddr(istate_t *istate, uintptr_t retaddr)
 {
-	/* TODO */
+ 	istate->pc = retaddr;
 }
 
-/** Return true if exception happened while in userspace */
+
+/** Returns true if exception happened while in userspace. */
 static inline int istate_from_uspace(istate_t *istate)
 {
-	/* TODO */
-	return 0;
+ 	return (istate->spsr & STATUS_REG_MODE_MASK) == USER_MODE;
 }
+
+
+/** Returns Program Counter member of given istate structure. */
 static inline unative_t istate_get_pc(istate_t *istate)
 {
-	/* TODO */
-	return 0;
+ 	return istate->pc;
 }
+
+
+extern void install_exception_handlers(void);
+extern void exception_init(void);
+extern void print_istate(istate_t *istate);
+
 
 #endif
Index: kernel/arch/arm32/include/faddr.h
===================================================================
--- kernel/arch/arm32/include/faddr.h	(revision 3ee8a07528aa466b40a362672714a05e936d396e)
+++ kernel/arch/arm32/include/faddr.h	(revision 6b781c0c856d94b3114ccd6375bc6667a19e9bfe)
@@ -31,4 +31,5 @@
  */
 /** @file
+ *  @brief Function address conversion.
  */
 
@@ -38,4 +39,8 @@
 #include <arch/types.h>
 
+/** Calculate absolute address of function referenced by fptr pointer.
+ *
+ * @param fptr Function pointer.
+ */
 #define FADDR(fptr)		((uintptr_t) (fptr))
 
Index: kernel/arch/arm32/include/fpu_context.h
===================================================================
--- kernel/arch/arm32/include/fpu_context.h	(revision 3ee8a07528aa466b40a362672714a05e936d396e)
+++ kernel/arch/arm32/include/fpu_context.h	(revision 6b781c0c856d94b3114ccd6375bc6667a19e9bfe)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2005 Jakub Vana
+ * Copyright (c) 2007 Michal Kebrt
  * All rights reserved.
  *
@@ -31,4 +31,7 @@
  */
 /** @file
+ *  @brief FPU context (not implemented).
+ *
+ *  GXemul doesn't support FPU on its ARM CPU.
  */
 
@@ -38,5 +41,5 @@
 #include <arch/types.h>
 
-#define FPU_CONTEXT_ALIGN    0	/* TODO */
+#define FPU_CONTEXT_ALIGN    0
 
 typedef struct {
Index: kernel/arch/arm32/include/interrupt.h
===================================================================
--- kernel/arch/arm32/include/interrupt.h	(revision 3ee8a07528aa466b40a362672714a05e936d396e)
+++ kernel/arch/arm32/include/interrupt.h	(revision 6b781c0c856d94b3114ccd6375bc6667a19e9bfe)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2005 Jakub Jermar
+ * Copyright (c) 2007 Michal Kebrt
  * All rights reserved.
  *
@@ -28,8 +28,8 @@
 
 /** @addtogroup arm32interrupt
- * @ingroup interrupt
  * @{
  */
 /** @file
+ *  @brief Declarations of interrupt controlling routines.
  */
 
@@ -37,6 +37,19 @@
 #define KERN_arm32_INTERRUPT_H_
 
-#define IVT_ITEMS 	0	/* TODO */
-#define IVT_FIRST	0	/* TODO */
+#include <arch/types.h>
+
+/** Initial size of exception dispatch table. */
+#define IVT_ITEMS 	6
+
+/** Index of the first item in exception dispatch table. */
+#define IVT_FIRST	0
+
+
+extern void interrupt_init(void);
+extern ipl_t interrupts_disable(void);
+extern ipl_t interrupts_enable(void);
+extern void interrupts_restore(ipl_t ipl);
+extern ipl_t interrupts_read(void);
+
 
 #endif
Index: kernel/arch/arm32/include/machine.h
===================================================================
--- kernel/arch/arm32/include/machine.h	(revision 6b781c0c856d94b3114ccd6375bc6667a19e9bfe)
+++ kernel/arch/arm32/include/machine.h	(revision 6b781c0c856d94b3114ccd6375bc6667a19e9bfe)
@@ -0,0 +1,122 @@
+/*
+ * 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 Declarations of machine specific functions.
+ *
+ *  These functions enable to differentiate more kinds of ARM emulators
+ *  or CPUs. It's the same concept as "arch" functions on the architecture
+ *  level.
+ */
+
+#ifndef KERN_arm32_MACHINE_H_
+#define KERN_arm32_MACHINE_H_
+
+#include <console/console.h>
+#include <arch/types.h>
+#include <arch/exception.h>
+#include <arch/drivers/gxemul.h>
+
+
+/** Initializes console.
+ *
+ * @param devno Console device number.
+ */
+extern void machine_console_init(devno_t devno);
+
+
+/** Acquire console back for kernel. */
+extern void machine_grab_console(void);
+
+
+/** Return console to userspace. */
+extern void machine_release_console(void);
+
+
+/** Maps HW devices to the kernel address space using #hw_map. */
+extern void machine_hw_map_init(void);
+
+
+/** Starts timer. */
+extern void machine_timer_irq_start(void);
+
+
+/** Halts CPU. */
+extern void machine_cpu_halt(void);
+
+
+/** Returns size of available memory.
+ *
+ *  @return Size of available memory.
+ */
+extern size_t machine_get_memory_size(void);
+
+
+/** Prints a character. 
+ *
+ *  @param ch Character to be printed.
+ */
+extern void machine_debug_putc(char ch);
+
+
+/** Interrupt exception handler.
+ *
+ * @param exc_no Interrupt exception number.
+ * @param istate Saved processor state.
+ */
+extern void machine_irq_exception(int exc_no, istate_t *istate);
+
+
+/** Returns address of framebuffer device.
+ *
+ *  @return Address of framebuffer device.
+ */
+extern uintptr_t machine_get_fb_address(void);
+
+
+#ifdef MACHINE_GXEMUL_TESTARM 	
+#define machine_console_init(devno)           gxemul_console_init(devno)
+#define machine_grab_console                  gxemul_grab_console
+#define machine_release_console               gxemul_release_console 
+#define machine_hw_map_init                   gxemul_hw_map_init
+#define machine_timer_irq_start               gxemul_timer_irq_start
+#define machine_cpu_halt                      gxemul_cpu_halt
+#define machine_get_memory_size               gxemul_get_memory_size
+#define machine_debug_putc(ch)                gxemul_debug_putc(ch)
+#define machine_irq_exception(exc_no, istate) \
+        gxemul_irq_exception(exc_no, istate)
+#define machine_get_fb_address                gxemul_get_fb_address
+#endif
+
+#endif
+
+/** @}
+ */
Index: kernel/arch/arm32/include/mainpage.h
===================================================================
--- kernel/arch/arm32/include/mainpage.h	(revision 6b781c0c856d94b3114ccd6375bc6667a19e9bfe)
+++ kernel/arch/arm32/include/mainpage.h	(revision 6b781c0c856d94b3114ccd6375bc6667a19e9bfe)
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2005 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.
+ */
+
+/** @mainpage HelenOS ARM 32-bit port
+ *
+ *
+ * @section sec_arm32 ARM 32-bit port
+ *     arm32 port is the ninth port of SPARTAN, originally written by Michal Kebrt,
+ *     Petr Stepan, Pavel Jancik. The goal is to support 32-bit ARM architecture.
+ *     So far, it runs only in emulator.
+ *
+ * @subsection sec_arm32_doc Documentation
+ * <ul>
+ *	<li>See 'kernel/doc/arm32_HOWTO' for information about getting an emulator, 
+ *	    building sources and running HelenOS.
+ *	</li>
+ *	<li>See <a href="http://www.helenos.eu/doc/slides/2007-05-21-Stepan-ARM.pdf">slides</a>
+ *	    for some information about ARM architecture and porting HelenOS to ARM
+ *	    (only in Czech).
+ *	</li>
+ * </ul>
+ *
+ *     
+ */
Index: kernel/arch/arm32/include/memstr.h
===================================================================
--- kernel/arch/arm32/include/memstr.h	(revision 3ee8a07528aa466b40a362672714a05e936d396e)
+++ kernel/arch/arm32/include/memstr.h	(revision 6b781c0c856d94b3114ccd6375bc6667a19e9bfe)
@@ -31,4 +31,5 @@
  */
 /** @file
+ *  @brief Memory manipulating functions declarations.
  */
 
Index: kernel/arch/arm32/include/mm/as.h
===================================================================
--- kernel/arch/arm32/include/mm/as.h	(revision 3ee8a07528aa466b40a362672714a05e936d396e)
+++ kernel/arch/arm32/include/mm/as.h	(revision 6b781c0c856d94b3114ccd6375bc6667a19e9bfe)
@@ -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 manipulating functions declarations.
  */
 
@@ -38,8 +39,8 @@
 #define KERNEL_ADDRESS_SPACE_SHADOWED_ARCH	0
 
-#define KERNEL_ADDRESS_SPACE_START_ARCH		(unsigned long) 0x80000000
-#define KERNEL_ADDRESS_SPACE_END_ARCH		(unsigned long) 0xffffffff
-#define USER_ADDRESS_SPACE_START_ARCH		(unsigned long) 0x00000000
-#define USER_ADDRESS_SPACE_END_ARCH		(unsigned long) 0x7fffffff
+#define KERNEL_ADDRESS_SPACE_START_ARCH     (unsigned long) 0x80000000
+#define KERNEL_ADDRESS_SPACE_END_ARCH       (unsigned long) 0xffffffff
+#define USER_ADDRESS_SPACE_START_ARCH       (unsigned long) 0x00000000
+#define USER_ADDRESS_SPACE_END_ARCH         (unsigned long) 0x7fffffff
 
 #define USTACK_ADDRESS_ARCH	(0x80000000 - PAGE_SIZE)
@@ -53,4 +54,5 @@
 #define as_destructor_arch(as)			(as != as)
 #define as_create_arch(as, flags)		(as != as)
+#define as_install_arch(as)
 #define as_deinstall_arch(as)
 #define as_invalidate_translation_cache(as, page, cnt)
Index: kernel/arch/arm32/include/mm/asid.h
===================================================================
--- kernel/arch/arm32/include/mm/asid.h	(revision 3ee8a07528aa466b40a362672714a05e936d396e)
+++ kernel/arch/arm32/include/mm/asid.h	(revision 6b781c0c856d94b3114ccd6375bc6667a19e9bfe)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2005 Martin Decky
+ * Copyright (c) 2007 Pavel Jancik, Michal Kebrt
  * All rights reserved.
  *
@@ -31,4 +31,7 @@
  */
 /** @file
+ *  @brief ASIDs related declarations.
+ *
+ *  ARM CPUs doesn't support ASIDs.
  */
 
@@ -38,7 +41,15 @@
 #include <arch/types.h>
 
-#define ASID_MAX_ARCH		3	/* TODO */
+#define ASID_MAX_ARCH		3	/* minimal required number */
 
 typedef uint8_t asid_t;
+
+/*
+ * This works due to fact that this file is never included alone but only
+ * through "generic/include/mm/asid.h" where ASID_START is defined.
+ */
+#define asid_get()		(ASID_START + 1)
+
+#define asid_put(asid) 
 
 #endif
Index: kernel/arch/arm32/include/mm/frame.h
===================================================================
--- kernel/arch/arm32/include/mm/frame.h	(revision 3ee8a07528aa466b40a362672714a05e936d396e)
+++ kernel/arch/arm32/include/mm/frame.h	(revision 6b781c0c856d94b3114ccd6375bc6667a19e9bfe)
@@ -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 Frame related declarations.
  */
 
@@ -36,5 +37,5 @@
 #define KERN_arm32_FRAME_H_
 
-#define FRAME_WIDTH		0	/* TODO */
+#define FRAME_WIDTH		12 /* 4KB frames */
 #define FRAME_SIZE		(1 << FRAME_WIDTH)
 
@@ -42,5 +43,16 @@
 #ifndef __ASM__
 
+#include <arch/types.h>
+
+#define BOOT_PAGE_TABLE_SIZE    0x4000
+#define BOOT_PAGE_TABLE_ADDRESS 0x4000
+
+#define BOOT_PAGE_TABLE_START_FRAME     (BOOT_PAGE_TABLE_ADDRESS >> FRAME_WIDTH)
+#define BOOT_PAGE_TABLE_SIZE_IN_FRAMES  (BOOT_PAGE_TABLE_SIZE >> FRAME_WIDTH)
+
+extern uintptr_t last_frame;
+
 extern void frame_arch_init(void);
+extern void boot_page_table_free(void);
 
 #endif /* __ASM__ */
Index: kernel/arch/arm32/include/mm/memory_init.h
===================================================================
--- kernel/arch/arm32/include/mm/memory_init.h	(revision 3ee8a07528aa466b40a362672714a05e936d396e)
+++ kernel/arch/arm32/include/mm/memory_init.h	(revision 6b781c0c856d94b3114ccd6375bc6667a19e9bfe)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2005 Jakub Jermar
+ * Copyright (c) 2007 Pavel Jancik
  * All rights reserved.
  *
@@ -31,4 +31,5 @@
  */
 /** @file
+ *  @brief Memory information functions declarations.
  */
 
@@ -38,5 +39,5 @@
 #include <config.h>
 
-#define get_memory_size()	CONFIG_MEMORY_SIZE	/* TODO */
+size_t get_memory_size(void);
 
 #endif
Index: kernel/arch/arm32/include/mm/page.h
===================================================================
--- kernel/arch/arm32/include/mm/page.h	(revision 3ee8a07528aa466b40a362672714a05e936d396e)
+++ kernel/arch/arm32/include/mm/page.h	(revision 6b781c0c856d94b3114ccd6375bc6667a19e9bfe)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2003-2007 Jakub Jermar
+ * Copyright (c) 2007 Pavel Jancik, Michal Kebrt
  * All rights reserved.
  *
@@ -31,4 +31,5 @@
  */
 /** @file
+ *  @brief Paging related declarations.
  */
 
@@ -37,4 +38,6 @@
 
 #include <arch/mm/frame.h>
+#include <mm/mm.h>
+#include <arch/exception.h>
 
 #define PAGE_WIDTH	FRAME_WIDTH
@@ -53,60 +56,259 @@
 #ifdef KERNEL
 
-#define PTL0_ENTRIES_ARCH	0	/* TODO */
-#define PTL1_ENTRIES_ARCH	0	/* TODO */
-#define PTL2_ENTRIES_ARCH	0	/* TODO */
-#define PTL3_ENTRIES_ARCH	0	/* TODO */
-
-#define PTL0_INDEX_ARCH(vaddr)  0	/* TODO */ 
-#define PTL1_INDEX_ARCH(vaddr)  0	/* TODO */
-#define PTL2_INDEX_ARCH(vaddr)  0	/* TODO */
-#define PTL3_INDEX_ARCH(vaddr)  0	/* TODO */
-
-#define SET_PTL0_ADDRESS_ARCH(ptl0)
-
-#define GET_PTL1_ADDRESS_ARCH(ptl0, i)		0	/* TODO */
-#define GET_PTL2_ADDRESS_ARCH(ptl1, i)		0	/* TODO */
-#define GET_PTL3_ADDRESS_ARCH(ptl2, i)		0	/* TODO */
-#define GET_FRAME_ADDRESS_ARCH(ptl3, i)		0	/* TODO */
-
-#define SET_PTL1_ADDRESS_ARCH(ptl0, i, a)	/* TODO */
-#define SET_PTL2_ADDRESS_ARCH(ptl1, i, a)	/* TODO */
-#define SET_PTL3_ADDRESS_ARCH(ptl2, i, a)	/* TODO */
-#define SET_FRAME_ADDRESS_ARCH(ptl3, i, a)	/* TODO */
-
-#define GET_PTL1_FLAGS_ARCH(ptl0, i)		0	/* TODO */
-#define GET_PTL2_FLAGS_ARCH(ptl1, i)		0	/* TODO */
-#define GET_PTL3_FLAGS_ARCH(ptl2, i)		0	/* TODO */
-#define GET_FRAME_FLAGS_ARCH(ptl3, i)		0	/* TODO */
-
-#define SET_PTL1_FLAGS_ARCH(ptl0, i, x)		/* TODO */
-#define SET_PTL2_FLAGS_ARCH(ptl1, i, x)		/* TODO */
-#define SET_PTL3_FLAGS_ARCH(ptl2, i, x)		/* TODO */
-#define SET_FRAME_FLAGS_ARCH(ptl3, i, x)	/* TODO */
-
-#define PTE_VALID_ARCH(pte)			0	/* TODO */
-#define PTE_PRESENT_ARCH(pte)			0	/* TODO */
-#define PTE_GET_FRAME_ARCH(pte)			0	/* TODO */
-#define PTE_WRITABLE_ARCH(pte)			0	/* TODO */
-#define PTE_EXECUTABLE_ARCH(pte)		0	/* TODO */
+#define PTL0_ENTRIES_ARCH 	(2 << 12)	/* 4096 */
+#define PTL1_ENTRIES_ARCH 	0
+#define PTL2_ENTRIES_ARCH 	0
+
+/* coarse page tables used (256 * 4 = 1KB per page) */
+#define PTL3_ENTRIES_ARCH 	(2 << 8)	/* 256 */
+
+#define PTL0_SIZE_ARCH 		FOUR_FRAMES
+#define PTL1_SIZE_ARCH 		0
+#define PTL2_SIZE_ARCH 		0
+#define PTL3_SIZE_ARCH 		ONE_FRAME
+
+#define PTL0_INDEX_ARCH(vaddr) 	(((vaddr) >> 20) & 0xfff)
+#define PTL1_INDEX_ARCH(vaddr) 	0
+#define PTL2_INDEX_ARCH(vaddr) 	0
+#define PTL3_INDEX_ARCH(vaddr) 	(((vaddr) >> 12) & 0x0ff)
+
+#define GET_PTL1_ADDRESS_ARCH(ptl0, i) \
+	((pte_t *) ((((pte_level0_t *)(ptl0))[(i)]).coarse_table_addr << 10))
+#define GET_PTL2_ADDRESS_ARCH(ptl1, i) \
+	(ptl1)
+#define GET_PTL3_ADDRESS_ARCH(ptl2, i) \
+	(ptl2)
+#define GET_FRAME_ADDRESS_ARCH(ptl3, i) \
+	((uintptr_t) ((((pte_level1_t *)(ptl3))[(i)]).frame_base_addr << 12))
+
+#define SET_PTL0_ADDRESS_ARCH(ptl0) \
+	(set_ptl0_addr((pte_level0_t *) (ptl0)))
+#define SET_PTL1_ADDRESS_ARCH(ptl0, i, a) \
+	(((pte_level0_t *) (ptl0))[(i)].coarse_table_addr = (a) >> 10)
+#define SET_PTL2_ADDRESS_ARCH(ptl1, i, a)
+#define SET_PTL3_ADDRESS_ARCH(ptl2, i, a)
+#define SET_FRAME_ADDRESS_ARCH(ptl3, i, a) \
+	(((pte_level1_t *) (ptl3))[(i)].frame_base_addr = (a) >> 12)
+
+#define GET_PTL1_FLAGS_ARCH(ptl0, i) \
+	get_pt_level0_flags((pte_level0_t *) (ptl0), (index_t) (i))
+#define GET_PTL2_FLAGS_ARCH(ptl1, i) \
+	PAGE_PRESENT
+#define GET_PTL3_FLAGS_ARCH(ptl2, i) \
+	PAGE_PRESENT
+#define GET_FRAME_FLAGS_ARCH(ptl3, i) \
+	get_pt_level1_flags((pte_level1_t *) (ptl3), (index_t) (i))
+
+#define SET_PTL1_FLAGS_ARCH(ptl0, i, x) \
+	set_pt_level0_flags((pte_level0_t *) (ptl0), (index_t) (i), (x))
+#define SET_PTL2_FLAGS_ARCH(ptl1, i, x)
+#define SET_PTL3_FLAGS_ARCH(ptl2, i, x)
+#define SET_FRAME_FLAGS_ARCH(ptl3, i, x) \
+	set_pt_level1_flags((pte_level1_t *) (ptl3), (index_t) (i), (x))
+
+#define PTE_VALID_ARCH(pte) \
+	(*((uint32_t *) (pte)) != 0)
+#define PTE_PRESENT_ARCH(pte) \
+	(((pte_level0_t *) (pte))->descriptor_type != 0)
+
+/* pte should point into ptl3 */
+#define PTE_GET_FRAME_ARCH(pte) \
+	(((pte_level1_t *) (pte))->frame_base_addr << FRAME_WIDTH)
+
+/* pte should point into ptl3 */
+#define PTE_WRITABLE_ARCH(pte) \
+	(((pte_level1_t *) (pte))->access_permission_0 == \
+	    PTE_AP_USER_RW_KERNEL_RW)
+
+#define PTE_EXECUTABLE_ARCH(pte) \
+	1
 
 #ifndef __ASM__
 
-#include <mm/mm.h>
-#include <arch/exception.h>
-
-static inline int get_pt_flags(pte_t *pt, index_t i)
-{
-	return 0;	/* TODO */
-}
-
-static inline void set_pt_flags(pte_t *pt, index_t i, int flags)
-{
-	/* TODO */
-	return;
-}
+/** Level 0 page table entry. */
+typedef struct {
+	/* 0b01 for coarse tables, see below for details */
+	unsigned descriptor_type     : 2;
+	unsigned impl_specific       : 3;
+	unsigned domain              : 4;
+	unsigned should_be_zero      : 1;
+
+	/* Pointer to the coarse 2nd level page table (holding entries for small
+	 * (4KB) or large (64KB) pages. ARM also supports fine 2nd level page
+	 * tables that may hold even tiny pages (1KB) but they are bigger (4KB
+	 * per table in comparison with 1KB per the coarse table)
+	 */
+	unsigned coarse_table_addr   : 22;
+} ATTRIBUTE_PACKED pte_level0_t;
+
+/** Level 1 page table entry (small (4KB) pages used). */
+typedef struct {
+
+	/* 0b10 for small pages */
+	unsigned descriptor_type     : 2;
+	unsigned bufferable          : 1;
+	unsigned cacheable           : 1;
+
+	/* access permissions for each of 4 subparts of a page
+	 * (for each 1KB when small pages used */
+	unsigned access_permission_0 : 2;
+	unsigned access_permission_1 : 2;
+	unsigned access_permission_2 : 2;
+	unsigned access_permission_3 : 2;
+	unsigned frame_base_addr     : 20;
+} ATTRIBUTE_PACKED pte_level1_t;
+
+
+/* Level 1 page tables access permissions */
+
+/** User mode: no access, privileged mode: no access. */
+#define PTE_AP_USER_NO_KERNEL_NO	0
+
+/** User mode: no access, privileged mode: read/write. */
+#define PTE_AP_USER_NO_KERNEL_RW	1
+
+/** User mode: read only, privileged mode: read/write. */
+#define PTE_AP_USER_RO_KERNEL_RW	2
+
+/** User mode: read/write, privileged mode: read/write. */
+#define PTE_AP_USER_RW_KERNEL_RW	3
+
+
+/* pte_level0_t and pte_level1_t descriptor_type flags */
+
+/** pte_level0_t and pte_level1_t "not present" flag (used in descriptor_type). */
+#define PTE_DESCRIPTOR_NOT_PRESENT	0
+
+/** pte_level0_t coarse page table flag (used in descriptor_type). */
+#define PTE_DESCRIPTOR_COARSE_TABLE	1
+
+/** pte_level1_t small page table flag (used in descriptor type). */
+#define PTE_DESCRIPTOR_SMALL_PAGE	2
+
+
+/** Sets the address of level 0 page table.
+ *
+ * @param pt    Pointer to the page table to set.
+ */   
+static inline void set_ptl0_addr( pte_level0_t *pt)
+{
+	asm volatile (
+		"mcr p15, 0, %0, c2, c0, 0 \n"
+		:
+		: "r"(pt)
+	);
+}
+
+
+/** Returns level 0 page table entry flags.
+ *
+ *  @param pt     Level 0 page table.
+ *  @param i      Index of the entry to return.
+ */
+static inline int get_pt_level0_flags(pte_level0_t *pt, index_t i)
+{
+	pte_level0_t *p = &pt[i];
+	int np = (p->descriptor_type == PTE_DESCRIPTOR_NOT_PRESENT);
+
+	return (np << PAGE_PRESENT_SHIFT) | (1 << PAGE_USER_SHIFT) |
+	    (1 << PAGE_READ_SHIFT) | (1 << PAGE_WRITE_SHIFT) |
+	    (1 << PAGE_EXEC_SHIFT) | (1 << PAGE_CACHEABLE_SHIFT);
+}
+
+/** Returns level 1 page table entry flags.
+ *
+ *  @param pt     Level 1 page table.
+ *  @param i      Index of the entry to return.
+ */
+static inline int get_pt_level1_flags(pte_level1_t *pt, index_t i)
+{
+	pte_level1_t *p = &pt[i];
+
+	int dt = p->descriptor_type;
+	int ap = p->access_permission_0;
+
+	return ((dt == PTE_DESCRIPTOR_NOT_PRESENT) << PAGE_PRESENT_SHIFT) |
+	    ((ap == PTE_AP_USER_RO_KERNEL_RW) << PAGE_READ_SHIFT) |
+	    ((ap == PTE_AP_USER_RW_KERNEL_RW) << PAGE_READ_SHIFT) |
+	    ((ap == PTE_AP_USER_RW_KERNEL_RW) << PAGE_WRITE_SHIFT) |
+	    ((ap != PTE_AP_USER_NO_KERNEL_RW) << PAGE_USER_SHIFT) |
+	    ((ap == PTE_AP_USER_NO_KERNEL_RW) << PAGE_READ_SHIFT) |
+	    ((ap == PTE_AP_USER_NO_KERNEL_RW) << PAGE_WRITE_SHIFT) |
+	    (1 << PAGE_EXEC_SHIFT) |
+	    (p->bufferable << PAGE_CACHEABLE);
+}
+
+
+/** Sets flags of level 0 page table entry.
+ *
+ *  @param pt     level 0 page table
+ *  @param i      index of the entry to be changed
+ *  @param flags  new flags
+ */
+static inline void set_pt_level0_flags(pte_level0_t *pt, index_t i, int flags)
+{
+	pte_level0_t *p = &pt[i];
+
+	if (flags & PAGE_NOT_PRESENT) {
+		p->descriptor_type = PTE_DESCRIPTOR_NOT_PRESENT;
+		/*
+		 * Ensures that the entry will be recognized as valid when
+		 * PTE_VALID_ARCH applied.
+		 */
+		p->should_be_zero = 1;
+	} else {
+		p->descriptor_type = PTE_DESCRIPTOR_COARSE_TABLE;
+		p->should_be_zero = 0;
+    }
+}
+
+
+/** Sets flags of level 1 page table entry.
+ *
+ *  We use same access rights for the whole page. When page is not preset we
+ *  store 1 in acess_rigts_3 so that at least one bit is 1 (to mark correct
+ *  page entry, see #PAGE_VALID_ARCH).
+ *
+ *  @param pt     Level 1 page table.
+ *  @param i      Index of the entry to be changed.
+ *  @param flags  New flags.
+ */  
+static inline void set_pt_level1_flags(pte_level1_t *pt, index_t i, int flags)
+{
+	pte_level1_t *p = &pt[i];
+	
+	if (flags & PAGE_NOT_PRESENT) {
+		p->descriptor_type = PTE_DESCRIPTOR_NOT_PRESENT;
+		p->access_permission_3 = 1;
+	} else {
+		p->descriptor_type = PTE_DESCRIPTOR_SMALL_PAGE;
+		p->access_permission_3 = p->access_permission_0;
+	}
+  
+	p->cacheable = p->bufferable = (flags & PAGE_CACHEABLE) != 0;
+
+	/* default access permission */
+	p->access_permission_0 = p->access_permission_1 = 
+	    p->access_permission_2 = p->access_permission_3 =
+	    PTE_AP_USER_NO_KERNEL_RW;
+
+	if (flags & PAGE_USER)  {
+		if (flags & PAGE_READ) {
+			p->access_permission_0 = p->access_permission_1 = 
+			    p->access_permission_2 = p->access_permission_3 = 
+			    PTE_AP_USER_RO_KERNEL_RW;
+		}
+		if (flags & PAGE_WRITE) {
+			p->access_permission_0 = p->access_permission_1 = 
+			    p->access_permission_2 = p->access_permission_3 = 
+			    PTE_AP_USER_RW_KERNEL_RW; 
+		}
+	}
+}
+
 
 extern void page_arch_init(void);
 
+
 #endif /* __ASM__ */
 
Index: kernel/arch/arm32/include/mm/page_fault.h
===================================================================
--- kernel/arch/arm32/include/mm/page_fault.h	(revision 6b781c0c856d94b3114ccd6375bc6667a19e9bfe)
+++ kernel/arch/arm32/include/mm/page_fault.h	(revision 6b781c0c856d94b3114ccd6375bc6667a19e9bfe)
@@ -0,0 +1,89 @@
+/*
+ * 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 declarations.
+ */
+
+#ifndef KERN_arm32_PAGE_FAULT_H_
+#define KERN_arm32_PAGE_FAULT_H_
+
+#include <arch/types.h>
+
+
+/** Decribes CP15 "fault status register" (FSR). */
+typedef struct {
+	unsigned status           : 3;
+	unsigned domain           : 4;
+	unsigned zero             : 1;
+	unsigned should_be_zero   : 24;
+} ATTRIBUTE_PACKED fault_status_t;
+
+
+/** Help union used for casting integer value into #fault_status_t. */
+typedef union {
+	fault_status_t fs;
+	uint32_t dummy;
+} fault_status_union_t;
+
+
+/** Simplified description of instruction code.
+ *
+ * @note Used for recognizing memory access instructions.
+ * @see ARM architecture reference (chapter 3.1)
+ */
+typedef struct {
+	unsigned dummy1        : 4;
+	unsigned bit4          : 1;
+	unsigned bits567       : 3;
+	unsigned dummy         : 12;
+	unsigned access        : 1;
+	unsigned opcode        : 4;
+	unsigned type          : 3;
+	unsigned condition     : 4;
+} ATTRIBUTE_PACKED instruction_t;
+
+
+/** Help union used for casting pc register (uint_32_t) value into
+ *  #instruction_t pointer.
+ */
+typedef union {
+	instruction_t *instr;
+	uint32_t pc;
+} instruction_union_t;
+
+extern void prefetch_abort(int n, istate_t *istate);
+extern void data_abort(int n, istate_t *istate);
+
+#endif
+
+/** @}
+ */
Index: kernel/arch/arm32/include/mm/tlb.h
===================================================================
--- kernel/arch/arm32/include/mm/tlb.h	(revision 3ee8a07528aa466b40a362672714a05e936d396e)
+++ kernel/arch/arm32/include/mm/tlb.h	(revision 6b781c0c856d94b3114ccd6375bc6667a19e9bfe)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2005 Jakub Jermar
+ * Copyright (c) 2007 Pavel Jancik
  * All rights reserved.
  *
@@ -31,4 +31,5 @@
  */
 /** @file
+ *  @brief TLB related declarations.
  */
 
Index: kernel/arch/arm32/include/proc/task.h
===================================================================
--- kernel/arch/arm32/include/proc/task.h	(revision 3ee8a07528aa466b40a362672714a05e936d396e)
+++ kernel/arch/arm32/include/proc/task.h	(revision 6b781c0c856d94b3114ccd6375bc6667a19e9bfe)
@@ -31,4 +31,5 @@
  */
 /** @file
+ *  @brief Task related declarations.
  */
 
Index: kernel/arch/arm32/include/proc/thread.h
===================================================================
--- kernel/arch/arm32/include/proc/thread.h	(revision 3ee8a07528aa466b40a362672714a05e936d396e)
+++ kernel/arch/arm32/include/proc/thread.h	(revision 6b781c0c856d94b3114ccd6375bc6667a19e9bfe)
@@ -31,4 +31,5 @@
  */
 /** @file
+ *  @brief Thread related declarations.
  */
 
@@ -47,3 +48,2 @@
 /** @}
  */
-
Index: kernel/arch/arm32/include/regutils.h
===================================================================
--- kernel/arch/arm32/include/regutils.h	(revision 6b781c0c856d94b3114ccd6375bc6667a19e9bfe)
+++ kernel/arch/arm32/include/regutils.h	(revision 6b781c0c856d94b3114ccd6375bc6667a19e9bfe)
@@ -0,0 +1,86 @@
+/*
+ * 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 Utilities for convenient manipulation with ARM registers.
+ */
+
+#ifndef KERN_arm32_REGUTILS_H_
+#define KERN_arm32_REGUTILS_H_
+
+#define STATUS_REG_IRQ_DISABLED_BIT (1 << 7)
+#define STATUS_REG_MODE_MASK        0x1f
+
+#define CP15_R1_HIGH_VECTORS_BIT    (1 << 13)
+
+
+/* ARM Processor Operation Modes */
+#define USER_MODE         0x10
+#define FIQ_MODE          0x11
+#define	IRQ_MODE          0x12
+#define	SUPERVISOR_MODE   0x13
+#define	ABORT_MODE        0x17
+#define	UNDEFINED_MODE    0x1b
+#define	SYSTEM_MODE       0x1f
+
+/* [CS]PRS manipulation macros */
+#define GEN_STATUS_READ(nm,reg) \
+static inline uint32_t nm## _status_reg_read(void) \
+{ \
+	uint32_t retval; \
+	asm volatile("mrs %0, " #reg : "=r" (retval)); \
+	return retval; \
+}
+
+#define GEN_STATUS_WRITE(nm,reg,fieldname, field) \
+static inline void nm## _status_reg_ ##fieldname## _write(uint32_t value) \
+{ \
+	asm volatile("msr " #reg "_" #field ", %0" : : "r" (value)); \
+}
+
+
+/** Returns the value of CPSR (Current Program Status Register). */
+GEN_STATUS_READ(current, cpsr)
+
+
+/** Sets control bits of CPSR. */
+GEN_STATUS_WRITE(current, cpsr, control, c);
+
+
+/** Returns the value of SPSR (Saved Program Status Register). */
+GEN_STATUS_READ(saved, spsr)
+
+
+#endif
+
+/** @}
+ */
Index: kernel/arch/arm32/include/stack.h
===================================================================
--- kernel/arch/arm32/include/stack.h	(revision 6b781c0c856d94b3114ccd6375bc6667a19e9bfe)
+++ kernel/arch/arm32/include/stack.h	(revision 6b781c0c856d94b3114ccd6375bc6667a19e9bfe)
@@ -0,0 +1,49 @@
+/*
+ * 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 Stack constants.
+ */
+
+#ifndef KERN_arm32_STACK_H_
+#define KERN_arm32_STACK_H_
+
+#define STACK_ITEM_SIZE		4
+
+/** See <a href="http://www.arm.com/support/faqdev/14269.html">ABI</a> for
+ * details
+ */
+#define STACK_ALIGNMENT		8
+
+#endif
+
+/** @}
+ */
Index: kernel/arch/arm32/include/types.h
===================================================================
--- kernel/arch/arm32/include/types.h	(revision 3ee8a07528aa466b40a362672714a05e936d396e)
+++ kernel/arch/arm32/include/types.h	(revision 6b781c0c856d94b3114ccd6375bc6667a19e9bfe)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2003-2007 Jakub Jermar
+ * Copyright (c) 2007 Pavel Jancik, Michal Kebrt
  * All rights reserved.
  *
@@ -31,8 +31,15 @@
  */
 /** @file
+ *  @brief Type definitions.
  */
 
 #ifndef KERN_arm32_TYPES_H_
 #define KERN_arm32_TYPES_H_
+
+#ifndef DOXYGEN
+#	define ATTRIBUTE_PACKED __attribute__ ((packed))
+#else
+#	define ATTRIBUTE_PACKED
+#endif
 
 #define NULL 0
@@ -70,7 +77,12 @@
 typedef int32_t devno_t;
 
-/** Page Table Entry. */
+
+/** Page table entry.
+ *
+ *  We have different structs for level 0 and level 1 page table entries.
+ *  See page.h for definition of pte_level*_t.
+ */
 typedef struct {
-	/* placeholder */
+	unsigned dummy : 32;
 } pte_t;
 
Index: kernel/arch/arm32/src/arm32.c
===================================================================
--- kernel/arch/arm32/src/arm32.c	(revision 3ee8a07528aa466b40a362672714a05e936d396e)
+++ kernel/arch/arm32/src/arm32.c	(revision 6b781c0c856d94b3114ccd6375bc6667a19e9bfe)
@@ -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 6b781c0c856d94b3114ccd6375bc6667a19e9bfe)
+++ kernel/arch/arm32/src/asm.S	(revision 6b781c0c856d94b3114ccd6375bc6667a19e9bfe)
@@ -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 6b781c0c856d94b3114ccd6375bc6667a19e9bfe)
+++ kernel/arch/arm32/src/console.c	(revision 6b781c0c856d94b3114ccd6375bc6667a19e9bfe)
@@ -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 3ee8a07528aa466b40a362672714a05e936d396e)
+++ kernel/arch/arm32/src/context.S	(revision 6b781c0c856d94b3114ccd6375bc6667a19e9bfe)
@@ -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 3ee8a07528aa466b40a362672714a05e936d396e)
+++ kernel/arch/arm32/src/cpu/cpu.c	(revision 6b781c0c856d94b3114ccd6375bc6667a19e9bfe)
@@ -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 3ee8a07528aa466b40a362672714a05e936d396e)
+++ kernel/arch/arm32/src/ddi/ddi.c	(revision 6b781c0c856d94b3114ccd6375bc6667a19e9bfe)
@@ -31,4 +31,5 @@
  */
 /** @file
+ *  @brief DDI.
  */
 
Index: kernel/arch/arm32/src/debug/print.c
===================================================================
--- kernel/arch/arm32/src/debug/print.c	(revision 6b781c0c856d94b3114ccd6375bc6667a19e9bfe)
+++ kernel/arch/arm32/src/debug/print.c	(revision 6b781c0c856d94b3114ccd6375bc6667a19e9bfe)
@@ -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 6b781c0c856d94b3114ccd6375bc6667a19e9bfe)
+++ kernel/arch/arm32/src/drivers/gxemul.c	(revision 6b781c0c856d94b3114ccd6375bc6667a19e9bfe)
@@ -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 3ee8a07528aa466b40a362672714a05e936d396e)
+++ kernel/arch/arm32/src/dummy.S	(revision 6b781c0c856d94b3114ccd6375bc6667a19e9bfe)
@@ -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 6b781c0c856d94b3114ccd6375bc6667a19e9bfe)
+++ kernel/arch/arm32/src/exception.c	(revision 6b781c0c856d94b3114ccd6375bc6667a19e9bfe)
@@ -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 6b781c0c856d94b3114ccd6375bc6667a19e9bfe)
+++ kernel/arch/arm32/src/interrupt.c	(revision 6b781c0c856d94b3114ccd6375bc6667a19e9bfe)
@@ -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 3ee8a07528aa466b40a362672714a05e936d396e)
+++ kernel/arch/arm32/src/mm/as.c	(revision 6b781c0c856d94b3114ccd6375bc6667a19e9bfe)
@@ -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 3ee8a07528aa466b40a362672714a05e936d396e)
+++ kernel/arch/arm32/src/mm/frame.c	(revision 6b781c0c856d94b3114ccd6375bc6667a19e9bfe)
@@ -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 6b781c0c856d94b3114ccd6375bc6667a19e9bfe)
+++ kernel/arch/arm32/src/mm/memory_init.c	(revision 6b781c0c856d94b3114ccd6375bc6667a19e9bfe)
@@ -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 3ee8a07528aa466b40a362672714a05e936d396e)
+++ kernel/arch/arm32/src/mm/page.c	(revision 6b781c0c856d94b3114ccd6375bc6667a19e9bfe)
@@ -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 6b781c0c856d94b3114ccd6375bc6667a19e9bfe)
+++ kernel/arch/arm32/src/mm/page_fault.c	(revision 6b781c0c856d94b3114ccd6375bc6667a19e9bfe)
@@ -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 6b781c0c856d94b3114ccd6375bc6667a19e9bfe)
+++ kernel/arch/arm32/src/mm/tlb.c	(revision 6b781c0c856d94b3114ccd6375bc6667a19e9bfe)
@@ -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 6b781c0c856d94b3114ccd6375bc6667a19e9bfe)
+++ kernel/arch/arm32/src/panic.S	(revision 6b781c0c856d94b3114ccd6375bc6667a19e9bfe)
@@ -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 3ee8a07528aa466b40a362672714a05e936d396e)
+++ kernel/arch/arm32/src/start.S	(revision 6b781c0c856d94b3114ccd6375bc6667a19e9bfe)
@@ -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 6b781c0c856d94b3114ccd6375bc6667a19e9bfe)
+++ kernel/arch/arm32/src/userspace.c	(revision 6b781c0c856d94b3114ccd6375bc6667a19e9bfe)
@@ -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)
+		;
+}
+
+/** @}
+ */
Index: kernel/arch/ia32/include/mm/page.h
===================================================================
--- kernel/arch/ia32/include/mm/page.h	(revision 3ee8a07528aa466b40a362672714a05e936d396e)
+++ kernel/arch/ia32/include/mm/page.h	(revision 6b781c0c856d94b3114ccd6375bc6667a19e9bfe)
@@ -61,4 +61,9 @@
 #define PTL2_ENTRIES_ARCH	0
 #define PTL3_ENTRIES_ARCH	1024
+
+#define PTL0_SIZE_ARCH       ONE_FRAME
+#define PTL1_SIZE_ARCH       0
+#define PTL2_SIZE_ARCH       0
+#define PTL3_SIZE_ARCH       ONE_FRAME
 
 #define PTL0_INDEX_ARCH(vaddr)	(((vaddr) >> 22) & 0x3ff)
Index: kernel/arch/ia32xen/include/mm/page.h
===================================================================
--- kernel/arch/ia32xen/include/mm/page.h	(revision 3ee8a07528aa466b40a362672714a05e936d396e)
+++ kernel/arch/ia32xen/include/mm/page.h	(revision 6b781c0c856d94b3114ccd6375bc6667a19e9bfe)
@@ -62,4 +62,9 @@
 #define PTL3_ENTRIES_ARCH	1024
 
+#define PTL0_SIZE_ARCH       ONE_FRAME
+#define PTL1_SIZE_ARCH       0
+#define PTL2_SIZE_ARCH       0
+#define PTL3_SIZE_ARCH       ONE_FRAME
+
 #define PTL0_INDEX_ARCH(vaddr)	(((vaddr) >> 22) & 0x3ff)
 #define PTL1_INDEX_ARCH(vaddr)	0
Index: kernel/arch/mips32/include/mm/page.h
===================================================================
--- kernel/arch/mips32/include/mm/page.h	(revision 3ee8a07528aa466b40a362672714a05e936d396e)
+++ kernel/arch/mips32/include/mm/page.h	(revision 6b781c0c856d94b3114ccd6375bc6667a19e9bfe)
@@ -74,4 +74,9 @@
 #define PTL2_ENTRIES_ARCH	0
 #define PTL3_ENTRIES_ARCH	4096
+
+#define PTL0_SIZE_ARCH       ONE_FRAME
+#define PTL1_SIZE_ARCH       0
+#define PTL2_SIZE_ARCH       0
+#define PTL3_SIZE_ARCH       ONE_FRAME
 
 #define PTL0_INDEX_ARCH(vaddr)  ((vaddr)>>26) 
Index: kernel/arch/ppc32/include/mm/page.h
===================================================================
--- kernel/arch/ppc32/include/mm/page.h	(revision 3ee8a07528aa466b40a362672714a05e936d396e)
+++ kernel/arch/ppc32/include/mm/page.h	(revision 6b781c0c856d94b3114ccd6375bc6667a19e9bfe)
@@ -71,4 +71,9 @@
 #define PTL3_ENTRIES_ARCH	1024
 
+#define PTL0_SIZE_ARCH       ONE_FRAME
+#define PTL1_SIZE_ARCH       0
+#define PTL2_SIZE_ARCH       0
+#define PTL3_SIZE_ARCH       ONE_FRAME
+
 #define PTL0_INDEX_ARCH(vaddr)	(((vaddr) >> 22) & 0x3ff)
 #define PTL1_INDEX_ARCH(vaddr)	0
Index: kernel/arch/ppc64/include/mm/page.h
===================================================================
--- kernel/arch/ppc64/include/mm/page.h	(revision 3ee8a07528aa466b40a362672714a05e936d396e)
+++ kernel/arch/ppc64/include/mm/page.h	(revision 6b781c0c856d94b3114ccd6375bc6667a19e9bfe)
@@ -70,4 +70,9 @@
 #define PTL2_ENTRIES_ARCH	0
 #define PTL3_ENTRIES_ARCH	1024
+
+#define PTL0_SIZE_ARCH		ONE_FRAME
+#define PTL1_SIZE_ARCH		0
+#define PTL2_SIZE_ARCH		0
+#define PTL3_SIZE_ARCH		ONE_FRAME
 
 #define PTL0_INDEX_ARCH(vaddr)	(((vaddr) >> 22) & 0x3ff)
