MTRR: Clearing variable MTRRs on boot causes system freeze
|Reported by:||mmlr||Owned by:||mmlr|
|Has a Patch:||no||Platform:||All|
I've recently upgraded my desktop PC to 4GB of RAM. This worked for a few days without problem. After updating the BIOS/Firmware of this machine however, Haiku would hang at boot. I've tracked it down to the MTRR initialization. The system hangs when all variable MTRRs are cleared in generic_init_mtrrs() (http://dev.haiku-os.org/browser/haiku/trunk/src/add-ons/kernel/cpu/x86/generic_x86.cpp#L61) and then caches are re-enabled by clearing the cache-disable bit in cr0 (http://dev.haiku-os.org/browser/haiku/trunk/src/system/kernel/arch/x86/arch_cpu.cpp#L143).
The system does not hang if either MTRRs aren't used at all (by hacking the returned count to 0 for example), if MTRRs aren't enabled again at the end of generic_init_mtrrs(), or if the MTRRs aren't cleared in generic_init_mtrrs().
From reading the specs and cross-referencing other implementations it seems that we aren't really supposed to clear whatever has been setup in the MTRRs by the BIOS/Firmware. Instead other systems seem to take the existing MTRR setup as a base and then work with that.
What leads me to suspect that clearing is not intended by the specs is that it states in the MTRR examples (Example 10-2 in 10.11.3): "This setup also fulfills the requirement that two register pairs are left for operating system usage." Which could indicate that the other pairs aren't really supposed to be re-set, though it doesn't explicitly state that anywhere.
Linux seems to gather all MTRR info from the boot processor first and then syncs the other processors to match if necessary. Otherwise it leaves the existing MTRRs and later extends them as needed or uses free slots for new ranges.
My current work-around is to simply skip clearing MTRRs. They are later over-written by Haiku, which doesn't seem to be a problem. It only seems to be a problem when caches are enabled and there are no variable MTRRs programmed at all.
Board is an Intel DG33TL with latest BIOS/Firmware, 2.4GHz Core 2 Quad, 4GB of RAM.