processor.h 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  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. #ifndef CONFIG_PARAVIRT
  73. #define __cpuid native_cpuid
  74. #define paravirt_enabled() 0
  75. /*
  76. * These special macros can be used to get or set a debugging register
  77. */
  78. #define get_debugreg(var, register) \
  79. (var) = native_get_debugreg(register)
  80. #define set_debugreg(value, register) \
  81. native_set_debugreg(register, value)
  82. #endif /* CONFIG_PARAVIRT */
  83. /*
  84. * Save the cr4 feature set we're using (ie
  85. * Pentium 4MB enable and PPro Global page
  86. * enable), so that any CPU's that boot up
  87. * after us can get the correct flags.
  88. */
  89. extern unsigned long mmu_cr4_features;
  90. static inline void set_in_cr4(unsigned long mask)
  91. {
  92. unsigned cr4;
  93. mmu_cr4_features |= mask;
  94. cr4 = read_cr4();
  95. cr4 |= mask;
  96. write_cr4(cr4);
  97. }
  98. static inline void clear_in_cr4(unsigned long mask)
  99. {
  100. unsigned cr4;
  101. mmu_cr4_features &= ~mask;
  102. cr4 = read_cr4();
  103. cr4 &= ~mask;
  104. write_cr4(cr4);
  105. }
  106. /*
  107. * Generic CPUID function
  108. * clear %ecx since some cpus (Cyrix MII) do not set or clear %ecx
  109. * resulting in stale register contents being returned.
  110. */
  111. static inline void cpuid(unsigned int op,
  112. unsigned int *eax, unsigned int *ebx,
  113. unsigned int *ecx, unsigned int *edx)
  114. {
  115. *eax = op;
  116. *ecx = 0;
  117. __cpuid(eax, ebx, ecx, edx);
  118. }
  119. /* Some CPUID calls want 'count' to be placed in ecx */
  120. static inline void cpuid_count(unsigned int op, int count,
  121. unsigned int *eax, unsigned int *ebx,
  122. unsigned int *ecx, unsigned int *edx)
  123. {
  124. *eax = op;
  125. *ecx = count;
  126. __cpuid(eax, ebx, ecx, edx);
  127. }
  128. /*
  129. * CPUID functions returning a single datum
  130. */
  131. static inline unsigned int cpuid_eax(unsigned int op)
  132. {
  133. unsigned int eax, ebx, ecx, edx;
  134. cpuid(op, &eax, &ebx, &ecx, &edx);
  135. return eax;
  136. }
  137. static inline unsigned int cpuid_ebx(unsigned int op)
  138. {
  139. unsigned int eax, ebx, ecx, edx;
  140. cpuid(op, &eax, &ebx, &ecx, &edx);
  141. return ebx;
  142. }
  143. static inline unsigned int cpuid_ecx(unsigned int op)
  144. {
  145. unsigned int eax, ebx, ecx, edx;
  146. cpuid(op, &eax, &ebx, &ecx, &edx);
  147. return ecx;
  148. }
  149. static inline unsigned int cpuid_edx(unsigned int op)
  150. {
  151. unsigned int eax, ebx, ecx, edx;
  152. cpuid(op, &eax, &ebx, &ecx, &edx);
  153. return edx;
  154. }
  155. #endif