Hi,
shacknetisp wrote:
I've done some experiments, trying to find what the source of this may be:
- Perhaps most importantly, this does not occur when the loop is empty or a pause instruction. It only fails when the loop is a hlt.
- This issue does not occur for other IRQs which I've tested, the PIT IRQ0 and RTC IRQ8.
- This issue does not occur when firing the interrupt manually with the int instruction.
- This/similiar issues do not occur in plain 32-bit protected mode.
- The issue occurs whether I set up IRQ1 through the PIC or APIC. It is not affected by the APIC system being initialized or not.
These tests rule out all the "more likely" possibilities I could think of and mostly only leaves the "firmware is buggy" option (e.g. maybe HLT triggers SMM and the firmware's SMM handler only supports 32-bit software properly).
I did some searching and found that Linux has a special work-around to make sure that (if the firmware's DMI says the computer is "Pavilion zv5000") only the maximum C state is used. Further digging suggests this was done because the C2 state ("stop clock") is buggy, but I'm not sure about the C1 state ("HLT"). Note that Linux also has generic work-arounds for various "HLT is buggy" situations done during boot (e.g. to test if HLT wakes up from an IRQ).
However; before assuming that the problem is the firmware, there's one little test I'd suggest.
Originally when AMD released long mode their documentation ("BIOS and Kernel Developer's Guide for AMD Athlon 64 TM and AMD Opteron Processors TM") described a BIOS function intended to inform the BIOS of whether or not the OS intends to use 64-bit/long mode. Nobody really had any idea why this BIOS function was created, and I assumed it might be so that the BIOS could reconfigure itself (and things like its SMM handler) differently if the OS says it intends to use 64-bit. Since then (as far as I know) almost everyone (including motherboard/firmware manufactures) have deprecated/ignored the BIOS function and mostly forgotten that it ("temporarily") existed. Note that HP also had a "Pavilion zv5000
z" that did use an AMD Athlon CPU, and it's reasonable to assume that parts of the firmware are shared by both "Pavilion zv5000" and "Pavilion zv5000
z".
I'm thinking that there's a tiny chance (if you're not doing it already) that the problem is that you're not informing the BIOS that you intend to use 64-bit during boot. To do this, here's the relevant part of AMD's original documentation:
AMD wrote:
12.21 Detect Target Operating Mode CallbackThe operating system notifies the BIOS what the expected operating mode is with the Detect Target Operating Mode callback (INT 15, function EC00h). Based on the target operating mode, the BIOS can enable or disable mode specific performance and functional optimizations that are not visible to system software.
This callback does not change the operating mode; it only declares the target mode to the BIOS. It should be executed only once by the BSP before the first transition into long mode.
The default operating mode assumed by the BIOS is Legacy Mode Target Only. If this is not the target operating mode, system software must execute this callback to change it before transitioning to long mode for the first time. If the target operating mode is Legacy Mode Target Only, the callback does not need to be executed.
The Detect Target Operating Mode callback inputs are stored in the AX and BL registers. AX has a value of EC00h, selecting the Detect Target Operating Mode function. One of the following values in the BL register selects the operating mode:
- 01h — Legacy Mode Target Only. All enabled processors will operate in legacy mode only.
- 02h — Long Mode Target Only. All enabled processor will switch into long mode once.
- 03h — Mixed Mode Target. Processors may switch between legacy mode and long mode, or the preferred mode for system software is unknown. This value instructs the BIOS to use settings that are valid in all modes.
- All other values are reserved.
The Detect Target Operating Mode callback outputs are stored in the AH register and CF (carry flag in the EFLAGS register), and the values of other registers are not modified. The following output values are possible:
- AH = 00h and CF = 0, if the callback is implemented and the value in BL is supported.
- AH = 00h and CF = 1, if the callback is implemented and the value in BL is reserved. This indicates an error; the target operating mode is set to Legacy Mode Target Only.
- AH = 86h and CF = 1, if the callback is not supported.
Cheers,
Brendan