📄 bugs.h
字号:
/*
* include/asm-i386/bugs.h
*
* Copyright (C) 1994 Linus Torvalds
*/
/*
* This is included by init/main.c to check for architecture-dependent bugs.
*
* Needs:
* void check_bugs(void);
*/
#include <linux/config.h>
#define CONFIG_BUGi386
static void no_halt(char *s, int *ints)
{
hlt_works_ok = 0;
}
static void no_387(char *s, int *ints)
{
hard_math = 0;
__asm__("movl %%cr0,%%eax\n\t"
"orl $0xE,%%eax\n\t"
"movl %%eax,%%cr0\n\t" : : : "ax");
}
static char fpu_error = 0;
static void copro_timeout(void)
{
fpu_error = 1;
timer_table[COPRO_TIMER].expires = jiffies+100;
timer_active |= 1<<COPRO_TIMER;
printk("387 failed: trying to reset\n");
send_sig(SIGFPE, last_task_used_math, 1);
outb_p(0,0xf1);
outb_p(0,0xf0);
}
static void check_fpu(void)
{
static double x = 4195835.0;
static double y = 3145727.0;
unsigned short control_word;
if (!hard_math) {
#ifndef CONFIG_MATH_EMULATION
printk("No coprocessor found and no math emulation present.\n");
printk("Giving up.\n");
for (;;) ;
#endif
return;
}
/*
* check if exception 16 works correctly.. This is truly evil
* code: it disables the high 8 interrupts to make sure that
* the irq13 doesn't happen. But as this will lead to a lockup
* if no exception16 arrives, it depends on the fact that the
* high 8 interrupts will be re-enabled by the next timer tick.
* So the irq13 will happen eventually, but the exception 16
* should get there first..
*/
printk("Checking 386/387 coupling... ");
timer_table[COPRO_TIMER].expires = jiffies+50;
timer_table[COPRO_TIMER].fn = copro_timeout;
timer_active |= 1<<COPRO_TIMER;
__asm__("clts ; fninit ; fnstcw %0 ; fwait":"=m" (*&control_word));
control_word &= 0xffc0;
__asm__("fldcw %0 ; fwait": :"m" (*&control_word));
outb_p(inb_p(0x21) | (1 << 2), 0x21);
__asm__("fldz ; fld1 ; fdiv %st,%st(1) ; fwait");
timer_active &= ~(1<<COPRO_TIMER);
if (fpu_error)
return;
if (!ignore_irq13) {
printk("Ok, fpu using old IRQ13 error reporting\n");
return;
}
__asm__("fninit\n\t"
"fldl %1\n\t"
"fdivl %2\n\t"
"fmull %2\n\t"
"fldl %1\n\t"
"fsubp %%st,%%st(1)\n\t"
"fistpl %0\n\t"
"fwait\n\t"
"fninit"
: "=m" (*&fdiv_bug)
: "m" (*&x), "m" (*&y));
if (!fdiv_bug) {
printk("Ok, fpu using exception 16 error reporting.\n");
return;
}
printk("Hmm, FDIV bug i%c86 system\n", '0'+x86);
}
static void check_hlt(void)
{
printk("Checking 'hlt' instruction... ");
if (!hlt_works_ok) {
printk("disabled\n");
return;
}
__asm__ __volatile__("hlt ; hlt ; hlt ; hlt");
printk("Ok.\n");
}
static void check_tlb(void)
{
#ifndef CONFIG_M386
/*
* The 386 chips don't support TLB finegrained invalidation.
* They will fault when they hit a invlpg instruction.
*/
if (x86 == 3) {
printk("CPU is a 386 and this kernel was compiled for 486 or better.\n");
printk("Giving up.\n");
for (;;) ;
}
#endif
}
/*
* All current models of Pentium and Pentium with MMX technology CPUs
* have the F0 0F bug, which lets nonpriviledged users lock up the system:
*/
extern int pentium_f00f_bug;
extern void trap_init_f00f_bug(void);
static void check_pentium_f00f(void)
{
/*
* Pentium and Pentium MMX
*/
pentium_f00f_bug = 0;
if (x86==5 && !memcmp(x86_vendor_id, "GenuineIntel", 12)) {
printk(KERN_INFO "Intel Pentium with F0 0F bug - workaround enabled.\n");
pentium_f00f_bug = 1;
trap_init_f00f_bug();
}
}
static void check_bugs(void)
{
check_tlb();
check_fpu();
check_hlt();
check_pentium_f00f();
system_utsname.machine[1] = '0' + x86;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -