summaryrefslogtreecommitdiff
path: root/Platform/Intel/PurleyOpenBoardPkg/Pci/PciPlatform
diff options
context:
space:
mode:
Diffstat (limited to 'Platform/Intel/PurleyOpenBoardPkg/Pci/PciPlatform')
-rw-r--r--Platform/Intel/PurleyOpenBoardPkg/Pci/PciPlatform/IoApic.h28
-rw-r--r--Platform/Intel/PurleyOpenBoardPkg/Pci/PciPlatform/PciIovPlatformPolicy.c102
-rw-r--r--Platform/Intel/PurleyOpenBoardPkg/Pci/PciPlatform/PciIovPlatformPolicy.h57
-rw-r--r--Platform/Intel/PurleyOpenBoardPkg/Pci/PciPlatform/PciPlatform.c189
-rw-r--r--Platform/Intel/PurleyOpenBoardPkg/Pci/PciPlatform/PciPlatform.h207
-rw-r--r--Platform/Intel/PurleyOpenBoardPkg/Pci/PciPlatform/PciPlatform.inf78
-rw-r--r--Platform/Intel/PurleyOpenBoardPkg/Pci/PciPlatform/PciPlatformHooks.c533
-rw-r--r--Platform/Intel/PurleyOpenBoardPkg/Pci/PciPlatform/PciPlatformHooks.h30
-rw-r--r--Platform/Intel/PurleyOpenBoardPkg/Pci/PciPlatform/PciSupportLib.c109
-rw-r--r--Platform/Intel/PurleyOpenBoardPkg/Pci/PciPlatform/PciSupportLib.h50
10 files changed, 1383 insertions, 0 deletions
diff --git a/Platform/Intel/PurleyOpenBoardPkg/Pci/PciPlatform/IoApic.h b/Platform/Intel/PurleyOpenBoardPkg/Pci/PciPlatform/IoApic.h
new file mode 100644
index 0000000000..55ca9f68fd
--- /dev/null
+++ b/Platform/Intel/PurleyOpenBoardPkg/Pci/PciPlatform/IoApic.h
@@ -0,0 +1,28 @@
+/** @file
+
+Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials are licensed and made available under
+the terms and conditions of the BSD License that 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 _IOAPIC_H_
+#define _IOAPIC_H_
+
+#define EFI_IO_APIC_INDEX_OFFSET 0x00
+#define EFI_IO_APIC_DATA_OFFSET 0x10
+#define EFI_IO_APIC_IRQ_ASSERTION_OFFSET 0x20
+#define EFI_IO_APIC_EOI_OFFSET 0x40
+
+#define EFI_IO_APIC_ID_REGISTER 0x0
+#define EFI_IO_APIC_ID_BITSHIFT 24
+#define EFI_IO_APIC_VER_REGISTER 0x1
+#define EFI_IO_APIC_BOOT_CONFIG_REGISTER 0x3
+#define EFI_IO_APIC_FSB_INT_DELIVERY 0x1
+
+#endif
diff --git a/Platform/Intel/PurleyOpenBoardPkg/Pci/PciPlatform/PciIovPlatformPolicy.c b/Platform/Intel/PurleyOpenBoardPkg/Pci/PciPlatform/PciIovPlatformPolicy.c
new file mode 100644
index 0000000000..6737bbbcf0
--- /dev/null
+++ b/Platform/Intel/PurleyOpenBoardPkg/Pci/PciPlatform/PciIovPlatformPolicy.c
@@ -0,0 +1,102 @@
+/** @file
+
+Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials are licensed and made available under
+the terms and conditions of the BSD License that 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 <PiDxe.h>
+#include "PciPlatform.h"
+#include <Guid/SetupVariable.h>
+
+#ifdef EFI_PCI_IOV_SUPPORT
+
+/**
+
+ The GetSystemLowestPageSize() function retrieves the system lowest page size.
+
+ @param This - Pointer to the EFI_PCI_IOV_PLATFORM_PROTOCOL instance.
+ @param SystemLowestPageSize - The system lowest page size. (This system supports a
+ page size of 2^(n+12) if bit n is set.)
+
+ @retval EFI_SUCCESS - The function completed successfully.
+ @retval EFI_INVALID_PARAMETER - SystemLowestPageSize is NULL.
+
+**/
+EFI_STATUS
+EFIAPI
+GetSystemLowestPageSize (
+ IN EFI_PCI_IOV_PLATFORM_PROTOCOL *This,
+ OUT UINT32 *SystemLowestPageSize
+)
+{
+ UINT8 SystemPageSize;
+
+ CopyMem (&SystemPageSize, (UINT8 *)PcdGetPtr(PcdSetupData) + OFFSET_OF(SYSTEM_CONFIGURATION, SystemPageSize), sizeof(UINT8));
+
+ if (SystemLowestPageSize != NULL) {
+ //
+ // Page size is 4K
+ //
+ //*SystemLowestPageSize = 1;
+ *SystemLowestPageSize = SystemPageSize;
+ }
+ return EFI_SUCCESS;
+}
+
+/**
+
+ The GetIovPlatformPolicy() function retrieves the platform policy regarding PCI IOV.
+
+ @param This - Pointer to the EFI_PCI_IOV_PLATFORM_PROTOCOL instance.
+ @param PciIovPolicy - The platform policy for PCI IOV configuration.
+
+ @retval EFI_SUCCESS - The function completed successfully.
+ @retval EFI_INVALID_PARAMETER - PciPolicy is NULL.
+
+**/
+EFI_STATUS
+EFIAPI
+GetIovPlatformPolicy (
+ IN EFI_PCI_IOV_PLATFORM_PROTOCOL *This,
+ OUT EFI_PCI_IOV_PLATFORM_POLICY *PciIovPolicy
+)
+{
+ UINT8 PolicyEnable;
+ UINT8 ARIEnable;
+ UINT8 SRIOVEnable;
+ UINT8 MRIOVEnable;
+
+ PolicyEnable = 0;
+
+ CopyMem (&ARIEnable, (UINT8 *)PcdGetPtr(PcdSetupData) + OFFSET_OF(SYSTEM_CONFIGURATION, ARIEnable), sizeof(UINT8));
+ CopyMem (&SRIOVEnable, (UINT8 *)PcdGetPtr(PcdSetupData) + OFFSET_OF(SYSTEM_CONFIGURATION, SRIOVEnable), sizeof(UINT8));
+ CopyMem (&MRIOVEnable, (UINT8 *)PcdGetPtr(PcdSetupData) + OFFSET_OF(SYSTEM_CONFIGURATION, MRIOVEnable), sizeof(UINT8));
+
+ if (ARIEnable == TRUE) {
+ PolicyEnable = PolicyEnable | EFI_PCI_IOV_POLICY_ARI;
+ }
+
+ if (SRIOVEnable == TRUE) {
+ PolicyEnable = PolicyEnable | EFI_PCI_IOV_POLICY_SRIOV;
+ }
+
+ if (MRIOVEnable == TRUE) {
+ PolicyEnable = PolicyEnable | EFI_PCI_IOV_POLICY_MRIOV;
+ }
+
+ if (PciIovPolicy != NULL) {
+ //*PciIovPolicy = EFI_PCI_IOV_POLICY_ARI | EFI_PCI_IOV_POLICY_SRIOV;
+ *PciIovPolicy = PolicyEnable;
+ }
+ return EFI_SUCCESS;
+}
+
+#endif
+
diff --git a/Platform/Intel/PurleyOpenBoardPkg/Pci/PciPlatform/PciIovPlatformPolicy.h b/Platform/Intel/PurleyOpenBoardPkg/Pci/PciPlatform/PciIovPlatformPolicy.h
new file mode 100644
index 0000000000..8b358d14a3
--- /dev/null
+++ b/Platform/Intel/PurleyOpenBoardPkg/Pci/PciPlatform/PciIovPlatformPolicy.h
@@ -0,0 +1,57 @@
+/** @file
+
+Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials are licensed and made available under
+the terms and conditions of the BSD License that 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_IOV_PLATFORM_POLICY_H_
+#define PCI_IOV_PLATFORM_POLICY_H_
+
+/**
+
+ The GetSystemLowestPageSize() function retrieves the system lowest page size.
+
+ @param This - Pointer to the EFI_PCI_IOV_PLATFORM_PROTOCOL instance.
+ @param SystemLowestPageSize - The system lowest page size. (This system supports a
+ page size of 2^(n+12) if bit n is set.)
+
+ @retval EFI_SUCCESS - The function completed successfully.
+ @retval EFI_INVALID_PARAMETER - SystemLowestPageSize is NULL.
+
+**/
+EFI_STATUS
+EFIAPI
+GetSystemLowestPageSize (
+ IN EFI_PCI_IOV_PLATFORM_PROTOCOL *This,
+ OUT UINT32 *SystemLowestPageSize
+)
+;
+
+
+/**
+
+ The GetPlatformPolicy() function retrieves the platform policy regarding PCI IOV.
+
+ @param This - Pointer to the EFI_PCI_IOV_PLATFORM_PROTOCOL instance.
+ @param PciIovPolicy - The platform policy for PCI IOV configuration.
+
+ @retval EFI_SUCCESS - The function completed successfully.
+ @retval EFI_INVALID_PARAMETER - PciPolicy is NULL.
+
+**/
+EFI_STATUS
+EFIAPI
+GetIovPlatformPolicy (
+ IN EFI_PCI_IOV_PLATFORM_PROTOCOL *This,
+ OUT EFI_PCI_IOV_PLATFORM_POLICY *PciIovPolicy
+)
+;
+
+#endif
diff --git a/Platform/Intel/PurleyOpenBoardPkg/Pci/PciPlatform/PciPlatform.c b/Platform/Intel/PurleyOpenBoardPkg/Pci/PciPlatform/PciPlatform.c
new file mode 100644
index 0000000000..9f042c2b76
--- /dev/null
+++ b/Platform/Intel/PurleyOpenBoardPkg/Pci/PciPlatform/PciPlatform.c
@@ -0,0 +1,189 @@
+/** @file
+
+Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials are licensed and made available under
+the terms and conditions of the BSD License that 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 <PiDxe.h>
+#include "PciPlatform.h"
+#include <Library/PcdLib.h>
+#ifdef EFI_PCI_IOV_SUPPORT
+#include "PciIovPlatformPolicy.h"
+#endif
+
+PCI_PLATFORM_PRIVATE_DATA mPciPrivateData;
+
+BOOLEAN FirstCall = TRUE;
+UINT8 sSataRaidLoadEfiDriverOption;
+UINT8 SataRaidLoadEfiDriverOption;
+UINT8 BootNetworkOption;
+
+/**
+
+ Set the PciPolicy as EFI_RESERVE_ISA_IO_NO_ALIAS | EFI_RESERVE_VGA_IO_NO_ALIAS.
+
+ @param This - The pointer to the Protocol itself.
+ PciPolicy - the returned Policy.
+
+ @retval EFI_UNSUPPORTED - Function not supported.
+ @retval EFI_INVALID_PARAMETER - Invalid PciPolicy value.
+
+**/
+EFI_STATUS
+EFIAPI
+GetPlatformPolicy (
+ IN CONST EFI_PCI_PLATFORM_PROTOCOL *This,
+ OUT EFI_PCI_PLATFORM_POLICY *PciPolicy
+ )
+{
+ if (PciPolicy == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ return EFI_UNSUPPORTED;
+}
+
+/**
+
+ Return a PCI ROM image for the onboard device represented by PciHandle.
+
+ @param This - Protocol instance pointer.
+ PciHandle - PCI device to return the ROM image for.
+ RomImage - PCI Rom Image for onboard device.
+ RomSize - Size of RomImage in bytes.
+
+ @retval EFI_SUCCESS - RomImage is valid.
+ @retval EFI_NOT_FOUND - No RomImage.
+
+**/
+EFI_STATUS
+EFIAPI
+GetPciRom (
+ IN CONST EFI_PCI_PLATFORM_PROTOCOL *This,
+ IN EFI_HANDLE PciHandle,
+ OUT VOID **RomImage,
+ OUT UINTN *RomSize
+ )
+{
+ return EFI_NOT_FOUND;
+}
+
+/**
+
+ GC_TODO: Add function description
+
+ @param This - GC_TODO: add argument description
+ @param Function - GC_TODO: add argument description
+ @param Phase - GC_TODO: add argument description
+
+ @retval EFI_INVALID_PARAMETER - GC_TODO: Add description for return value
+ @retval EFI_INVALID_PARAMETER - GC_TODO: Add description for return value
+ @retval EFI_UNSUPPORTED - GC_TODO: Add description for return value
+ @retval EFI_SUCCESS - GC_TODO: Add description for return value
+
+**/
+EFI_STATUS
+EFIAPI
+RegisterPciCallback (
+ IN EFI_PCI_CALLBACK_PROTOCOL *This,
+ IN EFI_PCI_CALLBACK_FUNC Function,
+ IN EFI_PCI_ENUMERATION_PHASE Phase
+ )
+{
+ LIST_ENTRY *NodeEntry;
+ PCI_CALLBACK_DATA *PciCallbackData;
+
+ if (Function == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if ( (Phase & (EfiPciEnumerationDeviceScanning | EfiPciEnumerationBusNumberAssigned \
+ | EfiPciEnumerationResourceAssigned)) == 0) {
+ return EFI_INVALID_PARAMETER;
+ }
+ //
+ // Check if the node has been added
+ //
+ NodeEntry = GetFirstNode (&mPciPrivateData.PciCallbackList);
+ while (!IsNull (&mPciPrivateData.PciCallbackList, NodeEntry)) {
+ PciCallbackData = PCI_CALLBACK_DATA_FROM_LINK (NodeEntry);
+ if (PciCallbackData->Function == Function) {
+ return EFI_UNSUPPORTED;
+ }
+
+ NodeEntry = GetNextNode (&mPciPrivateData.PciCallbackList, NodeEntry);
+ }
+
+ PciCallbackData = NULL;
+ PciCallbackData = AllocateZeroPool (sizeof (PCI_CALLBACK_DATA));
+ ASSERT (PciCallbackData != NULL);
+
+ if(PciCallbackData != NULL){
+ PciCallbackData->Signature = PCI_CALLBACK_DATA_SIGNATURE;
+ PciCallbackData->Function = Function;
+ PciCallbackData->Phase = Phase;
+ InsertTailList (&mPciPrivateData.PciCallbackList, &PciCallbackData->Link);
+ return EFI_SUCCESS;
+ } else {
+ return EFI_UNSUPPORTED;
+ }
+}
+
+
+/**
+
+ Main Entry point of the Pci Platform Driver.
+
+ @param ImageHandle - Handle to the image.
+ @param SystemTable - Handle to System Table.
+
+ @retval EFI_STATUS - Status of the function calling.
+
+**/
+EFI_STATUS
+EFIAPI
+PciPlatformDriverEntry (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+
+ ZeroMem (&mPciPrivateData, sizeof (mPciPrivateData));
+ InitializeListHead (&mPciPrivateData.PciCallbackList);
+
+ mPciPrivateData.PciPlatform.PlatformNotify = PhaseNotify;
+ mPciPrivateData.PciPlatform.PlatformPrepController = PlatformPrepController;
+ mPciPrivateData.PciPlatform.GetPlatformPolicy = GetPlatformPolicy;
+ mPciPrivateData.PciPlatform.GetPciRom = GetPciRom;
+ mPciPrivateData.PciCallback.RegisterPciCallback = RegisterPciCallback;
+#ifdef EFI_PCI_IOV_SUPPORT
+ mPciPrivateData.PciIovPlatform.GetSystemLowestPageSize = GetSystemLowestPageSize;
+ mPciPrivateData.PciIovPlatform.GetPlatformPolicy = GetIovPlatformPolicy;
+#endif
+
+ //
+ // Install on a new handle
+ //
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &mPciPrivateData.PciPlatformHandle,
+ &gEfiPciPlatformProtocolGuid,
+ &mPciPrivateData.PciPlatform,
+ &gEfiPciCallbackProtocolGuid,
+ &mPciPrivateData.PciCallback,
+#ifdef EFI_PCI_IOV_SUPPORT
+ &gEfiPciIovPlatformProtocolGuid,
+ &mPciPrivateData.PciIovPlatform,
+#endif
+ NULL
+ );
+
+ return Status;
+}
diff --git a/Platform/Intel/PurleyOpenBoardPkg/Pci/PciPlatform/PciPlatform.h b/Platform/Intel/PurleyOpenBoardPkg/Pci/PciPlatform/PciPlatform.h
new file mode 100644
index 0000000000..f36fdda6e6
--- /dev/null
+++ b/Platform/Intel/PurleyOpenBoardPkg/Pci/PciPlatform/PciPlatform.h
@@ -0,0 +1,207 @@
+/** @file
+
+Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials are licensed and made available under
+the terms and conditions of the BSD License that 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_PLATFORM_H_
+#define PCI_PLATFORM_H_
+
+#include <PiDxe.h>
+#include <Register/PchRegsSata.h>
+#include <Register/PchRegsEva.h>
+#include <PchAccess.h>
+#include <Platform.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/S3PciLib.h>
+#include <Library/PciLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/HobLib.h>
+#include <Library/PcdLib.h>
+#include <Protocol/Runtime.h>
+#include <Protocol/CpuIo2.h>
+#include <Protocol/PciCallback.h>
+#include <Protocol/PciPlatform.h>
+#include <Protocol/PciIovPlatform.h>
+#include <Protocol/PciIo.h>
+#include <Protocol/FirmwareVolume2.h>
+#include <Guid/SetupVariable.h>
+#include <Guid/SocketVariable.h>
+#include <IndustryStandard/Pci.h>
+
+//
+// Global variables for Option ROMs
+//
+
+#define INVALID 0xBD
+
+#define PCI_CALLBACK_DATA_SIGNATURE SIGNATURE_32 ('P', 'c', 'i', 'c')
+
+typedef struct {
+ UINT32 Signature;
+ LIST_ENTRY Link;
+ EFI_PCI_CALLBACK_FUNC Function;
+ EFI_PCI_ENUMERATION_PHASE Phase;
+} PCI_CALLBACK_DATA;
+
+typedef struct {
+ EFI_HANDLE PciPlatformHandle;
+ EFI_HANDLE RootBridgeHandle;
+ EFI_PCI_PLATFORM_PROTOCOL PciPlatform;
+ EFI_PCI_CALLBACK_PROTOCOL PciCallback;
+#ifdef EFI_PCI_IOV_SUPPORT
+ EFI_PCI_IOV_PLATFORM_PROTOCOL PciIovPlatform;
+#endif
+ EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;
+ EFI_CPU_IO2_PROTOCOL *CpuIo;
+ EFI_LIST_ENTRY PciCallbackList;
+ EFI_PCI_CALLBACK_CONTEXT Context;
+ EFI_PCI_ENUMERATION_PHASE PciEnumerationPhase;
+ UINT8 BusAssignedTime;
+} PCI_PLATFORM_PRIVATE_DATA;
+
+#define PCI_CALLBACK_DATA_FROM_LINK(_node) \
+ CR ( \
+ _node, \
+ PCI_CALLBACK_DATA, \
+ Link, \
+ PCI_CALLBACK_DATA_SIGNATURE \
+ )
+
+extern PCI_PLATFORM_PRIVATE_DATA mPciPrivateData;
+extern EFI_GUID gPchSataEfiLoadProtocolGuid;
+
+/**
+
+ Perform initialization by the phase indicated.
+
+ @param This - Pointer to the EFI_PCI_PLATFORM_PROTOCOL instance.
+ @param HostBridge - The associated PCI host bridge handle.
+ @param Phase - The phase of the PCI controller enumeration.
+ @param ChipsetPhase - Defines the execution phase of the PCI chipset driver.
+
+ @retval EFI_SUCCESS - Must return with success.
+
+**/
+EFI_STATUS
+EFIAPI
+PhaseNotify (
+ IN EFI_PCI_PLATFORM_PROTOCOL *This,
+ IN EFI_HANDLE HostBridge,
+ IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PHASE Phase,
+ IN EFI_PCI_CHIPSET_EXECUTION_PHASE ChipsetPhase
+ )
+;
+
+/**
+
+ The PlatformPrepController() function can be used to notify the platform driver so that
+ it can perform platform-specific actions. No specific actions are required.
+ Several notification points are defined at this time. More synchronization points may be
+ added as required in the future. The PCI bus driver calls the platform driver twice for
+ every PCI controller-once before the PCI Host Bridge Resource Allocation Protocol driver
+ is notified, and once after the PCI Host Bridge Resource Allocation Protocol driver has
+ been notified.
+ This member function may not perform any error checking on the input parameters. It also
+ does not return any error codes. If this member function detects any error condition, it
+ needs to handle those errors on its own because there is no way to surface any errors to
+ the caller.
+
+ @param This - Pointer to the EFI_PCI_PLATFORM_PROTOCOL instance.
+ @param HostBridge - The associated PCI host bridge handle.
+ @param RootBridge - The associated PCI root bridge handle.
+ @param PciAddress - The address of the PCI device on the PCI bus.
+ @param Phase - The phase of the PCI controller enumeration.
+ @param ChipsetPhase - Defines the execution phase of the PCI chipset driver.
+
+ @retval EFI_SUCCESS - The function completed successfully.
+
+**/
+EFI_STATUS
+EFIAPI
+PlatformPrepController (
+ IN EFI_PCI_PLATFORM_PROTOCOL *This,
+ IN EFI_HANDLE HostBridge,
+ IN EFI_HANDLE RootBridge,
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS PciAddress,
+ IN EFI_PCI_CONTROLLER_RESOURCE_ALLOCATION_PHASE Phase,
+ IN EFI_PCI_CHIPSET_EXECUTION_PHASE ChipsetPhase
+ )
+;
+
+/**
+
+ Set the PciPolicy as EFI_RESERVE_ISA_IO_NO_ALIAS | EFI_RESERVE_VGA_IO_NO_ALIAS.
+
+ @param This - The pointer to the Protocol itself.
+ PciPolicy - the returned Policy.
+
+ @retval EFI_UNSUPPORTED - Function not supported.
+ @retval EFI_INVALID_PARAMETER - Invalid PciPolicy value.
+
+**/
+EFI_STATUS
+EFIAPI
+GetPlatformPolicy (
+ IN CONST EFI_PCI_PLATFORM_PROTOCOL *This,
+ OUT EFI_PCI_PLATFORM_POLICY *PciPolicy
+ )
+;
+
+/**
+
+ Return a PCI ROM image for the onboard device represented by PciHandle.
+
+ @param This - Protocol instance pointer.
+ PciHandle - PCI device to return the ROM image for.
+ RomImage - PCI Rom Image for onboard device.
+ RomSize - Size of RomImage in bytes.
+
+ @retval EFI_SUCCESS - RomImage is valid.
+ @retval EFI_NOT_FOUND - No RomImage.
+
+**/
+EFI_STATUS
+EFIAPI
+GetPciRom (
+ IN CONST EFI_PCI_PLATFORM_PROTOCOL *This,
+ IN EFI_HANDLE PciHandle,
+ OUT VOID **RomImage,
+ OUT UINTN *RomSize
+ )
+;
+
+/**
+
+ Register a callback during PCI bus enumeration
+
+ @param This - Protocol instance pointer.
+ @param Function - Callback function pointer.
+ @param Phase - PCI enumeration phase.
+
+ @retval EFI_SUCCESS - Function has registed successfully
+ @retval EFI_UNSUPPORTED - The function has been regisered
+ @retval EFI_InVALID_PARAMETER - The parameter is incorrect
+
+**/
+EFI_STATUS
+EFIAPI
+RegisterPciCallback (
+ IN EFI_PCI_CALLBACK_PROTOCOL *This,
+ IN EFI_PCI_CALLBACK_FUNC Function,
+ IN EFI_PCI_ENUMERATION_PHASE Phase
+ )
+;
+
+#endif
diff --git a/Platform/Intel/PurleyOpenBoardPkg/Pci/PciPlatform/PciPlatform.inf b/Platform/Intel/PurleyOpenBoardPkg/Pci/PciPlatform/PciPlatform.inf
new file mode 100644
index 0000000000..b46bbf713a
--- /dev/null
+++ b/Platform/Intel/PurleyOpenBoardPkg/Pci/PciPlatform/PciPlatform.inf
@@ -0,0 +1,78 @@
+### @file
+#
+# Copyright (c) 2018, Intel Corporation. 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.
+#
+###
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = PciPlatform
+ FILE_GUID = E2441B64-7EF4-41fe-B3A3-8CAA7F8D3017
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ ENTRY_POINT = PciPlatformDriverEntry
+
+[Sources]
+ PciPlatform.c
+ PciPlatform.h
+ PciPlatformHooks.c
+ PciPlatformHooks.h
+ PciIovPlatformPolicy.c
+ PciIovPlatformPolicy.h
+ PciSupportLib.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ LewisburgPkg/PchRcPkg.dec
+ PurleyOpenBoardPkg/PlatPkg.dec
+ PurleySktPkg/SocketPkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ PurleyRcPkg/RcPkg.dec
+ MinPlatformPkg/MinPlatformPkg.dec
+
+[LibraryClasses]
+ UefiDriverEntryPoint
+ IoLib
+ BaseMemoryLib
+ DebugLib
+ UefiRuntimeServicesTableLib
+ UefiBootServicesTableLib
+ HobLib
+ S3PciLib
+ PcdLib
+
+[Protocols]
+ gEfiPciCallbackProtocolGuid
+ gEfiCpuIo2ProtocolGuid
+ gEfiFirmwareVolume2ProtocolGuid
+ gEfiPciIoProtocolGuid
+ gEfiPciPlatformProtocolGuid
+ gEfiIioUdsProtocolGuid
+ gEfiPciRootBridgeIoProtocolGuid
+ gEfiPciIovPlatformProtocolGuid
+ gEfiIioSystemProtocolGuid
+ gEfiPciHostBridgeResourceAllocationProtocolGuid
+
+[Pcd]
+ gEfiMdeModulePkgTokenSpaceGuid.PcdSrIovSystemPageSize
+ gEfiMdeModulePkgTokenSpaceGuid.PcdSrIovSupport
+ gEfiMdeModulePkgTokenSpaceGuid.PcdAriSupport
+ gEfiMdeModulePkgTokenSpaceGuid.PcdMrIovSupport
+ gOemSkuTokenSpaceGuid.PcdSetupData
+ gMinPlatformPkgTokenSpaceGuid.PcdIoApicId
+ gMinPlatformPkgTokenSpaceGuid.PcdPcIoApicIdBase
+
+[FixedPcd]
+ gEfiCpRcPkgTokenSpaceGuid.PcdMaxNestedLevel
+
+[Depex]
+ TRUE
+
diff --git a/Platform/Intel/PurleyOpenBoardPkg/Pci/PciPlatform/PciPlatformHooks.c b/Platform/Intel/PurleyOpenBoardPkg/Pci/PciPlatform/PciPlatformHooks.c
new file mode 100644
index 0000000000..9310df3e67
--- /dev/null
+++ b/Platform/Intel/PurleyOpenBoardPkg/Pci/PciPlatform/PciPlatformHooks.c
@@ -0,0 +1,533 @@
+/** @file
+
+Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials are licensed and made available under
+the terms and conditions of the BSD License that 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 <PiDxe.h>
+#include <Protocol/IioUds.h>
+#include <PciPlatform.h>
+#include <PciPlatformHooks.h>
+#include <PciSupportLib.h>
+#include <IoApic.h>
+#include <Library/S3BootScriptLib.h>
+#include <Protocol/IioSystem.h>
+
+EFI_IIO_UDS_PROTOCOL *mIioUds = NULL;
+EFI_IIO_SYSTEM_PROTOCOL *IioSystemProtocol = NULL;
+IIO_GLOBALS *IioGlobalData = NULL;
+
+VOID
+ChipsetCallback (
+ IN EFI_HANDLE RootBridgeHandle,
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS PciAddress,
+ IN EFI_PCI_ENUMERATION_PHASE Phase,
+ EFI_PCI_CALLBACK_CONTEXT *Context
+ )
+{
+ EFI_LIST_ENTRY *NodeEntry;
+ PCI_CALLBACK_DATA *PciCallbackData;
+
+ //
+ // Check if the node has been added
+ //
+ // DEBUG ((DEBUG_ERROR, "PCI Callback (%d,%d,%d)\n",PciAddress.Bus, PciAddress.Device, PciAddress.Function ));
+ //
+ Context->PciRootBridgeIo = mPciPrivateData.PciRootBridgeIo;
+ NodeEntry = GetFirstNode (&mPciPrivateData.PciCallbackList);
+ while (!IsNull (&mPciPrivateData.PciCallbackList, NodeEntry)) {
+ PciCallbackData = PCI_CALLBACK_DATA_FROM_LINK (NodeEntry);
+ if (PciCallbackData->Phase & Phase) {
+ (PciCallbackData->Function) (RootBridgeHandle, PciAddress, Phase, Context);
+ }
+
+ NodeEntry = GetNextNode (&mPciPrivateData.PciCallbackList, NodeEntry);
+ }
+}
+
+/**
+
+ GC_TODO: add routine description
+
+ @param StartBus - GC_TODO: add arg description
+
+ @retval EFI_SUCCESS - GC_TODO: add retval description
+
+**/
+EFI_STATUS
+PciTreeTraverse (
+ IN UINT8 StartBus
+ )
+{
+ UINT64 PciAddress;
+ UINT8 Device;
+ UINT8 Func;
+ UINT8 SecondaryBus;
+ BOOLEAN MultiFunc;
+
+ for (Device = 0; Device <= PCI_MAX_DEVICE; Device++) {
+ MultiFunc = FALSE;
+ for (Func = 0; Func <= PCI_MAX_FUNC; Func++) {
+ if (IsPciDevicePresent (
+ mPciPrivateData.PciRootBridgeIo,
+ &mPciPrivateData.Context.PciHeader,
+ StartBus,
+ Device,
+ Func
+ )) {
+ if ((Func == 0) && IS_PCI_MULTI_FUNC(&(mPciPrivateData.Context.PciHeader))) {
+ MultiFunc = TRUE;
+ }
+ PciAddress = EFI_PCI_ADDRESS (StartBus, Device, Func, 0);
+ ChipsetCallback (
+ mPciPrivateData.RootBridgeHandle,
+ *(EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS *) &PciAddress,
+ mPciPrivateData.PciEnumerationPhase,
+ &(mPciPrivateData.Context)
+ );
+ if (IS_PCI_BRIDGE (&(mPciPrivateData.Context.PciHeader))) {
+ PciAddress = EFI_PCI_ADDRESS (StartBus, Device, Func, PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET);
+ mPciPrivateData.PciRootBridgeIo->Pci.Read (
+ mPciPrivateData.PciRootBridgeIo,
+ EfiPciWidthUint8,
+ *(UINT64 *) &PciAddress,
+ 1,
+ &SecondaryBus
+ );
+ if ((SecondaryBus > 0) && (SecondaryBus < 0xFF)) {
+ PciTreeTraverse (SecondaryBus);
+ }
+ }
+ }
+
+ if (MultiFunc == FALSE) {
+ //
+ // Skip sub functions, this is not a multi function device
+ //
+ Func = PCI_MAX_FUNC;
+ }
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+
+ Program Io Apic Id
+
+ @param IoApicAddress and IoApicId
+
+ @retval None
+
+**/
+VOID
+ProgramIoApicId (
+ IN UINT32 IoApicAddress,
+ IN UINT8 IoApicId
+ )
+{
+
+ UINT32 Data;
+
+ mPciPrivateData.CpuIo->Mem.Read (
+ mPciPrivateData.CpuIo,
+ EfiCpuIoWidthUint32,
+ IoApicAddress + EFI_IO_APIC_INDEX_OFFSET,
+ 1,
+ &Data
+ );
+
+ //
+ // IOAPIC is not there
+ //
+ if (Data == (UINT32) -1) {
+ return ;
+ }
+ //
+ // Set up IO APIC ID and enable FSB delivery
+ // Use CPU IO protocol since the IO APIC ranges
+ // are not included in PCI apertures
+ //
+ Data = EFI_IO_APIC_ID_REGISTER;
+ mPciPrivateData.CpuIo->Mem.Write (
+ mPciPrivateData.CpuIo,
+ EfiCpuIoWidthUint32,
+ IoApicAddress + EFI_IO_APIC_INDEX_OFFSET,
+ 1,
+ &Data
+ );
+
+ Data = IoApicId << EFI_IO_APIC_ID_BITSHIFT;
+ mPciPrivateData.CpuIo->Mem.Write (
+ mPciPrivateData.CpuIo,
+ EfiCpuIoWidthUint32,
+ IoApicAddress + EFI_IO_APIC_DATA_OFFSET,
+ 1,
+ &Data
+ );
+
+ Data = EFI_IO_APIC_BOOT_CONFIG_REGISTER;
+ mPciPrivateData.CpuIo->Mem.Write (
+ mPciPrivateData.CpuIo,
+ EfiCpuIoWidthUint32,
+ IoApicAddress + EFI_IO_APIC_INDEX_OFFSET,
+ 1,
+ &Data
+ );
+
+ Data = EFI_IO_APIC_FSB_INT_DELIVERY;
+ mPciPrivateData.CpuIo->Mem.Write (
+ mPciPrivateData.CpuIo,
+ EfiCpuIoWidthUint32,
+ IoApicAddress + EFI_IO_APIC_DATA_OFFSET,
+ 1,
+ &Data
+ );
+}
+
+#ifdef EFI_PCI_IOV_SUPPORT
+/**
+
+ Initialize the Pci Iov Platform Data.
+
+ @param ImageHandle - Handle to the image.
+ @param SystemTable - Handle to System Table.
+
+ @retval EFI_STATUS - Status of the function calling.
+
+**/
+EFI_STATUS
+EFIAPI
+PciPlatformInitPciIovData (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ EFI_PCI_IOV_PLATFORM_POLICY PciIovPolicy;
+ UINT32 SystemPageSize;
+ EFI_PCI_IOV_PLATFORM_PROTOCOL *gPciIovPlatformProtocol;
+
+ Status = gBS->LocateProtocol (
+ &gEfiPciIovPlatformProtocolGuid,
+ NULL,
+ &gPciIovPlatformProtocol
+ );
+ if (!EFI_ERROR (Status)) {
+ Status = gPciIovPlatformProtocol->GetSystemLowestPageSize (
+ gPciIovPlatformProtocol,
+ &SystemPageSize
+ );
+ if (!EFI_ERROR (Status)) {
+ Status = PcdSet32S (PcdSrIovSystemPageSize, (1 << SystemPageSize));
+ ASSERT_EFI_ERROR (Status);
+ if (EFI_ERROR(Status)) return Status;
+ } else {
+ return Status;
+ }
+ Status = gPciIovPlatformProtocol->GetPlatformPolicy (
+ gPciIovPlatformProtocol,
+ &PciIovPolicy
+ );
+ if (!EFI_ERROR (Status)) {
+ if (PciIovPolicy & EFI_PCI_IOV_POLICY_ARI) {
+ Status = PcdSetBoolS (PcdAriSupport, TRUE);
+ ASSERT_EFI_ERROR (Status);
+ if (EFI_ERROR(Status)) return Status;
+ } else {
+ Status = PcdSetBoolS (PcdAriSupport, FALSE);
+ ASSERT_EFI_ERROR (Status);
+ if (EFI_ERROR(Status)) return Status;
+ }
+ if (PciIovPolicy & EFI_PCI_IOV_POLICY_SRIOV) {
+ Status = PcdSetBoolS (PcdSrIovSupport, TRUE);
+ ASSERT_EFI_ERROR (Status);
+ if (EFI_ERROR(Status)) return Status;
+ } else {
+ Status = PcdSetBoolS (PcdSrIovSupport, FALSE);
+ ASSERT_EFI_ERROR (Status);
+ if (EFI_ERROR(Status)) return Status;
+ }
+ if (PciIovPolicy & EFI_PCI_IOV_POLICY_MRIOV) {
+ Status = PcdSetBoolS (PcdMrIovSupport, TRUE);
+ ASSERT_EFI_ERROR (Status);
+ if (EFI_ERROR(Status)) return Status;
+ } else {
+ Status = PcdSetBoolS (PcdMrIovSupport, FALSE);
+ ASSERT_EFI_ERROR (Status);
+ if (EFI_ERROR(Status)) return Status;
+ }
+ } else {
+ return Status;
+ }
+ DEBUG ((
+ EFI_D_INFO,
+ " Initialized SR-IOV Platform Data: PCIIovPolicy = 0x%x; SystemPageSize = 0x%x;\n",
+ PciIovPolicy, SystemPageSize
+ ));
+ } else {
+ DEBUG ((
+ EFI_D_INFO,
+ " Using default values for SystemPageSize;\n"
+ ));
+ }
+ return Status;
+}
+#endif
+
+/**
+
+ Platform Pci Express init.
+
+ @param HostBridgeInstance - Pointer to Host Bridge private data
+ does not support 64 bit memory addresses.
+
+ @retval EFI_SUCCESS - Success.
+
+**/
+EFI_STATUS
+PciPlatformEarlyInit (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ //
+ // Locate the IIO Protocol Interface
+ //
+ Status = gBS->LocateProtocol (&gEfiIioUdsProtocolGuid,NULL,&mIioUds);
+ ASSERT_EFI_ERROR (Status);
+ Status = gBS->LocateProtocol (&gEfiIioSystemProtocolGuid, NULL, &IioSystemProtocol);
+ ASSERT_EFI_ERROR (Status);
+
+ IioGlobalData = IioSystemProtocol->IioGlobalData;
+
+#ifdef EFI_PCI_IOV_SUPPORT
+ Status = PciPlatformInitPciIovData(); // Update IOV PCD values
+#endif
+ return EFI_SUCCESS;
+}
+
+
+/**
+
+ Init pci device registers after the device resources have been allocated, so
+ that devices behind a bus could be accessed.
+
+ @param HostBridgeInstance - PCI_HOST_BRIDGE_INSTANCE.
+
+ @retval EFI_SUCCESS - Function has completed successfully.
+
+**/
+EFI_STATUS
+PciPlatformPostInit (
+ VOID
+ )
+{
+ //
+ // Program all the IOAPIC in system
+ //
+ UINT8 Socket, Stack, IoApicId;
+ UINT8 Step;
+ UINT8 MaxSocket;
+
+#if MAX_SOCKET <= 4
+ Step = 6;
+ MaxSocket = 4;
+#else
+ Step = 4;
+ MaxSocket = 8;
+#endif
+
+ Stack = 0;
+ IoApicId = 0;
+ ProgramIoApicId (mIioUds->IioUdsPtr->PlatformData.IIO_resource[0].StackRes[0].IoApicBase, PcdGet8(PcdIoApicId));
+ for (Socket = 0; Socket < MAX_SOCKET; Socket++) {
+ if (!(mIioUds->IioUdsPtr->SystemStatus.socketPresentBitMap & (1 << Socket)))
+ continue;
+
+ for (Stack = 0; Stack < MAX_IIO_STACK; Stack++) {
+ if (!(mIioUds->IioUdsPtr->PlatformData.CpuQpiInfo[Socket].stackPresentBitmap & (1 << Stack)))
+ continue;
+
+ if ((Socket < MaxSocket) && (Stack < Step)) {
+ IoApicId = PcdGet8(PcdPcIoApicIdBase) + Step * Socket + Stack;
+ }
+
+ if ((Socket == 0) && (Stack == 0)) {
+ ProgramIoApicId ((mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket].StackRes[Stack].IoApicBase + 0x1000), IoApicId);
+ } else {
+ ProgramIoApicId (mIioUds->IioUdsPtr->PlatformData.IIO_resource[Socket].StackRes[Stack].IoApicBase, IoApicId);
+ }
+ }
+ }
+ return EFI_SUCCESS;
+}
+
+/**
+
+ The PlatformPrepController() function can be used to notify the platform driver so that
+ it can perform platform-specific actions. No specific actions are required.
+ Several notification points are defined at this time. More synchronization points may be
+ added as required in the future. The PCI bus driver calls the platform driver twice for
+ every PCI controller-once before the PCI Host Bridge Resource Allocation Protocol driver
+ is notified, and once after the PCI Host Bridge Resource Allocation Protocol driver has
+ been notified.
+ This member function may not perform any error checking on the input parameters. It also
+ does not return any error codes. If this member function detects any error condition, it
+ needs to handle those errors on its own because there is no way to surface any errors to
+ the caller.
+
+ @param This - Pointer to the EFI_PCI_PLATFORM_PROTOCOL instance.
+ @param HostBridge - The associated PCI host bridge handle.
+ @param RootBridge - The associated PCI root bridge handle.
+ @param PciAddress - The address of the PCI device on the PCI bus.
+ @param Phase - The phase of the PCI controller enumeration.
+ @param ChipsetPhase - Defines the execution phase of the PCI chipset driver.
+
+ @retval EFI_SUCCESS - The function completed successfully.
+ @retval EFI_UNSUPPORTED - Not supported.
+
+**/
+EFI_STATUS
+EFIAPI
+PlatformPrepController (
+ IN EFI_PCI_PLATFORM_PROTOCOL *This,
+ IN EFI_HANDLE HostBridge,
+ IN EFI_HANDLE RootBridge,
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS PciAddress,
+ IN EFI_PCI_CONTROLLER_RESOURCE_ALLOCATION_PHASE Phase,
+ IN EFI_PCI_CHIPSET_EXECUTION_PHASE ChipsetPhase
+ )
+{
+ if (mPciPrivateData.RootBridgeHandle == NULL) {
+ mPciPrivateData.RootBridgeHandle = RootBridge;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+
+ Perform initialization by the phase indicated.
+
+ @param This - Pointer to the EFI_PCI_PLATFORM_PROTOCOL instance.
+ @param HostBridge - The associated PCI host bridge handle.
+ @param Phase - The phase of the PCI controller enumeration.
+ @param ChipsetPhase - Defines the execution phase of the PCI chipset driver.
+
+ @retval EFI_SUCCESS - Must return with success.
+
+**/
+EFI_STATUS
+EFIAPI
+PhaseNotify (
+ IN EFI_PCI_PLATFORM_PROTOCOL *This,
+ IN EFI_HANDLE HostBridge,
+ IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PHASE Phase,
+ IN EFI_PCI_CHIPSET_EXECUTION_PHASE ChipsetPhase
+ )
+{
+ EFI_STATUS Status;
+ UINT8 i;
+ UINT8 Stack;
+
+ if (ChipsetPhase == ChipsetEntry) {
+ return EFI_SUCCESS;
+ }
+ //
+ // If for multiple host bridges, need special consideration
+ //
+ switch (Phase) {
+
+ case EfiPciHostBridgeBeginEnumeration:
+ //
+ // Pre-initialization before PCI bus enumeration
+ // No bus number and no PCI resource
+ //
+ Status = gBS->LocateProtocol (
+ &gEfiPciRootBridgeIoProtocolGuid,
+ NULL,
+ &(mPciPrivateData.PciRootBridgeIo)
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ Status = gBS->LocateProtocol (
+ &gEfiCpuIo2ProtocolGuid,
+ NULL,
+ &(mPciPrivateData.CpuIo)
+ );
+ ASSERT_EFI_ERROR (Status);
+ mPciPrivateData.Context.CpuIo = mPciPrivateData.CpuIo;
+
+ DEBUG ((DEBUG_ERROR, "PCI Platform Pre-Initialization (Before bus scanning)\n"));
+ PciPlatformEarlyInit ();
+ break;
+
+ case EfiPciHostBridgeEndBusAllocation:
+ //
+ // There are two rounds PCI bus scanning
+ // First round will initilize the PCI hotplug device
+ // Second round will be the final one
+ //
+ if (mPciPrivateData.BusAssignedTime == 0) {
+ mPciPrivateData.PciEnumerationPhase = EfiPciEnumerationDeviceScanning;
+ for (i = 0 ; i < MaxIIO ; i++) {
+ if (mIioUds->IioUdsPtr->PlatformData.IIO_resource[i].Valid) {
+ for(Stack = 0; Stack < MAX_IIO_STACK; Stack ++) {
+ PciTreeTraverse (mIioUds->IioUdsPtr->PlatformData.CpuQpiInfo[i].StackBus[Stack]);
+ }
+ }
+ }
+ mPciPrivateData.BusAssignedTime++;
+ DEBUG ((DEBUG_ERROR, "PCI Platform bus assigned\n"));
+ }
+ break;
+
+ case EfiPciHostBridgeBeginResourceAllocation:
+ //
+ // PCI bus number has been assigned, but resource is still empty
+ //
+ DEBUG ((DEBUG_ERROR, "PCI Platform Mid-Initialization (After bus number assignment)\n"));
+ mPciPrivateData.PciEnumerationPhase = EfiPciEnumerationBusNumberAssigned;
+ for (i = 0 ; i < MaxIIO ; i++) {
+ if (mIioUds->IioUdsPtr->PlatformData.IIO_resource[i].Valid) {
+ for(Stack = 0; Stack < MAX_IIO_STACK; Stack ++) {
+ PciTreeTraverse (mIioUds->IioUdsPtr->PlatformData.CpuQpiInfo[i].StackBus[Stack]);
+ }
+ }
+ }
+ //PciPlatformMidInit ();
+ break;
+
+ case EfiPciHostBridgeEndResourceAllocation:
+ //
+ // Resource enumeration is done.
+ // Both bus number and resource have been assigned
+ // Do any post initialization.
+ //
+ DEBUG ((DEBUG_ERROR, "PCI Platform Post-Initialization (After resource alloction)\n"));
+ mPciPrivateData.PciEnumerationPhase = EfiPciEnumerationResourceAssigned;
+ for (i = 0 ; i < MaxIIO ; i++) {
+ if (mIioUds->IioUdsPtr->PlatformData.IIO_resource[i].Valid) {
+ for(Stack = 0; Stack < MAX_IIO_STACK; Stack ++) {
+ PciTreeTraverse (mIioUds->IioUdsPtr->PlatformData.CpuQpiInfo[i].StackBus[Stack]);
+ }
+ }
+ }
+ PciPlatformPostInit ();
+ break;
+
+ default:
+ return EFI_UNSUPPORTED;
+ }
+
+ return EFI_SUCCESS;
+}
+
diff --git a/Platform/Intel/PurleyOpenBoardPkg/Pci/PciPlatform/PciPlatformHooks.h b/Platform/Intel/PurleyOpenBoardPkg/Pci/PciPlatform/PciPlatformHooks.h
new file mode 100644
index 0000000000..8d4734bb80
--- /dev/null
+++ b/Platform/Intel/PurleyOpenBoardPkg/Pci/PciPlatform/PciPlatformHooks.h
@@ -0,0 +1,30 @@
+/** @file
+
+Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials are licensed and made available under
+the terms and conditions of the BSD License that 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_PLATFORM_HOOKS_H_
+#define PCI_PLATFORM_HOOKS_H_
+
+VOID
+ChipsetCallback (
+ IN EFI_HANDLE RootBridgeHandle,
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS PciAddress,
+ IN EFI_PCI_ENUMERATION_PHASE Phase,
+ EFI_PCI_CALLBACK_CONTEXT *Context
+ );
+
+EFI_STATUS
+PciTreeTraverse (
+ IN UINT8 StartBus
+ );
+
+#endif
diff --git a/Platform/Intel/PurleyOpenBoardPkg/Pci/PciPlatform/PciSupportLib.c b/Platform/Intel/PurleyOpenBoardPkg/Pci/PciPlatform/PciSupportLib.c
new file mode 100644
index 0000000000..dbd744b9d2
--- /dev/null
+++ b/Platform/Intel/PurleyOpenBoardPkg/Pci/PciPlatform/PciSupportLib.c
@@ -0,0 +1,109 @@
+/** @file
+
+Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials are licensed and made available under
+the terms and conditions of the BSD License that 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 "PiDxe.h"
+#include <Base.h>
+#include <Guid/SocketIioVariable.h>
+#include <Library/IoLib.h>
+#include <Library/DebugLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include "IndustryStandard/Pci.h"
+#include "PciSupportLib.h"
+
+PCIE_STACK mPcieStack;
+
+
+/**
+
+ This routine is used to check whether the pci device is present
+
+ @retval None
+
+**/
+BOOLEAN
+IsPciDevicePresent (
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo,
+ PCI_TYPE00 *Pci,
+ UINT8 Bus,
+ UINT8 Device,
+ UINT8 Func
+ )
+// TODO: PciRootBridgeIo - add argument and description to function comment
+// TODO: Pci - add argument and description to function comment
+// TODO: Bus - add argument and description to function comment
+// TODO: Device - add argument and description to function comment
+// TODO: Func - add argument and description to function comment
+// TODO: EFI_SUCCESS - add return value to function comment
+// TODO: EFI_NOT_FOUND - add return value to function comment
+{
+ UINT64 Address;
+ UINT32 Dummy;
+ EFI_STATUS Status;
+
+ Dummy=0xFFFFFFFF;
+ //
+ // Create PCI address map in terms of Bus, Device and Func
+ //
+ Address = EFI_PCI_ADDRESS (Bus, Device, Func, 0);
+
+ //
+ // Read the Vendor Id register
+ //
+ Status = PciRootBridgeIo->Pci.Read (
+ PciRootBridgeIo,
+ EfiPciWidthUint32,
+ Address,
+ 1,
+ Pci
+ );
+ if ((Pci->Hdr).VendorId == 0xffff) {
+ /// PCIe card could have been assigned a temporary bus number.
+ /// An write cycle can be used to try to rewrite the Bus number in the card
+ /// Try to write the Vendor Id register, and recheck if the card is present.
+ Status = PciRootBridgeIo->Pci.Write(
+ PciRootBridgeIo,
+ EfiPciWidthUint32,
+ Address,
+ 1,
+ &Dummy
+ );
+
+ // Retry the previous read after the PCI cycle has been tried.
+ Status = PciRootBridgeIo->Pci.Read (
+ PciRootBridgeIo,
+ EfiPciWidthUint32,
+ Address,
+ 1,
+ Pci
+ );
+ }
+
+ if (!EFI_ERROR (Status) && (Pci->Hdr).VendorId != 0xffff) {
+
+ //
+ // Read the entire config header for the device
+ //
+
+ Status = PciRootBridgeIo->Pci.Read (
+ PciRootBridgeIo,
+ EfiPciWidthUint32,
+ Address,
+ sizeof (PCI_TYPE00) / sizeof (UINT32),
+ Pci
+ );
+
+ return TRUE;
+ }
+
+ return FALSE;
+}
diff --git a/Platform/Intel/PurleyOpenBoardPkg/Pci/PciPlatform/PciSupportLib.h b/Platform/Intel/PurleyOpenBoardPkg/Pci/PciPlatform/PciSupportLib.h
new file mode 100644
index 0000000000..78fd013498
--- /dev/null
+++ b/Platform/Intel/PurleyOpenBoardPkg/Pci/PciPlatform/PciSupportLib.h
@@ -0,0 +1,50 @@
+/** @file
+
+Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials are licensed and made available under
+the terms and conditions of the BSD License that 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 _EFI_PCI_SUPPORT_H_
+#define _EFI_PCI_SUPPORT_H_
+
+#include <Protocol/PciRootBridgeIo.h>
+
+#include <Guid/SetupVariable.h>
+
+typedef struct {
+ UINT8 PcieCapPtr;
+ UINT8 Function;
+ UINT8 Device;
+ UINT8 Bus;
+ UINT16 PcieLnkCap;
+ UINT16 PcieDevCap;
+ //Added to Support AtomicOp Request-->Start
+ UINT16 PcieDevCap2;
+ //Added to Support AtomicOp Request-->End
+} PCIE_CAP_INFO;
+
+typedef struct {
+ INTN Top;
+ PCIE_CAP_INFO PcieCapInfo[FixedPcdGet32(PcdMaxNestedLevel)];
+} PCIE_STACK;
+
+extern PCIE_STACK mPcieStack;
+
+BOOLEAN
+IsPciDevicePresent (
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo,
+ PCI_TYPE00 *Pci,
+ UINT8 Bus,
+ UINT8 Device,
+ UINT8 Func
+ );
+
+
+#endif