286-based detection of coprocessor (287/XL)

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
blasthash
Member
Member
Posts: 31
Joined: Tue May 06, 2014 12:19 am

286-based detection of coprocessor (287/XL)

Post 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?
Gigasoft
Member
Member
Posts: 856
Joined: Sat Nov 21, 2009 5:11 pm

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

Post by Gigasoft »

Just perform any instruction (for example, FNSTSW), and see if it did anything.
blasthash
Member
Member
Posts: 31
Joined: Tue May 06, 2014 12:19 am

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

Post 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?
alexfru
Member
Member
Posts: 1112
Joined: Tue Mar 04, 2014 5:27 am

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

Post 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.
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

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

Post 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.
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
DLBuunk
Member
Member
Posts: 39
Joined: Sun May 18, 2008 9:36 am
Location: The Netherlands

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

Post 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
blasthash
Member
Member
Posts: 31
Joined: Tue May 06, 2014 12:19 am

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

Post 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).
Gigasoft
Member
Member
Posts: 856
Joined: Sat Nov 21, 2009 5:11 pm

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

Post 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.
alexfru
Member
Member
Posts: 1112
Joined: Tue Mar 04, 2014 5:27 am

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

Post 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?
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

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

Post by Combuster »

Have you ever even seen #NM, #MP and #MF in the documentation?
In the documentation for a different processor. Oops.
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
alexfru
Member
Member
Posts: 1112
Joined: Tue Mar 04, 2014 5:27 am

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

Post 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? :)
Gigasoft
Member
Member
Posts: 856
Joined: Sat Nov 21, 2009 5:11 pm

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

Post 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.
alexfru
Member
Member
Posts: 1112
Joined: Tue Mar 04, 2014 5:27 am

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

Post 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).
?
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

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

Post 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
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
Post Reply