root/include/asm-i386/bugs.h

/* [previous][next][first][last][top][bottom][index][help] */

INCLUDED FROM


DEFINITIONS

This source file includes following definitions.
  1. no_halt
  2. no_387
  3. copro_timeout
  4. check_fpu
  5. check_hlt
  6. check_bugs

   1 /*
   2  *  include/asm-i386/bugs.h
   3  *
   4  *  Copyright (C) 1994  Linus Torvalds
   5  */
   6 
   7 /*
   8  * This is included by init/main.c to check for architecture-dependent bugs.
   9  *
  10  * Needs:
  11  *      void check_bugs(void);
  12  */
  13 
  14 #define CONFIG_BUGi386
  15 
  16 static void no_halt(char *s, int *ints)
     /* [previous][next][first][last][top][bottom][index][help] */
  17 {
  18         hlt_works_ok = 0;
  19 }
  20 
  21 static void no_387(char *s, int *ints)
     /* [previous][next][first][last][top][bottom][index][help] */
  22 {
  23         hard_math = 0;
  24         __asm__("movl %%cr0,%%eax\n\t"
  25                 "orl $0xE,%%eax\n\t"
  26                 "movl %%eax,%%cr0\n\t" : : : "ax");
  27 }
  28 
  29 static char fpu_error = 0;
  30 
  31 static void copro_timeout(void)
     /* [previous][next][first][last][top][bottom][index][help] */
  32 {
  33         fpu_error = 1;
  34         timer_table[COPRO_TIMER].expires = jiffies+100;
  35         timer_active |= 1<<COPRO_TIMER;
  36         printk("387 failed: trying to reset\n");
  37         send_sig(SIGFPE, last_task_used_math, 1);
  38         outb_p(0,0xf1);
  39         outb_p(0,0xf0);
  40 }
  41 
  42 static void check_fpu(void)
     /* [previous][next][first][last][top][bottom][index][help] */
  43 {
  44         static double x = 4195835.0;
  45         static double y = 3145727.0;
  46         unsigned short control_word;
  47 
  48         if (!hard_math) {
  49 #ifndef CONFIG_MATH_EMULATION
  50                 printk("No coprocessor found and no math emulation present.\n");
  51                 printk("Giving up.\n");
  52                 for (;;) ;
  53 #endif
  54                 return;
  55         }
  56         /*
  57          * check if exception 16 works correctly.. This is truly evil
  58          * code: it disables the high 8 interrupts to make sure that
  59          * the irq13 doesn't happen. But as this will lead to a lockup
  60          * if no exception16 arrives, it depends on the fact that the
  61          * high 8 interrupts will be re-enabled by the next timer tick.
  62          * So the irq13 will happen eventually, but the exception 16
  63          * should get there first..
  64          */
  65         printk("Checking 386/387 coupling... ");
  66         timer_table[COPRO_TIMER].expires = jiffies+50;
  67         timer_table[COPRO_TIMER].fn = copro_timeout;
  68         timer_active |= 1<<COPRO_TIMER;
  69         __asm__("clts ; fninit ; fnstcw %0 ; fwait":"=m" (*&control_word));
  70         control_word &= 0xffc0;
  71         __asm__("fldcw %0 ; fwait": :"m" (*&control_word));
  72         outb_p(inb_p(0x21) | (1 << 2), 0x21);
  73         __asm__("fldz ; fld1 ; fdiv %st,%st(1) ; fwait");
  74         timer_active &= ~(1<<COPRO_TIMER);
  75         if (fpu_error)
  76                 return;
  77         if (!ignore_irq13) {
  78                 printk("Ok, fpu using old IRQ13 error reporting\n");
  79                 return;
  80         }
  81         __asm__("fninit\n\t"
  82                 "fldl %1\n\t"
  83                 "fdivl %2\n\t"
  84                 "fmull %2\n\t"
  85                 "fldl %1\n\t"
  86                 "fsubp %%st,%%st(1)\n\t"
  87                 "fistpl %0\n\t"
  88                 "fwait\n\t"
  89                 "fninit"
  90                 : "=m" (*&fdiv_bug)
  91                 : "m" (*&x), "m" (*&y));
  92         if (!fdiv_bug) {
  93                 printk("Ok, fpu using exception 16 error reporting.\n");
  94                 return;
  95 
  96         }
  97         printk("Hmm, FDIV bug i%c86 system\n", '0'+x86);
  98 }
  99 
 100 static void check_hlt(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 101 {
 102         printk("Checking 'hlt' instruction... ");
 103         if (!hlt_works_ok) {
 104                 printk("disabled\n");
 105                 return;
 106         }
 107         __asm__ __volatile__("hlt ; hlt ; hlt ; hlt");
 108         printk("Ok.\n");
 109 }
 110 
 111 static void check_bugs(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 112 {
 113         check_fpu();
 114         check_hlt();
 115         system_utsname.machine[1] = '0' + x86;
 116 }

/* [previous][next][first][last][top][bottom][index][help] */