]> git.proxmox.com Git - mirror_edk2.git/commitdiff
ArmPlatformPkg/ArmJunoPkg: ACPI PCI Support
authorOlivier Martin <Olivier.Martin@arm.com>
Wed, 27 May 2015 15:06:11 +0000 (15:06 +0000)
committeroliviermartin <oliviermartin@Edk2>
Wed, 27 May 2015 15:06:11 +0000 (15:06 +0000)
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Olivier Martin <Olivier.Martin@arm.com>
Reviewed-by: Ronald Cron <Ronald.Cron@arm.com>
git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@17522 6f19259b-4bc3-4df7-8a09-765794883524

ArmPlatformPkg/ArmJunoPkg/AcpiTables/AcpiSsdtRootPci.asl [new file with mode: 0644]
ArmPlatformPkg/ArmJunoPkg/AcpiTables/AcpiTables.inf
ArmPlatformPkg/ArmJunoPkg/Drivers/ArmJunoDxe/AcpiTables.c [new file with mode: 0644]
ArmPlatformPkg/ArmJunoPkg/Drivers/ArmJunoDxe/ArmJunoDxe.c
ArmPlatformPkg/ArmJunoPkg/Drivers/ArmJunoDxe/ArmJunoDxe.inf
ArmPlatformPkg/ArmJunoPkg/Drivers/ArmJunoDxe/ArmJunoDxeInternal.h

