Page 1 of 1

286-based detection of coprocessor (287/XL)

Posted: Sat Nov 22, 2014 6:29 am
by blasthash
Alright everyone, let me preface this a little so you have some background; if you're going to call me insane, then at least let it be an informed judgment.

I began doing the homework for brewing my own OS a few months ago, but fell off it due to a number of concerns, namely the idea of graphics drivers as well as some of the intricacies of x86 that puzzled me. On the drivers front, I know I was thinking way too many steps (years) in advance. It took a calming down and studying without feeling the need to scratch out code for a long time to rest that problem in my mind. While when I started, I knew 99% of what I know now about how the x86 system works, it came down to that extra 1% that made me decide to make a renewed run of things.

So, I decided to scrap the idea of developing on a modern, GHz-level machine in lieu of working on an old IBM PC/AT. I don't have this machine yet, namely because I am building it (drawing custom boards from the original schematics); I like the challenge of inventing the wheel for myself. Anyway, it took a while away from the OS development front for me to finally realize to start small and with small expectations. Once I have an operating system that doesn't do everything in a predetermined manner, I'll work to move and port it to more advanced systems, but I'm now comfortable not worrying about that bridge until I cross it. Call it developer maturity.

Before I put you all to sleep, I'll get to the point. Obviously, the x87 coprocessor in these days was an optional accessory for the system, added in only if the program demand by the user warranted the extra performance, and while I'm reasonably sure I'll include it in the final boards, I would much rather write code that is functional without its existence and can account for that. I've consulted the guide on FPUs on the wiki, but due to the fact that I'm using a 80286, the CR0 and CPUID methods won't work. This leaves manual probing but I'm not quite sure how to accomplish that and to be completely honest, am wondering about its safety.

The only things I find otherwise are the rather esoteric and exceedingly-unsafe methods of determining FLAGS behavior (via PUSHF/POP/PUSH/POPF, etc.) and those don't do me any good because they don't work on a x87 coprocessor. Does anyone have any ideas?

Re: 286-based detection of coprocessor (287/XL)

Posted: Sat Nov 22, 2014 7:08 am
by Gigasoft
Just perform any instruction (for example, FNSTSW), and see if it did anything.

Re: 286-based detection of coprocessor (287/XL)

Posted: Sat Nov 22, 2014 7:09 am
by blasthash
Gigasoft wrote:Just perform any instruction (for example, FNSTSW), and see if it did anything.
Is that 'safe' - does it run the risk of a fault?

Re: 286-based detection of coprocessor (287/XL)

Posted: Sat Nov 22, 2014 7:45 am
by alexfru
blasthash wrote:
Gigasoft wrote:Just perform any instruction (for example, FNSTSW), and see if it did anything.
Is that 'safe' - does it run the risk of a fault?
It isn't and it does. Disable interrupts, install exception handlers, execute the probing instruction(s), observe the state (has it worked? has it caused an exception?), remove the handlers, enable the interrupts. I don't remember exactly how events were delivered from the i80287 to the i80286. They could've been regular hardware interrupts and not exceptions like #GP. It's worth checking this and taking into account. As usual, you could just peek into the detection code in some old DOS compiler (Turbo Pascal/C and such) and see how they did it. That code was known to work back then.

Re: 286-based detection of coprocessor (287/XL)

Posted: Sat Nov 22, 2014 9:25 am
by Combuster
In days of old, people simply had code for this. There was a more concise explanation on the other end of some google query, but I can't seem to find it again with just a few tries.

Re: 286-based detection of coprocessor (287/XL)

Posted: Sat Nov 22, 2014 3:17 pm
by DLBuunk
The official method for this, AFAIK, is buried somewhere in intel application note 485. In this version it's on page 33:
http://bochs.sourceforge.net/techspec/24161821.pdf

Re: 286-based detection of coprocessor (287/XL)

Posted: Sat Nov 22, 2014 8:19 pm
by blasthash
alexfru wrote:
blasthash wrote:
Gigasoft wrote:Just perform any instruction (for example, FNSTSW), and see if it did anything.
Is that 'safe' - does it run the risk of a fault?
It isn't and it does. Disable interrupts, install exception handlers, execute the probing instruction(s), observe the state (has it worked? has it caused an exception?), remove the handlers, enable the interrupts. I don't remember exactly how events were delivered from the i80287 to the i80286. They could've been regular hardware interrupts and not exceptions like #GP. It's worth checking this and taking into account. As usual, you could just peek into the detection code in some old DOS compiler (Turbo Pascal/C and such) and see how they did it. That code was known to work back then.
Okay. I have the IBM XT BIOS source from the old service manuals handy, so I might start looking into how it detected the existence for ideas. I'll have to see how to manage an interrupt/exception handler series, as I don't have familiarity with those (I do, but not from an operating system standpoint).

