Hi,
durand wrote:I grep'ed the bochs source code for the log entry and found it in fpu/fpu.cc.
Basically, it looks like the FPU specific flags in your CR0 are set up in a way that bochs doesn't support. In particular, your CR0 NE flag is set to 0. Bochs freaks out when it's set to 0.
Just investigate what bits you're setting and see if it's what you want, etc..
Once upon a time (80386 and older CPUs) the FPU was a seperate chip, which generated IRQ 13 via. the PIC when it got an error. When Intel put the FPU on the same chip as the CPU this became rather dumb - it's much faster and easier to generate an exception instead, and IRQ 13 doesn't work when you've got multiple CPUs.
To fix this Intel invented exception #16 (FPU error). The problem is that this would break backwards compatability, so they also added the NE flag in CR0. This means if the NE flag is clear you get the old IRQ from the PIC, and if it's set you get the new exception instead. Of course for backwards compatability the BIOS will leave the flag clear so that it doesn't break old stuff.
Now for Bochs... For 80486 and later Bochs does behave correctly regardless of whether the NE flag is set or cleared, although if NE flag is clear it'll show a message in the log. The comments in "fpu/fpu.cc" are completely wrong though, and so is the conditional code - they assume that 80286 and 80386 used the new exception rather than the old IRQ. In practice Bochs doesn't support 80386 or older CPUs, so this bug doesn't effect anyone...
None of this solves your problem though - why is the FPU generating an exception in the first place?
In the FPU control register there's a set of flags to enable/disable certain kinds of FPU exceptions (invalid operation, divide by zero, denormalized operand, overflow, underflow, inexact result). If the type of exception is disabled the FPU will continue without generating any exception (and will do some sort of default action to instead, which is intended to cause the least trouble later) - for example, for divide by zero it might set the result to positive or negative infinity and ignore the problem. Some of these exceptions are extremely likely - for example, doing "1 / 3" will result in an inexact result exception because the result can't be perfectly represented.
Given this, I'd guess that one or more of these possibilities may be the problem:
- - the code you're running enables some FPU exceptions in the FPU control register and expects the OS to handle the resulting exceptions in some way (for e.g perhaps the code expects to receive a SIGFPE signal from the OS).
- your OS doesn't initialize the FPU correctly, or the code you're running expects that certain FPU exceptions are disabled in the FPU control register when they aren't.
- your task switch code doesn't save and restore the FPU state correctly
- the code you're running is faulty or is relying on incorrect data (i.e. generating FPU exceptions for other reasons)
Hope something here helps....
Cheers,
Brendan