diff --git a/ArmPlatformPkg/ArmJunoPkg/AcpiTables/AcpiSsdtRootPci.asl b/ArmPlatformPkg/ArmJunoPkg/AcpiTables/AcpiSsdtRootPci.asl
new file mode 100644 (file)
index 0000000..c6d5a9a
--- /dev/null
@@ -0,0 +1,176 @@
+/** @file
+  Differentiated System Description Table Fields (SSDT)
+
+  Copyright (c) 2014-2015, ARM Ltd. All rights reserved.<BR>
+    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.
+
+**/
+
+#include "ArmPlatform.h"
+
+/*
+  See Reference [1] 6.2.12
+  "There are two ways that _PRT can be used. ...
+  In the second model, the PCI interrupts are hardwired to specific interrupt
+  inputs on the interrupt controller and are not configurable. In this case,
+  the Source field in _PRT does not reference a device, but instead contains
+  the value zero, and the Source Index field contains the global system
+  interrupt to which the PCI interrupt is hardwired."
+*/
+#define PRT_ENTRY(Address, Pin, Interrupt)                                                       \
+          Package (4) {                                                                           \
+            Address,    /* uses the same format as _ADR */                                        \
+            Pin,        /* The PCI pin number of the device (0-INTA, 1-INTB, 2-INTC, 3-INTD). */  \
+            Zero,       /* allocated from the global interrupt pool. */                           \
+            Interrupt   /* global system interrupt number */                                      \
+          }
+
+/*
+  See Reference [1] 6.1.1
+  "High word–Device #, Low word–Function #. (for example, device 3, function 2 is
+   0x00030002). To refer to all the functions on a device #, use a function number of FFFF)."
+*/
+#define ROOT_PRT_ENTRY(Pin, Interrupt)   PRT_ENTRY(0x0000FFFF, Pin, Interrupt)
+                                                    // Device 0 for Bridge.
+
+
+DefinitionBlock("SsdtPci.aml", "SSDT", 1, "ARMLTD", "ARM-JUNO", EFI_ACPI_ARM_OEM_REVISION) {
+  Scope(_SB) {
+       //
+       // PCI Root Complex
+       //
+       Device(PCI0)
+    {
+               Name(_HID, EISAID("PNP0A08")) // PCI Express Root Bridge
+               Name(_CID, EISAID("PNP0A03")) // Compatible PCI Root Bridge
+               Name(_SEG, Zero) // PCI Segment Group number
+               Name(_BBN, Zero) // PCI Base Bus Number
+
+        // Root Complex 0
+        Device (RP0) {
+            Name(_ADR, 0xF0000000)    // Dev 0, Func 0
+        }
+
+        // PCI Routing Table
+               Name(_PRT, Package() {
+               ROOT_PRT_ENTRY(0, 136),   // INTA
+               ROOT_PRT_ENTRY(1, 137),   // INTB
+               ROOT_PRT_ENTRY(2, 138),   // INTC
+               ROOT_PRT_ENTRY(3, 139),   // INTD
+       })
+        // Root complex resources
+               Method (_CRS, 0, Serialized) {
+                       Name (RBUF, ResourceTemplate () {
+                               WordBusNumber ( // Bus numbers assigned to this root
+                                       ResourceProducer,
+                                       MinFixed, MaxFixed, PosDecode,
+                                       0,   // AddressGranularity
+                                       0,   // AddressMinimum - Minimum Bus Number
+                                       255, // AddressMaximum - Maximum Bus Number
+                                       0,   // AddressTranslation - Set to 0
+                                       256  // RangeLength - Number of Busses
+                               )
+
+                               DWordMemory ( // 32-bit BAR Windows
+                                       ResourceProducer, PosDecode,
+                                       MinFixed, MaxFixed,
+                                       Cacheable, ReadWrite,
+                                       0x00000000,                                                     // Granularity
+                                       0x50000000,                                                     // Min Base Address
+                                       0x57FFFFFF,                                                     // Max Base Address
+                                       0x00000000,                                                     // Translate
+                                       0x08000000                                                              // Length
+                               )
+               
+                               QWordMemory ( // 64-bit BAR Windows
+                                       ResourceProducer, PosDecode,
+                                       MinFixed, MaxFixed,
+                                       Cacheable, ReadWrite,
+                                       0x00000000,                                                     // Granularity
+                                       0x4000000000,                                                   // Min Base Address
+                                       0x40FFFFFFFF,                                                   // Max Base Address
+                                       0x00000000,                                                     // Translate
+                                       0x100000000                                                             // Length
+                               )
+                       }) // Name(RBUF)
+                       
+                       Return (RBUF)
+               } // Method(_CRS)
+
+               //
+               // OS Control Handoff
+               //
+               Name(SUPP, Zero) // PCI _OSC Support Field value
+               Name(CTRL, Zero) // PCI _OSC Control Field value
+
+               /*
+         See [1] 6.2.10, [2] 4.5
+               */
+               Method(_OSC,4) {
+                       // Check for proper UUID
+                       If(LEqual(Arg0,ToUUID("33DB4D5B-1FF7-401C-9657-7441C03DD766"))) {
+                               // Create DWord-adressable fields from the Capabilities Buffer
+                               CreateDWordField(Arg3,0,CDW1)
+                               CreateDWordField(Arg3,4,CDW2)
+                               CreateDWordField(Arg3,8,CDW3)
+
+                               // Save Capabilities DWord2 & 3
+                               Store(CDW2,SUPP)
+                               Store(CDW3,CTRL)
+
+                               // Only allow native hot plug control if OS supports:
+                               // * ASPM
+                               // * Clock PM
+                               // * MSI/MSI-X
+                               If(LNotEqual(And(SUPP, 0x16), 0x16)) {
+                                       And(CTRL,0x1E,CTRL) // Mask bit 0 (and undefined bits)
+                               }
+
+                               // Always allow native PME, AER (no dependencies)
+
+                               // Never allow SHPC (no SHPC controller in this system)
+                               And(CTRL,0x1D,CTRL)
+
+#if 0
+                               If(LNot(And(CDW1,1))) {         // Query flag clear?
+                                       // Disable GPEs for features granted native control.
+                                       If(And(CTRL,0x01)) {    // Hot plug control granted?
+                                               Store(0,HPCE)           // clear the hot plug SCI enable bit
+                                               Store(1,HPCS)           // clear the hot plug SCI status bit
+                                       }
+                                       If(And(CTRL,0x04)) {    // PME control granted?
+                                               Store(0,PMCE)           // clear the PME SCI enable bit
+                                               Store(1,PMCS)           // clear the PME SCI status bit
+                                       }
+                                       If(And(CTRL,0x10)) {    // OS restoring PCIe cap structure?
+                                               // Set status to not restore PCIe cap structure
+                                               // upon resume from S3
+                                               Store(1,S3CR)
+                                       }
+                               }
+#endif
+
+                               If(LNotEqual(Arg1,One)) {       // Unknown revision
+                                       Or(CDW1,0x08,CDW1)
+                               }
+
+                               If(LNotEqual(CDW3,CTRL)) {      // Capabilities bits were masked
+                                       Or(CDW1,0x10,CDW1)
+                               }
+                               // Update DWORD3 in the buffer
+                               Store(CTRL,CDW3)
+                               Return(Arg3)
+                       } Else {
+                               Or(CDW1,4,CDW1) // Unrecognized UUID
+                               Return(Arg3)
+                       }
+               } // End _OSC
+    } // PCI0
+  }
+}
index 76a0d0aa349b08055a53d0a97bbd08ec3c0922bb..92a1c25354d0acf2dd2e43c3c86a70e43953ebe8 100644 (file)
@@ -2,7 +2,7 @@
 #\r
 #  ACPI table data and ASL sources required to boot the platform.\r
 #\r
