Factor out logic to distinguish between Q35 and PIIX4 platforms
into a separate header (OvmfPkg/Include/Library/PciHostBridge.h),
then refer to these macros from all relevant source locations
throughouth OvmfPkg.

This patch also adds a Q35-specific PIC IRQ routing initialization
function to OvmfPkg/Library/PlatformBdsLib/BdsPlatform.c

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Gabriel Somlo <[email protected]>
---

As discussed with Laszlo and Paolo in an earlier thread, this stuff should
hopefully be mostly uncontroversial and "the right thing to do" to support
Q35. Doesn't fix my weird OS X / Q35 / UHCI issues, but I guess that's a
whole different fight to be fought another day :)

The one thing I'm a bit unsure about is PciInitializationQ35 (BdsPlatform.c);
In PciInitializationPIIX (which used to be plain PciInitialization before
this patch), there's a whole bunch of other devices (ide, video, network,
etc.) being initialized by writing to registers which should mostly be
read-only on Q35; Leaving that stuff out from PciInitializationQ35 doesn't
seem to have any effect, negative or otherwise, so I decided to stick to
LNK* routing initialization only.

Any comments/suggestions much appreciated, as always.

Thanks,
  Gabriel

 OvmfPkg/Csm/CsmSupportLib/LegacyInterrupt.h  |  4 +-
 OvmfPkg/Include/Library/PciHostBridge.h      | 44 ++++++++++++++++
 OvmfPkg/Library/AcpiTimerLib/AcpiTimerLib.c  | 78 ++--------------------------
 OvmfPkg/Library/PlatformBdsLib/BdsPlatform.c | 36 ++++++++++++-
 OvmfPkg/Library/PlatformBdsLib/BdsPlatform.h |  1 +
 OvmfPkg/PlatformPei/Platform.c               |  9 ++--
 6 files changed, 90 insertions(+), 82 deletions(-)
 create mode 100644 OvmfPkg/Include/Library/PciHostBridge.h

diff --git a/OvmfPkg/Csm/CsmSupportLib/LegacyInterrupt.h 
b/OvmfPkg/Csm/CsmSupportLib/LegacyInterrupt.h
index 193e48b..712e8d5 100644
--- a/OvmfPkg/Csm/CsmSupportLib/LegacyInterrupt.h
+++ b/OvmfPkg/Csm/CsmSupportLib/LegacyInterrupt.h
@@ -23,9 +23,11 @@
 #include <Library/PciLib.h>
 #include <Library/DebugLib.h>
 #include <Library/UefiBootServicesTableLib.h>
+#include <Library/PciHostBridge.h>
+
 
 #define LEGACY_INT_BUS  0
-#define LEGACY_INT_DEV  1
+#define LEGACY_INT_DEV  (IS_Q35_HOSTBRIDGE ? 0x1f : 1)
 #define LEGACY_INT_FUNC 0
 
 #define PIRQN           0x00  // PIRQ Null
diff --git a/OvmfPkg/Include/Library/PciHostBridge.h 
b/OvmfPkg/Include/Library/PciHostBridge.h
new file mode 100644
index 0000000..f85a413
--- /dev/null
+++ b/OvmfPkg/Include/Library/PciHostBridge.h
@@ -0,0 +1,44 @@
+/** @file
+  PCI Host Bridge (PIIX4 vs. Q35) dependent device access
+
+  Copyright (c) 2014, Gabriel L. Somlo <[email protected]>
+
+  This program and the accompanying materials are licensed and made
+  available under the terms and conditions of the BSD License which
+  accompanies this distribution.   The full text of the license may
+  be found at http://opensource.org/licenses/bsd-license.php
+
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+**/
+
+#ifndef __PCI_HOST_BRIDGE__
+#define __PCI_HOST_BRIDGE__
+
+#include <Library/PciLib.h>
+
+//
+// Host Bridge Device ID (DID) register values
+//
+#define PCI_DEVICE_ID_INTEL_82441     0x1237  // PIIX4
+#define PCI_DEVICE_ID_INTEL_Q35_MCH   0x29C0  // Q35
+
+//
+// Access Host Bridge Device ID (00:00.0, offset 0x02)
+//
+#define HOSTBRIDGE_DID   PCI_LIB_ADDRESS (0, 0, 0, 0x02)
+
+//
+// Test if we're on a Q35/MCH Host Bridge (assume PIIX4 if false)
+//
+#define IS_Q35_HOSTBRIDGE  (PciRead16 (HOSTBRIDGE_DID) == 
PCI_DEVICE_ID_INTEL_Q35_MCH)
+
+//
+// Access ACPI Power Management register (device 00:1f.0 on Q35, 00:01.3 on 
PIIX)
+//
+#define PCI_PM_REG(Register) \
+  (IS_Q35_HOSTBRIDGE ? \
+   PCI_LIB_ADDRESS (0, 0x1f, 0, Register) : PCI_LIB_ADDRESS (0, 1, 3, 
Register))
+
+
+#endif
diff --git a/OvmfPkg/Library/AcpiTimerLib/AcpiTimerLib.c 
b/OvmfPkg/Library/AcpiTimerLib/AcpiTimerLib.c
index 7d324cb..52b2979 100644
--- a/OvmfPkg/Library/AcpiTimerLib/AcpiTimerLib.c
+++ b/OvmfPkg/Library/AcpiTimerLib/AcpiTimerLib.c
@@ -19,90 +19,18 @@
 #include <Library/BaseLib.h>
 #include <Library/IoLib.h>
 #include <Library/PciLib.h>
