base/include/asm-ppc/rtai_atomic.h

Go to the documentation of this file.
00001 /* 00002 * Copyright (C) 2003 Philippe Gerum <rpm@xenomai.org>. 00003 * 00004 * This program is free software; you can redistribute it and/or 00005 * modify it under the terms of the GNU General Public License as 00006 * published by the Free Software Foundation; either version 2 of the 00007 * License, or (at your option) any later version. 00008 * 00009 * This program is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 * GNU General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU General Public License 00015 * along with this program; if not, write to the Free Software 00016 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 00017 */ 00018 00019 #ifndef _RTAI_ASM_PPC_ATOMIC_H 00020 #define _RTAI_ASM_PPC_ATOMIC_H 00021 00022 #include <asm/atomic.h> 00023 00024 #ifdef __KERNEL__ 00025 00026 #include <linux/bitops.h> 00027 #include <asm/system.h> 00028 00029 #define atomic_xchg(ptr,v) xchg(ptr,v) 00030 #define atomic_cmpxchg(ptr,o,n) cmpxchg(ptr,o,n) 00031 00032 #else /* !__KERNEL__ */ 00033 00034 // shamelessly taken from Linux as they are 00035 00036 #ifdef CONFIG_SMP 00037 #define SMP_SYNC "sync" 00038 #define SMP_ISYNC "\n\tisync" 00039 #else 00040 #define SMP_SYNC "" 00041 #define SMP_ISYNC 00042 #endif 00043 00044 /* Erratum #77 on the 405 means we need a sync or dcbt before every stwcx. 00045 * The old ATOMIC_SYNC_FIX covered some but not all of this. 00046 */ 00047 #ifdef CONFIG_IBM405_ERR77 00048 #define PPC405_ERR77(ra,rb) "dcbt " #ra "," #rb ";" 00049 #else 00050 #define PPC405_ERR77(ra,rb) 00051 #endif 00052 00053 static __inline__ void atomic_inc(atomic_t *v) 00054 { 00055 int t; 00056 00057 __asm__ __volatile__( 00058 "1: lwarx %0,0,%2 # atomic_inc\n\ 00059 addic %0,%0,1\n" 00060 PPC405_ERR77(0,%2) 00061 " stwcx. %0,0,%2 \n\ 00062 bne- 1b" 00063 : "=&r" (t), "=m" (v->counter) 00064 : "r" (&v->counter), "m" (v->counter) 00065 : "cc"); 00066 } 00067 00068 static __inline__ int atomic_dec_return(atomic_t *v) 00069 { 00070 int t; 00071 00072 __asm__ __volatile__( 00073 "1: lwarx %0,0,%1 # atomic_dec_return\n\ 00074 addic %0,%0,-1\n" 00075 PPC405_ERR77(0,%1) 00076 " stwcx. %0,0,%1\n\ 00077 bne- 1b" 00078 SMP_ISYNC 00079 : "=&r" (t) 00080 : "r" (&v->counter) 00081 : "cc", "memory"); 00082 00083 return t; 00084 } 00085 00086 #define atomic_dec_and_test(v) (atomic_dec_return((v)) == 0) 00087 00088 #define __HAVE_ARCH_CMPXCHG 1 00089 00090 static __inline__ unsigned long 00091 __cmpxchg_u32(volatile int *p, int old, int new) 00092 { 00093 int prev; 00094 00095 __asm__ __volatile__ ("\n\ 00096 1: lwarx %0,0,%2 \n\ 00097 cmpw 0,%0,%3 \n\ 00098 bne 2f \n" 00099 PPC405_ERR77(0,%2) 00100 " stwcx. %4,0,%2 \n\ 00101 bne- 1b\n" 00102 #ifdef CONFIG_SMP 00103 " sync\n" 00104 #endif /* CONFIG_SMP */ 00105 "2:" 00106 : "=&r" (prev), "=m" (*p) 00107 : "r" (p), "r" (old), "r" (new), "m" (*p) 00108 : "cc", "memory"); 00109 00110 return prev; 00111 } 00112 00113 static __inline__ unsigned long 00114 __cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, int size) 00115 { 00116 switch (size) { 00117 case 4: 00118 return __cmpxchg_u32(ptr, old, new); 00119 #if 0 /* we don't have __cmpxchg_u64 on 32-bit PPC */ 00120 case 8: 00121 return __cmpxchg_u64(ptr, old, new); 00122 #endif /* 0 */ 00123 } 00124 return old; 00125 } 00126 00127 #define cmpxchg(ptr,o,n) \ 00128 ({ \ 00129 __typeof__(*(ptr)) _o_ = (o); \ 00130 __typeof__(*(ptr)) _n_ = (n); \ 00131 (__typeof__(*(ptr))) __cmpxchg((ptr), (unsigned long)_o_, \ 00132 (unsigned long)_n_, sizeof(*(ptr))); \ 00133 }) 00134 00135 #define atomic_cmpxchg(ptr,o,n) cmpxchg(ptr,o,n) 00136 00137 #endif /* __KERNEL__ */ 00138 00139 #endif /* !_RTAI_ASM_PPC_ATOMIC_H */

Generated on Thu Nov 20 11:49:48 2008 for RTAI API by doxygen 1.3.8