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 / pda.h < prev    next >
Encoding:
C/C++ Source or Header  |  2006-08-11  |  3.0 KB  |  88 lines

  1. #ifndef X86_64_PDA_H
  2. #define X86_64_PDA_H
  3.  
  4. #ifndef __ASSEMBLY__
  5. #include <linux/stddef.h>
  6. #include <linux/types.h>
  7. #include <linux/cache.h>
  8. #include <asm/page.h>
  9.  
  10. /* Per processor datastructure. %gs points to it while the kernel runs */ 
  11. struct x8664_pda {
  12.     struct task_struct *pcurrent;    /* Current process */
  13.     unsigned long data_offset;    /* Per cpu data offset from linker address */
  14.     unsigned long kernelstack;  /* top of kernel stack for current */ 
  15.     unsigned long oldrsp;         /* user rsp for system call */
  16. #if DEBUG_STKSZ > EXCEPTION_STKSZ
  17.     unsigned long debugstack;   /* #DB/#BP stack. */
  18. #endif
  19.         int irqcount;            /* Irq nesting counter. Starts with -1 */      
  20.     int cpunumber;            /* Logical CPU number */
  21.     char *irqstackptr;    /* top of irqstack */
  22.     int nodenumber;            /* number of current node */
  23.     unsigned int __softirq_pending;
  24.     unsigned int __nmi_count;    /* number of NMI on this CPUs */
  25.     int mmu_state;     
  26.     struct mm_struct *active_mm;
  27.     unsigned apic_timer_irqs;
  28. } ____cacheline_aligned_in_smp;
  29.  
  30. extern struct x8664_pda *_cpu_pda[];
  31. extern struct x8664_pda boot_cpu_pda[];
  32.  
  33. #define cpu_pda(i) (_cpu_pda[i])
  34.  
  35. /* 
  36.  * There is no fast way to get the base address of the PDA, all the accesses
  37.  * have to mention %fs/%gs.  So it needs to be done this Torvaldian way.
  38.  */ 
  39. #define sizeof_field(type,field)  (sizeof(((type *)0)->field))
  40. #define typeof_field(type,field)  typeof(((type *)0)->field)
  41.  
  42. extern void __bad_pda_field(void);
  43.  
  44. #define pda_offset(field) offsetof(struct x8664_pda, field)
  45.  
  46. #define pda_to_op(op,field,val) do { \
  47.     typedef typeof_field(struct x8664_pda, field) T__; \
  48.        switch (sizeof_field(struct x8664_pda, field)) {         \
  49. case 2: \
  50. asm volatile(op "w %0,%%gs:%P1"::"ri" ((T__)val),"i"(pda_offset(field)):"memory"); break; \
  51. case 4: \
  52. asm volatile(op "l %0,%%gs:%P1"::"ri" ((T__)val),"i"(pda_offset(field)):"memory"); break; \
  53. case 8: \
  54. asm volatile(op "q %0,%%gs:%P1"::"ri" ((T__)val),"i"(pda_offset(field)):"memory"); break; \
  55.        default: __bad_pda_field();                     \
  56.        } \
  57.        } while (0)
  58.  
  59. /* 
  60.  * AK: PDA read accesses should be neither volatile nor have an memory clobber.
  61.  * Unfortunately removing them causes all hell to break lose currently.
  62.  */
  63. #define pda_from_op(op,field) ({ \
  64.        typeof_field(struct x8664_pda, field) ret__; \
  65.        switch (sizeof_field(struct x8664_pda, field)) {         \
  66. case 2: \
  67. asm volatile(op "w %%gs:%P1,%0":"=r" (ret__):"i"(pda_offset(field)):"memory"); break;\
  68. case 4: \
  69. asm volatile(op "l %%gs:%P1,%0":"=r" (ret__):"i"(pda_offset(field)):"memory"); break;\
  70. case 8: \
  71. asm volatile(op "q %%gs:%P1,%0":"=r" (ret__):"i"(pda_offset(field)):"memory"); break;\
  72.        default: __bad_pda_field();                     \
  73.        } \
  74.        ret__; })
  75.  
  76.  
  77. #define read_pda(field) pda_from_op("mov",field)
  78. #define write_pda(field,val) pda_to_op("mov",field,val)
  79. #define add_pda(field,val) pda_to_op("add",field,val)
  80. #define sub_pda(field,val) pda_to_op("sub",field,val)
  81. #define or_pda(field,val) pda_to_op("or",field,val)
  82.  
  83. #endif
  84.  
  85. #define PDA_STACKOFFSET (5*8)
  86.  
  87. #endif
  88.