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

Linux/Unix编程

开发平台:

Unix_Linux

  1. /* Written 2000 by Andi Kleen */ 
  2. #ifndef __ARCH_DESC_H
  3. #define __ARCH_DESC_H
  4. #include <linux/threads.h>
  5. #include <asm/ldt.h>
  6. #ifndef __ASSEMBLY__
  7. #define __TSS_INDEX(n)  ((n)*64)
  8. #define __LDT_INDEX(n)  ((n)*64)
  9. extern __u8 gdt_table[];
  10. extern __u8 gdt_end[];
  11. enum { 
  12. GATE_INTERRUPT = 0xE, 
  13. GATE_TRAP = 0xF, 
  14. GATE_CALL = 0xC,
  15. }; 
  16. // 16byte gate
  17. struct gate_struct {          
  18. u16 offset_low;
  19. u16 segment; 
  20. unsigned ist : 3, zero0 : 5, type : 5, dpl : 2, p : 1;
  21. u16 offset_middle;
  22. u32 offset_high;
  23. u32 zero1; 
  24. } __attribute__((packed));
  25. // 8 byte segment descriptor
  26. struct desc_struct { 
  27. u16 limit0;
  28. u16 base0;
  29. unsigned base1 : 8, type : 4, s : 1, dpl : 2, p : 1;
  30. unsigned limit : 4, avl : 1, l : 1, d : 1, g : 1, base2 : 8;
  31. } __attribute__((packed)); 
  32. // LDT or TSS descriptor in the GDT. 16 bytes.
  33. struct ldttss_desc { 
  34. u16 limit0;
  35. u16 base0;
  36. unsigned base1 : 8, type : 5, dpl : 2, p : 1;
  37. unsigned limit1 : 4, zero0 : 3, g : 1, base2 : 8;
  38. u32 base3;
  39. u32 zero1; 
  40. } __attribute__((packed)); 
  41. struct per_cpu_gdt {
  42. struct ldttss_desc tss;
  43. struct ldttss_desc ldt; 
  44. } ____cacheline_aligned; 
  45. extern struct per_cpu_gdt gdt_cpu_table[]; 
  46. #define PTR_LOW(x) ((unsigned long)(x) & 0xFFFF) 
  47. #define PTR_MIDDLE(x) (((unsigned long)(x) >> 16) & 0xFFFF)
  48. #define PTR_HIGH(x) ((unsigned long)(x) >> 32)
  49. enum { 
  50. DESC_TSS = 0x9,
  51. DESC_LDT = 0x2,
  52. }; 
  53. struct desc_ptr {
  54. unsigned short size;
  55. unsigned long address;
  56. } __attribute__((packed)) ;
  57. #define __GDT_HEAD_SIZE 64
  58. #define __CPU_DESC_INDEX(x,field) 
  59. ((x) * sizeof(struct per_cpu_gdt) + offsetof(struct per_cpu_gdt, field) + __GDT_HEAD_SIZE)
  60. #define load_TR(cpu) asm volatile("ltr %w0"::"r" (__CPU_DESC_INDEX(cpu, tss)));
  61. #define __load_LDT(cpu) asm volatile("lldt %w0"::"r" (__CPU_DESC_INDEX(cpu, ldt)));
  62. #define clear_LDT(n)  asm volatile("lldt %w0"::"r" (0))
  63. extern struct gate_struct idt_table[]; 
  64. #define copy_16byte(dst,src)  memcpy((dst), (src), 16)
  65. static inline void _set_gate(void *adr, unsigned type, unsigned long func, unsigned dpl, unsigned ist)  
  66. {
  67. struct gate_struct s; 
  68. s.offset_low = PTR_LOW(func); 
  69. s.segment = __KERNEL_CS;
  70. s.ist = ist; 
  71. s.p = 1;
  72. s.dpl = dpl; 
  73. s.zero0 = 0;
  74. s.zero1 = 0; 
  75. s.type = type; 
  76. s.offset_middle = PTR_MIDDLE(func); 
  77. s.offset_high = PTR_HIGH(func); 
  78. copy_16byte(adr, &s);
  79. static inline void set_intr_gate(int nr, void *func) 
  80. _set_gate(&idt_table[nr], GATE_INTERRUPT, (unsigned long) func, 3, 0); 
  81. static inline void set_intr_gate_ist(int nr, void *func, unsigned ist) 
  82. _set_gate(&idt_table[nr], GATE_INTERRUPT, (unsigned long) func, 3, ist); 
  83. static inline void set_system_gate(int nr, void *func) 
  84. _set_gate(&idt_table[nr], GATE_INTERRUPT, (unsigned long) func, 3, 0); 
  85. static inline void set_tssldt_descriptor(struct ldttss_desc *dst, unsigned long ptr, unsigned type, 
  86.  unsigned size) 
  87. memset(dst,0,16); 
  88. dst->limit0 = size & 0xFFFF;
  89. dst->base0 = PTR_LOW(ptr); 
  90. dst->base1 = PTR_MIDDLE(ptr) & 0xFF; 
  91. dst->type = type;
  92. dst->p = 1; 
  93. dst->limit1 = 0xF;
  94. dst->base2 = (PTR_MIDDLE(ptr) >> 8) & 0xFF; 
  95. dst->base3 = PTR_HIGH(ptr); 
  96. }
  97. static inline void set_tss_desc(unsigned n, void *addr)
  98. set_tssldt_descriptor((void *)&gdt_table + __CPU_DESC_INDEX(n,tss), (unsigned long)addr, DESC_TSS, sizeof(struct tss_struct)); 
  99. static inline void set_ldt_desc(unsigned n, void *addr, int size)
  100. set_tssldt_descriptor((void *)&gdt_table + __CPU_DESC_INDEX(n,ldt), (unsigned long)addr, DESC_LDT, size); 
  101. }
  102. /*
  103.  * load one particular LDT into the current CPU
  104.  */
  105. static inline void load_LDT (struct mm_struct *mm)
  106. {
  107. int cpu = smp_processor_id();
  108. void *segments = mm->context.segments;
  109. if (!segments) {
  110. clear_LDT(cpu);
  111. return;
  112. }
  113. set_ldt_desc(cpu, segments, LDT_ENTRIES);
  114. __load_LDT(cpu);
  115. }
  116. #endif /* !__ASSEMBLY__ */
  117. #endif