1 /* 2 * Copyright (c) 1990 W. Jolitz 3 * @(#)npx.c 1.2 (Berkeley) 11/18/90 4 */ 5 #include "npx.h" 6 #if NNPX > 0 7 8 #include "param.h" 9 #include "systm.h" 10 #include "conf.h" 11 #include "file.h" 12 #include "dir.h" 13 #include "user.h" 14 #include "ioctl.h" 15 #include "vm.h" 16 #include "machine/pte.h" 17 #include "machine/isa/isa_device.h" 18 #include "icu.h" 19 /* 20 * 387 and 287 Numeric Coprocessor Extension (NPX) Driver. 21 */ 22 23 int npxprobe(), npxattach(), npxintr(); 24 struct isa_driver npxdriver = { 25 npxprobe, npxattach, "npx", 26 }; 27 28 struct proc *npxproc; /* process who owns device, otherwise zero */ 29 extern struct user npxutl; /* owners user structure */ 30 extern struct pte Npxmap[]; /* kernel ptes mapping owner's user structure */ 31 32 /* 33 * Probe routine - look device, otherwise set emulator bit 34 */ 35 npxprobe(dvp) 36 struct isa_device *dvp; 37 { static status, control; 38 39 #ifdef lint 40 npxintr(); 41 #endif 42 43 /* insure EM bit off */ 44 asm(" fninit "); /* put device in known state */ 45 46 /* check for a proper status of zero */ 47 status = 0xa5a5; 48 asm (" fnstsw %0 " : "=m" (status) : "m" (status) ); 49 50 if (status == 0) { 51 52 /* good, now check for a proper control word */ 53 control = 0xa5a5; 54 asm (" fnstcw %0 " : "=m" (control) : "m" (control)); 55 56 if ((control&0x103f) == 0x3f) { 57 /* then we have a numeric coprocessor */ 58 /* XXX should force an exception here to generate an intr */ 59 return (1); 60 } 61 } 62 63 /* insure EM bit on */ 64 return (0); 65 } 66 67 /* 68 * Attach routine - announce which it is, and wire into system 69 */ 70 npxattach(dvp) 71 struct isa_device *dvp; 72 { 73 74 npxinit(0x262); 75 /* check for ET bit to decide 387/287 */ 76 /*outb(0xb1,0); /* reset processor */ 77 } 78 79 /* 80 * Initialize floating point unit, usually after an error 81 */ 82 npxinit(control) { 83 84 asm (" fninit"); 85 asm(" fldcw %0" : : "g" (control)); 86 87 } 88 89 /* 90 * Load floating point context and record ownership to suite 91 */ 92 npxload() { 93 94 if (npxproc) panic ("npxload"); 95 npxproc = u.u_procp; 96 uaccess(npxproc, Npxmap, &npxutl); 97 asm(" frstor %0 " : : "g" (u.u_pcb.pcb_savefpu) ); 98 } 99 100 /* 101 * Unload floating point context and relinquish ownership 102 */ 103 npxunload() { 104 105 if (npxproc == 0) panic ("npxunload"); 106 asm(" fsave %0 " : : "g" (npxutl.u_pcb.pcb_savefpu) ); 107 npxproc = 0 ; 108 } 109 110 /* 111 * Record information needed in processing an exception and clear status word 112 */ 113 npxexcept() { 114 115 /* save state in appropriate user structure */ 116 if (npxproc == 0) panic ("npxexcept"); 117 asm (" fsave %0 " : : "g" (npxutl.u_pcb.pcb_savefpu) ); 118 119 /* 120 * encode the appropriate u_code for detailed information 121 * on this exception 122 */ 123 124 /* signal appropriate process */ 125 psignal (npxproc, SIGFPE); 126 127 /* clear the exception so we can catch others like it */ 128 asm (" fnclex"); 129 } 130 131 /* 132 * Catch AT/386 interrupt used to signal exception, and simulate trap() 133 */ 134 npxintr() { 135 outb(0xf0,0); 136 pg("npxintr"); 137 } 138 139 /* 140 * Implement device not available (DNA) exception 141 */ 142 npxdna() { 143 } 144 #endif 145