On Fri, Jul 28, 2017 at 04:20:10PM +0200, Laszlo Ersek wrote:
On 07/27/17 22:40, Kevin O'Connor wrote:
On Wed, Jul 26, 2017 at 11:31:36AM +0200, Paolo Bonzini wrote:
The tables that QEMU provides are not ACPI 1.0 compatible since commit 77af8a2b95 ("hw/i386: Use Rev3 FADT (ACPI 2.0) instead of Rev1 to improve guest OS support.", 2017-05-03). This is visible with Windows 2000, which refuses to parse the rev3 FADT and fails to boot.
The recommended solution in this case is to build two FADTs, v1 being pointed to by the RSDT and v3 by the XSDT. However, we leave this task to the firmware. This patch simply switches the RSDT to the XSDT, which is valid for all ACPI 2.0-friendly operating systems and also leaves SeaBIOS the freedom to build an RSDT that points to the compatibility FADT.
Another possible solution to this issue would be for QEMU to instruct the firmware to build both rev1 and rev3 FADTs, but be clear which links are for legacy purposes only. This could be done with a new ADD_LEGACY_POINTER linker loader command. Existing firmwares should ignore the new ADD_LEGACY_POINTER command and new versions of SeaBIOS could be extended to honor it.
I confirm OVMF ignores (skips) unknown commands.
But, so I can understand better, can you please explain what the effect of these patches would be? IIUC, some pointer updates would not be performed in OVMF (and old SeaBIOS) that would take place in new SeaBIOS. What pointers are these exactly (where do they live and what do they point at)?
- RSDT[0] would point to FADTv1, RSDT[n] (n>=1) would point to the rest
of the tables, and OVMF wouldn't set (or follow) any of these pointers,
- XSDT[0] would point to FADTv3, XSDT[n] (n>=1) would point to the rest
of the tables, and both SeaBIOS and OVMF would see these pointers,
- RSDP.RSDT would point to the RSDT, and OVMF would not see (or follow)
this pointer,
- RSDP.XSDT would point to the XSDT, and both SeaBIOS and OVMF would see
this pointer.
Is this a correct interpretation?
Yes - exactly.
[...]
Fourth, what about the links within the FADTv1 (to the FACS and DSDT)? AFAICS in build_fadt1(), those pointers continue to be patched with the non-legacy ADD_POINTER command. This is not necessarily a problem if FADTv1.FACS and FADTv3.FACS point to the exact same address (similarly if FADTv1.DSDT and FADTv3.DSDT point to the exact same address), because OVMF already has a kind of memoization against installing the exact same pointed-to table twice (e.g., when FADTv3.DSDT and FADTv3.X_DSDT refer to the same address). Still, for completeness, maybe the FADTv1.FACS and FADTv1.DSDT pointers should also be patched with the new legacy ADD_POINTER command, in build_fadt1().
Agreed. That was an oversight on my part.
Also, I agree with others that this is probably something to think about for post QEMU v2.10. The suggestion to use FACSv1 on piix and FACSv3 on q35 for v2.10 makes sense to me.
-Kevin