Re: 286-based detection of coprocessor (287/XL)

Posted: Sun Nov 23, 2014 1:55 am
by Gigasoft
Don't waste your time with handling exceptions, as there are none. He said he doesn't remember, which means that he made it up. The code found in the two links works.

Re: 286-based detection of coprocessor (287/XL)

Posted: Sun Nov 23, 2014 3:15 am
by alexfru
Gigasoft wrote:Don't waste your time with handling exceptions, as there are none.
Have you ever even seen #NM, #MP and #MF in the documentation?
Gigasoft wrote:He said he doesn't remember, which means that he made it up.
And you must be all-knowing, all-remembering and never-making-anything-up-even-unintentionally-even-after-more-than-a-decade-of-not-touching-the-subject, right?

Re: 286-based detection of coprocessor (287/XL)

Posted: Sun Nov 23, 2014 6:25 am
by Combuster
Have you ever even seen #NM, #MP and #MF in the documentation?
In the documentation for a different processor. Oops.

Re: 286-based detection of coprocessor (287/XL)

Posted: Sun Nov 23, 2014 6:04 pm
by alexfru
Combuster wrote:
Have you ever even seen #NM, #MP and #MF in the documentation?
In the documentation for a different processor. Oops.
Um, where would one expect to receive and handle those? In the x87 chip? :)

Re: 286-based detection of coprocessor (287/XL)

Posted: Sun Nov 23, 2014 10:55 pm
by Gigasoft
Neither of those exceptions are relevant.
#NM is controlled by software.
#MF is triggered by the /ERROR signal, which should be wired to "1".
#MP indicates a segmentation violation while executing a FPU instruction. Since the OP knows what he is doing and has wired PEREQ to "0", no operand transfer takes place and nothing of this sort can happen.
And you must be all-knowing, all-remembering and never-making-anything-up-even-unintentionally-even-after-more-than-a-decade-of-not-touching-the-subject, right?
I don't know what you are getting at. It's not like the manuals have disappeared, and I have no interest in trying to fool anyone by presenting wild claims from my imagination. If you think I have done so recently, you are of course welcome to respond in the appropriate thread.

Re: 286-based detection of coprocessor (287/XL)

Posted: Sun Nov 23, 2014 11:29 pm
by alexfru
Gigasoft wrote:
And you must be all-knowing, all-remembering and never-making-anything-up-even-unintentionally-even-after-more-than-a-decade-of-not-touching-the-subject, right?
I don't know what you are getting at. It's not like the manuals have disappeared, and I have no interest in trying to fool anyone by presenting wild claims from my imagination. If you think I have done so recently, you are of course welcome to respond in the appropriate thread.
Well, were you unintentionally being ambiguous with
Gigasoft wrote:which means that he made it up
, or was the negative connotation implied as in
If you make up something such as a story or excuse, you invent it, sometimes in order to deceive people (from Collins Cobuild).
?

Re: 286-based detection of coprocessor (287/XL)

Posted: Mon Nov 24, 2014 5:06 am
by Brendan
Hi,

For some clarification; for 80387 and earlier, the FPU's error signal was connected to the PIC chip's IRQ13 (and can be masked, just like any other IRQ).

It was slow and crappy (and couldn't work for multi-CPU at all); so for 80486 and later (where the FPU is built into the same chip as the CPU) Intel added an NE ("Native FPU Exceptions") flag to CR0. With NE set (native FPU exceptions enabled) the old/default "FPU errors routed through PIC chip" behaviour is disabled and you get a true exception (Interrupt 16, #MF - Maths Fault).

Note 1: For 80486SX and its optional "external FPU"; that "external FPU" is actually a complete CPU and FPU (a bit like an 80486DX) and when it's present the 80486SX is disabled and does nothing. This is sad (in a wasteful way); but means native FPU exceptions still work.

Note 2: I can't remember the exact details, but the "FPU errors routed through PIC chip" idea had race conditions and the IRQ13 handler had to be extremely careful to work around problems. Because of this, every OS should enable native FPU exceptions (on 80486 or later), even if the OS doesn't support multi-CPU.

Some FPU instructions (FNINIT, FNSTCW, FNSTSW) can't generate an error. These typically form the basis of the old FPU (and FPU type) detection algorithms, as different FPUs had different values in their control word and/or status word after FNINIT. These instructions are also "safe" when there is no FPU at all (the CPU just sends the opcode to the electronic equivalent of "/dev/null"). Of course for later CPUs (where the FPU is built into the CPU) you can just use the CPU type to infer the FPU type.

Also; you probably want to be careful with ancient stuff. Back then there were other companies (AMD, Cyrix, Weitec) who all made FPUs that worked with Intel's CPUs. I'm not sure how compatible these were with Intel's own FPU (or how to determine the difference between an Intel FPU and any of the other manufacturer's FPUs).


Cheers,

Brendan