82fafabbfe7a99055d463c4fb0ba1bb687d0f301
[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  * the following now lives in the per cpu area:
23  * extern       int cpu_llc_id[NR_CPUS];
24  */
25 DECLARE_PER_CPU(u8, cpu_llc_id);
26
27 /*
28  * User space process size: 3GB (default).
29  */
30 #define TASK_SIZE       (PAGE_OFFSET)
31
32
33 struct i387_fsave_struct {
34         long    cwd;
35         long    swd;
36         long    twd;
37         long    fip;
38         long    fcs;
39         long    foo;
40         long    fos;
41         long    st_space[20];   /* 8*10 bytes for each FP-reg = 80 bytes */
42         long    status;         /* software status information */
43 };
44
45 struct i387_fxsave_struct {
46         unsigned short  cwd;
47         unsigned short  swd;
48         unsigned short  twd;
49         unsigned short  fop;
50         long    fip;
51         long    fcs;
52         long    foo;
53         long    fos;
54         long    mxcsr;
55         long    mxcsr_mask;
56         long    st_space[32];   /* 8*16 bytes for each FP-reg = 128 bytes */
57         long    xmm_space[32];  /* 8*16 bytes for each XMM-reg = 128 bytes */
58         long    padding[56];
59 } __attribute__ ((aligned (16)));
60
61 struct i387_soft_struct {
62         long    cwd;
63         long    swd;
64         long    twd;
65         long    fip;
66         long    fcs;
67         long    foo;
68         long    fos;
69         long    st_space[20];   /* 8*10 bytes for each FP-reg = 80 bytes */
70         unsigned char   ftop, changed, lookahead, no_update, rm, alimit;
71         struct info     *info;
72         unsigned long   entry_eip;
73 };
74
75 union i387_union {
76         struct i387_fsave_struct        fsave;
77         struct i387_fxsave_struct       fxsave;
78         struct i387_soft_struct soft;
79 };
80
81 #define INIT_THREAD  {                                                  \
82         .sp0 = sizeof(init_stack) + (long)&init_stack,                  \
83         .vm86_info = NULL,                                              \
84         .sysenter_cs = __KERNEL_CS,                                     \
85         .io_bitmap_ptr = NULL,                                          \
86         .fs = __KERNEL_PERCPU,                                          \
87 }
88
89 /*
90  * Note that the .io_bitmap member must be extra-big. This is because
91  * the CPU will access an additional byte beyond the end of the IO
92  * permission bitmap. The extra byte must be all 1 bits, and must
93  * be within the limit.
94  */
95 #define INIT_TSS  {                                                     \
96         .x86_tss = {                                                    \
97                 .sp0            = sizeof(init_stack) + (long)&init_stack, \
98                 .ss0            = __KERNEL_DS,                          \
99                 .ss1            = __KERNEL_CS,                          \
100                 .io_bitmap_base = INVALID_IO_BITMAP_OFFSET,             \
101          },                                                             \
102         .io_bitmap      = { [ 0 ... IO_BITMAP_LONGS] = ~0 },            \
103 }
104
105 #define start_thread(regs, new_eip, new_esp) do {               \
106         __asm__("movl %0,%%gs": :"r" (0));                      \
107         regs->fs = 0;                                           \
108         set_fs(USER_DS);                                        \
109         regs->ds = __USER_DS;                                   \
110         regs->es = __USER_DS;                                   \
111         regs->ss = __USER_DS;                                   \
112         regs->cs = __USER_CS;                                   \
113         regs->ip = new_eip;                                     \
114         regs->sp = new_esp;                                     \
115 } while (0)
116
117
118 extern unsigned long thread_saved_pc(struct task_struct *tsk);
119
120 #define THREAD_SIZE_LONGS      (THREAD_SIZE/sizeof(unsigned long))
121 #define KSTK_TOP(info)                                                 \
122 ({                                                                     \
123        unsigned long *__ptr = (unsigned long *)(info);                 \
124        (unsigned long)(&__ptr[THREAD_SIZE_LONGS]);                     \
125 })
126
127 /*
128  * The below -8 is to reserve 8 bytes on top of the ring0 stack.
129  * This is necessary to guarantee that the entire "struct pt_regs"
130  * is accessable even if the CPU haven't stored the SS/ESP registers
131  * on the stack (interrupt gate does not save these registers
132  * when switching to the same priv ring).
133  * Therefore beware: accessing the ss/esp fields of the
134  * "struct pt_regs" is possible, but they may contain the
135  * completely wrong values.
136  */
137 #define task_pt_regs(task)                                             \
138 ({                                                                     \
139        struct pt_regs *__regs__;                                       \
140        __regs__ = (struct pt_regs *)(KSTK_TOP(task_stack_page(task))-8); \
141        __regs__ - 1;                                                   \
142 })
143
144 #define KSTK_ESP(task) (task_pt_regs(task)->sp)
145
146 #endif /* __ASM_I386_PROCESSOR_H */