home *** CD-ROM | disk | FTP | other *** search
/ PC Welt 2006 November (DVD) / PCWELT_11_2006.ISO / casper / filesystem.squashfs / usr / src / linux-headers-2.6.17-6 / include / asm-x86_64 / system.h < prev    next >
Encoding:
C/C++ Source or Header  |  2006-08-11  |  8.1 KB  |  291 lines

  1. #ifndef __ASM_SYSTEM_H
  2. #define __ASM_SYSTEM_H
  3.  
  4. #include <linux/kernel.h>
  5. #include <asm/segment.h>
  6. #include <asm/alternative.h>
  7.  
  8. #ifdef __KERNEL__
  9.  
  10. #define __STR(x) #x
  11. #define STR(x) __STR(x)
  12.  
  13. #define __SAVE(reg,offset) "movq %%" #reg ",(14-" #offset ")*8(%%rsp)\n\t"
  14. #define __RESTORE(reg,offset) "movq (14-" #offset ")*8(%%rsp),%%" #reg "\n\t"
  15.  
  16. /* frame pointer must be last for get_wchan */
  17. #define SAVE_CONTEXT    "pushq %%rbp ; movq %%rsi,%%rbp\n\t"
  18. #define RESTORE_CONTEXT "movq %%rbp,%%rsi ; popq %%rbp\n\t"
  19.  
  20. #define __EXTRA_CLOBBER  \
  21.     ,"rcx","rbx","rdx","r8","r9","r10","r11","r12","r13","r14","r15"
  22.  
  23. #define switch_to(prev,next,last) \
  24.     asm volatile(SAVE_CONTEXT                            \
  25.              "movq %%rsp,%P[threadrsp](%[prev])\n\t" /* save RSP */      \
  26.              "movq %P[threadrsp](%[next]),%%rsp\n\t" /* restore RSP */      \
  27.              "call __switch_to\n\t"                      \
  28.              ".globl thread_return\n"                    \
  29.              "thread_return:\n\t"                        \
  30.              "movq %%gs:%P[pda_pcurrent],%%rsi\n\t"              \
  31.              "movq %P[thread_info](%%rsi),%%r8\n\t"              \
  32.              LOCK_PREFIX "btr  %[tif_fork],%P[ti_flags](%%r8)\n\t"      \
  33.              "movq %%rax,%%rdi\n\t"                       \
  34.              "jc   ret_from_fork\n\t"                      \
  35.              RESTORE_CONTEXT                            \
  36.              : "=a" (last)                            \
  37.              : [next] "S" (next), [prev] "D" (prev),              \
  38.                [threadrsp] "i" (offsetof(struct task_struct, thread.rsp)), \
  39.                [ti_flags] "i" (offsetof(struct thread_info, flags)),\
  40.                [tif_fork] "i" (TIF_FORK),              \
  41.                [thread_info] "i" (offsetof(struct task_struct, thread_info)), \
  42.                [pda_pcurrent] "i" (offsetof(struct x8664_pda, pcurrent))   \
  43.              : "memory", "cc" __EXTRA_CLOBBER)
  44.     
  45. extern void load_gs_index(unsigned); 
  46.  
  47. /*
  48.  * Load a segment. Fall back on loading the zero
  49.  * segment if something goes wrong..
  50.  */
  51. #define loadsegment(seg,value)    \
  52.     asm volatile("\n"            \
  53.         "1:\t"                \
  54.         "movl %k0,%%" #seg "\n"        \
  55.         "2:\n"                \
  56.         ".section .fixup,\"ax\"\n"    \
  57.         "3:\t"                \
  58.         "movl %1,%%" #seg "\n\t"     \
  59.         "jmp 2b\n"            \
  60.         ".previous\n"            \
  61.         ".section __ex_table,\"a\"\n\t"    \
  62.         ".align 8\n\t"            \
  63.         ".quad 1b,3b\n"            \
  64.         ".previous"            \
  65.         : :"r" (value), "r" (0))
  66.  
  67. /*
  68.  * Clear and set 'TS' bit respectively
  69.  */
  70. #define clts() __asm__ __volatile__ ("clts")
  71.  
  72. static inline unsigned long read_cr0(void)
  73.     unsigned long cr0;
  74.     asm volatile("movq %%cr0,%0" : "=r" (cr0));
  75.     return cr0;
  76.  
  77. static inline void write_cr0(unsigned long val) 
  78.     asm volatile("movq %0,%%cr0" :: "r" (val));
  79.  
  80. static inline unsigned long read_cr3(void)
  81.     unsigned long cr3;
  82.     asm("movq %%cr3,%0" : "=r" (cr3));
  83.     return cr3;
  84.  
  85. static inline unsigned long read_cr4(void)
  86.     unsigned long cr4;
  87.     asm("movq %%cr4,%0" : "=r" (cr4));
  88.     return cr4;
  89.  
  90. static inline void write_cr4(unsigned long val)
  91.     asm volatile("movq %0,%%cr4" :: "r" (val));
  92.  
  93. #define stts() write_cr0(8 | read_cr0())
  94.  
  95. #define wbinvd() \
  96.     __asm__ __volatile__ ("wbinvd": : :"memory");
  97.  
  98. /*
  99.  * On SMP systems, when the scheduler does migration-cost autodetection,
  100.  * it needs a way to flush as much of the CPU's caches as possible.
  101.  */
  102. static inline void sched_cacheflush(void)
  103. {
  104.     wbinvd();
  105. }
  106.  
  107. #endif    /* __KERNEL__ */
  108.  
  109. #define nop() __asm__ __volatile__ ("nop")
  110.  
  111. #define xchg(ptr,v) ((__typeof__(*(ptr)))__xchg((unsigned long)(v),(ptr),sizeof(*(ptr))))
  112.  
  113. #define tas(ptr) (xchg((ptr),1))
  114.  
  115. #define __xg(x) ((volatile long *)(x))
  116.  
  117. static inline void set_64bit(volatile unsigned long *ptr, unsigned long val)
  118. {
  119.     *ptr = val;
  120. }
  121.  
  122. #define _set_64bit set_64bit
  123.  
  124. /*
  125.  * Note: no "lock" prefix even on SMP: xchg always implies lock anyway
  126.  * Note 2: xchg has side effect, so that attribute volatile is necessary,
  127.  *      but generally the primitive is invalid, *ptr is output argument. --ANK
  128.  */
  129. static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int size)
  130. {
  131.     switch (size) {
  132.         case 1:
  133.             __asm__ __volatile__("xchgb %b0,%1"
  134.                 :"=q" (x)
  135.                 :"m" (*__xg(ptr)), "0" (x)
  136.                 :"memory");
  137.             break;
  138.         case 2:
  139.             __asm__ __volatile__("xchgw %w0,%1"
  140.                 :"=r" (x)
  141.                 :"m" (*__xg(ptr)), "0" (x)
  142.                 :"memory");
  143.             break;
  144.         case 4:
  145.             __asm__ __volatile__("xchgl %k0,%1"
  146.                 :"=r" (x)
  147.                 :"m" (*__xg(ptr)), "0" (x)
  148.                 :"memory");
  149.             break;
  150.         case 8:
  151.             __asm__ __volatile__("xchgq %0,%1"
  152.                 :"=r" (x)
  153.                 :"m" (*__xg(ptr)), "0" (x)
  154.                 :"memory");
  155.             break;
  156.     }
  157.     return x;
  158. }
  159.  
  160. /*
  161.  * Atomic compare and exchange.  Compare OLD with MEM, if identical,
  162.  * store NEW in MEM.  Return the initial value in MEM.  Success is
  163.  * indicated by comparing RETURN with OLD.
  164.  */
  165.  
  166. #define __HAVE_ARCH_CMPXCHG 1
  167.  
  168. static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old,
  169.                       unsigned long new, int size)
  170. {
  171.     unsigned long prev;
  172.     switch (size) {
  173.     case 1:
  174.         __asm__ __volatile__(LOCK_PREFIX "cmpxchgb %b1,%2"
  175.                      : "=a"(prev)
  176.                      : "q"(new), "m"(*__xg(ptr)), "0"(old)
  177.                      : "memory");
  178.         return prev;
  179.     case 2:
  180.         __asm__ __volatile__(LOCK_PREFIX "cmpxchgw %w1,%2"
  181.                      : "=a"(prev)
  182.                      : "r"(new), "m"(*__xg(ptr)), "0"(old)
  183.                      : "memory");
  184.         return prev;
  185.     case 4:
  186.         __asm__ __volatile__(LOCK_PREFIX "cmpxchgl %k1,%2"
  187.                      : "=a"(prev)
  188.                      : "r"(new), "m"(*__xg(ptr)), "0"(old)
  189.                      : "memory");
  190.         return prev;
  191.     case 8:
  192.         __asm__ __volatile__(LOCK_PREFIX "cmpxchgq %1,%2"
  193.                      : "=a"(prev)
  194.                      : "r"(new), "m"(*__xg(ptr)), "0"(old)
  195.                      : "memory");
  196.         return prev;
  197.     }
  198.     return old;
  199. }
  200.  
  201. #define cmpxchg(ptr,o,n)\
  202.     ((__typeof__(*(ptr)))__cmpxchg((ptr),(unsigned long)(o),\
  203.                     (unsigned long)(n),sizeof(*(ptr))))
  204.  
  205. #ifdef CONFIG_SMP
  206. #define smp_mb()    mb()
  207. #define smp_rmb()    rmb()
  208. #define smp_wmb()    wmb()
  209. #define smp_read_barrier_depends()    do {} while(0)
  210. #else
  211. #define smp_mb()    barrier()
  212. #define smp_rmb()    barrier()
  213. #define smp_wmb()    barrier()
  214. #define smp_read_barrier_depends()    do {} while(0)
  215. #endif
  216.  
  217.     
  218. /*
  219.  * Force strict CPU ordering.
  220.  * And yes, this is required on UP too when we're talking
  221.  * to devices.
  222.  */
  223. #define mb()     asm volatile("mfence":::"memory")
  224. #define rmb()    asm volatile("lfence":::"memory")
  225.  
  226. #ifdef CONFIG_UNORDERED_IO
  227. #define wmb()    asm volatile("sfence" ::: "memory")
  228. #else
  229. #define wmb()    asm volatile("" ::: "memory")
  230. #endif
  231. #define read_barrier_depends()    do {} while(0)
  232. #define set_mb(var, value) do { (void) xchg(&var, value); } while (0)
  233. #define set_wmb(var, value) do { var = value; wmb(); } while (0)
  234.  
  235. #define warn_if_not_ulong(x) do { unsigned long foo; (void) (&(x) == &foo); } while (0)
  236.  
  237. /* interrupt control.. */
  238. #define local_save_flags(x)    do { warn_if_not_ulong(x); __asm__ __volatile__("# save_flags \n\t pushfq ; popq %q0":"=g" (x): /* no input */ :"memory"); } while (0)
  239. #define local_irq_restore(x)     __asm__ __volatile__("# restore_flags \n\t pushq %0 ; popfq": /* no output */ :"g" (x):"memory", "cc")
  240.  
  241. #ifdef CONFIG_X86_VSMP
  242. /* Interrupt control for VSMP  architecture */
  243. #define local_irq_disable()    do { unsigned long flags; local_save_flags(flags); local_irq_restore((flags & ~(1 << 9)) | (1 << 18)); } while (0)
  244. #define local_irq_enable()    do { unsigned long flags; local_save_flags(flags); local_irq_restore((flags | (1 << 9)) & ~(1 << 18)); } while (0)
  245.  
  246. #define irqs_disabled()                    \
  247. ({                            \
  248.     unsigned long flags;                \
  249.     local_save_flags(flags);            \
  250.     (flags & (1<<18)) || !(flags & (1<<9));        \
  251. })
  252.  
  253. /* For spinlocks etc */
  254. #define local_irq_save(x)    do { local_save_flags(x); local_irq_restore((x & ~(1 << 9)) | (1 << 18)); } while (0)
  255. #else  /* CONFIG_X86_VSMP */
  256. #define local_irq_disable()     __asm__ __volatile__("cli": : :"memory")
  257. #define local_irq_enable()    __asm__ __volatile__("sti": : :"memory")
  258.  
  259. #define irqs_disabled()            \
  260. ({                    \
  261.     unsigned long flags;        \
  262.     local_save_flags(flags);    \
  263.     !(flags & (1<<9));        \
  264. })
  265.  
  266. /* For spinlocks etc */
  267. #define local_irq_save(x)     do { warn_if_not_ulong(x); __asm__ __volatile__("# local_irq_save \n\t pushfq ; popq %0 ; cli":"=g" (x): /* no input */ :"memory"); } while (0)
  268. #endif
  269.  
  270. /* used in the idle loop; sti takes one instruction cycle to complete */
  271. #define safe_halt()        __asm__ __volatile__("sti; hlt": : :"memory")
  272. /* used when interrupts are already enabled or to shutdown the processor */
  273. #define halt()            __asm__ __volatile__("hlt": : :"memory")
  274.  
  275. void cpu_idle_wait(void);
  276.  
  277. extern unsigned long arch_align_stack(unsigned long sp);
  278. extern void free_init_pages(char *what, unsigned long begin, unsigned long end);
  279.  
  280. #endif
  281.