Index: kernel/arch/arm32/Makefile.inc
===================================================================
--- kernel/arch/arm32/Makefile.inc	(revision 45d5f8656e9fa5b05cfa12b7c37b0e1e72f29700)
+++ kernel/arch/arm32/Makefile.inc	(revision 216cb85316fa347aa65efa528359fb202c2fdd80)
@@ -61,5 +61,6 @@
 	arch/$(KARCH)/src/mm/page.c \
 	arch/$(KARCH)/src/mm/tlb.c \
-	arch/$(KARCH)/src/mm/page_fault.c
+	arch/$(KARCH)/src/mm/page_fault.c \
+	arch/$(KARCH)/src/ras.c
 
 ifeq ($(MACHINE),testarm)
Index: kernel/arch/arm32/include/ras.h
===================================================================
--- kernel/arch/arm32/include/ras.h	(revision 216cb85316fa347aa65efa528359fb202c2fdd80)
+++ kernel/arch/arm32/include/ras.h	(revision 216cb85316fa347aa65efa528359fb202c2fdd80)
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2009 Jakub Jermar 
+ * 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 related to Restartable Atomic Sequences.
+ */
+
+#ifndef KERN_arm32_RAS_H_
+#define KERN_arm32_RAS_H_
+
+#include <arch/exception.h>
+#include <arch/types.h>
+
+#define RAS_START	0
+#define RAS_END		1
+
+extern uintptr_t *ras_page;
+
+extern void ras_init(void);
+extern void ras_check(int, istate_t *);
+
+#endif
+
+/** @}
+ */
Index: kernel/arch/arm32/src/arm32.c
===================================================================
--- kernel/arch/arm32/src/arm32.c	(revision 45d5f8656e9fa5b05cfa12b7c37b0e1e72f29700)
+++ kernel/arch/arm32/src/arm32.c	(revision 216cb85316fa347aa65efa528359fb202c2fdd80)
@@ -48,4 +48,5 @@
 #include <macros.h>
 #include <string.h>
+#include <arch/ras.h>
 
 #ifdef MACHINE_testarm
@@ -88,4 +89,7 @@
 	exception_init();
 	interrupt_init();
+
+	/* Initialize Restartable Atomic Sequences support. */
+	ras_init();
 	
 	machine_output_init();
Index: kernel/arch/arm32/src/exc_handler.S
===================================================================
--- kernel/arch/arm32/src/exc_handler.S	(revision 45d5f8656e9fa5b05cfa12b7c37b0e1e72f29700)
+++ kernel/arch/arm32/src/exc_handler.S	(revision 216cb85316fa347aa65efa528359fb202c2fdd80)
@@ -148,5 +148,5 @@
 	mov r0, #0
 	mov r1, r13
-	bl exc_dispatch
+	bl ras_check 
 	LOAD_REGS_FROM_STACK
 
@@ -156,5 +156,5 @@
 	mov r0, #5
 	mov r1, r13
-	bl exc_dispatch
+	bl ras_check 
 	LOAD_REGS_FROM_STACK
 
@@ -164,5 +164,5 @@
 	mov r0, #6
 	mov r1, r13
-	bl exc_dispatch
+	bl ras_check 
 	LOAD_REGS_FROM_STACK
 
@@ -171,5 +171,5 @@
 	mov r0, #1
 	mov r1, r13
-	bl exc_dispatch
+	bl ras_check 
 	LOAD_REGS_FROM_STACK
 
@@ -179,5 +179,5 @@
 	mov r0, #3
 	mov r1, r13
-	bl exc_dispatch
+	bl ras_check 
 	LOAD_REGS_FROM_STACK
 
@@ -187,5 +187,5 @@
 	mov r0, #4
 	mov r1, r13
-	bl exc_dispatch
+	bl ras_check 
 	LOAD_REGS_FROM_STACK
 
@@ -195,5 +195,5 @@
 	mov r0, #2
 	mov r1, r13
-	bl exc_dispatch
+	bl ras_check
 	LOAD_REGS_FROM_STACK
 
