From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mga11.intel.com (mga11.intel.com [192.55.52.93]) by mx.groups.io with SMTP id smtpd.web12.8357.1634818299883453680 for ; Thu, 21 Oct 2021 05:11:39 -0700 Authentication-Results: mx.groups.io; dkim=missing; spf=pass (domain: intel.com, ip: 192.55.52.93, mailfrom: w.sheng@intel.com) X-IronPort-AV: E=McAfee;i="6200,9189,10143"; a="226475910" X-IronPort-AV: E=Sophos;i="5.87,169,1631602800"; d="scan'208";a="226475910" Received: from orsmga008.jf.intel.com ([10.7.209.65]) by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 21 Oct 2021 05:11:37 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.87,169,1631602800"; d="scan'208";a="495123953" Received: from shwdesssddpdwei.ccr.corp.intel.com ([10.239.157.43]) by orsmga008.jf.intel.com with ESMTP; 21 Oct 2021 05:11:34 -0700 From: "Sheng Wei" To: devel@edk2.groups.io Cc: Robert Kowalewski , Jenny Huang , Ray Ni , Rangasai V Chaganty , Albecki Mateusz , Kolakowski Jacek Subject: [PATCH v3] IntelSiliconPkg/IntelVTdDxe: Support Multi PCI Root Bus Date: Thu, 21 Oct 2021 20:11:29 +0800 Message-Id: <20211021121129.16184-1-w.sheng@intel.com> X-Mailer: git-send-email 2.16.2.windows.1 Some system may has multi PCI root bus. It needs to use PciRootBridgeIo protocol to get the root bus count. Scan each root bus to get all devices. REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3695 Signed-off-by: Robert Kowalewski Signed-off-by: Sheng Wei Cc: Jenny Huang Cc: Ray Ni Cc: Rangasai V Chaganty Cc: Robert Kowalewski Cc: Albecki Mateusz Cc: Kolakowski Jacek --- .../Feature/VTd/IntelVTdDxe/DmaProtection.h | 17 +++++ .../Feature/VTd/IntelVTdDxe/DmarAcpiTable.c | 2 +- .../Feature/VTd/IntelVTdDxe/IntelVTdDxe.inf | 1 + .../Feature/VTd/IntelVTdDxe/PciInfo.c | 72 ++++++++++++++++++++++ 4 files changed, 91 insertions(+), 1 deletion(-) diff --git a/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/DmaProtection.h b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/DmaProtection.h index a24fbc37..7dd29a24 100644 --- a/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/DmaProtection.h +++ b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/DmaProtection.h @@ -33,6 +33,7 @@ #include #include #include +#include #include #include @@ -341,6 +342,22 @@ ScanPciBus ( IN SCAN_BUS_FUNC_CALLBACK_FUNC Callback ); +/** + Scan PCI bus and invoke callback function for each PCI devices under all root bus. + + @param[in] Context The context of the callback function. + @param[in] Segment The segment of the source. + @param[in] Callback The callback function in PCI scan. + + @retval EFI_SUCCESS The PCI devices under the bus are scaned. +**/ +EFI_STATUS +ScanAllPciBus ( + IN VOID *Context, + IN UINT16 Segment, + IN SCAN_BUS_FUNC_CALLBACK_FUNC Callback + ); + /** Dump the PCI device information managed by this VTd engine. diff --git a/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/DmarAcpiTable.c b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/DmarAcpiTable.c index 2d9b4374..1ee290b7 100644 --- a/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/DmarAcpiTable.c +++ b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/DmarAcpiTable.c @@ -692,7 +692,7 @@ ProcessDhrd ( mVtdUnitInformation[VtdIndex].PciDeviceInfo.IncludeAllFlag = TRUE; DEBUG ((DEBUG_INFO," ProcessDhrd: with INCLUDE ALL\n")); - Status = ScanPciBus((VOID *)VtdIndex, DmarDrhd->SegmentNumber, 0, ScanBusCallbackRegisterPciDevice); + Status = ScanAllPciBus((VOID *)VtdIndex, DmarDrhd->SegmentNumber, ScanBusCallbackRegisterPciDevice); if (EFI_ERROR (Status)) { return Status; } diff --git a/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/IntelVTdDxe.inf b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/IntelVTdDxe.inf index 220636ad..387f90e3 100644 --- a/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/IntelVTdDxe.inf +++ b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/IntelVTdDxe.inf @@ -70,6 +70,7 @@ gEfiPciIoProtocolGuid ## CONSUMES gEfiPciEnumerationCompleteProtocolGuid ## CONSUMES gEdkiiPlatformVTdPolicyProtocolGuid ## SOMETIMES_CONSUMES + gEfiPciRootBridgeIoProtocolGuid ## CONSUMES [Pcd] gIntelSiliconPkgTokenSpaceGuid.PcdVTdPolicyPropertyMask ## CONSUMES diff --git a/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/PciInfo.c b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/PciInfo.c index 4af376b3..cffb9f61 100644 --- a/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/PciInfo.c +++ b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/PciInfo.c @@ -279,6 +279,78 @@ ScanPciBus ( return EFI_SUCCESS; } +/** + Scan PCI bus and invoke callback function for each PCI devices under all root bus. + + @param[in] Context The context of the callback function. + @param[in] Segment The segment of the source. + @param[in] Callback The callback function in PCI scan. + + @retval EFI_SUCCESS The PCI devices under the bus are scaned. +**/ +EFI_STATUS +ScanAllPciBus ( + IN VOID *Context, + IN UINT16 Segment, + IN SCAN_BUS_FUNC_CALLBACK_FUNC Callback + ) +{ + EFI_STATUS Status; + UINTN Index; + UINTN HandleCount; + EFI_HANDLE *HandleBuffer; + EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo; + EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Descriptors; + + DEBUG ((DEBUG_INFO, "ScanAllPciBus ()\n")); + + Status = gBS->LocateHandleBuffer ( + ByProtocol, + &gEfiPciRootBridgeIoProtocolGuid, + NULL, + &HandleCount, + &HandleBuffer + ); + if (EFI_ERROR (Status)) { + // + // If PciRootBridgeIo protocol is not support, scan PCI device from root bus 0x00. + // + Status = ScanPciBus(Context, Segment, 0x00, Callback); + return Status; + } + + DEBUG ((DEBUG_INFO,"Find %d root bridges\n", HandleCount)); + + for (Index = 0; Index < HandleCount; Index++) { + Status = gBS->HandleProtocol ( + HandleBuffer[Index], + &gEfiPciRootBridgeIoProtocolGuid, + (VOID **) &PciRootBridgeIo + ); + ASSERT_EFI_ERROR (Status); + + Status = PciRootBridgeIo->Configuration (PciRootBridgeIo, (VOID **) &Descriptors); + ASSERT_EFI_ERROR (Status); + + while (Descriptors->Desc != ACPI_END_TAG_DESCRIPTOR) { + if (Descriptors->ResType == ACPI_ADDRESS_SPACE_TYPE_BUS) { + break; + } + Descriptors++; + } + + DEBUG ((DEBUG_INFO,"Scan root bridges : %d, Segment : %d, Bus : 0x%02X\n", Index, PciRootBridgeIo->SegmentNumber, Descriptors->AddrRangeMin)); + Status = ScanPciBus(Context, (UINT16) PciRootBridgeIo->SegmentNumber, (UINT8) Descriptors->AddrRangeMin, Callback); + if (EFI_ERROR (Status)) { + break; + } + } + + FreePool(HandleBuffer); + + return Status; +} + /** Dump the PCI device information managed by this VTd engine. -- 2.16.2.windows.1