system.h
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:9k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1. #ifndef __ASM_SYSTEM_H
  2. #define __ASM_SYSTEM_H
  3. #include <linux/config.h>
  4. #include <linux/kernel.h>
  5. #include <linux/init.h>
  6. #include <asm/segment.h>
  7. #include <linux/bitops.h> /* for LOCK_PREFIX */
  8. #ifdef __KERNEL__
  9. struct task_struct; /* one of the stranger aspects of C forward declarations.. */
  10. extern void FASTCALL(__switch_to(struct task_struct *prev, struct task_struct *next));
  11. #define prepare_to_switch() do { } while(0)
  12. #define switch_to(prev,next,last) do {
  13. asm volatile("pushl %%esint"
  14.      "pushl %%edint"
  15.      "pushl %%ebpnt"
  16.      "movl %%esp,%0nt" /* save ESP */
  17.      "movl %3,%%espnt" /* restore ESP */
  18.      "movl $1f,%1nt" /* save EIP */
  19.      "pushl %4nt" /* restore EIP */
  20.      "jmp __switch_ton"
  21.      "1:t"
  22.      "popl %%ebpnt"
  23.      "popl %%edint"
  24.      "popl %%esint"
  25.      :"=m" (prev->thread.esp),"=m" (prev->thread.eip),
  26.       "=b" (last)
  27.      :"m" (next->thread.esp),"m" (next->thread.eip),
  28.       "a" (prev), "d" (next),
  29.       "b" (prev));
  30. } while (0)
  31. #define _set_base(addr,base) do { unsigned long __pr; 
  32. __asm__ __volatile__ ("movw %%dx,%1nt" 
  33. "rorl $16,%%edxnt" 
  34. "movb %%dl,%2nt" 
  35. "movb %%dh,%3" 
  36. :"=&d" (__pr) 
  37. :"m" (*((addr)+2)), 
  38.  "m" (*((addr)+4)), 
  39.  "m" (*((addr)+7)), 
  40.          "0" (base) 
  41.         ); } while(0)
  42. #define _set_limit(addr,limit) do { unsigned long __lr; 
  43. __asm__ __volatile__ ("movw %%dx,%1nt" 
  44. "rorl $16,%%edxnt" 
  45. "movb %2,%%dhnt" 
  46. "andb $0xf0,%%dhnt" 
  47. "orb %%dh,%%dlnt" 
  48. "movb %%dl,%2" 
  49. :"=&d" (__lr) 
  50. :"m" (*(addr)), 
  51.  "m" (*((addr)+6)), 
  52.  "0" (limit) 
  53.         ); } while(0)
  54. #define set_base(ldt,base) _set_base( ((char *)&(ldt)) , (base) )
  55. #define set_limit(ldt,limit) _set_limit( ((char *)&(ldt)) , ((limit)-1)>>12 )
  56. static inline unsigned long _get_base(char * addr)
  57. {
  58. unsigned long __base;
  59. __asm__("movb %3,%%dhnt"
  60. "movb %2,%%dlnt"
  61. "shll $16,%%edxnt"
  62. "movw %1,%%dx"
  63. :"=&d" (__base)
  64. :"m" (*((addr)+2)),
  65.  "m" (*((addr)+4)),
  66.  "m" (*((addr)+7)));
  67. return __base;
  68. }
  69. #define get_base(ldt) _get_base( ((char *)&(ldt)) )
  70. /*
  71.  * Load a segment. Fall back on loading the zero
  72.  * segment if something goes wrong..
  73.  */
  74. #define loadsegment(seg,value)
  75. asm volatile("n"
  76. "1:t"
  77. "movl %0,%%" #seg "n"
  78. "2:n"
  79. ".section .fixup,"ax"n"
  80. "3:t"
  81. "pushl $0nt"
  82. "popl %%" #seg "nt"
  83. "jmp 2bn"
  84. ".previousn"
  85. ".section __ex_table,"a"nt"
  86. ".align 4nt"
  87. ".long 1b,3bn"
  88. ".previous"
  89. : :"m" (*(unsigned int *)&(value)))
  90. /*
  91.  * Clear and set 'TS' bit respectively
  92.  */
  93. #define clts() __asm__ __volatile__ ("clts")
  94. #define read_cr0() ({ 
  95. unsigned int __dummy; 
  96. __asm__( 
  97. "movl %%cr0,%0nt" 
  98. :"=r" (__dummy)); 
  99. __dummy; 
  100. })
  101. #define write_cr0(x) 
  102. __asm__("movl %0,%%cr0": :"r" (x));
  103. #define read_cr4() ({ 
  104. unsigned int __dummy; 
  105. __asm__( 
  106. "movl %%cr4,%0nt" 
  107. :"=r" (__dummy)); 
  108. __dummy; 
  109. })
  110. #define write_cr4(x) 
  111. __asm__("movl %0,%%cr4": :"r" (x));
  112. #define stts() write_cr0(8 | read_cr0())
  113. #endif /* __KERNEL__ */
  114. #define wbinvd() 
  115. __asm__ __volatile__ ("wbinvd": : :"memory");
  116. static inline unsigned long get_limit(unsigned long segment)
  117. {
  118. unsigned long __limit;
  119. __asm__("lsll %1,%0"
  120. :"=r" (__limit):"r" (segment));
  121. return __limit+1;
  122. }
  123. #define nop() __asm__ __volatile__ ("nop")
  124. #define xchg(ptr,v) ((__typeof__(*(ptr)))__xchg((unsigned long)(v),(ptr),sizeof(*(ptr))))
  125. #define tas(ptr) (xchg((ptr),1))
  126. struct __xchg_dummy { unsigned long a[100]; };
  127. #define __xg(x) ((struct __xchg_dummy *)(x))
  128. /*
  129.  * The semantics of XCHGCMP8B are a bit strange, this is why
  130.  * there is a loop and the loading of %%eax and %%edx has to
  131.  * be inside. This inlines well in most cases, the cached
  132.  * cost is around ~38 cycles. (in the future we might want
  133.  * to do an SIMD/3DNOW!/MMX/FPU 64-bit store here, but that
  134.  * might have an implicit FPU-save as a cost, so it's not
  135.  * clear which path to go.)
  136.  */
  137. static inline void __set_64bit (unsigned long long * ptr,
  138. unsigned int low, unsigned int high)
  139. {
  140. __asm__ __volatile__ (
  141. "n1:t"
  142. "movl (%0), %%eaxnt"
  143. "movl 4(%0), %%edxnt"
  144. "cmpxchg8b (%0)nt"
  145. "jnz 1b"
  146. : /* no outputs */
  147. : "D"(ptr),
  148. "b"(low),
  149. "c"(high)
  150. : "ax","dx","memory");
  151. }
  152. static inline void __set_64bit_constant (unsigned long long *ptr,
  153.  unsigned long long value)
  154. {
  155. __set_64bit(ptr,(unsigned int)(value), (unsigned int)((value)>>32ULL));
  156. }
  157. #define ll_low(x) *(((unsigned int*)&(x))+0)
  158. #define ll_high(x) *(((unsigned int*)&(x))+1)
  159. static inline void __set_64bit_var (unsigned long long *ptr,
  160.  unsigned long long value)
  161. {
  162. __set_64bit(ptr,ll_low(value), ll_high(value));
  163. }
  164. #define set_64bit(ptr,value) 
  165. (__builtin_constant_p(value) ? 
  166.  __set_64bit_constant(ptr, value) : 
  167.  __set_64bit_var(ptr, value) )
  168. #define _set_64bit(ptr,value) 
  169. (__builtin_constant_p(value) ? 
  170.  __set_64bit(ptr, (unsigned int)(value), (unsigned int)((value)>>32ULL) ) : 
  171.  __set_64bit(ptr, ll_low(value), ll_high(value)) )
  172. /*
  173.  * Note: no "lock" prefix even on SMP: xchg always implies lock anyway
  174.  * Note 2: xchg has side effect, so that attribute volatile is necessary,
  175.  *   but generally the primitive is invalid, *ptr is output argument. --ANK
  176.  */
  177. static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int size)
  178. {
  179. switch (size) {
  180. case 1:
  181. __asm__ __volatile__("xchgb %b0,%1"
  182. :"=q" (x)
  183. :"m" (*__xg(ptr)), "0" (x)
  184. :"memory");
  185. break;
  186. case 2:
  187. __asm__ __volatile__("xchgw %w0,%1"
  188. :"=r" (x)
  189. :"m" (*__xg(ptr)), "0" (x)
  190. :"memory");
  191. break;
  192. case 4:
  193. __asm__ __volatile__("xchgl %0,%1"
  194. :"=r" (x)
  195. :"m" (*__xg(ptr)), "0" (x)
  196. :"memory");
  197. break;
  198. }
  199. return x;
  200. }
  201. /*
  202.  * Atomic compare and exchange.  Compare OLD with MEM, if identical,
  203.  * store NEW in MEM.  Return the initial value in MEM.  Success is
  204.  * indicated by comparing RETURN with OLD.
  205.  */
  206. #ifdef CONFIG_X86_CMPXCHG
  207. #define __HAVE_ARCH_CMPXCHG 1
  208. static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old,
  209.       unsigned long new, int size)
  210. {
  211. unsigned long prev;
  212. switch (size) {
  213. case 1:
  214. __asm__ __volatile__(LOCK_PREFIX "cmpxchgb %b1,%2"
  215.      : "=a"(prev)
  216.      : "q"(new), "m"(*__xg(ptr)), "0"(old)
  217.      : "memory");
  218. return prev;
  219. case 2:
  220. __asm__ __volatile__(LOCK_PREFIX "cmpxchgw %w1,%2"
  221.      : "=a"(prev)
  222.      : "q"(new), "m"(*__xg(ptr)), "0"(old)
  223.      : "memory");
  224. return prev;
  225. case 4:
  226. __asm__ __volatile__(LOCK_PREFIX "cmpxchgl %1,%2"
  227.      : "=a"(prev)
  228.      : "q"(new), "m"(*__xg(ptr)), "0"(old)
  229.      : "memory");
  230. return prev;
  231. }
  232. return old;
  233. }
  234. #define cmpxchg(ptr,o,n)
  235. ((__typeof__(*(ptr)))__cmpxchg((ptr),(unsigned long)(o),
  236. (unsigned long)(n),sizeof(*(ptr))))
  237.     
  238. #else
  239. /* Compiling for a 386 proper. Is it worth implementing via cli/sti?  */
  240. #endif
  241. /*
  242.  * Force strict CPU ordering.
  243.  * And yes, this is required on UP too when we're talking
  244.  * to devices.
  245.  *
  246.  * For now, "wmb()" doesn't actually do anything, as all
  247.  * Intel CPU's follow what Intel calls a *Processor Order*,
  248.  * in which all writes are seen in the program order even
  249.  * outside the CPU.
  250.  *
  251.  * I expect future Intel CPU's to have a weaker ordering,
  252.  * but I'd also expect them to finally get their act together
  253.  * and add some real memory barriers if so.
  254.  *
  255.  * Some non intel clones support out of order store. wmb() ceases to be a
  256.  * nop for these.
  257.  */
  258.  
  259. #define mb()  __asm__ __volatile__ ("lock; addl $0,0(%%esp)": : :"memory")
  260. #define rmb() mb()
  261. #ifdef CONFIG_X86_OOSTORE
  262. #define wmb()  __asm__ __volatile__ ("lock; addl $0,0(%%esp)": : :"memory")
  263. #else
  264. #define wmb() __asm__ __volatile__ ("": : :"memory")
  265. #endif
  266. #ifdef CONFIG_SMP
  267. #define smp_mb() mb()
  268. #define smp_rmb() rmb()
  269. #define smp_wmb() wmb()
  270. #else
  271. #define smp_mb() barrier()
  272. #define smp_rmb() barrier()
  273. #define smp_wmb() barrier()
  274. #endif
  275. #define set_mb(var, value) do { xchg(&var, value); } while (0)
  276. #define set_wmb(var, value) do { var = value; wmb(); } while (0)
  277. /* interrupt control.. */
  278. #define __save_flags(x) __asm__ __volatile__("pushfl ; popl %0":"=g" (x): /* no input */)
  279. #define __restore_flags(x)  __asm__ __volatile__("pushl %0 ; popfl": /* no output */ :"g" (x):"memory", "cc")
  280. #define __cli()  __asm__ __volatile__("cli": : :"memory")
  281. #define __sti() __asm__ __volatile__("sti": : :"memory")
  282. /* used in the idle loop; sti takes one instruction cycle to complete */
  283. #define safe_halt() __asm__ __volatile__("sti; hlt": : :"memory")
  284. /* For spinlocks etc */
  285. #define local_irq_save(x) __asm__ __volatile__("pushfl ; popl %0 ; cli":"=g" (x): /* no input */ :"memory")
  286. #define local_irq_restore(x) __restore_flags(x)
  287. #define local_irq_disable() __cli()
  288. #define local_irq_enable() __sti()
  289. #ifdef CONFIG_SMP
  290. extern void __global_cli(void);
  291. extern void __global_sti(void);
  292. extern unsigned long __global_save_flags(void);
  293. extern void __global_restore_flags(unsigned long);
  294. #define cli() __global_cli()
  295. #define sti() __global_sti()
  296. #define save_flags(x) ((x)=__global_save_flags())
  297. #define restore_flags(x) __global_restore_flags(x)
  298. #else
  299. #define cli() __cli()
  300. #define sti() __sti()
  301. #define save_flags(x) __save_flags(x)
  302. #define restore_flags(x) __restore_flags(x)
  303. #endif
  304. /*
  305.  * disable hlt during certain critical i/o operations
  306.  */
  307. #define HAVE_DISABLE_HLT
  308. void disable_hlt(void);
  309. void enable_hlt(void);
  310. extern unsigned long dmi_broken;
  311. extern int is_sony_vaio_laptop;
  312. #define BROKEN_ACPI_Sx 0x0001
  313. #define BROKEN_INIT_AFTER_S1 0x0002
  314. #endif