/*
 * Atomic xchg and cmpxchg operations.
 *
 * This file is subject to the terms and conditions of the GNU General Public
 * License.  See the file "COPYING" in the main directory of this archive
 * for more details.
 *
 * Copyright (C) 2001 - 2005 Tensilica Inc.
 */

#ifndef _XTENSA_CMPXCHG_H
#define _XTENSA_CMPXCHG_H

#ifndef __ASSEMBLY__

#include <linux/bits.h>
#include <linux/stringify.h>

/*
 * cmpxchg
 */

static inline unsigned long
__cmpxchg_u32(volatile int *p, int old, int new)
{
#if XCHAL_HAVE_EXCLUSIVE
	unsigned long tmp, result;

	__asm__ __volatile__(
			"1:     l32ex   %[result], %[addr]\n"
			"       bne     %[result], %[cmp], 2f\n"
			"       mov     %[tmp], %[new]\n"
			"       s32ex   %[tmp], %[addr]\n"
			"       getex   %[tmp]\n"
			"       beqz    %[tmp], 1b\n"
			"2:\n"
			: [result] "=&a" (result), [tmp] "=&a" (tmp)
			: [new] "a" (new), [addr] "a" (p), [cmp] "a" (old)
			: "memory"
			);

	return result;
#elif XCHAL_HAVE_S32C1I
	__asm__ __volatile__(
			"       wsr     %[cmp], scompare1\n"
			"       s32c1i  %[new], %[mem]\n"
			: [new] "+a" (new), [mem] "+m" (*p)
			: [cmp] "a" (old)
			: "memory"
			);

	return new;
#else
	__asm__ __volatile__(
			"       rsil    a14, "__stringify(TOPLEVEL)"\n"
			"       l32i    %[old], %[mem]\n"
			"       bne     %[old], %[cmp], 1f\n"
			"       s32i    %[new], %[mem]\n"
			"1:\n"
			"       wsr     a14, ps\n"
			"       rsync\n"
			: [old] "=&a" (old), [mem] "+m" (*p)
			: [cmp] "a" (old), [new] "r" (new)
			: "a14", "memory");
	return old;
#endif
}
/* 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)
{
	switch (size) {
	case 4:  return __cmpxchg_u32(ptr, old, new);
	default: __cmpxchg_called_with_bad_pointer();
		 return old;
	}
}

#define arch_cmpxchg(ptr,o,n)						      \
	({ __typeof__(*(ptr)) _o_ = (o);				      \
	   __typeof__(*(ptr)) _n_ = (n);				      \
	   (__typeof__(*(ptr))) __cmpxchg((ptr), (unsigned long)_o_,	      \
	   			        (unsigned long)_n_, sizeof (*(ptr))); \
	})

#include <asm-generic/cmpxchg-local.h>

static inline unsigned long __cmpxchg_local(volatile void *ptr,
				      unsigned long old,
				      unsigned long new, int size)
{
	switch (size) {
	case 4:
		return __cmpxchg_u32(ptr, old, new);
	default:
		return __generic_cmpxchg_local(ptr, old, new, size);
	}

	return old;
}

/*
 * cmpxchg_local and cmpxchg64_local are atomic wrt current CPU. Always make
 * them available.
 */
#define arch_cmpxchg_local(ptr, o, n)				  	       \
	((__typeof__(*(ptr)))__generic_cmpxchg_local((ptr), (unsigned long)(o),\
			(unsigned long)(n), sizeof(*(ptr))))
#define arch_cmpxchg64_local(ptr, o, n) __generic_cmpxchg64_local((ptr), (o), (n))
#define arch_cmpxchg64(ptr, o, n)    arch_cmpxchg64_local((ptr), (o), (n))

/*
 * xchg_u32
 *
 * Note that a14 is used here because the register allocation
 * done by the compiler is not guaranteed and a window overflow
 * may not occur between the rsil and wsr instructions. By using
 * a14 in the rsil, the machine is guaranteed to be in a state
 * where no register reference will cause an overflow.
 */

static inline unsigned long xchg_u32(volatile int * m, unsigned long val)
{
#if XCHAL_HAVE_EXCLUSIVE
	unsigned long tmp, result;

	__asm__ __volatile__(
			"1:     l32ex   %[result], %[addr]\n"
			"       mov     %[tmp], %[val]\n"
			"       s32ex   %[tmp], %[addr]\n"
			"       getex   %[tmp]\n"
			"       beqz    %[tmp], 1b\n"
			: [result] "=&a" (result), [tmp] "=&a" (tmp)
			: [val] "a" (val), [addr] "a" (m)
			: "memory"
			);

	return result;
#elif XCHAL_HAVE_S32C1I
	unsigned long tmp, result;
	__asm__ __volatile__(
			"1:     l32i    %[tmp], %[mem]\n"
			"       mov     %[result], %[val]\n"
			"       wsr     %[tmp], scompare1\n"
			"       s32c1i  %[result], %[mem]\n"
			"       bne     %[result], %[tmp], 1b\n"
			: [result] "=&a" (result), [tmp] "=&a" (tmp),
			  [mem] "+m" (*m)
			: [val] "a" (val)
			: "memory"
			);
	return result;
#else
	unsigned long tmp;
	__asm__ __volatile__(
			"       rsil    a14, "__stringify(TOPLEVEL)"\n"
			"       l32i    %[tmp], %[mem]\n"
			"       s32i    %[val], %[mem]\n"
			"       wsr     a14, ps\n"
			"       rsync\n"
			: [tmp] "=&a" (tmp), [mem] "+m" (*m)
			: [val] "a" (val)
			: "a14", "memory");
	return tmp;
#endif
}

#define arch_xchg(ptr,x) \
	((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr))))

static inline u32 xchg_small(volatile void *ptr, u32 x, int size)
{
	int off = (unsigned long)ptr % sizeof(u32);
	volatile u32 *p = ptr - off;
#ifdef __BIG_ENDIAN
	int bitoff = (sizeof(u32) - size - off) * BITS_PER_BYTE;
#else
	int bitoff = off * BITS_PER_BYTE;
#endif
	u32 bitmask = ((0x1 << size * BITS_PER_BYTE) - 1) << bitoff;
	u32 oldv, newv;
	u32 ret;

	do {
		oldv = READ_ONCE(*p);
		ret = (oldv & bitmask) >> bitoff;
		newv = (oldv & ~bitmask) | (x << bitoff);
	} while (__cmpxchg_u32(p, oldv, newv) != oldv);

	return ret;
}

/*
 * This only works if the compiler isn't horribly bad at optimizing.
 * gcc-2.5.8 reportedly can't handle this, but I define that one to
 * be dead anyway.
 */

extern void __xchg_called_with_bad_pointer(void);

static __inline__ unsigned long
__xchg(unsigned long x, volatile void * ptr, int size)
{
	switch (size) {
	case 1:
		return xchg_small(ptr, x, 1);
	case 2:
		return xchg_small(ptr, x, 2);
	case 4:
		return xchg_u32(ptr, x);
	default:
		__xchg_called_with_bad_pointer();
		return x;
	}
}

#endif /* __ASSEMBLY__ */

#endif /* _XTENSA_CMPXCHG_H */
