X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=OvmfPkg%2FLibrary%2FPciHostBridgeLib%2FPciHostBridgeLib.c;h=65d0ef9252c55d09ca475de041c8e53b1a6d2825;hb=e33305ea6c6a7c9946ca4ec60aa270764a91ab8f;hp=25746dd1cfd0c2040a47221478fd21d62d506a8a;hpb=dc4d64670a19d4f813e8f3dc7231998615404511;p=mirror_edk2.git diff --git a/OvmfPkg/Library/PciHostBridgeLib/PciHostBridgeLib.c b/OvmfPkg/Library/PciHostBridgeLib/PciHostBridgeLib.c index 25746dd1cf..65d0ef9252 100644 --- a/OvmfPkg/Library/PciHostBridgeLib/PciHostBridgeLib.c +++ b/OvmfPkg/Library/PciHostBridgeLib/PciHostBridgeLib.c @@ -16,12 +16,27 @@ #include #include +#include +#include +#include + +#include #include +#include #include #include #include #include +#include "PciHostBridge.h" + + +#pragma pack(1) +typedef struct { + ACPI_HID_DEVICE_PATH AcpiDevicePath; + EFI_DEVICE_PATH_PROTOCOL EndDevicePath; +} OVMF_PCI_ROOT_BRIDGE_DEVICE_PATH; +#pragma pack () GLOBAL_REMOVE_IF_UNREFERENCED @@ -30,12 +45,46 @@ CHAR16 *mPciHostBridgeLibAcpiAddressSpaceTypeStr[] = { }; +STATIC +CONST +OVMF_PCI_ROOT_BRIDGE_DEVICE_PATH mRootBridgeDevicePathTemplate = { + { + { + ACPI_DEVICE_PATH, + ACPI_DP, + { + (UINT8) (sizeof(ACPI_HID_DEVICE_PATH)), + (UINT8) ((sizeof(ACPI_HID_DEVICE_PATH)) >> 8) + } + }, + EISA_PNP_ID(0x0A03), // HID + 0 // UID + }, + + { + END_DEVICE_PATH_TYPE, + END_ENTIRE_DEVICE_PATH_SUBTYPE, + { + END_DEVICE_PATH_LENGTH, + 0 + } + } +}; + +STATIC PCI_ROOT_BRIDGE_APERTURE mNonExistAperture = { MAX_UINT64, 0 }; + /** Initialize a PCI_ROOT_BRIDGE structure. - param[in] RootBusNumber The bus number to store in RootBus. + @param[in] Supports Supported attributes. + + @param[in] Attributes Initial attributes. + + @param[in] AllocAttributes Allocation attributes. - param[in] MaxSubBusNumber The inclusive maximum bus number that can be + @param[in] RootBusNumber The bus number to store in RootBus. + + @param[in] MaxSubBusNumber The inclusive maximum bus number that can be assigned to any subordinate bus found behind any PCI bridge hanging off this root bus. @@ -44,7 +93,17 @@ CHAR16 *mPciHostBridgeLibAcpiAddressSpaceTypeStr[] = { RootBusNumber equals MaxSubBusNumber, then the root bus has no room for subordinate buses. - param[out] RootBus The PCI_ROOT_BRIDGE structure (allocated by the + @param[in] Io IO aperture. + + @param[in] Mem MMIO aperture. + + @param[in] MemAbove4G MMIO aperture above 4G. + + @param[in] PMem Prefetchable MMIO aperture. + + @param[in] PMemAbove4G Prefetchable MMIO aperture above 4G. + + @param[out] RootBus The PCI_ROOT_BRIDGE structure (allocated by the caller) that should be filled in by this function. @@ -55,15 +114,60 @@ CHAR16 *mPciHostBridgeLibAcpiAddressSpaceTypeStr[] = { @retval EFI_OUT_OF_RESOURCES Memory allocation failed. **/ -STATIC EFI_STATUS InitRootBridge ( - IN UINT8 RootBusNumber, - IN UINT8 MaxSubBusNumber, - OUT PCI_ROOT_BRIDGE *RootBus + IN UINT64 Supports, + IN UINT64 Attributes, + IN UINT64 AllocAttributes, + IN UINT8 RootBusNumber, + IN UINT8 MaxSubBusNumber, + IN PCI_ROOT_BRIDGE_APERTURE *Io, + IN PCI_ROOT_BRIDGE_APERTURE *Mem, + IN PCI_ROOT_BRIDGE_APERTURE *MemAbove4G, + IN PCI_ROOT_BRIDGE_APERTURE *PMem, + IN PCI_ROOT_BRIDGE_APERTURE *PMemAbove4G, + OUT PCI_ROOT_BRIDGE *RootBus ) { - return EFI_OUT_OF_RESOURCES; + OVMF_PCI_ROOT_BRIDGE_DEVICE_PATH *DevicePath; + + // + // Be safe if other fields are added to PCI_ROOT_BRIDGE later. + // + ZeroMem (RootBus, sizeof *RootBus); + + RootBus->Segment = 0; + + RootBus->Supports = Supports; + RootBus->Attributes = Attributes; + + RootBus->DmaAbove4G = FALSE; + + RootBus->AllocationAttributes = AllocAttributes; + RootBus->Bus.Base = RootBusNumber; + RootBus->Bus.Limit = MaxSubBusNumber; + CopyMem (&RootBus->Io, Io, sizeof (*Io)); + CopyMem (&RootBus->Mem, Mem, sizeof (*Mem)); + CopyMem (&RootBus->MemAbove4G, MemAbove4G, sizeof (*MemAbove4G)); + CopyMem (&RootBus->PMem, PMem, sizeof (*PMem)); + CopyMem (&RootBus->PMemAbove4G, PMemAbove4G, sizeof (*PMemAbove4G)); + + RootBus->NoExtendedConfigSpace = (PcdGet16 (PcdOvmfHostBridgePciDevId) != + INTEL_Q35_MCH_DEVICE_ID); + + DevicePath = AllocateCopyPool (sizeof mRootBridgeDevicePathTemplate, + &mRootBridgeDevicePathTemplate); + if (DevicePath == NULL) { + DEBUG ((EFI_D_ERROR, "%a: %r\n", __FUNCTION__, EFI_OUT_OF_RESOURCES)); + return EFI_OUT_OF_RESOURCES; + } + DevicePath->AcpiDevicePath.UID = RootBusNumber; + RootBus->DevicePath = (EFI_DEVICE_PATH_PROTOCOL *)DevicePath; + + DEBUG ((EFI_D_INFO, + "%a: populated root bus %d, with room for %d subordinate bus(es)\n", + __FUNCTION__, RootBusNumber, MaxSubBusNumber - RootBusNumber)); + return EFI_SUCCESS; } @@ -80,6 +184,7 @@ UninitRootBridge ( IN PCI_ROOT_BRIDGE *RootBus ) { + FreePool (RootBus->DevicePath); } @@ -106,6 +211,42 @@ PciHostBridgeGetRootBridges ( UINTN Initialized; UINTN LastRootBridgeNumber; UINTN RootBridgeNumber; + UINT64 Attributes; + UINT64 AllocationAttributes; + PCI_ROOT_BRIDGE_APERTURE Io; + PCI_ROOT_BRIDGE_APERTURE Mem; + PCI_ROOT_BRIDGE_APERTURE MemAbove4G; + + if (PcdGetBool (PcdPciDisableBusEnumeration)) { + return ScanForRootBridges (Count); + } + + ZeroMem (&Io, sizeof (Io)); + ZeroMem (&Mem, sizeof (Mem)); + ZeroMem (&MemAbove4G, sizeof (MemAbove4G)); + + Attributes = EFI_PCI_ATTRIBUTE_IDE_PRIMARY_IO | + EFI_PCI_ATTRIBUTE_IDE_SECONDARY_IO | + EFI_PCI_ATTRIBUTE_ISA_IO_16 | + EFI_PCI_ATTRIBUTE_ISA_MOTHERBOARD_IO | + EFI_PCI_ATTRIBUTE_VGA_MEMORY | + EFI_PCI_ATTRIBUTE_VGA_IO_16 | + EFI_PCI_ATTRIBUTE_VGA_PALETTE_IO_16; + + AllocationAttributes = EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM; + if (PcdGet64 (PcdPciMmio64Size) > 0) { + AllocationAttributes |= EFI_PCI_HOST_BRIDGE_MEM64_DECODE; + MemAbove4G.Base = PcdGet64 (PcdPciMmio64Base); + MemAbove4G.Limit = PcdGet64 (PcdPciMmio64Base) + + PcdGet64 (PcdPciMmio64Size) - 1; + } else { + CopyMem (&MemAbove4G, &mNonExistAperture, sizeof (mNonExistAperture)); + } + + Io.Base = PcdGet64 (PcdPciIoBase); + Io.Limit = PcdGet64 (PcdPciIoBase) + (PcdGet64 (PcdPciIoSize) - 1); + Mem.Base = PcdGet64 (PcdPciMmio32Base); + Mem.Limit = PcdGet64 (PcdPciMmio32Base) + (PcdGet64 (PcdPciMmio32Size) - 1); *Count = 0; @@ -166,8 +307,19 @@ PciHostBridgeGetRootBridges ( // because now we know how big a bus number range *that* one has, for any // subordinate buses that might exist behind PCI bridges hanging off it. // - Status = InitRootBridge ((UINT8)LastRootBridgeNumber, - (UINT8)(RootBridgeNumber - 1), &Bridges[Initialized]); + Status = InitRootBridge ( + Attributes, + Attributes, + AllocationAttributes, + (UINT8) LastRootBridgeNumber, + (UINT8) (RootBridgeNumber - 1), + &Io, + &Mem, + &MemAbove4G, + &mNonExistAperture, + &mNonExistAperture, + &Bridges[Initialized] + ); if (EFI_ERROR (Status)) { goto FreeBridges; } @@ -180,8 +332,19 @@ PciHostBridgeGetRootBridges ( // Install the last root bus (which might be the only, ie. main, root bus, if // we've found no extra root buses). // - Status = InitRootBridge ((UINT8)LastRootBridgeNumber, PCI_MAX_BUS, - &Bridges[Initialized]); + Status = InitRootBridge ( + Attributes, + Attributes, + AllocationAttributes, + (UINT8) LastRootBridgeNumber, + PCI_MAX_BUS, + &Io, + &Mem, + &MemAbove4G, + &mNonExistAperture, + &mNonExistAperture, + &Bridges[Initialized] + ); if (EFI_ERROR (Status)) { goto FreeBridges; } @@ -260,9 +423,7 @@ PciHostBridgeResourceConflict ( DEBUG ((EFI_D_ERROR, "RootBridge[%d]:\n", RootBridgeIndex++)); for (; Descriptor->Desc == ACPI_ADDRESS_SPACE_DESCRIPTOR; Descriptor++) { ASSERT (Descriptor->ResType < - (sizeof (mPciHostBridgeLibAcpiAddressSpaceTypeStr) / - sizeof (mPciHostBridgeLibAcpiAddressSpaceTypeStr[0]) - ) + ARRAY_SIZE (mPciHostBridgeLibAcpiAddressSpaceTypeStr) ); DEBUG ((EFI_D_ERROR, " %s: Length/Alignment = 0x%lx / 0x%lx\n", mPciHostBridgeLibAcpiAddressSpaceTypeStr[Descriptor->ResType],