On Mon, Sep 22, 2014 at 10:40:04PM +0200, Laszlo Ersek wrote: > On 09/22/14 18:44, Paolo Bonzini wrote: > > Il 22/09/2014 00:43, Laszlo Ersek ha scritto: > >> // Bus 0, Device 1, Function 0 - PCI to ISA Bridge > >> // > >> PciWrite8 (PCI_LIB_ADDRESS (0, 1, 0, 0x3c), 0x00); > >> PciWrite8 (PCI_LIB_ADDRESS (0, 1, 0, 0x60), 0x0b); // LNKA routing target > >> PciWrite8 (PCI_LIB_ADDRESS (0, 1, 0, 0x61), 0x0b); // LNKB routing target > >> PciWrite8 (PCI_LIB_ADDRESS (0, 1, 0, 0x62), 0x0a); // LNKC routing target > >> PciWrite8 (PCI_LIB_ADDRESS (0, 1, 0, 0x63), 0x0a); // LNKD routing target > >> > >> This is not appropriate for q35. See "ICH9 PCI to ISA irq remapping" in > >> qemu's "q35-acpi-dsdt.dsl" file, vs. "PIIX PCI to ISA irq remapping" in > >> "acpi-dsdt.dsl". > > > > If I understand the DSDT right, the field is still at 0x60, but the > > bridge is now at 1f.0. Right? Also, LNKE-LNKH must be set at 0x68.
With the patch included below, I now get identical behavior in terms of q35 LNK[A-H] between SeaBIOS and OVMF. > > However, these are only used if OS X runs in PIC mode rather than APIC > > mode (see \_PIC). Why should OS X be running in PIC mode? So fixing > > the above is right to do, but may not be enough. Grepping for GSIA on either SeaBIOS or OVMF looks the same: [ 0.000000] ACPI: IOAPIC (id[0x00] address[0xfec00000] gsi_base[0]) [ 0.000000] IOAPIC[0]: apic_id 0, version 17, address 0xfec00000, GSI 0-23 [ 0.000000] nr_irqs_gsi: 40 [ 0.195980] ACPI: PCI Interrupt Link [GSIA] (IRQs *16) [ 0.196012] ACPI: PCI Interrupt Link [GSIB] (IRQs *17) [ 0.196022] ACPI: PCI Interrupt Link [GSIC] (IRQs *18) [ 0.196031] ACPI: PCI Interrupt Link [GSID] (IRQs *19) [ 0.196041] ACPI: PCI Interrupt Link [GSIE] (IRQs *20) [ 0.196050] ACPI: PCI Interrupt Link [GSIF] (IRQs *21) [ 0.196059] ACPI: PCI Interrupt Link [GSIG] (IRQs *22) [ 0.196068] ACPI: PCI Interrupt Link [GSIH] (IRQs *23) [ 0.325959] ACPI: PCI Interrupt Link [GSIA] enabled at IRQ 16 [ 0.327518] ACPI: PCI Interrupt Link [GSIB] enabled at IRQ 17 [ 0.328839] ACPI: PCI Interrupt Link [GSIC] enabled at IRQ 18 [ 0.330071] ACPI: PCI Interrupt Link [GSID] enabled at IRQ 19 [ 2.432386] ACPI: PCI Interrupt Link [GSIG] enabled at IRQ 22 (and did so even before I fixed LNK*), but I still don't get UHCI1 and UHCI2 detected under OS X :( Speaking of the patch: the original (piix) PciInitialization() function touches a bunch of devices' interrupt line (0x3c) and interrupt pin (0x3d) registers, but on q35/ich those are mostly supposed to be unused or read-only, so I only did LNK routing setup for the q35 version. Not enough clue yet to know if I'm missing anything important. Also, during PciInitializationQ35() I read and dumped the line and pin register values for 00:1d.0-2, and got 0xff for line and 1,2,3 respectively for pin (as opposed to 0,1,2 as set up in qemu). Not sure if that's important or not :) Thanks, --Gabriel diff --git a/OvmfPkg/Library/PlatformBdsLib/BdsPlatform.c b/OvmfPkg/Library/PlatformBdsLib/BdsPlatform.c index 9cc6068..380f07f 100644 --- a/OvmfPkg/Library/PlatformBdsLib/BdsPlatform.c +++ b/OvmfPkg/Library/PlatformBdsLib/BdsPlatform.c @@ -716,8 +716,9 @@ Returns: } +STATIC VOID -PciInitialization ( +PciInitializationPIIX ( ) { // @@ -765,6 +766,55 @@ PciInitialization ( } +STATIC +VOID +PciInitializationQ35 ( + ) +{ + // + // Bus 0, Device 0x1f, Function 0 - LPC Bridge: Initialize PIC IRQ routing + // + PciWrite8 (PCI_LIB_ADDRESS (0, 0x1f, 0, 0x60), 0x0a); // LNKA routing target + PciWrite8 (PCI_LIB_ADDRESS (0, 0x1f, 0, 0x61), 0x0a); // LNKB routing target + PciWrite8 (PCI_LIB_ADDRESS (0, 0x1f, 0, 0x62), 0x0b); // LNKC routing target + PciWrite8 (PCI_LIB_ADDRESS (0, 0x1f, 0, 0x63), 0x0b); // LNKD routing target + PciWrite8 (PCI_LIB_ADDRESS (0, 0x1f, 0, 0x68), 0x0a); // LNKE routing target + PciWrite8 (PCI_LIB_ADDRESS (0, 0x1f, 0, 0x69), 0x0a); // LNKF routing target + PciWrite8 (PCI_LIB_ADDRESS (0, 0x1f, 0, 0x6a), 0x0b); // LNKG routing target + PciWrite8 (PCI_LIB_ADDRESS (0, 0x1f, 0, 0x6b), 0x0b); // LNKH routing target +} + + +// +// Distinguish between Q35 and PIIX host bridges +// +#define PCI_DEVICE_ID_INTEL_82441 0x1237 // DID value for PIIX4 +#define PCI_DEVICE_ID_INTEL_Q35_MCH 0x29C0 // DID value for Q35 + +#define HOSTBRIDGE_DID PCI_LIB_ADDRESS (0, 0, 0, 0x02) +#define IS_Q35_HOSTBRIDGE (PciRead16 (HOSTBRIDGE_DID) == PCI_DEVICE_ID_INTEL_Q35_MCH) + + +VOID +PciInitialization ( + ) +{ + if (IS_Q35_HOSTBRIDGE) { + PciInitializationQ35 (); + } else { + PciInitializationPIIX (); + } +} + + +// +// Locate PMCNTRL register (0x40) on the appropriate (Q35 vs. PIIX) host bridge +// +#define PMCNTRL_PIIX PCI_LIB_ADDRESS (0, 1, 3, 0x40) +#define PMCNTRL_Q35 PCI_LIB_ADDRESS (0, 0x1f, 0, 0x40) +#define PMCNTRL (IS_Q35_HOSTBRIDGE ? PMCNTRL_Q35 : PMCNTRL_PIIX) + + VOID AcpiInitialization ( VOID @@ -773,7 +823,7 @@ AcpiInitialization ( // // Set ACPI SCI_EN bit in PMCNTRL // - IoOr16 ((PciRead32 (PCI_LIB_ADDRESS (0, 1, 3, 0x40)) & ~BIT0) + 4, BIT0); + IoOr16 ((PciRead32 (PMCNTRL) & ~BIT0) + 4, BIT0); }