On Mon, 2 Aug 1999, Alex Holden wrote:
> On Fri, 30 Jul 1999, Greg Haerr wrote:
> > I see. Does anyone have any code for auto-detection of an
> > 8087/8287/8387?
> >From allegro/src/cpu.c:
I finally figured out where it's hiding in the NetBSD tree (the maths
coprocessor is an ISA device called npx???). It's longer than the other
two, but makes more sense...
>From sys/arch/i386/isa/npx.c:
#define fninit() __asm("fninit")
#define fnstsw(addr) __asm("fnstsw %0" : "=m" (*addr))
#define fnstcw(addr) __asm("fnstcw %0" : "=m" (*addr))
#define fldcw(addr) __asm("fldcw %0" : : "m" (*addr))
#define fp_divide_by_0() __asm("fldz; fld1; fdiv %st,%st(1);
fwait")
static inline int
npxprobe1(ia)
struct isa_attach_args *ia;
{
int control;
int status;
ia->ia_iosize = 16;
ia->ia_msize = 0;
/*
* Finish resetting the coprocessor, if any. If there is an error
* pending, then we may get a bogus IRQ13, but probeintr() will
handle
* it OK. Bogus halts have never been observed, but we enabled
* IRQ13 and cleared the BUSY# latch early to handle them anyway.
*/
fninit();
delay(1000); /* wait for any IRQ13 (fwait might hang)
*/
/*
* Check for a status of mostly zero.
*/
status = 0x5a5a;
fnstsw(&status);
if ((status & 0xb8ff) == 0) {
/*
* Good, now check for a proper control word.
*/
control = 0x5a5a;
fnstcw(&control);
if ((control & 0x1f3f) == 0x033f) {
/*
* We have an npx, now divide by 0 to see if
exception
* 16 works.
*/
control &= ~(1 << 2); /* enable divide by 0 trap
*/
fldcw(&control);
npx_traps_while_probing = npx_intrs_while_probing
= 0;
fp_divide_by_0();
if (npx_traps_while_probing != 0) {
/*
* Good, exception 16 works.
*/
npx_type = NPX_EXCEPTION;
ia->ia_irq = IRQUNK; /* zap the
interrupt */
} else if (npx_intrs_while_probing != 0) {
/*
* Bad, we are stuck with IRQ13.
*/
npx_type = NPX_INTERRUPT;
} else {
/*
* Worse, even IRQ13 is broken. Use
emulator.
*/
npx_type = NPX_BROKEN;
ia->ia_irq = IRQUNK;
}
return 1;
}
}
/*
* Probe failed. There is no usable FPU.
*/
npx_type = NPX_NONE;
return 0;
}
--------------- Linux- the choice of a GNU generation. --------------
: Alex Holden (M1CJD)- Caver, Programmer, Land Rover nut, Radio Ham :
-------------------- http://www.linuxhacker.org/ --------------------