1 /** @file 2 OVMF's instance of the PCI Host Bridge Library. 3 4 Copyright (C) 2016, Red Hat, Inc. 5 Copyright (c) 2016, Intel Corporation. All rights reserved.<BR> 6 7 This program and the accompanying materials are licensed and made available 8 under the terms and conditions of the BSD License which accompanies this 9 distribution. The full text of the license may be found at 10 http://opensource.org/licenses/bsd-license.php. 11 12 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT 13 WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 14 15 **/ 16 #include <PiDxe.h> 17 18 #include <IndustryStandard/Pci.h> 19 #include <IndustryStandard/Q35MchIch9.h> 20 21 #include <Protocol/PciHostBridgeResourceAllocation.h> 22 #include <Protocol/PciRootBridgeIo.h> 23 24 #include <Library/BaseMemoryLib.h> 25 #include <Library/DebugLib.h> 26 #include <Library/DevicePathLib.h> 27 #include <Library/MemoryAllocationLib.h> 28 #include <Library/PciHostBridgeLib.h> 29 #include <Library/PciLib.h> 30 #include <Library/QemuFwCfgLib.h> 31 #include "PciHostBridge.h" 32 33 34 #pragma pack(1) 35 typedef struct { 36 ACPI_HID_DEVICE_PATH AcpiDevicePath; 37 EFI_DEVICE_PATH_PROTOCOL EndDevicePath; 38 } OVMF_PCI_ROOT_BRIDGE_DEVICE_PATH; 39 #pragma pack () 40 41 42 GLOBAL_REMOVE_IF_UNREFERENCED 43 CHAR16 *mPciHostBridgeLibAcpiAddressSpaceTypeStr[] = { 44 L"Mem", L"I/O", L"Bus" 45 }; 46 47 48 STATIC 49 CONST 50 OVMF_PCI_ROOT_BRIDGE_DEVICE_PATH mRootBridgeDevicePathTemplate = { 51 { 52 { 53 ACPI_DEVICE_PATH, 54 ACPI_DP, 55 { 56 (UINT8) (sizeof(ACPI_HID_DEVICE_PATH)), 57 (UINT8) ((sizeof(ACPI_HID_DEVICE_PATH)) >> 8) 58 } 59 }, 60 EISA_PNP_ID(0x0A03), // HID 61 0 // UID 62 }, 63 64 { 65 END_DEVICE_PATH_TYPE, 66 END_ENTIRE_DEVICE_PATH_SUBTYPE, 67 { 68 END_DEVICE_PATH_LENGTH, 69 0 70 } 71 } 72 }; 73 74 STATIC PCI_ROOT_BRIDGE_APERTURE mNonExistAperture = { MAX_UINT64, 0 }; 75 76 /** 77 Initialize a PCI_ROOT_BRIDGE structure. 78 79 @param[in] Supports Supported attributes. 80 81 @param[in] Attributes Initial attributes. 82 83 @param[in] AllocAttributes Allocation attributes. 84 85 @param[in] RootBusNumber The bus number to store in RootBus. 86 87 @param[in] MaxSubBusNumber The inclusive maximum bus number that can be 88 assigned to any subordinate bus found behind any 89 PCI bridge hanging off this root bus. 90 91 The caller is repsonsible for ensuring that 92 RootBusNumber <= MaxSubBusNumber. If 93 RootBusNumber equals MaxSubBusNumber, then the 94 root bus has no room for subordinate buses. 95 96 @param[in] Io IO aperture. 97 98 @param[in] Mem MMIO aperture. 99 100 @param[in] MemAbove4G MMIO aperture above 4G. 101 102 @param[in] PMem Prefetchable MMIO aperture. 103 104 @param[in] PMemAbove4G Prefetchable MMIO aperture above 4G. 105 106 @param[out] RootBus The PCI_ROOT_BRIDGE structure (allocated by the 107 caller) that should be filled in by this 108 function. 109 110 @retval EFI_SUCCESS Initialization successful. A device path 111 consisting of an ACPI device path node, with 112 UID = RootBusNumber, has been allocated and 113 linked into RootBus. 114 115 @retval EFI_OUT_OF_RESOURCES Memory allocation failed. 116 **/ 117 EFI_STATUS 118 InitRootBridge ( 119 IN UINT64 Supports, 120 IN UINT64 Attributes, 121 IN UINT64 AllocAttributes, 122 IN UINT8 RootBusNumber, 123 IN UINT8 MaxSubBusNumber, 124 IN PCI_ROOT_BRIDGE_APERTURE *Io, 125 IN PCI_ROOT_BRIDGE_APERTURE *Mem, 126 IN PCI_ROOT_BRIDGE_APERTURE *MemAbove4G, 127 IN PCI_ROOT_BRIDGE_APERTURE *PMem, 128 IN PCI_ROOT_BRIDGE_APERTURE *PMemAbove4G, 129 OUT PCI_ROOT_BRIDGE *RootBus 130 ) 131 { 132 OVMF_PCI_ROOT_BRIDGE_DEVICE_PATH *DevicePath; 133 134 // 135 // Be safe if other fields are added to PCI_ROOT_BRIDGE later. 136 // 137 ZeroMem (RootBus, sizeof *RootBus); 138 139 RootBus->Segment = 0; 140 141 RootBus->Supports = Supports; 142 RootBus->Attributes = Attributes; 143 144 RootBus->DmaAbove4G = FALSE; 145 146 RootBus->AllocationAttributes = AllocAttributes; 147 RootBus->Bus.Base = RootBusNumber; 148 RootBus->Bus.Limit = MaxSubBusNumber; 149 CopyMem (&RootBus->Io, Io, sizeof (*Io)); 150 CopyMem (&RootBus->Mem, Mem, sizeof (*Mem)); 151 CopyMem (&RootBus->MemAbove4G, MemAbove4G, sizeof (*MemAbove4G)); 152 CopyMem (&RootBus->PMem, PMem, sizeof (*PMem)); 153 CopyMem (&RootBus->PMemAbove4G, PMemAbove4G, sizeof (*PMemAbove4G)); 154 155 RootBus->NoExtendedConfigSpace = (PcdGet16 (PcdOvmfHostBridgePciDevId) != 156 INTEL_Q35_MCH_DEVICE_ID); 157 158 DevicePath = AllocateCopyPool (sizeof mRootBridgeDevicePathTemplate, 159 &mRootBridgeDevicePathTemplate); 160 if (DevicePath == NULL) { 161 DEBUG ((EFI_D_ERROR, "%a: %r\n", __FUNCTION__, EFI_OUT_OF_RESOURCES)); 162 return EFI_OUT_OF_RESOURCES; 163 } 164 DevicePath->AcpiDevicePath.UID = RootBusNumber; 165 RootBus->DevicePath = (EFI_DEVICE_PATH_PROTOCOL *)DevicePath; 166 167 DEBUG ((EFI_D_INFO, 168 "%a: populated root bus %d, with room for %d subordinate bus(es)\n", 169 __FUNCTION__, RootBusNumber, MaxSubBusNumber - RootBusNumber)); 170 return EFI_SUCCESS; 171 } 172 173 174 /** 175 Uninitialize a PCI_ROOT_BRIDGE structure set up with InitRootBridge(). 176 177 param[in] RootBus The PCI_ROOT_BRIDGE structure, allocated by the caller and 178 initialized with InitRootBridge(), that should be 179 uninitialized. This function doesn't free RootBus. 180 **/ 181 STATIC 182 VOID 183 UninitRootBridge ( 184 IN PCI_ROOT_BRIDGE *RootBus 185 ) 186 { 187 FreePool (RootBus->DevicePath); 188 } 189 190 191 /** 192 Return all the root bridge instances in an array. 193 194 @param Count Return the count of root bridge instances. 195 196 @return All the root bridge instances in an array. 197 The array should be passed into PciHostBridgeFreeRootBridges() 198 when it's not used. 199 **/ 200 PCI_ROOT_BRIDGE * 201 EFIAPI 202 PciHostBridgeGetRootBridges ( 203 UINTN *Count 204 ) 205 { 206 EFI_STATUS Status; 207 FIRMWARE_CONFIG_ITEM FwCfgItem; 208 UINTN FwCfgSize; 209 UINT64 ExtraRootBridges; 210 PCI_ROOT_BRIDGE *Bridges; 211 UINTN Initialized; 212 UINTN LastRootBridgeNumber; 213 UINTN RootBridgeNumber; 214 UINT64 Attributes; 215 UINT64 AllocationAttributes; 216 PCI_ROOT_BRIDGE_APERTURE Io; 217 PCI_ROOT_BRIDGE_APERTURE Mem; 218 PCI_ROOT_BRIDGE_APERTURE MemAbove4G; 219 220 if (PcdGetBool (PcdPciDisableBusEnumeration)) { 221 return ScanForRootBridges (Count); 222 } 223 224 Attributes = EFI_PCI_ATTRIBUTE_IDE_PRIMARY_IO | 225 EFI_PCI_ATTRIBUTE_IDE_SECONDARY_IO | 226 EFI_PCI_ATTRIBUTE_ISA_IO_16 | 227 EFI_PCI_ATTRIBUTE_ISA_MOTHERBOARD_IO | 228 EFI_PCI_ATTRIBUTE_VGA_MEMORY | 229 EFI_PCI_ATTRIBUTE_VGA_IO_16 | 230 EFI_PCI_ATTRIBUTE_VGA_PALETTE_IO_16; 231 232 AllocationAttributes = EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM; 233 if (PcdGet64 (PcdPciMmio64Size) > 0) { 234 AllocationAttributes |= EFI_PCI_HOST_BRIDGE_MEM64_DECODE; 235 MemAbove4G.Base = PcdGet64 (PcdPciMmio64Base); 236 MemAbove4G.Limit = PcdGet64 (PcdPciMmio64Base) + 237 PcdGet64 (PcdPciMmio64Size) - 1; 238 } else { 239 CopyMem (&MemAbove4G, &mNonExistAperture, sizeof (mNonExistAperture)); 240 } 241 242 Io.Base = PcdGet64 (PcdPciIoBase); 243 Io.Limit = PcdGet64 (PcdPciIoBase) + (PcdGet64 (PcdPciIoSize) - 1); 244 Mem.Base = PcdGet64 (PcdPciMmio32Base); 245 Mem.Limit = PcdGet64 (PcdPciMmio32Base) + (PcdGet64 (PcdPciMmio32Size) - 1); 246 247 *Count = 0; 248 249 // 250 // QEMU provides the number of extra root buses, shortening the exhaustive 251 // search below. If there is no hint, the feature is missing. 252 // 253 Status = QemuFwCfgFindFile ("etc/extra-pci-roots", &FwCfgItem, &FwCfgSize); 254 if (EFI_ERROR (Status) || FwCfgSize != sizeof ExtraRootBridges) { 255 ExtraRootBridges = 0; 256 } else { 257 QemuFwCfgSelectItem (FwCfgItem); 258 QemuFwCfgReadBytes (FwCfgSize, &ExtraRootBridges); 259 260 if (ExtraRootBridges > PCI_MAX_BUS) { 261 DEBUG ((EFI_D_ERROR, "%a: invalid count of extra root buses (%Lu) " 262 "reported by QEMU\n", __FUNCTION__, ExtraRootBridges)); 263 return NULL; 264 } 265 DEBUG ((EFI_D_INFO, "%a: %Lu extra root buses reported by QEMU\n", 266 __FUNCTION__, ExtraRootBridges)); 267 } 268 269 // 270 // Allocate the "main" root bridge, and any extra root bridges. 271 // 272 Bridges = AllocatePool ((1 + (UINTN)ExtraRootBridges) * sizeof *Bridges); 273 if (Bridges == NULL) { 274 DEBUG ((EFI_D_ERROR, "%a: %r\n", __FUNCTION__, EFI_OUT_OF_RESOURCES)); 275 return NULL; 276 } 277 Initialized = 0; 278 279 // 280 // The "main" root bus is always there. 281 // 282 LastRootBridgeNumber = 0; 283 284 // 285 // Scan all other root buses. If function 0 of any device on a bus returns a 286 // VendorId register value different from all-bits-one, then that bus is 287 // alive. 288 // 289 for (RootBridgeNumber = 1; 290 RootBridgeNumber <= PCI_MAX_BUS && Initialized < ExtraRootBridges; 291 ++RootBridgeNumber) { 292 UINTN Device; 293 294 for (Device = 0; Device <= PCI_MAX_DEVICE; ++Device) { 295 if (PciRead16 (PCI_LIB_ADDRESS (RootBridgeNumber, Device, 0, 296 PCI_VENDOR_ID_OFFSET)) != MAX_UINT16) { 297 break; 298 } 299 } 300 if (Device <= PCI_MAX_DEVICE) { 301 // 302 // Found the next root bus. We can now install the *previous* one, 303 // because now we know how big a bus number range *that* one has, for any 304 // subordinate buses that might exist behind PCI bridges hanging off it. 305 // 306 Status = InitRootBridge ( 307 Attributes, 308 Attributes, 309 AllocationAttributes, 310 (UINT8) LastRootBridgeNumber, 311 (UINT8) (RootBridgeNumber - 1), 312 &Io, 313 &Mem, 314 &MemAbove4G, 315 &mNonExistAperture, 316 &mNonExistAperture, 317 &Bridges[Initialized] 318 ); 319 if (EFI_ERROR (Status)) { 320 goto FreeBridges; 321 } 322 ++Initialized; 323 LastRootBridgeNumber = RootBridgeNumber; 324 } 325 } 326 327 // 328 // Install the last root bus (which might be the only, ie. main, root bus, if 329 // we've found no extra root buses). 330 // 331 Status = InitRootBridge ( 332 Attributes, 333 Attributes, 334 AllocationAttributes, 335 (UINT8) LastRootBridgeNumber, 336 PCI_MAX_BUS, 337 &Io, 338 &Mem, 339 &MemAbove4G, 340 &mNonExistAperture, 341 &mNonExistAperture, 342 &Bridges[Initialized] 343 ); 344 if (EFI_ERROR (Status)) { 345 goto FreeBridges; 346 } 347 ++Initialized; 348 349 *Count = Initialized; 350 return Bridges; 351 352 FreeBridges: 353 while (Initialized > 0) { 354 --Initialized; 355 UninitRootBridge (&Bridges[Initialized]); 356 } 357 358 FreePool (Bridges); 359 return NULL; 360 } 361 362 363 /** 364 Free the root bridge instances array returned from 365 PciHostBridgeGetRootBridges(). 366 367 @param The root bridge instances array. 368 @param The count of the array. 369 **/ 370 VOID 371 EFIAPI 372 PciHostBridgeFreeRootBridges ( 373 PCI_ROOT_BRIDGE *Bridges, 374 UINTN Count 375 ) 376 { 377 if (Bridges == NULL && Count == 0) { 378 return; 379 } 380 ASSERT (Bridges != NULL && Count > 0); 381 382 do { 383 --Count; 384 UninitRootBridge (&Bridges[Count]); 385 } while (Count > 0); 386 387 FreePool (Bridges); 388 } 389 390 391 /** 392 Inform the platform that the resource conflict happens. 393 394 @param HostBridgeHandle Handle of the Host Bridge. 395 @param Configuration Pointer to PCI I/O and PCI memory resource 396 descriptors. The Configuration contains the resources 397 for all the root bridges. The resource for each root 398 bridge is terminated with END descriptor and an 399 additional END is appended indicating the end of the 400 entire resources. The resource descriptor field 401 values follow the description in 402 EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL 403 .SubmitResources(). 404 **/ 405 VOID 406 EFIAPI 407 PciHostBridgeResourceConflict ( 408 EFI_HANDLE HostBridgeHandle, 409 VOID *Configuration 410 ) 411 { 412 EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Descriptor; 413 UINTN RootBridgeIndex; 414 DEBUG ((EFI_D_ERROR, "PciHostBridge: Resource conflict happens!\n")); 415 416 RootBridgeIndex = 0; 417 Descriptor = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) Configuration; 418 while (Descriptor->Desc == ACPI_ADDRESS_SPACE_DESCRIPTOR) { 419 DEBUG ((EFI_D_ERROR, "RootBridge[%d]:\n", RootBridgeIndex++)); 420 for (; Descriptor->Desc == ACPI_ADDRESS_SPACE_DESCRIPTOR; Descriptor++) { 421 ASSERT (Descriptor->ResType < 422 ARRAY_SIZE (mPciHostBridgeLibAcpiAddressSpaceTypeStr) 423 ); 424 DEBUG ((EFI_D_ERROR, " %s: Length/Alignment = 0x%lx / 0x%lx\n", 425 mPciHostBridgeLibAcpiAddressSpaceTypeStr[Descriptor->ResType], 426 Descriptor->AddrLen, Descriptor->AddrRangeMax 427 )); 428 if (Descriptor->ResType == ACPI_ADDRESS_SPACE_TYPE_MEM) { 429 DEBUG ((EFI_D_ERROR, " Granularity/SpecificFlag = %ld / %02x%s\n", 430 Descriptor->AddrSpaceGranularity, Descriptor->SpecificFlag, 431 ((Descriptor->SpecificFlag & 432 EFI_ACPI_MEMORY_RESOURCE_SPECIFIC_FLAG_CACHEABLE_PREFETCHABLE 433 ) != 0) ? L" (Prefetchable)" : L"" 434 )); 435 } 436 } 437 // 438 // Skip the END descriptor for root bridge 439 // 440 ASSERT (Descriptor->Desc == ACPI_END_TAG_DESCRIPTOR); 441 Descriptor = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)( 442 (EFI_ACPI_END_TAG_DESCRIPTOR *)Descriptor + 1 443 ); 444 } 445 } 446