+#include <Library/PciHostBridge.h>
 #include <Library/DebugLib.h>
 #include <Library/PcdLib.h>
 #include <IndustryStandard/Pci22.h>
 #include <IndustryStandard/Acpi.h>
 
 //
-// PCI Location of PIIX4 Power Management PCI Configuration Registers
-//
-#define PIIX4_POWER_MANAGEMENT_BUS       0x00
-#define PIIX4_POWER_MANAGEMENT_DEVICE    0x01
-#define PIIX4_POWER_MANAGEMENT_FUNCTION  0x03
-
-//
-// Macro to access PIIX4 Power Management PCI Configuration Registers
-//
-#define PIIX4_PCI_POWER_MANAGEMENT_REGISTER(Register) \
-  PCI_LIB_ADDRESS (                                   \
-    PIIX4_POWER_MANAGEMENT_BUS,                       \
-    PIIX4_POWER_MANAGEMENT_DEVICE,                    \
-    PIIX4_POWER_MANAGEMENT_FUNCTION,                  \
-    Register                                          \
-    )
-
-//
-// PCI Location of Q35 Power Management PCI Configuration Registers
-//
-#define Q35_POWER_MANAGEMENT_BUS       0x00
-#define Q35_POWER_MANAGEMENT_DEVICE    0x1f
-#define Q35_POWER_MANAGEMENT_FUNCTION  0x00
-
-//
-// Macro to access Q35 Power Management PCI Configuration Registers
-//
-#define Q35_PCI_POWER_MANAGEMENT_REGISTER(Register) \
-  PCI_LIB_ADDRESS (                                 \
-    Q35_POWER_MANAGEMENT_BUS,                       \
-    Q35_POWER_MANAGEMENT_DEVICE,                    \
-    Q35_POWER_MANAGEMENT_FUNCTION,                  \
-    Register                                        \
-    )
-
-//
-// PCI Location of Host Bridge PCI Configuration Registers
-//
-#define HOST_BRIDGE_BUS       0x00
-#define HOST_BRIDGE_DEVICE    0x00
-#define HOST_BRIDGE_FUNCTION  0x00
-
-//
-// Macro to access Host Bridge Configuration Registers
-//
-#define HOST_BRIDGE_REGISTER(Register) \
-  PCI_LIB_ADDRESS (                    \
-    HOST_BRIDGE_BUS,                   \
-    HOST_BRIDGE_DEVICE,                \
-    HOST_BRIDGE_FUNCTION,              \
-    Register                           \
-    )
-
-//
-// Host Bridge Device ID (DID) Register
-//
-#define HOST_BRIDGE_DID  HOST_BRIDGE_REGISTER (0x02)
-
-//
-// Host Bridge DID Register values
-//
-#define PCI_DEVICE_ID_INTEL_82441    0x1237  // DID value for PIIX4
-#define PCI_DEVICE_ID_INTEL_Q35_MCH  0x29C0  // DID value for Q35
-
-//
-// Access Power Management PCI Config Regs based on Host Bridge type
-//
-#define PCI_POWER_MANAGEMENT_REGISTER(Register)                   \
-  ((PciRead16 (HOST_BRIDGE_DID) == PCI_DEVICE_ID_INTEL_Q35_MCH) ? \
-    Q35_PCI_POWER_MANAGEMENT_REGISTER (Register) :                \
-    PIIX4_PCI_POWER_MANAGEMENT_REGISTER (Register))
-
-//
 // Power Management PCI Configuration Registers
 //
-#define PMBA                PCI_POWER_MANAGEMENT_REGISTER (0x40)
+#define PMBA                PCI_PM_REG (0x40)
 #define   PMBA_RTE          BIT0
