summaryrefslogtreecommitdiff
path: root/ArmPlatformPkg
diff options
context:
space:
mode:
authorOlivier Martin <Olivier.Martin@arm.com>2015-05-27 15:06:11 +0000
committeroliviermartin <oliviermartin@Edk2>2015-05-27 15:06:11 +0000
commite0ae276139a24baea95f6fc2f97892263d0e0443 (patch)
tree143df5df0c99efad8c5a4e8625655e36b4e1db57 /ArmPlatformPkg
parent0ad3c50558955afddcc03b5dfbce0b53665cbbff (diff)
downloadedk2-platforms-e0ae276139a24baea95f6fc2f97892263d0e0443.tar.xz
ArmPlatformPkg/ArmJunoPkg: ACPI PCI Support
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
Diffstat (limited to 'ArmPlatformPkg')
-rw-r--r--ArmPlatformPkg/ArmJunoPkg/AcpiTables/AcpiSsdtRootPci.asl176
-rw-r--r--ArmPlatformPkg/ArmJunoPkg/AcpiTables/AcpiTables.inf3
-rw-r--r--ArmPlatformPkg/ArmJunoPkg/Drivers/ArmJunoDxe/AcpiTables.c78
-rw-r--r--ArmPlatformPkg/ArmJunoPkg/Drivers/ArmJunoDxe/ArmJunoDxe.c44
-rw-r--r--ArmPlatformPkg/ArmJunoPkg/Drivers/ArmJunoDxe/ArmJunoDxe.inf8
-rw-r--r--ArmPlatformPkg/ArmJunoPkg/Drivers/ArmJunoDxe/ArmJunoDxeInternal.h12
6 files changed, 316 insertions, 5 deletions
diff --git a/ArmPlatformPkg/ArmJunoPkg/AcpiTables/AcpiSsdtRootPci.asl b/ArmPlatformPkg/ArmJunoPkg/AcpiTables/AcpiSsdtRootPci.asl
new file mode 100644
index 0000000000..c6d5a9a7de
--- /dev/null
+++ b/ArmPlatformPkg/ArmJunoPkg/AcpiTables/AcpiSsdtRootPci.asl
@@ -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
+ }
+}
diff --git a/ArmPlatformPkg/ArmJunoPkg/AcpiTables/AcpiTables.inf b/ArmPlatformPkg/ArmJunoPkg/AcpiTables/AcpiTables.inf
index 76a0d0aa34..92a1c25354 100644
--- a/ArmPlatformPkg/ArmJunoPkg/AcpiTables/AcpiTables.inf
+++ b/ArmPlatformPkg/ArmJunoPkg/AcpiTables/AcpiTables.inf
@@ -2,7 +2,7 @@
#
# ACPI table data and ASL sources required to boot the platform.
#
-# Copyright (c) 2014, ARM Ltd. All rights reserved.
+# Copyright (c) 2014-2015, ARM Ltd. All rights reserved.
#
# This program and the accompanying materials
# are licensed and made available under the terms and conditions of the BSD License
@@ -27,6 +27,7 @@
Fadt.aslc
Gtdt.aslc
Madt.aslc
+ AcpiSsdtRootPci.asl # Juno R1 specific
[Packages]
ArmPkg/ArmPkg.dec
diff --git a/ArmPlatformPkg/ArmJunoPkg/Drivers/ArmJunoDxe/AcpiTables.c b/ArmPlatformPkg/ArmJunoPkg/Drivers/ArmJunoDxe/AcpiTables.c
new file mode 100644
index 0000000000..bf08346434
--- /dev/null
+++ b/ArmPlatformPkg/ArmJunoPkg/Drivers/ArmJunoDxe/AcpiTables.c
@@ -0,0 +1,78 @@
+/** @file
+
+ This file contains support for ACPI Tables that are generated at boot time.
+
+ Copyright (c) 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"
+#include "ArmJunoDxeInternal.h"
+
+#include <IndustryStandard/MemoryMappedConfigurationSpaceAccessTable.h>
+
+/*
+ * Memory Mapped Configuration Space Access Table (MCFG)
+ */
+typedef struct {
+ EFI_ACPI_MEMORY_MAPPED_CONFIGURATION_BASE_ADDRESS_TABLE_HEADER Header;
+ EFI_ACPI_MEMORY_MAPPED_ENHANCED_CONFIGURATION_SPACE_BASE_ADDRESS_ALLOCATION_STRUCTURE Entry;
+} MEMORY_MAPPED_CONFIGURATION_SPACE_BASE_ACCESS_TABLE;
+
+MEMORY_MAPPED_CONFIGURATION_SPACE_BASE_ACCESS_TABLE mAcpiMcfgTable = {
+ {
+ ARM_ACPI_HEADER (
+ EFI_ACPI_5_0_PCI_EXPRESS_MEMORY_MAPPED_CONFIGURATION_SPACE_BASE_ADDRESS_DESCRIPTION_TABLE_SIGNATURE,
+ MEMORY_MAPPED_CONFIGURATION_SPACE_BASE_ACCESS_TABLE,
+ EFI_ACPI_MEMORY_MAPPED_CONFIGURATION_SPACE_ACCESS_TABLE_REVISION
+ ),
+ 0, // Reserved
+ }, {
+ FixedPcdGet32 (PcdPciConfigurationSpaceBaseAddress),
+ 0, // PciSegmentGroupNumber
+ FixedPcdGet32 (PcdPciBusMin),
+ FixedPcdGet32 (PcdPciBusMax),
+ 0 // Reserved;
+ }
+};
+
+/**
+ * Callback called when ACPI Protocol is installed
+ */
+VOID
+AcpiPciNotificationEvent (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ EFI_STATUS Status;
+ EFI_ACPI_TABLE_PROTOCOL *AcpiTableProtocol;
+ UINTN AcpiTableKey;
+
+ //
+ // Ensure the ACPI protocol is installed
+ //
+ Status = gBS->LocateProtocol (
+ &gEfiAcpiTableProtocolGuid,
+ NULL,
+ (VOID**)&AcpiTableProtocol
+ );
+ if (EFI_ERROR (Status)) {
+ return;
+ }
+
+ //
+ // Install MCFG Table
+ //
+ AcpiTableKey = 0;
+ Status = AcpiTableProtocol->InstallAcpiTable (AcpiTableProtocol, &mAcpiMcfgTable, sizeof (mAcpiMcfgTable), &AcpiTableKey);
+ ASSERT_EFI_ERROR (Status);
+}
diff --git a/ArmPlatformPkg/ArmJunoPkg/Drivers/ArmJunoDxe/ArmJunoDxe.c b/ArmPlatformPkg/ArmJunoPkg/Drivers/ArmJunoDxe/ArmJunoDxe.c
index 386cf08e32..629d03a9ba 100644
--- a/ArmPlatformPkg/ArmJunoPkg/Drivers/ArmJunoDxe/ArmJunoDxe.c
+++ b/ArmPlatformPkg/ArmJunoPkg/Drivers/ArmJunoDxe/ArmJunoDxe.c
@@ -78,6 +78,8 @@ STATIC CONST EFI_PCI_ROOT_BRIDGE_DEVICE_PATH mPciRootComplexDevicePath = {
}
};
+EFI_EVENT mAcpiRegistration = NULL;
+
/**
* Build and Set UEFI Variable Boot####
*
@@ -187,6 +189,24 @@ OnEndOfDxe (
ASSERT_EFI_ERROR (Status);
}
+STATIC
+BOOLEAN
+AcpiTableJunoR0Check (
+ IN EFI_ACPI_DESCRIPTION_HEADER *AcpiHeader
+ )
+{
+ return TRUE;
+}
+
+STATIC
+BOOLEAN
+AcpiTableJunoR1Check (
+ IN EFI_ACPI_DESCRIPTION_HEADER *AcpiHeader
+ )
+{
+ return TRUE;
+}
+
EFI_STATUS
EFIAPI
ArmJunoEntryPoint (
@@ -297,9 +317,19 @@ ArmJunoEntryPoint (
}
//
- // Set the R1 two boot options if not already done.
+ // Try to install the ACPI Tables
//
+ if (JunoRevision == JUNO_R0) {
+ Status = LocateAndInstallAcpiFromFvConditional (&mJunoAcpiTableFile, AcpiTableJunoR0Check);
+ } else if (JunoRevision == JUNO_R1) {
+ Status = LocateAndInstallAcpiFromFvConditional (&mJunoAcpiTableFile, AcpiTableJunoR1Check);
+ }
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Set the R1 two boot options if not already done.
+ //
if (JunoRevision == JUNO_R1) {
Status = SetJunoR1DefaultBootEntries ();
if (EFI_ERROR (Status)) {
@@ -308,6 +338,15 @@ ArmJunoEntryPoint (
// Enable PCI enumeration
PcdSetBool (PcdPciDisableBusEnumeration, FALSE);
+
+ // Declare the related ACPI Tables
+ EfiCreateProtocolNotifyEvent (
+ &gEfiAcpiTableProtocolGuid,
+ TPL_CALLBACK,
+ AcpiPciNotificationEvent,
+ NULL,
+ &mAcpiRegistration
+ );
}
//
@@ -342,9 +381,6 @@ ArmJunoEntryPoint (
return Status;
}
- // Try to install the ACPI Tables
- Status = LocateAndInstallAcpiFromFv (&mJunoAcpiTableFile);
-
return Status;
}
diff --git a/ArmPlatformPkg/ArmJunoPkg/Drivers/ArmJunoDxe/ArmJunoDxe.inf b/ArmPlatformPkg/ArmJunoPkg/Drivers/ArmJunoDxe/ArmJunoDxe.inf
index 9013977c61..6157f9807f 100644
--- a/ArmPlatformPkg/ArmJunoPkg/Drivers/ArmJunoDxe/ArmJunoDxe.inf
+++ b/ArmPlatformPkg/ArmJunoPkg/Drivers/ArmJunoDxe/ArmJunoDxe.inf
@@ -19,6 +19,7 @@
ENTRY_POINT = ArmJunoEntryPoint
[Sources.common]
+ AcpiTables.c
ArmJunoDxe.c
PciEmulation.c
PciRootBridgeIo.c
@@ -26,6 +27,7 @@
[Packages]
ArmPkg/ArmPkg.dec
ArmPlatformPkg/ArmPlatformPkg.dec
+ ArmPlatformPkg/ArmVExpressPkg/ArmVExpressPkg.dec
ArmPlatformPkg/ArmJunoPkg/ArmJuno.dec
EmbeddedPkg/EmbeddedPkg.dec
MdePkg/MdePkg.dec
@@ -60,6 +62,7 @@
gEfiPciIoProtocolGuid
gEfiPciRootBridgeIoProtocolGuid
gEfiSimpleFileSystemProtocolGuid
+ gEfiAcpiTableProtocolGuid
[FixedPcd]
gArmTokenSpaceGuid.PcdSystemMemoryBase
@@ -78,6 +81,11 @@
gArmPlatformTokenSpaceGuid.PcdDefaultBootDevicePath
gArmPlatformTokenSpaceGuid.PcdDefaultBootArgument
+ # PCI Root complex specific PCDs
+ gArmJunoTokenSpaceGuid.PcdPciConfigurationSpaceBaseAddress
+ gArmPlatformTokenSpaceGuid.PcdPciBusMin
+ gArmPlatformTokenSpaceGuid.PcdPciBusMax
+
[Pcd]
gEmbeddedTokenSpaceGuid.PcdFdtDevicePaths
gEfiMdeModulePkgTokenSpaceGuid.PcdPciDisableBusEnumeration
diff --git a/ArmPlatformPkg/ArmJunoPkg/Drivers/ArmJunoDxe/ArmJunoDxeInternal.h b/ArmPlatformPkg/ArmJunoPkg/Drivers/ArmJunoDxe/ArmJunoDxeInternal.h
index c7b1865877..662c41377f 100644
--- a/ArmPlatformPkg/ArmJunoPkg/Drivers/ArmJunoDxe/ArmJunoDxeInternal.h
+++ b/ArmPlatformPkg/ArmJunoPkg/Drivers/ArmJunoDxe/ArmJunoDxeInternal.h
@@ -23,6 +23,9 @@
#include <Library/DebugLib.h>
#include <Library/DxeServicesTableLib.h>
#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiLib.h>
+
+#include <Protocol/AcpiTable.h>
#include <IndustryStandard/Acpi.h>
@@ -31,4 +34,13 @@ PciEmulationEntryPoint (
VOID
);
+/**
+ * Callback called when ACPI Protocol is installed
+ */
+VOID
+AcpiPciNotificationEvent (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ );
+
#endif // __ARM_JUNO_DXE_INTERNAL_H__