-#  Copyright (c) 2014, ARM Ltd. All rights reserved.\r
+#  Copyright (c) 2014-2015, ARM Ltd. All rights reserved.\r
 #\r
 #  This program and the accompanying materials\r
 #  are licensed and made available under the terms and conditions of the BSD License\r
@@ -27,6 +27,7 @@
   Fadt.aslc\r
   Gtdt.aslc\r
   Madt.aslc\r
+  AcpiSsdtRootPci.asl          # Juno R1 specific\r
 \r
 [Packages]\r
   ArmPkg/ArmPkg.dec\r
diff --git a/ArmPlatformPkg/ArmJunoPkg/Drivers/ArmJunoDxe/AcpiTables.c b/ArmPlatformPkg/ArmJunoPkg/Drivers/ArmJunoDxe/AcpiTables.c
new file mode 100644 (file)
index 0000000..bf08346
--- /dev/null
@@ -0,0 +1,78 @@
+/** @file\r
+\r
+  This file contains support for ACPI Tables that are generated at boot time.\r
+\r
+  Copyright (c) 2015, ARM Ltd. All rights reserved.<BR>\r
+\r
+  This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include "ArmPlatform.h"\r
+#include "ArmJunoDxeInternal.h"\r
+\r
+#include <IndustryStandard/MemoryMappedConfigurationSpaceAccessTable.h>\r
+\r
+/*\r
+ * Memory Mapped Configuration Space Access Table (MCFG)\r
+ */\r
+typedef struct {\r
+  EFI_ACPI_MEMORY_MAPPED_CONFIGURATION_BASE_ADDRESS_TABLE_HEADER                        Header;\r
+  EFI_ACPI_MEMORY_MAPPED_ENHANCED_CONFIGURATION_SPACE_BASE_ADDRESS_ALLOCATION_STRUCTURE Entry;\r
+} MEMORY_MAPPED_CONFIGURATION_SPACE_BASE_ACCESS_TABLE;\r
+\r
+MEMORY_MAPPED_CONFIGURATION_SPACE_BASE_ACCESS_TABLE mAcpiMcfgTable = {\r
+    {\r
+        ARM_ACPI_HEADER (\r
+          EFI_ACPI_5_0_PCI_EXPRESS_MEMORY_MAPPED_CONFIGURATION_SPACE_BASE_ADDRESS_DESCRIPTION_TABLE_SIGNATURE,\r
+          MEMORY_MAPPED_CONFIGURATION_SPACE_BASE_ACCESS_TABLE,\r
+          EFI_ACPI_MEMORY_MAPPED_CONFIGURATION_SPACE_ACCESS_TABLE_REVISION\r
+        ),\r
+        0, // Reserved\r
+    }, {\r
+        FixedPcdGet32 (PcdPciConfigurationSpaceBaseAddress),\r
+        0, // PciSegmentGroupNumber\r
+        FixedPcdGet32 (PcdPciBusMin),\r
+        FixedPcdGet32 (PcdPciBusMax),\r
+        0 // Reserved;\r
+    }\r
+};\r
+\r
+/**\r
+ * Callback called when ACPI Protocol is installed\r
+ */\r
+VOID\r
+AcpiPciNotificationEvent (\r
+  IN  EFI_EVENT                Event,\r
+  IN  VOID                     *Context\r
+  )\r
+{\r
+  EFI_STATUS                Status;\r
+  EFI_ACPI_TABLE_PROTOCOL   *AcpiTableProtocol;\r
+  UINTN                     AcpiTableKey;\r
+\r
+  //\r
+  // Ensure the ACPI protocol is installed\r
+  //\r
+  Status = gBS->LocateProtocol (\r
+                  &gEfiAcpiTableProtocolGuid,\r
+                  NULL,\r
+                  (VOID**)&AcpiTableProtocol\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    return;\r
+  }\r
+\r
+  //\r
+  // Install MCFG Table\r
+  //\r
+  AcpiTableKey = 0;\r
+  Status = AcpiTableProtocol->InstallAcpiTable (AcpiTableProtocol, &mAcpiMcfgTable, sizeof (mAcpiMcfgTable), &AcpiTableKey);\r
+  ASSERT_EFI_ERROR (Status);\r
+}\r
index 386cf08e32d7d580231e5e4bbbc9bd603d8c8ca9..629d03a9ba96a15a75e5070d017eadb7d4084727 100644 (file)
@@ -78,6 +78,8 @@ STATIC CONST EFI_PCI_ROOT_BRIDGE_DEVICE_PATH mPciRootComplexDevicePath = {
     }\r
 };\r
 \r
