system.h
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:8k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. #ifndef __ASM_SYSTEM_H
  2. #define __ASM_SYSTEM_H
  3. #include <linux/config.h>
  4. #include <linux/kernel.h>
  5. #include <asm/segment.h>
  6. #ifdef __KERNEL__
  7. #ifdef CONFIG_SMP
  8. #define LOCK_PREFIX "lock ; "
  9. #else
  10. #define LOCK_PREFIX ""
  11. #endif
  12. #define prepare_to_switch() do {} while(0)
  13. #define __STR(x) #x
  14. #define STR(x) __STR(x)
  15. #define __PUSH(x) "pushq %%" __STR(x) "nt"
  16. #define __POP(x)  "popq  %%" __STR(x) "nt"
  17. /* frame pointer must be last for get_wchan */
  18. #define SAVE_CONTEXT 
  19. __PUSH(rsi) __PUSH(rdi) 
  20.     __PUSH(r12) __PUSH(r13) __PUSH(r14) __PUSH(r15)  
  21. __PUSH(rdx) __PUSH(rcx) __PUSH(r8) __PUSH(r9) __PUSH(r10) __PUSH(r11)  
  22. __PUSH(rbx) __PUSH(rbp) 
  23. #define RESTORE_CONTEXT 
  24. __POP(rbp) __POP(rbx) 
  25. __POP(r11) __POP(r10) __POP(r9) __POP(r8) __POP(rcx) __POP(rdx) 
  26. __POP(r15) __POP(r14) __POP(r13) __POP(r12) 
  27. __POP(rdi) __POP(rsi)
  28. #define switch_to(prev,next,last) do { void *l; 
  29. asm volatile(SAVE_CONTEXT
  30.      "movq %%rsp,%0nt" /* save RSP */
  31.      "movq %3,%%rspnt" /* restore RSP */
  32.      "leaq 1f(%%rip),%%raxnt"
  33.      "movq %%rax,%1nt" /* save RIP */
  34.      "pushq %4nt" /* setup new RIP */
  35.      "jmp __switch_tont"
  36.      "1:nt"
  37.      RESTORE_CONTEXT
  38.      :"=m" (prev->thread.rsp),"=m" (prev->thread.rip), "=a" (l) 
  39.      :"m" (next->thread.rsp),"m" (next->thread.rip),
  40.       "S" (next), "D" (prev)
  41.      :"memory","cc");
  42. last = l; 
  43. } while(0)
  44.      
  45. extern void load_gs_index(unsigned); 
  46. /*
  47.  * Load a segment. Fall back on loading the zero
  48.  * segment if something goes wrong..
  49.  */
  50. #define loadsegment(seg,value)
  51. asm volatile("n"
  52. "1:t"
  53. "movl %0,%%" #seg "n"
  54. "2:n"
  55. ".section .fixup,"ax"n"
  56. "3:t"
  57. "pushq $0 ; popq %% " #seg "nt"
  58. "jmp 2bn"
  59. ".previousn"
  60. ".section __ex_table,"a"nt"
  61. ".align 4nt"
  62. ".quad 1b,3bn"
  63. ".previous"
  64. : :"r" ((int)(value)))
  65. #define set_debug(value,register) 
  66.                 __asm__("movq %0,%%db" #register  
  67. : /* no output */ 
  68. :"r" ((unsigned long) value))
  69. /*
  70.  * Clear and set 'TS' bit respectively
  71.  */
  72. #define clts() __asm__ __volatile__ ("clts")
  73. #define read_cr0() ({ 
  74. unsigned long __dummy; 
  75. __asm__( 
  76. "movq %%cr0,%0nt" 
  77. :"=r" (__dummy)); 
  78. __dummy; 
  79. })
  80. #define write_cr0(x) 
  81. __asm__("movq %0,%%cr0": :"r" (x));
  82. #define read_cr4() ({ 
  83. unsigned long __dummy; 
  84. __asm__( 
  85. "movq %%cr4,%0nt" 
  86. :"=r" (__dummy)); 
  87. __dummy; 
  88. })
  89. #define write_cr4(x) 
  90. __asm__("movq %0,%%cr4": :"r" (x));
  91. #define stts() write_cr0(8 | read_cr0())
  92. #define wbinvd() 
  93. __asm__ __volatile__ ("wbinvd": : :"memory");
  94. #endif /* __KERNEL__ */
  95. #define nop() __asm__ __volatile__ ("nop")
  96. #define xchg(ptr,v) ((__typeof__(*(ptr)))__xchg((unsigned long)(v),(ptr),sizeof(*(ptr))))
  97. #define tas(ptr) (xchg((ptr),1))
  98. #define __xg(x) ((volatile long *)(x))
  99. extern inline void set_64bit(volatile unsigned long *ptr, unsigned long val)
  100. {
  101. *ptr = val;
  102. }
  103. #define _set_64bit set_64bit
  104. /*
  105.  * Note: no "lock" prefix even on SMP: xchg always implies lock anyway
  106.  * Note 2: xchg has side effect, so that attribute volatile is necessary,
  107.  *   but generally the primitive is invalid, *ptr is output argument. --ANK
  108.  */
  109. static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int size)
  110. {
  111. switch (size) {
  112. case 1:
  113. __asm__ __volatile__("xchgb %b0,%1"
  114. :"=q" (x)
  115. :"m" (*__xg(ptr)), "0" (x)
  116. :"memory");
  117. break;
  118. case 2:
  119. __asm__ __volatile__("xchgw %w0,%1"
  120. :"=r" (x)
  121. :"m" (*__xg(ptr)), "0" (x)
  122. :"memory");
  123. break;
  124. case 4:
  125. __asm__ __volatile__("xchgl %k0,%1"
  126. :"=r" (x)
  127. :"m" (*__xg(ptr)), "0" (x)
  128. :"memory");
  129. break;
  130. case 8:
  131. __asm__ __volatile__("xchgq %0,%1"
  132. :"=r" (x)
  133. :"m" (*__xg(ptr)), "0" (x)
  134. :"memory");
  135. break;
  136. }
  137. return x;
  138. }
  139. /*
  140.  * Atomic compare and exchange.  Compare OLD with MEM, if identical,
  141.  * store NEW in MEM.  Return the initial value in MEM.  Success is
  142.  * indicated by comparing RETURN with OLD.
  143.  */
  144. #define __HAVE_ARCH_CMPXCHG 1
  145. static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old,
  146.       unsigned long new, int size)
  147. {
  148. unsigned long prev;
  149. switch (size) {
  150. case 1:
  151. __asm__ __volatile__(LOCK_PREFIX "cmpxchgb %b1,%2"
  152.      : "=a"(prev)
  153.      : "q"(new), "m"(*__xg(ptr)), "0"(old)
  154.      : "memory");
  155. return prev;
  156. case 2:
  157. __asm__ __volatile__(LOCK_PREFIX "cmpxchgw %w1,%2"
  158.      : "=a"(prev)
  159.      : "q"(new), "m"(*__xg(ptr)), "0"(old)
  160.      : "memory");
  161. return prev;
  162. case 4:
  163. __asm__ __volatile__(LOCK_PREFIX "cmpxchgl %k1,%2"
  164.      : "=a"(prev)
  165.      : "q"(new), "m"(*__xg(ptr)), "0"(old)
  166.      : "memory");
  167. return prev;
  168. case 8:
  169. __asm__ __volatile__(LOCK_PREFIX "cmpxchgq %1,%2"
  170.      : "=a"(prev)
  171.      : "q"(new), "m"(*__xg(ptr)), "0"(old)
  172.      : "memory");
  173. return prev;
  174. }
  175. return old;
  176. }
  177. #define cmpxchg(ptr,o,n)
  178. ((__typeof__(*(ptr)))__cmpxchg((ptr),(unsigned long)(o),
  179. (unsigned long)(n),sizeof(*(ptr))))
  180. #ifdef CONFIG_SMP
  181. #define smp_mb() mb()
  182. #define smp_rmb() rmb()
  183. #define smp_wmb() wmb()
  184. #else
  185. #define smp_mb() barrier()
  186. #define smp_rmb() barrier()
  187. #define smp_wmb() barrier()
  188. #endif
  189.     
  190. /*
  191.  * Force strict CPU ordering.
  192.  * And yes, this is required on UP too when we're talking
  193.  * to devices.
  194.  *
  195.  * For now, "wmb()" doesn't actually do anything, as all
  196.  * Intel CPU's follow what Intel calls a *Processor Order*,
  197.  * in which all writes are seen in the program order even
  198.  * outside the CPU.
  199.  *
  200.  * I expect future Intel CPU's to have a weaker ordering,
  201.  * but I'd also expect them to finally get their act together
  202.  * and add some real memory barriers if so.
  203.  */
  204. #define mb()  asm volatile("mfence":::"memory")
  205. #define rmb() asm volatile("lfence":::"memory")
  206. #define wmb() asm volatile("sfence":::"memory")
  207. #define set_mb(var, value) do { xchg(&var, value); } while (0)
  208. #define set_wmb(var, value) do { var = value; wmb(); } while (0)
  209. #define warn_if_not_ulong(x) do { unsigned long foo; (void) (&(x) == &foo); } while (0)
  210. /* interrupt control.. */
  211. #define __save_flags(x) do { warn_if_not_ulong(x); __asm__ __volatile__("# save_flags nt pushfq ; popq %q0":"=g" (x): /* no input */ :"memory"); } while (0)
  212. #define __restore_flags(x)  __asm__ __volatile__("# restore_flags nt pushq %0 ; popfq": /* no output */ :"g" (x):"memory", "cc")
  213. #define __cli()  __asm__ __volatile__("cli": : :"memory")
  214. #define __sti() __asm__ __volatile__("sti": : :"memory")
  215. /* used in the idle loop; sti takes one instruction cycle to complete */
  216. #define safe_halt() __asm__ __volatile__("sti; hlt": : :"memory")
  217. /* For spinlocks etc */
  218. #define local_irq_save(x)  do { warn_if_not_ulong(x); __asm__ __volatile__("# local_irq_save nt pushfq ; popq %0 ; cli":"=g" (x): /* no input */ :"memory"); } while (0)
  219. #define local_irq_restore(x) __asm__ __volatile__("# local_irq_restore nt pushq %0 ; popfq": /* no output */ :"g" (x):"memory")
  220. #define local_irq_disable() __cli()
  221. #define local_irq_enable() __sti()
  222. #ifdef CONFIG_SMP
  223. extern void __global_cli(void);
  224. extern void __global_sti(void);
  225. extern unsigned long __global_save_flags(void);
  226. extern void __global_restore_flags(unsigned long);
  227. #define cli() __global_cli()
  228. #define sti() __global_sti()
  229. #define save_flags(x) ((x)=__global_save_flags())
  230. #define restore_flags(x) __global_restore_flags(x)
  231. #else
  232. #define cli() __cli()
  233. #define sti() __sti()
  234. #define save_flags(x) __save_flags(x)
  235. #define restore_flags(x) __restore_flags(x)
  236. #endif
  237. /* Default simics "magic" breakpoint */
  238. #define icebp() asm volatile("xchg %%bx,%%bx" ::: "ebx")
  239. /*
  240.  * disable hlt during certain critical i/o operations
  241.  */
  242. #define HAVE_DISABLE_HLT
  243. void disable_hlt(void);
  244. void enable_hlt(void);
  245. #endif