-#define PMREGMISC           PCI_POWER_MANAGEMENT_REGISTER (0x80)
+#define PMREGMISC           PCI_PM_REG (0x80)
 #define   PMIOSE            BIT0
 
 //
diff --git a/OvmfPkg/Library/PlatformBdsLib/BdsPlatform.c 
b/OvmfPkg/Library/PlatformBdsLib/BdsPlatform.c
index 2a1ca88..75efbc2 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,37 @@ 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
+}
+
+
+VOID
+PciInitialization (
+  )
+{
+  if (IS_Q35_HOSTBRIDGE) {
+    PciInitializationQ35 ();
+  } else {
+    PciInitializationPIIX ();
+  }
+}
+
+
 VOID
 AcpiInitialization (
   VOID
@@ -773,7 +805,7 @@ AcpiInitialization (
   //
   // Set ACPI SCI_EN bit in PMCNTRL
   //
-  IoOr16 ((PciRead32 (PCI_LIB_ADDRESS (0, 1, 3, 0x40)) & ~BIT0) + 4, BIT0);
+  IoOr16 ((PciRead32 (PCI_PM_REG (0x40)) & ~BIT0) + 4, BIT0);
 }
 
 
diff --git a/OvmfPkg/Library/PlatformBdsLib/BdsPlatform.h 
b/OvmfPkg/Library/PlatformBdsLib/BdsPlatform.h
index 72b0e14..3a3bc0c 100644
--- a/OvmfPkg/Library/PlatformBdsLib/BdsPlatform.h
+++ b/OvmfPkg/Library/PlatformBdsLib/BdsPlatform.h
@@ -39,6 +39,7 @@ Abstract:
 #include <Library/BaseLib.h>
 #include <Library/PcdLib.h>
 #include <Library/PciLib.h>
+#include <Library/PciHostBridge.h>
 #include <Library/GenericBdsLib.h>
 #include <Library/PlatformBdsLib.h>
 #include <Library/HobLib.h>
diff --git a/OvmfPkg/PlatformPei/Platform.c b/OvmfPkg/PlatformPei/Platform.c
index 11b4cb7..21adab8 100644
--- a/OvmfPkg/PlatformPei/Platform.c
+++ b/OvmfPkg/PlatformPei/Platform.c
@@ -28,6 +28,7 @@
 #include <Library/MemoryAllocationLib.h>
 #include <Library/PcdLib.h>
 #include <Library/PciLib.h>
+#include <Library/PciHostBridge.h>
 #include <Library/PeimEntryPoint.h>
 #include <Library/PeiServicesLib.h>
 #include <Library/QemuFwCfgLib.h>
@@ -243,13 +244,13 @@ MiscInitialization (
   // example by Xen) and skip the setup here. This matches the logic in
   // AcpiTimerLibConstructor ().
   //
-  if ((PciRead8 (PCI_LIB_ADDRESS (0, 1, 3, 0x80)) & 0x01) == 0) {
+  if ((PciRead8 (PCI_PM_REG (0x80)) & 0x01) == 0) {
     //
     // The PEI phase should be exited with fully accessibe PIIX4 IO space:
     // 1. set PMBA
     //
     PciAndThenOr32 (
-      PCI_LIB_ADDRESS (0, 1, 3, 0x40),
+      PCI_PM_REG (0x40),
       (UINT32) ~0xFFC0,
       PcdGet16 (PcdAcpiPmBaseAddress)
       );
@@ -258,14 +259,14 @@ MiscInitialization (
     // 2. set PCICMD/IOSE
     //
     PciOr8 (
-      PCI_LIB_ADDRESS (0, 1, 3, PCI_COMMAND_OFFSET),
+      PCI_PM_REG (PCI_COMMAND_OFFSET),
       EFI_PCI_COMMAND_IO_SPACE
       );
 
     //
     // 3. set PMREGMISC/PMIOSE
     //
-    PciOr8 (PCI_LIB_ADDRESS (0, 1, 3, 0x80), 0x01);
+    PciOr8 (PCI_PM_REG (0x80), 0x01);
   }
 }
 
-- 
1.9.3


------------------------------------------------------------------------------
Meet PCI DSS 3.0 Compliance Requirements with EventLog Analyzer
Achieve PCI DSS 3.0 Compliant Status with Out-of-the-box PCI DSS Reports
Are you Audit-Ready for PCI DSS 3.0 Compliance? Download White paper
Comply to PCI DSS 3.0 Requirement 10 and 11.5 with EventLog Analyzer
http://pubads.g.doubleclick.net/gampad/clk?id=154622311&iu=/4140/ostg.clktrk
_______________________________________________
edk2-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/edk2-devel

Reply via email to