summaryrefslogtreecommitdiffstats
path: root/QuarkPlatformPkg/Pci
diff options
context:
space:
mode:
authorMichael Kinney <michael.d.kinney@intel.com>2015-12-15 19:23:57 +0000
committermdkinney <mdkinney@Edk2>2015-12-15 19:23:57 +0000
commitb303605e1b7e113b4311daf161c6c3289350447b (patch)
tree67bf068eb99ea84822f234b7194ee1084ee5455a /QuarkPlatformPkg/Pci
parent9b6bbcdbfdf5e54c6d1ed538ea8076d0858fb164 (diff)
downloadedk2-b303605e1b7e113b4311daf161c6c3289350447b.tar.gz
edk2-b303605e1b7e113b4311daf161c6c3289350447b.tar.bz2
edk2-b303605e1b7e113b4311daf161c6c3289350447b.zip
QuarkPlatformPkg: Add new package for Galileo boards
Changes for V4 ============== 1) Move delete of QuarkSocPkg\QuarkNorthCluster\Binary\QuarkMicrocode from QuarkPlatformPkg commit to QuarkSocPkg commit 2) Fix incorrect license header in PlatformSecLibModStrs.uni Changes for V3 ============== 1) Set PcdResetOnMemoryTypeInformationChange FALSE in QuarkMin.dsc This is required because QuarkMin.dsc uses the emulated variable driver that does not preserve any non-volatile UEFI variables across reset. If the condition is met where the memory type information variable needs to be updated, then the system will reset every time the UEFI Shell is run. By setting this PCD to FALSE, then reset action is disabled. 2) Move one binary file to QuarkSocBinPkg 3) Change RMU.bin FILE statements to INF statement in DSC FD region to be compatible with PACKAGES_PATH search for QuarkSocBinPkg Changes for V2 ============== 1) Use new generic PCI serial driver PciSioSerialDxe in MdeModulePkg 2) Configure PcdPciSerialParameters for PCI serial driver for Quark 3) Use new MtrrLib API to reduce time to set MTRRs for all DRAM 4) Convert all UNI files to utf-8 5) Replace tabs with spaces and remove trailing spaces 6) Add License.txt Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Michael Kinney <michael.d.kinney@intel.com> Acked-by: Jordan Justen <jordan.l.justen@intel.com> git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@19287 6f19259b-4bc3-4df7-8a09-765794883524
Diffstat (limited to 'QuarkPlatformPkg/Pci')
-rw-r--r--QuarkPlatformPkg/Pci/Dxe/PciHostBridge/PciHostBridge.c1403
-rw-r--r--QuarkPlatformPkg/Pci/Dxe/PciHostBridge/PciHostBridge.h395
-rw-r--r--QuarkPlatformPkg/Pci/Dxe/PciHostBridge/PciHostBridge.inf67
-rw-r--r--QuarkPlatformPkg/Pci/Dxe/PciHostBridge/PciHostBridgeSupport.c146
-rw-r--r--QuarkPlatformPkg/Pci/Dxe/PciHostBridge/PciHostResource.h66
-rw-r--r--QuarkPlatformPkg/Pci/Dxe/PciHostBridge/PciRootBridge.h699
-rw-r--r--QuarkPlatformPkg/Pci/Dxe/PciHostBridge/PciRootBridgeIo.c1616
-rw-r--r--QuarkPlatformPkg/Pci/Dxe/PciPlatform/CommonHeader.h37
-rw-r--r--QuarkPlatformPkg/Pci/Dxe/PciPlatform/PciPlatform.c200
-rw-r--r--QuarkPlatformPkg/Pci/Dxe/PciPlatform/PciPlatform.h88
-rw-r--r--QuarkPlatformPkg/Pci/Dxe/PciPlatform/PciPlatform.inf60
11 files changed, 4777 insertions, 0 deletions
diff --git a/QuarkPlatformPkg/Pci/Dxe/PciHostBridge/PciHostBridge.c b/QuarkPlatformPkg/Pci/Dxe/PciHostBridge/PciHostBridge.c
new file mode 100644
index 0000000000..ecc357efcb
--- /dev/null
+++ b/QuarkPlatformPkg/Pci/Dxe/PciHostBridge/PciHostBridge.c
@@ -0,0 +1,1403 @@
+/** @file
+Pci Host Bridge driver for a simple IIO. There is only one PCI Root Bridge in the system.
+Provides the basic interfaces to abstract a PCI Host Bridge Resource Allocation.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+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 "PciHostBridge.h"
+#include <IntelQNCRegs.h>
+
+//
+// We can hardcode the following for a Simple IIO -
+// Root Bridge Count within the host bridge
+// Root Bridge's device path
+// Root Bridge's resource appeture
+//
+EFI_PCI_ROOT_BRIDGE_DEVICE_PATH mEfiPciRootBridgeDevicePath[ROOT_BRIDGE_COUNT] = {
+ {
+ {
+ {
+ ACPI_DEVICE_PATH,
+ ACPI_DP,
+ {
+ (UINT8) (sizeof (ACPI_HID_DEVICE_PATH)),
+ (UINT8) ((sizeof (ACPI_HID_DEVICE_PATH)) >> 8)
+ }
+ },
+ EISA_PNP_ID (0x0A03),
+ 0
+ },
+ {
+ END_DEVICE_PATH_TYPE,
+ END_ENTIRE_DEVICE_PATH_SUBTYPE,
+ {
+ END_DEVICE_PATH_LENGTH,
+ 0
+ }
+ }
+ }
+};
+
+EFI_HANDLE mDriverImageHandle;
+PCI_ROOT_BRIDGE_RESOURCE_APERTURE *mResAperture;
+
+//
+// Implementation
+//
+EFI_STATUS
+EFIAPI
+InitializePciHostBridge (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+/*++
+
+Routine Description:
+
+ Entry point of this driver.
+
+Arguments:
+
+ ImageHandle - Image handle of this driver.
+ SystemTable - Pointer to standard EFI system table.
+
+Returns:
+
+ EFI_SUCCESS - Succeed.
+ EFI_DEVICE_ERROR - Fail to install PCI_ROOT_BRIDGE_IO protocol.
+
+--*/
+{
+ EFI_STATUS Status;
+ UINTN TotalRootBridgeFound;
+ PCI_HOST_BRIDGE_INSTANCE *HostBridge;
+ PCI_ROOT_BRIDGE_INSTANCE *PrivateData;
+ UINT64 AllocAttributes;
+ EFI_PHYSICAL_ADDRESS BaseAddress;
+
+ PrivateData = NULL;
+
+ mDriverImageHandle = ImageHandle;
+
+ //
+ // Most systems in the world including complex servers
+ // have only one Host Bridge. Create Host Bridge Device Handle
+ //
+ Status = gBS->AllocatePool(EfiBootServicesData, sizeof(PCI_HOST_BRIDGE_INSTANCE), (VOID **) &HostBridge);
+ ASSERT_EFI_ERROR (Status);
+ ZeroMem (HostBridge, sizeof (PCI_HOST_BRIDGE_INSTANCE));
+
+ HostBridge->Signature = PCI_HOST_BRIDGE_SIGNATURE;
+ HostBridge->RootBridgeCount = 1;
+ HostBridge->ResourceSubmited = FALSE;
+ HostBridge->CanRestarted = TRUE;
+ //
+ // InitializeListHead (&HostBridge->Head);
+ //
+ HostBridge->ResAlloc.NotifyPhase = NotifyPhase;
+ HostBridge->ResAlloc.GetNextRootBridge = GetNextRootBridge;
+ HostBridge->ResAlloc.GetAllocAttributes = GetAttributes;
+ HostBridge->ResAlloc.StartBusEnumeration = StartBusEnumeration;
+ HostBridge->ResAlloc.SetBusNumbers = SetBusNumbers;
+ HostBridge->ResAlloc.SubmitResources = SubmitResources;
+ HostBridge->ResAlloc.GetProposedResources = GetProposedResources;
+ HostBridge->ResAlloc.PreprocessController = PreprocessController;
+
+ Status = gBS->InstallProtocolInterface (
+ &HostBridge->HostBridgeHandle,
+ &gEfiPciHostBridgeResourceAllocationProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ &HostBridge->ResAlloc
+ );
+ if (EFI_ERROR (Status)) {
+ gBS->FreePool (HostBridge);
+ return EFI_DEVICE_ERROR;
+ }
+
+ Status = gBS->AllocatePool (EfiBootServicesData,
+ HostBridge->RootBridgeCount * sizeof(PCI_ROOT_BRIDGE_RESOURCE_APERTURE),
+ (VOID **) &mResAperture);
+ ASSERT_EFI_ERROR (Status);
+ ZeroMem (mResAperture, HostBridge->RootBridgeCount * sizeof(PCI_ROOT_BRIDGE_RESOURCE_APERTURE));
+
+ DEBUG ((EFI_D_INFO, "Address of resource Aperture: %x\n", mResAperture));
+
+ //
+ // Create Root Bridge Device Handle in this Host Bridge
+ //
+ InitializeListHead (&HostBridge->Head);
+
+ TotalRootBridgeFound = 0;
+
+ Status = gBS->AllocatePool ( EfiBootServicesData,sizeof (PCI_ROOT_BRIDGE_INSTANCE), (VOID **) &PrivateData);
+ ASSERT_EFI_ERROR (Status);
+ ZeroMem (PrivateData, sizeof (PCI_ROOT_BRIDGE_INSTANCE));
+
+ PrivateData->Signature = PCI_ROOT_BRIDGE_SIGNATURE;
+ PrivateData->DevicePath = (EFI_DEVICE_PATH_PROTOCOL *) &mEfiPciRootBridgeDevicePath[TotalRootBridgeFound];
+ AllocAttributes = GetAllocAttributes (TotalRootBridgeFound);
+
+ SimpleIioRootBridgeConstructor (
+ &PrivateData->Io,
+ HostBridge->HostBridgeHandle,
+ &(mResAperture[TotalRootBridgeFound]),
+ AllocAttributes
+ );
+ //
+ // Update Root Bridge with UDS resource information
+ //
+ PrivateData->Aperture.BusBase = QNC_PCI_HOST_BRIDGE_RESOURCE_APPETURE_BUSBASE;
+ PrivateData->Aperture.BusLimit = QNC_PCI_HOST_BRIDGE_RESOURCE_APPETURE_BUSLIMIT;
+ PrivateData->Aperture.Mem32Base = PcdGet32 (PcdPciHostBridgeMemory32Base);
+ PrivateData->Aperture.Mem32Limit = PcdGet32 (PcdPciHostBridgeMemory32Base) + (PcdGet32 (PcdPciHostBridgeMemory32Size) - 1);
+ PrivateData->Aperture.IoBase = PcdGet16 (PcdPciHostBridgeIoBase);
+ PrivateData->Aperture.IoLimit = PcdGet16 (PcdPciHostBridgeIoBase) + (PcdGet16 (PcdPciHostBridgeIoSize) - 1);
+
+ DEBUG ((EFI_D_INFO, "PCI Host Bridge BusBase: %x\n", QNC_PCI_HOST_BRIDGE_RESOURCE_APPETURE_BUSBASE));
+ DEBUG ((EFI_D_INFO, "PCI Host Bridge BusLimit: %x\n", QNC_PCI_HOST_BRIDGE_RESOURCE_APPETURE_BUSLIMIT));
+ DEBUG ((EFI_D_INFO, "PCI Host Bridge PciResourceMem32Base: %x\n", PcdGet32 (PcdPciHostBridgeMemory32Base)));
+ DEBUG ((EFI_D_INFO, "PCI Host Bridge PciResourceMem32Limit: %x\n", PcdGet32 (PcdPciHostBridgeMemory32Base) + (PcdGet32 (PcdPciHostBridgeMemory32Size) - 1)));
+ DEBUG ((EFI_D_INFO, "PCI Host Bridge PciResourceMem64Base: %lX\n", PcdGet64 (PcdPciHostBridgeMemory64Base)));
+ DEBUG ((EFI_D_INFO, "PCI Host Bridge PciResourceMem64Limit: %lX\n", PcdGet64 (PcdPciHostBridgeMemory64Base) + (PcdGet64 (PcdPciHostBridgeMemory64Size) - 1)));
+ DEBUG ((EFI_D_INFO, "PCI Host Bridge PciResourceIoBase: %x\n", PcdGet16 (PcdPciHostBridgeIoBase)));
+ DEBUG ((EFI_D_INFO, "PCI Host Bridge PciResourceIoLimit: %x\n", PcdGet16 (PcdPciHostBridgeIoBase) + (PcdGet16 (PcdPciHostBridgeIoSize) - 1)));
+
+ PrivateData->Handle = NULL;
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &PrivateData->Handle,
+ &gEfiDevicePathProtocolGuid,
+ PrivateData->DevicePath,
+ &gEfiPciRootBridgeIoProtocolGuid,
+ &PrivateData->Io,
+ NULL
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ InsertTailList (&HostBridge->Head, &PrivateData->Link);
+ TotalRootBridgeFound++; // This is a valid rootbridge so imcrement total root bridges found
+
+ //
+ // Add PCIE base into Runtime memory so that it can be reported in E820 table
+ //
+ Status = gDS->AddMemorySpace (
+ EfiGcdMemoryTypeMemoryMappedIo,
+ PcdGet64 (PcdPciExpressBaseAddress),
+ PcdGet64 (PcdPciExpressSize),
+ EFI_MEMORY_RUNTIME | EFI_MEMORY_UC
+ );
+ ASSERT_EFI_ERROR(Status);
+
+ BaseAddress = PcdGet64 (PcdPciExpressBaseAddress);
+
+ Status = gDS->AllocateMemorySpace (
+ EfiGcdAllocateAddress,
+ EfiGcdMemoryTypeMemoryMappedIo,
+ 0,
+ PcdGet64 (PcdPciExpressSize),
+ &BaseAddress,
+ ImageHandle,
+ NULL
+ );
+ ASSERT_EFI_ERROR(Status);
+
+ Status = gDS->SetMemorySpaceAttributes (
+ PcdGet64 (PcdPciExpressBaseAddress),
+ PcdGet64 (PcdPciExpressSize),
+ EFI_MEMORY_RUNTIME
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ if (PcdGet16 (PcdPciHostBridgeIoSize) > 0) {
+ //
+ // At present, we use up the first 4k for fixed ranges like
+ // ICH GPIO, ACPI and ISA devices. The first 4k is not
+ // tracked through GCD. It should be.
+ //
+ Status = gDS->AddIoSpace (
+ EfiGcdIoTypeIo,
+ PcdGet16(PcdPciHostBridgeIoBase),
+ PcdGet16(PcdPciHostBridgeIoSize)
+ );
+ ASSERT_EFI_ERROR (Status);
+ }
+
+ if (PcdGet32(PcdPciHostBridgeMemory32Size) > 0) {
+ //
+ // Shouldn't the capabilities be UC?
+ //
+ Status = gDS->AddMemorySpace (
+ EfiGcdMemoryTypeMemoryMappedIo,
+ PcdGet32(PcdPciHostBridgeMemory32Base),
+ PcdGet32(PcdPciHostBridgeMemory32Size),
+ 0
+ );
+ ASSERT_EFI_ERROR (Status);
+ }
+
+ return Status;
+}
+
+EFI_STATUS
+EFIAPI
+NotifyPhase (
+ IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,
+ IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PHASE Phase
+ )
+/*++
+
+Routine Description:
+
+ Enter a certain phase of the PCI enumeration process.
+
+Arguments:
+
+ This - The EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL instance.
+ Phase - The phase during enumeration.
+
+Returns:
+
+ EFI_SUCCESS - Succeed.
+ EFI_INVALID_PARAMETER - Wrong phase parameter passed in.
+ EFI_NOT_READY - Resources have not been submitted yet.
+
+--*/
+{
+ PCI_HOST_BRIDGE_INSTANCE *HostBridgeInstance;
+ PCI_ROOT_BRIDGE_INSTANCE *RootBridgeInstance;
+ PCI_RESOURCE_TYPE Index;
+ EFI_LIST_ENTRY *List;
+ EFI_PHYSICAL_ADDRESS BaseAddress;
+ UINT64 AddrLen;
+ UINTN BitsOfAlignment;
+ UINT64 Alignment;
+ EFI_STATUS Status;
+ EFI_STATUS ReturnStatus;
+ PCI_RESOURCE_TYPE Index1;
+ PCI_RESOURCE_TYPE Index2;
+ BOOLEAN ResNodeHandled[TypeMax];
+ UINT64 MaxAlignment;
+
+ HostBridgeInstance = INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This);
+
+ switch (Phase) {
+ case EfiPciHostBridgeBeginEnumeration:
+ if (HostBridgeInstance->CanRestarted) {
+ //
+ // Reset Root Bridge
+ //
+ List = HostBridgeInstance->Head.ForwardLink;
+
+ while (List != &HostBridgeInstance->Head) {
+ RootBridgeInstance = DRIVER_INSTANCE_FROM_LIST_ENTRY (List);
+ for (Index = TypeIo; Index < TypeMax; Index++) {
+ RootBridgeInstance->ResAllocNode[Index].Type = Index;
+ RootBridgeInstance->ResAllocNode[Index].Base = 0;
+ RootBridgeInstance->ResAllocNode[Index].Length = 0;
+ RootBridgeInstance->ResAllocNode[Index].Status = ResNone;
+ } // for
+
+ List = List->ForwardLink;
+ } // while
+
+ HostBridgeInstance->ResourceSubmited = FALSE;
+ HostBridgeInstance->CanRestarted = TRUE;
+ } else {
+ //
+ // Can not restart
+ //
+ return EFI_NOT_READY;
+ } // if
+ break;
+
+ case EfiPciHostBridgeEndEnumeration:
+ return EFI_SUCCESS;
+ break;
+
+ case EfiPciHostBridgeBeginBusAllocation:
+ //
+ // No specific action is required here, can perform any chipset specific programing
+ //
+ HostBridgeInstance->CanRestarted = FALSE;
+ return EFI_SUCCESS;
+ break;
+
+ case EfiPciHostBridgeEndBusAllocation:
+ //
+ // No specific action is required here, can perform any chipset specific programing
+ //
+ // HostBridgeInstance->CanRestarted = FALSE;
+ //
+ return EFI_SUCCESS;
+ break;
+
+ case EfiPciHostBridgeBeginResourceAllocation:
+ //
+ // No specific action is required here, can perform any chipset specific programing
+ //
+ // HostBridgeInstance->CanRestarted = FALSE;
+ //
+ return EFI_SUCCESS;
+ break;
+
+ case EfiPciHostBridgeAllocateResources:
+ ReturnStatus = EFI_SUCCESS;
+ if (HostBridgeInstance->ResourceSubmited) {
+ List = HostBridgeInstance->Head.ForwardLink;
+ while (List != &HostBridgeInstance->Head) {
+ for (Index1 = TypeIo; Index1 < TypeBus; Index1++) {
+ ResNodeHandled[Index1] = FALSE;
+ }
+
+ RootBridgeInstance = DRIVER_INSTANCE_FROM_LIST_ENTRY (List);
+ DEBUG ((EFI_D_INFO, "Address of RootBridgeInstance: %x)\n", RootBridgeInstance));
+ DEBUG ((EFI_D_INFO, " Signature: %x\n", RootBridgeInstance->Signature));
+ DEBUG ((EFI_D_INFO, " Bus Number Assigned: %x\n", RootBridgeInstance->BusNumberAssigned));
+ DEBUG ((EFI_D_INFO, " Bus Scan Count: %x\n", RootBridgeInstance->BusScanCount));
+
+ for (Index1 = TypeIo; Index1 < TypeBus; Index1++) {
+ if (RootBridgeInstance->ResAllocNode[Index1].Status == ResNone) {
+ ResNodeHandled[Index1] = TRUE;
+ } else {
+ //
+ // Allocate the resource node with max alignment at first
+ //
+ MaxAlignment = 0;
+ Index = TypeMax;
+ for (Index2 = TypeIo; Index2 < TypeBus; Index2++) {
+ if (ResNodeHandled[Index2]) {
+ continue;
+ }
+ if (MaxAlignment <= RootBridgeInstance->ResAllocNode[Index2].Alignment) {
+ MaxAlignment = RootBridgeInstance->ResAllocNode[Index2].Alignment;
+ Index = Index2;
+ }
+ } // for
+
+ if (Index < TypeMax) {
+ ResNodeHandled[Index] = TRUE;
+ } else {
+ ASSERT (FALSE);
+ }
+
+ Alignment = RootBridgeInstance->ResAllocNode[Index].Alignment;
+
+ //
+ // Get the number of '1' in Alignment.
+ //
+ for (BitsOfAlignment = 0; Alignment != 0; BitsOfAlignment++) {
+ Alignment = RShiftU64 (Alignment, 1);
+ }
+
+ AddrLen = RootBridgeInstance->ResAllocNode[Index].Length;
+ Alignment = RootBridgeInstance->ResAllocNode[Index].Alignment;
+
+ DEBUG ((EFI_D_INFO, "\n\nResource Type to assign : %x\n", Index));
+ DEBUG ((EFI_D_INFO, " Length to allocate: %x\n", RootBridgeInstance->ResAllocNode[Index].Length));
+ DEBUG ((EFI_D_INFO, " Aligment: %x\n", Alignment));
+
+ switch (Index) {
+ case TypeIo:
+ if (RootBridgeInstance->Aperture.IoBase < RootBridgeInstance->Aperture.IoLimit) {
+ //
+ // It is impossible for 0xFFFF Alignment for IO16
+ //
+ if (BitsOfAlignment >= 16)
+ Alignment = 0;
+
+ BaseAddress = RootBridgeInstance->Aperture.IoBase;
+
+ //
+ // Have to make sure Aligment is handled seeing we are doing direct address allocation
+ //
+ if ((BaseAddress & ~(Alignment)) != BaseAddress)
+ BaseAddress = ((BaseAddress + Alignment) & ~(Alignment));
+
+ while((BaseAddress + AddrLen) <= RootBridgeInstance->Aperture.IoLimit + 1) {
+
+ Status = gDS->AllocateIoSpace ( EfiGcdAllocateAddress, EfiGcdIoTypeIo, BitsOfAlignment,
+ AddrLen, &BaseAddress, mDriverImageHandle, NULL );
+
+ if (!EFI_ERROR (Status)) {
+ RootBridgeInstance->ResAllocNode[Index].Base = (UINT64) BaseAddress;
+ RootBridgeInstance->ResAllocNode[Index].Status = ResAllocated;
+ goto TypeIoFound;
+ }
+
+ BaseAddress += (Alignment + 1);
+ } // while
+
+ } // if
+
+ TypeIoFound:
+ if (RootBridgeInstance->ResAllocNode[Index].Status != ResAllocated) {
+ //
+ // No Room at the Inn for this resources request
+ //
+ ReturnStatus = EFI_OUT_OF_RESOURCES;
+ } // if
+
+ break;
+
+ case TypeMem32:
+ if (RootBridgeInstance->Aperture.Mem32Base < RootBridgeInstance->Aperture.Mem32Limit) {
+
+ BaseAddress = RootBridgeInstance->Aperture.Mem32Base;
+ //
+ // Have to make sure Aligment is handled seeing we are doing direct address allocation
+ //
+ if ((BaseAddress & ~(Alignment)) != BaseAddress)
+ BaseAddress = ((BaseAddress + Alignment) & ~(Alignment));
+
+ while((BaseAddress + AddrLen) <= RootBridgeInstance->Aperture.Mem32Limit + 1) {
+
+ Status = gDS->AllocateMemorySpace ( EfiGcdAllocateAddress, EfiGcdMemoryTypeMemoryMappedIo,
+ BitsOfAlignment, AddrLen, &BaseAddress, mDriverImageHandle, NULL);
+
+ if (!EFI_ERROR (Status)) {
+ RootBridgeInstance->ResAllocNode[Index].Base = (UINT64) BaseAddress;
+ RootBridgeInstance->ResAllocNode[Index].Status = ResAllocated;
+ goto TypeMem32Found;
+ } // if
+
+ BaseAddress += (Alignment + 1);
+ } // while
+ } // if
+
+ TypeMem32Found:
+ if (RootBridgeInstance->ResAllocNode[Index].Status != ResAllocated) {
+ //
+ // No Room at the Inn for this resources request
+ //
+ ReturnStatus = EFI_OUT_OF_RESOURCES;
+ }
+
+ break;
+
+ case TypePMem32:
+ StartTypePMem32:
+ if (RootBridgeInstance->Aperture.Mem32Base < RootBridgeInstance->Aperture.Mem32Limit) {
+
+ BaseAddress = RootBridgeInstance->Aperture.Mem32Limit + 1;
+ BaseAddress -= AddrLen;
+
+ //
+ // Have to make sure Aligment is handled seeing we are doing direct address allocation
+ //
+ if ((BaseAddress & ~(Alignment)) != BaseAddress)
+ BaseAddress = ((BaseAddress) & ~(Alignment));
+
+ while(RootBridgeInstance->Aperture.Mem32Base <= BaseAddress) {
+
+ DEBUG ((EFI_D_INFO, " Attempting %x allocation at 0x%lx .....", Index, BaseAddress));
+ Status = gDS->AllocateMemorySpace ( EfiGcdAllocateAddress, EfiGcdMemoryTypeMemoryMappedIo,
+ BitsOfAlignment, AddrLen, &BaseAddress, mDriverImageHandle, NULL);
+
+ if (!EFI_ERROR (Status)) {
+ RootBridgeInstance->ResAllocNode[Index].Base = (UINT64) BaseAddress;
+ RootBridgeInstance->ResAllocNode[Index].Status = ResAllocated;
+ DEBUG ((EFI_D_INFO, "... Passed!!\n"));
+ goto TypePMem32Found;
+ }
+ DEBUG ((EFI_D_INFO, "... Failed!!\n"));
+ BaseAddress -= (Alignment + 1);
+ } // while
+ } // if
+
+ TypePMem32Found:
+ if (RootBridgeInstance->ResAllocNode[Index].Status != ResAllocated) {
+ //
+ // No Room at the Inn for this resources request
+ //
+ ReturnStatus = EFI_OUT_OF_RESOURCES;
+ }
+
+ break;
+
+ case TypeMem64:
+ case TypePMem64:
+ if (RootBridgeInstance->ResAllocNode[Index].Status != ResAllocated) {
+ //
+ // If 64-bit resourcing is not available, then try as PMem32
+ //
+ goto StartTypePMem32;
+ }
+
+ break;
+
+ default:
+ break;
+ } // End switch (Index)
+
+ DEBUG ((EFI_D_INFO, "Resource Type Assigned: %x\n", Index));
+ if (RootBridgeInstance->ResAllocNode[Index].Status == ResAllocated) {
+ DEBUG ((EFI_D_INFO, " Base Address Assigned: %x\n", RootBridgeInstance->ResAllocNode[Index].Base));
+ DEBUG ((EFI_D_INFO, " Length Assigned: %x\n", RootBridgeInstance->ResAllocNode[Index].Length));
+ } else {
+ DEBUG ((DEBUG_ERROR, " Resource Allocation failed! There was no room at the inn\n"));
+ }
+
+ }
+ }
+
+ List = List->ForwardLink;
+ }
+
+ if (ReturnStatus == EFI_OUT_OF_RESOURCES) {
+ DEBUG ((DEBUG_ERROR, "Resource allocation Failed. Continue booting the system.\n"));
+ }
+
+ //
+ // Set resource to zero for nodes where allocation fails
+ //
+ List = HostBridgeInstance->Head.ForwardLink;
+ while (List != &HostBridgeInstance->Head) {
+ RootBridgeInstance = DRIVER_INSTANCE_FROM_LIST_ENTRY (List);
+ for (Index = TypeIo; Index < TypeBus; Index++) {
+ if (RootBridgeInstance->ResAllocNode[Index].Status != ResAllocated) {
+ RootBridgeInstance->ResAllocNode[Index].Length = 0;
+ }
+ }
+ List = List->ForwardLink;
+ }
+ return ReturnStatus;
+ } else {
+ return EFI_NOT_READY;
+ }
+ //
+ // HostBridgeInstance->CanRestarted = FALSE;
+ //
+ break;
+
+ case EfiPciHostBridgeSetResources:
+ //
+ // HostBridgeInstance->CanRestarted = FALSE;
+ //
+ break;
+
+ case EfiPciHostBridgeFreeResources:
+ //
+ // HostBridgeInstance->CanRestarted = FALSE;
+ //
+ ReturnStatus = EFI_SUCCESS;
+ List = HostBridgeInstance->Head.ForwardLink;
+ while (List != &HostBridgeInstance->Head) {
+ RootBridgeInstance = DRIVER_INSTANCE_FROM_LIST_ENTRY (List);
+ for (Index = TypeIo; Index < TypeBus; Index++) {
+ if (RootBridgeInstance->ResAllocNode[Index].Status == ResAllocated) {
+ AddrLen = RootBridgeInstance->ResAllocNode[Index].Length;
+ BaseAddress = (EFI_PHYSICAL_ADDRESS) RootBridgeInstance->ResAllocNode[Index].Base;
+ switch (Index) {
+ case TypeIo:
+ Status = gDS->FreeIoSpace (BaseAddress, AddrLen);
+ if (EFI_ERROR (Status)) {
+ ReturnStatus = Status;
+ }
+ break;
+
+ case TypeMem32:
+ Status = gDS->FreeMemorySpace (BaseAddress, AddrLen);
+ if (EFI_ERROR (Status)) {
+ ReturnStatus = Status;
+ }
+ break;
+
+ case TypePMem32:
+ break;
+
+ case TypeMem64:
+ break;
+
+ case TypePMem64:
+ Status = gDS->FreeMemorySpace (BaseAddress, AddrLen);
+ if (EFI_ERROR (Status)) {
+ ReturnStatus = Status;
+ }
+ break;
+
+ default:
+ break;
+ } // end switch (Index)
+
+ RootBridgeInstance->ResAllocNode[Index].Type = Index;
+ RootBridgeInstance->ResAllocNode[Index].Base = 0;
+ RootBridgeInstance->ResAllocNode[Index].Length = 0;
+ RootBridgeInstance->ResAllocNode[Index].Status = ResNone;
+ }
+ }
+
+ List = List->ForwardLink;
+ }
+
+ HostBridgeInstance->ResourceSubmited = FALSE;
+ HostBridgeInstance->CanRestarted = TRUE;
+ return ReturnStatus;
+ break;
+
+ case EfiPciHostBridgeEndResourceAllocation:
+ //
+ // Resource enumeration is done. Perform any activities that
+ // must wait until that time.
+ //
+ break;
+
+ default:
+ return EFI_INVALID_PARAMETER;
+ } // End switch (Phase)
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+GetNextRootBridge (
+ IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,
+ IN OUT EFI_HANDLE *RootBridgeHandle
+ )
+/*++
+
+Routine Description:
+ Return the device handle of the next PCI root bridge that is associated with
+ this Host Bridge.
+
+Arguments:
+
+ This - The EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_ PROTOCOL instance.
+ RootBridgeHandle - Returns the device handle of the next PCI Root Bridge.
+ On input, it holds the RootBridgeHandle returned by the most
+ recent call to GetNextRootBridge().The handle for the first
+ PCI Root Bridge is returned if RootBridgeHandle is NULL on input.
+
+Returns:
+
+ EFI_SUCCESS - Succeed.
+ EFI_NOT_FOUND - Next PCI root bridge not found.
+ EFI_INVALID_PARAMETER - Wrong parameter passed in.
+
+--*/
+{
+ BOOLEAN NoRootBridge;
+ EFI_LIST_ENTRY *List;
+ PCI_HOST_BRIDGE_INSTANCE *HostBridgeInstance;
+ PCI_ROOT_BRIDGE_INSTANCE *RootBridgeInstance;
+
+ NoRootBridge = TRUE;
+ HostBridgeInstance = INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This);
+ List = HostBridgeInstance->Head.ForwardLink;
+
+ while (List != &HostBridgeInstance->Head) {
+ NoRootBridge = FALSE;
+ RootBridgeInstance = DRIVER_INSTANCE_FROM_LIST_ENTRY (List);
+ if (*RootBridgeHandle == NULL) {
+ //
+ // Return the first Root Bridge Handle of the Host Bridge
+ //
+ *RootBridgeHandle = RootBridgeInstance->Handle;
+ return EFI_SUCCESS;
+ } else {
+ if (*RootBridgeHandle == RootBridgeInstance->Handle) {
+ //
+ // Get next if have
+ //
+ List = List->ForwardLink;
+ if (List != &HostBridgeInstance->Head) {
+ RootBridgeInstance = DRIVER_INSTANCE_FROM_LIST_ENTRY (List);
+ *RootBridgeHandle = RootBridgeInstance->Handle;
+ return EFI_SUCCESS;
+ } else {
+ return EFI_NOT_FOUND;
+ }
+ }
+ }
+
+ List = List->ForwardLink;
+ //
+ // end while
+ //
+ }
+
+ if (NoRootBridge) {
+ return EFI_NOT_FOUND;
+ } else {
+ return EFI_INVALID_PARAMETER;
+ }
+}
+
+EFI_STATUS
+EFIAPI
+GetAttributes (
+ IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,
+ IN EFI_HANDLE RootBridgeHandle,
+ OUT UINT64 *Attributes
+ )
+/*++
+
+Routine Description:
+ Returns the attributes of a PCI Root Bridge.
+
+Arguments:
+
+ This - The EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_ PROTOCOL instance.
+ RootBridgeHandle - The device handle of the PCI Root Bridge
+ that the caller is interested in.
+ Attributes - The pointer to attributes of the PCI Root Bridge.
+
+Returns:
+
+ EFI_SUCCESS - Succeed.
+ EFI_INVALID_PARAMETER - Attributes parameter passed in is NULL or
+ RootBridgeHandle is not an EFI_HANDLE
+ that was returned on a previous call to
+ GetNextRootBridge().
+
+--*/
+{
+ EFI_LIST_ENTRY *List;
+ PCI_HOST_BRIDGE_INSTANCE *HostBridgeInstance;
+ PCI_ROOT_BRIDGE_INSTANCE *RootBridgeInstance;
+
+ if (Attributes == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ HostBridgeInstance = INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This);
+ List = HostBridgeInstance->Head.ForwardLink;
+
+ while (List != &HostBridgeInstance->Head) {
+ RootBridgeInstance = DRIVER_INSTANCE_FROM_LIST_ENTRY (List);
+ if (RootBridgeHandle == RootBridgeInstance->Handle) {
+ *Attributes = RootBridgeInstance->RootBridgeAllocAttrib;
+ return EFI_SUCCESS;
+ }
+
+ List = List->ForwardLink;
+ }
+ //
+ // RootBridgeHandle is not an EFI_HANDLE
+ // that was returned on a previous call to GetNextRootBridge()
+ //
+ return EFI_INVALID_PARAMETER;
+}
+
+EFI_STATUS
+EFIAPI
+StartBusEnumeration (
+ IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,
+ IN EFI_HANDLE RootBridgeHandle,
+ OUT VOID **Configuration
+ )
+/*++
+
+Routine Description:
+ This is the request from the PCI enumerator to set up
+ the specified PCI Root Bridge for bus enumeration process.
+
+Arguments:
+
+ This - The EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_ PROTOCOL instance.
+ RootBridgeHandle - The PCI Root Bridge to be set up.
+ Configuration - Pointer to the pointer to the PCI bus resource descriptor.
+
+Returns:
+
+ EFI_SUCCESS - Succeed.
+ EFI_OUT_OF_RESOURCES - Not enough pool to be allocated.
+ EFI_INVALID_PARAMETER - RootBridgeHandle is not a valid handle.
+
+--*/
+{
+ EFI_LIST_ENTRY *List;
+ PCI_HOST_BRIDGE_INSTANCE *HostBridgeInstance;
+ PCI_ROOT_BRIDGE_INSTANCE *RootBridgeInstance;
+ VOID *Buffer;
+ UINT8 *Temp;
+ EFI_STATUS Status;
+ UINTN BusStart;
+ UINTN BusEnd;
+ UINT64 BusReserve;
+
+ HostBridgeInstance = INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This);
+ List = HostBridgeInstance->Head.ForwardLink;
+
+ while (List != &HostBridgeInstance->Head) {
+ RootBridgeInstance = DRIVER_INSTANCE_FROM_LIST_ENTRY (List);
+ if (RootBridgeHandle == RootBridgeInstance->Handle) {
+ //
+ // Set up the Root Bridge for Bus Enumeration
+ //
+ BusStart = RootBridgeInstance->Aperture.BusBase;
+ BusEnd = RootBridgeInstance->Aperture.BusLimit;
+ BusReserve = RootBridgeInstance->Aperture.BusReserve;
+ //
+ // Program the Hardware(if needed) if error return EFI_DEVICE_ERROR
+ //
+ Status = gBS->AllocatePool (
+ EfiBootServicesData,
+ sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) + sizeof (EFI_ACPI_END_TAG_DESCRIPTOR),
+ &Buffer
+ );
+ if (EFI_ERROR (Status)) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ Temp = (UINT8 *) Buffer;
+
+ ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) Temp)->Desc = ACPI_ADDRESS_SPACE_DESCRIPTOR;
+ ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) Temp)->Len = 0x2B;
+ ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) Temp)->ResType = ACPI_ADDRESS_SPACE_TYPE_BUS;
+ ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) Temp)->GenFlag = 0;
+ ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) Temp)->SpecificFlag = 0;
+ ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) Temp)->AddrSpaceGranularity = 0;
+ ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) Temp)->AddrRangeMin = BusStart;
+ ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) Temp)->AddrRangeMax = BusReserve;
+ ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) Temp)->AddrTranslationOffset = 0;
+ ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) Temp)->AddrLen = BusEnd - BusStart + 1;
+
+ Temp = Temp + sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR);
+ ((EFI_ACPI_END_TAG_DESCRIPTOR *) Temp)->Desc = ACPI_END_TAG_DESCRIPTOR;
+ ((EFI_ACPI_END_TAG_DESCRIPTOR *) Temp)->Checksum = 0x0;
+
+ *Configuration = Buffer;
+ return EFI_SUCCESS;
+ }
+
+ List = List->ForwardLink;
+ }
+
+ return EFI_INVALID_PARAMETER;
+}
+
+EFI_STATUS
+EFIAPI
+SetBusNumbers (
+ IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,
+ IN EFI_HANDLE RootBridgeHandle,
+ IN VOID *Configuration
+ )
+/*++
+
+Routine Description:
+ This function programs the PCI Root Bridge hardware so that
+ it decodes the specified PCI bus range.
+
+Arguments:
+
+ This - The EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_ PROTOCOL instance.
+ RootBridgeHandle - The PCI Root Bridge whose bus range is to be programmed.
+ Configuration - The pointer to the PCI bus resource descriptor.
+
+Returns:
+
+ EFI_SUCCESS - Succeed.
+ EFI_INVALID_PARAMETER - Wrong parameters passed in.
+
+--*/
+{
+ EFI_LIST_ENTRY *List;
+ PCI_HOST_BRIDGE_INSTANCE *HostBridgeInstance;
+ PCI_ROOT_BRIDGE_INSTANCE *RootBridgeInstance;
+ UINT8 *Ptr;
+ UINTN BusStart;
+ UINTN BusEnd;
+ UINTN BusLen;
+
+ if (Configuration == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Ptr = Configuration;
+
+ //
+ // Check the Configuration is valid
+ //
+ if (*Ptr != ACPI_ADDRESS_SPACE_DESCRIPTOR) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) Ptr)->ResType != ACPI_ADDRESS_SPACE_TYPE_BUS) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Ptr += sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR);
+ if (*Ptr != ACPI_END_TAG_DESCRIPTOR) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ HostBridgeInstance = INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This);
+ List = HostBridgeInstance->Head.ForwardLink;
+
+ Ptr = Configuration;
+
+ while (List != &HostBridgeInstance->Head) {
+ RootBridgeInstance = DRIVER_INSTANCE_FROM_LIST_ENTRY (List);
+ if (RootBridgeHandle == RootBridgeInstance->Handle) {
+ BusStart = (UINTN) ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) Ptr)->AddrRangeMin;
+ BusLen = (UINTN) ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) Ptr)->AddrLen;
+ BusEnd = BusStart + BusLen - 1;
+
+ if (BusStart > BusEnd) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if ((BusStart < RootBridgeInstance->Aperture.BusBase) || (BusEnd > RootBridgeInstance->Aperture.BusLimit)) {
+ return EFI_INVALID_PARAMETER;
+ }
+ //
+ // Update the Bus Range
+ //
+ RootBridgeInstance->ResAllocNode[TypeBus].Base = BusStart;
+ RootBridgeInstance->ResAllocNode[TypeBus].Length = BusLen;
+ RootBridgeInstance->ResAllocNode[TypeBus].Status = ResAllocated;
+ RootBridgeInstance->BusScanCount++;
+ if (RootBridgeInstance->BusScanCount > 0) {
+ //
+ // Only care about the 2nd PCI bus scanning
+ //
+ RootBridgeInstance->BusNumberAssigned = TRUE;
+ }
+
+ return EFI_SUCCESS;
+ }
+
+ List = List->ForwardLink;
+ }
+
+ return EFI_INVALID_PARAMETER;
+}
+
+EFI_STATUS
+EFIAPI
+SubmitResources (
+ IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,
+ IN EFI_HANDLE RootBridgeHandle,
+ IN VOID *Configuration
+ )
+/*++
+
+Routine Description:
+
+ Submits the I/O and memory resource requirements for the specified PCI Root Bridge.
+
+Arguments:
+ This - The EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_ PROTOCOL instance.
+ RootBridgeHandle - The PCI Root Bridge whose I/O and memory resource requirements.
+ are being submitted.
+ Configuration - The pointer to the PCI I/O and PCI memory resource descriptor.
+
+Returns:
+
+ EFI_SUCCESS - Succeed.
+ EFI_INVALID_PARAMETER - Wrong parameters passed in.
+
+--*/
+{
+ EFI_LIST_ENTRY *List;
+ PCI_HOST_BRIDGE_INSTANCE *HostBridgeInstance;
+ PCI_ROOT_BRIDGE_INSTANCE *RootBridgeInstance;
+ UINT8 *Temp;
+ EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *ptr;
+ UINT64 AddrLen;
+ UINT64 Alignment;
+ UINT64 Value;
+
+ //
+ // Check the input parameter: Configuration
+ //
+ if (Configuration == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ HostBridgeInstance = INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This);
+ List = HostBridgeInstance->Head.ForwardLink;
+
+ Temp = (UINT8 *) Configuration;
+ while (List != &HostBridgeInstance->Head) {
+ RootBridgeInstance = DRIVER_INSTANCE_FROM_LIST_ENTRY (List);
+ if (RootBridgeHandle == RootBridgeInstance->Handle) {
+ //
+ // Check the resource descriptors.
+ // If the Configuration includes one or more invalid resource descriptors, all the resource
+ // descriptors are ignored and the function returns EFI_INVALID_PARAMETER.
+ //
+ while (*Temp == ACPI_ADDRESS_SPACE_DESCRIPTOR) {
+ ptr = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) Temp;
+ DEBUG ((EFI_D_INFO, " ptr->ResType:%x \n",ptr->ResType));
+ DEBUG ((EFI_D_INFO, " ptr->AddrLen:0x%lx AddrRangeMin:0x%lx AddrRangeMax:0x%lx\n\n",ptr->AddrLen,ptr->AddrRangeMin,ptr->AddrRangeMax));
+
+ switch (ptr->ResType) {
+ case ACPI_ADDRESS_SPACE_TYPE_MEM:
+ if (ptr->AddrSpaceGranularity != 32 && ptr->AddrSpaceGranularity != 64) {
+ return EFI_INVALID_PARAMETER;
+ }
+ if (ptr->AddrSpaceGranularity == 32 && ptr->AddrLen > 0xffffffff) {
+ return EFI_INVALID_PARAMETER;
+ }
+ //
+ // If the PCI root bridge does not support separate windows for nonprefetchable and
+ // prefetchable memory, then the PCI bus driver needs to include requests for
+ // prefetchable memory in the nonprefetchable memory pool.
+ //
+ if ((RootBridgeInstance->RootBridgeAllocAttrib & EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM) != 0 &&
+ ((ptr->SpecificFlag & (BIT2 | BIT1)) != 0)) {
+ return EFI_INVALID_PARAMETER;
+ }
+ case ACPI_ADDRESS_SPACE_TYPE_IO:
+ //
+ // Check aligment, it should be of the form 2^n-1
+ //
+ Value = Power2MaxMemory (ptr->AddrRangeMax + 1);
+ if (Value != (ptr->AddrRangeMax + 1)) {
+ CpuDeadLoop();
+ return EFI_INVALID_PARAMETER;
+ }
+ break;
+ case ACPI_ADDRESS_SPACE_TYPE_BUS:
+ default:
+ return EFI_INVALID_PARAMETER;
+ }
+ Temp += sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) ;
+ }
+ if (*Temp != ACPI_END_TAG_DESCRIPTOR) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Temp = (UINT8 *) Configuration;
+ while (*Temp == ACPI_ADDRESS_SPACE_DESCRIPTOR) {
+ ptr = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) Temp;
+
+ switch (ptr->ResType) {
+ case ACPI_ADDRESS_SPACE_TYPE_MEM:
+ AddrLen = (UINT64) ptr->AddrLen;
+ Alignment = (UINT64) ptr->AddrRangeMax;
+ if (ptr->AddrSpaceGranularity == 32) {
+ if (ptr->SpecificFlag == 0x06) {
+ //
+ // Apply from GCD
+ //
+ RootBridgeInstance->ResAllocNode[TypePMem32].Status = ResSubmitted;
+ } else {
+ RootBridgeInstance->ResAllocNode[TypeMem32].Length = AddrLen;
+ RootBridgeInstance->ResAllocNode[TypeMem32].Alignment = Alignment;
+ RootBridgeInstance->ResAllocNode[TypeMem32].Status = ResRequested;
+ HostBridgeInstance->ResourceSubmited = TRUE;
+ }
+ }
+
+ if (ptr->AddrSpaceGranularity == 64) {
+ if (ptr->SpecificFlag == 0x06) {
+ RootBridgeInstance->ResAllocNode[TypePMem64].Status = ResSubmitted;
+ } else {
+ RootBridgeInstance->ResAllocNode[TypeMem64].Length = AddrLen;
+ RootBridgeInstance->ResAllocNode[TypeMem64].Alignment = Alignment;
+ RootBridgeInstance->ResAllocNode[TypeMem64].Status = ResSubmitted;
+ HostBridgeInstance->ResourceSubmited = TRUE;
+ }
+ }
+ break;
+
+ case ACPI_ADDRESS_SPACE_TYPE_IO:
+ AddrLen = (UINT64) ptr->AddrLen;
+ Alignment = (UINT64) ptr->AddrRangeMax;
+ RootBridgeInstance->ResAllocNode[TypeIo].Length = AddrLen;
+ RootBridgeInstance->ResAllocNode[TypeIo].Alignment = Alignment;
+ RootBridgeInstance->ResAllocNode[TypeIo].Status = ResRequested;
+ HostBridgeInstance->ResourceSubmited = TRUE;
+ break;
+
+ default:
+ break;
+ }
+
+ Temp += sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR);
+ }
+
+ return EFI_SUCCESS;
+ }
+
+ List = List->ForwardLink;
+ }
+
+ return EFI_INVALID_PARAMETER;
+}
+
+EFI_STATUS
+EFIAPI
+GetProposedResources (
+ IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,
+ IN EFI_HANDLE RootBridgeHandle,
+ OUT VOID **Configuration
+ )
+/*++
+
+Routine Description:
+ This function returns the proposed resource settings for the specified
+ PCI Root Bridge.
+
+Arguments:
+
+ This - The EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_ PROTOCOL instance.
+ RootBridgeHandle - The PCI Root Bridge handle.
+ Configuration - The pointer to the pointer to the PCI I/O
+ and memory resource descriptor.
+
+Returns:
+
+ EFI_SUCCESS - Succeed.
+ EFI_OUT_OF_RESOURCES - Not enough pool to be allocated.
+ EFI_INVALID_PARAMETER - RootBridgeHandle is not a valid handle.
+
+--*/
+{
+ EFI_LIST_ENTRY *List;
+ PCI_HOST_BRIDGE_INSTANCE *HostBridgeInstance;
+ PCI_ROOT_BRIDGE_INSTANCE *RootBridgeInstance;
+ UINTN Index;
+ UINTN Number;
+ VOID *Buffer;
+ UINT8 *Temp;
+ EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *ptr;
+ EFI_STATUS Status;
+ UINT64 ResStatus;
+
+ Buffer = NULL;
+ Number = 0;
+ //
+ // Get the Host Bridge Instance from the resource allocation protocol
+ //
+ HostBridgeInstance = INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This);
+ List = HostBridgeInstance->Head.ForwardLink;
+
+ //
+ // Enumerate the root bridges in this host bridge
+ //
+ while (List != &HostBridgeInstance->Head) {
+ RootBridgeInstance = DRIVER_INSTANCE_FROM_LIST_ENTRY (List);
+ if (RootBridgeHandle == RootBridgeInstance->Handle) {
+ for (Index = 0; Index < TypeBus; Index++) {
+ if (RootBridgeInstance->ResAllocNode[Index].Status != ResNone) {
+ Number++;
+ }
+ }
+
+ if (Number > 0) {
+ Status = gBS->AllocatePool (
+ EfiBootServicesData,
+ Number * sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) + sizeof (EFI_ACPI_END_TAG_DESCRIPTOR),
+ &Buffer
+ );
+
+ if (EFI_ERROR (Status)) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ ZeroMem (Buffer, sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) * Number + sizeof (EFI_ACPI_END_TAG_DESCRIPTOR));
+ }
+
+ ASSERT (Buffer != NULL);
+ Temp = Buffer;
+ for (Index = 0; Index < TypeBus; Index++) {
+ if (RootBridgeInstance->ResAllocNode[Index].Status != ResNone) {
+ ptr = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) Temp;
+ ResStatus = RootBridgeInstance->ResAllocNode[Index].Status;
+
+ switch (Index) {
+
+ case TypeIo:
+ //
+ // Io
+ //
+ ptr->Desc = 0x8A;
+ ptr->Len = 0x2B;
+ ptr->ResType = 1;
+ ptr->GenFlag = 0;
+ ptr->SpecificFlag = 0;
+ ptr->AddrRangeMin = RootBridgeInstance->ResAllocNode[Index].Base;
+ ptr->AddrRangeMax = 0;
+ ptr->AddrTranslationOffset = (ResStatus == ResAllocated) ? EFI_RESOURCE_SATISFIED : EFI_RESOURCE_LESS;
+ ptr->AddrLen = RootBridgeInstance->ResAllocNode[Index].Length;
+ break;
+
+ case TypeMem32:
+ //
+ // Memory 32
+ //
+ ptr->Desc = 0x8A;
+ ptr->Len = 0x2B;
+ ptr->ResType = 0;
+ ptr->GenFlag = 0;
+ ptr->SpecificFlag = 0;
+ ptr->AddrSpaceGranularity = 32;
+ ptr->AddrRangeMin = RootBridgeInstance->ResAllocNode[Index].Base;
+ ptr->AddrRangeMax = 0;
+ ptr->AddrTranslationOffset = (ResStatus == ResAllocated) ? EFI_RESOURCE_SATISFIED : EFI_RESOURCE_LESS;
+ ptr->AddrLen = RootBridgeInstance->ResAllocNode[Index].Length;
+ break;
+
+ case TypePMem32:
+ //
+ // Prefetch memory 32
+ //
+ ptr->Desc = 0x8A;
+ ptr->Len = 0x2B;
+ ptr->ResType = 0;
+ ptr->GenFlag = 0;
+ ptr->SpecificFlag = 6;
+ ptr->AddrSpaceGranularity = 32;
+ ptr->AddrRangeMin = 0;
+ ptr->AddrRangeMax = 0;
+ ptr->AddrTranslationOffset = EFI_RESOURCE_NONEXISTENT;
+ ptr->AddrLen = 0;
+ break;
+
+ case TypeMem64:
+ //
+ // Memory 64
+ //
+ ptr->Desc = 0x8A;
+ ptr->Len = 0x2B;
+ ptr->ResType = 0;
+ ptr->GenFlag = 0;
+ ptr->SpecificFlag = 0;
+ ptr->AddrSpaceGranularity = 64;
+ ptr->AddrRangeMin = RootBridgeInstance->ResAllocNode[Index].Base;
+ ptr->AddrRangeMax = 0;
+ ptr->AddrTranslationOffset = (ResStatus == ResAllocated) ? EFI_RESOURCE_SATISFIED : EFI_RESOURCE_LESS;
+ ptr->AddrLen = RootBridgeInstance->ResAllocNode[Index].Length;
+ break;
+
+ case TypePMem64:
+ //
+ // Prefetch memory 64
+ //
+ ptr->Desc = 0x8A;
+ ptr->Len = 0x2B;
+ ptr->ResType = 0;
+ ptr->GenFlag = 0;
+ ptr->SpecificFlag = 6;
+ ptr->AddrSpaceGranularity = 64;
+ ptr->AddrRangeMin = 0;
+ ptr->AddrRangeMax = 0;
+ ptr->AddrTranslationOffset = EFI_RESOURCE_NONEXISTENT;
+ ptr->AddrLen = 0;
+ break;
+ }
+
+ Temp += sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR);
+ }
+ }
+
+ ((EFI_ACPI_END_TAG_DESCRIPTOR *) Temp)->Desc = 0x79;
+ ((EFI_ACPI_END_TAG_DESCRIPTOR *) Temp)->Checksum = 0x0;
+
+ *Configuration = Buffer;
+
+ return EFI_SUCCESS;
+ }
+
+ List = List->ForwardLink;
+ }
+
+ return EFI_INVALID_PARAMETER;
+}
+
+EFI_STATUS
+EFIAPI
+PreprocessController (
+ IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,
+ IN EFI_HANDLE RootBridgeHandle,
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS PciAddress,
+ IN EFI_PCI_CONTROLLER_RESOURCE_ALLOCATION_PHASE Phase
+ )
+/*++
+
+Routine Description:
+ This function is called for all the PCI controllers that the PCI
+ bus driver finds. Can be used to Preprogram the controller.
+
+Arguments:
+
+ This - The EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_ PROTOCOL instance.
+ RootBridgeHandle - The PCI Root Bridge handle.
+ PciAddress - Address of the controller on the PCI bus.
+ Phase - The Phase during resource allocation.
+
+Returns:
+
+ EFI_SUCCESS - Succeed.
+ EFI_INVALID_PARAMETER - RootBridgeHandle is not a valid handle.
+
+--*/
+{
+ BOOLEAN RootBridgeFound;
+ EFI_LIST_ENTRY *List;
+ PCI_HOST_BRIDGE_INSTANCE *HostBridgeInstance;
+ PCI_ROOT_BRIDGE_INSTANCE *RootBridgeInstance;
+
+ if (RootBridgeHandle == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ RootBridgeFound = FALSE;
+ HostBridgeInstance = INSTANCE_FROM_RESOURCE_ALLOCATION_THIS (This);
+ List = HostBridgeInstance->Head.ForwardLink;
+
+ while (List != &HostBridgeInstance->Head) {
+ RootBridgeInstance = DRIVER_INSTANCE_FROM_LIST_ENTRY (List);
+
+ if (RootBridgeHandle == RootBridgeInstance->Handle) {
+ RootBridgeFound = TRUE;
+ break;
+ }
+ //
+ // Get next if have
+ //
+ List = List->ForwardLink;
+ }
+
+ if (RootBridgeFound == FALSE) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ return EFI_SUCCESS;
+}
+
+UINT64
+Power2MaxMemory (
+ IN UINT64 MemoryLength
+ )
+/*++
+
+Routine Description:
+
+ Calculate maximum memory length that can be fit to a mtrr.
+
+Arguments:
+
+ MemoryLength - Input memory length.
+
+Returns:
+
+ Returned Maximum length.
+
+--*/
+{
+ UINT64 Result;
+
+ if (RShiftU64 (MemoryLength, 32)) {
+ Result = LShiftU64 ((UINT64) GetPowerOfTwo64 ((UINT32) RShiftU64 (MemoryLength, 32)), 32);
+ } else {
+ Result = (UINT64) GetPowerOfTwo64 ((UINT32) MemoryLength);
+ }
+
+ return Result;
+}
diff --git a/QuarkPlatformPkg/Pci/Dxe/PciHostBridge/PciHostBridge.h b/QuarkPlatformPkg/Pci/Dxe/PciHostBridge/PciHostBridge.h
new file mode 100644
index 0000000000..1f33b825fc
--- /dev/null
+++ b/QuarkPlatformPkg/Pci/Dxe/PciHostBridge/PciHostBridge.h
@@ -0,0 +1,395 @@
+/** @file
+The Header file of the Pci Host Bridge Driver.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+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_H_
+#define _PCI_HOST_BRIDGE_H_
+
+
+#include <PiDxe.h>
+#include <IndustryStandard/Acpi.h>
+#include <IndustryStandard/Pci.h>
+#include <PciRootBridge.h>
+#include <Library/UefiDriverEntryPoint.h>
+#include <IndustryStandard/Pci22.h>
+#include <Library/UefiLib.h>
+#include <Guid/HobList.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Protocol/PciHostBridgeResourceAllocation.h>
+
+#define PCI_HOST_BRIDGE_SIGNATURE SIGNATURE_32 ('e', 'h', 's', 't')
+typedef struct {
+ UINTN Signature;
+ EFI_HANDLE HostBridgeHandle;
+ UINTN RootBridgeCount;
+ EFI_LIST_ENTRY Head;
+ BOOLEAN ResourceSubmited;
+ BOOLEAN CanRestarted;
+ EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL ResAlloc;
+} PCI_HOST_BRIDGE_INSTANCE;
+
+#define INSTANCE_FROM_RESOURCE_ALLOCATION_THIS(a) CR (a, PCI_HOST_BRIDGE_INSTANCE, ResAlloc, PCI_HOST_BRIDGE_SIGNATURE)
+
+typedef enum {
+ SocketResourceRatioChanged,
+ SocketResourceRatioNotChanged,
+ SocketResourceAdjustMax
+} SOCKET_RESOURCE_ADJUSTMENT_RESULT;
+
+//
+// Driver Entry Point
+//
+EFI_STATUS
+EFIAPI
+InitializePciHostBridge (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+/*++
+
+Routine Description:
+
+ Entry point of this driver.
+
+Arguments:
+
+ ImageHandle - Image handle of this driver.
+ SystemTable - Pointer to standard EFI system table.
+
+Returns:
+
+ EFI_SUCCESS - Succeed.
+ EFI_DEVICE_ERROR - Fail to install PCI_ROOT_BRIDGE_IO protocol.
+
+--*/
+;
+
+//
+// HostBridge Resource Allocation interface
+//
+EFI_STATUS
+EFIAPI
+NotifyPhase (
+ IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,
+ IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PHASE Phase
+ )
+/*++
+
+Routine Description:
+
+ Enter a certain phase of the PCI enumeration process.
+
+Arguments:
+
+ This - The EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL instance.
+ Phase - The phase during enumeration.
+
+Returns:
+
+ EFI_SUCCESS - Succeed.
+ EFI_INVALID_PARAMETER - Wrong phase parameter passed in.
+ EFI_NOT_READY - Resources have not been submitted yet.
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+GetNextRootBridge (
+ IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,
+ IN OUT EFI_HANDLE *RootBridgeHandle
+ )
+/*++
+
+Routine Description:
+
+ Return the device handle of the next PCI root bridge that is associated with
+ this Host Bridge.
+
+Arguments:
+
+ This - The EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_ PROTOCOL instance.
+ RootBridgeHandle - Returns the device handle of the next PCI Root Bridge.
+ On input, it holds the RootBridgeHandle returned by the most
+ recent call to GetNextRootBridge().The handle for the first
+ PCI Root Bridge is returned if RootBridgeHandle is NULL on input.
+
+Returns:
+
+ EFI_SUCCESS - Succeed.
+ EFI_NOT_FOUND - Next PCI root bridge not found.
+ EFI_INVALID_PARAMETER - Wrong parameter passed in.
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+GetAttributes (
+ IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,
+ IN EFI_HANDLE RootBridgeHandle,
+ OUT UINT64 *Attributes
+ )
+/*++
+
+Routine Description:
+
+ Returns the attributes of a PCI Root Bridge.
+
+Arguments:
+
+ This - The EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_ PROTOCOL instance
+ RootBridgeHandle - The device handle of the PCI Root Bridge
+ that the caller is interested in
+ Attributes - The pointer to attributes of the PCI Root Bridge
+
+Returns:
+
+ EFI_SUCCESS - Succeed.
+ EFI_INVALID_PARAMETER - Attributes parameter passed in is NULL or
+ RootBridgeHandle is not an EFI_HANDLE
+ that was returned on a previous call to
+ GetNextRootBridge().
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+StartBusEnumeration (
+ IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,
+ IN EFI_HANDLE RootBridgeHandle,
+ OUT VOID **Configuration
+ )
+/*++
+
+Routine Description:
+
+ This is the request from the PCI enumerator to set up
+ the specified PCI Root Bridge for bus enumeration process.
+
+Arguments:
+
+ This - The EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_ PROTOCOL instance.
+ RootBridgeHandle - The PCI Root Bridge to be set up.
+ Configuration - Pointer to the pointer to the PCI bus resource descriptor.
+
+Returns:
+
+ EFI_SUCCESS - Succeed.
+ EFI_OUT_OF_RESOURCES - Not enough pool to be allocated.
+ EFI_INVALID_PARAMETER - RootBridgeHandle is not a valid handle.
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+SetBusNumbers (
+ IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,
+ IN EFI_HANDLE RootBridgeHandle,
+ IN VOID *Configuration
+ )
+/*++
+
+Routine Description:
+
+ This function programs the PCI Root Bridge hardware so that
+ it decodes the specified PCI bus range.
+
+Arguments:
+
+ This - The EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_ PROTOCOL instance.
+ RootBridgeHandle - The PCI Root Bridge whose bus range is to be programmed.
+ Configuration - The pointer to the PCI bus resource descriptor.
+
+Returns:
+
+ EFI_SUCCESS - Succeed.
+ EFI_INVALID_PARAMETER - Wrong parameters passed in.
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+SubmitResources (
+ IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,
+ IN EFI_HANDLE RootBridgeHandle,
+ IN VOID *Configuration
+ )
+/*++
+
+Routine Description:
+
+ Submits the I/O and memory resource requirements for the specified PCI Root Bridge.
+
+Arguments:
+
+ This - The EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_ PROTOCOL instance
+ RootBridgeHandle - The PCI Root Bridge whose I/O and memory resource requirements
+ are being submitted
+ Configuration - The pointer to the PCI I/O and PCI memory resource descriptor
+
+Returns:
+
+ EFI_SUCCESS - Succeed.
+ EFI_INVALID_PARAMETER - Wrong parameters passed in.
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+GetProposedResources (
+ IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,
+ IN EFI_HANDLE RootBridgeHandle,
+ OUT VOID **Configuration
+ )
+/*++
+
+Routine Description:
+
+ This function returns the proposed resource settings for the specified
+ PCI Root Bridge.
+
+Arguments:
+
+ This - The EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_ PROTOCOL instance.
+ RootBridgeHandle - The PCI Root Bridge handle.
+ Configuration - The pointer to the pointer to the PCI I/O
+ and memory resource descriptor.
+
+Returns:
+
+ EFI_SUCCESS - Succeed.
+ EFI_OUT_OF_RESOURCES - Not enough pool to be allocated.
+ EFI_INVALID_PARAMETER - RootBridgeHandle is not a valid handle.
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+PreprocessController (
+ IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,
+ IN EFI_HANDLE RootBridgeHandle,
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS PciAddress,
+ IN EFI_PCI_CONTROLLER_RESOURCE_ALLOCATION_PHASE Phase
+ )
+/*++
+
+Routine Description:
+
+ This function is called for all the PCI controllers that the PCI
+ bus driver finds. Can be used to Preprogram the controller.
+
+Arguments:
+
+ This - The EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_ PROTOCOL instance.
+ RootBridgeHandle - The PCI Root Bridge handle.
+ PciAddress - Address of the controller on the PCI bus.
+ Phase - The Phase during resource allocation.
+
+Returns:
+
+ EFI_SUCCESS - Succeed.
+ EFI_INVALID_PARAMETER - RootBridgeHandle is not a valid handle.
+
+--*/
+;
+
+//
+// Host Bridge Silicon specific hooks
+//
+UINT64
+GetAllocAttributes (
+ IN UINTN RootBridgeIndex
+ )
+/*++
+
+Routine Description:
+
+ Returns the Allocation attributes for the BNB Root Bridge.
+
+Arguments:
+
+ RootBridgeIndex - The root bridge number. 0 based.
+
+Returns:
+
+ EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM | EFI_PCI_HOST_BRIDGE_MEM64_DECODE
+
+--*/
+;
+
+EFI_STATUS
+GetHostBridgeMemApertures (
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo,
+ OUT UINT32 *Mem32Base,
+ OUT UINT32 *Mem32Limit,
+ OUT UINT64 *Mem64Base,
+ OUT UINT64 *Mem64Limit
+ )
+/*++
+
+Routine Description:
+
+ Returns memory apertures for the BNB Root Bridge.
+
+Arguments:
+
+ PciRootBridgeIo - Pointer to Efi Pci root bridge Io protocol interface instance.
+ Mem32Base - Pointer to 32 bit memory base. This is the lowest 32 bit memory address
+ that is decoded by the Host Bridge.
+ Mem32Limit - Pointer to 32 bit memory limit.This is the highest 32 bit memory address
+ that is decoded by the Host Bridge. The size of the 32 bit window is
+ (Mem32Limit - Mem32base + 1).
+ Mem64Base - Pointer to 64 bit memory base. This is the lowest 64 bit memory address
+ that is decoded by the Host Bridge.
+ Mem64Limit - Pointer to 64 bit memory limit.This is the highest 64 bit memory address
+ that is decoded by the Host Bridge. The size of the 64 bit window is
+ (Mem64Limit - Mem64base + 1). Set Mem64Limit < Mem64Base if the host bridge
+ does not support 64 bit memory addresses.
+
+Returns:
+
+ EFI_SUCCESS - Success.
+
+--*/
+;
+
+UINT64
+Power2MaxMemory (
+ IN UINT64 MemoryLength
+ )
+/*++
+
+Routine Description:
+
+ Calculate maximum memory length that can be fit to a mtrr.
+
+Arguments:
+
+ MemoryLength - Input memory length.
+
+Returns:
+
+ Returned Maximum length.
+
+--*/
+;
+
+#endif
diff --git a/QuarkPlatformPkg/Pci/Dxe/PciHostBridge/PciHostBridge.inf b/QuarkPlatformPkg/Pci/Dxe/PciHostBridge/PciHostBridge.inf
new file mode 100644
index 0000000000..870d48408f
--- /dev/null
+++ b/QuarkPlatformPkg/Pci/Dxe/PciHostBridge/PciHostBridge.inf
@@ -0,0 +1,67 @@
+## @file
+# Component description file for PciHostBridge module
+#
+# Copyright (c) 2013-2015 Intel Corporation.
+#
+# 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 = PciHostBridge
+ FILE_GUID = D58EBCE1-AF26-488d-BE66-C164417F8C13
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ ENTRY_POINT = InitializePciHostBridge
+
+[Sources]
+ PciHostBridge.h
+ PciRootBridge.h
+ PciHostBridge.c
+ PciRootBridgeIo.c
+ PciHostBridgeSupport.c
+ PciHostResource.h
+
+[Packages]
+ MdePkg/MdePkg.dec
+ QuarkSocPkg/QuarkSocPkg.dec
+ QuarkPlatformPkg/QuarkPlatformPkg.dec
+
+[LibraryClasses]
+ UefiDriverEntryPoint
+ UefiBootServicesTableLib
+ DebugLib
+ UefiLib
+ DxeServicesTableLib
+ UefiRuntimeServicesTableLib
+ DevicePathLib
+ BaseMemoryLib
+ BaseLib
+
+[Protocols]
+ gEfiMetronomeArchProtocolGuid
+ gEfiCpuIo2ProtocolGuid
+ gEfiDevicePathProtocolGuid
+ gEfiPciRootBridgeIoProtocolGuid
+ gEfiPciHostBridgeResourceAllocationProtocolGuid
+
+[Pcd]
+ gEfiQuarkNcSocIdTokenSpaceGuid.PcdPciHostBridgeIoBase
+ gEfiQuarkNcSocIdTokenSpaceGuid.PcdPciHostBridgeIoSize
+ gEfiQuarkNcSocIdTokenSpaceGuid.PcdPciHostBridgeMemory32Base
+ gEfiQuarkNcSocIdTokenSpaceGuid.PcdPciHostBridgeMemory32Size
+ gEfiQuarkNcSocIdTokenSpaceGuid.PcdPciHostBridgeMemory64Base
+ gEfiQuarkNcSocIdTokenSpaceGuid.PcdPciHostBridgeMemory64Size
+ gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress
+ gEfiQuarkNcSocIdTokenSpaceGuid.PcdPciExpressSize
+
+[Depex]
+ gEfiCpuIo2ProtocolGuid AND gEfiMetronomeArchProtocolGuid
diff --git a/QuarkPlatformPkg/Pci/Dxe/PciHostBridge/PciHostBridgeSupport.c b/QuarkPlatformPkg/Pci/Dxe/PciHostBridge/PciHostBridgeSupport.c
new file mode 100644
index 0000000000..24f719ff26
--- /dev/null
+++ b/QuarkPlatformPkg/Pci/Dxe/PciHostBridge/PciHostBridgeSupport.c
@@ -0,0 +1,146 @@
+/** @file
+Do platform initialization for PCI bridge.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+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 "PciHostBridge.h"
+
+EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *mPciRootBridgeIo;
+
+EFI_STATUS
+ChipsetPreprocessController (
+ IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,
+ IN EFI_HANDLE RootBridgeHandle,
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS PciAddress,
+ IN EFI_PCI_CONTROLLER_RESOURCE_ALLOCATION_PHASE Phase
+ )
+/*++
+
+Routine Description:
+ This function is called for all the PCI controllers that the PCI
+ bus driver finds. Can be used to Preprogram the controller.
+
+Arguments:
+ This -- The EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_ PROTOCOL instance
+ RootBridgeHandle -- The PCI Root Bridge handle
+ PciBusAddress -- Address of the controller on the PCI bus
+ Phase -- The Phase during resource allocation
+
+Returns:
+ EFI_SUCCESS
+
+--*/
+
+// GC_TODO: PciAddress - add argument and description to function comment
+//
+// GC_TODO: PciAddress - add argument and description to function comment
+//
+// GC_TODO: PciAddress - add argument and description to function comment
+//
+// GC_TODO: PciAddress - add argument and description to function comment
+//
+{
+
+ EFI_STATUS Status;
+ UINT8 Latency;
+ UINT8 CacheLineSize;
+
+ if (mPciRootBridgeIo == NULL) {
+ //
+ // Get root bridge in the system.
+ //
+ Status = gBS->HandleProtocol (RootBridgeHandle, &gEfiPciRootBridgeIoProtocolGuid, (VOID **) &mPciRootBridgeIo);
+ ASSERT_EFI_ERROR (Status);
+ }
+
+ if (Phase == EfiPciBeforeResourceCollection) {
+ //
+ // Program the latency register, CLS register
+ //
+ PciAddress.Register = PCI_LATENCY_TIMER_OFFSET;
+ mPciRootBridgeIo->Pci.Read (
+ mPciRootBridgeIo,
+ EfiPciWidthUint8,
+ *((UINT64 *) &PciAddress),
+ 1,
+ &Latency
+ );
+
+ //
+ // PCI-x cards come up with a default latency of 0x40. Don't touch them.
+ //
+ if (Latency == 0) {
+ Latency = DEFAULT_PCI_LATENCY;
+ mPciRootBridgeIo->Pci.Write (
+ mPciRootBridgeIo,
+ EfiPciWidthUint8,
+ *((UINT64 *) &PciAddress),
+ 1,
+ &Latency
+ );
+ }
+ //
+ // Program Cache Line Size as 64bytes
+ // 16 of DWORDs = 64bytes (0x10)
+ //
+ PciAddress.Register = PCI_CACHELINE_SIZE_OFFSET;
+ CacheLineSize = 0x10;
+ mPciRootBridgeIo->Pci.Write (
+ mPciRootBridgeIo,
+ EfiPciWidthUint8,
+ *((UINT64 *) &PciAddress),
+ 1,
+ &CacheLineSize
+ );
+
+ }
+
+ return EFI_SUCCESS;
+}
+
+UINT64
+GetAllocAttributes (
+ IN UINTN RootBridgeIndex
+ )
+/*++
+
+Routine Description:
+
+ Returns the Allocation attributes for the BNB Root Bridge.
+
+Arguments:
+
+ RootBridgeIndex - The root bridge number. 0 based.
+
+Returns:
+
+ EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM | EFI_PCI_HOST_BRIDGE_MEM64_DECODE
+
+--*/
+{
+ //
+ // Cannot have more than one Root bridge
+ //
+ //ASSERT (RootBridgeIndex == 0);
+
+ //
+ // PCI Root Bridge does not support separate windows for Non-prefetchable
+ // and Prefetchable memory. A PCI bus driver needs to include requests for
+ // Prefetchable memory in the Non-prefetchable memory pool.
+ // Further TNB does not support 64 bit memory apertures for PCI. BNB
+ // can only have system memory above 4 GB,
+ //
+
+ return EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM | EFI_PCI_HOST_BRIDGE_MEM64_DECODE;
+}
diff --git a/QuarkPlatformPkg/Pci/Dxe/PciHostBridge/PciHostResource.h b/QuarkPlatformPkg/Pci/Dxe/PciHostBridge/PciHostResource.h
new file mode 100644
index 0000000000..3de7c8defc
--- /dev/null
+++ b/QuarkPlatformPkg/Pci/Dxe/PciHostBridge/PciHostResource.h
@@ -0,0 +1,66 @@
+/** @file
+The Header file of the Pci Host Bridge Driver.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+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_RESOURCE_H_
+#define _PCI_HOST_RESOURCE_H_
+
+#include <PiDxe.h>
+
+#define EFI_RESOURCE_NONEXISTENT 0xFFFFFFFFFFFFFFFFULL
+#define EFI_RESOURCE_LESS 0xFFFFFFFFFFFFFFFEULL
+
+typedef struct {
+ UINTN BusBase;
+ UINTN BusLimit;
+ UINTN BusReserve;
+
+ UINT32 Mem32Base;
+ UINT32 Mem32Limit;
+
+ UINT64 Mem64Base;
+ UINT64 Mem64Limit;
+
+ UINTN IoBase;
+ UINTN IoLimit;
+} PCI_ROOT_BRIDGE_RESOURCE_APERTURE;
+
+typedef enum {
+ TypeIo = 0,
+ TypeMem32,
+ TypePMem32,
+ TypeMem64,
+ TypePMem64,
+ TypeBus,
+ TypeMax
+} PCI_RESOURCE_TYPE;
+
+typedef enum {
+ ResNone = 0,
+ ResSubmitted,
+ ResRequested,
+ ResAllocated,
+ ResStatusMax
+} RES_STATUS;
+
+typedef struct {
+ PCI_RESOURCE_TYPE Type;
+ UINT64 Base;
+ UINT64 Length;
+ UINT64 Alignment;
+ RES_STATUS Status;
+} PCI_RES_NODE;
+
+#endif
diff --git a/QuarkPlatformPkg/Pci/Dxe/PciHostBridge/PciRootBridge.h b/QuarkPlatformPkg/Pci/Dxe/PciHostBridge/PciRootBridge.h
new file mode 100644
index 0000000000..4727b53758
--- /dev/null
+++ b/QuarkPlatformPkg/Pci/Dxe/PciHostBridge/PciRootBridge.h
@@ -0,0 +1,699 @@
+/** @file
+The PCI Root Bridge header file.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+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_ROOT_BRIDGE_H_
+#define _PCI_ROOT_BRIDGE_H_
+
+#include <PiDxe.h>
+#include <IndustryStandard/Acpi.h>
+#include <IndustryStandard/Pci.h>
+#include <PciHostResource.h>
+
+//
+// Driver Consumed Protocol Prototypes
+//
+#include <Protocol/Metronome.h>
+#include <Protocol/CpuIo2.h>
+#include <Protocol/DevicePath.h>
+#include <Protocol/Runtime.h>
+#include <Protocol/PciRootBridgeIo.h>
+#include <Library/UefiLib.h>
+#include <Library/DebugLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DxeServicesTableLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/BaseLib.h>
+
+
+//
+// Define the region of memory used for DMA memory
+//
+#define DMA_MEMORY_TOP 0x0000000001FFFFFFULL
+
+//
+// The number of PCI root bridges
+//
+#define ROOT_BRIDGE_COUNT 1
+
+//
+// The default latency for controllers
+//
+#define DEFAULT_PCI_LATENCY 0x20
+
+//
+// Define resource status constant
+//
+typedef struct {
+ EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_OPERATION Operation;
+ UINTN NumberOfBytes;
+ UINTN NumberOfPages;
+ EFI_PHYSICAL_ADDRESS HostAddress;
+ EFI_PHYSICAL_ADDRESS MappedHostAddress;
+} MAP_INFO;
+
+typedef struct {
+ ACPI_HID_DEVICE_PATH AcpiDevicePath;
+ EFI_DEVICE_PATH_PROTOCOL EndDevicePath;
+} EFI_PCI_ROOT_BRIDGE_DEVICE_PATH;
+
+#define PCI_ROOT_BRIDGE_SIGNATURE SIGNATURE_32 ('e', '2', 'p', 'b')
+
+typedef struct {
+ UINT32 Signature;
+ EFI_LIST_ENTRY Link;
+ EFI_HANDLE Handle;
+ UINT64 RootBridgeAllocAttrib;
+ UINT64 Attributes;
+ UINT64 Supports;
+ PCI_RES_NODE ResAllocNode[6];
+ PCI_ROOT_BRIDGE_RESOURCE_APERTURE Aperture;
+ EFI_LOCK PciLock;
+ UINTN PciAddress;
+ UINTN PciData;
+ UINT32 HecBase;
+ UINT32 HecLen;
+ UINTN BusScanCount;
+ BOOLEAN BusNumberAssigned;
+ VOID *ConfigBuffer;
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;
+ EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL Io;
+} PCI_ROOT_BRIDGE_INSTANCE;
+
+//
+// Driver Instance Data Macros
+//
+#define DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS(a) CR (a, PCI_ROOT_BRIDGE_INSTANCE, Io, PCI_ROOT_BRIDGE_SIGNATURE)
+
+#define DRIVER_INSTANCE_FROM_LIST_ENTRY(a) CR (a, PCI_ROOT_BRIDGE_INSTANCE, Link, PCI_ROOT_BRIDGE_SIGNATURE)
+
+EFI_STATUS
+SimpleIioRootBridgeConstructor (
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *Protocol,
+ IN EFI_HANDLE HostBridgeHandle,
+ IN PCI_ROOT_BRIDGE_RESOURCE_APERTURE *ResAppeture,
+ IN UINT64 AllocAttributes
+ )
+/*++
+
+Routine Description:
+
+ Construct the Pci Root Bridge Io protocol.
+
+Arguments:
+
+ Protocol - Protocol to initialize.
+ HostBridgeHandle - Handle to the HostBridge.
+ ResAppeture - Resource apperture of the root bridge.
+ AllocAttributes - Attribute of resouce allocated.
+
+Returns:
+
+ EFI_SUCCESS - Success.
+ Others - Fail.
+
+--*/
+;
+
+//
+// Protocol Member Function Prototypes
+//
+EFI_STATUS
+EFIAPI
+RootBridgeIoPollMem (
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
+ IN UINT64 Address,
+ IN UINT64 Mask,
+ IN UINT64 Value,
+ IN UINT64 Delay,
+ OUT UINT64 *Result
+ )
+/*++
+
+Routine Description:
+
+ Poll an address in memory mapped space until an exit condition is met
+ or a timeout occurs.
+
+Arguments:
+
+ This - Pointer to EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL instance.
+ Width - Width of the memory operation.
+ Address - The base address of the memory operation.
+ Mask - Mask used for polling criteria.
+ Value - Comparison value used for polling exit criteria.
+ Delay - Number of 100ns units to poll.
+ Result - Pointer to the last value read from memory location.
+
+Returns:
+
+ EFI_SUCCESS - Success.
+ EFI_INVALID_PARAMETER - Invalid parameter found.
+ EFI_TIMEOUT - Delay expired before a match occurred.
+ EFI_OUT_OF_RESOURCES - Fail due to lack of resources.
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+RootBridgeIoPollIo (
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
+ IN UINT64 Address,
+ IN UINT64 Mask,
+ IN UINT64 Value,
+ IN UINT64 Delay,
+ OUT UINT64 *Result
+ )
+/*++
+
+Routine Description:
+
+ Poll an address in I/O space until an exit condition is met
+ or a timeout occurs.
+
+Arguments:
+
+ This - Pointer to EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL instance.
+ Width - Width of I/O operation.
+ Address - The base address of the I/O operation.
+ Mask - Mask used for polling criteria.
+ Value - Comparison value used for polling exit criteria.
+ Delay - Number of 100ns units to poll.
+ Result - Pointer to the last value read from memory location.
+
+Returns:
+
+ EFI_SUCCESS - Success.
+ EFI_INVALID_PARAMETER - Invalid parameter found.
+ EFI_TIMEOUT - Delay expired before a match occurred.
+ EFI_OUT_OF_RESOURCES - Fail due to lack of resources.
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+RootBridgeIoMemRead (
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
+ IN UINT64 Address,
+ IN UINTN Count,
+ IN OUT VOID *Buffer
+ )
+/*++
+
+Routine Description:
+
+ Allow read from memory mapped I/O space.
+
+Arguments:
+
+ This - Pointer to EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL instance.
+ Width - The width of memory operation.
+ Address - Base address of the memory operation.
+ Count - Number of memory opeartion to perform.
+ Buffer - The destination buffer to store data.
+
+Returns:
+
+ EFI_SUCCESS - Success.
+ EFI_INVALID_PARAMETER - Invalid parameter found.
+ EFI_OUT_OF_RESOURCES - Fail due to lack of resources.
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+RootBridgeIoMemWrite (
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
+ IN UINT64 Address,
+ IN UINTN Count,
+ IN OUT VOID *Buffer
+ )
+/*++
+
+Routine Description:
+
+ Allow write to memory mapped I/O space.
+
+Arguments:
+
+ This - Pointer to EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL instance.
+ Width - The width of memory operation.
+ Address - Base address of the memory operation.
+ Count - Number of memory opeartion to perform.
+ Buffer - The source buffer to write data from.
+
+Returns:
+
+ EFI_SUCCESS - Success.
+ EFI_INVALID_PARAMETER - Invalid parameter found.
+ EFI_OUT_OF_RESOURCES - Fail due to lack of resources.
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+RootBridgeIoIoRead (
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
+ IN UINT64 UserAddress,
+ IN UINTN Count,
+ IN OUT VOID *UserBuffer
+ )
+/*++
+
+Routine Description:
+
+ Enable a PCI driver to read PCI controller registers in the
+ PCI root bridge I/O space.
+
+Arguments:
+
+ This - A pointer to EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
+ Width - Signifies the width of the memory operation.
+ UserAddress - The base address of the I/O operation.
+ Count - The number of I/O operations to perform.
+ UserBuffer - The destination buffer to store the results.
+
+Returns:
+
+ EFI_SUCCESS - The data was read from the PCI root bridge.
+ EFI_INVALID_PARAMETER - Invalid parameters found.
+ EFI_OUT_OF_RESOURCES - The request could not be completed due to a lack of
+ resources.
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+RootBridgeIoIoWrite (
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
+ IN UINT64 UserAddress,
+ IN UINTN Count,
+ IN OUT VOID *UserBuffer
+ )
+/*++
+
+Routine Description:
+
+ Enable a PCI driver to write to PCI controller registers in the
+ PCI root bridge I/O space.
+
+Arguments:
+
+ This - A pointer to EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
+ Width - Signifies the width of the memory operation.
+ UserAddress - The base address of the I/O operation.
+ Count - The number of I/O operations to perform.
+ UserBuffer - The source buffer to write data from.
+
+Returns:
+
+ EFI_SUCCESS - The data was written to the PCI root bridge.
+ EFI_INVALID_PARAMETER - Invalid parameters found.
+ EFI_OUT_OF_RESOURCES - The request could not be completed due to a lack of
+ resources.
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+RootBridgeIoCopyMem (
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
+ IN UINT64 DestAddress,
+ IN UINT64 SrcAddress,
+ IN UINTN Count
+ )
+/*++
+
+Routine Description:
+
+ Copy one region of PCI root bridge memory space to be copied to
+ another region of PCI root bridge memory space.
+
+Arguments:
+
+ This - A pointer to EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL instance.
+ Width - Signifies the width of the memory operation.
+ DestAddress - Destination address of the memory operation.
+ SrcAddress - Source address of the memory operation.
+ Count - Number of memory operations to perform.
+
+Returns:
+
+ EFI_SUCCESS - The data was copied successfully.
+ EFI_INVALID_PARAMETER - Invalid parameters found.
+ EFI_OUT_OF_RESOURCES - The request could not be completed due to a lack of
+ resources.
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+RootBridgeIoPciRead (
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
+ IN UINT64 Address,
+ IN UINTN Count,
+ IN OUT VOID *Buffer
+ )
+/*++
+
+Routine Description:
+
+ Allows read from PCI configuration space.
+
+Arguments:
+
+ This - A pointer to EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
+ Width - Signifies the width of the memory operation.
+ Address - The address within the PCI configuration space
+ for the PCI controller.
+ Count - The number of PCI configuration operations
+ to perform.
+ Buffer - The destination buffer to store the results.
+
+Returns:
+
+ EFI_SUCCESS - The data was read from the PCI root bridge.
+ EFI_INVALID_PARAMETER - Invalid parameters found.
+ EFI_OUT_OF_RESOURCES - The request could not be completed due to a lack of
+ resources.
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+RootBridgeIoPciWrite (
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
+ IN UINT64 Address,
+ IN UINTN Count,
+ IN OUT VOID *Buffer
+ )
+/*++
+
+Routine Description:
+
+ Allows write to PCI configuration space.
+
+Arguments:
+
+ This - A pointer to EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
+ Width - Signifies the width of the memory operation.
+ Address - The address within the PCI configuration space
+ for the PCI controller.
+ Count - The number of PCI configuration operations
+ to perform.
+ Buffer - The source buffer to get the results.
+
+Returns:
+
+ EFI_SUCCESS - The data was written to the PCI root bridge.
+ EFI_INVALID_PARAMETER - Invalid parameters found.
+ EFI_OUT_OF_RESOURCES - The request could not be completed due to a lack of
+ resources.
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+RootBridgeIoMap (
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_OPERATION Operation,
+ IN VOID *HostAddress,
+ IN OUT UINTN *NumberOfBytes,
+ OUT EFI_PHYSICAL_ADDRESS *DeviceAddress,
+ OUT VOID **Mapping
+ )
+/*++
+
+Routine Description:
+
+ Provides the PCI controller-specific address needed to access
+ system memory for DMA.
+
+Arguments:
+
+ This - A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
+ Operation - Indicate if the bus master is going to read or write
+ to system memory.
+ HostAddress - The system memory address to map on the PCI controller.
+ NumberOfBytes - On input the number of bytes to map.
+ On output the number of bytes that were mapped.
+ DeviceAddress - The resulting map address for the bus master PCI
+ controller to use to access the system memory's HostAddress.
+ Mapping - The value to pass to Unmap() when the bus master DMA
+ operation is complete.
+
+Returns:
+
+ EFI_SUCCESS - Success.
+ EFI_INVALID_PARAMETER - Invalid parameters found.
+ EFI_UNSUPPORTED - The HostAddress cannot be mapped as a common
+ buffer.
+ EFI_DEVICE_ERROR - The System hardware could not map the requested
+ address.
+ EFI_OUT_OF_RESOURCES - The request could not be completed due to
+ lack of resources.
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+RootBridgeIoUnmap (
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
+ IN VOID *Mapping
+ )
+/*++
+
+Routine Description:
+
+ Completes the Map() operation and releases any corresponding resources.
+
+Arguments:
+
+ This - Pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL instance.
+ Mapping - The value returned from Map() operation.
+
+Returns:
+
+ EFI_SUCCESS - The range was unmapped successfully.
+ EFI_INVALID_PARAMETER - Mapping is not a value that was returned
+ by Map operation.
+ EFI_DEVICE_ERROR - The data was not committed to the target
+ system memory.
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+RootBridgeIoAllocateBuffer (
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
+ IN EFI_ALLOCATE_TYPE Type,
+ IN EFI_MEMORY_TYPE MemoryType,
+ IN UINTN Pages,
+ OUT VOID **HostAddress,
+ IN UINT64 Attributes
+ )
+/*++
+
+Routine Description:
+
+ Allocates pages that are suitable for a common buffer mapping.
+
+Arguments:
+
+ This - Pointer to EFI_ROOT_BRIDGE_IO_PROTOCOL instance.
+ Type - Not used and can be ignored.
+ MemoryType - Type of memory to allocate.
+ Pages - Number of pages to allocate.
+ HostAddress - Pointer to store the base system memory address
+ of the allocated range.
+ Attributes - Requested bit mask of attributes of the allocated
+ range.
+
+Returns:
+
+ EFI_SUCCESS - The requested memory range were allocated.
+ EFI_INVALID_PARAMETER - Invalid parameter found.
+ EFI_UNSUPPORTED - Attributes is unsupported.
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+RootBridgeIoFreeBuffer (
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
+ IN UINTN Pages,
+ OUT VOID *HostAddress
+ )
+/*++
+
+Routine Description:
+
+ Free memory allocated in AllocateBuffer.
+
+Arguments:
+
+ This - Pointer to EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
+ instance.
+ Pages - Number of pages to free.
+ HostAddress - The base system memory address of the
+ allocated range.
+
+Returns:
+
+ EFI_SUCCESS - Requested memory pages were freed.
+ EFI_INVALID_PARAMETER - Invalid parameter found.
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+RootBridgeIoFlush (
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This
+ )
+/*++
+
+Routine Description:
+
+ Flushes all PCI posted write transactions from a PCI host
+ bridge to system memory.
+
+Arguments:
+
+ This - Pointer to EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL instance.
+
+Returns:
+
+ EFI_SUCCESS - PCI posted write transactions were flushed
+ from PCI host bridge to system memory.
+ EFI_DEVICE_ERROR - Fail due to hardware error.
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+RootBridgeIoGetAttributes (
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
+ OUT UINT64 *Supported,
+ OUT UINT64 *Attributes
+ )
+/*++
+
+Routine Description:
+
+ Get the attributes that a PCI root bridge supports and
+ the attributes the PCI root bridge is currently using.
+
+Arguments:
+
+ This - Pointer to EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
+ instance.
+ Supports - A pointer to the mask of attributes that
+ this PCI root bridge supports.
+ Attributes - A pointer to the mask of attributes that
+ this PCI root bridge is currently using.
+Returns:
+
+ EFI_SUCCESS - Success.
+ EFI_INVALID_PARAMETER - Invalid parameter found.
+
+--*/
+
+// GC_TODO: Supported - add argument and description to function comment
+//
+// GC_TODO: Supported - add argument and description to function comment
+//
+// GC_TODO: Supported - add argument and description to function comment
+//
+;
+
+EFI_STATUS
+EFIAPI
+RootBridgeIoSetAttributes (
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
+ IN UINT64 Attributes,
+ IN OUT UINT64 *ResourceBase,
+ IN OUT UINT64 *ResourceLength
+ )
+/*++
+
+Routine Description:
+
+ Sets the attributes for a resource range on a PCI root bridge.
+
+Arguments:
+
+ This - Pointer to EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL instance.
+ Attributes - The mask of attributes to set.
+ ResourceBase - Pointer to the base address of the resource range
+ to be modified by the attributes specified by Attributes.
+ ResourceLength - Pointer to the length of the resource range to be modified.
+
+Returns:
+ EFI_SUCCESS - Success.
+ EFI_INVALID_PARAMETER - Invalid parameter found.
+ EFI_OUT_OF_RESOURCES - Not enough resources to set the attributes upon.
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+RootBridgeIoConfiguration (
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
+ OUT VOID **Resources
+ )
+/*++
+
+Routine Description:
+
+ Retrieves the current resource settings of this PCI root bridge
+ in the form of a set of ACPI 2.0 resource descriptor.
+
+Arguments:
+
+ This - Pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL instance.
+ Resources - Pointer to the ACPI 2.0 resource descriptor that
+ describe the current configuration of this PCI root
+ bridge.
+
+Returns:
+
+ EFI_SUCCESS - Success.
+ EFI_UNSUPPORTED - Current configuration of the PCI root bridge
+ could not be retrieved.
+
+--*/
+;
+
+#endif
diff --git a/QuarkPlatformPkg/Pci/Dxe/PciHostBridge/PciRootBridgeIo.c b/QuarkPlatformPkg/Pci/Dxe/PciHostBridge/PciRootBridgeIo.c
new file mode 100644
index 0000000000..72847c6083
--- /dev/null
+++ b/QuarkPlatformPkg/Pci/Dxe/PciHostBridge/PciRootBridgeIo.c
@@ -0,0 +1,1616 @@
+/** @file
+IIO PCI Root Bridge Io Protocol code. Generic enough to work for all IIOs.
+Does not support configuration accesses to the extended PCI Express registers yet.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+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 "PciRootBridge.h"
+
+//
+// Define PCI express offse
+//
+#define PCIE_OFF(Bus, Device, Function, Register) \
+ ((UINT64) ((UINTN) (Bus << 20) + (UINTN) (Device << 15) + (UINTN) (Function << 12) + (UINTN) (Register)))
+
+//
+// Pci Root Bridge Io Module Variables
+//
+EFI_METRONOME_ARCH_PROTOCOL *mMetronome;
+EFI_CPU_IO2_PROTOCOL *mCpuIo;
+
+EFI_STATUS
+SimpleIioRootBridgeConstructor (
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *Protocol,
+ IN EFI_HANDLE HostBridgeHandle,
+ IN PCI_ROOT_BRIDGE_RESOURCE_APERTURE *ResAperture,
+ UINT64 AllocAttributes
+ )
+/*++
+
+Routine Description:
+
+ Construct the Pci Root Bridge Io protocol.
+
+Arguments:
+
+ Protocol - Protocol to initialize.
+ HostBridgeHandle - Handle to the HostBridge.
+ ResAperture - Resource apperture of the root bridge.
+ AllocAttributes - Attribute of resouce allocated.
+
+Returns:
+
+ EFI_SUCCESS - Success.
+ Others - Fail.
+
+--*/
+{
+ EFI_STATUS Status;
+ PCI_ROOT_BRIDGE_INSTANCE *PrivateData;
+ PCI_RESOURCE_TYPE Index;
+ UINT32 HecBase;
+ UINT32 HecSize;
+
+ PrivateData = DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS (Protocol);
+
+ //
+ // Initialize the apertures with default values
+ //
+ CopyMem (
+ &PrivateData->Aperture,
+ ResAperture,
+ sizeof (PCI_ROOT_BRIDGE_RESOURCE_APERTURE)
+ );
+
+ for (Index = TypeIo; Index < TypeMax; Index++) {
+ PrivateData->ResAllocNode[Index].Type = Index;
+ PrivateData->ResAllocNode[Index].Base = 0;
+ PrivateData->ResAllocNode[Index].Length = 0;
+ PrivateData->ResAllocNode[Index].Status = ResNone;
+ }
+
+ EfiInitializeLock (&PrivateData->PciLock, TPL_HIGH_LEVEL);
+ PrivateData->PciAddress = 0xCF8;
+ PrivateData->PciData = 0xCFC;
+
+ PrivateData->RootBridgeAllocAttrib = AllocAttributes;
+ PrivateData->Attributes = 0;
+ PrivateData->Supports = EFI_PCI_ATTRIBUTE_IDE_PRIMARY_IO |
+ EFI_PCI_ATTRIBUTE_IDE_SECONDARY_IO |
+ EFI_PCI_ATTRIBUTE_ISA_IO_16 |
+ EFI_PCI_ATTRIBUTE_VGA_PALETTE_IO_16 |
+ EFI_PCI_ATTRIBUTE_VGA_MEMORY |
+ EFI_PCI_ATTRIBUTE_VGA_IO_16;
+
+ //
+ // Don't support BASE above 4GB currently
+ // Position to bit 39:28
+ //
+ HecBase = (UINT32) PcdGet64 (PcdPciExpressBaseAddress);
+ HecSize = (UINT32) PcdGet64 (PcdPciExpressSize);
+
+ ASSERT ((HecBase & (HecSize - 1)) == 0);
+ ASSERT (HecBase != 0);
+
+ PrivateData->HecBase = HecBase;
+ PrivateData->HecLen = HecSize;
+
+ PrivateData->BusNumberAssigned = FALSE;
+ PrivateData->BusScanCount = 0;
+
+ Protocol->ParentHandle = HostBridgeHandle;
+
+ Protocol->PollMem = RootBridgeIoPollMem;
+ Protocol->PollIo = RootBridgeIoPollIo;
+
+ Protocol->Mem.Read = RootBridgeIoMemRead;
+ Protocol->Mem.Write = RootBridgeIoMemWrite;
+
+ Protocol->Io.Read = RootBridgeIoIoRead;
+ Protocol->Io.Write = RootBridgeIoIoWrite;
+
+ Protocol->CopyMem = RootBridgeIoCopyMem;
+
+ Protocol->Pci.Read = RootBridgeIoPciRead;
+ Protocol->Pci.Write = RootBridgeIoPciWrite;
+
+ Protocol->Map = RootBridgeIoMap;
+ Protocol->Unmap = RootBridgeIoUnmap;
+
+ Protocol->AllocateBuffer = RootBridgeIoAllocateBuffer;
+ Protocol->FreeBuffer = RootBridgeIoFreeBuffer;
+
+ Protocol->Flush = RootBridgeIoFlush;
+
+ Protocol->GetAttributes = RootBridgeIoGetAttributes;
+ Protocol->SetAttributes = RootBridgeIoSetAttributes;
+
+ Protocol->Configuration = RootBridgeIoConfiguration;
+
+ Protocol->SegmentNumber = 0;
+
+ Status = gBS->LocateProtocol (&gEfiMetronomeArchProtocolGuid, NULL, (VOID **) &mMetronome);
+ ASSERT_EFI_ERROR (Status);
+
+ Status = gBS->LocateProtocol (
+ &gEfiCpuIo2ProtocolGuid,
+ NULL,
+ (VOID **) &mCpuIo
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+RootBridgeIoPollMem (
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
+ IN UINT64 Address,
+ IN UINT64 Mask,
+ IN UINT64 Value,
+ IN UINT64 Delay,
+ OUT UINT64 *Result
+ )
+/*++
+
+Routine Description:
+
+ Poll an address in memory mapped space until an exit condition is met
+ or a timeout occurs.
+
+Arguments:
+
+ This - Pointer to EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL instance.
+ Width - Width of the memory operation.
+ Address - The base address of the memory operation.
+ Mask - Mask used for polling criteria.
+ Value - Comparison value used for polling exit criteria.
+ Delay - Number of 100ns units to poll.
+ Result - Pointer to the last value read from memory location.
+
+Returns:
+
+ EFI_SUCCESS - Success.
+ EFI_INVALID_PARAMETER - Invalid parameter found.
+ EFI_TIMEOUT - Delay expired before a match occurred.
+ EFI_OUT_OF_RESOURCES - Fail due to lack of resources.
+
+--*/
+{
+ EFI_STATUS Status;
+ UINT64 NumberOfTicks;
+ UINT32 Remainder;
+
+ if (Result == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (Width < 0 || Width > EfiPciWidthUint64) {
+ return EFI_INVALID_PARAMETER;
+ }
+ //
+ // No matter what, always do a single poll.
+ //
+ Status = This->Mem.Read (
+ This,
+ Width,
+ Address,
+ 1,
+ Result
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ if ((*Result & Mask) == Value) {
+ return EFI_SUCCESS;
+ }
+
+ if (Delay != 0) {
+ //
+ // Determine the proper # of metronome ticks to wait for polling the
+ // location. The nuber of ticks is Roundup (Delay / mMetronome->TickPeriod)+1
+ // The "+1" to account for the possibility of the first tick being short
+ // because we started in the middle of a tick.
+ //
+ // BugBug: overriding mMetronome->TickPeriod with UINT32 until Metronome
+ // protocol definition is updated.
+ //
+ NumberOfTicks = DivU64x32Remainder (
+ Delay,
+ (UINT32) mMetronome->TickPeriod,
+ &Remainder
+ );
+ if (Remainder != 0) {
+ NumberOfTicks += 1;
+ }
+
+ NumberOfTicks += 1;
+
+ while (NumberOfTicks) {
+
+ mMetronome->WaitForTick (mMetronome, 1);
+
+ Status = This->Mem.Read (
+ This,
+ Width,
+ Address,
+ 1,
+ Result
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ if ((*Result & Mask) == Value) {
+ return EFI_SUCCESS;
+ }
+
+ NumberOfTicks -= 1;
+ }
+ }
+
+ return EFI_TIMEOUT;
+}
+
+EFI_STATUS
+EFIAPI
+RootBridgeIoPollIo (
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
+ IN UINT64 Address,
+ IN UINT64 Mask,
+ IN UINT64 Value,
+ IN UINT64 Delay,
+ OUT UINT64 *Result
+ )
+/*++
+
+Routine Description:
+
+ Poll an address in I/O space until an exit condition is met
+ or a timeout occurs.
+
+Arguments:
+
+ This - Pointer to EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL instance.
+ Width - Width of I/O operation.
+ Address - The base address of the I/O operation.
+ Mask - Mask used for polling criteria.
+ Value - Comparison value used for polling exit criteria.
+ Delay - Number of 100ns units to poll.
+ Result - Pointer to the last value read from memory location.
+
+Returns:
+
+ EFI_SUCCESS - Success.
+ EFI_INVALID_PARAMETER - Invalid parameter found.
+ EFI_TIMEOUT - Delay expired before a match occurred.
+ EFI_OUT_OF_RESOURCES - Fail due to lack of resources.
+
+--*/
+{
+ EFI_STATUS Status;
+ UINT64 NumberOfTicks;
+ UINT32 Remainder;
+
+ //
+ // No matter what, always do a single poll.
+ //
+ if (Result == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (Width < 0 || Width > EfiPciWidthUint64) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Status = This->Io.Read (
+ This,
+ Width,
+ Address,
+ 1,
+ Result
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ if ((*Result & Mask) == Value) {
+ return EFI_SUCCESS;
+ }
+
+ if (Delay != 0) {
+ //
+ // Determine the proper # of metronome ticks to wait for polling the
+ // location. The number of ticks is Roundup (Delay / mMetronome->TickPeriod)+1
+ // The "+1" to account for the possibility of the first tick being short
+ // because we started in the middle of a tick.
+ //
+ NumberOfTicks = DivU64x32Remainder (
+ Delay,
+ (UINT32) mMetronome->TickPeriod,
+ &Remainder
+ );
+ if (Remainder != 0) {
+ NumberOfTicks += 1;
+ }
+
+ NumberOfTicks += 1;
+
+ while (NumberOfTicks) {
+
+ mMetronome->WaitForTick (mMetronome, 1);
+
+ Status = This->Io.Read (
+ This,
+ Width,
+ Address,
+ 1,
+ Result
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ if ((*Result & Mask) == Value) {
+ return EFI_SUCCESS;
+ }
+
+ NumberOfTicks -= 1;
+ }
+ }
+
+ return EFI_TIMEOUT;
+}
+
+EFI_STATUS
+EFIAPI
+RootBridgeIoMemRead (
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
+ IN UINT64 Address,
+ IN UINTN Count,
+ IN OUT VOID *Buffer
+ )
+/*++
+
+Routine Description:
+
+ Allow read from memory mapped I/O space.
+
+Arguments:
+
+ This - Pointer to EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL instance.
+ Width - The width of memory operation.
+ Address - Base address of the memory operation.
+ Count - Number of memory opeartion to perform.
+ Buffer - The destination buffer to store data.
+
+Returns:
+
+ EFI_SUCCESS - Success.
+ EFI_INVALID_PARAMETER - Invalid parameter found.
+ EFI_OUT_OF_RESOURCES - Fail due to lack of resources.
+
+--*/
+{
+ PCI_ROOT_BRIDGE_INSTANCE *PrivateData;
+ if (Buffer == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (Width < 0 ||
+ Width == EfiPciWidthUint64 ||
+ Width == EfiPciWidthFifoUint64 ||
+ Width == EfiPciWidthFillUint64 ||
+ Width >= EfiPciWidthMaximum
+ ) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ PrivateData = DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS (This);
+ //
+ // Check memory access limit
+ //
+ if (PrivateData->Aperture.Mem64Limit > PrivateData->Aperture.Mem64Base) {
+ if (Address > PrivateData->Aperture.Mem64Limit) {
+ return EFI_INVALID_PARAMETER;
+ }
+ } else {
+ if (Address > PrivateData->Aperture.Mem32Limit) {
+ return EFI_INVALID_PARAMETER;
+ }
+ }
+
+ return mCpuIo->Mem.Read (
+ mCpuIo,
+ (EFI_CPU_IO_PROTOCOL_WIDTH) Width,
+ Address,
+ Count,
+ Buffer
+ );
+}
+
+EFI_STATUS
+EFIAPI
+RootBridgeIoMemWrite (
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
+ IN UINT64 Address,
+ IN UINTN Count,
+ IN OUT VOID *Buffer
+ )
+/*++
+
+Routine Description:
+
+ Allow write to memory mapped I/O space.
+
+Arguments:
+
+ This - Pointer to EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL instance.
+ Width - The width of memory operation.
+ Address - Base address of the memory operation.
+ Count - Number of memory opeartion to perform.
+ Buffer - The source buffer to write data from.
+
+Returns:
+
+ EFI_SUCCESS - Success.
+ EFI_INVALID_PARAMETER - Invalid parameter found.
+ EFI_OUT_OF_RESOURCES - Fail due to lack of resources.
+
+--*/
+{
+ PCI_ROOT_BRIDGE_INSTANCE *PrivateData;
+
+ if (Buffer == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (Width < 0 ||
+ Width == EfiPciWidthUint64 ||
+ Width == EfiPciWidthFifoUint64 ||
+ Width == EfiPciWidthFillUint64 ||
+ Width >= EfiPciWidthMaximum
+ ) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ PrivateData = DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS (This);
+
+ //
+ // Check memory access limit
+ //
+ if (PrivateData->Aperture.Mem64Limit > PrivateData->Aperture.Mem64Base) {
+ if (Address > PrivateData->Aperture.Mem64Limit) {
+ return EFI_INVALID_PARAMETER;
+ }
+ } else {
+ if (Address > PrivateData->Aperture.Mem32Limit) {
+ return EFI_INVALID_PARAMETER;
+ }
+ }
+
+ return mCpuIo->Mem.Write (
+ mCpuIo,
+ (EFI_CPU_IO_PROTOCOL_WIDTH) Width,
+ Address,
+ Count,
+ Buffer
+ );
+}
+
+EFI_STATUS
+EFIAPI
+RootBridgeIoIoRead (
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
+ IN UINT64 Address,
+ IN UINTN Count,
+ IN OUT VOID *Buffer
+ )
+/*++
+
+Routine Description:
+
+ Enable a PCI driver to read PCI controller registers in the
+ PCI root bridge I/O space.
+
+Arguments:
+
+ This - A pointer to EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
+ Width - Signifies the width of the memory operation.
+ Address - The base address of the I/O operation.
+ Count - The number of I/O operations to perform.
+ Buffer - The destination buffer to store the results.
+
+Returns:
+
+ EFI_SUCCESS - The data was read from the PCI root bridge.
+ EFI_INVALID_PARAMETER - Invalid parameters found.
+ EFI_OUT_OF_RESOURCES - The request could not be completed due to a lack of
+ resources.
+--*/
+{
+
+ UINTN AlignMask;
+ PCI_ROOT_BRIDGE_INSTANCE *PrivateData;
+
+ if (Buffer == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (Width < 0 ||
+ Width == EfiPciWidthUint64 ||
+ Width == EfiPciWidthFifoUint64 ||
+ Width == EfiPciWidthFillUint64 ||
+ Width >= EfiPciWidthMaximum
+ ) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ PrivateData = DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS (This);
+
+ //
+ // AlignMask = (1 << Width) - 1;
+ //
+ AlignMask = (1 << (Width & 0x03)) - 1;
+
+ //
+ // check Io access limit
+ //
+ if (Address > PrivateData->Aperture.IoLimit) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (Address & AlignMask) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ return mCpuIo->Io.Read (
+ mCpuIo,
+ (EFI_CPU_IO_PROTOCOL_WIDTH) Width,
+ Address,
+ Count,
+ Buffer
+ );
+
+}
+
+EFI_STATUS
+EFIAPI
+RootBridgeIoIoWrite (
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
+ IN UINT64 Address,
+ IN UINTN Count,
+ IN OUT VOID *Buffer
+ )
+/*++
+
+Routine Description:
+
+ Enable a PCI driver to write to PCI controller registers in the
+ PCI root bridge I/O space.
+
+Arguments:
+
+ This - A pointer to EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
+ Width - Signifies the width of the memory operation.
+ Address - The base address of the I/O operation.
+ Count - The number of I/O operations to perform.
+ Buffer - The source buffer to write data from.
+
+Returns:
+
+ EFI_SUCCESS - The data was written to the PCI root bridge.
+ EFI_INVALID_PARAMETER - Invalid parameters found.
+ EFI_OUT_OF_RESOURCES - The request could not be completed due to a lack of
+ resources.
+--*/
+{
+ UINTN AlignMask;
+ PCI_ROOT_BRIDGE_INSTANCE *PrivateData;
+
+ if (Buffer == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (Width < 0 ||
+ Width == EfiPciWidthUint64 ||
+ Width == EfiPciWidthFifoUint64 ||
+ Width == EfiPciWidthFillUint64 ||
+ Width >= EfiPciWidthMaximum
+ ) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ PrivateData = DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS (This);
+
+ //
+ // AlignMask = (1 << Width) - 1;
+ //
+ AlignMask = (1 << (Width & 0x03)) - 1;
+
+ //
+ // Check Io access limit
+ //
+ if (Address > PrivateData->Aperture.IoLimit) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (Address & AlignMask) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ return mCpuIo->Io.Write (
+ mCpuIo,
+ (EFI_CPU_IO_PROTOCOL_WIDTH) Width,
+ Address,
+ Count,
+ Buffer
+ );
+
+}
+
+EFI_STATUS
+EFIAPI
+RootBridgeIoCopyMem (
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
+ IN UINT64 DestAddress,
+ IN UINT64 SrcAddress,
+ IN UINTN Count
+ )
+/*++
+
+Routine Description:
+
+ Copy one region of PCI root bridge memory space to be copied to
+ another region of PCI root bridge memory space.
+
+Arguments:
+
+ This - A pointer to EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL instance.
+ Width - Signifies the width of the memory operation.
+ DestAddress - Destination address of the memory operation.
+ SrcAddress - Source address of the memory operation.
+ Count - Number of memory operations to perform.
+
+Returns:
+
+ EFI_SUCCESS - The data was copied successfully.
+ EFI_INVALID_PARAMETER - Invalid parameters found.
+ EFI_OUT_OF_RESOURCES - The request could not be completed due to a lack of
+ resources.
+--*/
+{
+ EFI_STATUS Status;
+ BOOLEAN Direction;
+ UINTN Stride;
+ UINTN Index;
+ UINT64 Result;
+
+ if (Width < 0 || Width > EfiPciWidthUint64) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (DestAddress == SrcAddress) {
+ return EFI_SUCCESS;
+ }
+
+ Stride = (UINTN)1 << Width;
+
+ Direction = TRUE;
+ if ((DestAddress > SrcAddress) && (DestAddress < (SrcAddress + Count * Stride))) {
+ Direction = FALSE;
+ SrcAddress = SrcAddress + (Count - 1) * Stride;
+ DestAddress = DestAddress + (Count - 1) * Stride;
+ }
+
+ for (Index = 0; Index < Count; Index++) {
+ Status = RootBridgeIoMemRead (
+ This,
+ Width,
+ SrcAddress,
+ 1,
+ &Result
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = RootBridgeIoMemWrite (
+ This,
+ Width,
+ DestAddress,
+ 1,
+ &Result
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ if (Direction) {
+ SrcAddress += Stride;
+ DestAddress += Stride;
+ } else {
+ SrcAddress -= Stride;
+ DestAddress -= Stride;
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+RootBridgeIoPciRW (
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
+ IN BOOLEAN Write,
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
+ IN UINT64 UserAddress,
+ IN UINTN Count,
+ IN OUT VOID *UserBuffer
+ )
+/*++
+
+Routine Description:
+
+Arguments:
+
+Returns:
+
+--*/
+{
+ PCI_CONFIG_ACCESS_CF8 Pci;
+ PCI_CONFIG_ACCESS_CF8 PciAligned;
+ UINT32 Stride;
+ UINTN PciData;
+ UINTN PciDataStride;
+ PCI_ROOT_BRIDGE_INSTANCE *PrivateData;
+
+ if (Width >= EfiPciWidthMaximum) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ PrivateData = DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS(This);
+
+ ASSERT (((EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS*)&UserAddress)->ExtendedRegister == 0x00);
+
+ Stride = 1 << Width;
+
+ Pci.Bits.Reg = ((EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS*) &UserAddress)->Register;
+ Pci.Bits.Func = ((EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS*) &UserAddress)->Function;
+ Pci.Bits.Dev = ((EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS*) &UserAddress)->Device;
+ Pci.Bits.Bus = ((EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS*) &UserAddress)->Bus;
+ Pci.Bits.Reserved = 0;
+ Pci.Bits.Enable = 1;
+
+ //
+ // PCI Configure access are all 32-bit aligned, but by accessing the
+ // CONFIG_DATA_REGISTER (0xcfc) with different widths more cycle types
+ // are possible on PCI.
+ //
+ // To read a byte of PCI configuration space you load 0xcf8 and
+ // read 0xcfc, 0xcfd, 0xcfe, 0xcff
+ //
+ PciDataStride = ((EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS*) &UserAddress)->Register & 0x03;
+
+ while (Count) {
+ PciAligned = Pci;
+ PciAligned.Bits.Reg &= 0xfc;
+ PciData = PrivateData->PciData + PciDataStride;
+ EfiAcquireLock(&PrivateData->PciLock);
+ This->Io.Write (This, EfiPciWidthUint32, \
+ PrivateData->PciAddress, 1, &PciAligned);
+ if (Write) {
+ This->Io.Write (This, Width, PciData, 1, UserBuffer);
+ } else {
+ This->Io.Read (This, Width, PciData, 1, UserBuffer);
+ }
+ EfiReleaseLock(&PrivateData->PciLock);
+ UserBuffer = ((UINT8 *)UserBuffer) + Stride;
+ PciDataStride = (PciDataStride + Stride) % 4;
+ Count -= 1;
+
+ //
+ // Only increment the PCI address if Width is not a FIFO.
+ //
+ if (Width >= EfiPciWidthUint8 && Width <= EfiPciWidthUint64) {
+ Pci.Bits.Reg += Stride;
+ }
+ }
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+RootBridgeIoPciRead (
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
+ IN UINT64 Address,
+ IN UINTN Count,
+ IN OUT VOID *Buffer
+ )
+/*++
+
+Routine Description:
+
+ Allows read from PCI configuration space.
+
+Arguments:
+
+ This - A pointer to EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
+ Width - Signifies the width of the memory operation.
+ Address - The address within the PCI configuration space
+ for the PCI controller.
+ Count - The number of PCI configuration operations
+ to perform.
+ Buffer - The destination buffer to store the results.
+
+Returns:
+
+ EFI_SUCCESS - The data was read from the PCI root bridge.
+ EFI_INVALID_PARAMETER - Invalid parameters found.
+ EFI_OUT_OF_RESOURCES - The request could not be completed due to a lack of
+ resources.
+--*/
+{
+ PCI_ROOT_BRIDGE_INSTANCE *PrivateData;
+ UINT32 PciBus;
+ UINT32 PciDev;
+ UINT32 PciFn;
+ UINT32 PciExtReg;
+ UINT64 ExtConfigAdd;
+
+ if (Buffer == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (Width < 0 ||
+ Width == EfiPciWidthUint64 ||
+ Width == EfiPciWidthFifoUint64 ||
+ Width == EfiPciWidthFillUint64 ||
+ Width >= EfiPciWidthMaximum
+ ) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Read Pci configuration space
+ //
+ PrivateData = DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS (This);
+
+ if (PrivateData->HecBase == 0) {
+ return RootBridgeIoPciRW (This, FALSE, Width, Address, Count, Buffer);
+ }
+
+ if (!((EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS *) &Address)->ExtendedRegister) {
+ PciExtReg = ((EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS *) &Address)->Register;
+ } else {
+ PciExtReg = ((EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS *) &Address)->ExtendedRegister & 0x0FFF;
+ }
+
+ PciBus = ((EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS *) &Address)->Bus;
+ PciDev = ((EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS *) &Address)->Device;
+ PciFn = ((EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS *) &Address)->Function;
+
+ ExtConfigAdd = (UINT64) PrivateData->HecBase + PCIE_OFF (PciBus, PciDev, PciFn, PciExtReg);
+
+ return mCpuIo->Mem.Read (
+ mCpuIo,
+ (EFI_CPU_IO_PROTOCOL_WIDTH) Width,
+ ExtConfigAdd,
+ Count,
+ Buffer
+ );
+}
+
+EFI_STATUS
+EFIAPI
+RootBridgeIoPciWrite (
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
+ IN UINT64 Address,
+ IN UINTN Count,
+ IN OUT VOID *Buffer
+ )
+/*++
+
+Routine Description:
+
+ Allows write to PCI configuration space.
+
+Arguments:
+
+ This - A pointer to EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
+ Width - Signifies the width of the memory operation.
+ Address - The address within the PCI configuration space
+ for the PCI controller.
+ Count - The number of PCI configuration operations
+ to perform.
+ Buffer - The source buffer to get the results.
+
+Returns:
+
+ EFI_SUCCESS - The data was written to the PCI root bridge.
+ EFI_INVALID_PARAMETER - Invalid parameters found.
+ EFI_OUT_OF_RESOURCES - The request could not be completed due to a lack of
+ resources.
+--*/
+{
+ PCI_ROOT_BRIDGE_INSTANCE *PrivateData;
+ UINT32 PciBus;
+ UINT32 PciDev;
+ UINT32 PciFn;
+ UINT32 PciExtReg;
+ UINT64 ExtConfigAdd;
+
+ if (Buffer == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (Width < 0 || Width >= EfiPciWidthMaximum) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Write Pci configuration space
+ //
+ PrivateData = DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS (This);
+
+ if (PrivateData->HecBase == 0) {
+ return RootBridgeIoPciRW (This, TRUE, Width, Address, Count, Buffer);
+ }
+
+ if (!((EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS *) &Address)->ExtendedRegister) {
+ PciExtReg = ((EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS *) &Address)->Register;
+ } else {
+ PciExtReg = ((EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS *) &Address)->ExtendedRegister & 0x0FFF;
+ }
+
+ PciBus = ((EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS *) &Address)->Bus;
+ PciDev = ((EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS *) &Address)->Device;
+ PciFn = ((EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS *) &Address)->Function;
+
+ ExtConfigAdd = (UINT64) PrivateData->HecBase + PCIE_OFF (PciBus, PciDev, PciFn, PciExtReg);
+
+ return mCpuIo->Mem.Write (
+ mCpuIo,
+ (EFI_CPU_IO_PROTOCOL_WIDTH) Width,
+ ExtConfigAdd,
+ Count,
+ Buffer
+ );
+}
+
+EFI_STATUS
+EFIAPI
+RootBridgeIoMap (
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_OPERATION Operation,
+ IN VOID *HostAddress,
+ IN OUT UINTN *NumberOfBytes,
+ OUT EFI_PHYSICAL_ADDRESS *DeviceAddress,
+ OUT VOID **Mapping
+ )
+/*++
+
+Routine Description:
+
+ Provides the PCI controller-specific address needed to access
+ system memory for DMA.
+
+Arguments:
+
+ This - A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
+ Operation - Indicate if the bus master is going to read or write
+ to system memory.
+ HostAddress - The system memory address to map on the PCI controller.
+ NumberOfBytes - On input the number of bytes to map.
+ On output the number of bytes that were mapped.
+ DeviceAddress - The resulting map address for the bus master PCI
+ controller to use to access the system memory's HostAddress.
+ Mapping - The value to pass to Unmap() when the bus master DMA
+ operation is complete.
+
+Returns:
+
+ EFI_SUCCESS - Success.
+ EFI_INVALID_PARAMETER - Invalid parameters found.
+ EFI_UNSUPPORTED - The HostAddress cannot be mapped as a common
+ buffer.
+ EFI_DEVICE_ERROR - The System hardware could not map the requested
+ address.
+ EFI_OUT_OF_RESOURCES - The request could not be completed due to
+ lack of resources.
+
+--*/
+{
+ EFI_STATUS Status;
+ EFI_PHYSICAL_ADDRESS PhysicalAddress;
+ MAP_INFO *MapInfo;
+
+ if (NumberOfBytes == NULL || Mapping == NULL || DeviceAddress == NULL || HostAddress == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+ //
+ // Initialize the return values to their defaults
+ //
+ *Mapping = NULL;
+
+ //
+ // Make sure that Operation is valid
+ //
+ if ((Operation < 0) || (Operation > EfiPciOperationBusMasterCommonBuffer64)) {
+ return EFI_INVALID_PARAMETER;
+ }
+ //
+ // Most PCAT like chipsets can not handle performing DMA above 4GB.
+ // If any part of the DMA transfer being mapped is above 4GB, then
+ // map the DMA transfer to a buffer below 4GB.
+ //
+ PhysicalAddress = (EFI_PHYSICAL_ADDRESS) (UINTN) HostAddress;
+ if ((PhysicalAddress +*NumberOfBytes) > 0x100000000ULL) {
+ //
+ // Common Buffer operations can not be remapped. If the common buffer
+ // if above 4GB, then it is not possible to generate a mapping, so return
+ // an error.
+ //
+ if (Operation == EfiPciOperationBusMasterCommonBuffer || Operation == EfiPciOperationBusMasterCommonBuffer64) {
+ return EFI_INVALID_PARAMETER;
+ }
+ }
+
+ if ((PhysicalAddress + *NumberOfBytes) > (DMA_MEMORY_TOP+1)) {
+
+ //
+ // Common Buffer operations can not be remapped.
+ //
+ if (Operation == EfiPciOperationBusMasterCommonBuffer || Operation == EfiPciOperationBusMasterCommonBuffer64) {
+ *DeviceAddress = PhysicalAddress;
+ return EFI_SUCCESS;
+ }
+ //
+ // Allocate a MAP_INFO structure to remember the mapping when Unmap() is
+ // called later.
+ //
+ Status = gBS->AllocatePool (
+ EfiBootServicesData,
+ sizeof (MAP_INFO),
+ (VOID **) &MapInfo
+ );
+ if (EFI_ERROR (Status)) {
+ *NumberOfBytes = 0;
+ return Status;
+ }
+ //
+ // Return a pointer to the MAP_INFO structure in Mapping
+ //
+ *Mapping = MapInfo;
+
+ //
+ // Initialize the MAP_INFO structure
+ //
+ MapInfo->Operation = Operation;
+ MapInfo->NumberOfBytes = *NumberOfBytes;
+ MapInfo->NumberOfPages = EFI_SIZE_TO_PAGES (*NumberOfBytes);
+ MapInfo->HostAddress = PhysicalAddress;
+ MapInfo->MappedHostAddress = DMA_MEMORY_TOP;
+
+ //
+ // Allocate a buffer below DMA_MEMORY_TOP to map the transfer to.
+ //
+ Status = gBS->AllocatePages (
+ AllocateMaxAddress,
+ EfiBootServicesData,
+ MapInfo->NumberOfPages,
+ &MapInfo->MappedHostAddress
+ );
+ if (EFI_ERROR (Status)) {
+ gBS->FreePool (MapInfo);
+ *NumberOfBytes = 0;
+ return Status;
+ }
+ //
+ // If this is a read operation from the Bus Master's point of view,
+ // then copy the contents of the real buffer into the mapped buffer
+ // so the Bus Master can read the contents of the real buffer.
+ //
+ if (Operation == EfiPciOperationBusMasterRead || Operation == EfiPciOperationBusMasterRead64) {
+ CopyMem (
+ (VOID *) (UINTN) MapInfo->MappedHostAddress,
+ (VOID *) (UINTN) MapInfo->HostAddress,
+ MapInfo->NumberOfBytes
+ );
+ }
+ //
+ // The DeviceAddress is the address of the maped buffer below DMA_MEMORY_TOP
+ //
+ *DeviceAddress = MapInfo->MappedHostAddress;
+ } else {
+ //
+ // The transfer is below DMA_MEMORY_TOP, so the DeviceAddress is simply the HostAddress
+ //
+ *DeviceAddress = PhysicalAddress;
+ }
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+RootBridgeIoUnmap (
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
+ IN VOID *Mapping
+ )
+/*++
+
+Routine Description:
+
+ Completes the Map() operation and releases any corresponding resources.
+
+Arguments:
+
+ This - Pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL instance.
+ Mapping - The value returned from Map() operation.
+
+Returns:
+
+ EFI_SUCCESS - The range was unmapped successfully.
+ EFI_INVALID_PARAMETER - Mapping is not a value that was returned
+ by Map operation.
+ EFI_DEVICE_ERROR - The data was not committed to the target
+ system memory.
+
+--*/
+{
+ MAP_INFO *MapInfo;
+
+ //
+ // See if the Map() operation associated with this Unmap() required a mapping buffer.
+ // If a mapping buffer was not required, then this function simply returns EFI_SUCCESS.
+ //
+ if (Mapping != NULL) {
+ //
+ // Get the MAP_INFO structure from Mapping
+ //
+ MapInfo = (MAP_INFO *) Mapping;
+
+ //
+ // If this is a write operation from the Bus Master's point of view,
+ // then copy the contents of the mapped buffer into the real buffer
+ // so the processor can read the contents of the real buffer.
+ //
+ if ((MapInfo->Operation == EfiPciOperationBusMasterWrite) ||
+ (MapInfo->Operation == EfiPciOperationBusMasterWrite64)
+ ) {
+ CopyMem (
+ (VOID *) (UINTN) MapInfo->HostAddress,
+ (VOID *) (UINTN) MapInfo->MappedHostAddress,
+ MapInfo->NumberOfBytes
+ );
+ }
+ //
+ // Free the mapped buffer and the MAP_INFO structure.
+ //
+ gBS->FreePages (MapInfo->MappedHostAddress, MapInfo->NumberOfPages);
+ gBS->FreePool (Mapping);
+ }
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+RootBridgeIoAllocateBuffer (
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
+ IN EFI_ALLOCATE_TYPE Type,
+ IN EFI_MEMORY_TYPE MemoryType,
+ IN UINTN Pages,
+ OUT VOID **HostAddress,
+ IN UINT64 Attributes
+ )
+/*++
+
+Routine Description:
+
+ Allocates pages that are suitable for a common buffer mapping.
+
+Arguments:
+
+ This - Pointer to EFI_ROOT_BRIDGE_IO_PROTOCOL instance.
+ Type - Not used and can be ignored.
+ MemoryType - Type of memory to allocate.
+ Pages - Number of pages to allocate.
+ HostAddress - Pointer to store the base system memory address
+ of the allocated range.
+ Attributes - Requested bit mask of attributes of the allocated
+ range.
+
+Returns:
+
+ EFI_SUCCESS - The requested memory range were allocated.
+ EFI_INVALID_PARAMETER - Invalid parameter found.
+ EFI_UNSUPPORTED - Attributes is unsupported.
+
+--*/
+{
+ EFI_STATUS Status;
+ EFI_PHYSICAL_ADDRESS PhysicalAddress;
+
+ //
+ // Validate Attributes
+ //
+ if ((Attributes & EFI_PCI_ATTRIBUTE_INVALID_FOR_ALLOCATE_BUFFER) != 0) {
+ return EFI_UNSUPPORTED;
+ }
+ //
+ // Check for invalid inputs
+ //
+ if (HostAddress == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+ //
+ // The only valid memory types are EfiBootServicesData and EfiRuntimeServicesData
+ //
+ if ((MemoryType != EfiBootServicesData) && (MemoryType != EfiRuntimeServicesData)) {
+ return EFI_INVALID_PARAMETER;
+ }
+ //
+ // Limit allocations to memory below DMA_MEMORY_TOP
+ //
+ PhysicalAddress = DMA_MEMORY_TOP;
+
+ Status = gBS->AllocatePages (
+ AllocateMaxAddress,
+ MemoryType,
+ Pages,
+ &PhysicalAddress
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ *HostAddress = (VOID *) (UINTN) PhysicalAddress;
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+RootBridgeIoFreeBuffer (
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
+ IN UINTN Pages,
+ OUT VOID *HostAddress
+ )
+/*++
+
+Routine Description:
+
+ Free memory allocated in AllocateBuffer.
+
+Arguments:
+
+ This - Pointer to EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
+ instance.
+ Pages - Number of pages to free.
+ HostAddress - The base system memory address of the
+ allocated range.
+
+Returns:
+
+ EFI_SUCCESS - Requested memory pages were freed.
+ EFI_INVALID_PARAMETER - Invalid parameter found.
+
+--*/
+{
+ return gBS->FreePages ((EFI_PHYSICAL_ADDRESS) (UINTN) HostAddress, Pages);
+}
+
+EFI_STATUS
+EFIAPI
+RootBridgeIoFlush (
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This
+ )
+/*++
+
+Routine Description:
+
+ Flushes all PCI posted write transactions from a PCI host
+ bridge to system memory.
+
+Arguments:
+
+ This - Pointer to EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL instance.
+
+Returns:
+
+ EFI_SUCCESS - PCI posted write transactions were flushed
+ from PCI host bridge to system memory.
+ EFI_DEVICE_ERROR - Fail due to hardware error.
+
+--*/
+{
+ //
+ // not supported yet
+ //
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+RootBridgeIoGetAttributes (
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
+ OUT UINT64 *Supported,
+ OUT UINT64 *Attributes
+ )
+/*++
+
+Routine Description:
+
+ Get the attributes that a PCI root bridge supports and
+ the attributes the PCI root bridge is currently using.
+
+Arguments:
+
+ This - Pointer to EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
+ instance.
+ Supports - A pointer to the mask of attributes that
+ this PCI root bridge supports.
+ Attributes - A pointer to the mask of attributes that
+ this PCI root bridge is currently using.
+Returns:
+
+ EFI_SUCCESS - Success.
+ EFI_INVALID_PARAMETER - Invalid parameter found.
+
+--*/
+
+// GC_TODO: Supported - add argument and description to function comment
+//
+// GC_TODO: Supported - add argument and description to function comment
+//
+// GC_TODO: Supported - add argument and description to function comment
+//
+{
+ PCI_ROOT_BRIDGE_INSTANCE *PrivateData;
+
+ PrivateData = DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS (This);
+
+ if (Attributes == NULL && Supported == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+ //
+ // Set the return value for Supported and Attributes
+ //
+ if (Supported) {
+ *Supported = PrivateData->Supports;
+ }
+
+ if (Attributes) {
+ *Attributes = PrivateData->Attributes;
+ }
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+RootBridgeIoSetAttributes (
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
+ IN UINT64 Attributes,
+ IN OUT UINT64 *ResourceBase,
+ IN OUT UINT64 *ResourceLength
+ )
+/*++
+
+Routine Description:
+
+ Sets the attributes for a resource range on a PCI root bridge.
+
+Arguments:
+
+ This - Pointer to EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL instance.
+ Attributes - The mask of attributes to set.
+ ResourceBase - Pointer to the base address of the resource range
+ to be modified by the attributes specified by Attributes.
+ ResourceLength - Pointer to the length of the resource range to be modified.
+
+Returns:
+ EFI_SUCCESS - Success.
+ EFI_INVALID_PARAMETER - Invalid parameter found.
+ EFI_OUT_OF_RESOURCES - Not enough resources to set the attributes upon.
+
+--*/
+
+//
+// GC_TODO: EFI_UNSUPPORTED - add return value to function comment
+//
+{
+ PCI_ROOT_BRIDGE_INSTANCE *PrivateData;
+
+ PrivateData = DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS (This);
+
+ if (Attributes != 0) {
+ Attributes &= (PrivateData->Supports);
+ if (Attributes == 0) {
+ return EFI_UNSUPPORTED;
+ }
+ }
+
+ if (Attributes == PrivateData->Attributes) {
+ return EFI_SUCCESS;
+ }
+ //
+ // It is just a trick for some attribute can only be enabled or disabled
+ // otherwise it can impact on other devices
+ //
+ PrivateData->Attributes = Attributes;
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+RootBridgeIoConfiguration (
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
+ OUT VOID **Resources
+ )
+/*++
+
+Routine Description:
+
+ Retrieves the current resource settings of this PCI root bridge
+ in the form of a set of ACPI 2.0 resource descriptor.
+
+Arguments:
+
+ This - Pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL instance.
+ Resources - Pointer to the ACPI 2.0 resource descriptor that
+ describe the current configuration of this PCI root
+ bridge.
+
+Returns:
+
+ EFI_SUCCESS - Success.
+ EFI_UNSUPPORTED - Current configuration of the PCI root bridge
+ could not be retrieved.
+
+--*/
+
+//
+// GC_TODO: EFI_OUT_OF_RESOURCES - add return value to function comment
+//
+{
+ EFI_STATUS Status;
+ UINTN Idx;
+
+ PCI_ROOT_BRIDGE_INSTANCE *RbPrivateData;
+ PCI_RES_NODE *ResAllocNode;
+ EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Config;
+
+ //
+ // Get this instance of the Root Bridge.
+ //
+ RbPrivateData = DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS (This);
+
+ //
+ // If the pointer is not NULL, it points to a buffer already allocated.
+ //
+ if (RbPrivateData->ConfigBuffer == NULL) {
+ Status = gBS->AllocatePool (
+ EfiBootServicesData,
+ TypeMax * sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) + sizeof (EFI_ACPI_END_TAG_DESCRIPTOR),
+ &RbPrivateData->ConfigBuffer
+ );
+ if (EFI_ERROR (Status)) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ }
+
+ Config = RbPrivateData->ConfigBuffer;
+
+ ZeroMem (Config, TypeMax * sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) + sizeof (EFI_ACPI_END_TAG_DESCRIPTOR));
+
+ for (Idx = 0; Idx < TypeMax; Idx++) {
+
+ ResAllocNode = &RbPrivateData->ResAllocNode[Idx];
+
+ if (ResAllocNode->Status != ResAllocated) {
+ continue;
+ }
+
+ switch (ResAllocNode->Type) {
+
+ case TypeIo:
+ Config->Desc = ACPI_ADDRESS_SPACE_DESCRIPTOR;
+ Config->Len = sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) - 3;
+ Config->ResType = ACPI_ADDRESS_SPACE_TYPE_IO;
+ Config->AddrRangeMin = ResAllocNode->Base;
+ Config->AddrRangeMax = ResAllocNode->Base + ResAllocNode->Length - 1;
+ Config->AddrLen = ResAllocNode->Length;
+ break;
+
+ case TypeMem32:
+ Config->Desc = ACPI_ADDRESS_SPACE_DESCRIPTOR;
+ Config->Len = sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) - 3;
+ Config->ResType = ACPI_ADDRESS_SPACE_TYPE_MEM;
+ Config->AddrSpaceGranularity = 32;
+ Config->AddrRangeMin = ResAllocNode->Base;
+ Config->AddrRangeMax = ResAllocNode->Base + ResAllocNode->Length - 1;
+ Config->AddrLen = ResAllocNode->Length;
+ break;
+
+ case TypePMem32:
+ Config->Desc = ACPI_ADDRESS_SPACE_DESCRIPTOR;
+ Config->Len = sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) - 3;
+ Config->ResType = ACPI_ADDRESS_SPACE_TYPE_MEM;
+ Config->SpecificFlag = 6;
+ Config->AddrSpaceGranularity = 32;
+ Config->AddrRangeMin = ResAllocNode->Base;
+ Config->AddrRangeMax = ResAllocNode->Base + ResAllocNode->Length - 1;
+ Config->AddrLen = ResAllocNode->Length;
+ break;
+
+ case TypeMem64:
+ Config->Desc = ACPI_ADDRESS_SPACE_DESCRIPTOR;
+ Config->Len = sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) - 3;
+ Config->ResType = ACPI_ADDRESS_SPACE_TYPE_MEM;
+ Config->SpecificFlag = 6;
+ Config->AddrSpaceGranularity = 64;
+ Config->AddrRangeMin = ResAllocNode->Base;
+ Config->AddrRangeMax = ResAllocNode->Base + ResAllocNode->Length - 1;
+ Config->AddrLen = ResAllocNode->Length;
+ break;
+
+ case TypePMem64:
+ Config->Desc = ACPI_ADDRESS_SPACE_DESCRIPTOR;
+ Config->Len = sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) - 3;
+ Config->ResType = ACPI_ADDRESS_SPACE_TYPE_MEM;
+ Config->SpecificFlag = 6;
+ Config->AddrSpaceGranularity = 64;
+ Config->AddrRangeMin = ResAllocNode->Base;
+ Config->AddrRangeMax = ResAllocNode->Base + ResAllocNode->Length - 1;
+ Config->AddrLen = ResAllocNode->Length;
+ break;
+
+ case TypeBus:
+ Config->Desc = ACPI_ADDRESS_SPACE_DESCRIPTOR;
+ Config->Len = sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) - 3;
+ Config->ResType = ACPI_ADDRESS_SPACE_TYPE_BUS;
+ Config->AddrRangeMin = ResAllocNode->Base;
+ Config->AddrRangeMax = ResAllocNode->Base + ResAllocNode->Length - 1;
+ Config->AddrLen = ResAllocNode->Length;
+ break;
+
+ default:
+ break;
+ }
+
+ Config++;
+ }
+ //
+ // Terminate the entries.
+ //
+ ((EFI_ACPI_END_TAG_DESCRIPTOR *) Config)->Desc = ACPI_END_TAG_DESCRIPTOR;
+ ((EFI_ACPI_END_TAG_DESCRIPTOR *) Config)->Checksum = 0x0;
+
+ *Resources = RbPrivateData->ConfigBuffer;
+ return EFI_SUCCESS;
+}
diff --git a/QuarkPlatformPkg/Pci/Dxe/PciPlatform/CommonHeader.h b/QuarkPlatformPkg/Pci/Dxe/PciPlatform/CommonHeader.h
new file mode 100644
index 0000000000..90a0369167
--- /dev/null
+++ b/QuarkPlatformPkg/Pci/Dxe/PciPlatform/CommonHeader.h
@@ -0,0 +1,37 @@
+/** @file
+Common header file shared by all source files.
+
+This file includes package header files, library classes and protocol, PPI & GUID definitions.
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+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 __COMMON_HEADER_H_
+#define __COMMON_HEADER_H_
+
+
+
+#include <PiDxe.h>
+#include <IntelQNCDxe.h>
+
+#include <Protocol/PciPlatform.h>
+#include <Protocol/PciIo.h>
+
+#include <Library/DxeServicesLib.h>
+#include <Library/UefiDriverEntryPoint.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+#include <Library/PciLib.h>
+#include <Library/IohLib.h>
+
+#endif
diff --git a/QuarkPlatformPkg/Pci/Dxe/PciPlatform/PciPlatform.c b/QuarkPlatformPkg/Pci/Dxe/PciPlatform/PciPlatform.c
new file mode 100644
index 0000000000..173e8af103
--- /dev/null
+++ b/QuarkPlatformPkg/Pci/Dxe/PciPlatform/PciPlatform.c
@@ -0,0 +1,200 @@
+/** @file
+Registers onboard PCI ROMs with PCI.IO
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+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 "CommonHeader.h"
+
+#include "PciPlatform.h"
+
+
+PCI_OPTION_ROM_TABLE mPciOptionRomTable[] = {
+ { NULL_ROM_FILE_GUID, 0, 0, 0, 0, 0xffff, 0xffff }
+};
+EFI_PCI_PLATFORM_PROTOCOL mPciPlatform = {
+ PhaseNotify,
+ PlatformPrepController,
+ GetPlatformPolicy,
+ GetPciRom
+};
+
+EFI_HANDLE mPciPlatformHandle = NULL;
+EFI_HANDLE mImageHandle = NULL;
+
+
+EFI_STATUS
+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
+ )
+{
+ UINT8 UsbHostBusNumber = IOH_BUS;
+ if (Phase == EfiPciHostBridgeEndResourceAllocation) {
+ // Required for QuarkSouthCluster.
+ // Enable USB controller memory, io and bus master before Ehci driver.
+ EnableUsbMemIoBusMaster (UsbHostBusNumber);
+ return EFI_SUCCESS;
+ }
+ return EFI_UNSUPPORTED;
+}
+
+
+EFI_STATUS
+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
+ )
+{
+ return EFI_UNSUPPORTED;
+}
+
+EFI_STATUS
+GetPlatformPolicy (
+ IN CONST EFI_PCI_PLATFORM_PROTOCOL *This,
+ OUT EFI_PCI_PLATFORM_POLICY *PciPolicy
+ )
+{
+ if (PciPolicy == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ return EFI_UNSUPPORTED;
+}
+
+EFI_STATUS
+GetPciRom (
+ IN CONST EFI_PCI_PLATFORM_PROTOCOL *This,
+ IN EFI_HANDLE PciHandle,
+ OUT VOID **RomImage,
+ OUT UINTN *RomSize
+ )
+/*++
+
+ Routine Description:
+ Return a PCI ROM image for the onboard device represented by PciHandle
+
+ Arguments:
+ 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
+
+ Returns:
+ EFI_SUCCESS - RomImage is valid
+ EFI_NOT_FOUND - No RomImage
+
+--*/
+{
+ EFI_STATUS Status;
+ EFI_PCI_IO_PROTOCOL *PciIo;
+ UINTN Segment;
+ UINTN Bus;
+ UINTN Device;
+ UINTN Function;
+ UINT16 VendorId;
+ UINT16 DeviceId;
+ UINT16 DeviceClass;
+ UINTN TableIndex;
+
+ Status = gBS->HandleProtocol (
+ PciHandle,
+ &gEfiPciIoProtocolGuid,
+ (VOID **) &PciIo
+ );
+ if (EFI_ERROR (Status)) {
+ return EFI_NOT_FOUND;
+ }
+
+ PciIo->GetLocation (PciIo, &Segment, &Bus, &Device, &Function);
+
+ PciIo->Pci.Read (PciIo, EfiPciIoWidthUint16, 0x0A, 1, &DeviceClass);
+
+ PciIo->Pci.Read (PciIo, EfiPciIoWidthUint16, 0, 1, &VendorId);
+
+ PciIo->Pci.Read (PciIo, EfiPciIoWidthUint16, 2, 1, &DeviceId);
+
+ //
+ // Loop through table of video option rom descriptions
+ //
+ for (TableIndex = 0; mPciOptionRomTable[TableIndex].VendorId != 0xffff; TableIndex++) {
+
+ //
+ // See if the PCI device specified by PciHandle matches at device in mPciOptionRomTable
+ //
+ if (VendorId != mPciOptionRomTable[TableIndex].VendorId ||
+ DeviceId != mPciOptionRomTable[TableIndex].DeviceId ||
+ Segment != mPciOptionRomTable[TableIndex].Segment ||
+ Bus != mPciOptionRomTable[TableIndex].Bus ||
+ Device != mPciOptionRomTable[TableIndex].Device ||
+ Function != mPciOptionRomTable[TableIndex].Function) {
+ continue;
+ }
+
+ Status = GetSectionFromFv (
+ &mPciOptionRomTable[TableIndex].FileName,
+ EFI_SECTION_RAW,
+ 0,
+ RomImage,
+ RomSize
+ );
+
+ if (EFI_ERROR (Status)) {
+ continue;
+ }
+
+ return EFI_SUCCESS;
+ }
+
+ return EFI_NOT_FOUND;
+}
+
+EFI_STATUS
+PciPlatformDriverEntry (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+/*++
+
+Routine Description:
+
+Arguments:
+ (Standard EFI Image entry - EFI_IMAGE_ENTRY_POINT)
+
+Returns:
+ EFI_STATUS
+
+--*/
+{
+ EFI_STATUS Status;
+
+ mImageHandle = ImageHandle;
+
+ //
+ // Install on a new handle
+ //
+ Status = gBS->InstallProtocolInterface (
+ &mPciPlatformHandle,
+ &gEfiPciPlatformProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ &mPciPlatform
+ );
+
+ return Status;
+}
diff --git a/QuarkPlatformPkg/Pci/Dxe/PciPlatform/PciPlatform.h b/QuarkPlatformPkg/Pci/Dxe/PciPlatform/PciPlatform.h
new file mode 100644
index 0000000000..147a0e577b
--- /dev/null
+++ b/QuarkPlatformPkg/Pci/Dxe/PciPlatform/PciPlatform.h
@@ -0,0 +1,88 @@
+/** @file
+This code supports a the private implementation
+of the Legacy BIOS Platform protocol
+
+Copyright (c) 2013-2015 Intel Corporation.
+
+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_PLATFORM_H_
+#define PCI_PLATFORM_H_
+
+#include <IndustryStandard/Pci.h>
+#include <Library/PcdLib.h>
+//
+// Global variables for Option ROMs
+//
+#define NULL_ROM_FILE_GUID \
+{ 0x00000000, 0x0000, 0x0000, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }}
+
+#define ONBOARD_VIDEO_OPTION_ROM_FILE_GUID \
+{ 0x8dfae5d4, 0xb50e, 0x4c10, {0x96, 0xe6, 0xf2, 0xc2, 0x66, 0xca, 0xcb, 0xb6 }}
+
+#define IDE_RAID_OPTION_ROM_FILE_GUID \
+{ 0x3392A8E1, 0x1881, 0x4398, {0x83, 0xa6, 0x53, 0xd3, 0x87, 0xdb, 0x20, 0x20 }}
+
+#define TANX_UNDI_OPTION_ROM_FILE_GUID \
+{ 0x84c24ab0, 0x124e, 0x4aed, {0x8e, 0xfe, 0xf9, 0x1b, 0xb9, 0x73, 0x69, 0xf4 }}
+
+#define PXE_UNDI_OPTION_ROM_FILE_GUID \
+{ 0xea34cd48, 0x5fdf, 0x46f0, {0xb5, 0xfa, 0xeb, 0xe0, 0x76, 0xa4, 0xf1, 0x2c }}
+
+
+typedef struct {
+ EFI_GUID FileName;
+ UINTN Segment;
+ UINTN Bus;
+ UINTN Device;
+ UINTN Function;
+ UINT16 VendorId;
+ UINT16 DeviceId;
+} PCI_OPTION_ROM_TABLE;
+
+
+EFI_STATUS
+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
+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
+ );
+
+EFI_STATUS
+GetPlatformPolicy (
+ IN CONST EFI_PCI_PLATFORM_PROTOCOL *This,
+ OUT EFI_PCI_PLATFORM_POLICY *PciPolicy
+ );
+
+EFI_STATUS
+GetPciRom (
+ IN CONST EFI_PCI_PLATFORM_PROTOCOL *This,
+ IN EFI_HANDLE PciHandle,
+ OUT VOID **RomImage,
+ OUT UINTN *RomSize
+ );
+
+#endif
+
+
diff --git a/QuarkPlatformPkg/Pci/Dxe/PciPlatform/PciPlatform.inf b/QuarkPlatformPkg/Pci/Dxe/PciPlatform/PciPlatform.inf
new file mode 100644
index 0000000000..a3c036a541
--- /dev/null
+++ b/QuarkPlatformPkg/Pci/Dxe/PciPlatform/PciPlatform.inf
@@ -0,0 +1,60 @@
+## @file
+# Component description file for PciPlatform module.
+#
+# This driver installs pciplatform protocol to provide access interfaces to the onboard pci roms.
+# Copyright (c) 2013-2015 Intel Corporation.
+#
+# 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 = 2E8CD01A-BDB7-40b4-8376-E7C26EAC21FF
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ ENTRY_POINT = PciPlatformDriverEntry
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 IPF EBC
+#
+
+[Sources]
+ PciPlatform.c
+ PciPlatform.h
+ CommonHeader.h
+
+[Packages]
+ MdePkg/MdePkg.dec
+ QuarkPlatformPkg/QuarkPlatformPkg.dec
+ QuarkSocPkg/QuarkSocPkg.dec
+
+[LibraryClasses]
+ PciLib
+ PcdLib
+ IohLib
+ DebugLib
+ UefiRuntimeServicesTableLib
+ UefiBootServicesTableLib
+ UefiDriverEntryPoint
+ DxeServicesLib
+
+[Guids]
+
+[Protocols]
+ gEfiPciIoProtocolGuid # PROTOCOL ALWAYS_CONSUMED
+ gEfiPciPlatformProtocolGuid # PROTOCOL ALWAYS_PRODUCED
+
+[Pcd]
+
+[Depex]
+ TRUE