summaryrefslogtreecommitdiffstats
path: root/include/asm-i386/processor.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/asm-i386/processor.h')
-rw-r--r--include/asm-i386/processor.h120
1 files changed, 90 insertions, 30 deletions
diff --git a/include/asm-i386/processor.h b/include/asm-i386/processor.h
index dde35a87c..99b291d40 100644
--- a/include/asm-i386/processor.h
+++ b/include/asm-i386/processor.h
@@ -12,6 +12,7 @@
#include <asm/segment.h>
#include <asm/page.h>
#include <asm/types.h>
+#include <linux/threads.h>
/*
* Default implementation of macro that returns current
@@ -95,6 +96,7 @@ struct cpuinfo_x86 {
#define X86_FEATURE_AMD3D 0x80000000
extern struct cpuinfo_x86 boot_cpu_data;
+extern struct tss_struct init_tss[NR_CPUS];
#ifdef __SMP__
extern struct cpuinfo_x86 cpu_data[];
@@ -124,6 +126,48 @@ extern inline void cpuid(int op, int *eax, int *ebx, int *ecx, int *edx)
: "cc");
}
+
+/*
+ * Intel CPU features in CR4
+ */
+#define X86_CR4_VME 0x0001 /* enable vm86 extensions */
+#define X86_CR4_PVI 0x0002 /* virtual interrupts flag enable */
+#define X86_CR4_TSD 0x0004 /* disable time stamp at ipl 3 */
+#define X86_CR4_DE 0x0008 /* enable debugging extensions */
+#define X86_CR4_PSE 0x0010 /* enable page size extensions */
+#define X86_CR4_PAE 0x0020 /* enable physical address extensions */
+#define X86_CR4_MCE 0x0040 /* Machine check enable */
+#define X86_CR4_PGE 0x0080 /* enable global pages */
+#define X86_CR4_PCE 0x0100 /* enable performance counters at ipl 3 */
+
+/*
+ * Save the cr4 feature set we're using (ie
+ * Pentium 4MB enable and PPro Global page
+ * enable), so that any CPU's that boot up
+ * after us can get the correct flags.
+ */
+extern unsigned long mmu_cr4_features;
+
+static inline void set_in_cr4 (unsigned long mask)
+{
+ mmu_cr4_features |= mask;
+ __asm__("movl %%cr4,%%eax\n\t"
+ "orl %0,%%eax\n\t"
+ "movl %%eax,%%cr4\n"
+ : : "irg" (mask)
+ :"ax");
+}
+
+static inline void clear_in_cr4 (unsigned long mask)
+{
+ mmu_cr4_features &= ~mask;
+ __asm__("movl %%cr4,%%eax\n\t"
+ "andl %0,%%eax\n\t"
+ "movl %%eax,%%cr4\n"
+ : : "irg" (~mask)
+ :"ax");
+}
+
/*
* Cyrix CPU configuration register indexes
*/
@@ -177,6 +221,8 @@ extern unsigned int mca_pentium_flag;
* Size of io_bitmap in longwords: 32 is ports 0-0x3ff.
*/
#define IO_BITMAP_SIZE 32
+#define IO_BITMAP_OFFSET offsetof(struct tss_struct,io_bitmap)
+#define INVALID_IO_BITMAP_OFFSET 0x8000
struct i387_hard_struct {
long cwd;
@@ -213,7 +259,7 @@ typedef struct {
unsigned long seg;
} mm_segment_t;
-struct thread_struct {
+struct tss_struct {
unsigned short back_link,__blh;
unsigned long esp0;
unsigned short ss0,__ss0h;
@@ -221,7 +267,7 @@ struct thread_struct {
unsigned short ss1,__ss1h;
unsigned long esp2;
unsigned short ss2,__ss2h;
- unsigned long cr3;
+ unsigned long __cr3;
unsigned long eip;
unsigned long eflags;
unsigned long eax,ecx,edx,ebx;
@@ -238,19 +284,43 @@ struct thread_struct {
unsigned short ldt, __ldth;
unsigned short trace, bitmap;
unsigned long io_bitmap[IO_BITMAP_SIZE+1];
- unsigned long tr;
+ /*
+ * pads the TSS to be cacheline-aligned (size is 0x100)
+ */
+ unsigned long __cacheline_filler[5];
+};
+
+struct thread_struct {
+ unsigned long esp0;
+ unsigned long eip;
+ unsigned long esp;
+ unsigned long fs;
+ unsigned long gs;
+/* Hardware debugging registers */
+ unsigned long debugreg[8]; /* %%db0-7 debug registers */
+/* fault info */
unsigned long cr2, trap_no, error_code;
- mm_segment_t segment;
-/* debug registers */
- long debugreg[8]; /* Hardware debugging registers */
/* floating point info */
- union i387_union i387;
+ union i387_union i387;
/* virtual 86 mode info */
- struct vm86_struct * vm86_info;
- unsigned long screen_bitmap;
- unsigned long v86flags, v86mask, v86mode, saved_esp0;
+ struct vm86_struct * vm86_info;
+ unsigned long screen_bitmap;
+ unsigned long v86flags, v86mask, v86mode, saved_esp0;
+/* IO permissions */
+ int ioperm;
+ unsigned long io_bitmap[IO_BITMAP_SIZE+1];
};
+#define INIT_THREAD { \
+ 0, \
+ 0, 0, 0, 0, \
+ { [0 ... 7] = 0 }, /* debugging registers */ \
+ 0, 0, 0, \
+ { { 0, }, }, /* 387 state */ \
+ 0,0,0,0,0,0, \
+ 0,{~0,} /* io permissions */ \
+}
+
#define INIT_MMAP \
{ &init_mm, 0, 0, NULL, PAGE_SHARED, VM_READ | VM_WRITE | VM_EXEC, 1, NULL, NULL }
@@ -259,19 +329,15 @@ struct thread_struct {
sizeof(init_stack) + (long) &init_stack, /* esp0 */ \
__KERNEL_DS, 0, /* ss0 */ \
0,0,0,0,0,0, /* stack1, stack2 */ \
- (long) &swapper_pg_dir - PAGE_OFFSET, /* cr3 */ \
+ 0, /* cr3 */ \
0,0, /* eip,eflags */ \
0,0,0,0, /* eax,ecx,edx,ebx */ \
0,0,0,0, /* esp,ebp,esi,edi */ \
0,0,0,0,0,0, /* es,cs,ss */ \
0,0,0,0,0,0, /* ds,fs,gs */ \
- _LDT(0),0, /* ldt */ \
- 0, 0x8000, /* tace, bitmap */ \
- {~0, }, /* ioperm */ \
- _TSS(0), 0, 0, 0, (mm_segment_t) { 0 }, /* obsolete */ \
- { 0, }, \
- { { 0, }, }, /* 387 state */ \
- NULL, 0, 0, 0, 0, 0, /* vm86_info */ \
+ __LDT(0),0, /* ldt */ \
+ 0, INVALID_IO_BITMAP_OFFSET, /* tace, bitmap */ \
+ {~0, } /* ioperm */ \
}
#define start_thread(regs, new_eip, new_esp) do { \
@@ -291,10 +357,13 @@ struct mm_struct;
/* Free all resources held by a thread. */
extern void release_thread(struct task_struct *);
+/*
+ * create a kernel thread without removing it from tasklists
+ */
extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
/* Copy and release all segment info associated with a VM */
-extern void copy_segments(int nr, struct task_struct *p, struct mm_struct * mm);
+extern void copy_segments(struct task_struct *p, struct mm_struct * mm);
extern void release_segments(struct mm_struct * mm);
extern void forget_segments(void);
@@ -302,7 +371,7 @@ extern void forget_segments(void);
* FPU lazy state save handling..
*/
#define save_fpu(tsk) do { \
- asm volatile("fnsave %0\n\tfwait":"=m" (tsk->tss.i387)); \
+ asm volatile("fnsave %0\n\tfwait":"=m" (tsk->thread.i387)); \
tsk->flags &= ~PF_USEDFPU; \
stts(); \
} while (0)
@@ -327,20 +396,11 @@ extern inline unsigned long thread_saved_pc(struct thread_struct *t)
return ((unsigned long *)t->esp)[3];
}
+#define THREAD_SIZE (2*PAGE_SIZE)
extern struct task_struct * alloc_task_struct(void);
extern void free_task_struct(struct task_struct *);
#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 */