-#include <PiDxe.h>\r
-\r
-#include <IndustryStandard/Pci.h>\r
-#include <IndustryStandard/Q35MchIch9.h>\r
-\r
-#include <Protocol/PciHostBridgeResourceAllocation.h>\r
-#include <Protocol/PciRootBridgeIo.h>\r
-\r
-#include <Library/BaseMemoryLib.h>\r
-#include <Library/DebugLib.h>\r
-#include <Library/DevicePathLib.h>\r
-#include <Library/MemoryAllocationLib.h>\r
-#include <Library/PciHostBridgeLib.h>\r
-#include <Library/PciLib.h>\r
-#include <Library/QemuFwCfgLib.h>\r
-\r
-\r
-#pragma pack(1)\r
-typedef struct {\r
- ACPI_HID_DEVICE_PATH AcpiDevicePath;\r
- EFI_DEVICE_PATH_PROTOCOL EndDevicePath;\r
-} OVMF_PCI_ROOT_BRIDGE_DEVICE_PATH;\r
-#pragma pack ()\r
-\r
-\r
-GLOBAL_REMOVE_IF_UNREFERENCED\r
-CHAR16 *mPciHostBridgeLibAcpiAddressSpaceTypeStr[] = {\r
- L"Mem", L"I/O", L"Bus"\r
-};\r
-\r
-\r
-STATIC\r
-CONST\r
-OVMF_PCI_ROOT_BRIDGE_DEVICE_PATH mRootBridgeDevicePathTemplate = {\r
- {\r
- {\r
- ACPI_DEVICE_PATH,\r
- ACPI_DP,\r
- {\r
- (UINT8) (sizeof(ACPI_HID_DEVICE_PATH)),\r
- (UINT8) ((sizeof(ACPI_HID_DEVICE_PATH)) >> 8)\r
- }\r
- },\r
- EISA_PNP_ID(0x0A03), // HID\r
- 0 // UID\r
- },\r
-\r
- {\r
- END_DEVICE_PATH_TYPE,\r
- END_ENTIRE_DEVICE_PATH_SUBTYPE,\r
- {\r
- END_DEVICE_PATH_LENGTH,\r
- 0\r
- }\r
- }\r
-};\r
-\r
-STATIC PCI_ROOT_BRIDGE_APERTURE mNonExistAperture = { MAX_UINT64, 0 };\r
-\r
-/**\r
- Initialize a PCI_ROOT_BRIDGE structure.\r
-\r
- @param[in] Supports Supported attributes.\r
-\r
- @param[in] Attributes Initial attributes.\r
-\r
- @param[in] AllocAttributes Allocation attributes.\r
-\r
- @param[in] RootBusNumber The bus number to store in RootBus.\r
-\r
- @param[in] MaxSubBusNumber The inclusive maximum bus number that can be\r
- assigned to any subordinate bus found behind any\r
- PCI bridge hanging off this root bus.\r
-\r
- The caller is repsonsible for ensuring that\r
- RootBusNumber <= MaxSubBusNumber. If\r
- RootBusNumber equals MaxSubBusNumber, then the\r
- root bus has no room for subordinate buses.\r
-\r
- @param[in] Io IO aperture.\r
-\r
- @param[in] Mem MMIO aperture.\r
-\r
- @param[in] MemAbove4G MMIO aperture above 4G.\r
-\r
- @param[in] PMem Prefetchable MMIO aperture.\r
-\r
- @param[in] PMemAbove4G Prefetchable MMIO aperture above 4G.\r
-\r
- @param[out] RootBus The PCI_ROOT_BRIDGE structure (allocated by the\r
- caller) that should be filled in by this\r
- function.\r
-\r
- @retval EFI_SUCCESS Initialization successful. A device path\r
- consisting of an ACPI device path node, with\r
- UID = RootBusNumber, has been allocated and\r
- linked into RootBus.\r
-\r
- @retval EFI_OUT_OF_RESOURCES Memory allocation failed.\r
-**/\r
-STATIC\r
-EFI_STATUS\r
-InitRootBridge (\r
- IN UINT64 Supports,\r
- IN UINT64 Attributes,\r
- IN UINT64 AllocAttributes,\r
- IN UINT8 RootBusNumber,\r
- IN UINT8 MaxSubBusNumber,\r
- IN PCI_ROOT_BRIDGE_APERTURE *Io,\r
- IN PCI_ROOT_BRIDGE_APERTURE *Mem,\r
- IN PCI_ROOT_BRIDGE_APERTURE *MemAbove4G,\r
- IN PCI_ROOT_BRIDGE_APERTURE *PMem,\r
- IN PCI_ROOT_BRIDGE_APERTURE *PMemAbove4G,\r
- OUT PCI_ROOT_BRIDGE *RootBus\r
- )\r
-{\r
- OVMF_PCI_ROOT_BRIDGE_DEVICE_PATH *DevicePath;\r
-\r
- //\r
- // Be safe if other fields are added to PCI_ROOT_BRIDGE later.\r
- //\r
- ZeroMem (RootBus, sizeof *RootBus);\r
-\r
- RootBus->Segment = 0;\r
-\r
- RootBus->Supports = Supports;\r
- RootBus->Attributes = Attributes;\r
-\r
- RootBus->DmaAbove4G = FALSE;\r
-\r
- RootBus->AllocationAttributes = AllocAttributes;\r
- RootBus->Bus.Base = RootBusNumber;\r
- RootBus->Bus.Limit = MaxSubBusNumber;\r
- CopyMem (&RootBus->Io, Io, sizeof (*Io));\r
- CopyMem (&RootBus->Mem, Mem, sizeof (*Mem));\r
- CopyMem (&RootBus->MemAbove4G, MemAbove4G, sizeof (*MemAbove4G));\r
- CopyMem (&RootBus->PMem, PMem, sizeof (*PMem));\r
- CopyMem (&RootBus->PMemAbove4G, PMemAbove4G, sizeof (*PMemAbove4G));\r
-\r
- RootBus->NoExtendedConfigSpace = (PcdGet16 (PcdOvmfHostBridgePciDevId) !=\r
- INTEL_Q35_MCH_DEVICE_ID);\r
-\r
- DevicePath = AllocateCopyPool (sizeof mRootBridgeDevicePathTemplate,\r
- &mRootBridgeDevicePathTemplate);\r
- if (DevicePath == NULL) {\r
- DEBUG ((EFI_D_ERROR, "%a: %r\n", __FUNCTION__, EFI_OUT_OF_RESOURCES));\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
- DevicePath->AcpiDevicePath.UID = RootBusNumber;\r
- RootBus->DevicePath = (EFI_DEVICE_PATH_PROTOCOL *)DevicePath;\r
-\r
- DEBUG ((EFI_D_INFO,\r
- "%a: populated root bus %d, with room for %d subordinate bus(es)\n",\r
- __FUNCTION__, RootBusNumber, MaxSubBusNumber - RootBusNumber));\r
- return EFI_SUCCESS;\r
-}\r
-\r
-\r
-/**\r
- Uninitialize a PCI_ROOT_BRIDGE structure set up with InitRootBridge().\r
-\r
- param[in] RootBus The PCI_ROOT_BRIDGE structure, allocated by the caller and\r
- initialized with InitRootBridge(), that should be\r
- uninitialized. This function doesn't free RootBus.\r
-**/\r
-STATIC\r
-VOID\r
-UninitRootBridge (\r
- IN PCI_ROOT_BRIDGE *RootBus\r
- )\r
-{\r
- FreePool (RootBus->DevicePath);\r
-}\r