home *** CD-ROM | disk | FTP | other *** search
/ Il CD di internet / CD.iso / SOURCE / KERNEL-S / V1.2 / LINUX-1.2 / LINUX-1 / linux / include / asm-i386 / bugs.h < prev    next >
Encoding:
C/C++ Source or Header  |  1995-02-08  |  2.6 KB  |  117 lines

  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)
  17. {
  18.     hlt_works_ok = 0;
  19. }
  20.  
  21. static void no_387(char *s, int *ints)
  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)
  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)
  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)
  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)
  112. {
  113.     check_fpu();
  114.     check_hlt();
  115.     system_utsname.machine[1] = '0' + x86;
  116. }
  117.