Update to 3.4-final.
[linux-flexiantxendom0-3.2.10.git] / drivers / xen / sfc_netback / ci / compat / gcc_x86.h
1 /****************************************************************************
2  * Copyright 2002-2005: Level 5 Networks Inc.
3  * Copyright 2005-2008: Solarflare Communications Inc,
4  *                      9501 Jeronimo Road, Suite 250,
5  *                      Irvine, CA 92618, USA
6  *
7  * Maintained by Solarflare Communications
8  *  <linux-xen-drivers@solarflare.com>
9  *  <onload-dev@solarflare.com>
10  *
11  * This program is free software; you can redistribute it and/or modify it
12  * under the terms of the GNU General Public License version 2 as published
13  * by the Free Software Foundation, incorporated herein by reference.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
23  ****************************************************************************
24  */
25
26 /*! \cidoxg_include_ci_compat  */
27
28 #ifndef __CI_COMPAT_GCC_X86_H__
29 #define __CI_COMPAT_GCC_X86_H__
30
31 /*
32 ** The facts:
33 **
34 **   SSE   sfence
35 **   SSE2  lfence, mfence, pause
36 */
37
38 /* 
39    Barriers to enforce ordering with respect to:
40
41    normal memory use: ci_wmb, ci_rmb, ci_wmb
42    IO bus access use: ci_wiob, ci_riob, ci_iob
43 */
44 #if defined(__x86_64__)
45 # define ci_x86_mb() __asm__ __volatile__ ("lock; addl $0,0(%%rsp)":::"memory")
46 #else
47 # define ci_x86_mb() __asm__ __volatile__ ("lock; addl $0,0(%%esp)":::"memory")
48 #endif
49
50 /* ?? measure the impact of latency of sfence on a modern processor before we
51    take a decision on how to integrate with respect to writecombining */
52
53 /* DJR: I don't think we need to add "memory" here.  It means the asm does
54 ** something to memory that GCC doesn't understand.  But all this does is
55 ** commit changes that GCC thinks have already happened.  NB. GCC will not
56 ** reorder across a __volatile__ __asm__ anyway.
57 */
58 #define ci_gcc_fence()    __asm__ __volatile__ ("")
59
60 #if __GNUC__ >= 3 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 96)
61 # define ci_x86_sfence()  __asm__ __volatile__ ("sfence")
62 # define ci_x86_lfence()  __asm__ __volatile__ ("lfence")
63 # define ci_x86_mfence()  __asm__ __volatile__ ("mfence")
64 #else
65 # define ci_x86_sfence()  __asm__ __volatile__ (".byte 0x0F, 0xAE, 0xF8")
66 # define ci_x86_lfence()  __asm__ __volatile__ (".byte 0x0F, 0xAE, 0xE8")
67 # define ci_x86_mfence()  __asm__ __volatile__ (".byte 0x0F, 0xAE, 0xF0")
68 #endif
69
70
71 /* x86 processors to P4 Xeon store in-order unless executing streaming
72    extensions or when using writecombining 
73
74    Hence we do not define ci_wmb to use sfence by default. Requirement is that
75    we do not use writecombining to memory and any code which uses SSE
76    extensions must call sfence directly 
77
78    We need to track non intel clones which may support out of order store.
79
80 */
81
82 #if CI_CPU_OOS
83 # if CI_CPU_HAS_SSE
84 #  define ci_wmb()      ci_x86_sfence()
85 # else
86 #  define ci_wmb()      ci_x86_mb()
87 # endif
88 #else
89 # define ci_wmb()       ci_gcc_fence()
90 #endif
91
92 #if CI_CPU_HAS_SSE2
93 # define ci_rmb()       ci_x86_lfence()
94 # define ci_mb()        ci_x86_mfence()
95 # define ci_riob()      ci_x86_lfence()
96 # define ci_wiob()      ci_x86_sfence()
97 # define ci_iob()       ci_x86_mfence()
98 #else
99 # if CI_CPU_HAS_SSE
100 #  define ci_wiob()     ci_x86_sfence()
101 # else
102 #  define ci_wiob()     ci_x86_mb()
103 # endif
104 # define ci_rmb()       ci_x86_mb()
105 # define ci_mb()        ci_x86_mb()
106 # define ci_riob()      ci_x86_mb()
107 # define ci_iob()       ci_x86_mb()
108 #endif
109
110 typedef unsigned long   ci_phys_addr_t;
111 #define ci_phys_addr_fmt  "%lx"
112
113 #endif  /* __CI_COMPAT_GCC_X86_H__ */
114
115 /*! \cidoxg_end */