home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / bsd_srcs / sys / i386 / isa / npx.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-05-12  |  5.5 KB  |  208 lines

  1. /*-
  2.  * Copyright (c) 1990 William Jolitz.
  3.  * Copyright (c) 1991 The Regents of the University of California.
  4.  * All rights reserved.
  5.  *
  6.  * Redistribution and use in source and binary forms, with or without
  7.  * modification, are permitted provided that the following conditions
  8.  * are met:
  9.  * 1. Redistributions of source code must retain the above copyright
  10.  *    notice, this list of conditions and the following disclaimer.
  11.  * 2. Redistributions in binary form must reproduce the above copyright
  12.  *    notice, this list of conditions and the following disclaimer in the
  13.  *    documentation and/or other materials provided with the distribution.
  14.  * 3. All advertising materials mentioning features or use of this software
  15.  *    must display the following acknowledgement:
  16.  *    This product includes software developed by the University of
  17.  *    California, Berkeley and its contributors.
  18.  * 4. Neither the name of the University nor the names of its contributors
  19.  *    may be used to endorse or promote products derived from this software
  20.  *    without specific prior written permission.
  21.  *
  22.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  23.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  24.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  25.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  26.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  27.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  28.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  29.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  30.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  31.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  32.  * SUCH DAMAGE.
  33.  *
  34.  *    @(#)npx.c    7.2 (Berkeley) 5/12/91
  35.  */
  36. #include "npx.h"
  37. #if NNPX > 0
  38.  
  39. #include "param.h"
  40. #include "systm.h"
  41. #include "conf.h"
  42. #include "file.h"
  43. #include "proc.h"
  44. #include "machine/cpu.h"
  45. #include "machine/pcb.h"
  46. #include "machine/trap.h"
  47. #include "ioctl.h"
  48. #include "machine/specialreg.h"
  49. #include "i386/isa/isa_device.h"
  50. #include "icu.h"
  51. /*
  52.  * 387 and 287 Numeric Coprocessor Extension (NPX) Driver.
  53.  */
  54.  
  55. int    npxprobe(), npxattach(), npxintr();
  56. struct    isa_driver npxdriver = {
  57.     npxprobe, npxattach, "npx",
  58. };
  59.  
  60. struct proc *npxproc;    /* process who owns device, otherwise zero */
  61. struct pcb *npxpcb;    /* owners context structure */
  62. static npxexists;
  63. extern long npx0mask;
  64.  
  65. /*
  66.  * Probe routine - look device, otherwise set emulator bit
  67.  */
  68. npxprobe(dvp)
  69.     struct isa_device *dvp;
  70. {    static status, control;
  71.  
  72. #ifdef lint
  73.     npxintr();
  74. #endif
  75.  
  76.     /* insure EM bit off */
  77.     asm("    fninit ");    /* put device in known state */
  78.  
  79.     /* check for a proper status of zero */
  80.     status = 0xa5a5;    
  81.     asm ("    fnstsw    %0 " : "=m" (status) : "m" (status) );
  82.  
  83.     if (status == 0) {
  84.  
  85.         /* good, now check for a proper control word */
  86.         control = 0xa5a5;    
  87.         asm ("    fnstcw %0 " : "=m" (control) : "m" (control));
  88.  
  89.         if ((control&0x103f) == 0x3f) {
  90.             /* then we have a numeric coprocessor */
  91.         /* XXX should force an exception here to generate an intr */
  92.             return (1);
  93.         }
  94.     }
  95.  
  96. /* insure EM bit on */
  97.     return (0);
  98. }
  99.  
  100. /*
  101.  * Attach routine - announce which it is, and wire into system
  102.  */
  103. npxattach(dvp)
  104.     struct isa_device *dvp;
  105. {
  106.  
  107.     npxinit(0x262);
  108.     /* check for ET bit to decide 387/287 */
  109.     /*outb(0xb1,0);        /* reset processor */
  110.     npxexists++;
  111.     npx0mask = dvp->id_irq;
  112. }
  113.  
  114. /*
  115.  * Initialize floating point unit, usually after an error
  116.  */
  117. npxinit(control) {
  118.  
  119.     if (npxexists == 0) return;
  120.  
  121.  
  122.     load_cr0(rcr0() & ~CR0_EM);    /* stop emulating */
  123. #ifdef INTEL_COMPAT
  124.     asm ("    finit");
  125.     asm("    fldcw %0" : : "g" (control));
  126.     asm("    fnsave %0 " : : "g" (curpcb->pcb_savefpu) );
  127. #else
  128.     asm("fninit");
  129.     asm("    fnsave %0 " : : "g" (curpcb->pcb_savefpu) );
  130. #endif
  131.     load_cr0(rcr0() | CR0_EM);    /* start emulating */
  132.  
  133. }
  134.  
  135. /*
  136.  * Load floating point context and record ownership to suite
  137.  */
  138. npxload() {
  139.  
  140.     if (npxproc) panic ("npxload");
  141.     npxproc = curproc;
  142.     npxpcb = curpcb;
  143.     asm("    frstor %0 " : : "g" (curpcb->pcb_savefpu) );
  144. }
  145.  
  146. /*
  147.  * Unload floating point context and relinquish ownership
  148.  */
  149. npxunload() {
  150.  
  151.     if (npxproc == 0) panic ("npxunload");
  152.     asm("    fsave %0 " : : "g" (npxpcb->pcb_savefpu) );
  153.     npxproc = 0 ;
  154. }
  155.  
  156. /*
  157.  * Record information needed in processing an exception and clear status word
  158.  */
  159. npxintr(frame) struct intrframe frame; {
  160.     struct trapframe tf;
  161.  
  162.     outb(0xf0,0);        /* reset processor */
  163.  
  164.     /* sync state in process context structure, in advance of debugger/process looking for it */
  165.     if (npxproc == 0 || npxexists == 0) panic ("npxintr");
  166.     asm ("    fnsave %0 " : : "g" (npxpcb->pcb_savefpu) );
  167.  
  168.     /*
  169.      * Prepair a trap frame for our generic exception processing routine, trap()
  170.      */
  171.     bcopy(&frame.if_es, &tf, sizeof(tf));
  172.     tf.tf_trapno = T_ARITHTRAP;
  173. #ifdef notyet
  174.     /* encode the appropriate code for detailed information on this exception */
  175.     tf.tf_err = ???;
  176. #endif
  177.     trap(tf);
  178.  
  179.     /*
  180.      * Restore with any changes to superior frame
  181.      */
  182.     bcopy(&tf, &frame.if_es, sizeof(tf));
  183.  
  184.     /* clear the exception so we can catch others like it */
  185.     asm ("    fnclex");
  186. }
  187.  
  188. /*
  189.  * Implement device not available (DNA) exception
  190.  */
  191. npxdna() {
  192.  
  193.     if (npxexists == 0) return(0);
  194.     if (!(curpcb->pcb_flags & FP_WASUSED)
  195.         ||(curpcb->pcb_flags & FP_NEEDSRESTORE)) {
  196.         load_cr0(rcr0() & ~CR0_EM);    /* stop emulating */
  197.         asm("    frstor %0 " : : "g" (curpcb->pcb_savefpu));
  198.         curpcb->pcb_flags |= FP_WASUSED | FP_NEEDSSAVE;
  199.         curpcb->pcb_flags &= ~FP_NEEDSRESTORE;
  200.         npxproc = curproc;
  201.         npxpcb = curpcb;
  202.         
  203.         return(1);
  204.     }
  205.     return (0);
  206. }
  207. #endif
  208.