Index: kernel/arch/arm32/src/ras.c
===================================================================
--- kernel/arch/arm32/src/ras.c	(revision 216cb85316fa347aa65efa528359fb202c2fdd80)
+++ kernel/arch/arm32/src/ras.c	(revision 216cb85316fa347aa65efa528359fb202c2fdd80)
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2009 Jakub Jermar 
+ * 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 Kernel part of Restartable Atomic Sequences support.
+ */
+
+#include <arch/ras.h>
+#include <mm/mm.h>
+#include <mm/frame.h>
+#include <mm/page.h>
+#include <mm/tlb.h>
+#include <mm/asid.h>
+#include <interrupt.h>
+#include <arch/exception.h>
+#include <arch.h>
+#include <memstr.h>
+#include <arch/types.h>
+
+uintptr_t *ras_page = NULL;
+
+void ras_init(void)
+{
+	ras_page = frame_alloc(ONE_FRAME, FRAME_KA);
+	memsetb(ras_page, FRAME_SIZE, 0); 
+	ras_page[RAS_START] = 0;
+	ras_page[RAS_END] = 0xffffffff;
+	/*
+	 * Userspace needs to be able to write to this page. The page is 
+	 * cached in TLB as PAGE_KERNEL. Purge it from TLB and map it
+	 * read/write PAGE_USER.
+	 */
+	tlb_invalidate_pages(ASID_KERNEL, (uintptr_t)ras_page, 1);
+	page_table_lock(AS, true);
+	page_mapping_insert(AS, (uintptr_t)ras_page, (uintptr_t)KA2PA(ras_page),
+	    PAGE_READ | PAGE_WRITE | PAGE_USER);
+	page_table_unlock(AS, true);
+}
+
+void ras_check(int n, istate_t *istate)
+{
+	uintptr_t rewrite_pc = istate->pc;
+
+	if (istate_from_uspace(istate)) {
+		if (ras_page[RAS_START]) {
+			if ((ras_page[RAS_START] < istate->pc) &&
+			    (ras_page[RAS_END] > istate->pc)) {
+				rewrite_pc = ras_page[RAS_START];
+			}
+			ras_page[RAS_START] = 0;
+			ras_page[RAS_END] = 0xffffffff;
+		}	
+	}
+
+	exc_dispatch(n, istate);
+
+	istate->pc = rewrite_pc;
+}
+
Index: kernel/arch/arm32/src/userspace.c
===================================================================
--- kernel/arch/arm32/src/userspace.c	(revision 45d5f8656e9fa5b05cfa12b7c37b0e1e72f29700)
+++ kernel/arch/arm32/src/userspace.c	(revision 216cb85316fa347aa65efa528359fb202c2fdd80)
@@ -35,4 +35,5 @@
 
 #include <userspace.h>
+#include <arch/ras.h>
 
 /** Struct for holding all general purpose registers.
@@ -74,8 +75,11 @@
 	ustate.r1 = 0;
 
+	/* pass the RAS page address in %r2 */
+	ustate.r2 = (uintptr_t) ras_page;
+
 	/* clear other registers */
-	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;
+	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 */
Index: uspace/lib/libc/arch/arm32/include/atomic.h
===================================================================
--- uspace/lib/libc/arch/arm32/include/atomic.h	(revision 45d5f8656e9fa5b05cfa12b7c37b0e1e72f29700)
+++ uspace/lib/libc/arch/arm32/include/atomic.h	(revision 216cb85316fa347aa65efa528359fb202c2fdd80)
@@ -37,28 +37,48 @@
 #define LIBC_arm32_ATOMIC_H_
 
+#define LIBC_ARCH_ATOMIC_H_
+#define CAS 
+
+#include <atomicdflt.h>
 #include <bool.h>
+#include <sys/types.h>
 
-typedef struct atomic {
-	volatile long count;
-} atomic_t;
-
-static inline void atomic_set(atomic_t *val, long i)
-{
-        val->count = i;
-}
-
-static inline long atomic_get(atomic_t *val)
-{
-        return val->count;
-}
+extern uintptr_t *ras_page;
 
 static inline bool cas(atomic_t *val, long ov, long nv)
 {
-	/* FIXME: is not atomic */
-	if (val->count == ov) {
-		val->count = nv;
-		return true;
-	}
-	return false;
+	long ret = 0;
+
+	/*
+	 * The following instructions between labels 1 and 2 constitute a
+	 * Restartable Atomic Seqeunce. Should the sequence be non-atomic,
+	 * the kernel will restart it.
+	 */
+	asm volatile (
+		"1:\n"
+		"	adr %[ret], 1b\n"
+		"	str %[ret], %[rp0]\n"
+		"	adr %[ret], 2f\n"
+		"	str %[ret], %[rp1]\n"
+		"	ldr %[ret], %[addr]\n"
+		"	cmp %[ret], %[ov]\n"
+		"	streq %[nv], %[addr]\n"
+		"2:\n"
+		"	moveq %[ret], #1\n"
+		"	movne %[ret], #0\n"
+		: [ret] "+&r" (ret),
+		  [rp0] "=m" (ras_page[0]),
+		  [rp1] "=m" (ras_page[1]),
+		  [addr] "+m" (val->count)
+		: [ov] "r" (ov),
+		  [nv] "r" (nv)
+		: "memory"
+	);
+
+	ras_page[0] = 0;
+	asm volatile ("" ::: "memory");	
+	ras_page[1] = 0xffffffff;
+
+	return (bool) ret;
 }
 
