base/include/asm-arm/rtai_atomic.h

Go to the documentation of this file.
00001 /*
00002  * Atomic operations.
00003  *
00004  * Original RTAI/x86 layer implementation:
00005  *   Copyright (c) 2000 Paolo Mantegazza (mantegazza@aero.polimi.it)
00006  *   Copyright (c) 2000 Steve Papacharalambous (stevep@zentropix.com)
00007  *   Copyright (c) 2000 Stuart Hughes
00008  *   and others.
00009  *
00010  * RTAI/x86 rewrite over Adeos:
00011  *   Copyright (c) 2002 Philippe Gerum (rpm@xenomai.org)
00012  *
00013  * Original RTAI/ARM RTHAL implementation:
00014  *   Copyright (c) 2000 Pierre Cloutier (pcloutier@poseidoncontrols.com)
00015  *   Copyright (c) 2001 Alex Züpke, SYSGO RTS GmbH (azu@sysgo.de)
00016  *   Copyright (c) 2002 Guennadi Liakhovetski DSA GmbH (gl@dsa-ac.de)
00017  *   Copyright (c) 2002 Steve Papacharalambous (stevep@zentropix.com)
00018  *   Copyright (c) 2002 Wolfgang Müller (wolfgang.mueller@dsa-ac.de)
00019  *   Copyright (c) 2003 Bernard Haible, Marconi Communications
00020  *   Copyright (c) 2003 Thomas Gleixner (tglx@linutronix.de)
00021  *   Copyright (c) 2003 Philippe Gerum (rpm@xenomai.org)
00022  *
00023  * RTAI/ARM over Adeos rewrite:
00024  *   Copyright (c) 2004-2005 Michael Neuhauser, Firmix Software GmbH (mike@firmix.at)
00025  *
00026  *  RTAI/ARM over Adeos rewrite for PXA255_2.6.7:
00027  *   Copyright (c) 2005 Stefano Gafforelli (stefano.gafforelli@tiscali.it)
00028  *   Copyright (c) 2005 Luca Pizzi (lucapizzi@hotmail.com)
00029  *
00030  * This program is free software; you can redistribute it and/or modify it under
00031  * the terms of the GNU General Public License as published by the Free Software
00032  * Foundation, Inc., 675 Mass Ave, Cambridge MA 02139, USA; either version 2 of
00033  * the License, or (at your option) any later version.
00034  *
00035  * This program is distributed in the hope that it will be useful, but WITHOUT
00036  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00037  * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
00038  * details.
00039  *
00040  * You should have received a copy of the GNU General Public License along with
00041  * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
00042  * Place - Suite 330, Boston, MA 02111-1307, USA.
00043  */
00044 #ifndef _RTAI_ASM_ARM_ATOMIC_H
00045 #define _RTAI_ASM_ARM_ATOMIC_H
00046 
00047 #include <asm/atomic.h>
00048 
00049 #ifdef __KERNEL__
00050 
00051 #include <linux/bitops.h>
00052 #include <asm/system.h>
00053 
00054 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,11)
00055 
00056 #define atomic_xchg(ptr,v)      xchg(ptr,v)
00057 
00058 /* Poor man's cmpxchg(). */
00059 #define atomic_cmpxchg(p, o, n) ({  \
00060     typeof(*(p)) __o = (o);     \
00061     typeof(*(p)) __n = (n);     \
00062     typeof(*(p)) __prev;        \
00063     unsigned long flags;        \
00064     rtai_hw_lock(flags);        \
00065     __prev = *(p);          \
00066     if (__prev == __o)      \
00067         *(p) = __n;     \
00068     rtai_hw_unlock(flags);      \
00069     __prev; })
00070 
00071 #endif /* version < 2.6.11 */
00072 
00073 #else /* !__KERNEL__ */
00074 
00075 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
00076 #include <asm/proc/system.h>
00077 #else
00078 #include <asm/system.h>
00079 #endif
00080 
00081 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
00082 typedef struct { volatile int counter; } atomic_t;
00083 #endif
00084 
00085 static inline unsigned long
00086 atomic_xchg(volatile void *ptr, unsigned long x)
00087 {
00088     asm volatile(
00089     "swp %0, %1, [%2]"
00090     : "=&r" (x)
00091     : "r" (x), "r" (ptr)
00092     : "memory"
00093     );
00094     return x;
00095 }
00096 
00097 static inline unsigned long atomic_cmpxchg(volatile void *ptr, unsigned long old, unsigned long new)
00098 {
00099     unsigned long oldval, res;
00100 
00101     do {
00102         __asm__ __volatile__("@ atomic_cmpxchg\n"
00103         "ldrex  %1, [%2]\n"
00104         "teq    %1, %3\n"
00105         "strexeq %0, %4, [%2]\n"
00106             : "=&r" (res), "=&r" (oldval)
00107             : "r" (*(unsigned long*)ptr), "r" (old), "r" (new)
00108             : "cc");
00109     } while (res);
00110 
00111     return oldval;
00112 }
00113 
00114 /*
00115 static inline unsigned long
00116 atomic_cmpxchg(volatile void *ptr, unsigned long o, unsigned long n)
00117 {
00118     unsigned long prev;
00119     unsigned long flags;
00120     hal_hw_local_irq_save(flags);
00121     prev = *(unsigned long*)ptr;
00122     if (prev == o)
00123     *(unsigned long*)ptr = n;
00124     hal_hw_local_irq_restore(flags);
00125     return prev;
00126 }
00127 */
00128 
00129 static inline int atomic_add_return(int i, atomic_t *v)
00130 {
00131     unsigned long tmp;
00132     int result;
00133 
00134     __asm__ __volatile__("@ atomic_add_return\n"
00135 "1: ldrex   %0, [%2]\n"
00136 "   add %0, %0, %3\n"
00137 "   strex   %1, %0, [%2]\n"
00138 "   teq %1, #0\n"
00139 "   bne 1b"
00140     : "=&r" (result), "=&r" (tmp)
00141     : "r" (&v->counter), "Ir" (i)
00142     : "cc");
00143 
00144     return result;
00145 }
00146 
00147 static inline int atomic_sub_return(int i, atomic_t *v)
00148 {
00149     unsigned long tmp;
00150     int result;
00151 
00152     __asm__ __volatile__("@ atomic_sub_return\n"
00153 "1: ldrex   %0, [%2]\n"
00154 "   sub %0, %0, %3\n"
00155 "   strex   %1, %0, [%2]\n"
00156 "   teq %1, #0\n"
00157 "   bne 1b"
00158     : "=&r" (result), "=&r" (tmp)
00159     : "r" (&v->counter), "Ir" (i)
00160     : "cc");
00161 
00162     return result;
00163 }
00164 
00165 #define atomic_inc(v)       (void) atomic_add_return(1, v)
00166 #define atomic_dec_and_test(v)  (atomic_sub_return(1, v) == 0)
00167 
00168 #endif /* __KERNEL__ */
00169 #endif /* !_RTAI_ASM_ARM_ATOMIC_H */

Generated on Tue Feb 2 17:46:04 2010 for RTAI API by  doxygen 1.4.7