1 /** @file 2 * Pci Host Bridge support for the Xpress-RICH3 PCIe Root Complex 3 * 4 * Copyright (c) 2011-2015, ARM Ltd. All rights reserved. 5 * 6 * This program and the accompanying materials 7 * are licensed and made available under the terms and conditions of the BSD License 8 * which accompanies this distribution. The full text of the license may be found at 9 * http://opensource.org/licenses/bsd-license.php 10 * 11 * THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 13 * 14 **/ 15 16 #include "PciHostBridge.h" 17 18 #include <Guid/EventGroup.h> 19 20 /** 21 * PCI Root Bridge Description 22 */ 23 typedef struct { 24 UINT32 AcpiUid; 25 UINT64 MemAllocAttributes; 26 } PCI_ROOT_BRIDGE_DESC; 27 28 PCI_ROOT_BRIDGE_DESC PciRbDescriptions = { 29 0, // AcpiUid 30 PCI_MEMORY_ALLOCATION_ATTRIBUTES // MemAllocAttributes 31 }; 32 33 /** 34 * Template for PCI Host Bridge Instance 35 **/ 36 STATIC CONST PCI_HOST_BRIDGE_INSTANCE 37 gPciHostBridgeInstanceTemplate = { 38 PCI_HOST_BRIDGE_SIGNATURE, //Signature 39 NULL, // Handle 40 NULL, // ImageHandle 41 NULL, // RootBridge 42 TRUE, // CanRestarted 43 NULL, // CpuIo 44 NULL, // Metronome 45 { // ResAlloc 46 PciHbRaNotifyPhase, // ResAlloc.NotifyPhase 47 PciHbRaGetNextRootBridge, // ResAlloc.GetNextRootBridge 48 PciHbRaGetAllocAttributes, // ResAlloc.GetAllocAttributes 49 PciHbRaStartBusEnumeration, // ResAlloc.StartBusEnumeration 50 PciHbRaSetBusNumbers, // ResAlloc.SetBusNumbers 51 PciHbRaSubmitResources, // ResAlloc.SubmitResources 52 PciHbRaGetProposedResources, // ResAlloc.GetProposedResources 53 PciHbRaPreprocessController // ResAlloc.PreprocessController 54 } 55 }; 56 PCI_HOST_BRIDGE_INSTANCE* gpPciHostBridgeInstance; 57 58 EFI_STATUS 59 HostBridgeConstructor ( 60 IN OUT PCI_HOST_BRIDGE_INSTANCE** Instance, 61 IN EFI_HANDLE ImageHandle 62 ) 63 { 64 EFI_STATUS Status; 65 PCI_HOST_BRIDGE_INSTANCE* HostBridge; 66 67 PCI_TRACE ("HostBridgeConstructor()"); 68 69 if (Instance == NULL) { 70 return EFI_INVALID_PARAMETER; 71 } 72 73 HostBridge = AllocateCopyPool (sizeof (PCI_HOST_BRIDGE_INSTANCE), &gPciHostBridgeInstanceTemplate); 74 if (HostBridge == NULL) { 75 PCI_TRACE ("HostBridgeConstructor(): FAIL to allocate resources"); 76 return EFI_OUT_OF_RESOURCES; 77 } 78 79 // It will also create a device handle for the PCI Host Bridge (as HostBridge->Handle == NULL) 80 Status = gBS->InstallMultipleProtocolInterfaces ( 81 &HostBridge->Handle, 82 &gEfiPciHostBridgeResourceAllocationProtocolGuid, &HostBridge->ResAlloc, 83 NULL 84 ); 85 if (EFI_ERROR (Status)) { 86 PCI_TRACE ("HostBridgeConstructor(): FAIL to install resource allocator"); 87 FreePool (HostBridge); 88 return EFI_DEVICE_ERROR; 89 } else { 90 PCI_TRACE ("HostBridgeConstructor(): SUCCEED to install resource allocator"); 91 } 92 93 Status = gBS->LocateProtocol (&gEfiCpuIo2ProtocolGuid, NULL, (VOID **)(&(HostBridge->CpuIo))); 94 ASSERT_EFI_ERROR (Status); 95 96 Status = gBS->LocateProtocol (&gEfiMetronomeArchProtocolGuid, NULL, (VOID **)(&(HostBridge->Metronome))); 97 ASSERT_EFI_ERROR (Status); 98 99 HostBridge->ImageHandle = ImageHandle; 100 101 *Instance = HostBridge; 102 return EFI_SUCCESS; 103 } 104 105 EFI_STATUS 106 HostBridgeDestructor ( 107 IN PCI_HOST_BRIDGE_INSTANCE* HostBridge 108 ) 109 { 110 EFI_STATUS Status; 111 112 Status = gBS->UninstallMultipleProtocolInterfaces ( 113 HostBridge->Handle, 114 &gEfiPciHostBridgeResourceAllocationProtocolGuid, &HostBridge->ResAlloc, 115 NULL 116 ); 117 118 if (HostBridge->RootBridge) { 119 PciRbDestructor (HostBridge->RootBridge); 120 } 121 122 FreePool (HostBridge); 123 124 return Status; 125 } 126 127 /** 128 Entry point of this driver 129 130 @param ImageHandle Handle of driver image 131 @param SystemTable Point to EFI_SYSTEM_TABLE 132 133 @retval EFI_OUT_OF_RESOURCES Can not allocate memory resource 134 @retval EFI_DEVICE_ERROR Can not install the protocol instance 135 @retval EFI_SUCCESS Success to initialize the Pci host bridge. 136 **/ 137 EFI_STATUS 138 EFIAPI 139 PciHostBridgeEntryPoint ( 140 IN EFI_HANDLE ImageHandle, 141 IN EFI_SYSTEM_TABLE *SystemTable 142 ) 143 { 144 EFI_STATUS Status; 145 146 PCI_TRACE ("PciHostBridgeEntryPoint()"); 147 148 // Creation of the PCI Host Bridge Instance 149 Status = HostBridgeConstructor (&gpPciHostBridgeInstance, ImageHandle); 150 if (EFI_ERROR (Status)) { 151 PCI_TRACE ("PciHostBridgeEntryPoint(): ERROR: Fail to construct PCI Host Bridge."); 152 return Status; 153 } 154 155 // Creation of the PCIe Root Bridge 156 Status = PciRbConstructor (gpPciHostBridgeInstance, PciRbDescriptions.AcpiUid, PciRbDescriptions.MemAllocAttributes); 157 if (EFI_ERROR (Status)) { 158 PCI_TRACE ("PciHostBridgeEntryPoint(): ERROR: Fail to construct PCI Root Bridge."); 159 return Status; 160 } 161 ASSERT (gpPciHostBridgeInstance->RootBridge->Signature == PCI_ROOT_BRIDGE_SIGNATURE); 162 163 // PCI 32bit Memory Space 164 Status = gDS->AddMemorySpace ( 165 EfiGcdMemoryTypeMemoryMappedIo, 166 PCI_MEM32_BASE, 167 PCI_MEM32_SIZE, 168 0 169 ); 170 171 // PCI 64bit Memory Space 172 Status = gDS->AddMemorySpace ( 173 EfiGcdMemoryTypeMemoryMappedIo, 174 PCI_MEM64_BASE, 175 PCI_MEM64_SIZE, 176 0 177 ); 178 179 return EFI_SUCCESS; 180 } 181 182 EFI_STATUS 183 EFIAPI 184 PciHostBridgeUnload ( 185 IN EFI_HANDLE ImageHandle 186 ) 187 { 188 EFI_STATUS Status; 189 190 // Free Reserved memory space in GCD 191 gDS->RemoveMemorySpace (PCI_MEM32_BASE, PCI_MEM32_SIZE); 192 gDS->RemoveMemorySpace (PCI_MEM64_BASE, PCI_MEM64_SIZE); 193 194 // Free the allocated memory 195 Status = HostBridgeDestructor (gpPciHostBridgeInstance); 196 ASSERT_EFI_ERROR (Status); 197 198 return Status; 199 } 200