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