processor.h 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. #ifndef __ASM_X86_PROCESSOR_H
  2. #define __ASM_X86_PROCESSOR_H
  3. #include <asm/processor-flags.h>
  4. #include <asm/page.h>
  5. #include <asm/system.h>
  6. static inline void native_cpuid(unsigned int *eax, unsigned int *ebx,
  7. unsigned int *ecx, unsigned int *edx)
  8. {
  9. /* ecx is often an input as well as an output. */
  10. __asm__("cpuid"
  11. : "=a" (*eax),
  12. "=b" (*ebx),
  13. "=c" (*ecx),
  14. "=d" (*edx)
  15. : "0" (*eax), "2" (*ecx));
  16. }
  17. static inline void load_cr3(pgd_t *pgdir)
  18. {
  19. write_cr3(__pa(pgdir));
  20. }
  21. #ifdef CONFIG_X86_32
  22. # include "processor_32.h"
  23. #else
  24. # include "processor_64.h"
  25. #endif
  26. static inline unsigned long native_get_debugreg(int regno)
  27. {
  28. unsigned long val = 0; /* Damn you, gcc! */
  29. switch (regno) {
  30. case 0:
  31. asm("mov %%db0, %0" :"=r" (val)); break;
  32. case 1:
  33. asm("mov %%db1, %0" :"=r" (val)); break;
  34. case 2:
  35. asm("mov %%db2, %0" :"=r" (val)); break;
  36. case 3:
  37. asm("mov %%db3, %0" :"=r" (val)); break;
  38. case 6:
  39. asm("mov %%db6, %0" :"=r" (val)); break;
  40. case 7:
  41. asm("mov %%db7, %0" :"=r" (val)); break;
  42. default:
  43. BUG();
  44. }
  45. return val;
  46. }
  47. static inline void native_set_debugreg(int regno, unsigned long value)
  48. {
  49. switch (regno) {
  50. case 0:
  51. asm("mov %0,%%db0" : /* no output */ :"r" (value));
  52. break;
  53. case 1:
  54. asm("mov %0,%%db1" : /* no output */ :"r" (value));
  55. break;
  56. case 2:
  57. asm("mov %0,%%db2" : /* no output */ :"r" (value));
  58. break;
  59. case 3:
  60. asm("mov %0,%%db3" : /* no output */ :"r" (value));
  61. break;
  62. case 6:
  63. asm("mov %0,%%db6" : /* no output */ :"r" (value));
  64. break;
  65. case 7:
  66. asm("mov %0,%%db7" : /* no output */ :"r" (value));
  67. break;
  68. default:
  69. BUG();
  70. }
  71. }
  72. /*
  73. * Set IOPL bits in EFLAGS from given mask
  74. */
  75. static inline void native_set_iopl_mask(unsigned mask)
  76. {
  77. #ifdef CONFIG_X86_32
  78. unsigned int reg;
  79. __asm__ __volatile__ ("pushfl;"
  80. "popl %0;"
  81. "andl %1, %0;"
  82. "orl %2, %0;"
  83. "pushl %0;"
  84. "popfl"
  85. : "=&r" (reg)
  86. : "i" (~X86_EFLAGS_IOPL), "r" (mask));
  87. #endif
  88. }
  89. #ifndef CONFIG_PARAVIRT
  90. #define __cpuid native_cpuid
  91. #define paravirt_enabled() 0
  92. /*
  93. * These special macros can be used to get or set a debugging register
  94. */
  95. #define get_debugreg(var, register) \
  96. (var) = native_get_debugreg(register)
  97. #define set_debugreg(value, register) \
  98. native_set_debugreg(register, value)
  99. #define set_iopl_mask native_set_iopl_mask
  100. #endif /* CONFIG_PARAVIRT */
  101. /*
  102. * Save the cr4 feature set we're using (ie
  103. * Pentium 4MB enable and PPro Global page
  104. * enable), so that any CPU's that boot up
  105. * after us can get the correct flags.
  106. */
  107. extern unsigned long mmu_cr4_features;
  108. static inline void set_in_cr4(unsigned long mask)
  109. {
  110. unsigned cr4;
  111. mmu_cr4_features |= mask;
  112. cr4 = read_cr4();
  113. cr4 |= mask;
  114. write_cr4(cr4);
  115. }
  116. static inline void clear_in_cr4(unsigned long mask)
  117. {
  118. unsigned cr4;
  119. mmu_cr4_features &= ~mask;
  120. cr4 = read_cr4();
  121. cr4 &= ~mask;
  122. write_cr4(cr4);
  123. }
  124. /*
  125. * Generic CPUID function
  126. * clear %ecx since some cpus (Cyrix MII) do not set or clear %ecx
  127. * resulting in stale register contents being returned.
  128. */
  129. static inline void cpuid(unsigned int op,
  130. unsigned int *eax, unsigned int *ebx,
  131. unsigned int *ecx, unsigned int *edx)
  132. {
  133. *eax = op;
  134. *ecx = 0;
  135. __cpuid(eax, ebx, ecx, edx);
  136. }
  137. /* Some CPUID calls want 'count' to be placed in ecx */
  138. static inline void cpuid_count(unsigned int op, int count,
  139. unsigned int *eax, unsigned int *ebx,
  140. unsigned int *ecx, unsigned int *edx)
  141. {
  142. *eax = op;
  143. *ecx = count;
  144. __cpuid(eax, ebx, ecx, edx);
  145. }
  146. /*
  147. * CPUID functions returning a single datum
  148. */
  149. static inline unsigned int cpuid_eax(unsigned int op)
  150. {
  151. unsigned int eax, ebx, ecx, edx;
  152. cpuid(op, &eax, &ebx, &ecx, &edx);
  153. return eax;
  154. }
  155. static inline unsigned int cpuid_ebx(unsigned int op)
  156. {
  157. unsigned int eax, ebx, ecx, edx;
  158. cpuid(op, &eax, &ebx, &ecx, &edx);
  159. return ebx;
  160. }
  161. static inline unsigned int cpuid_ecx(unsigned int op)
  162. {
  163. unsigned int eax, ebx, ecx, edx;
  164. cpuid(op, &eax, &ebx, &ecx, &edx);
  165. return ecx;
  166. }
  167. static inline unsigned int cpuid_edx(unsigned int op)
  168. {
  169. unsigned int eax, ebx, ecx, edx;
  170. cpuid(op, &eax, &ebx, &ecx, &edx);
  171. return edx;
  172. }
  173. #endif