summaryrefslogtreecommitdiff
path: root/ArmPlatformPkg/ArmJunoPkg/Drivers/PciHostBridgeDxe/PciHostBridge.c
diff options
context:
space:
mode:
Diffstat (limited to 'ArmPlatformPkg/ArmJunoPkg/Drivers/PciHostBridgeDxe/PciHostBridge.c')
-rw-r--r--ArmPlatformPkg/ArmJunoPkg/Drivers/PciHostBridgeDxe/PciHostBridge.c199
1 files changed, 199 insertions, 0 deletions
diff --git a/ArmPlatformPkg/ArmJunoPkg/Drivers/PciHostBridgeDxe/PciHostBridge.c b/ArmPlatformPkg/ArmJunoPkg/Drivers/PciHostBridgeDxe/PciHostBridge.c
new file mode 100644
index 0000000000..e1a6b749e4
--- /dev/null
+++ b/ArmPlatformPkg/ArmJunoPkg/Drivers/PciHostBridgeDxe/PciHostBridge.c
@@ -0,0 +1,199 @@
+/** @file
+* Pci Host Bridge support for the Xpress-RICH3 PCIe Root Complex
+*
+* Copyright (c) 2011-2015, ARM Ltd. All rights reserved.
+*
+* This program and the accompanying materials
+* are licensed and made available under the terms and conditions of the BSD License
+* 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 <Guid/EventGroup.h>
+
+/**
+ * PCI Root Bridge Description
+ */
+typedef struct {
+ UINT32 AcpiUid;
+ UINT64 MemAllocAttributes;
+} PCI_ROOT_BRIDGE_DESC;
+
+PCI_ROOT_BRIDGE_DESC PciRbDescriptions = {
+ 0, // AcpiUid
+ PCI_MEMORY_ALLOCATION_ATTRIBUTES // MemAllocAttributes
+};
+
+/**
+ * Template for PCI Host Bridge Instance
+ **/
+STATIC CONST PCI_HOST_BRIDGE_INSTANCE
+gPciHostBridgeInstanceTemplate = {
+ PCI_HOST_BRIDGE_SIGNATURE, //Signature
+ NULL, // Handle
+ NULL, // ImageHandle
+ NULL, // RootBridge
+ TRUE, // CanRestarted
+ NULL, // CpuIo
+ NULL, // Metronome
+ { // ResAlloc
+ PciHbRaNotifyPhase, // ResAlloc.NotifyPhase
+ PciHbRaGetNextRootBridge, // ResAlloc.GetNextRootBridge
+ PciHbRaGetAllocAttributes, // ResAlloc.GetAllocAttributes
+ PciHbRaStartBusEnumeration, // ResAlloc.StartBusEnumeration
+ PciHbRaSetBusNumbers, // ResAlloc.SetBusNumbers
+ PciHbRaSubmitResources, // ResAlloc.SubmitResources
+ PciHbRaGetProposedResources, // ResAlloc.GetProposedResources
+ PciHbRaPreprocessController // ResAlloc.PreprocessController
+ }
+};
+PCI_HOST_BRIDGE_INSTANCE* gpPciHostBridgeInstance;
+
+EFI_STATUS
+HostBridgeConstructor (
+ IN OUT PCI_HOST_BRIDGE_INSTANCE** Instance,
+ IN EFI_HANDLE ImageHandle
+ )
+{
+ EFI_STATUS Status;
+ PCI_HOST_BRIDGE_INSTANCE* HostBridge;
+
+ PCI_TRACE ("HostBridgeConstructor()");
+
+ if (Instance == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ HostBridge = AllocateCopyPool (sizeof (PCI_HOST_BRIDGE_INSTANCE), &gPciHostBridgeInstanceTemplate);
+ if (HostBridge == NULL) {
+ PCI_TRACE ("HostBridgeConstructor(): FAIL to allocate resources");
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ // It will also create a device handle for the PCI Host Bridge (as HostBridge->Handle == NULL)
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &HostBridge->Handle,
+ &gEfiPciHostBridgeResourceAllocationProtocolGuid, &HostBridge->ResAlloc,
+ NULL
+ );
+ if (EFI_ERROR (Status)) {
+ PCI_TRACE ("HostBridgeConstructor(): FAIL to install resource allocator");
+ FreePool (HostBridge);
+ return EFI_DEVICE_ERROR;
+ } else {
+ PCI_TRACE ("HostBridgeConstructor(): SUCCEED to install resource allocator");
+ }
+
+ Status = gBS->LocateProtocol (&gEfiCpuIo2ProtocolGuid, NULL, (VOID **)(&(HostBridge->CpuIo)));
+ ASSERT_EFI_ERROR (Status);
+
+ Status = gBS->LocateProtocol (&gEfiMetronomeArchProtocolGuid, NULL, (VOID **)(&(HostBridge->Metronome)));
+ ASSERT_EFI_ERROR (Status);
+
+ HostBridge->ImageHandle = ImageHandle;
+
+ *Instance = HostBridge;
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+HostBridgeDestructor (
+ IN PCI_HOST_BRIDGE_INSTANCE* HostBridge
+ )
+{
+ EFI_STATUS Status;
+
+ Status = gBS->UninstallMultipleProtocolInterfaces (
+ HostBridge->Handle,
+ &gEfiPciHostBridgeResourceAllocationProtocolGuid, &HostBridge->ResAlloc,
+ NULL
+ );
+
+ if (HostBridge->RootBridge) {
+ PciRbDestructor (HostBridge->RootBridge);
+ }
+
+ FreePool (HostBridge);
+
+ return Status;
+}
+
+/**
+ Entry point of this driver
+
+ @param ImageHandle Handle of driver image
+ @param SystemTable Point to EFI_SYSTEM_TABLE
+
+ @retval EFI_OUT_OF_RESOURCES Can not allocate memory resource
+ @retval EFI_DEVICE_ERROR Can not install the protocol instance
+ @retval EFI_SUCCESS Success to initialize the Pci host bridge.
+**/
+EFI_STATUS
+EFIAPI
+PciHostBridgeEntryPoint (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+
+ PCI_TRACE ("PciHostBridgeEntryPoint()");
+
+ // Creation of the PCI Host Bridge Instance
+ Status = HostBridgeConstructor (&gpPciHostBridgeInstance, ImageHandle);
+ if (EFI_ERROR (Status)) {
+ PCI_TRACE ("PciHostBridgeEntryPoint(): ERROR: Fail to construct PCI Host Bridge.");
+ return Status;
+ }
+
+ // Creation of the PCIe Root Bridge
+ Status = PciRbConstructor (gpPciHostBridgeInstance, PciRbDescriptions.AcpiUid, PciRbDescriptions.MemAllocAttributes);
+ if (EFI_ERROR (Status)) {
+ PCI_TRACE ("PciHostBridgeEntryPoint(): ERROR: Fail to construct PCI Root Bridge.");
+ return Status;
+ }
+ ASSERT (gpPciHostBridgeInstance->RootBridge->Signature == PCI_ROOT_BRIDGE_SIGNATURE);
+
+ // PCI 32bit Memory Space
+ Status = gDS->AddMemorySpace (
+ EfiGcdMemoryTypeMemoryMappedIo,
+ PCI_MEM32_BASE,
+ PCI_MEM32_SIZE,
+ 0
+ );
+
+ // PCI 64bit Memory Space
+ Status = gDS->AddMemorySpace (
+ EfiGcdMemoryTypeMemoryMappedIo,
+ PCI_MEM64_BASE,
+ PCI_MEM64_SIZE,
+ 0
+ );
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+PciHostBridgeUnload (
+ IN EFI_HANDLE ImageHandle
+ )
+{
+ EFI_STATUS Status;
+
+ // Free Reserved memory space in GCD
+ gDS->RemoveMemorySpace (PCI_MEM32_BASE, PCI_MEM32_SIZE);
+ gDS->RemoveMemorySpace (PCI_MEM64_BASE, PCI_MEM64_SIZE);
+
+ // Free the allocated memory
+ Status = HostBridgeDestructor (gpPciHostBridgeInstance);
+ ASSERT_EFI_ERROR (Status);
+
+ return Status;
+}