From 825423e4c4f18289df2393951cfd2a7a31fc0464 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Wed, 31 Jan 2001 22:22:27 +0000 Subject: Merge with Linux 2.4.1. --- arch/i386/Makefile | 2 +- arch/i386/boot/bootsect.S | 13 +++--- arch/i386/config.in | 14 ++---- arch/i386/defconfig | 17 +++++-- arch/i386/kernel/i387.c | 71 +++++++++++++++------------- arch/i386/kernel/io_apic.c | 5 +- arch/i386/kernel/pci-irq.c | 113 ++++++++++++++++++++++++++++++++++++++------- arch/i386/kernel/setup.c | 24 +++++++--- arch/i386/kernel/signal.c | 2 - arch/i386/kernel/traps.c | 1 + arch/i386/lib/mmx.c | 34 ++++---------- arch/i386/mm/init.c | 12 ++--- 12 files changed, 197 insertions(+), 111 deletions(-) (limited to 'arch/i386') diff --git a/arch/i386/Makefile b/arch/i386/Makefile index 25b523026..f7941bcbe 100644 --- a/arch/i386/Makefile +++ b/arch/i386/Makefile @@ -50,7 +50,7 @@ ifdef CONFIG_M686 CFLAGS += -march=i686 endif -ifdef CONFIG_M686FXSR +ifdef CONFIG_MPENTIUMIII CFLAGS += -march=i686 endif diff --git a/arch/i386/boot/bootsect.S b/arch/i386/boot/bootsect.S index 26c67d5fd..5434a9df2 100644 --- a/arch/i386/boot/bootsect.S +++ b/arch/i386/boot/bootsect.S @@ -25,10 +25,9 @@ * loads pretty fast by getting whole tracks at a time whenever possible. */ -#include /* for CONFIG_ROOT_RDONLY */ #include -SETUPSECS = 4 /* default nr of setup-sectors */ +SETUPSECTS = 4 /* default nr of setup-sectors */ BOOTSEG = 0x07C0 /* original address of boot-sector */ INITSEG = DEF_INITSEG /* we move boot here - out of the way */ SETUPSEG = DEF_SETUPSEG /* setup starts here */ @@ -46,8 +45,8 @@ SWAP_DEV = 0 /* SWAP_DEV is now written by "build" */ #define RAMDISK 0 #endif -#ifndef CONFIG_ROOT_RDONLY -#define CONFIG_ROOT_RDONLY 1 +#ifndef ROOT_RDONLY +#define ROOT_RDONLY 1 #endif .code16 @@ -394,11 +393,11 @@ disksizes: .byte 36, 18, 15, 9 msg1: .byte 13, 10 .ascii "Loading" -# XXX: This is a *very* snug fit. +# XXX: This is a fairly snug fit. .org 497 -setup_sects: .byte SETUPSECS -root_flags: .word CONFIG_ROOT_RDONLY +setup_sects: .byte SETUPSECTS +root_flags: .word ROOT_RDONLY syssize: .word SYSSIZE swap_dev: .word SWAP_DEV ram_size: .word RAMDISK diff --git a/arch/i386/config.in b/arch/i386/config.in index 4dc863995..2dec3d90b 100644 --- a/arch/i386/config.in +++ b/arch/i386/config.in @@ -33,7 +33,7 @@ choice 'Processor family' \ Pentium-Classic CONFIG_M586TSC \ Pentium-MMX CONFIG_M586MMX \ Pentium-Pro/Celeron/Pentium-II CONFIG_M686 \ - Pentium-III CONFIG_M686FXSR \ + Pentium-III CONFIG_MPENTIUMIII \ Pentium-4 CONFIG_MPENTIUM4 \ K6/K6-II/K6-III CONFIG_MK6 \ Athlon/K7 CONFIG_MK7 \ @@ -45,8 +45,6 @@ choice 'Processor family' \ # Define implied options from the CPU selection here # -unset CONFIG_X86_FXSR - if [ "$CONFIG_M386" = "y" ]; then define_bool CONFIG_X86_CMPXCHG n define_int CONFIG_X86_L1_CACHE_SHIFT 4 @@ -87,14 +85,12 @@ if [ "$CONFIG_M686" = "y" ]; then define_bool CONFIG_X86_PGE y define_bool CONFIG_X86_USE_PPRO_CHECKSUM y fi -if [ "$CONFIG_M686FXSR" = "y" ]; then +if [ "$CONFIG_MPENTIUMIII" = "y" ]; then define_int CONFIG_X86_L1_CACHE_SHIFT 5 define_bool CONFIG_X86_TSC y define_bool CONFIG_X86_GOOD_APIC y define_bool CONFIG_X86_PGE y define_bool CONFIG_X86_USE_PPRO_CHECKSUM y - define_bool CONFIG_X86_FXSR y - define_bool CONFIG_X86_XMM y fi if [ "$CONFIG_MPENTIUM4" = "y" ]; then define_int CONFIG_X86_L1_CACHE_SHIFT 7 @@ -102,8 +98,6 @@ if [ "$CONFIG_MPENTIUM4" = "y" ]; then define_bool CONFIG_X86_GOOD_APIC y define_bool CONFIG_X86_PGE y define_bool CONFIG_X86_USE_PPRO_CHECKSUM y - define_bool CONFIG_X86_FXSR y - define_bool CONFIG_X86_XMM y fi if [ "$CONFIG_MK6" = "y" ]; then define_int CONFIG_X86_L1_CACHE_SHIFT 5 @@ -158,9 +152,7 @@ if [ "$CONFIG_HIGHMEM64G" = "y" ]; then define_bool CONFIG_X86_PAE y fi -if [ "$CONFIG_X86_FXSR" != "y" ]; then - bool 'Math emulation' CONFIG_MATH_EMULATION -fi +bool 'Math emulation' CONFIG_MATH_EMULATION bool 'MTRR (Memory Type Range Register) support' CONFIG_MTRR bool 'Symmetric multi-processing support' CONFIG_SMP if [ "$CONFIG_SMP" != "y" ]; then diff --git a/arch/i386/defconfig b/arch/i386/defconfig index de38a46ef..05a2e3725 100644 --- a/arch/i386/defconfig +++ b/arch/i386/defconfig @@ -27,7 +27,7 @@ CONFIG_KMOD=y # CONFIG_M586TSC is not set # CONFIG_M586MMX is not set # CONFIG_M686 is not set -CONFIG_M686FXSR=y +CONFIG_MPENTIUMIII=y # CONFIG_MPENTIUM4 is not set # CONFIG_MK6 is not set # CONFIG_MK7 is not set @@ -45,8 +45,6 @@ CONFIG_X86_TSC=y CONFIG_X86_GOOD_APIC=y CONFIG_X86_PGE=y CONFIG_X86_USE_PPRO_CHECKSUM=y -CONFIG_X86_FXSR=y -CONFIG_X86_XMM=y # CONFIG_TOSHIBA is not set # CONFIG_MICROCODE is not set # CONFIG_X86_MSR is not set @@ -54,6 +52,7 @@ CONFIG_X86_XMM=y CONFIG_NOHIGHMEM=y # CONFIG_HIGHMEM4G is not set # CONFIG_HIGHMEM64G is not set +# CONFIG_MATH_EMULATION is not set # CONFIG_MTRR is not set CONFIG_SMP=y CONFIG_HAVE_DEC_LOCK=y @@ -134,7 +133,6 @@ CONFIG_BLK_DEV_FD=y # CONFIG_MD_RAID1 is not set # CONFIG_MD_RAID5 is not set # CONFIG_BLK_DEV_LVM is not set -# CONFIG_LVM_PROC_FS is not set # # Networking options @@ -512,11 +510,18 @@ CONFIG_PSMOUSE=y # Ftape, the floppy tape device driver # # CONFIG_FTAPE is not set -# CONFIG_AGP is not set +CONFIG_AGP=y +CONFIG_AGP_INTEL=y +CONFIG_AGP_I810=y +CONFIG_AGP_VIA=y +CONFIG_AGP_AMD=y +CONFIG_AGP_SIS=y +CONFIG_AGP_ALI=y CONFIG_DRM=y CONFIG_DRM_TDFX=y # CONFIG_DRM_GAMMA is not set # CONFIG_DRM_R128 is not set +CONFIG_DRM_RADEON=y # CONFIG_DRM_I810 is not set # CONFIG_DRM_MGA is not set CONFIG_PCMCIA_SERIAL=y @@ -538,6 +543,8 @@ CONFIG_PCMCIA_SERIAL=y # CONFIG_QUOTA is not set # CONFIG_AUTOFS_FS is not set CONFIG_AUTOFS4_FS=y +# CONFIG_REISERFS_FS is not set +# CONFIG_REISERFS_CHECK is not set # CONFIG_ADFS_FS is not set # CONFIG_ADFS_FS_RW is not set # CONFIG_AFFS_FS is not set diff --git a/arch/i386/kernel/i387.c b/arch/i386/kernel/i387.c index 3031432d0..a3a526b4b 100644 --- a/arch/i386/kernel/i387.c +++ b/arch/i386/kernel/i387.c @@ -18,14 +18,6 @@ #include #include -#if defined(CONFIG_X86_FXSR) -#define HAVE_FXSR 1 -#elif defined(CONFIG_X86_RUNTIME_FXSR) -#define HAVE_FXSR (cpu_has_fxsr) -#else -#define HAVE_FXSR 0 -#endif - #ifdef CONFIG_MATH_EMULATION #define HAVE_HWFP (boot_cpu_data.hard_math) #else @@ -35,13 +27,13 @@ /* * The _current_ task is using the FPU for the first time * so initialize it and set the mxcsr to its default - * value at reset if we support FXSR and then + * value at reset if we support XMM instructions and then * remeber the current task has used the FPU. */ void init_fpu(void) { __asm__("fninit"); - if ( HAVE_FXSR ) + if ( cpu_has_xmm ) load_mxcsr(0x1f80); current->used_math = 1; @@ -51,9 +43,9 @@ void init_fpu(void) * FPU lazy state save handling. */ -void save_init_fpu( struct task_struct *tsk ) +static inline void __save_init_fpu( struct task_struct *tsk ) { - if ( HAVE_FXSR ) { + if ( cpu_has_fxsr ) { asm volatile( "fxsave %0 ; fnclex" : "=m" (tsk->thread.i387.fxsave) ); } else { @@ -61,12 +53,28 @@ void save_init_fpu( struct task_struct *tsk ) : "=m" (tsk->thread.i387.fsave) ); } tsk->flags &= ~PF_USEDFPU; +} + +void save_init_fpu( struct task_struct *tsk ) +{ + __save_init_fpu(tsk); stts(); } +void kernel_fpu_begin(void) +{ + struct task_struct *tsk = current; + + if (tsk->flags & PF_USEDFPU) { + __save_init_fpu(tsk); + return; + } + clts(); +} + void restore_fpu( struct task_struct *tsk ) { - if ( HAVE_FXSR ) { + if ( cpu_has_fxsr ) { asm volatile( "fxrstor %0" : : "m" (tsk->thread.i387.fxsave) ); } else { @@ -144,7 +152,7 @@ static inline unsigned long twd_fxsr_to_i387( struct i387_fxsave_struct *fxsave unsigned short get_fpu_cwd( struct task_struct *tsk ) { - if ( HAVE_FXSR ) { + if ( cpu_has_fxsr ) { return tsk->thread.i387.fxsave.cwd; } else { return (unsigned short)tsk->thread.i387.fsave.cwd; @@ -153,7 +161,7 @@ unsigned short get_fpu_cwd( struct task_struct *tsk ) unsigned short get_fpu_swd( struct task_struct *tsk ) { - if ( HAVE_FXSR ) { + if ( cpu_has_fxsr ) { return tsk->thread.i387.fxsave.swd; } else { return (unsigned short)tsk->thread.i387.fsave.swd; @@ -162,7 +170,7 @@ unsigned short get_fpu_swd( struct task_struct *tsk ) unsigned short get_fpu_twd( struct task_struct *tsk ) { - if ( HAVE_FXSR ) { + if ( cpu_has_fxsr ) { return tsk->thread.i387.fxsave.twd; } else { return (unsigned short)tsk->thread.i387.fsave.twd; @@ -171,7 +179,7 @@ unsigned short get_fpu_twd( struct task_struct *tsk ) unsigned short get_fpu_mxcsr( struct task_struct *tsk ) { - if ( HAVE_FXSR ) { + if ( cpu_has_fxsr ) { return tsk->thread.i387.fxsave.mxcsr; } else { return 0x1f80; @@ -180,7 +188,7 @@ unsigned short get_fpu_mxcsr( struct task_struct *tsk ) void set_fpu_cwd( struct task_struct *tsk, unsigned short cwd ) { - if ( HAVE_FXSR ) { + if ( cpu_has_fxsr ) { tsk->thread.i387.fxsave.cwd = cwd; } else { tsk->thread.i387.fsave.cwd = ((long)cwd | 0xffff0000); @@ -189,7 +197,7 @@ void set_fpu_cwd( struct task_struct *tsk, unsigned short cwd ) void set_fpu_swd( struct task_struct *tsk, unsigned short swd ) { - if ( HAVE_FXSR ) { + if ( cpu_has_fxsr ) { tsk->thread.i387.fxsave.swd = swd; } else { tsk->thread.i387.fsave.swd = ((long)swd | 0xffff0000); @@ -198,7 +206,7 @@ void set_fpu_swd( struct task_struct *tsk, unsigned short swd ) void set_fpu_twd( struct task_struct *tsk, unsigned short twd ) { - if ( HAVE_FXSR ) { + if ( cpu_has_fxsr ) { tsk->thread.i387.fxsave.twd = twd_i387_to_fxsr(twd); } else { tsk->thread.i387.fsave.twd = ((long)twd | 0xffff0000); @@ -207,7 +215,7 @@ void set_fpu_twd( struct task_struct *tsk, unsigned short twd ) void set_fpu_mxcsr( struct task_struct *tsk, unsigned short mxcsr ) { - if ( HAVE_FXSR ) { + if ( cpu_has_xmm ) { tsk->thread.i387.fxsave.mxcsr = mxcsr; } } @@ -321,7 +329,7 @@ int save_i387( struct _fpstate *buf ) current->used_math = 0; if ( HAVE_HWFP ) { - if ( HAVE_FXSR ) { + if ( cpu_has_fxsr ) { return save_i387_fxsave( buf ); } else { return save_i387_fsave( buf ); @@ -354,7 +362,7 @@ int restore_i387( struct _fpstate *buf ) int err; if ( HAVE_HWFP ) { - if ( HAVE_FXSR ) { + if ( cpu_has_fxsr ) { err = restore_i387_fxsave( buf ); } else { err = restore_i387_fsave( buf ); @@ -387,7 +395,7 @@ static inline int get_fpregs_fxsave( struct user_i387_struct *buf, int get_fpregs( struct user_i387_struct *buf, struct task_struct *tsk ) { if ( HAVE_HWFP ) { - if ( HAVE_FXSR ) { + if ( cpu_has_fxsr ) { return get_fpregs_fxsave( buf, tsk ); } else { return get_fpregs_fsave( buf, tsk ); @@ -415,7 +423,7 @@ static inline int set_fpregs_fxsave( struct task_struct *tsk, int set_fpregs( struct task_struct *tsk, struct user_i387_struct *buf ) { if ( HAVE_HWFP ) { - if ( HAVE_FXSR ) { + if ( cpu_has_fxsr ) { return set_fpregs_fxsave( tsk, buf ); } else { return set_fpregs_fsave( tsk, buf ); @@ -428,9 +436,10 @@ int set_fpregs( struct task_struct *tsk, struct user_i387_struct *buf ) int get_fpxregs( struct user_fxsr_struct *buf, struct task_struct *tsk ) { - if ( HAVE_FXSR ) { - __copy_to_user( (void *)buf, &tsk->thread.i387.fxsave, - sizeof(struct user_fxsr_struct) ); + if ( cpu_has_fxsr ) { + if (__copy_to_user( (void *)buf, &tsk->thread.i387.fxsave, + sizeof(struct user_fxsr_struct) )) + return -EFAULT; return 0; } else { return -EIO; @@ -439,7 +448,7 @@ int get_fpxregs( struct user_fxsr_struct *buf, struct task_struct *tsk ) int set_fpxregs( struct task_struct *tsk, struct user_fxsr_struct *buf ) { - if ( HAVE_FXSR ) { + if ( cpu_has_fxsr ) { __copy_from_user( &tsk->thread.i387.fxsave, (void *)buf, sizeof(struct user_fxsr_struct) ); /* mxcsr bit 6 and 31-16 must be zero for security reasons */ @@ -485,7 +494,7 @@ int dump_fpu( struct pt_regs *regs, struct user_i387_struct *fpu ) fpvalid = tsk->used_math; if ( fpvalid ) { unlazy_fpu( tsk ); - if ( HAVE_FXSR ) { + if ( cpu_has_fxsr ) { copy_fpu_fxsave( tsk, fpu ); } else { copy_fpu_fsave( tsk, fpu ); @@ -500,7 +509,7 @@ int dump_extended_fpu( struct pt_regs *regs, struct user_fxsr_struct *fpu ) int fpvalid; struct task_struct *tsk = current; - fpvalid = tsk->used_math && HAVE_FXSR; + fpvalid = tsk->used_math && cpu_has_fxsr; if ( fpvalid ) { unlazy_fpu( tsk ); memcpy( fpu, &tsk->thread.i387.fxsave, diff --git a/arch/i386/kernel/io_apic.c b/arch/i386/kernel/io_apic.c index c5aece040..b17f499b4 100644 --- a/arch/i386/kernel/io_apic.c +++ b/arch/i386/kernel/io_apic.c @@ -253,7 +253,8 @@ static int __init find_isa_irq_pin(int irq, int type) * Find a specific PCI IRQ entry. * Not an __init, possibly needed by modules */ -static int __init pin_2_irq(int idx, int apic, int pin); +static int pin_2_irq(int idx, int apic, int pin); + int IO_APIC_get_PCI_irq_vector(int bus, int slot, int pci_pin) { int apic, i, best_guess = -1; @@ -475,7 +476,7 @@ static inline int irq_trigger(int idx) return MPBIOS_trigger(idx); } -static int __init pin_2_irq(int idx, int apic, int pin) +static int pin_2_irq(int idx, int apic, int pin) { int irq, i; int bus = mp_irqs[idx].mpc_srcbus; diff --git a/arch/i386/kernel/pci-irq.c b/arch/i386/kernel/pci-irq.c index bd2bf22d3..8281e3f82 100644 --- a/arch/i386/kernel/pci-irq.c +++ b/arch/i386/kernel/pci-irq.c @@ -234,22 +234,107 @@ static int pirq_cyrix_set(struct pci_dev *router, struct pci_dev *dev, int pirq, return 1; } +/* + * PIRQ routing for SiS 85C503 router used in several SiS chipsets + * According to the SiS 5595 datasheet (preliminary V1.0, 12/24/1997) + * the related registers work as follows: + * + * general: one byte per re-routable IRQ, + * bit 7 IRQ mapping enabled (0) or disabled (1) + * bits [6:4] reserved + * bits [3:0] IRQ to map to + * allowed: 3-7, 9-12, 14-15 + * reserved: 0, 1, 2, 8, 13 + * + * individual registers in device config space: + * + * 0x41/0x42/0x43/0x44: PCI INT A/B/C/D - bits as in general case + * + * 0x61: IDEIRQ: bits as in general case - but: + * bits [6:5] must be written 01 + * bit 4 channel-select primary (0), secondary (1) + * + * 0x62: USBIRQ: bits as in general case - but: + * bit 4 OHCI function disabled (0), enabled (1) + * + * 0x6a: ACPI/SCI IRQ - bits as in general case + * + * 0x7e: Data Acq. Module IRQ - bits as in general case + * + * Apparently there are systems implementing PCI routing table using both + * link values 0x01-0x04 and 0x41-0x44 for PCI INTA..D, but register offsets + * like 0x62 as link values for USBIRQ e.g. So there is no simple + * "register = offset + pirq" relation. + * Currently we support PCI INTA..D and USBIRQ and try our best to handle + * both link mappings. + * IDE/ACPI/DAQ mapping is currently unsupported (left untouched as set by BIOS). + */ + static int pirq_sis_get(struct pci_dev *router, struct pci_dev *dev, int pirq) { u8 x; - int reg = 0x41 + (pirq - 'A') ; - - pci_read_config_byte(router, reg, &x); + int reg = pirq; + + switch(pirq) { + case 0x01: + case 0x02: + case 0x03: + case 0x04: + reg += 0x40; + case 0x41: + case 0x42: + case 0x43: + case 0x44: + case 0x62: + pci_read_config_byte(router, reg, &x); + if (reg != 0x62) + break; + if (!(x & 0x40)) + return 0; + break; + case 0x61: + case 0x6a: + case 0x7e: + printk("SiS pirq: advanced IDE/ACPI/DAQ mapping not yet implemented\n"); + return 0; + default: + printk("SiS router pirq escape (%d)\n", pirq); + return 0; + } return (x & 0x80) ? 0 : (x & 0x0f); } static int pirq_sis_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq) { u8 x; - int reg = 0x41 + (pirq - 'A') ; - - pci_read_config_byte(router, reg, &x); - x = (pirq & 0x20) ? 0 : (irq & 0x0f); + int reg = pirq; + + switch(pirq) { + case 0x01: + case 0x02: + case 0x03: + case 0x04: + reg += 0x40; + case 0x41: + case 0x42: + case 0x43: + case 0x44: + case 0x62: + x = (irq&0x0f) ? (irq&0x0f) : 0x80; + if (reg != 0x62) + break; + /* always mark OHCI enabled, as nothing else knows about this */ + x |= 0x40; + break; + case 0x61: + case 0x6a: + case 0x7e: + printk("advanced SiS pirq mapping not yet implemented\n"); + return 0; + default: + printk("SiS router pirq escape (%d)\n", pirq); + return 0; + } pci_write_config_byte(router, reg, x); return 1; @@ -462,18 +547,9 @@ static int pcibios_lookup_irq(struct pci_dev *dev, int assign) irq = pirq & 0xf; DBG(" -> hardcoded IRQ %d\n", irq); msg = "Hardcoded"; - if (dev->irq && dev->irq != irq) { - printk("IRQ routing conflict in pirq table! Try 'pci=autoirq'\n"); - return 0; - } } else if (r->get && (irq = r->get(pirq_router_dev, dev, pirq))) { DBG(" -> got IRQ %d\n", irq); msg = "Found"; - /* We refuse to override the dev->irq information. Give a warning! */ - if (dev->irq && dev->irq != irq) { - printk("IRQ routing conflict in pirq table! Try 'pci=autoirq'\n"); - return 0; - } } else if (newirq && r->set && (dev->class >> 8) != PCI_CLASS_DISPLAY_VGA) { DBG(" -> assigning IRQ %d", newirq); if (r->set(pirq_router_dev, dev, pirq, newirq)) { @@ -504,6 +580,11 @@ static int pcibios_lookup_irq(struct pci_dev *dev, int assign) if (!info) continue; if (info->irq[pin].link == pirq) { + /* We refuse to override the dev->irq information. Give a warning! */ + if (dev2->irq && dev2->irq != irq) { + printk("IRQ routing conflict in pirq table for device %s\n", dev2->slot_name); + continue; + } dev2->irq = irq; pirq_penalty[irq]++; if (dev != dev2) diff --git a/arch/i386/kernel/setup.c b/arch/i386/kernel/setup.c index 09aa4a08c..2c3f61f7f 100644 --- a/arch/i386/kernel/setup.c +++ b/arch/i386/kernel/setup.c @@ -147,6 +147,7 @@ extern char _text, _etext, _edata, _end; extern unsigned long cpu_khz; static int disable_x86_serial_nr __initdata = 1; +static int disable_x86_fxsr __initdata = 0; /* * This is set up by the setup-routine at boot-time @@ -518,7 +519,7 @@ void __init setup_memory_region(void) e820.nr_map = 0; add_memory_region(0, LOWMEMSIZE(), E820_RAM); - add_memory_region(HIGH_MEMORY, (mem_size << 10) - HIGH_MEMORY, E820_RAM); + add_memory_region(HIGH_MEMORY, mem_size << 10, E820_RAM); } printk("BIOS-provided physical RAM map:\n"); print_memory_map(who); @@ -1400,9 +1401,6 @@ static void __init init_centaur(struct cpuinfo_x86 *c) wrmsr (0x1107, lo, hi); set_bit(X86_FEATURE_CX8, &c->x86_capability); - rdmsr (0x80000001, lo, hi); - if (hi & (1<<31)) - set_bit(X86_FEATURE_3DNOW, &c->x86_capability); get_model_name(c); display_cacheinfo(c); @@ -1796,6 +1794,13 @@ int __init x86_serial_nr_setup(char *s) } __setup("serialnumber", x86_serial_nr_setup); +int __init x86_fxsr_setup(char * s) +{ + disable_x86_fxsr = 1; + return 1; +} +__setup("nofxsr", x86_fxsr_setup); + /* Standard macro to see if a specific flag is changeable */ static inline int flag_is_changeable_p(u32 flag) @@ -1866,7 +1871,8 @@ static int __init id_and_try_enable_cpuid(struct cpuinfo_x86 *c) /* Detect Cyrix with disabled CPUID */ if ( c->x86 == 4 && test_cyrix_52div() ) { strcpy(c->x86_vendor_id, "CyrixInstead"); - } + c->x86_vendor = X86_VENDOR_CYRIX; + } else /* Detect NexGen with old hypercode */ if ( deep_magic_nexgen_probe() ) { @@ -2000,11 +2006,17 @@ void __init identify_cpu(struct cpuinfo_x86 *c) */ /* TSC disabled? */ -#ifdef CONFIG_TSC +#ifndef CONFIG_X86_TSC if ( tsc_disable ) clear_bit(X86_FEATURE_TSC, &c->x86_capability); #endif + /* FXSR disabled? */ + if (disable_x86_fxsr) { + clear_bit(X86_FEATURE_FXSR, &c->x86_capability); + clear_bit(X86_FEATURE_XMM, &c->x86_capability); + } + /* Disable the PN if appropriate */ squash_the_stupid_serial_number(c); diff --git a/arch/i386/kernel/signal.c b/arch/i386/kernel/signal.c index 2423a8b06..7df9c875c 100644 --- a/arch/i386/kernel/signal.c +++ b/arch/i386/kernel/signal.c @@ -26,8 +26,6 @@ #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) -asmlinkage int sys_wait4(pid_t pid, unsigned long *stat_addr, - int options, unsigned long *ru); asmlinkage int FASTCALL(do_signal(struct pt_regs *regs, sigset_t *oldset)); int copy_siginfo_to_user(siginfo_t *to, siginfo_t *from) diff --git a/arch/i386/kernel/traps.c b/arch/i386/kernel/traps.c index 158d183b8..7c02813af 100644 --- a/arch/i386/kernel/traps.c +++ b/arch/i386/kernel/traps.c @@ -23,6 +23,7 @@ #include #include #include +#include #ifdef CONFIG_MCA #include diff --git a/arch/i386/lib/mmx.c b/arch/i386/lib/mmx.c index 4aca07e72..dfbf7ba8e 100644 --- a/arch/i386/lib/mmx.c +++ b/arch/i386/lib/mmx.c @@ -2,6 +2,8 @@ #include #include +#include + /* * MMX 3DNow! library helper functions * @@ -26,13 +28,7 @@ void *_mmx_memcpy(void *to, const void *from, size_t len) void *p=to; int i= len >> 6; /* len/64 */ - if (!(current->flags & PF_USEDFPU)) - clts(); - else - { - __asm__ __volatile__ ( " fnsave %0; fwait\n"::"m"(current->thread.i387)); - current->flags &= ~PF_USEDFPU; - } + kernel_fpu_begin(); __asm__ __volatile__ ( "1: prefetch (%0)\n" /* This set is 28 bytes */ @@ -88,20 +84,15 @@ void *_mmx_memcpy(void *to, const void *from, size_t len) * Now do the tail of the block */ __memcpy(to, from, len&63); - stts(); + kernel_fpu_end(); return p; } static void fast_clear_page(void *page) { int i; - if (!(current->flags & PF_USEDFPU)) - clts(); - else - { - __asm__ __volatile__ ( " fnsave %0; fwait\n"::"m"(current->thread.i387)); - current->flags &= ~PF_USEDFPU; - } + + kernel_fpu_begin(); __asm__ __volatile__ ( " pxor %%mm0, %%mm0\n" : : @@ -127,19 +118,14 @@ static void fast_clear_page(void *page) __asm__ __volatile__ ( " sfence \n" : : ); - stts(); + kernel_fpu_end(); } static void fast_copy_page(void *to, void *from) { int i; - if (!(current->flags & PF_USEDFPU)) - clts(); - else - { - __asm__ __volatile__ ( " fnsave %0; fwait\n"::"m"(current->thread.i387)); - current->flags &= ~PF_USEDFPU; - } + + kernel_fpu_begin(); /* maybe the prefetch stuff can go before the expensive fnsave... * but that is for later. -AV @@ -199,7 +185,7 @@ static void fast_copy_page(void *to, void *from) __asm__ __volatile__ ( " sfence \n" : : ); - stts(); + kernel_fpu_end(); } /* diff --git a/arch/i386/mm/init.c b/arch/i386/mm/init.c index b2e5a1bfc..6414b508c 100644 --- a/arch/i386/mm/init.c +++ b/arch/i386/mm/init.c @@ -317,7 +317,7 @@ static void __init pagetable_init (void) pgd_t *pgd, *pgd_base; int i, j, k; pmd_t *pmd; - pte_t *pte; + pte_t *pte, *pte_base; /* * This can be zero as well - no problem, in that case we exit @@ -366,11 +366,7 @@ static void __init pagetable_init (void) continue; } - pte = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE); - set_pmd(pmd, __pmd(_KERNPG_TABLE + __pa(pte))); - - if (pte != pte_offset(pmd, 0)) - BUG(); + pte_base = pte = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE); for (k = 0; k < PTRS_PER_PTE; pte++, k++) { vaddr = i*PGDIR_SIZE + j*PMD_SIZE + k*PAGE_SIZE; @@ -378,6 +374,10 @@ static void __init pagetable_init (void) break; *pte = mk_pte_phys(__pa(vaddr), PAGE_KERNEL); } + set_pmd(pmd, __pmd(_KERNPG_TABLE + __pa(pte_base))); + if (pte_base != pte_offset(pmd, 0)) + BUG(); + } } -- cgit v1.2.3