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

Linux/Unix编程

开发平台:

Unix_Linux

  1. #ifndef X86_64_PDA_H
  2. #define X86_64_PDA_H
  3. #include <linux/stddef.h>
  4. #ifndef ASM_OFFSET_H
  5. #include <asm/offset.h>
  6. #endif
  7. #include <linux/cache.h>
  8. /* Per processor datastructure. %gs points to it while the kernel runs */ 
  9. /* To use a new field with the *_pda macros it needs to be added to tools/offset.c */
  10. struct x8664_pda {
  11. unsigned long kernelstack;  /* TOS for current process */ 
  12. unsigned long oldrsp;      /* user rsp for system call */
  13. unsigned long irqrsp;     /* Old rsp for interrupts. */ 
  14. struct task_struct *pcurrent; /* Current process */
  15.         int irqcount;     /* Irq nesting counter. Starts with -1 */  
  16. int cpunumber;     /* Logical CPU number */
  17. /* XXX: could be a single list */
  18. unsigned long *pgd_quick;
  19. unsigned long *pmd_quick;
  20. unsigned long *pte_quick;
  21. unsigned long pgtable_cache_sz;
  22. char *irqstackptr; /* top of irqstack */
  23. unsigned long volatile *level4_pgt; 
  24. } ____cacheline_aligned;
  25. #define PDA_STACKOFFSET (5*8)
  26. #define IRQSTACK_ORDER 2
  27. #define IRQSTACKSIZE (PAGE_SIZE << IRQSTACK_ORDER) 
  28. extern struct x8664_pda cpu_pda[];
  29. /* 
  30.  * There is no fast way to get the base address of the PDA, all the accesses
  31.  * have to mention %fs/%gs.  So it needs to be done this Torvaldian way.
  32.  */ 
  33. #define sizeof_field(type,field)  (sizeof(((type *)0)->field))
  34. #define typeof_field(type,field)  typeof(((type *)0)->field)
  35. #ifndef __STR
  36. #define __STR(x) #x
  37. #endif
  38. #define __STR2(x) __STR(x) 
  39. extern void __bad_pda_field(void);
  40. #define pda_to_op(op,field,val) do { 
  41.        switch (sizeof_field(struct x8664_pda, field)) { 
  42.        case 2: asm volatile(op "w %0,%%gs:" __STR2(pda_ ## field) ::"r" (val):"memory"); break;
  43.        case 4: asm volatile(op "l %0,%%gs:" __STR2(pda_ ## field) ::"r" (val):"memory"); break;
  44.        case 8: asm volatile(op "q %0,%%gs:" __STR2(pda_ ## field) ::"r" (val):"memory"); break;
  45.        default: __bad_pda_field(); 
  46.        } 
  47.        } while (0)
  48. #define pda_from_op(op,field) ({ 
  49.        typedef typeof_field(struct x8664_pda, field) T__; T__ ret__; 
  50.        switch (sizeof_field(struct x8664_pda, field)) { 
  51.        case 2: asm volatile(op "w %%gs:" __STR2(pda_ ## field) ",%0":"=r" (ret__)::"memory"); break;
  52.        case 4: asm volatile(op "l %%gs:" __STR2(pda_ ## field) ",%0":"=r" (ret__)::"memory"); break;
  53.        case 8: asm volatile(op "q %%gs:" __STR2(pda_ ## field) ",%0":"=r" (ret__)::"memory"); break;
  54.        default: __bad_pda_field(); 
  55.        } 
  56.        ret__; })
  57. #define read_pda(field) pda_from_op("mov",field)
  58. #define write_pda(field,val) pda_to_op("mov",field,val)
  59. #define add_pda(field,val) pda_to_op("add",field,val)
  60. #define sub_pda(field,val) pda_to_op("sub",field,val)
  61. #endif