3deb5ba55f550469b3e21f036bba26e4b7e041b6
[cascardo/linux.git] / 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 /* Forward declaration, a strange C thing */
7 struct task_struct;
8 struct mm_struct;
9
10 #include <asm/page.h>
11 #include <asm/system.h>
12
13 /*
14  * Default implementation of macro that returns current
15  * instruction pointer ("program counter").
16  */
17 static inline void *current_text_addr(void)
18 {
19         void *pc;
20         asm volatile("mov $1f,%0\n1:":"=r" (pc));
21         return pc;
22 }
23
24 static inline void native_cpuid(unsigned int *eax, unsigned int *ebx,
25                                          unsigned int *ecx, unsigned int *edx)
26 {
27         /* ecx is often an input as well as an output. */
28         __asm__("cpuid"
29                 : "=a" (*eax),
30                   "=b" (*ebx),
31                   "=c" (*ecx),
32                   "=d" (*edx)
33                 : "0" (*eax), "2" (*ecx));
34 }
35
36 static inline void load_cr3(pgd_t *pgdir)
37 {
38         write_cr3(__pa(pgdir));
39 }
40
41 #ifdef CONFIG_X86_32
42 # include "processor_32.h"
43 #else
44 # include "processor_64.h"
45 #endif
46
47 extern void print_cpu_info(struct cpuinfo_x86 *);
48 extern void init_scattered_cpuid_features(struct cpuinfo_x86 *c);
49 extern unsigned int init_intel_cacheinfo(struct cpuinfo_x86 *c);
50 extern unsigned short num_cache_leaves;
51
52 static inline unsigned long native_get_debugreg(int regno)
53 {
54         unsigned long val = 0;  /* Damn you, gcc! */
55
56         switch (regno) {
57         case 0:
58                 asm("mov %%db0, %0" :"=r" (val)); break;
59         case 1:
60                 asm("mov %%db1, %0" :"=r" (val)); break;
61         case 2:
62                 asm("mov %%db2, %0" :"=r" (val)); break;
63         case 3:
64                 asm("mov %%db3, %0" :"=r" (val)); break;
65         case 6:
66                 asm("mov %%db6, %0" :"=r" (val)); break;
67         case 7:
68                 asm("mov %%db7, %0" :"=r" (val)); break;
69         default:
70                 BUG();
71         }
72         return val;
73 }
74
75 static inline void native_set_debugreg(int regno, unsigned long value)
76 {
77         switch (regno) {
78         case 0:
79                 asm("mov %0,%%db0"      : /* no output */ :"r" (value));
80                 break;
81         case 1:
82                 asm("mov %0,%%db1"      : /* no output */ :"r" (value));
83                 break;
84         case 2:
85                 asm("mov %0,%%db2"      : /* no output */ :"r" (value));
86                 break;
87         case 3:
88                 asm("mov %0,%%db3"      : /* no output */ :"r" (value));
89                 break;
90         case 6:
91                 asm("mov %0,%%db6"      : /* no output */ :"r" (value));
92                 break;
93         case 7:
94                 asm("mov %0,%%db7"      : /* no output */ :"r" (value));
95                 break;
96         default:
97                 BUG();
98         }
99 }
100
101 /*
102  * Set IOPL bits in EFLAGS from given mask
103  */
104 static inline void native_set_iopl_mask(unsigned mask)
105 {
106 #ifdef CONFIG_X86_32
107         unsigned int reg;
108         __asm__ __volatile__ ("pushfl;"
109                               "popl %0;"
110                               "andl %1, %0;"
111                               "orl %2, %0;"
112                               "pushl %0;"
113                               "popfl"
114                                 : "=&r" (reg)
115                                 : "i" (~X86_EFLAGS_IOPL), "r" (mask));
116 #endif
117 }
118
119
120 #ifndef CONFIG_PARAVIRT
121 #define __cpuid native_cpuid
122 #define paravirt_enabled() 0
123
124 /*
125  * These special macros can be used to get or set a debugging register
126  */
127 #define get_debugreg(var, register)                             \
128         (var) = native_get_debugreg(register)
129 #define set_debugreg(value, register)                           \
130         native_set_debugreg(register, value)
131
132 #define set_iopl_mask native_set_iopl_mask
133 #endif /* CONFIG_PARAVIRT */
134
135 /*
136  * Save the cr4 feature set we're using (ie
137  * Pentium 4MB enable and PPro Global page
138  * enable), so that any CPU's that boot up
139  * after us can get the correct flags.
140  */
141 extern unsigned long mmu_cr4_features;
142
143 static inline void set_in_cr4(unsigned long mask)
144 {
145         unsigned cr4;
146         mmu_cr4_features |= mask;
147         cr4 = read_cr4();
148         cr4 |= mask;
149         write_cr4(cr4);
150 }
151
152 static inline void clear_in_cr4(unsigned long mask)
153 {
154         unsigned cr4;
155         mmu_cr4_features &= ~mask;
156         cr4 = read_cr4();
157         cr4 &= ~mask;
158         write_cr4(cr4);
159 }
160
161 struct microcode_header {
162         unsigned int hdrver;
163         unsigned int rev;
164         unsigned int date;
165         unsigned int sig;
166         unsigned int cksum;
167         unsigned int ldrver;
168         unsigned int pf;
169         unsigned int datasize;
170         unsigned int totalsize;
171         unsigned int reserved[3];
172 };
173
174 struct microcode {
175         struct microcode_header hdr;
176         unsigned int bits[0];
177 };
178
179 typedef struct microcode microcode_t;
180 typedef struct microcode_header microcode_header_t;
181
182 /* microcode format is extended from prescott processors */
183 struct extended_signature {
184         unsigned int sig;
185         unsigned int pf;
186         unsigned int cksum;
187 };
188
189 struct extended_sigtable {
190         unsigned int count;
191         unsigned int cksum;
192         unsigned int reserved[3];
193         struct extended_signature sigs[0];
194 };
195
196 /*
197  * create a kernel thread without removing it from tasklists
198  */
199 extern int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);
200
201 /* Free all resources held by a thread. */
202 extern void release_thread(struct task_struct *);
203
204 /* Prepare to copy thread state - unlazy all lazy status */
205 extern void prepare_to_copy(struct task_struct *tsk);
206
207 unsigned long get_wchan(struct task_struct *p);
208
209 /*
210  * Generic CPUID function
211  * clear %ecx since some cpus (Cyrix MII) do not set or clear %ecx
212  * resulting in stale register contents being returned.
213  */
214 static inline void cpuid(unsigned int op,
215                          unsigned int *eax, unsigned int *ebx,
216                          unsigned int *ecx, unsigned int *edx)
217 {
218         *eax = op;
219         *ecx = 0;
220         __cpuid(eax, ebx, ecx, edx);
221 }
222
223 /* Some CPUID calls want 'count' to be placed in ecx */
224 static inline void cpuid_count(unsigned int op, int count,
225                                unsigned int *eax, unsigned int *ebx,
226                                unsigned int *ecx, unsigned int *edx)
227 {
228         *eax = op;
229         *ecx = count;
230         __cpuid(eax, ebx, ecx, edx);
231 }
232
233 /*
234  * CPUID functions returning a single datum
235  */
236 static inline unsigned int cpuid_eax(unsigned int op)
237 {
238         unsigned int eax, ebx, ecx, edx;
239
240         cpuid(op, &eax, &ebx, &ecx, &edx);
241         return eax;
242 }
243 static inline unsigned int cpuid_ebx(unsigned int op)
244 {
245         unsigned int eax, ebx, ecx, edx;
246
247         cpuid(op, &eax, &ebx, &ecx, &edx);
248         return ebx;
249 }
250 static inline unsigned int cpuid_ecx(unsigned int op)
251 {
252         unsigned int eax, ebx, ecx, edx;
253
254         cpuid(op, &eax, &ebx, &ecx, &edx);
255         return ecx;
256 }
257 static inline unsigned int cpuid_edx(unsigned int op)
258 {
259         unsigned int eax, ebx, ecx, edx;
260
261         cpuid(op, &eax, &ebx, &ecx, &edx);
262         return edx;
263 }
264
265 /* REP NOP (PAUSE) is a good thing to insert into busy-wait loops. */
266 static inline void rep_nop(void)
267 {
268         __asm__ __volatile__("rep;nop": : :"memory");
269 }
270
271 /* Stop speculative execution */
272 static inline void sync_core(void)
273 {
274         int tmp;
275         asm volatile("cpuid" : "=a" (tmp) : "0" (1)
276                                           : "ebx", "ecx", "edx", "memory");
277 }
278
279 #define cpu_relax()   rep_nop()
280
281 static inline void __monitor(const void *eax, unsigned long ecx,
282                 unsigned long edx)
283 {
284         /* "monitor %eax,%ecx,%edx;" */
285         asm volatile(
286                 ".byte 0x0f,0x01,0xc8;"
287                 : :"a" (eax), "c" (ecx), "d"(edx));
288 }
289
290 static inline void __mwait(unsigned long eax, unsigned long ecx)
291 {
292         /* "mwait %eax,%ecx;" */
293         asm volatile(
294                 ".byte 0x0f,0x01,0xc9;"
295                 : :"a" (eax), "c" (ecx));
296 }
297
298 static inline void __sti_mwait(unsigned long eax, unsigned long ecx)
299 {
300         /* "mwait %eax,%ecx;" */
301         asm volatile(
302                 "sti; .byte 0x0f,0x01,0xc9;"
303                 : :"a" (eax), "c" (ecx));
304 }
305
306 extern void mwait_idle_with_hints(unsigned long eax, unsigned long ecx);
307
308 extern int force_mwait;
309
310 extern void select_idle_routine(const struct cpuinfo_x86 *c);
311
312 extern unsigned long boot_option_idle_override;
313
314 /* Boot loader type from the setup header */
315 extern int bootloader_type;
316 #define cache_line_size() (boot_cpu_data.x86_cache_alignment)
317
318 #define HAVE_ARCH_PICK_MMAP_LAYOUT 1
319 #define ARCH_HAS_PREFETCHW
320 #define ARCH_HAS_SPINLOCK_PREFETCH
321
322 #define spin_lock_prefetch(x)   prefetchw(x)
323 /* This decides where the kernel will search for a free chunk of vm
324  * space during mmap's.
325  */
326 #define TASK_UNMAPPED_BASE      (PAGE_ALIGN(TASK_SIZE / 3))
327
328 #define KSTK_EIP(task) (task_pt_regs(task)->ip)
329
330 #endif