2012-03-28 21:30:03 +04:00
/*
* Copyright 2010 Tilera Corporation . All Rights Reserved .
*
* This program is free software ; you can redistribute it and / or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation , version 2.
*
* This program is distributed in the hope that it will be useful , but
* WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE , GOOD TITLE or
* NON INFRINGEMENT . See the GNU General Public License for
* more details .
*/
# ifndef _ASM_TILE_BARRIER_H
# define _ASM_TILE_BARRIER_H
# ifndef __ASSEMBLY__
# include <linux/types.h>
# include <arch/chip.h>
# include <arch/spr_def.h>
# include <asm/timex.h>
# define __sync() __insn_mf()
# include <hv/syscall_public.h>
/*
* Issue an uncacheable load to each memory controller , then
* wait until those loads have completed .
*/
static inline void __mb_incoherent ( void )
{
long clobber_r10 ;
asm volatile ( " swint2 "
: " =R10 " ( clobber_r10 )
: " R10 " ( HV_SYS_fence_incoherent )
: " r0 " , " r1 " , " r2 " , " r3 " , " r4 " ,
" r5 " , " r6 " , " r7 " , " r8 " , " r9 " ,
" r11 " , " r12 " , " r13 " , " r14 " ,
" r15 " , " r16 " , " r17 " , " r18 " , " r19 " ,
" r20 " , " r21 " , " r22 " , " r23 " , " r24 " ,
" r25 " , " r26 " , " r27 " , " r28 " , " r29 " ) ;
}
/* Fence to guarantee visibility of stores to incoherent memory. */
static inline void
mb_incoherent ( void )
{
__insn_mf ( ) ;
{
# if CHIP_HAS_TILE_WRITE_PENDING()
const unsigned long WRITE_TIMEOUT_CYCLES = 400 ;
unsigned long start = get_cycles_low ( ) ;
do {
if ( __insn_mfspr ( SPR_TILE_WRITE_PENDING ) = = 0 )
return ;
} while ( ( get_cycles_low ( ) - start ) < WRITE_TIMEOUT_CYCLES ) ;
# endif /* CHIP_HAS_TILE_WRITE_PENDING() */
( void ) __mb_incoherent ( ) ;
}
}
# define fast_wmb() __sync()
# define fast_rmb() __sync()
# define fast_mb() __sync()
# define fast_iob() mb_incoherent()
# define wmb() fast_wmb()
# define rmb() fast_rmb()
# define mb() fast_mb()
# define iob() fast_iob()
2014-03-13 22:00:35 +04:00
# ifndef __tilegx__ /* 32 bit */
/*
* We need to barrier before modifying the word , since the _atomic_xxx ( )
* routines just tns the lock and then read / modify / write of the word .
* But after the word is updated , the routine issues an " mf " before returning ,
* and since it ' s a function call , we don ' t even need a compiler barrier .
*/
2015-12-27 16:04:42 +03:00
# define __smp_mb__before_atomic() __smp_mb()
# define __smp_mb__after_atomic() do { } while (0)
# define smp_mb__after_atomic() __smp_mb__after_atomic()
2014-03-13 22:00:35 +04:00
# else /* 64 bit */
2015-12-27 16:04:42 +03:00
# define __smp_mb__before_atomic() __smp_mb()
# define __smp_mb__after_atomic() __smp_mb()
2014-03-13 22:00:35 +04:00
# endif
2016-05-30 15:32:04 +03:00
/*
* The TILE architecture does not do speculative reads ; this ensures
* that a control dependency also orders against loads and already provides
* a LOAD - > { LOAD , STORE } order and can forgo the additional RMB .
*/
# define smp_acquire__after_ctrl_dep() barrier()
2013-11-06 17:57:36 +04:00
# include <asm-generic/barrier.h>
2012-03-28 21:30:03 +04:00
# endif /* !__ASSEMBLY__ */
# endif /* _ASM_TILE_BARRIER_H */