cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

atomic.h (3609B)


      1/*
      2 * Copyright (C) 2014 Stefan Kristiansson <stefan.kristiansson@saunalahti.fi>
      3 *
      4 * This file is licensed under the terms of the GNU General Public License
      5 * version 2.  This program is licensed "as is" without any warranty of any
      6 * kind, whether express or implied.
      7 */
      8
      9#ifndef __ASM_OPENRISC_ATOMIC_H
     10#define __ASM_OPENRISC_ATOMIC_H
     11
     12#include <linux/types.h>
     13
     14/* Atomically perform op with v->counter and i */
     15#define ATOMIC_OP(op)							\
     16static inline void arch_atomic_##op(int i, atomic_t *v)			\
     17{									\
     18	int tmp;							\
     19									\
     20	__asm__ __volatile__(						\
     21		"1:	l.lwa	%0,0(%1)	\n"			\
     22		"	l." #op " %0,%0,%2	\n"			\
     23		"	l.swa	0(%1),%0	\n"			\
     24		"	l.bnf	1b		\n"			\
     25		"	 l.nop			\n"			\
     26		: "=&r"(tmp)						\
     27		: "r"(&v->counter), "r"(i)				\
     28		: "cc", "memory");					\
     29}
     30
     31/* Atomically perform op with v->counter and i, return the result */
     32#define ATOMIC_OP_RETURN(op)						\
     33static inline int arch_atomic_##op##_return(int i, atomic_t *v)		\
     34{									\
     35	int tmp;							\
     36									\
     37	__asm__ __volatile__(						\
     38		"1:	l.lwa	%0,0(%1)	\n"			\
     39		"	l." #op " %0,%0,%2	\n"			\
     40		"	l.swa	0(%1),%0	\n"			\
     41		"	l.bnf	1b		\n"			\
     42		"	 l.nop			\n"			\
     43		: "=&r"(tmp)						\
     44		: "r"(&v->counter), "r"(i)				\
     45		: "cc", "memory");					\
     46									\
     47	return tmp;							\
     48}
     49
     50/* Atomically perform op with v->counter and i, return orig v->counter */
     51#define ATOMIC_FETCH_OP(op)						\
     52static inline int arch_atomic_fetch_##op(int i, atomic_t *v)		\
     53{									\
     54	int tmp, old;							\
     55									\
     56	__asm__ __volatile__(						\
     57		"1:	l.lwa	%0,0(%2)	\n"			\
     58		"	l." #op " %1,%0,%3	\n"			\
     59		"	l.swa	0(%2),%1	\n"			\
     60		"	l.bnf	1b		\n"			\
     61		"	 l.nop			\n"			\
     62		: "=&r"(old), "=&r"(tmp)				\
     63		: "r"(&v->counter), "r"(i)				\
     64		: "cc", "memory");					\
     65									\
     66	return old;							\
     67}
     68
     69ATOMIC_OP_RETURN(add)
     70ATOMIC_OP_RETURN(sub)
     71
     72ATOMIC_FETCH_OP(add)
     73ATOMIC_FETCH_OP(sub)
     74ATOMIC_FETCH_OP(and)
     75ATOMIC_FETCH_OP(or)
     76ATOMIC_FETCH_OP(xor)
     77
     78ATOMIC_OP(add)
     79ATOMIC_OP(sub)
     80ATOMIC_OP(and)
     81ATOMIC_OP(or)
     82ATOMIC_OP(xor)
     83
     84#undef ATOMIC_FETCH_OP
     85#undef ATOMIC_OP_RETURN
     86#undef ATOMIC_OP
     87
     88#define arch_atomic_add_return	arch_atomic_add_return
     89#define arch_atomic_sub_return	arch_atomic_sub_return
     90#define arch_atomic_fetch_add	arch_atomic_fetch_add
     91#define arch_atomic_fetch_sub	arch_atomic_fetch_sub
     92#define arch_atomic_fetch_and	arch_atomic_fetch_and
     93#define arch_atomic_fetch_or	arch_atomic_fetch_or
     94#define arch_atomic_fetch_xor	arch_atomic_fetch_xor
     95#define arch_atomic_add		arch_atomic_add
     96#define arch_atomic_sub		arch_atomic_sub
     97#define arch_atomic_and		arch_atomic_and
     98#define arch_atomic_or		arch_atomic_or
     99#define arch_atomic_xor		arch_atomic_xor
    100
    101/*
    102 * Atomically add a to v->counter as long as v is not already u.
    103 * Returns the original value at v->counter.
    104 *
    105 * This is often used through atomic_inc_not_zero()
    106 */
    107static inline int arch_atomic_fetch_add_unless(atomic_t *v, int a, int u)
    108{
    109	int old, tmp;
    110
    111	__asm__ __volatile__(
    112		"1:	l.lwa %0, 0(%2)		\n"
    113		"	l.sfeq %0, %4		\n"
    114		"	l.bf 2f			\n"
    115		"	 l.add %1, %0, %3	\n"
    116		"	l.swa 0(%2), %1		\n"
    117		"	l.bnf 1b		\n"
    118		"	 l.nop			\n"
    119		"2:				\n"
    120		: "=&r"(old), "=&r" (tmp)
    121		: "r"(&v->counter), "r"(a), "r"(u)
    122		: "cc", "memory");
    123
    124	return old;
    125}
    126#define arch_atomic_fetch_add_unless	arch_atomic_fetch_add_unless
    127
    128#define arch_atomic_read(v)		READ_ONCE((v)->counter)
    129#define arch_atomic_set(v,i)		WRITE_ONCE((v)->counter, (i))
    130
    131#include <asm/cmpxchg.h>
    132
    133#define arch_atomic_xchg(ptr, v)		(arch_xchg(&(ptr)->counter, (v)))
    134#define arch_atomic_cmpxchg(v, old, new)	(arch_cmpxchg(&((v)->counter), (old), (new)))
    135
    136#endif /* __ASM_OPENRISC_ATOMIC_H */