@@ -72,21 +92,31 @@
 static inline long atomic_add(atomic_t *val, int i)
 {
-	int ret;
-	volatile long * mem = &(val->count);
+	long ret = 0;
 
-	/* FIXME: is not atomic, is broken */
+	/*
+	 * The following instructions between labels 1 and 2 constitute a
+	 * Restartable Atomic Seqeunce. Should the sequence be non-atomic,
+	 * the kernel will restart it.
+	 */
 	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"
+		"1:\n"
+		"	adr %[ret], 1b\n"
+		"	str %[ret], %[rp0]\n"
+		"	adr %[ret], 2f\n"
+		"	str %[ret], %[rp1]\n"
+		"	ldr %[ret], %[addr]\n"
+		"	add %[ret], %[ret], %[imm]\n"
+		"	str %[ret], %[addr]\n"
+		"2:\n"
+		: [ret] "+&r" (ret),
+		  [rp0] "=m" (ras_page[0]),
+		  [rp1] "=m" (ras_page[1]),
+		  [addr] "+m" (val->count)
+		: [imm] "r" (i)
+	);
 
-		: "=m" (ret)
-		: "r" (mem), "r" (i)
-		: "r3", "r2"
-	);
+	ras_page[0] = 0;
+	asm volatile ("" ::: "memory");	
+	ras_page[1] = 0xffffffff;
 
 	return ret;
Index: uspace/lib/libc/arch/arm32/src/entry.s
===================================================================
--- uspace/lib/libc/arch/arm32/src/entry.s	(revision 45d5f8656e9fa5b05cfa12b7c37b0e1e72f29700)
+++ uspace/lib/libc/arch/arm32/src/entry.s	(revision 216cb85316fa347aa65efa528359fb202c2fdd80)
@@ -36,6 +36,11 @@
 #
 # r1 contains the PCB pointer
+# r2 contains the RAS page address
 #
 __entry:
+	# Store the RAS page address into the ras_page variable
+	ldr r0, =ras_page
+	str r2, [r0]
+
 	# Pass pcb_ptr to __main as the first argument (in r0)
 	mov r0, r1
@@ -43,2 +48,9 @@
 
 	bl __exit
+
+.data
+
+.global ras_page
+ras_page:
+	.long 0
+
Index: uspace/lib/libc/include/atomicdflt.h
===================================================================
--- uspace/lib/libc/include/atomicdflt.h	(revision 45d5f8656e9fa5b05cfa12b7c37b0e1e72f29700)
+++ uspace/lib/libc/include/atomicdflt.h	(revision 216cb85316fa347aa65efa528359fb202c2fdd80)
@@ -56,8 +56,10 @@
 }
 
+#ifndef CAS 
 static inline bool cas(atomic_t *val, long ov, long nv)
 {
 	return __sync_bool_compare_and_swap(&val->count, ov, nv);
 }
+#endif
 
 #endif
Index: uspace/srv/loader/arch/arm32/arm32.s
===================================================================
--- uspace/srv/loader/arch/arm32/arm32.s	(revision 45d5f8656e9fa5b05cfa12b7c37b0e1e72f29700)
+++ uspace/srv/loader/arch/arm32/arm32.s	(revision 216cb85316fa347aa65efa528359fb202c2fdd80)
@@ -36,4 +36,7 @@
 # Jump to a program entry point
 program_run:
+	# load ras_page address to r2
+	ldr r2, =ras_page
+	ldr r2, [r2]
 	# pcb is passed to the entry point in r1 (where it already is)
 	mov r15, r0
