diff options
Diffstat (limited to 'include/asm-i386/processor.h')
-rw-r--r-- | include/asm-i386/processor.h | 120 |
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 */ |