Linux kernel & device driver programming

Cross-Referenced Linux and Device Driver Code

[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ]
Version: [ 2.6.11.8 ] [ 2.6.25 ] [ 2.6.25.8 ] [ 2.6.31.13 ] Architecture: [ i386 ]

Diff markup

Differences between /linux/include/asm-arm/system.h (Version 2.6.25) and /linux/include/asm-i386/system.h (Version 2.6.11.8)


  1 #ifndef __ASM_ARM_SYSTEM_H                     !!   1 #ifndef __ASM_SYSTEM_H
  2 #define __ASM_ARM_SYSTEM_H                     !!   2 #define __ASM_SYSTEM_H
                                                   >>   3 
                                                   >>   4 #include <linux/config.h>
                                                   >>   5 #include <linux/kernel.h>
                                                   >>   6 #include <asm/segment.h>
                                                   >>   7 #include <asm/cpufeature.h>
                                                   >>   8 #include <linux/bitops.h> /* for LOCK_PREFIX */
  3                                                     9 
  4 #ifdef __KERNEL__                                  10 #ifdef __KERNEL__
  5                                                    11 
  6 #include <asm/memory.h>                        !!  12 struct task_struct;     /* one of the stranger aspects of C forward declarations.. */
                                                   >>  13 extern struct task_struct * FASTCALL(__switch_to(struct task_struct *prev, struct task_struct *next));
  7                                                    14 
  8 #define CPU_ARCH_UNKNOWN        0              !!  15 #define switch_to(prev,next,last) do {                                  \
  9 #define CPU_ARCH_ARMv3          1              !!  16         unsigned long esi,edi;                                          \
 10 #define CPU_ARCH_ARMv4          2              !!  17         asm volatile("pushfl\n\t"                                       \
 11 #define CPU_ARCH_ARMv4T         3              !!  18                      "pushl %%ebp\n\t"                                  \
 12 #define CPU_ARCH_ARMv5          4              !!  19                      "movl %%esp,%0\n\t"        /* save ESP */          \
 13 #define CPU_ARCH_ARMv5T         5              !!  20                      "movl %5,%%esp\n\t"        /* restore ESP */       \
 14 #define CPU_ARCH_ARMv5TE        6              !!  21                      "movl $1f,%1\n\t"          /* save EIP */          \
 15 #define CPU_ARCH_ARMv5TEJ       7              !!  22                      "pushl %6\n\t"             /* restore EIP */       \
 16 #define CPU_ARCH_ARMv6          8              !!  23                      "jmp __switch_to\n"                                \
 17 #define CPU_ARCH_ARMv7          9              !!  24                      "1:\t"                                             \
                                                   >>  25                      "popl %%ebp\n\t"                                   \
                                                   >>  26                      "popfl"                                            \
                                                   >>  27                      :"=m" (prev->thread.esp),"=m" (prev->thread.eip),  \
                                                   >>  28                       "=a" (last),"=S" (esi),"=D" (edi)                 \
                                                   >>  29                      :"m" (next->thread.esp),"m" (next->thread.eip),    \
                                                   >>  30                       "2" (prev), "d" (next));                          \
                                                   >>  31 } while (0)
 18                                                    32 
 19 /*                                             !!  33 #define _set_base(addr,base) do { unsigned long __pr; \
 20  * CR1 bits (CP#15 CR1)                        !!  34 __asm__ __volatile__ ("movw %%dx,%1\n\t" \
 21  */                                            !!  35         "rorl $16,%%edx\n\t" \
 22 #define CR_M    (1 << 0)        /* MMU enable  !!  36         "movb %%dl,%2\n\t" \
 23 #define CR_A    (1 << 1)        /* Alignment a !!  37         "movb %%dh,%3" \
 24 #define CR_C    (1 << 2)        /* Dcache enab !!  38         :"=&d" (__pr) \
 25 #define CR_W    (1 << 3)        /* Write buffe !!  39         :"m" (*((addr)+2)), \
 26 #define CR_P    (1 << 4)        /* 32-bit exce !!  40          "m" (*((addr)+4)), \
 27 #define CR_D    (1 << 5)        /* 32-bit data !!  41          "m" (*((addr)+7)), \
 28 #define CR_L    (1 << 6)        /* Implementat !!  42          "" (base) \
 29 #define CR_B    (1 << 7)        /* Big endian  !!  43         ); } while(0)
 30 #define CR_S    (1 << 8)        /* System MMU  !!  44 
 31 #define CR_R    (1 << 9)        /* ROM MMU pro !!  45 #define _set_limit(addr,limit) do { unsigned long __lr; \
 32 #define CR_F    (1 << 10)       /* Implementat !!  46 __asm__ __volatile__ ("movw %%dx,%1\n\t" \
 33 #define CR_Z    (1 << 11)       /* Implementat !!  47         "rorl $16,%%edx\n\t" \
 34 #define CR_I    (1 << 12)       /* Icache enab !!  48         "movb %2,%%dh\n\t" \
 35 #define CR_V    (1 << 13)       /* Vectors rel !!  49         "andb $0xf0,%%dh\n\t" \
 36 #define CR_RR   (1 << 14)       /* Round Robin !!  50         "orb %%dh,%%dl\n\t" \
 37 #define CR_L4   (1 << 15)       /* LDR pc can  !!  51         "movb %%dl,%2" \
 38 #define CR_DT   (1 << 16)                      !!  52         :"=&d" (__lr) \
 39 #define CR_IT   (1 << 18)                      !!  53         :"m" (*(addr)), \
 40 #define CR_ST   (1 << 19)                      !!  54          "m" (*((addr)+6)), \
 41 #define CR_FI   (1 << 21)       /* Fast interr !!  55          "" (limit) \
 42 #define CR_U    (1 << 22)       /* Unaligned a !!  56         ); } while(0)
 43 #define CR_XP   (1 << 23)       /* Extended pa << 
 44 #define CR_VE   (1 << 24)       /* Vectored in << 
 45                                                << 
 46 #define CPUID_ID        0                      << 
 47 #define CPUID_CACHETYPE 1                      << 
 48 #define CPUID_TCM       2                      << 
 49 #define CPUID_TLBTYPE   3                      << 
 50                                                << 
 51 #ifdef CONFIG_CPU_CP15                         << 
 52 #define read_cpuid(reg)                        << 
 53         ({                                     << 
 54                 unsigned int __val;            << 
 55                 asm("mrc        p15, 0, %0, c0 << 
 56                     : "=r" (__val)             << 
 57                     :                          << 
 58                     : "cc");                   << 
 59                 __val;                         << 
 60         })                                     << 
 61 #else                                          << 
 62 #define read_cpuid(reg) (processor_id)         << 
 63 #endif                                         << 
 64                                                    57 
 65 /*                                             !!  58 #define set_base(ldt,base) _set_base( ((char *)&(ldt)) , (base) )
 66  * This is used to ensure the compiler did act !!  59 #define set_limit(ldt,limit) _set_limit( ((char *)&(ldt)) , ((limit)-1)>>12 )
 67  * asked it for some inline assembly sequences << 
 68  * the compiler from one version to another so << 
 69  * This string is meant to be concatenated wit << 
 70  * will cause compilation to stop on mismatch. << 
 71  * (for details, see gcc PR 15089)             << 
 72  */                                            << 
 73 #define __asmeq(x, y)  ".ifnc " x "," y " ; .e << 
 74                                                << 
 75 #ifndef __ASSEMBLY__                           << 
 76                                                << 
 77 #include <linux/linkage.h>                     << 
 78 #include <linux/stringify.h>                   << 
 79 #include <linux/irqflags.h>                    << 
 80                                                    60 
 81 /*                                             !!  61 static inline unsigned long _get_base(char * addr)
 82  * The CPU ID never changes at run time, so we << 
 83  * compiler that it's constant.  Use this func << 
 84  * rather than directly reading processor_id o << 
 85  */                                            << 
 86 static inline unsigned int read_cpuid_id(void) << 
 87                                                << 
 88 static inline unsigned int read_cpuid_id(void) << 
 89 {                                                  62 {
 90         return read_cpuid(CPUID_ID);           !!  63         unsigned long __base;
                                                   >>  64         __asm__("movb %3,%%dh\n\t"
                                                   >>  65                 "movb %2,%%dl\n\t"
                                                   >>  66                 "shll $16,%%edx\n\t"
                                                   >>  67                 "movw %1,%%dx"
                                                   >>  68                 :"=&d" (__base)
                                                   >>  69                 :"m" (*((addr)+2)),
                                                   >>  70                  "m" (*((addr)+4)),
                                                   >>  71                  "m" (*((addr)+7)));
                                                   >>  72         return __base;
 91 }                                                  73 }
 92                                                    74 
 93 #define __exception     __attribute__((section !!  75 #define get_base(ldt) _get_base( ((char *)&(ldt)) )
 94                                                    76 
 95 struct thread_info;                            !!  77 /*
 96 struct task_struct;                            !!  78  * Load a segment. Fall back on loading the zero
                                                   >>  79  * segment if something goes wrong..
                                                   >>  80  */
                                                   >>  81 #define loadsegment(seg,value)                  \
                                                   >>  82         asm volatile("\n"                       \
                                                   >>  83                 "1:\t"                          \
                                                   >>  84                 "movl %0,%%" #seg "\n"          \
                                                   >>  85                 "2:\n"                          \
                                                   >>  86                 ".section .fixup,\"ax\"\n"      \
                                                   >>  87                 "3:\t"                          \
                                                   >>  88                 "pushl $0\n\t"                  \
                                                   >>  89                 "popl %%" #seg "\n\t"           \
                                                   >>  90                 "jmp 2b\n"                      \
                                                   >>  91                 ".previous\n"                   \
                                                   >>  92                 ".section __ex_table,\"a\"\n\t" \
                                                   >>  93                 ".align 4\n\t"                  \
                                                   >>  94                 ".long 1b,3b\n"                 \
                                                   >>  95                 ".previous"                     \
                                                   >>  96                 : :"m" (*(unsigned int *)&(value)))
 97                                                    97 
 98 /* information about the system we're running  !!  98 /*
 99 extern unsigned int system_rev;                !!  99  * Save a segment register away
100 extern unsigned int system_serial_low;         !! 100  */
101 extern unsigned int system_serial_high;        !! 101 #define savesegment(seg, value) \
102 extern unsigned int mem_fclk_21285;            !! 102         asm volatile("movl %%" #seg ",%0":"=m" (*(int *)&(value)))
103                                                   103 
104 struct pt_regs;                                !! 104 /*
                                                   >> 105  * Clear and set 'TS' bit respectively
                                                   >> 106  */
                                                   >> 107 #define clts() __asm__ __volatile__ ("clts")
                                                   >> 108 #define read_cr0() ({ \
                                                   >> 109         unsigned int __dummy; \
                                                   >> 110         __asm__( \
                                                   >> 111                 "movl %%cr0,%0\n\t" \
                                                   >> 112                 :"=r" (__dummy)); \
                                                   >> 113         __dummy; \
                                                   >> 114 })
                                                   >> 115 #define write_cr0(x) \
                                                   >> 116         __asm__("movl %0,%%cr0": :"r" (x));
                                                   >> 117 
                                                   >> 118 #define read_cr4() ({ \
                                                   >> 119         unsigned int __dummy; \
                                                   >> 120         __asm__( \
                                                   >> 121                 "movl %%cr4,%0\n\t" \
                                                   >> 122                 :"=r" (__dummy)); \
                                                   >> 123         __dummy; \
                                                   >> 124 })
                                                   >> 125 #define write_cr4(x) \
                                                   >> 126         __asm__("movl %0,%%cr4": :"r" (x));
                                                   >> 127 #define stts() write_cr0(8 | read_cr0())