+EFI_EVENT mAcpiRegistration = NULL;\r
+\r
 /**\r
  * Build and Set UEFI Variable Boot####\r
  *\r
@@ -187,6 +189,24 @@ OnEndOfDxe (
   ASSERT_EFI_ERROR (Status);\r
 }\r
 \r
+STATIC\r
+BOOLEAN\r
+AcpiTableJunoR0Check (\r
+  IN  EFI_ACPI_DESCRIPTION_HEADER *AcpiHeader\r
+  )\r
+{\r
+  return TRUE;\r
+}\r
+\r
+STATIC\r
+BOOLEAN\r
+AcpiTableJunoR1Check (\r
+  IN  EFI_ACPI_DESCRIPTION_HEADER *AcpiHeader\r
+  )\r
+{\r
+  return TRUE;\r
+}\r
+\r
 EFI_STATUS\r
 EFIAPI\r
 ArmJunoEntryPoint (\r
@@ -297,9 +317,19 @@ ArmJunoEntryPoint (
   }\r
 \r
   //\r
-  // Set the R1 two boot options if not already done.\r
+  // Try to install the ACPI Tables\r
   //\r
+  if (JunoRevision == JUNO_R0) {\r
+    Status = LocateAndInstallAcpiFromFvConditional (&mJunoAcpiTableFile, AcpiTableJunoR0Check);\r
+  } else if (JunoRevision == JUNO_R1) {\r
+    Status = LocateAndInstallAcpiFromFvConditional (&mJunoAcpiTableFile, AcpiTableJunoR1Check);\r
+  }\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
 \r
+  //\r
+  // Set the R1 two boot options if not already done.\r
+  //\r
   if (JunoRevision == JUNO_R1) {\r
     Status = SetJunoR1DefaultBootEntries ();\r
     if (EFI_ERROR (Status)) {\r
@@ -308,6 +338,15 @@ ArmJunoEntryPoint (
 \r
     // Enable PCI enumeration\r
     PcdSetBool (PcdPciDisableBusEnumeration, FALSE);\r
+\r
+    // Declare the related ACPI Tables\r
+    EfiCreateProtocolNotifyEvent (\r
+        &gEfiAcpiTableProtocolGuid,\r
+        TPL_CALLBACK,\r
+        AcpiPciNotificationEvent,\r
+        NULL,\r
+        &mAcpiRegistration\r
+        );\r
   }\r
 \r
   //\r
@@ -342,9 +381,6 @@ ArmJunoEntryPoint (
     return Status;\r
   }\r
 \r
-  // Try to install the ACPI Tables\r
-  Status = LocateAndInstallAcpiFromFv (&mJunoAcpiTableFile);\r
-\r
   return Status;\r
 }\r
 \r
index 9013977c615e83f93ae7ab3d39ace061d0cb0cf9..6157f9807fafd87588b34d42dd44bb8214242f83 100644 (file)
@@ -19,6 +19,7 @@
   ENTRY_POINT                    = ArmJunoEntryPoint\r
 \r
 [Sources.common]\r
+  AcpiTables.c\r
   ArmJunoDxe.c\r
   PciEmulation.c\r
   PciRootBridgeIo.c\r
@@ -26,6 +27,7 @@
 [Packages]\r
   ArmPkg/ArmPkg.dec\r
   ArmPlatformPkg/ArmPlatformPkg.dec\r
+  ArmPlatformPkg/ArmVExpressPkg/ArmVExpressPkg.dec\r
   ArmPlatformPkg/ArmJunoPkg/ArmJuno.dec\r
   EmbeddedPkg/EmbeddedPkg.dec\r
   MdePkg/MdePkg.dec\r
@@ -60,6 +62,7 @@
   gEfiPciIoProtocolGuid\r
   gEfiPciRootBridgeIoProtocolGuid\r
   gEfiSimpleFileSystemProtocolGuid\r
+  gEfiAcpiTableProtocolGuid\r
 \r
 [FixedPcd]\r
   gArmTokenSpaceGuid.PcdSystemMemoryBase\r
   gArmPlatformTokenSpaceGuid.PcdDefaultBootDevicePath\r
   gArmPlatformTokenSpaceGuid.PcdDefaultBootArgument\r
 \r
+  # PCI Root complex specific PCDs\r
+  gArmJunoTokenSpaceGuid.PcdPciConfigurationSpaceBaseAddress\r
+  gArmPlatformTokenSpaceGuid.PcdPciBusMin\r
+  gArmPlatformTokenSpaceGuid.PcdPciBusMax\r
+\r
 [Pcd]\r
   gEmbeddedTokenSpaceGuid.PcdFdtDevicePaths\r
   gEfiMdeModulePkgTokenSpaceGuid.PcdPciDisableBusEnumeration\r
index c7b1865877a722339cb755923748a99e0000f840..662c41377f45a522bfac63103746f5b79e0ffa5e 100644 (file)
@@ -23,6 +23,9 @@
 #include <Library/DebugLib.h>\r
 #include <Library/DxeServicesTableLib.h>\r
 #include <Library/UefiBootServicesTableLib.h>\r
+#include <Library/UefiLib.h>\r
+\r
+#include <Protocol/AcpiTable.h>\r
 \r
 #include <IndustryStandard/Acpi.h>\r
 \r
@@ -31,4 +34,13 @@ PciEmulationEntryPoint (
   VOID\r
   );\r
 \r
+/**\r
+ * Callback called when ACPI Protocol is installed\r
+ */\r
+VOID\r
+AcpiPciNotificationEvent (\r
+  IN  EFI_EVENT                Event,\r
+  IN  VOID                     *Context\r
+  );\r
+\r
 #endif // __ARM_JUNO_DXE_INTERNAL_H__\r