1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
|
/*
* include/asm-i386/processor.h
*
* Copyright (C) 1994 Linus Torvalds
*/
#ifndef __ASM_I386_PROCESSOR_H
#define __ASM_I386_PROCESSOR_H
#include <asm/vm86.h>
#include <asm/math_emu.h>
/*
* System setup and hardware bug flags..
* [Note we don't test the 386 multiply bug or popad bug]
*/
extern char hard_math;
extern char x86; /* lower 4 bits */
extern char x86_vendor_id[13];
extern char x86_model; /* lower 4 bits */
extern char x86_mask; /* lower 4 bits */
extern int x86_capability; /* field of flags */
extern int fdiv_bug;
extern char ignore_irq13;
extern char wp_works_ok; /* doesn't work on a 386 */
extern char hlt_works_ok; /* problems on some 486Dx4's and old 386's */
extern int have_cpuid; /* We have a CPUID */
/*
* Bus types (default is ISA, but people can check others with these..)
*/
extern int EISA_bus;
extern int MCA_bus;
/* from system description table in BIOS. Mostly for MCA use, but
others may find it useful. */
extern unsigned int machine_id;
extern unsigned int machine_submodel_id;
extern unsigned int BIOS_revision;
/*
* User space process size: 3GB. This is hardcoded into a few places,
* so don't change it unless you know what you are doing.
*/
#define TASK_SIZE (0xC0000000UL)
/* This decides where the kernel will search for a free chunk of vm
* space during mmap's.
*/
#define TASK_UNMAPPED_BASE (TASK_SIZE / 3)
/*
* Size of io_bitmap in longwords: 32 is ports 0-0x3ff.
*/
#define IO_BITMAP_SIZE 32
struct i387_hard_struct {
long cwd;
long swd;
long twd;
long fip;
long fcs;
long foo;
long fos;
long st_space[20]; /* 8*10 bytes for each FP-reg = 80 bytes */
long status; /* software status information */
};
struct i387_soft_struct {
long cwd;
long swd;
long twd;
long fip;
long fcs;
long foo;
long fos;
long top;
struct fpu_reg regs[8]; /* 8*16 bytes for each FP-reg = 128 bytes */
unsigned char lookahead;
struct info *info;
unsigned long entry_eip;
};
union i387_union {
struct i387_hard_struct hard;
struct i387_soft_struct soft;
};
struct thread_struct {
unsigned short back_link,__blh;
unsigned long esp0;
unsigned short ss0,__ss0h;
unsigned long esp1;
unsigned short ss1,__ss1h;
unsigned long esp2;
unsigned short ss2,__ss2h;
unsigned long cr3;
unsigned long eip;
unsigned long eflags;
unsigned long eax,ecx,edx,ebx;
unsigned long esp;
unsigned long ebp;
unsigned long esi;
unsigned long edi;
unsigned short es, __esh;
unsigned short cs, __csh;
unsigned short ss, __ssh;
unsigned short ds, __dsh;
unsigned short fs, __fsh;
unsigned short gs, __gsh;
unsigned short ldt, __ldth;
unsigned short trace, bitmap;
unsigned long io_bitmap[IO_BITMAP_SIZE+1];
unsigned long tr;
unsigned long cr2, trap_no, error_code, segment;
/* floating point info */
union i387_union i387;
/* virtual 86 mode info */
struct vm86_struct * vm86_info;
unsigned long screen_bitmap;
unsigned long v86flags, v86mask, v86mode, saved_esp0;
};
#define INIT_MMAP \
{ &init_mm, 0, 0, PAGE_SHARED, VM_READ | VM_WRITE | VM_EXEC, NULL, &init_mm.mmap }
#define INIT_TSS { \
0,0, \
sizeof(init_stack) + (long) &init_stack, \
KERNEL_DS, 0, \
0,0,0,0,0,0, \
(long) &swapper_pg_dir - PAGE_OFFSET, \
0,0,0,0,0,0,0,0,0,0, \
USER_DS,0,USER_DS,0,USER_DS,0,USER_DS,0,USER_DS,0,USER_DS,0, \
_LDT(0),0, \
0, 0x8000, \
{~0, }, /* ioperm */ \
_TSS(0), 0, 0, 0, KERNEL_DS, \
{ { 0, }, }, /* 387 state */ \
NULL, 0, 0, 0, 0, 0 /* vm86_info */, \
}
#define start_thread(regs, new_eip, new_esp) do {\
unsigned long seg = USER_DS; \
__asm__("mov %w0,%%fs ; mov %w0,%%gs":"=r" (seg) :"0" (seg)); \
set_fs(seg); \
regs->xds = seg; \
regs->xes = seg; \
regs->xss = seg; \
regs->xcs = USER_CS; \
regs->eip = new_eip; \
regs->esp = new_esp; \
} while (0)
/* Free all resources held by a thread. */
extern void release_thread(struct task_struct *);
/*
* Return saved PC of a blocked thread.
*/
extern inline unsigned long thread_saved_pc(struct thread_struct *t)
{
return ((unsigned long *)t->esp)[3];
}
/* Allocation and freeing of basic task resources. */
/*
* NOTE! The task struct and the stack go together
*/
#define alloc_task_struct() \
((struct task_struct *) __get_free_pages(GFP_KERNEL,1,0))
#define free_task_struct(p) free_pages((unsigned long)(p),1)
#define init_task (init_task_union.task)
#define init_stack (init_task_union.stack)
/*
* Return_address is a replacement for __builtin_return_address(count)
* which on certain architectures cannot reasonably be implemented in GCC
* (MIPS, Alpha) or is unuseable with -fomit-frame-pointer (i386).
* Note that __builtin_return_address(x>=1) is forbidden because the GCC
* aborts compilation on some CPUs. It's simply not possible to unwind
* some CPU's stackframes.
*/
#define return_address() __builtin_return_address(0)
#endif /* __ASM_I386_PROCESSOR_H */
|