105                                                   128 
106 void die(const char *msg, struct pt_regs *regs !! 129 #endif  /* __KERNEL__ */
107                 __attribute__((noreturn));     << 
108                                                   130 
109 struct siginfo;                                !! 131 #define wbinvd() \
110 void arm_notify_die(const char *str, struct pt !! 132         __asm__ __volatile__ ("wbinvd": : :"memory");
111                 unsigned long err, unsigned lo << 
112                                                   133 
113 void hook_fault_code(int nr, int (*fn)(unsigne !! 134 static inline unsigned long get_limit(unsigned long segment)
114                                        struct  !! 135 {
115                      int sig, const char *name !! 136         unsigned long __limit;
                                                   >> 137         __asm__("lsll %1,%0"
                                                   >> 138                 :"=r" (__limit):"r" (segment));
                                                   >> 139         return __limit+1;
                                                   >> 140 }
116                                                   141 
117 #define xchg(ptr,x) \                          !! 142 #define nop() __asm__ __volatile__ ("nop")
118         ((__typeof__(*(ptr)))__xchg((unsigned  << 
119                                                   143 
120 extern asmlinkage void __backtrace(void);      !! 144 #define xchg(ptr,v) ((__typeof__(*(ptr)))__xchg((unsigned long)(v),(ptr),sizeof(*(ptr))))
121 extern asmlinkage void c_backtrace(unsigned lo << 
122                                                   145 
123 struct mm_struct;                              !! 146 #define tas(ptr) (xchg((ptr),1))
124 extern void show_pte(struct mm_struct *mm, uns << 
125 extern void __show_regs(struct pt_regs *);     << 
126                                                   147 
127 extern int cpu_architecture(void);             !! 148 struct __xchg_dummy { unsigned long a[100]; };
128 extern void cpu_init(void);                    !! 149 #define __xg(x) ((struct __xchg_dummy *)(x))
129                                                   150 
130 void arm_machine_restart(char mode);           << 
131 extern void (*arm_pm_restart)(char str);       << 
132                                                   151 
133 /*                                                152 /*
134  * Intel's XScale3 core supports some v6 featu !! 153  * The semantics of XCHGCMP8B are a bit strange, this is why
135  * but advertises itself as v5 as it does not  !! 154  * there is a loop and the loading of %%eax and %%edx has to
136  * this reason, we need a way to explicitly te !! 155  * be inside. This inlines well in most cases, the cached
                                                   >> 156  * cost is around ~38 cycles. (in the future we might want
                                                   >> 157  * to do an SIMD/3DNOW!/MMX/FPU 64-bit store here, but that
                                                   >> 158  * might have an implicit FPU-save as a cost, so it's not
                                                   >> 159  * clear which path to go.)
                                                   >> 160  *
                                                   >> 161  * cmpxchg8b must be used with the lock prefix here to allow
                                                   >> 162  * the instruction to be executed atomically, see page 3-102
                                                   >> 163  * of the instruction set reference 24319102.pdf. We need
                                                   >> 164  * the reader side to see the coherent 64bit value.
137  */                                               165  */
138 #ifndef CONFIG_CPU_XSC3                        !! 166 static inline void __set_64bit (unsigned long long * ptr,
139 #define cpu_is_xsc3()   0                      !! 167                 unsigned int low, unsigned int high)
140 #else                                          << 
141 static inline int cpu_is_xsc3(void)            << 
142 {                                                 168 {
143         extern unsigned int processor_id;      !! 169         __asm__ __volatile__ (
144                                                !! 170                 "\n1:\t"
145         if ((processor_id & 0xffffe000) == 0x6 !! 171                 "movl (%0), %%eax\n\t"
146                 return 1;                      !! 172                 "movl 4(%0), %%edx\n\t"
147                                                !! 173                 "lock cmpxchg8b (%0)\n\t"
148         return 0;                              !! 174                 "jnz 1b"
                                                   >> 175                 : /* no outputs */
                                                   >> 176                 :       "D"(ptr),
                                                   >> 177                         "b"(low),
                                                   >> 178                         "c"(high)
                                                   >> 179                 :       "ax","dx","memory");
149 }                                                 180 }
150 #endif                                         << 
151                                                << 
152 #if !defined(CONFIG_CPU_XSCALE) && !defined(CO << 
153 #define cpu_is_xscale() 0                      << 
154 #else                                          << 
155 #define cpu_is_xscale() 1                      << 
156 #endif                                         << 
157                                                << 
158 #define UDBG_UNDEFINED  (1 << 0)               << 
159 #define UDBG_SYSCALL    (1 << 1)               << 
160 #define UDBG_BADABORT   (1 << 2)               << 
161 #define UDBG_SEGV       (1 << 3)               << 
162 #define UDBG_BUS        (1 << 4)               << 
163                                                   181 
164 extern unsigned int user_debug;                !! 182 static inline void __set_64bit_constant (unsigned long long *ptr,
165                                                !! 183                                                  unsigned long long value)
166 #if __LINUX_ARM_ARCH__ >= 4                    << 
167 #define vectors_high()  (cr_alignment & CR_V)  << 
168 #else                                          << 
169 #define vectors_high()  (0)                    << 
170 #endif                                         << 
171                                                << 
172 #if __LINUX_ARM_ARCH__ >= 7                    << 
173 #define isb() __asm__ __volatile__ ("isb" : :  << 
174 #define dsb() __asm__ __volatile__ ("dsb" : :  << 
175 #define dmb() __asm__ __volatile__ ("dmb" : :  << 
176 #elif defined(CONFIG_CPU_XSC3) || __LINUX_ARM_ << 
177 #define isb() __asm__ __volatile__ ("mcr p15,  << 
178                                     : : "r" (0 << 
179 #define dsb() __asm__ __volatile__ ("mcr p15,  << 
180                                     : : "r" (0 << 
181 #define dmb() __asm__ __volatile__ ("mcr p15,  << 
182                                     : : "r" (0 << 
183 #else                                          << 
184 #define isb() __asm__ __volatile__ ("" : : : " << 
185 #define dsb() __asm__ __volatile__ ("mcr p15,  << 
186                                     : : "r" (0 << 
187 #define dmb() __asm__ __volatile__ ("" : : : " << 
188 #endif                                         << 
189                                                << 
190 #ifndef CONFIG_SMP                             << 
191 #define mb()    do { if (arch_is_coherent()) d << 
192 #define rmb()   do { if (arch_is_coherent()) d << 
193 #define wmb()   do { if (arch_is_coherent()) d << 
194 #define smp_mb()        barrier()              << 
195 #define smp_rmb()       barrier()              << 
196 #define smp_wmb()       barrier()              << 
197 #else                                          << 
198 #define mb()            dmb()                  << 
199 #define rmb()           dmb()                  << 
200 #define wmb()           dmb()                  << 
201 #define smp_mb()        dmb()                  << 
202 #define smp_rmb()       dmb()                  << 
203 #define smp_wmb()       dmb()                  << 
204 #endif                                         << 
205 #define read_barrier_depends()          do { } << 
206 #define smp_read_barrier_depends()      do { } << 
207                                                << 
208 #define set_mb(var, value)      do { var = val << 
209 #define nop() __asm__ __volatile__("mov\tr0,r0 << 
210                                                << 
211 extern unsigned long cr_no_alignment;   /* def << 
212 extern unsigned long cr_alignment;      /* def << 
213                                                << 
214 static inline unsigned int get_cr(void)        << 
215 {                                                 184 {
216         unsigned int val;                      !! 185         __set_64bit(ptr,(unsigned int)(value), (unsigned int)((value)>>32ULL));
217         asm("mrc p15, 0, %0, c1, c0, 0  @ get  << 
218         return val;                            << 
219 }                                                 186 }
                                                   >> 187 #define ll_low(x)       *(((unsigned int*)&(x))+0)
                                                   >> 188 #define ll_high(x)      *(((unsigned int*)&(x))+1)
220                                                   189 
221 static inline void set_cr(unsigned int val)    !! 190 static inline void __set_64bit_var (unsigned long long *ptr,
                                                   >> 191                          unsigned long long value)
222 {                                                 192 {
223         asm volatile("mcr p15, 0, %0, c1, c0,  !! 193         __set_64bit(ptr,ll_low(value), ll_high(value));
224           : : "r" (val) : "cc");               << 
225         isb();                                 << 
226 }                                                 194 }
227                                                   195 
228 #ifndef CONFIG_SMP                             !! 196 #define set_64bit(ptr,value) \
229 extern void adjust_cr(unsigned long mask, unsi !! 197 (__builtin_constant_p(value) ? \
230 #endif                                         !! 198  __set_64bit_constant(ptr, value) : \
231                                                !! 199  __set_64bit_var(ptr, value) )
232 #define CPACC_FULL(n)           (3 << (n * 2)) !! 200 
233 #define CPACC_SVC(n)            (1 << (n * 2)) !! 201 #define _set_64bit(ptr,value) \
234 #define CPACC_DISABLE(n)        (0 << (n * 2)) !! 202 (__builtin_constant_p(value) ? \
                                                   >> 203  __set_64bit(ptr, (unsigned int)(value), (unsigned int)((value)>>32ULL) ) : \
                                                   >> 204  __set_64bit(ptr, ll_low(value), ll_high(value)) )
235                                                   205 
236 static inline unsigned int get_copro_access(vo !! 206 /*
                                                   >> 207  * Note: no "lock" prefix even on SMP: xchg always implies lock anyway
                                                   >> 208  * Note 2: xchg has side effect, so that attribute volatile is necessary,
                                                   >> 209  *        but generally the primitive is invalid, *ptr is output argument. --ANK
                                                   >> 210  */
                                                   >> 211 static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int size)
237 {                                                 212 {
238         unsigned int val;                      !! 213         switch (size) {
239         asm("mrc p15, 0, %0, c1, c0, 2 @ get c !! 214                 case 1:
240           : "=r" (val) : : "cc");              !! 215                         __asm__ __volatile__("xchgb %b0,%1"
241         return val;                            !! 216                                 :"=q" (x)
                                                   >> 217                                 :"m" (*__xg(ptr)), "" (x)
                                                   >> 218                                 :"memory");
                                                   >> 219                         break;
                                                   >> 220                 case 2:
                                                   >> 221                         __asm__ __volatile__("xchgw %w0,%1"
                                                   >> 222                                 :"=r" (x)
                                                   >> 223                                 :"m" (*__xg(ptr)), "" (x)
                                                   >> 224                                 :"memory");
                                                   >> 225                         break;
                                                   >> 226                 case 4:
                                                   >> 227                         __asm__ __volatile__("xchgl %0,%1"
                                                   >> 228                                 :"=r" (x)
                                                   >> 229                                 :"m" (*__xg(ptr)), "" (x)
                                                   >> 230                                 :"memory");
                                                   >> 231                         break;
                                                   >> 232         }
                                                   >> 233         return x;
242 }                                                 234 }
243                                                   235 
244 static inline void set_copro_access(unsigned i !! 236 /*
                                                   >> 237  * Atomic compare and exchange.  Compare OLD with MEM, if identical,
                                                   >> 238  * store NEW in MEM.  Return the initial value in MEM.  Success is
                                                   >> 239  * indicated by comparing RETURN with OLD.
                                                   >> 240  */
                                                   >> 241 
                                                   >> 242 #ifdef CONFIG_X86_CMPXCHG
                                                   >> 243 #define __HAVE_ARCH_CMPXCHG 1
                                                   >> 244 #endif
                                                   >> 245 
                                                   >> 246 static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old,
                                                   >> 247                                       unsigned long new, int size)
245 {                                                 248 {
246         asm volatile("mcr p15, 0, %0, c1, c0,  !! 249         unsigned long prev;
247           : : "r" (val) : "cc");               !! 250         switch (size) {
248         isb();                                 !! 251         case 1:
                                                   >> 252                 __asm__ __volatile__(LOCK_PREFIX "cmpxchgb %b1,%2"
                                                   >> 253                                      : "=a"(prev)
                                                   >> 254                                      : "q"(new), "m"(*__xg(ptr)), ""(old)
                                                   >> 255                                      : "memory");
                                                   >> 256                 return prev;
                                                   >> 257         case 2:
                                                   >> 258                 __asm__ __volatile__(LOCK_PREFIX "cmpxchgw %w1,%2"
                                                   >> 259                                      : "=a"(prev)
                                                   >> 260                                      : "q"(new), "m"(*__xg(ptr)), ""(old)
                                                   >> 261                                      : "memory");
                                                   >> 262                 return prev;
                                                   >> 263         case 4:
                                                   >> 264                 __asm__ __volatile__(LOCK_PREFIX "cmpxchgl %1,%2"
                                                   >> 265                                      : "=a"(prev)
                                                   >> 266                                      : "q"(new), "m"(*__xg(ptr)), ""(old)
                                                   >> 267                                      : "memory");
                                                   >> 268                 return prev;
                                                   >> 269         }
                                                   >> 270         return old;
249 }                                                 271 }
250                                                   272 
251 /*                                             !! 273 #define cmpxchg(ptr,o,n)\
252  * switch_mm() may do a full cache flush over  !! 274         ((__typeof__(*(ptr)))__cmpxchg((ptr),(unsigned long)(o),\
253  * so enable interrupts over the context switc !! 275                                         (unsigned long)(n),sizeof(*(ptr))))
254  * latency.                                    !! 276     
                                                   >> 277 #ifdef __KERNEL__
                                                   >> 278 struct alt_instr { 
                                                   >> 279         __u8 *instr;            /* original instruction */
                                                   >> 280         __u8 *replacement;
                                                   >> 281         __u8  cpuid;            /* cpuid bit set for replacement */
                                                   >> 282         __u8  instrlen;         /* length of original instruction */
                                                   >> 283         __u8  replacementlen;   /* length of new instruction, <= instrlen */ 
                                                   >> 284         __u8  pad;
                                                   >> 285 }; 
                                                   >> 286 #endif
                                                   >> 287 
                                                   >> 288 /* 
                                                   >> 289  * Alternative instructions for different CPU types or capabilities.
                                                   >> 290  * 
                                                   >> 291  * This allows to use optimized instructions even on generic binary
                                                   >> 292  * kernels.
                                                   >> 293  * 
                                                   >> 294  * length of oldinstr must be longer or equal the length of newinstr
                                                   >> 295  * It can be padded with nops as needed.
                                                   >> 296  * 
                                                   >> 297  * For non barrier like inlines please define new variants
                                                   >> 298  * without volatile and memory clobber.
255  */                                               299  */
256 #define __ARCH_WANT_INTERRUPTS_ON_CTXSW        !! 300 #define alternative(oldinstr, newinstr, feature)        \
                                                   >> 301         asm volatile ("661:\n\t" oldinstr "\n662:\n"                 \
                                                   >> 302                       ".section .altinstructions,\"a\"\n"            \
                                                   >> 303                       "  .align 4\n"                                   \
                                                   >> 304                       "  .long 661b\n"            /* label */          \
                                                   >> 305                       "  .long 663f\n"            /* new instruction */         \
                                                   >> 306                       "  .byte %c0\n"             /* feature bit */    \
                                                   >> 307                       "  .byte 662b-661b\n"       /* sourcelen */      \
                                                   >> 308                       "  .byte 664f-663f\n"       /* replacementlen */ \
                                                   >> 309                       ".previous\n"                                             \
                                                   >> 310                       ".section .altinstr_replacement,\"ax\"\n"                 \
                                                   >> 311                       "663:\n\t" newinstr "\n664:\n"   /* replacement */    \
                                                   >> 312                       ".previous" :: "i" (feature) : "memory")  
257                                                   313 
258 /*                                                314 /*
259  * switch_to(prev, next) should switch from ta !! 315  * Alternative inline assembly with input.
260  * `prev' will never be the same as `next'.  s !! 316  * 
261  * contains the memory barrier to tell GCC not !! 317  * Pecularities:
262  */                                            !! 318  * No memory clobber here. 
263 extern struct task_struct *__switch_to(struct  !! 319  * Argument numbers start with 1.
264                                                !! 320  * Best is to use constraints that are fixed size (like (%1) ... "r")
265 #define switch_to(prev,next,last)              !! 321  * If you use variable sized constraints like "m" or "g" in the 
266 do {                                           !! 322  * replacement maake sure to pad to the worst case length.
267         last = __switch_to(prev,task_thread_in !! 323  */
268 } while (0)                                    !! 324 #define alternative_input(oldinstr, newinstr, feature, input...)                \
                                                   >> 325         asm volatile ("661:\n\t" oldinstr "\n662:\n"                            \
                                                   >> 326                       ".section .altinstructions,\"a\"\n"                       \
                                                   >> 327                       "  .align 4\n"                                            \
                                                   >> 328                       "  .long 661b\n"            /* label */                   \
                                                   >> 329                       "  .long 663f\n"            /* new instruction */         \
                                                   >> 330                       "  .byte %c0\n"             /* feature bit */             \
                                                   >> 331                       "  .byte 662b-661b\n"       /* sourcelen */               \
                                                   >> 332                       "  .byte 664f-663f\n"       /* replacementlen */          \
                                                   >> 333                       ".previous\n"                                             \
                                                   >> 334                       ".section .altinstr_replacement,\"ax\"\n"                 \
                                                   >> 335                       "663:\n\t" newinstr "\n664:\n"   /* replacement */        \
                                                   >> 336                       ".previous" :: "i" (feature), ##input)
269                                                   337 
270 #if defined(CONFIG_CPU_SA1100) || defined(CONF << 
271 /*                                                338 /*
272  * On the StrongARM, "swp" is terminally broke !! 339  * Force strict CPU ordering.
273  * cache totally.  This means that the cache b !! 340  * And yes, this is required on UP too when we're talking
274  * since we use normal loads/stores as well, t !! 341  * to devices.
275  * Typically, this causes oopsen in filp_close !! 342  *
276  * more disasterous effects.  There are two wo !! 343  * For now, "wmb()" doesn't actually do anything, as all
277  *  1. Disable interrupts and emulate the atom !! 344  * Intel CPU's follow what Intel calls a *Processor Order*,
278  *  2. Clean the cache, perform atomic swap, f !! 345  * in which all writes are seen in the program order even
                                                   >> 346  * outside the CPU.
279  *                                                347  *
280  * We choose (1) since its the "easiest" to ac !! 348  * I expect future Intel CPU's to have a weaker ordering,
281  * dependent on the processor type.            !! 349  * but I'd also expect them to finally get their act together
                                                   >> 350  * and add some real memory barriers if so.
282  *                                                351  *
283  * NOTE that this solution won't work on an SM !! 352  * Some non intel clones support out of order store. wmb() ceases to be a
284  * forbid it here.                             !! 353  * nop for these.
285  */                                               354  */
286 #define swp_is_buggy                           !! 355  
287 #endif                                         << 
288                                                   356 
289 static inline unsigned long __xchg(unsigned lo !! 357 /* 
290 {                                              !! 358  * Actually only lfence would be needed for mb() because all stores done 
291         extern void __bad_xchg(volatile void * !! 359  * by the kernel should be already ordered. But keep a full barrier for now. 
292         unsigned long ret;                     !! 360  */
293 #ifdef swp_is_buggy                            << 
294         unsigned long flags;                   << 
295 #endif                                         << 
296 #if __LINUX_ARM_ARCH__ >= 6                    << 
297         unsigned int tmp;                      << 
298 #endif                                         << 
299                                                   361 
300         switch (size) {                        !! 362 #define mb() alternative("lock; addl $0,0(%%esp)", "mfence", X86_FEATURE_XMM2)
301 #if __LINUX_ARM_ARCH__ >= 6                    !! 363 #define rmb() alternative("lock; addl $0,0(%%esp)", "lfence", X86_FEATURE_XMM2)
302         case 1:                                !! 364 
303                 asm volatile("@ __xchg1\n"     !! 365 /**
304                 "1:     ldrexb  %0, [%3]\n"    !! 366  * read_barrier_depends - Flush all pending reads that subsequents reads
305                 "       strexb  %1, %2, [%3]\n !! 367  * depend on.
306                 "       teq     %1, #0\n"      !! 368  *
307                 "       bne     1b"            !! 369  * No data-dependent reads from memory-like regions are ever reordered
308                         : "=&r" (ret), "=&r" ( !! 370  * over this barrier.  All reads preceding this primitive are guaranteed
309                         : "r" (x), "r" (ptr)   !! 371  * to access memory (but not necessarily other CPUs' caches) before any
310                         : "memory", "cc");     !! 372  * reads following this primitive that depend on the data return by
311                 break;                         !! 373  * any of the preceding reads.  This primitive is much lighter weight than
312         case 4:                                !! 374  * rmb() on most CPUs, and is never heavier weight than is
313                 asm volatile("@ __xchg4\n"     !! 375  * rmb().
314                 "1:     ldrex   %0, [%3]\n"    !! 376  *
315                 "       strex   %1, %2, [%3]\n !! 377  * These ordering constraints are respected by both the local CPU
316                 "       teq     %1, #0\n"      !! 378  * and the compiler.
317                 "       bne     1b"            !! 379  *
318                         : "=&r" (ret), "=&r" ( !! 380  * Ordering is not guaranteed by anything other than these primitives,
319                         : "r" (x), "r" (ptr)   !! 381  * not even by data dependencies.  See the documentation for
320                         : "memory", "cc");     !! 382  * memory_barrier() for examples and URLs to more information.
321                 break;                         !! 383  *
322 #elif defined(swp_is_buggy)                    !! 384  * For example, the following code would force ordering (the initial
323 #ifdef CONFIG_SMP                              !! 385  * value of "a" is zero, "b" is one, and "p" is "&a"):
324 #error SMP is not supported on this platform   !! 386  *
                                                   >> 387  * <programlisting>
                                                   >> 388  *      CPU 0                           CPU 1
                                                   >> 389  *
                                                   >> 390  *      b = 2;
                                                   >> 391  *      memory_barrier();
                                                   >> 392  *      p = &b;                         q = p;
                                                   >> 393  *                                      read_barrier_depends();
                                                   >> 394  *                                      d = *q;
                                                   >> 395  * </programlisting>
                                                   >> 396  *
                                                   >> 397  * because the read of "*q" depends on the read of "p" and these
                                                   >> 398  * two reads are separated by a read_barrier_depends().  However,
                                                   >> 399  * the following code, with the same initial values for "a" and "b":
                                                   >> 400  *
                                                   >> 401  * <programlisting>
                                                   >> 402  *      CPU 0                           CPU 1
                                                   >> 403  *
                                                   >> 404  *      a = 2;
                                                   >> 405  *      memory_barrier();
                                                   >> 406  *      b = 3;                          y = b;
                                                   >> 407  *                                      read_barrier_depends();
                                                   >> 408  *                                      x = a;
                                                   >> 409  * </programlisting>
                                                   >> 410  *
                                                   >> 411  * does not enforce ordering, since there is no data dependency between
                                                   >> 412  * the read of "a" and the read of "b".  Therefore, on some CPUs, such
                                                   >> 413  * as Alpha, "y" could be set to 3 and "x" to 0.  Use rmb()
                                                   >> 414  * in cases like thiswhere there are no data dependencies.
                                                   >> 415  **/
                                                   >> 416 
                                                   >> 417 #define read_barrier_depends()  do { } while(0)
                                                   >> 418 
                                                   >> 419 #ifdef CONFIG_X86_OOSTORE
                                                   >> 420 /* Actually there are no OOO store capable CPUs for now that do SSE, 
                                                   >> 421    but make it already an possibility. */
                                                   >> 422 #define wmb() alternative("lock; addl $0,0(%%esp)", "sfence", X86_FEATURE_XMM)
                                                   >> 423 #else
                                                   >> 424 #define wmb()   __asm__ __volatile__ ("": : :"memory")
325 #endif                                            425 #endif
326         case 1:                                << 
327                 raw_local_irq_save(flags);     << 
328                 ret = *(volatile unsigned char << 
329                 *(volatile unsigned char *)ptr << 
330                 raw_local_irq_restore(flags);  << 
331                 break;                         << 
332                                                   426 
333         case 4:                                !! 427 #ifdef CONFIG_SMP
334                 raw_local_irq_save(flags);     !! 428 #define smp_mb()        mb()
335                 ret = *(volatile unsigned long !! 429 #define smp_rmb()       rmb()
336                 *(volatile unsigned long *)ptr !! 430 #define smp_wmb()       wmb()
337                 raw_local_irq_restore(flags);  !! 431 #define smp_read_barrier_depends()      read_barrier_depends()
338                 break;                         !! 432 #define set_mb(var, value) do { xchg(&var, value); } while (0)
339 #else                                             433 #else
340         case 1:                                !! 434 #define smp_mb()        barrier()
341                 asm volatile("@ __xchg1\n"     !! 435 #define smp_rmb()       barrier()
342                 "       swpb    %0, %1, [%2]"  !! 436 #define smp_wmb()       barrier()
343                         : "=&r" (ret)          !! 437 #define smp_read_barrier_depends()      do { } while(0)
344                         : "r" (x), "r" (ptr)   !! 438 #define set_mb(var, value) do { var = value; barrier(); } while (0)
345                         : "memory", "cc");     << 
346                 break;                         << 
347         case 4:                                << 
348                 asm volatile("@ __xchg4\n"     << 
349                 "       swp     %0, %1, [%2]"  << 
350                         : "=&r" (ret)          << 
351                         : "r" (x), "r" (ptr)   << 
352                         : "memory", "cc");     << 
353                 break;                         << 
354 #endif                                            439 #endif
355         default:                               << 
356                 __bad_xchg(ptr, size), ret = 0 << 
357                 break;                         << 
358         }                                      << 
359                                                   440 
360         return ret;                            !! 441 #define set_wmb(var, value) do { var = value; wmb(); } while (0)
361 }                                              << 
362                                                   442 
363 extern void disable_hlt(void);                 !! 443 /* interrupt control.. */
364 extern void enable_hlt(void);                  !! 444 #define local_save_flags(x)     do { typecheck(unsigned long,x); __asm__ __volatile__("pushfl ; popl %0":"=g" (x): /* no input */); } while (0)
                                                   >> 445 #define local_irq_restore(x)    do { typecheck(unsigned long,x); __asm__ __volatile__("pushl %0 ; popfl": /* no output */ :"g" (x):"memory", "cc"); } while (0)
                                                   >> 446 #define local_irq_disable()     __asm__ __volatile__("cli": : :"memory")
                                                   >> 447 #define local_irq_enable()      __asm__ __volatile__("sti": : :"memory")
                                                   >> 448 /* used in the idle loop; sti takes one instruction cycle to complete */
                                                   >> 449 #define safe_halt()             __asm__ __volatile__("sti; hlt": : :"memory")
                                                   >> 450 
                                                   >> 451 #define irqs_disabled()                 \
                                                   >> 452 ({                                      \
                                                   >> 453         unsigned long flags;            \
                                                   >> 454         local_save_flags(flags);        \
                                                   >> 455         !(flags & (1<<9));              \
                                                   >> 456 })
365                                                   457 
366 #include <asm-generic/cmpxchg-local.h>         !! 458 /* For spinlocks etc */
                                                   >> 459 #define local_irq_save(x)       __asm__ __volatile__("pushfl ; popl %0 ; cli":"=g" (x): /* no input */ :"memory")
367                                                   460 
368 /*                                                461 /*
369  * cmpxchg_local and cmpxchg64_local are atomi !! 462  * disable hlt during certain critical i/o operations
370  * them available.                             << 
371  */                                               463  */
372 #define cmpxchg_local(ptr, o, n)               !! 464 #define HAVE_DISABLE_HLT
373         ((__typeof__(*(ptr)))__cmpxchg_local_g !! 465 void disable_hlt(void);
374                         (unsigned long)(n), si !! 466 void enable_hlt(void);
375 #define cmpxchg64_local(ptr, o, n) __cmpxchg64 << 
376                                                << 
377 #ifndef CONFIG_SMP                             << 
378 #include <asm-generic/cmpxchg.h>               << 
379 #endif                                         << 
380                                                << 
381 #endif /* __ASSEMBLY__ */                      << 
382                                                << 
383 #define arch_align_stack(x) (x)                << 
384                                                   467 
385 #endif /* __KERNEL__ */                        !! 468 extern int es7000_plat;
                                                   >> 469 void cpu_idle_wait(void);
386                                                   470 
387 #endif                                            471 #endif
388                                                   472 
  This page was automatically generated by the LXR engine.