atomic: add cmpxchg_local to ppc

Gunnar Larisch <[email protected]> Tue, 24 Jul 2007 11:11:57 +0200
Newsgroups gmane.linux.kernel.tracing
Message-ID <[email protected]>
Hello Mathieu,

attached is a patch which adds support for cmpxchg_local on "old" ppc.
I tested the great LTTng (V0.9.10) on an ocotea board, which is only
supported in ppc architecture.

Best Regards,
Gunnar Larisch
-- 
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: +49-8142-66989-0 Fax: +49-8142-66989-80  Email: [email protected]

_______________________________________________
Ltt-dev mailing list
[email protected]
http://listserv.shafik.org/mailman/listinfo/ltt-dev
atomic_cmpxchg_in_ppc.patch.patch (text/x-diff, 2.4 KB)
atomic: add cmpxchg_local to ppc

Add a local processor version of cmpxchg for ppc

Signed-off-by: Gunnar Larisch <[email protected]>
---

 include/asm-ppc/system.h |   48 +++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 47 insertions(+), 1 deletions(-)

diff --git a/include/asm-ppc/system.h b/include/asm-ppc/system.h
index d84a3cf..16c4331 100644
--- a/include/asm-ppc/system.h
+++ b/include/asm-ppc/system.h
@@ -217,12 +217,34 @@ __cmpxchg_u32(volatile unsigned int *p, unsigned int old, unsigned int new)
 	return prev;
 }
 
+static __inline__ unsigned long
+__cmpxchg_u32_local(volatile unsigned int *p, unsigned int old,
+	unsigned int new)
+{
+	unsigned int prev;
+
+	__asm__ __volatile__ ("\n\
+1:	lwarx	%0,0,%2 \n\
+	cmpw	0,%0,%3 \n\
+	bne	2f \n"
+	PPC405_ERR77(0,%2)
+"	stwcx.	%4,0,%2 \n\
+	bne-	1b\n"
+"2:"
+	: "=&r" (prev), "=m" (*p)
+	: "r" (p), "r" (old), "r" (new), "m" (*p)
+	: "cc", "memory");
+
+	return prev;
+}
+
 /* This function doesn't exist, so you'll get a linker error
    if something tries to do an invalid cmpxchg().  */
 extern void __cmpxchg_called_with_bad_pointer(void);
 
 static __inline__ unsigned long
-__cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, int size)
+__cmpxchg(volatile void *ptr, unsigned long old, unsigned long new,
+	  unsigned int size)
 {
 	switch (size) {
 	case 4:
@@ -236,6 +258,22 @@ __cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, int size)
 	return old;
 }
 
+static __inline__ unsigned long
+__cmpxchg_local(volatile void *ptr, unsigned long old, unsigned long new,
+	  unsigned int size)
+{
+	switch (size) {
+	case 4:
+		return __cmpxchg_u32_local(ptr, old, new);
+#if 0	/* we don't have __cmpxchg_u64_local on 32-bit PPC */
+	case 8:
+		return __cmpxchg_u64_local(ptr, old, new);
+#endif
+	}
+	__cmpxchg_called_with_bad_pointer();
+	return old;
+}
+
 #define cmpxchg(ptr,o,n)						 \
   ({									 \
      __typeof__(*(ptr)) _o_ = (o);					 \
@@ -244,6 +282,14 @@ __cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, int size)
 				    (unsigned long)_n_, sizeof(*(ptr))); \
   })
 
+#define cmpxchg_local(ptr,o,n)						 \
+  ({									 \
+     __typeof__(*(ptr)) _o_ = (o);					 \
+     __typeof__(*(ptr)) _n_ = (n);					 \
+     (__typeof__(*(ptr))) __cmpxchg_local((ptr), (unsigned long)_o_,	 \
+				    (unsigned long)_n_, sizeof(*(ptr))); \
+  })
+
 #define arch_align_stack(x) (x)
 
 #endif /* __KERNEL__ */