fa921aa1a93f64300b1b0a97825f2a3629b8375a
[sfrench/cifs-2.6.git] / include / asm-x86 / processor_32.h
1 /*
2  * Copyright (C) 1994 Linus Torvalds
3  */
4
5 #ifndef __ASM_I386_PROCESSOR_H
6 #define __ASM_I386_PROCESSOR_H
7
8 #include <asm/vm86.h>
9 #include <asm/math_emu.h>
10 #include <asm/segment.h>
11 #include <asm/page.h>
12 #include <asm/types.h>
13 #include <asm/sigcontext.h>
14 #include <asm/cpufeature.h>
15 #include <asm/msr.h>
16 #include <asm/system.h>
17 #include <linux/threads.h>
18 #include <linux/init.h>
19 #include <asm/desc_defs.h>
20
21 /*
22  * capabilities of CPUs
23  */
24 extern struct cpuinfo_x86 new_cpu_data;
25 extern struct tss_struct doublefault_tss;
26
27 /*
28  * the following now lives in the per cpu area:
29  * extern       int cpu_llc_id[NR_CPUS];
30  */
31 DECLARE_PER_CPU(u8, cpu_llc_id);
32 extern char ignore_fpu_irq;
33
34 void __init cpu_detect(struct cpuinfo_x86 *c);
35
36 extern void identify_boot_cpu(void);
37 extern void identify_secondary_cpu(struct cpuinfo_x86 *);
38
39 #ifdef CONFIG_X86_HT
40 extern void detect_ht(struct cpuinfo_x86 *c);
41 #else
42 static inline void detect_ht(struct cpuinfo_x86 *c) {}
43 #endif
44
45 /* from system description table in BIOS.  Mostly for MCA use, but
46 others may find it useful. */
47 extern unsigned int machine_id;
48 extern unsigned int machine_submodel_id;
49 extern unsigned int BIOS_revision;
50 extern unsigned int mca_pentium_flag;
51
52 /*
53  * User space process size: 3GB (default).
54  */
55 #define TASK_SIZE       (PAGE_OFFSET)
56
57
58 struct i387_fsave_struct {
59         long    cwd;
60         long    swd;
61         long    twd;
62         long    fip;
63         long    fcs;
64         long    foo;
65         long    fos;
66         long    st_space[20];   /* 8*10 bytes for each FP-reg = 80 bytes */
67         long    status;         /* software status information */
68 };
69
70 struct i387_fxsave_struct {
71         unsigned short  cwd;
72         unsigned short  swd;
73         unsigned short  twd;
74         unsigned short  fop;
75         long    fip;
76         long    fcs;
77         long    foo;
78         long    fos;
79         long    mxcsr;
80         long    mxcsr_mask;
81         long    st_space[32];   /* 8*16 bytes for each FP-reg = 128 bytes */
82         long    xmm_space[32];  /* 8*16 bytes for each XMM-reg = 128 bytes */
83         long    padding[56];
84 } __attribute__ ((aligned (16)));
85
86 struct i387_soft_struct {
87         long    cwd;
88         long    swd;
89         long    twd;
90         long    fip;
91         long    fcs;
92         long    foo;
93         long    fos;
94         long    st_space[20];   /* 8*10 bytes for each FP-reg = 80 bytes */
95         unsigned char   ftop, changed, lookahead, no_update, rm, alimit;
96         struct info     *info;
97         unsigned long   entry_eip;
98 };
99
100 union i387_union {
101         struct i387_fsave_struct        fsave;
102         struct i387_fxsave_struct       fxsave;
103         struct i387_soft_struct soft;
104 };
105
106 #define INIT_THREAD  {                                                  \
107         .sp0 = sizeof(init_stack) + (long)&init_stack,                  \
108         .vm86_info = NULL,                                              \
109         .sysenter_cs = __KERNEL_CS,                                     \
110         .io_bitmap_ptr = NULL,                                          \
111         .fs = __KERNEL_PERCPU,                                          \
112 }
113
114 /*
115  * Note that the .io_bitmap member must be extra-big. This is because
116  * the CPU will access an additional byte beyond the end of the IO
117  * permission bitmap. The extra byte must be all 1 bits, and must
118  * be within the limit.
119  */
120 #define INIT_TSS  {                                                     \
121         .x86_tss = {                                                    \
122                 .sp0            = sizeof(init_stack) + (long)&init_stack, \
123                 .ss0            = __KERNEL_DS,                          \
124                 .ss1            = __KERNEL_CS,                          \
125                 .io_bitmap_base = INVALID_IO_BITMAP_OFFSET,             \
126          },                                                             \
127         .io_bitmap      = { [ 0 ... IO_BITMAP_LONGS] = ~0 },            \
128 }
129
130 #define start_thread(regs, new_eip, new_esp) do {               \
131         __asm__("movl %0,%%gs": :"r" (0));                      \
132         regs->fs = 0;                                           \
133         set_fs(USER_DS);                                        \
134         regs->ds = __USER_DS;                                   \
135         regs->es = __USER_DS;                                   \
136         regs->ss = __USER_DS;                                   \
137         regs->cs = __USER_CS;                                   \
138         regs->ip = new_eip;                                     \
139         regs->sp = new_esp;                                     \
140 } while (0)
141
142
143 extern unsigned long thread_saved_pc(struct task_struct *tsk);
144
145 #define THREAD_SIZE_LONGS      (THREAD_SIZE/sizeof(unsigned long))
146 #define KSTK_TOP(info)                                                 \
147 ({                                                                     \
148        unsigned long *__ptr = (unsigned long *)(info);                 \
149        (unsigned long)(&__ptr[THREAD_SIZE_LONGS]);                     \
150 })
151
152 /*
153  * The below -8 is to reserve 8 bytes on top of the ring0 stack.
154  * This is necessary to guarantee that the entire "struct pt_regs"
155  * is accessable even if the CPU haven't stored the SS/ESP registers
156  * on the stack (interrupt gate does not save these registers
157  * when switching to the same priv ring).
158  * Therefore beware: accessing the ss/esp fields of the
159  * "struct pt_regs" is possible, but they may contain the
160  * completely wrong values.
161  */
162 #define task_pt_regs(task)                                             \
163 ({                                                                     \
164        struct pt_regs *__regs__;                                       \
165        __regs__ = (struct pt_regs *)(KSTK_TOP(task_stack_page(task))-8); \
166        __regs__ - 1;                                                   \
167 })
168
169 #define KSTK_ESP(task) (task_pt_regs(task)->sp)
170
171 /* generic versions from gas */
172 #define GENERIC_NOP1    ".byte 0x90\n"
173 #define GENERIC_NOP2            ".byte 0x89,0xf6\n"
174 #define GENERIC_NOP3        ".byte 0x8d,0x76,0x00\n"
175 #define GENERIC_NOP4        ".byte 0x8d,0x74,0x26,0x00\n"
176 #define GENERIC_NOP5        GENERIC_NOP1 GENERIC_NOP4
177 #define GENERIC_NOP6    ".byte 0x8d,0xb6,0x00,0x00,0x00,0x00\n"
178 #define GENERIC_NOP7    ".byte 0x8d,0xb4,0x26,0x00,0x00,0x00,0x00\n"
179 #define GENERIC_NOP8    GENERIC_NOP1 GENERIC_NOP7
180
181 /* Opteron nops */
182 #define K8_NOP1 GENERIC_NOP1
183 #define K8_NOP2 ".byte 0x66,0x90\n" 
184 #define K8_NOP3 ".byte 0x66,0x66,0x90\n" 
185 #define K8_NOP4 ".byte 0x66,0x66,0x66,0x90\n" 
186 #define K8_NOP5 K8_NOP3 K8_NOP2 
187 #define K8_NOP6 K8_NOP3 K8_NOP3
188 #define K8_NOP7 K8_NOP4 K8_NOP3
189 #define K8_NOP8 K8_NOP4 K8_NOP4
190
191 /* K7 nops */
192 /* uses eax dependencies (arbitary choice) */
193 #define K7_NOP1  GENERIC_NOP1
194 #define K7_NOP2 ".byte 0x8b,0xc0\n" 
195 #define K7_NOP3 ".byte 0x8d,0x04,0x20\n"
196 #define K7_NOP4 ".byte 0x8d,0x44,0x20,0x00\n"
197 #define K7_NOP5 K7_NOP4 ASM_NOP1
198 #define K7_NOP6 ".byte 0x8d,0x80,0,0,0,0\n"
199 #define K7_NOP7        ".byte 0x8D,0x04,0x05,0,0,0,0\n"
200 #define K7_NOP8        K7_NOP7 ASM_NOP1
201
202 /* P6 nops */
203 /* uses eax dependencies (Intel-recommended choice) */
204 #define P6_NOP1 GENERIC_NOP1
205 #define P6_NOP2 ".byte 0x66,0x90\n"
206 #define P6_NOP3 ".byte 0x0f,0x1f,0x00\n"
207 #define P6_NOP4 ".byte 0x0f,0x1f,0x40,0\n"
208 #define P6_NOP5 ".byte 0x0f,0x1f,0x44,0x00,0\n"
209 #define P6_NOP6 ".byte 0x66,0x0f,0x1f,0x44,0x00,0\n"
210 #define P6_NOP7 ".byte 0x0f,0x1f,0x80,0,0,0,0\n"
211 #define P6_NOP8 ".byte 0x0f,0x1f,0x84,0x00,0,0,0,0\n"
212
213 #ifdef CONFIG_MK8
214 #define ASM_NOP1 K8_NOP1
215 #define ASM_NOP2 K8_NOP2
216 #define ASM_NOP3 K8_NOP3
217 #define ASM_NOP4 K8_NOP4
218 #define ASM_NOP5 K8_NOP5
219 #define ASM_NOP6 K8_NOP6
220 #define ASM_NOP7 K8_NOP7
221 #define ASM_NOP8 K8_NOP8
222 #elif defined(CONFIG_MK7)
223 #define ASM_NOP1 K7_NOP1
224 #define ASM_NOP2 K7_NOP2
225 #define ASM_NOP3 K7_NOP3
226 #define ASM_NOP4 K7_NOP4
227 #define ASM_NOP5 K7_NOP5
228 #define ASM_NOP6 K7_NOP6
229 #define ASM_NOP7 K7_NOP7
230 #define ASM_NOP8 K7_NOP8
231 #elif defined(CONFIG_M686) || defined(CONFIG_MPENTIUMII) || \
232       defined(CONFIG_MPENTIUMIII) || defined(CONFIG_MPENTIUMM) || \
233       defined(CONFIG_MCORE2) || defined(CONFIG_PENTIUM4)
234 #define ASM_NOP1 P6_NOP1
235 #define ASM_NOP2 P6_NOP2
236 #define ASM_NOP3 P6_NOP3
237 #define ASM_NOP4 P6_NOP4
238 #define ASM_NOP5 P6_NOP5
239 #define ASM_NOP6 P6_NOP6
240 #define ASM_NOP7 P6_NOP7
241 #define ASM_NOP8 P6_NOP8
242 #else
243 #define ASM_NOP1 GENERIC_NOP1
244 #define ASM_NOP2 GENERIC_NOP2
245 #define ASM_NOP3 GENERIC_NOP3
246 #define ASM_NOP4 GENERIC_NOP4
247 #define ASM_NOP5 GENERIC_NOP5
248 #define ASM_NOP6 GENERIC_NOP6
249 #define ASM_NOP7 GENERIC_NOP7
250 #define ASM_NOP8 GENERIC_NOP8
251 #endif
252
253 #define ASM_NOP_MAX 8
254
255 /* Prefetch instructions for Pentium III and AMD Athlon */
256 /* It's not worth to care about 3dnow! prefetches for the K6
257    because they are microcoded there and very slow.
258    However we don't do prefetches for pre XP Athlons currently
259    That should be fixed. */
260 static inline void prefetch(const void *x)
261 {
262         alternative_input(ASM_NOP4,
263                           "prefetchnta (%1)",
264                           X86_FEATURE_XMM,
265                           "r" (x));
266 }
267
268 #define ARCH_HAS_PREFETCH
269
270 /* 3dnow! prefetch to get an exclusive cache line. Useful for 
271    spinlocks to avoid one state transition in the cache coherency protocol. */
272 static inline void prefetchw(const void *x)
273 {
274         alternative_input(ASM_NOP4,
275                           "prefetchw (%1)",
276                           X86_FEATURE_3DNOW,
277                           "r" (x));
278 }
279
280 extern void enable_sep_cpu(void);
281 extern int sysenter_setup(void);
282
283 /* Defined in head.S */
284 extern struct desc_ptr early_gdt_descr;
285
286 extern void cpu_set_gdt(int);
287 extern void switch_to_new_gdt(void);
288 extern void cpu_init(void);
289 extern void init_gdt(int cpu);
290
291 #endif /* __ASM_I386_PROCESSOR_H */