From nobody Sat Apr 27 15:17:16 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) client-ip=66.175.222.108; envelope-from=bounce+27952+84786+1787277+3901457@groups.io; helo=mail02.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+84786+1787277+3901457@groups.io; dmarc=fail(p=none dis=none) header.from=intel.com ARC-Seal: i=1; a=rsa-sha256; t=1639460146; cv=none; d=zohomail.com; s=zohoarc; b=FoCz1cmO1hJQxCd136qRun+Ww2xLiX56XGEfAjxLOAIfkCtHFNLkzIVr0BqxcNTfdZ1UDV7n3e6/yUi943n9Esr26eq7yp3IbYkGFw9y55rMayMETvhVQPcJebYv4VOe4svI5aw/7fekfKNRT2KdwTQ9ynonLKwhNzH1Zvj2Zqw= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1639460146; h=Cc:Date:From:In-Reply-To:List-Subscribe:List-Id:List-Help:List-Unsubscribe:Message-ID:Reply-To:References:Sender:Subject:To; bh=71+ziOyQeKYz0+FNHImmEJ5PjRDE7prcRNS3o7S9gwU=; b=IMMvZN9uOOAW2H6YtuSbh3YW1Bxar22P+Tc+dQbMhDFPEh8R/zQqvWaKoyuSjXtK89rpu9qVEflqLt+qUPoOqzlwI7flCS6+Y5M6m8zlhrHPYdXWU+cfzbxcx5BUHlS6h5IRuVTprjg3CUp2A0XEBpBrmxvNCnm3IAugAvUdiSw= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+84786+1787277+3901457@groups.io; dmarc=fail header.from= (p=none dis=none) Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 1639460146759488.81121805271766; Mon, 13 Dec 2021 21:35:46 -0800 (PST) Return-Path: X-Received: by 127.0.0.2 with SMTP id 8MwSYY1788612xZI4TSlkzh1; Mon, 13 Dec 2021 21:35:46 -0800 X-Received: from mga01.intel.com (mga01.intel.com [192.55.52.88]) by mx.groups.io with SMTP id smtpd.web08.22205.1639460143699577345 for ; Mon, 13 Dec 2021 21:35:45 -0800 X-IronPort-AV: E=McAfee;i="6200,9189,10197"; a="263039429" X-IronPort-AV: E=Sophos;i="5.88,204,1635231600"; d="scan'208";a="263039429" X-Received: from orsmga005.jf.intel.com ([10.7.209.41]) by fmsmga101.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 13 Dec 2021 21:35:44 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.88,204,1635231600"; d="scan'208";a="681919864" X-Received: from shwdesssddpdwei.ccr.corp.intel.com ([10.239.157.43]) by orsmga005.jf.intel.com with ESMTP; 13 Dec 2021 21:35:42 -0800 From: "Sheng Wei" To: devel@edk2.groups.io Cc: Ray Ni , Rangasai V Chaganty , Jenny Huang , Robert Kowalewski Subject: [edk2-devel] [PATCH v3 1/4] IntelSiliconPkg/VTd: Fix typos Date: Tue, 14 Dec 2021 13:35:35 +0800 Message-Id: <20211214053538.2828-2-w.sheng@intel.com> In-Reply-To: <20211214053538.2828-1-w.sheng@intel.com> References: <20211214053538.2828-1-w.sheng@intel.com> Precedence: Bulk List-Unsubscribe: List-Subscribe: List-Help: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,w.sheng@intel.com X-Gm-Message-State: kz4ihuOYXgX3V4cpY0CJ5aOZx1787277AA= DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1639460146; bh=C0KE00MiJg2U6lKsShpGYWQu0IVfqdiLWrpbpoQE5jw=; h=Cc:Date:From:Reply-To:Subject:To; b=Ddh9sGWxOEFOAGJXJZG08NfVmR+199NzsZcsbBkwAg67hpBXEmMoCntrRPPKiMKP9LU tr/UZ81sRhyRg0BgMtLbz1eZnsTtJ1Kk6LhqfpVn2ctjLw2arLQ1aPmsFj7mL5ZkZEQMA tlbcznRS1gSgszzgddD+C44hmIiO7yQuGmk= X-ZohoMail-DKIM: pass (identity @groups.io) X-ZM-MESSAGEID: 1639460148234100002 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" It is DRHD(DMA Remapping Hardware Unit Definition). REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3D3622 Cc: Ray Ni Cc: Rangasai V Chaganty Cc: Jenny Huang Cc: Robert Kowalewski Signed-off-by: Sheng Wei --- .../IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/DmarTable.c | 12 ++++++--= ---- .../IntelSiliconPkg/Feature/VTd/IntelVTdDxe/DmarAcpiTable.c | 12 ++++++--= ---- .../IntelSiliconPkg/Feature/VTd/IntelVTdPmrPei/DmarTable.c | 6 +++--- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/Dmar= Table.c b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/DmarTab= le.c index 2154690d..e9c99d0a 100644 --- a/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/DmarTable.c +++ b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/DmarTable.c @@ -539,14 +539,14 @@ RegisterPciDevice ( } =20 /** - Process DMAR DHRD table. + Process DMAR DRHD table. =20 @param[in] VTdUnitInfo The VTd engine unit information. @param[in] DmarDrhd The DRHD table. =20 **/ VOID -ProcessDhrd ( +ProcessDrhd ( IN VTD_UNIT_INFO *VTdUnitInfo, IN EFI_ACPI_DMAR_DRHD_HEADER *DmarDrhd ) @@ -581,10 +581,10 @@ ProcessDhrd ( =20 if ((DmarDrhd->Flags & EFI_ACPI_DMAR_DRHD_FLAGS_INCLUDE_PCI_ALL) !=3D 0)= { VTdUnitInfo->PciDeviceInfo.IncludeAllFlag =3D TRUE; - DEBUG ((DEBUG_INFO," ProcessDhrd: with INCLUDE ALL\n")); + DEBUG ((DEBUG_INFO," ProcessDrhd: with INCLUDE ALL\n")); } else { VTdUnitInfo->PciDeviceInfo.IncludeAllFlag =3D FALSE; - DEBUG ((DEBUG_INFO," ProcessDhrd: without INCLUDE ALL\n")); + DEBUG ((DEBUG_INFO," ProcessDrhd: without INCLUDE ALL\n")); } =20 VTdUnitInfo->PciDeviceInfo.PciDeviceDataNumber =3D 0; @@ -600,7 +600,7 @@ ProcessDhrd ( return; } =20 - DEBUG ((DEBUG_INFO," ProcessDhrd: ")); + DEBUG ((DEBUG_INFO," ProcessDrhd: ")); switch (DmarDevScopeEntry->Type) { case EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_ENDPOINT: DEBUG ((DEBUG_INFO,"PCI Endpoint")); @@ -708,7 +708,7 @@ ParseDmarAcpiTableDrhd ( switch (DmarHeader->Type) { case EFI_ACPI_DMAR_TYPE_DRHD: ASSERT (VtdIndex < VtdUnitNumber); - ProcessDhrd (&VTdInfo->VtdUnitInfo[VtdIndex], (EFI_ACPI_DMAR_DRHD_HE= ADER *) DmarHeader); + ProcessDrhd (&VTdInfo->VtdUnitInfo[VtdIndex], (EFI_ACPI_DMAR_DRHD_HE= ADER *) DmarHeader); VtdIndex++; =20 break; diff --git a/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/DmarAcpi= Table.c b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/DmarAcpiTab= le.c index 1ee290b7..75fbd53e 100644 --- a/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/DmarAcpiTable.c +++ b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/DmarAcpiTable.c @@ -662,7 +662,7 @@ GetPciBusDeviceFunction ( } =20 /** - Process DMAR DHRD table. + Process DMAR DRHD table. =20 @param[in] VtdIndex The index of VTd engine. @param[in] DmarDrhd The DRHD table. @@ -670,7 +670,7 @@ GetPciBusDeviceFunction ( @retval EFI_SUCCESS The DRHD table is processed. **/ EFI_STATUS -ProcessDhrd ( +ProcessDrhd ( IN UINTN VtdIndex, IN EFI_ACPI_DMAR_DRHD_HEADER *DmarDrhd ) @@ -690,7 +690,7 @@ ProcessDhrd ( =20 if ((DmarDrhd->Flags & EFI_ACPI_DMAR_DRHD_FLAGS_INCLUDE_PCI_ALL) !=3D 0)= { mVtdUnitInformation[VtdIndex].PciDeviceInfo.IncludeAllFlag =3D TRUE; - DEBUG ((DEBUG_INFO," ProcessDhrd: with INCLUDE ALL\n")); + DEBUG ((DEBUG_INFO," ProcessDrhd: with INCLUDE ALL\n")); =20 Status =3D ScanAllPciBus((VOID *)VtdIndex, DmarDrhd->SegmentNumber, Sc= anBusCallbackRegisterPciDevice); if (EFI_ERROR (Status)) { @@ -698,7 +698,7 @@ ProcessDhrd ( } } else { mVtdUnitInformation[VtdIndex].PciDeviceInfo.IncludeAllFlag =3D FALSE; - DEBUG ((DEBUG_INFO," ProcessDhrd: without INCLUDE ALL\n")); + DEBUG ((DEBUG_INFO," ProcessDrhd: without INCLUDE ALL\n")); } =20 DmarDevScopeEntry =3D (EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER *)((U= INTN)(DmarDrhd + 1)); @@ -709,7 +709,7 @@ ProcessDhrd ( return Status; } =20 - DEBUG ((DEBUG_INFO," ProcessDhrd: ")); + DEBUG ((DEBUG_INFO," ProcessDrhd: ")); switch (DmarDevScopeEntry->Type) { case EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_ENDPOINT: DEBUG ((DEBUG_INFO,"PCI Endpoint")); @@ -877,7 +877,7 @@ ParseDmarAcpiTableDrhd ( switch (DmarHeader->Type) { case EFI_ACPI_DMAR_TYPE_DRHD: ASSERT (VtdIndex < mVtdUnitNumber); - Status =3D ProcessDhrd (VtdIndex, (EFI_ACPI_DMAR_DRHD_HEADER *)DmarH= eader); + Status =3D ProcessDrhd (VtdIndex, (EFI_ACPI_DMAR_DRHD_HEADER *)DmarH= eader); if (EFI_ERROR (Status)) { return Status; } diff --git a/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdPmrPei/DmarT= able.c b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdPmrPei/DmarTable= .c index d920d136..1bb74f40 100644 --- a/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdPmrPei/DmarTable.c +++ b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdPmrPei/DmarTable.c @@ -356,14 +356,14 @@ GetVtdEngineNumber ( } =20 /** - Process DMAR DHRD table. + Process DMAR DRHD table. =20 @param[in] VTdInfo The VTd engine context information. @param[in] VtdIndex The index of VTd engine. @param[in] DmarDrhd The DRHD table. **/ VOID -ProcessDhrd ( +ProcessDrhd ( IN VTD_INFO *VTdInfo, IN UINTN VtdIndex, IN EFI_ACPI_DMAR_DRHD_HEADER *DmarDrhd @@ -415,7 +415,7 @@ ParseDmarAcpiTableDrhd ( switch (DmarHeader->Type) { case EFI_ACPI_DMAR_TYPE_DRHD: ASSERT (VtdIndex < VtdUnitNumber); - ProcessDhrd (VTdInfo, VtdIndex, (EFI_ACPI_DMAR_DRHD_HEADER *)DmarHea= der); + ProcessDrhd (VTdInfo, VtdIndex, (EFI_ACPI_DMAR_DRHD_HEADER *)DmarHea= der); VtdIndex++; =20 break; --=20 2.16.2.windows.1 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#84786): https://edk2.groups.io/g/devel/message/84786 Mute This Topic: https://groups.io/mt/87715955/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- From nobody Sat Apr 27 15:17:16 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) client-ip=66.175.222.108; envelope-from=bounce+27952+84787+1787277+3901457@groups.io; helo=mail02.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+84787+1787277+3901457@groups.io; dmarc=fail(p=none dis=none) header.from=intel.com ARC-Seal: i=1; a=rsa-sha256; t=1639460148; cv=none; d=zohomail.com; s=zohoarc; b=ipVOo5cTmXpko5EaahyfuZ5fL8YW6blQ6b4a5mfs7Jv1FXv3FIn76Wsadg/hHwO/cdgpRom5Q5TEeqYO1j7j7xwDzfJQ9z7aKi+BiCv+o2xpjqOCyn3oovQv6V7UUIO/Rq39dXDBAPJkjVfSiJ0FGTqSbXlNzTLq3CtLqUhNyt8= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1639460148; h=Cc:Date:From:In-Reply-To:List-Subscribe:List-Id:List-Help:List-Unsubscribe:Message-ID:Reply-To:References:Sender:Subject:To; bh=c4i7BIciSEtNsg1/RsPV1OxsgTr2xIDg6yQLWBmQ1GY=; b=kp3nZPXzNQgXkTBe0veTiRycP3KepdWHExWvEwNZpzox1qVhC/aTYU8nJjVfAfKwpvvS9Ot8GPPloGRYtNOfZCkoky7Hf2b5J26Ld2FT/XOkunObWZJMCWbE3gtZHRXwjOSsuzWDuZ6pjZ4PMYWAydSP1/KK/HXd7KYXKFvKGIQ= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+84787+1787277+3901457@groups.io; dmarc=fail header.from= (p=none dis=none) Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 1639460148212777.8296764247009; Mon, 13 Dec 2021 21:35:48 -0800 (PST) Return-Path: X-Received: by 127.0.0.2 with SMTP id wsQzYY1788612xxglzMANvFn; Mon, 13 Dec 2021 21:35:47 -0800 X-Received: from mga01.intel.com (mga01.intel.com [192.55.52.88]) by mx.groups.io with SMTP id smtpd.web08.22205.1639460143699577345 for ; Mon, 13 Dec 2021 21:35:47 -0800 X-IronPort-AV: E=McAfee;i="6200,9189,10197"; a="263039448" X-IronPort-AV: E=Sophos;i="5.88,204,1635231600"; d="scan'208";a="263039448" X-Received: from orsmga005.jf.intel.com ([10.7.209.41]) by fmsmga101.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 13 Dec 2021 21:35:46 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.88,204,1635231600"; d="scan'208";a="681919870" X-Received: from shwdesssddpdwei.ccr.corp.intel.com ([10.239.157.43]) by orsmga005.jf.intel.com with ESMTP; 13 Dec 2021 21:35:44 -0800 From: "Sheng Wei" To: devel@edk2.groups.io Cc: Ray Ni , Rangasai V Chaganty , Jenny Huang , Robert Kowalewski Subject: [edk2-devel] [PATCH v3 2/4] IntelSiliconPkg/VTd: Update VTd register structs Date: Tue, 14 Dec 2021 13:35:36 +0800 Message-Id: <20211214053538.2828-3-w.sheng@intel.com> In-Reply-To: <20211214053538.2828-1-w.sheng@intel.com> References: <20211214053538.2828-1-w.sheng@intel.com> Precedence: Bulk List-Unsubscribe: List-Subscribe: List-Help: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,w.sheng@intel.com X-Gm-Message-State: UtjMbvfEf34C3lSv8Rsb39P9x1787277AA= DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1639460147; bh=TeiqK6+Yo8PYyaYdXEzmeoBHk+ADTuj16uYntq1kcM4=; h=Cc:Date:From:Reply-To:Subject:To; b=kjpMp9VtM0NEzH9Ofs1iMcf7+iM+KmK9dV4U1L9Okem6v0nahJf6RpxkbhtWsfUreQC 9HtMCogu67FXKBoPRcUG235fCG41K0mdPp5NROKnG7ItbCNkdp493f+VNPLbYvZ3uHx5j Icoe/EjMMMrlFZGKomJSLb9STB25EavlMX0= X-ZohoMail-DKIM: pass (identity @groups.io) X-ZM-MESSAGEID: 1639460150330100005 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Update VTd register structs accroding to VTd spec ver 3.3 REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3D3765 Cc: Ray Ni Cc: Rangasai V Chaganty Cc: Jenny Huang Cc: Robert Kowalewski Signed-off-by: Sheng Wei --- .../Feature/VTd/IntelVTdDmarPei/IntelVTdDmar.c | 3 +- .../Feature/VTd/IntelVTdDmarPei/TranslationTable.c | 23 +++++++++++---- .../Feature/VTd/IntelVTdDxe/TranslationTable.c | 22 ++++++++++++-- .../Feature/VTd/IntelVTdDxe/VtdReg.c | 6 ++-- .../IntelSiliconPkg/Include/IndustryStandard/Vtd.h | 34 +++++++++++++++++-= ---- 5 files changed, 67 insertions(+), 21 deletions(-) diff --git a/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/Inte= lVTdDmar.c b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/Inte= lVTdDmar.c index c3a939c9..87ce9716 100644 --- a/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/IntelVTdDma= r.c +++ b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/IntelVTdDma= r.c @@ -631,10 +631,8 @@ DumpVtdECapRegs ( DEBUG ((DEBUG_INFO, " SC - 0x%x\n", ECapReg->Bits.SC)); DEBUG ((DEBUG_INFO, " IRO - 0x%x\n", ECapReg->Bits.IRO)); DEBUG ((DEBUG_INFO, " MHMV - 0x%x\n", ECapReg->Bits.MHMV)); - DEBUG ((DEBUG_INFO, " ECS - 0x%x\n", ECapReg->Bits.ECS)); DEBUG ((DEBUG_INFO, " MTS - 0x%x\n", ECapReg->Bits.MTS)); DEBUG ((DEBUG_INFO, " NEST - 0x%x\n", ECapReg->Bits.NEST)); - DEBUG ((DEBUG_INFO, " DIS - 0x%x\n", ECapReg->Bits.DIS)); DEBUG ((DEBUG_INFO, " PASID - 0x%x\n", ECapReg->Bits.PASID)); DEBUG ((DEBUG_INFO, " PRS - 0x%x\n", ECapReg->Bits.PRS)); DEBUG ((DEBUG_INFO, " ERS - 0x%x\n", ECapReg->Bits.ERS)); @@ -642,6 +640,7 @@ DumpVtdECapRegs ( DEBUG ((DEBUG_INFO, " NWFS - 0x%x\n", ECapReg->Bits.NWFS)); DEBUG ((DEBUG_INFO, " EAFS - 0x%x\n", ECapReg->Bits.EAFS)); DEBUG ((DEBUG_INFO, " PSS - 0x%x\n", ECapReg->Bits.PSS)); + DEBUG ((DEBUG_INFO, " ADMS - 0x%x\n", ECapReg->Bits.ADMS)); } =20 =20 diff --git a/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/Tran= slationTable.c b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/= TranslationTable.c index 6676b2a9..a309d566 100644 --- a/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/Translation= Table.c +++ b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/Translation= Table.c @@ -884,13 +884,26 @@ SetupTranslationTable ( return Status; } =20 - if (VtdUnitInfo->ECapReg.Bits.ECS) { - DEBUG ((DEBUG_INFO, "CreateExtContextEntry - %d\n", Index)); - Status =3D CreateExtContextEntry (VtdUnitInfo); + if (VtdUnitInfo->ECapReg.Bits.SMTS) { + if (VtdUnitInfo->ECapReg.Bits.DEP_24) { + DEBUG ((DEBUG_ERROR,"ECapReg.bit24 is not zero\n")); + ASSERT(FALSE); + Status =3D EFI_UNSUPPORTED; + } else { + Status =3D CreateExtContextEntry (VtdUnitInfo); + } } else { - DEBUG ((DEBUG_INFO, "CreateContextEntry - %d\n", Index)); - Status =3D CreateContextEntry (VtdUnitInfo); + if (VtdUnitInfo->ECapReg.Bits.DEP_24) { + // + // To compatible with pervious VTd engine + // It was ECS(Extended Context Support) bit. + // + Status =3D CreateExtContextEntry (VtdUnitInfo); + } else { + Status =3D CreateContextEntry (VtdUnitInfo); + } } + if (EFI_ERROR (Status)) { return Status; } diff --git a/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/Translat= ionTable.c b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/Translat= ionTable.c index ca5f65a8..48e38d56 100644 --- a/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/TranslationTabl= e.c +++ b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/TranslationTabl= e.c @@ -382,11 +382,27 @@ SetupTranslationTable ( =20 for (Index =3D 0; Index < mVtdUnitNumber; Index++) { DEBUG((DEBUG_INFO, "CreateContextEntry - %d\n", Index)); - if (mVtdUnitInformation[Index].ECapReg.Bits.ECS) { - Status =3D CreateExtContextEntry (Index); + + if (mVtdUnitInformation[Index].ECapReg.Bits.SMTS) { + if (mVtdUnitInformation[Index].ECapReg.Bits.DEP_24) { + DEBUG ((DEBUG_ERROR,"ECapReg.bit24 is not zero\n")); + ASSERT(FALSE); + Status =3D EFI_UNSUPPORTED; + } else { + Status =3D CreateExtContextEntry (Index); + } } else { - Status =3D CreateContextEntry (Index); + if (mVtdUnitInformation[Index].ECapReg.Bits.DEP_24) { + // + // To compatible with pervious VTd engine + // It was ECS(Extended Context Support) bit. + // + Status =3D CreateExtContextEntry (Index); + } else { + Status =3D CreateContextEntry (Index); + } } + if (EFI_ERROR (Status)) { return Status; } diff --git a/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/VtdReg.c= b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/VtdReg.c index 1ce9c1c0..105911a9 100644 --- a/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/VtdReg.c +++ b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDxe/VtdReg.c @@ -698,10 +698,8 @@ DumpVtdECapRegs ( DEBUG((DEBUG_INFO, " SC - 0x%x\n", ECapReg->Bits.SC)); DEBUG((DEBUG_INFO, " IRO - 0x%x\n", ECapReg->Bits.IRO)); DEBUG((DEBUG_INFO, " MHMV - 0x%x\n", ECapReg->Bits.MHMV)); - DEBUG((DEBUG_INFO, " ECS - 0x%x\n", ECapReg->Bits.ECS)); DEBUG((DEBUG_INFO, " MTS - 0x%x\n", ECapReg->Bits.MTS)); DEBUG((DEBUG_INFO, " NEST - 0x%x\n", ECapReg->Bits.NEST)); - DEBUG((DEBUG_INFO, " DIS - 0x%x\n", ECapReg->Bits.DIS)); DEBUG((DEBUG_INFO, " PASID - 0x%x\n", ECapReg->Bits.PASID)); DEBUG((DEBUG_INFO, " PRS - 0x%x\n", ECapReg->Bits.PRS)); DEBUG((DEBUG_INFO, " ERS - 0x%x\n", ECapReg->Bits.ERS)); @@ -709,6 +707,8 @@ DumpVtdECapRegs ( DEBUG((DEBUG_INFO, " NWFS - 0x%x\n", ECapReg->Bits.NWFS)); DEBUG((DEBUG_INFO, " EAFS - 0x%x\n", ECapReg->Bits.EAFS)); DEBUG((DEBUG_INFO, " PSS - 0x%x\n", ECapReg->Bits.PSS)); + DEBUG((DEBUG_INFO, " SMTS - 0x%x\n", ECapReg->Bits.SMTS)); + DEBUG((DEBUG_INFO, " ADMS - 0x%x\n", ECapReg->Bits.ADMS)); } =20 /** @@ -771,7 +771,7 @@ DumpVtdRegs ( DEBUG((DEBUG_INFO, " Fault Info - 0x%016lx\n", VTD_64BITS_ADDRESS= (FrcdReg.Bits.FILo, FrcdReg.Bits.FIHi))); SourceId.Uint16 =3D (UINT16)FrcdReg.Bits.SID; DEBUG((DEBUG_INFO, " Source - B%02x D%02x F%02x\n", SourceId.Bits= .Bus, SourceId.Bits.Device, SourceId.Bits.Function)); - DEBUG((DEBUG_INFO, " Type - %x (%a)\n", FrcdReg.Bits.T, FrcdReg.B= its.T ? "read" : "write")); + DEBUG((DEBUG_INFO, " Type - 0x%02x\n", (FrcdReg.Bits.T1 << 1) | F= rcdReg.Bits.T2)); DEBUG((DEBUG_INFO, " Reason - %x (Refer to VTd Spec, Appendix A)\= n", FrcdReg.Bits.FR)); } } diff --git a/Silicon/Intel/IntelSiliconPkg/Include/IndustryStandard/Vtd.h b= /Silicon/Intel/IntelSiliconPkg/Include/IndustryStandard/Vtd.h index a759ca10..32fbdd02 100644 --- a/Silicon/Intel/IntelSiliconPkg/Include/IndustryStandard/Vtd.h +++ b/Silicon/Intel/IntelSiliconPkg/Include/IndustryStandard/Vtd.h @@ -216,6 +216,7 @@ typedef union { #define B_GSTS_REG_RTPS BIT30 #define B_GSTS_REG_TE BIT31 #define R_RTADDR_REG 0x20 +#define V_RTADDR_REG_TTM_ADM (BIT11|BIT10) #define R_CCMD_REG 0x28 #define B_CCMD_REG_CIRG_MASK (BIT62|BIT61) #define V_CCMD_REG_CIRG_GLOBAL BIT61 @@ -334,7 +335,10 @@ typedef union { UINT8 FL1GP:1; // First Level 1-GByte Page Support UINT8 Rsvd_57:2; UINT8 PI:1; // Posted Interrupts Support - UINT8 Rsvd_60:4; + UINT8 FL5LP:1; // First Level 5-level Paging Support + UINT8 Rsvd_61:1; + UINT8 ESIRTPS:1; // Enhanced Set Interrupt Remap Table Pointer= Support + UINT8 ESRTPS:1; // Enhanced Set Root Table Pointer Support } Bits; UINT64 Uint64; } VTD_CAP_REG; @@ -346,7 +350,7 @@ typedef union { UINT8 DT:1; // Device-TLB support UINT8 IR:1; // Interrupt Remapping support UINT8 EIM:1; // Extended Interrupt Mode - UINT8 Rsvd_5:1; + UINT8 DEP_5:1; UINT8 PT:1; // Pass Through UINT8 SC:1; // Snoop Control =20 @@ -354,11 +358,11 @@ typedef union { UINT16 Rsvd_18:2; UINT16 MHMV:4; // Maximum Handle Mask Value =20 - UINT8 ECS:1; // Extended Context Support + UINT8 DEP_24:1; UINT8 MTS:1; // Memory Type Support UINT8 NEST:1; // Nested Translation Support - UINT8 DIS:1; // Deferred Invalidate Support - UINT8 PASID:1; // Process Address Space ID Support + UINT8 Rsvd_27:1; + UINT8 DEP_28:1; UINT8 PRS:1; // Page Request Support UINT8 ERS:1; // Execute Request Support UINT8 SRS:1; // Supervisor Request Support @@ -367,7 +371,20 @@ typedef union { UINT32 NWFS:1; // No Write Flag Support UINT32 EAFS:1; // Extended Accessed Flag Support UINT32 PSS:5; // PASID Size Supported - UINT32 Rsvd_40:24; + UINT32 PASID:1; // Process Address Space ID Support + UINT32 DIT:1; // Device-TLB Invalidation Throttle + UINT32 PDS:1; // Page-request Drain Support + UINT32 SMTS:1; // Scalable Mode Translation Support + UINT32 VCS:1; // Virtual Command Support + UINT32 SLADS:1; // Second-Level Accessed Dirty Support + UINT32 SLTS:1; // Second-level Translation Support + UINT32 FLTS:1; // First-level Translation Support + UINT32 SMPWCS:1; // Scalable-Mode Page-walk Coherency Support + UINT32 RPS:1; // RID-PASID Support + UINT32 Rsvd_50:2; + UINT32 ADMS:1; // Abort DMA Mode Support + UINT32 RPRIVS:1; // RID_PRIV Support + UINT32 Rsvd_54:10; } Bits; UINT64 Uint64; } VTD_ECAP_REG; @@ -379,7 +396,8 @@ typedef union { UINT32 FIHi:32; // FaultInfo =20 UINT32 SID:16; // Source Identifier - UINT32 Rsvd_80:13; + UINT32 Rsvd_80:12; + UINT32 T2:1; // Type bit2 (0: Write/Read, 1: Page/AtomicOp) UINT32 PRIV:1; // Privilege Mode Requested UINT32 EXE:1; // Execute Permission Requested UINT32 PP:1; // PASID Present @@ -387,7 +405,7 @@ typedef union { UINT32 FR:8; // Fault Reason UINT32 PV:20; // PASID Value UINT32 AT:2; // Address Type - UINT32 T:1; // Type (0: Write, 1: Read) + UINT32 T1:1; // Type bit1 (0: Write/Page, 1: Read/AtomicOp) UINT32 F:1; // Fault } Bits; UINT64 Uint64[2]; --=20 2.16.2.windows.1 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#84787): https://edk2.groups.io/g/devel/message/84787 Mute This Topic: https://groups.io/mt/87715956/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- From nobody Sat Apr 27 15:17:16 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) client-ip=66.175.222.108; envelope-from=bounce+27952+84788+1787277+3901457@groups.io; helo=mail02.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+84788+1787277+3901457@groups.io; dmarc=fail(p=none dis=none) header.from=intel.com ARC-Seal: i=1; a=rsa-sha256; t=1639460149; cv=none; d=zohomail.com; s=zohoarc; b=nmCNUD3gPHB9yIm2PkR6IB5bvPRWdmTPQ9ILfQzwkHxJMiJNiSrvVxxsOGtoBHqCsnOqytaoTAqbhMQkOQ10myPGYHMxBH3z9MF2jWua9fAeyG73tY6Vr3m/VrQx2ceV0KrK7vY0J65Z2Ot/ALlZemmRLEbtLa9W1xEz3527IZ8= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1639460149; h=Cc:Date:From:In-Reply-To:List-Subscribe:List-Id:List-Help:List-Unsubscribe:Message-ID:Reply-To:References:Sender:Subject:To; bh=QcqwCODJipvXaXeYyQvx7Lpm4wAXsbbyMzojJkKjciE=; b=neNEMBz7lYD7JjewA0zALUNbDlEyLGOzNbkBl9pwoJ2tju7ZA9ANCd5iLLb45iHi8pX8J/vLvukVJtsbEYevbLfv0VXzzoIacd0pCNYjnqPcTHAkCKmfpsa6gPrBiHPKLTN3yHkqh0yTaKxnQ5JS1JhNC+VFk1JbBe7zhZt4mBU= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+84788+1787277+3901457@groups.io; dmarc=fail header.from= (p=none dis=none) Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 1639460149422435.25586199020006; Mon, 13 Dec 2021 21:35:49 -0800 (PST) Return-Path: X-Received: by 127.0.0.2 with SMTP id QWPcYY1788612xNwrscfWHlB; Mon, 13 Dec 2021 21:35:49 -0800 X-Received: from mga01.intel.com (mga01.intel.com [192.55.52.88]) by mx.groups.io with SMTP id smtpd.web08.22205.1639460143699577345 for ; Mon, 13 Dec 2021 21:35:48 -0800 X-IronPort-AV: E=McAfee;i="6200,9189,10197"; a="263039467" X-IronPort-AV: E=Sophos;i="5.88,204,1635231600"; d="scan'208";a="263039467" X-Received: from orsmga005.jf.intel.com ([10.7.209.41]) by fmsmga101.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 13 Dec 2021 21:35:48 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.88,204,1635231600"; d="scan'208";a="681919874" X-Received: from shwdesssddpdwei.ccr.corp.intel.com ([10.239.157.43]) by orsmga005.jf.intel.com with ESMTP; 13 Dec 2021 21:35:46 -0800 From: "Sheng Wei" To: devel@edk2.groups.io Cc: Ray Ni , Rangasai V Chaganty , Jenny Huang , Robert Kowalewski Subject: [edk2-devel] [PATCH v3 3/4] IntelSiliconPkg/VTd: Support VTd Abort DMA Mode Date: Tue, 14 Dec 2021 13:35:37 +0800 Message-Id: <20211214053538.2828-4-w.sheng@intel.com> In-Reply-To: <20211214053538.2828-1-w.sheng@intel.com> References: <20211214053538.2828-1-w.sheng@intel.com> Precedence: Bulk List-Unsubscribe: List-Subscribe: List-Help: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,w.sheng@intel.com X-Gm-Message-State: yxsNBqZvFPKJeCLc7gek08UQx1787277AA= DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1639460149; bh=dwpzaYehOp2UCX7yOa4umJIvom8OdQZnBHotL1Aqxvg=; h=Cc:Date:From:Reply-To:Subject:To; b=VHFN8sehggzSY/VBdqbAvM2r8bv+iPd8qMI5rSXPnesdrNu1GV0oMAk3E1FA2GbfUv5 +K2ywnHA2MXkYHTpZHAPVx3OMK3s3ZwvEu8dN0CahVIKeS/1OROxB4yTG8I26uDlpd8YR 8nrRtg4sYedYapi6xfvZwl9+QU6L8+Hvf+0= X-ZohoMail-DKIM: pass (identity @groups.io) X-ZM-MESSAGEID: 1639460150409100008 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" If VTd ECAP_REG.ADMS bit is set, abort DMA mode is supported. When VTd Abort DMA Mode is enabled, hardware will abort all DMA operations without the need to set up a root-table with each entry marked as not-present. REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3D3766 Cc: Ray Ni Cc: Rangasai V Chaganty Cc: Jenny Huang Cc: Robert Kowalewski Signed-off-by: Sheng Wei --- .../Feature/VTd/IntelVTdDmarPei/IntelVTdDmar.c | 43 +++++++++++++-----= ---- 1 file changed, 26 insertions(+), 17 deletions(-) diff --git a/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/Inte= lVTdDmar.c b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/Inte= lVTdDmar.c index 87ce9716..63397a1a 100644 --- a/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/IntelVTdDma= r.c +++ b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/IntelVTdDma= r.c @@ -384,7 +384,7 @@ InvalidateIOTLB ( Enable DMAR translation inpre-mem phase. =20 @param[in] VtdUnitBaseAddress The base address of the VTd engine. - @param[in] RootEntryTable The address of the VTd RootEntryTable. + @param[in] RtaddrRegValue The value of RTADDR_REG. =20 @retval EFI_SUCCESS DMAR translation is enabled. @retval EFI_DEVICE_ERROR DMAR translation is not enabled. @@ -392,15 +392,15 @@ InvalidateIOTLB ( EFI_STATUS EnableDmarPreMem ( IN UINTN VtdUnitBaseAddress, - IN UINTN RootEntryTable + IN UINTN RtaddrRegValue ) { UINT32 Reg32; =20 DEBUG ((DEBUG_INFO, ">>>>>>EnableDmarPreMem() for engine [%x] \n", VtdUn= itBaseAddress)); =20 - DEBUG ((DEBUG_INFO, "RootEntryTable 0x%x \n", RootEntryTable)); - MmioWrite64 (VtdUnitBaseAddress + R_RTADDR_REG, (UINT64) (UINTN) RootEnt= ryTable); + DEBUG ((DEBUG_INFO, "RTADDR_REG : 0x%x \n", RtaddrRegValue)); + MmioWrite64 (VtdUnitBaseAddress + R_RTADDR_REG, (UINT64) RtaddrRegValue); =20 Reg32 =3D MmioRead32 (VtdUnitBaseAddress + R_GSTS_REG); MmioWrite32 (VtdUnitBaseAddress + R_GCMD_REG, Reg32 | B_GMCD_REG_SRTP); @@ -662,18 +662,6 @@ EnableVTdTranslationProtectionAll ( =20 DEBUG ((DEBUG_INFO, "EnableVTdTranslationProtectionAll - 0x%lx\n", Engin= eMask)); =20 - Status =3D PeiServicesLocatePpi ( - &gEdkiiVTdNullRootEntryTableGuid, - 0, - NULL, - (VOID **)&RootEntryTable - ); - if (EFI_ERROR(Status)) { - DEBUG ((DEBUG_ERROR, "Locate Null Root Entry Table Ppi Failed : %r\n",= Status)); - ASSERT (FALSE); - return; - } - for (Index =3D 0; Index < VTdInfo->VTdEngineCount; Index++) { if ((EngineMask & LShiftU64(1, Index)) =3D=3D 0) { continue; @@ -686,7 +674,28 @@ EnableVTdTranslationProtectionAll ( VTdInfo->VtdUnitInfo[Index].ECapReg.Uint64 =3D MmioRead64 (VTdInfo->Vt= dUnitInfo[Index].VtdUnitBaseAddress + R_ECAP_REG); DumpVtdECapRegs (&VTdInfo->VtdUnitInfo[Index].ECapReg); =20 - EnableDmarPreMem (VTdInfo->VtdUnitInfo[Index].VtdUnitBaseAddress, (UIN= TN) *RootEntryTable); + if (VTdInfo->VtdUnitInfo[Index].ECapReg.Bits.ADMS =3D=3D 1) { + // + // Use Abort DMA Mode + // + Status =3D EnableDmarPreMem (VTdInfo->VtdUnitInfo[Index].VtdUnitBase= Address, V_RTADDR_REG_TTM_ADM); + } else { + // + // Use Null Root Entry Table + // + Status =3D PeiServicesLocatePpi ( + &gEdkiiVTdNullRootEntryTableGuid, + 0, + NULL, + (VOID **)&RootEntryTable + ); + if (EFI_ERROR(Status)) { + DEBUG ((DEBUG_ERROR, "Locate Null Root Entry Table Ppi Failed : %r= \n", Status)); + ASSERT (FALSE); + return; + } + EnableDmarPreMem (VTdInfo->VtdUnitInfo[Index].VtdUnitBaseAddress, (U= INTN) *RootEntryTable); + } } =20 return; --=20 2.16.2.windows.1 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#84788): https://edk2.groups.io/g/devel/message/84788 Mute This Topic: https://groups.io/mt/87715957/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- From nobody Sat Apr 27 15:17:16 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) client-ip=66.175.222.108; envelope-from=bounce+27952+84789+1787277+3901457@groups.io; helo=mail02.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+84789+1787277+3901457@groups.io; dmarc=fail(p=none dis=none) header.from=intel.com ARC-Seal: i=1; a=rsa-sha256; t=1639460152; cv=none; d=zohomail.com; s=zohoarc; b=AifWFP9PjJiiQdClCYE3zpwtnd9KH7Mh5qJFUyx3W6fZouZTXbct+EHqXOGch0BDhbtEMsFS3VdZdBpE5IEW3i315CoHWLwd3xV+itZXTH4rcCvcJ2nYXYmSiTGgUzFWQIE7U8VnCPbINa5NxaDLHOWxaox7GZ0prP9WC0lgyZ4= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1639460152; h=Cc:Date:From:In-Reply-To:List-Subscribe:List-Id:List-Help:List-Unsubscribe:Message-ID:Reply-To:References:Sender:Subject:To; bh=e6eS8c4mD2194Pwtg5GNxMxf/WS3GXfJcu8OcaBCNDc=; b=CNnAhJV/IvurcbPgsKI7wCdR8ZI7xMlUWT/gZW6b1YDs6sCWqUvX8kX41zcxkz7EYM+L7uQM8zQosH+2adllBvc1gmrfj/5KVqhsxx40WxHvN8nRcb1Us/QBdzQqQ+YOx6K7Li/dq1HyZ1Ldn6KrYwWwBAi2iey/laOOKNsgzag= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+84789+1787277+3901457@groups.io; dmarc=fail header.from= (p=none dis=none) Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 1639460152848770.9293135956643; Mon, 13 Dec 2021 21:35:52 -0800 (PST) Return-Path: X-Received: by 127.0.0.2 with SMTP id iCxeYY1788612x6NjS0flqDW; Mon, 13 Dec 2021 21:35:52 -0800 X-Received: from mga01.intel.com (mga01.intel.com [192.55.52.88]) by mx.groups.io with SMTP id smtpd.web08.22205.1639460143699577345 for ; Mon, 13 Dec 2021 21:35:52 -0800 X-IronPort-AV: E=McAfee;i="6200,9189,10197"; a="263039479" X-IronPort-AV: E=Sophos;i="5.88,204,1635231600"; d="scan'208";a="263039479" X-Received: from orsmga005.jf.intel.com ([10.7.209.41]) by fmsmga101.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 13 Dec 2021 21:35:51 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.88,204,1635231600"; d="scan'208";a="681919896" X-Received: from shwdesssddpdwei.ccr.corp.intel.com ([10.239.157.43]) by orsmga005.jf.intel.com with ESMTP; 13 Dec 2021 21:35:48 -0800 From: "Sheng Wei" To: devel@edk2.groups.io Cc: Ray Ni , Rangasai V Chaganty , Jenny Huang , Robert Kowalewski Subject: [edk2-devel] [PATCH v3 4/4] IntelSiliconPkg/VTd: Only generate PEI DMA buffer once. Date: Tue, 14 Dec 2021 13:35:38 +0800 Message-Id: <20211214053538.2828-5-w.sheng@intel.com> In-Reply-To: <20211214053538.2828-1-w.sheng@intel.com> References: <20211214053538.2828-1-w.sheng@intel.com> Precedence: Bulk List-Unsubscribe: List-Subscribe: List-Help: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,w.sheng@intel.com X-Gm-Message-State: KOtCgvPwUOH7G7hJ2nOcT6xVx1787277AA= DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1639460152; bh=MNMn5NOh0GF6n6SYNr4Ik0AWD1fI9i4j52OlRpPODl4=; h=Cc:Date:From:Reply-To:Subject:To; b=sTZOM/5cF9rgIRJxKJD+RpYENYd/OR0eovGZ3v1BmbmH7pdBLMoX/0bvDr00M3CB4NZ vi4zeOaHqVqX8lamrl/nAmnC3ec/aTVt0gpTBdGSl7LIvo43YAEUepIyN68Vx9OFfQIUl WYwqlLTOWhdz+0v/TwPBipyCK6l84AMr0V8= X-ZohoMail-DKIM: pass (identity @groups.io) X-ZM-MESSAGEID: 1639460154790100001 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" VTdInfoNotify may be called manay times, PEI DMA buffer should be generated only once. REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3D3667 Cc: Ray Ni Cc: Rangasai V Chaganty Cc: Jenny Huang Cc: Robert Kowalewski Signed-off-by: Sheng Wei --- .../Feature/VTd/IntelVTdDmarPei/DmarTable.c | 405 +++++----------- .../Feature/VTd/IntelVTdDmarPei/IntelVTdDmar.c | 433 ++++++++---------- .../Feature/VTd/IntelVTdDmarPei/IntelVTdDmarPei.c | 507 ++++++++++++-----= ---- .../Feature/VTd/IntelVTdDmarPei/IntelVTdDmarPei.h | 127 ++++-- .../Feature/VTd/IntelVTdDmarPei/TranslationTable.c | 201 ++++---- 5 files changed, 769 insertions(+), 904 deletions(-) diff --git a/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/Dmar= Table.c b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/DmarTab= le.c index e9c99d0a..31792189 100644 --- a/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/DmarTable.c +++ b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/DmarTable.c @@ -1,6 +1,7 @@ /** @file =20 - Copyright (c) 2020, Intel Corporation. All rights reserved.
+ Copyright (c) 2020 - 2021, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent =20 **/ @@ -413,142 +414,53 @@ GetPciBusDeviceFunction ( } =20 /** - Return the index of PCI data. - - @param[in] VTdUnitInfo The VTd engine unit information. - @param[in] Segment The Segment used to identify a VTd engine. - @param[in] SourceId The SourceId used to identify a VTd engine= and table entry. - - @return The index of the PCI data. - @retval (UINTN)-1 The PCI data is not found. -**/ -UINTN -GetPciDataIndex ( - IN VTD_UNIT_INFO *VTdUnitInfo, - IN UINT16 Segment, - IN VTD_SOURCE_ID SourceId - ) -{ - UINTN Index; - VTD_SOURCE_ID *PciSourceId; - PEI_PCI_DEVICE_DATA *PciDeviceDataBase; - - if (Segment !=3D VTdUnitInfo->Segment) { - return (UINTN)-1; - } - - for (Index =3D 0; Index < VTdUnitInfo->PciDeviceInfo.PciDeviceDataNumber= ; Index++) { - PciDeviceDataBase =3D (PEI_PCI_DEVICE_DATA*) (UINTN) VTdUnitInfo->PciD= eviceInfo.PciDeviceData; - PciSourceId =3D &PciDeviceDataBase[Index].PciSourceId; - if ((PciSourceId->Bits.Bus =3D=3D SourceId.Bits.Bus) && - (PciSourceId->Bits.Device =3D=3D SourceId.Bits.Device) && - (PciSourceId->Bits.Function =3D=3D SourceId.Bits.Function) ) { - return Index; - } - } - - return (UINTN)-1; -} - - -/** - Register PCI device to VTd engine. + Parse DMAR DRHD table. =20 - @param[in] VTdUnitInfo The VTd engine unit information. - @param[in] Segment The segment of the source. - @param[in] SourceId The SourceId of the source. - @param[in] DeviceType The DMAR device scope type. - @param[in] CheckExist TRUE: ERROR will be returned if the PCI de= vice is already registered. - FALSE: SUCCESS will be returned if the PCI= device is registered. + @param[in] AcpiDmarTable DMAR ACPI table + @param[in] Callback Callback function for handle DRHD + @param[in] Context Callback function Context =20 - @retval EFI_SUCCESS The PCI device is registered. - @retval EFI_OUT_OF_RESOURCES No enough resource to register a new PCI d= evice. - @retval EFI_ALREADY_STARTED The device is already registered. + @return EFI_SUCCESS The DMAR DRHD table is parsed. =20 **/ EFI_STATUS -RegisterPciDevice ( - IN VTD_UNIT_INFO *VTdUnitInfo, - IN UINT16 Segment, - IN VTD_SOURCE_ID SourceId, - IN UINT8 DeviceType, - IN BOOLEAN CheckExist +ParseDmarAcpiTableDrhd ( + IN EFI_ACPI_DMAR_HEADER *AcpiDmarTable, + IN PROCESS_DRHD_CALLBACK_FUNC Callback, + IN VOID *Context ) { - PEI_PCI_DEVICE_INFORMATION *PciDeviceInfo; - VTD_SOURCE_ID *PciSourceId; - UINTN PciDataIndex; - UINTN PciDeviceDataSize; - PEI_PCI_DEVICE_DATA *NewPciDeviceData; - PEI_PCI_DEVICE_DATA *PciDeviceDataBase; - - PciDeviceInfo =3D &VTdUnitInfo->PciDeviceInfo; - - PciDataIndex =3D GetPciDataIndex (VTdUnitInfo, Segment, SourceId); - if (PciDataIndex =3D=3D (UINTN)-1) { - // - // Register new - // - - if (PciDeviceInfo->PciDeviceDataNumber >=3D PciDeviceInfo->PciDeviceDa= taMaxNumber) { - // - // Reallocate - // - PciDeviceDataSize =3D sizeof(*NewPciDeviceData) * (PciDeviceInfo->Pc= iDeviceDataMaxNumber + MAX_VTD_PCI_DATA_NUMBER); - DEBUG ((DEBUG_INFO, "New PciDeviceDataSize:%d Page:%d\n", PciDeviceD= ataSize, EFI_SIZE_TO_PAGES (PciDeviceDataSize))); - NewPciDeviceData =3D AllocateZeroPages (EFI_SIZE_TO_PAGES(PciDeviceD= ataSize)); - if (NewPciDeviceData =3D=3D NULL) { - return EFI_OUT_OF_RESOURCES; - } - PciDeviceInfo->PciDeviceDataMaxNumber +=3D MAX_VTD_PCI_DATA_NUMBER; - if (PciDeviceInfo->PciDeviceData !=3D 0) { - CopyMem (NewPciDeviceData, (VOID *) (UINTN) PciDeviceInfo->PciDevi= ceData, sizeof (*NewPciDeviceData) * PciDeviceInfo->PciDeviceDataNumber); - FreePages((VOID *) (UINTN) PciDeviceInfo->PciDeviceData, PciDevice= Info->PciDeviceDataPageSize); - } - PciDeviceInfo->PciDeviceData =3D (UINT32) (UINTN) NewPciDeviceData; - PciDeviceInfo->PciDeviceDataPageSize =3D (UINT32) EFI_SIZE_TO_PAGES = (PciDeviceDataSize); - } - - ASSERT (PciDeviceInfo->PciDeviceDataNumber < PciDeviceInfo->PciDeviceD= ataMaxNumber); - - PciDeviceDataBase =3D (PEI_PCI_DEVICE_DATA *) (UINTN) PciDeviceInfo->P= ciDeviceData; - PciSourceId =3D &PciDeviceDataBase[PciDeviceInfo->PciDeviceDataNumber]= .PciSourceId; - PciSourceId->Bits.Bus =3D SourceId.Bits.Bus; - PciSourceId->Bits.Device =3D SourceId.Bits.Device; - PciSourceId->Bits.Function =3D SourceId.Bits.Function; - - DEBUG ((DEBUG_INFO, " RegisterPciDevice: PCI S%04x B%02x D%02x F%02x"= , Segment, SourceId.Bits.Bus, SourceId.Bits.Device, SourceId.Bits.Function)= ); - - PciDeviceDataBase[PciDeviceInfo->PciDeviceDataNumber].DeviceType =3D D= eviceType; - - if ((DeviceType !=3D EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_ENDPOINT) && - (DeviceType !=3D EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_BRIDGE)) { - DEBUG ((DEBUG_INFO, " (*)")); - } - DEBUG ((DEBUG_INFO, "\n")); + EFI_ACPI_DMAR_STRUCTURE_HEADER *DmarHeader; + UINT32 VtdIndex; =20 - PciDeviceInfo->PciDeviceDataNumber++; - } else { - if (CheckExist) { - DEBUG ((DEBUG_INFO, " RegisterPciDevice: PCI S%04x B%02x D%02x F%02= x already registered\n", Segment, SourceId.Bits.Bus, SourceId.Bits.Device, = SourceId.Bits.Function)); - return EFI_ALREADY_STARTED; + VtdIndex =3D 0; + DmarHeader =3D (EFI_ACPI_DMAR_STRUCTURE_HEADER *) ((UINTN) (AcpiDmarTabl= e + 1)); + while ((UINTN) DmarHeader < (UINTN) AcpiDmarTable + AcpiDmarTable->Heade= r.Length) { + switch (DmarHeader->Type) { + case EFI_ACPI_DMAR_TYPE_DRHD: + Callback (Context, VtdIndex, (EFI_ACPI_DMAR_DRHD_HEADER *) DmarHeade= r); + VtdIndex++; + break; + default: + break; } + DmarHeader =3D (EFI_ACPI_DMAR_STRUCTURE_HEADER *) ((UINTN) DmarHeader = + DmarHeader->Length); } =20 return EFI_SUCCESS; } =20 /** - Process DMAR DRHD table. + Parse DMAR RMRR table to get device number. + + @param[in] DmarRmrr The RMRR table. =20 - @param[in] VTdUnitInfo The VTd engine unit information. - @param[in] DmarDrhd The DRHD table. + @return the device number =20 **/ -VOID -ProcessDrhd ( - IN VTD_UNIT_INFO *VTdUnitInfo, - IN EFI_ACPI_DMAR_DRHD_HEADER *DmarDrhd +UINTN +ProcessRmrrGetDeviceNumber ( + IN EFI_ACPI_DMAR_RMRR_HEADER *DmarRmrr ) { EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER *DmarDevScopeEntry; @@ -556,189 +468,83 @@ ProcessDrhd ( UINT8 Device; UINT8 Function; EFI_STATUS Status; - VTD_SOURCE_ID SourceId; - - DEBUG ((DEBUG_INFO," VTD BaseAddress - 0x%016lx\n", DmarDrhd->Register= BaseAddress)); - VTdUnitInfo->VtdUnitBaseAddress =3D (UINT32) DmarDrhd->RegisterBaseAddre= ss; - - VTdUnitInfo->EnableQueuedInvalidation =3D 0; - - DEBUG ((DEBUG_INFO," VTD Segment - %d\n", DmarDrhd->SegmentNumber)); - VTdUnitInfo->Segment =3D DmarDrhd->SegmentNumber; - - VTdUnitInfo->FixedSecondLevelPagingEntry =3D 0; - VTdUnitInfo->RmrrSecondLevelPagingEntry =3D 0; - VTdUnitInfo->RootEntryTable =3D 0; - VTdUnitInfo->ExtRootEntryTable =3D 0; - VTdUnitInfo->RootEntryTablePageSize =3D 0; - VTdUnitInfo->ExtRootEntryTablePageSize =3D 0; - - VTdUnitInfo->PciDeviceInfo.IncludeAllFlag =3D 0; - VTdUnitInfo->PciDeviceInfo.PciDeviceDataMaxNumber =3D 0; - VTdUnitInfo->PciDeviceInfo.PciDeviceDataNumber =3D 0; - VTdUnitInfo->PciDeviceInfo.PciDeviceDataPageSize =3D 0; - VTdUnitInfo->PciDeviceInfo.PciDeviceData =3D 0; - - if ((DmarDrhd->Flags & EFI_ACPI_DMAR_DRHD_FLAGS_INCLUDE_PCI_ALL) !=3D 0)= { - VTdUnitInfo->PciDeviceInfo.IncludeAllFlag =3D TRUE; - DEBUG ((DEBUG_INFO," ProcessDrhd: with INCLUDE ALL\n")); - } else { - VTdUnitInfo->PciDeviceInfo.IncludeAllFlag =3D FALSE; - DEBUG ((DEBUG_INFO," ProcessDrhd: without INCLUDE ALL\n")); - } + UINTN DeviceNumber; =20 - VTdUnitInfo->PciDeviceInfo.PciDeviceDataNumber =3D 0; - VTdUnitInfo->PciDeviceInfo.PciDeviceDataMaxNumber =3D 0; - VTdUnitInfo->PciDeviceInfo.PciDeviceDataPageSize =3D 0; - VTdUnitInfo->PciDeviceInfo.PciDeviceData =3D 0; + DEBUG ((DEBUG_INFO," PEI RMRR (Base 0x%016lx, Limit 0x%016lx)\n", DmarR= mrr->ReservedMemoryRegionBaseAddress, DmarRmrr->ReservedMemoryRegionLimitAd= dress)); =20 - DmarDevScopeEntry =3D (EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER *) ((= UINTN) (DmarDrhd + 1)); - while ((UINTN)DmarDevScopeEntry < (UINTN) DmarDrhd + DmarDrhd->Header.Le= ngth) { + DeviceNumber =3D 0; =20 - Status =3D GetPciBusDeviceFunction (DmarDrhd->SegmentNumber, DmarDevSc= opeEntry, &Bus, &Device, &Function); - if (EFI_ERROR (Status)) { - return; - } + if ((DmarRmrr->ReservedMemoryRegionBaseAddress =3D=3D 0) || + (DmarRmrr->ReservedMemoryRegionLimitAddress =3D=3D 0)) { + return DeviceNumber; + } =20 - DEBUG ((DEBUG_INFO," ProcessDrhd: ")); - switch (DmarDevScopeEntry->Type) { - case EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_ENDPOINT: - DEBUG ((DEBUG_INFO,"PCI Endpoint")); - break; - case EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_BRIDGE: - DEBUG ((DEBUG_INFO,"PCI-PCI bridge")); - break; - case EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_IOAPIC: - DEBUG ((DEBUG_INFO,"IOAPIC")); - break; - case EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_MSI_CAPABLE_HPET: - DEBUG ((DEBUG_INFO,"MSI Capable HPET")); - break; - case EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_ACPI_NAMESPACE_DEVICE: - DEBUG ((DEBUG_INFO,"ACPI Namespace Device")); - break; + DmarDevScopeEntry =3D (EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER *) ((= UINTN) (DmarRmrr + 1)); + while ((UINTN) DmarDevScopeEntry < (UINTN) DmarRmrr + DmarRmrr->Header.L= ength) { + if (DmarDevScopeEntry->Type !=3D EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_= ENDPOINT) { + DEBUG ((DEBUG_INFO,"RMRR DevScopeEntryType is not endpoint, type[0x%= x] \n", DmarDevScopeEntry->Type)); + return DeviceNumber; } - DEBUG ((DEBUG_INFO," S%04x B%02x D%02x F%02x\n", DmarDrhd->SegmentNumb= er, Bus, Device, Function)); - - SourceId.Bits.Bus =3D Bus; - SourceId.Bits.Device =3D Device; - SourceId.Bits.Function =3D Function; =20 - Status =3D RegisterPciDevice (VTdUnitInfo, DmarDrhd->SegmentNumber, So= urceId, DmarDevScopeEntry->Type, TRUE); + Status =3D GetPciBusDeviceFunction (DmarRmrr->SegmentNumber, DmarDevSc= opeEntry, &Bus, &Device, &Function); if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR,"RegisterPciDevice Failed !\n")); + continue; } =20 - DmarDevScopeEntry =3D (EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER *) = ((UINTN) DmarDevScopeEntry + DmarDevScopeEntry->Length); - } -} - -/** - Dump the PCI device information managed by this VTd engine. - - @param[in] VTdInfo The VTd engine context information. - @param[in] VtdIndex The index of VTd engine. - -**/ -VOID -DumpPciDeviceInfo ( - IN VTD_INFO *VTdInfo, - IN UINTN VtdIndex - ) -{ - UINTN Index; - PEI_PCI_DEVICE_DATA *PciDeviceDataBase; - - DEBUG ((DEBUG_INFO,"PCI Device Information (Number 0x%x, IncludeAll - %d= ):\n", - VTdInfo->VtdUnitInfo[VtdIndex].PciDeviceInfo.PciDeviceDataNumber, - VTdInfo->VtdUnitInfo[VtdIndex].PciDeviceInfo.IncludeAllFlag - )); + DEBUG ((DEBUG_INFO,"RMRR S%04x B%02x D%02x F%02x\n", DmarRmrr->Segment= Number, Bus, Device, Function)); =20 - PciDeviceDataBase =3D (PEI_PCI_DEVICE_DATA *) (UINTN) VTdInfo->VtdUnitIn= fo[VtdIndex].PciDeviceInfo.PciDeviceData; + DeviceNumber++; =20 - for (Index =3D 0; Index < VTdInfo->VtdUnitInfo[VtdIndex].PciDeviceInfo.P= ciDeviceDataNumber; Index++) { - DEBUG ((DEBUG_INFO," S%04x B%02x D%02x F%02x\n", - VTdInfo->VtdUnitInfo[VtdIndex].Segment, - PciDeviceDataBase[Index].PciSourceId.Bits.Bus, - PciDeviceDataBase[Index].PciSourceId.Bits.Device, - PciDeviceDataBase[Index].PciSourceId.Bits.Function - )); + DmarDevScopeEntry =3D (EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER *) = ((UINTN) DmarDevScopeEntry + DmarDevScopeEntry->Length); } + + return DeviceNumber; } =20 /** - Parse DMAR DRHD table. + Get VTd DMAR RMRR device number. =20 @param[in] AcpiDmarTable DMAR ACPI table =20 - @return EFI_SUCCESS The DMAR DRHD table is parsed. - + @return the device number **/ -EFI_STATUS -ParseDmarAcpiTableDrhd ( - IN EFI_ACPI_DMAR_HEADER *AcpiDmarTable +UINTN +GetVtdRmrrDeviceNumber ( + IN EFI_ACPI_DMAR_HEADER *AcpiDmarTable ) { - EFI_ACPI_DMAR_STRUCTURE_HEADER *DmarHeader; - UINTN VtdUnitNumber; - UINTN VtdIndex; - VTD_INFO *VTdInfo; - - VtdUnitNumber =3D GetVtdEngineNumber (AcpiDmarTable); - if (VtdUnitNumber =3D=3D 0) { - return EFI_UNSUPPORTED; - } + UINTN DeviceNumber; + EFI_ACPI_DMAR_STRUCTURE_HEADER *DmarHeader; =20 - VTdInfo =3D BuildGuidHob (&mVTdInfoGuid, sizeof (VTD_INFO) + (VtdUnitNum= ber - 1) * sizeof (VTD_UNIT_INFO)); - ASSERT(VTdInfo !=3D NULL); - if (VTdInfo =3D=3D NULL) { - return EFI_OUT_OF_RESOURCES; - } - - // - // Initialize the engine mask to all. - // - VTdInfo->AcpiDmarTable =3D (UINT32) (UINTN) AcpiDmarTable; - VTdInfo->HostAddressWidth =3D AcpiDmarTable->HostAddressWidth; - VTdInfo->VTdEngineCount =3D (UINT32) VtdUnitNumber; + DeviceNumber =3D 0; =20 - VtdIndex =3D 0; DmarHeader =3D (EFI_ACPI_DMAR_STRUCTURE_HEADER *) ((UINTN) (AcpiDmarTabl= e + 1)); while ((UINTN) DmarHeader < (UINTN) AcpiDmarTable + AcpiDmarTable->Heade= r.Length) { switch (DmarHeader->Type) { - case EFI_ACPI_DMAR_TYPE_DRHD: - ASSERT (VtdIndex < VtdUnitNumber); - ProcessDrhd (&VTdInfo->VtdUnitInfo[VtdIndex], (EFI_ACPI_DMAR_DRHD_HE= ADER *) DmarHeader); - VtdIndex++; - + case EFI_ACPI_DMAR_TYPE_RMRR: + DeviceNumber +=3D ProcessRmrrGetDeviceNumber ((EFI_ACPI_DMAR_RMRR_HE= ADER *) DmarHeader); break; - default: break; } DmarHeader =3D (EFI_ACPI_DMAR_STRUCTURE_HEADER *) ((UINTN) DmarHeader = + DmarHeader->Length); } - ASSERT (VtdIndex =3D=3D VtdUnitNumber); - - for (VtdIndex =3D 0; VtdIndex < VtdUnitNumber; VtdIndex++) { - DumpPciDeviceInfo (VTdInfo, VtdIndex); - } - - return EFI_SUCCESS; + return DeviceNumber; } =20 - /** - Process DMAR RMRR table. + Parse RMRR table. =20 - @param[in] VTdInfo The VTd engine context information. - @param[in] DmarRmrr The RMRR table. + @param[in] DmarRmrr RMRR table + @param[out] RmrrInfo The VTd RMRR information. + + @return EFI_SUCCESS The DMAR DRHD table is parsed. =20 **/ VOID ProcessRmrr ( - IN VTD_INFO *VTdInfo, - IN EFI_ACPI_DMAR_RMRR_HEADER *DmarRmrr + IN EFI_ACPI_DMAR_RMRR_HEADER *DmarRmrr, + OUT VTD_RMRR_INFO *RmrrInfo ) { EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER *DmarDevScopeEntry; @@ -746,7 +552,7 @@ ProcessRmrr ( UINT8 Device; UINT8 Function; EFI_STATUS Status; - VTD_SOURCE_ID SourceId; + UINTN DeviceIndex; =20 DEBUG ((DEBUG_INFO," PEI RMRR (Base 0x%016lx, Limit 0x%016lx)\n", DmarR= mrr->ReservedMemoryRegionBaseAddress, DmarRmrr->ReservedMemoryRegionLimitAd= dress)); =20 @@ -755,6 +561,11 @@ ProcessRmrr ( return ; } =20 + RmrrInfo->SegmentNumber =3D DmarRmrr->SegmentNumber; + RmrrInfo->ReservedMemoryRegionBaseAddress =3D DmarRmrr->ReservedMemoryRe= gionBaseAddress; + RmrrInfo->ReservedMemoryRegionLimitAddress =3D DmarRmrr->ReservedMemoryR= egionLimitAddress; + DeviceIndex =3D 0; + DmarDevScopeEntry =3D (EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER *) ((= UINTN) (DmarRmrr + 1)); while ((UINTN) DmarDevScopeEntry < (UINTN) DmarRmrr + DmarRmrr->Header.L= ength) { if (DmarDevScopeEntry->Type !=3D EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_= ENDPOINT) { @@ -766,50 +577,39 @@ ProcessRmrr ( if (EFI_ERROR (Status)) { continue; } + ASSERT (DeviceIndex < RmrrInfo->DeviceNumber); =20 DEBUG ((DEBUG_INFO,"RMRR S%04x B%02x D%02x F%02x\n", DmarRmrr->Segment= Number, Bus, Device, Function)); =20 - SourceId.Bits.Bus =3D Bus; - SourceId.Bits.Device =3D Device; - SourceId.Bits.Function =3D Function; - - Status =3D EnableRmrrPageAttribute ( - VTdInfo, - DmarRmrr->SegmentNumber, - SourceId, - DmarRmrr->ReservedMemoryRegionBaseAddress, - DmarRmrr->ReservedMemoryRegionLimitAddress, - EDKII_IOMMU_ACCESS_READ | EDKII_IOMMU_ACCESS_WRITE - ); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_INFO, "EnableRmrrPageAttribute : %r\n", Status)); - } + RmrrInfo->SourceId[DeviceIndex].Bits.Bus =3D Bus; + RmrrInfo->SourceId[DeviceIndex].Bits.Device =3D Device; + RmrrInfo->SourceId[DeviceIndex].Bits.Function =3D Function; + DeviceIndex++; =20 DmarDevScopeEntry =3D (EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER *) = ((UINTN) DmarDevScopeEntry + DmarDevScopeEntry->Length); } } =20 /** - Parse DMAR DRHD table. + Parse DMAR RMRR table. =20 - @param[in] VTdInfo The VTd engine context information. + @param[in] AcpiDmarTable DMAR ACPI table + @param[out] RmrrInfo The VTd RMRR information. =20 **/ VOID -ParseDmarAcpiTableRmrr ( - IN VTD_INFO *VTdInfo +ParseRmrrDmarAcpiTable ( + IN EFI_ACPI_DMAR_HEADER *AcpiDmarTable, + OUT VTD_RMRR_INFO *RmrrInfo ) { - EFI_ACPI_DMAR_HEADER *AcpiDmarTable; EFI_ACPI_DMAR_STRUCTURE_HEADER *DmarHeader; =20 - AcpiDmarTable =3D (EFI_ACPI_DMAR_HEADER *) (UINTN) VTdInfo->AcpiDmarTabl= e; - DmarHeader =3D (EFI_ACPI_DMAR_STRUCTURE_HEADER *) ((UINTN) (AcpiDmarTabl= e + 1)); while ((UINTN) DmarHeader < (UINTN) AcpiDmarTable + AcpiDmarTable->Heade= r.Length) { switch (DmarHeader->Type) { case EFI_ACPI_DMAR_TYPE_RMRR: - ProcessRmrr (VTdInfo, (EFI_ACPI_DMAR_RMRR_HEADER *) DmarHeader); + ProcessRmrr ((EFI_ACPI_DMAR_RMRR_HEADER *) DmarHeader, RmrrInfo); break; default: break; @@ -818,3 +618,36 @@ ParseDmarAcpiTableRmrr ( } } =20 +/** + Get RMRR Info from ACPI DMAR Table. + + @param[in] AcpiDmarTable DMAR ACPI table + + @return the VTd engine number. +**/ +VTD_RMRR_INFO * +GetVtdRmrrInfo ( + IN EFI_ACPI_DMAR_HEADER *AcpiDmarTable + ) +{ + UINTN DeviceNumber; + VTD_RMRR_INFO *RmrrInfo; + UINTN InfoSize; + + RmrrInfo =3D NULL; + DeviceNumber =3D GetVtdRmrrDeviceNumber (AcpiDmarTable); + + if (DeviceNumber > 0) { + InfoSize =3D sizeof (VTD_RMRR_INFO) - sizeof (VTD_SOURCE_ID) + sizeof = (VTD_SOURCE_ID) * DeviceNumber; + RmrrInfo =3D (VTD_RMRR_INFO *) AllocateZeroPages (EFI_SIZE_TO_PAGES (I= nfoSize)); + if (RmrrInfo =3D=3D NULL) { + DEBUG ((DEBUG_ERROR, "GetVtdRmrrInfo - OUT_OF_RESOURCE\n")); + ASSERT (FALSE); + return NULL; + } + + RmrrInfo->DeviceNumber =3D DeviceNumber; + ParseRmrrDmarAcpiTable (AcpiDmarTable, RmrrInfo); + } + return RmrrInfo; +} diff --git a/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/Inte= lVTdDmar.c b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/Inte= lVTdDmar.c index 63397a1a..b51b38a0 100644 --- a/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/IntelVTdDma= r.c +++ b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/IntelVTdDma= r.c @@ -1,6 +1,6 @@ /** @file =20 - Copyright (c) 2020, Intel Corporation. All rights reserved.
+ Copyright (c) 2020 - 2021, Intel Corporation. All rights reserved.
=20 SPDX-License-Identifier: BSD-2-Clause-Patent =20 @@ -79,77 +79,73 @@ PerpareCacheInvalidationInterface ( IN VTD_UNIT_INFO *VTdUnitInfo ) { - UINT16 QueueSize; + UINT16 QiDescLength; UINT64 Reg64; UINT32 Reg32; VTD_ECAP_REG ECapReg; + UINTN VtdUnitBaseAddress; =20 + VtdUnitBaseAddress =3D VTdUnitInfo->VtdUnitBaseAddress; =20 - if (VTdUnitInfo->VerReg.Bits.Major <=3D 6) { + if (VTdUnitInfo->VerReg.Bits.Major <=3D 5) { VTdUnitInfo->EnableQueuedInvalidation =3D 0; - DEBUG ((DEBUG_INFO, "Use Register-based Invalidation Interface for eng= ine [0x%x]\n", VTdUnitInfo->VtdUnitBaseAddress)); + DEBUG ((DEBUG_INFO, "Use Register-based Invalidation Interface for eng= ine [0x%x]\n", VtdUnitBaseAddress)); return EFI_SUCCESS; } =20 - ECapReg.Uint64 =3D MmioRead64 ((UINTN)VTdUnitInfo->VtdUnitBaseAddress + = R_ECAP_REG); + ECapReg.Uint64 =3D MmioRead64 (VtdUnitBaseAddress + R_ECAP_REG); if (ECapReg.Bits.QI =3D=3D 0) { - DEBUG ((DEBUG_ERROR, "Hardware does not support queued invalidations i= nterface for engine [0x%x]\n", VTdUnitInfo->VtdUnitBaseAddress)); + DEBUG ((DEBUG_ERROR, "Hardware does not support queued invalidations i= nterface for engine [0x%x]\n", VtdUnitBaseAddress)); return EFI_UNSUPPORTED; } =20 VTdUnitInfo->EnableQueuedInvalidation =3D 1; - DEBUG ((DEBUG_INFO, "Use Queued Invalidation Interface for engine [0x%x]= \n", VTdUnitInfo->VtdUnitBaseAddress)); + DEBUG ((DEBUG_INFO, "Use Queued Invalidation Interface for engine [0x%x]= \n", VtdUnitBaseAddress)); =20 - Reg32 =3D MmioRead32 ((UINTN)VTdUnitInfo->VtdUnitBaseAddress + R_GSTS_RE= G); + Reg32 =3D MmioRead32 (VtdUnitBaseAddress + R_GSTS_REG); if ((Reg32 & B_GSTS_REG_QIES) !=3D 0) { DEBUG ((DEBUG_INFO,"Queued Invalidation Interface was enabled.\n")); Reg32 &=3D (~B_GSTS_REG_QIES); - MmioWrite32 ((UINTN)VTdUnitInfo->VtdUnitBaseAddress + R_GCMD_REG, Reg3= 2); + MmioWrite32 (VtdUnitBaseAddress + R_GCMD_REG, Reg32); do { - Reg32 =3D MmioRead32 ((UINTN)VTdUnitInfo->VtdUnitBaseAddress + R_GST= S_REG); + Reg32 =3D MmioRead32 (VtdUnitBaseAddress + R_GSTS_REG); } while ((Reg32 & B_GSTS_REG_QIES) !=3D 0); - MmioWrite64 ((UINTN)VTdUnitInfo->VtdUnitBaseAddress + R_IQA_REG, 0); - - if (VTdUnitInfo->QiDesc !=3D NULL) { - FreePages(VTdUnitInfo->QiDesc, EFI_SIZE_TO_PAGES(sizeof(QI_DESC) * V= TdUnitInfo->QiDescLength)); - VTdUnitInfo->QiDesc =3D NULL; - VTdUnitInfo->QiDescLength =3D 0; - } + MmioWrite64 (VtdUnitBaseAddress + R_IQA_REG, 0); } =20 // // Initialize the Invalidation Queue Tail Register to zero. // - MmioWrite64 ((UINTN)VTdUnitInfo->VtdUnitBaseAddress + R_IQT_REG, 0); + MmioWrite64 (VtdUnitBaseAddress + R_IQT_REG, 0); =20 // // Setup the IQ address, size and descriptor width through the Invalidat= ion Queue Address Register // - QueueSize =3D 0; - VTdUnitInfo->QiDescLength =3D 1 << (QueueSize + 8); - VTdUnitInfo->QiDesc =3D (QI_DESC *) AllocatePages (EFI_SIZE_TO_PAGES(siz= eof(QI_DESC) * VTdUnitInfo->QiDescLength)); - if (VTdUnitInfo->QiDesc =3D=3D NULL) { - VTdUnitInfo->QiDescLength =3D 0; - DEBUG ((DEBUG_ERROR,"Could not Alloc Invalidation Queue Buffer.\n")); - return EFI_OUT_OF_RESOURCES; + VTdUnitInfo->QueueSize =3D 0; + QiDescLength =3D 1 << (VTdUnitInfo->QueueSize + 8); + VTdUnitInfo->QiDesc =3D (QI_DESC *) AllocatePages (EFI_SIZE_TO_PAGES(s= izeof(QI_DESC) * QiDescLength)); + if (VTdUnitInfo->QiDesc =3D=3D NULL) { + DEBUG ((DEBUG_ERROR,"Could not Alloc Invalidation Queue Buffer.\n")); + return EFI_OUT_OF_RESOURCES; + } } =20 - DEBUG ((DEBUG_INFO, "Invalidation Queue Length : %d\n", VTdUnitInfo->QiD= escLength)); - Reg64 =3D (UINT64)(UINTN)VTdUnitInfo->QiDesc; - Reg64 |=3D QueueSize; - MmioWrite64 ((UINTN)VTdUnitInfo->VtdUnitBaseAddress + R_IQA_REG, Reg64); + DEBUG ((DEBUG_INFO, "Invalidation Queue Length : %d\n", QiDescLength)); + Reg64 =3D (UINT64) (UINTN) VTdUnitInfo->QiDesc; + Reg64 |=3D VTdUnitInfo->QueueSize; + MmioWrite64 (VtdUnitBaseAddress + R_IQA_REG, Reg64); =20 // // Enable the queued invalidation interface through the Global Command R= egister. // When enabled, hardware sets the QIES field in the Global Status Regis= ter. // - Reg32 =3D MmioRead32 ((UINTN)VTdUnitInfo->VtdUnitBaseAddress + R_GSTS_RE= G); + Reg32 =3D MmioRead32 (VtdUnitBaseAddress + R_GSTS_REG); Reg32 |=3D B_GMCD_REG_QIE; - MmioWrite32 ((UINTN)VTdUnitInfo->VtdUnitBaseAddress + R_GCMD_REG, Reg32); + MmioWrite32 (VtdUnitBaseAddress + R_GCMD_REG, Reg32); DEBUG ((DEBUG_INFO, "Enable Queued Invalidation Interface. GCMD_REG =3D = 0x%x\n", Reg32)); do { - Reg32 =3D MmioRead32 ((UINTN)VTdUnitInfo->VtdUnitBaseAddress + R_GSTS_= REG); + Reg32 =3D MmioRead32 (VtdUnitBaseAddress + R_GSTS_REG); } while ((Reg32 & B_GSTS_REG_QIES) =3D=3D 0); =20 VTdUnitInfo->QiFreeHead =3D 0; @@ -167,21 +163,23 @@ DisableQueuedInvalidationInterface ( IN VTD_UNIT_INFO *VTdUnitInfo ) { - UINT32 Reg32; + UINT32 Reg32; + UINT16 QiDescLength; =20 if (VTdUnitInfo->EnableQueuedInvalidation !=3D 0) { - Reg32 =3D MmioRead32 ((UINTN)VTdUnitInfo->VtdUnitBaseAddress + R_GSTS_= REG); + Reg32 =3D MmioRead32 (VTdUnitInfo->VtdUnitBaseAddress + R_GSTS_REG); Reg32 &=3D (~B_GMCD_REG_QIE); - MmioWrite32 ((UINTN)VTdUnitInfo->VtdUnitBaseAddress + R_GCMD_REG, Reg3= 2); + MmioWrite32 (VTdUnitInfo->VtdUnitBaseAddress + R_GCMD_REG, Reg32); DEBUG ((DEBUG_INFO, "Disable Queued Invalidation Interface. GCMD_REG = =3D 0x%x\n", Reg32)); do { - Reg32 =3D MmioRead32 ((UINTN)VTdUnitInfo->VtdUnitBaseAddress + R_GST= S_REG); + Reg32 =3D MmioRead32 (VTdUnitInfo->VtdUnitBaseAddress + R_GSTS_REG); } while ((Reg32 & B_GSTS_REG_QIES) !=3D 0); =20 if (VTdUnitInfo->QiDesc !=3D NULL) { - FreePages(VTdUnitInfo->QiDesc, EFI_SIZE_TO_PAGES(sizeof(QI_DESC) * V= TdUnitInfo->QiDescLength)); + QiDescLength =3D 1 << (VTdUnitInfo->QueueSize + 8); + FreePages(VTdUnitInfo->QiDesc, EFI_SIZE_TO_PAGES(sizeof(QI_DESC) * Q= iDescLength)); VTdUnitInfo->QiDesc =3D NULL; - VTdUnitInfo->QiDescLength =3D 0; + VTdUnitInfo->QueueSize =3D 0; } =20 VTdUnitInfo->EnableQueuedInvalidation =3D 0; @@ -203,26 +201,11 @@ QueuedInvalidationCheckFault ( { UINT32 FaultReg; =20 - FaultReg =3D MmioRead32 ((UINTN)VTdUnitInfo->VtdUnitBaseAddress + R_FSTS= _REG); - - if (FaultReg & B_FSTS_REG_IQE) { - DEBUG((DEBUG_ERROR, "Detect Invalidation Queue Error [0x%08x]\n", Faul= tReg)); - FaultReg |=3D B_FSTS_REG_IQE; - MmioWrite32 ((UINTN)VTdUnitInfo->VtdUnitBaseAddress + R_FSTS_REG, Faul= tReg); - return RETURN_DEVICE_ERROR; - } - - if (FaultReg & B_FSTS_REG_ITE) { - DEBUG((DEBUG_ERROR, "Detect Invalidation Time-out Error [0x%08x]\n", F= aultReg)); - FaultReg |=3D B_FSTS_REG_ITE; - MmioWrite32 ((UINTN)VTdUnitInfo->VtdUnitBaseAddress + R_FSTS_REG, Faul= tReg); - return RETURN_DEVICE_ERROR; - } - - if (FaultReg & B_FSTS_REG_ICE) { - DEBUG((DEBUG_ERROR, "Detect Invalidation Completion Error [0x%08x]\n",= FaultReg)); - FaultReg |=3D B_FSTS_REG_ICE; - MmioWrite32 ((UINTN)VTdUnitInfo->VtdUnitBaseAddress + R_FSTS_REG, Faul= tReg); + FaultReg =3D MmioRead32 (VTdUnitInfo->VtdUnitBaseAddress + R_FSTS_REG); + if (FaultReg & (B_FSTS_REG_IQE | B_FSTS_REG_ITE | B_FSTS_REG_ICE)) { + DEBUG((DEBUG_ERROR, "Detect Queue Invalidation Error [0x%08x]\n", Faul= tReg)); + FaultReg |=3D (B_FSTS_REG_IQE | B_FSTS_REG_ITE | B_FSTS_REG_ICE); + MmioWrite32 (VTdUnitInfo->VtdUnitBaseAddress + R_FSTS_REG, FaultReg); return RETURN_DEVICE_ERROR; } =20 @@ -256,7 +239,7 @@ SubmitQueuedInvalidationDescriptor ( return EFI_INVALID_PARAMETER; } =20 - QiDescLength =3D VTdUnitInfo->QiDescLength; + QiDescLength =3D 1 << (VTdUnitInfo->QueueSize + 8); BaseDesc =3D VTdUnitInfo->QiDesc; =20 DEBUG((DEBUG_INFO, "[0x%x] Submit QI Descriptor [0x%08x, 0x%08x]\n", VTd= UnitInfo->VtdUnitBaseAddress, Desc->Low, Desc->High)); @@ -268,12 +251,12 @@ SubmitQueuedInvalidationDescriptor ( DEBUG((DEBUG_INFO,"QI Free Head=3D0x%x\n", VTdUnitInfo->QiFreeHead)); VTdUnitInfo->QiFreeHead =3D (VTdUnitInfo->QiFreeHead + 1) % QiDescLength; =20 - Reg64Iqh =3D MmioRead64 ((UINTN)VTdUnitInfo->VtdUnitBaseAddress + R_IQH_= REG); + Reg64Iqh =3D MmioRead64 (VTdUnitInfo->VtdUnitBaseAddress + R_IQH_REG); // // Update the HW tail register indicating the presence of new descriptor= s. // Reg64Iqt =3D VTdUnitInfo->QiFreeHead << DMAR_IQ_SHIFT; - MmioWrite64 ((UINTN)VTdUnitInfo->VtdUnitBaseAddress + R_IQT_REG, Reg64Iq= t); + MmioWrite64 (VTdUnitInfo->VtdUnitBaseAddress + R_IQT_REG, Reg64Iqt); =20 Status =3D EFI_SUCCESS; do { @@ -283,7 +266,7 @@ SubmitQueuedInvalidationDescriptor ( break; } =20 - Reg64Iqh =3D MmioRead64 ((UINTN)VTdUnitInfo->VtdUnitBaseAddress + R_IQ= H_REG); + Reg64Iqh =3D MmioRead64 (VTdUnitInfo->VtdUnitBaseAddress + R_IQH_REG); } while (Reg64Iqt !=3D Reg64Iqh); =20 DEBUG((DEBUG_ERROR,"SubmitQueuedInvalidationDescriptor end\n")); @@ -307,18 +290,18 @@ InvalidateContextCache ( // // Register-based Invalidation // - Reg64 =3D MmioRead64 ((UINTN)VTdUnitInfo->VtdUnitBaseAddress + R_CCMD_= REG); + Reg64 =3D MmioRead64 (VTdUnitInfo->VtdUnitBaseAddress + R_CCMD_REG); if ((Reg64 & B_CCMD_REG_ICC) !=3D 0) { - DEBUG ((DEBUG_ERROR,"ERROR: InvalidateContextCache: B_CCMD_REG_ICC i= s set for VTD(%x)\n", (UINTN)VTdUnitInfo->VtdUnitBaseAddress)); + DEBUG ((DEBUG_ERROR,"ERROR: InvalidateContextCache: B_CCMD_REG_ICC i= s set for VTD(%x)\n", VTdUnitInfo->VtdUnitBaseAddress)); return EFI_DEVICE_ERROR; } =20 Reg64 &=3D ((~B_CCMD_REG_ICC) & (~B_CCMD_REG_CIRG_MASK)); Reg64 |=3D (B_CCMD_REG_ICC | V_CCMD_REG_CIRG_GLOBAL); - MmioWrite64 ((UINTN)VTdUnitInfo->VtdUnitBaseAddress + R_CCMD_REG, Reg6= 4); + MmioWrite64 (VTdUnitInfo->VtdUnitBaseAddress + R_CCMD_REG, Reg64); =20 do { - Reg64 =3D MmioRead64 ((UINTN)VTdUnitInfo->VtdUnitBaseAddress + R_CCM= D_REG); + Reg64 =3D MmioRead64 (VTdUnitInfo->VtdUnitBaseAddress + R_CCMD_REG); } while ((Reg64 & B_CCMD_REG_ICC) !=3D 0); } else { // @@ -351,26 +334,26 @@ InvalidateIOTLB ( // // Register-based Invalidation // - ECapReg.Uint64 =3D MmioRead64 ((UINTN)VTdUnitInfo->VtdUnitBaseAddress = + R_ECAP_REG); + ECapReg.Uint64 =3D MmioRead64 (VTdUnitInfo->VtdUnitBaseAddress + R_ECA= P_REG); =20 - Reg64 =3D MmioRead64 ((UINTN)VTdUnitInfo->VtdUnitBaseAddress + (ECapRe= g.Bits.IRO * 16) + R_IOTLB_REG); + Reg64 =3D MmioRead64 (VTdUnitInfo->VtdUnitBaseAddress + (ECapReg.Bits.= IRO * 16) + R_IOTLB_REG); if ((Reg64 & B_IOTLB_REG_IVT) !=3D 0) { - DEBUG ((DEBUG_ERROR, "ERROR: InvalidateIOTLB: B_IOTLB_REG_IVT is se= t for VTD(%x)\n", (UINTN)VTdUnitInfo->VtdUnitBaseAddress)); + DEBUG ((DEBUG_ERROR, "ERROR: InvalidateIOTLB: B_IOTLB_REG_IVT is se= t for VTD(%x)\n", VTdUnitInfo->VtdUnitBaseAddress)); return EFI_DEVICE_ERROR; } =20 Reg64 &=3D ((~B_IOTLB_REG_IVT) & (~B_IOTLB_REG_IIRG_MASK)); Reg64 |=3D (B_IOTLB_REG_IVT | V_IOTLB_REG_IIRG_GLOBAL); - MmioWrite64 ((UINTN)VTdUnitInfo->VtdUnitBaseAddress + (ECapReg.Bits.IR= O * 16) + R_IOTLB_REG, Reg64); + MmioWrite64 (VTdUnitInfo->VtdUnitBaseAddress + (ECapReg.Bits.IRO * 16)= + R_IOTLB_REG, Reg64); =20 do { - Reg64 =3D MmioRead64 ((UINTN)VTdUnitInfo->VtdUnitBaseAddress + (ECap= Reg.Bits.IRO * 16) + R_IOTLB_REG); + Reg64 =3D MmioRead64 (VTdUnitInfo->VtdUnitBaseAddress + (ECapReg.Bit= s.IRO * 16) + R_IOTLB_REG); } while ((Reg64 & B_IOTLB_REG_IVT) !=3D 0); } else { // // Queued Invalidation // - ECapReg.Uint64 =3D MmioRead64 ((UINTN)VTdUnitInfo->VtdUnitBaseAddress = + R_ECAP_REG); + ECapReg.Uint64 =3D MmioRead64 (VTdUnitInfo->VtdUnitBaseAddress + R_ECA= P_REG); QiDesc.Low =3D QI_IOTLB_DID(0) | QI_IOTLB_DR(CAP_READ_DRAIN(ECapReg.Ui= nt64)) | QI_IOTLB_DW(CAP_WRITE_DRAIN(ECapReg.Uint64)) | QI_IOTLB_GRAN(1) | = QI_IOTLB_TYPE; QiDesc.High =3D QI_IOTLB_ADDR(0) | QI_IOTLB_IH(0) | QI_IOTLB_AM(0); =20 @@ -392,14 +375,14 @@ InvalidateIOTLB ( EFI_STATUS EnableDmarPreMem ( IN UINTN VtdUnitBaseAddress, - IN UINTN RtaddrRegValue + IN UINT64 RtaddrRegValue ) { UINT32 Reg32; =20 DEBUG ((DEBUG_INFO, ">>>>>>EnableDmarPreMem() for engine [%x] \n", VtdUn= itBaseAddress)); =20 - DEBUG ((DEBUG_INFO, "RTADDR_REG : 0x%x \n", RtaddrRegValue)); + DEBUG ((DEBUG_INFO, "RTADDR_REG : 0x%016lx \n", RtaddrRegValue)); MmioWrite64 (VtdUnitBaseAddress + R_RTADDR_REG, (UINT64) RtaddrRegValue); =20 Reg32 =3D MmioRead32 (VtdUnitBaseAddress + R_GSTS_REG); @@ -452,30 +435,33 @@ EnableDmar ( ) { UINT32 Reg32; + UINTN VtdUnitBaseAddress; =20 - DEBUG ((DEBUG_INFO, ">>>>>>EnableDmar() for engine [%x] \n", VTdUnitInfo= ->VtdUnitBaseAddress)); + VtdUnitBaseAddress =3D VTdUnitInfo->VtdUnitBaseAddress; + + DEBUG ((DEBUG_INFO, ">>>>>>EnableDmar() for engine [%x] \n", VtdUnitBase= Address)); =20 DEBUG ((DEBUG_INFO, "RootEntryTable 0x%x \n", RootEntryTable)); - MmioWrite64 ((UINTN)VTdUnitInfo->VtdUnitBaseAddress + R_RTADDR_REG, (UIN= T64) (UINTN) RootEntryTable); + MmioWrite64 (VtdUnitBaseAddress + R_RTADDR_REG, (UINT64) RootEntryTable); =20 - Reg32 =3D MmioRead32 ((UINTN)VTdUnitInfo->VtdUnitBaseAddress + R_GSTS_RE= G); - MmioWrite32 ((UINTN)VTdUnitInfo->VtdUnitBaseAddress + R_GCMD_REG, Reg32 = | B_GMCD_REG_SRTP); + Reg32 =3D MmioRead32 (VtdUnitBaseAddress + R_GSTS_REG); + MmioWrite32 (VtdUnitBaseAddress + R_GCMD_REG, Reg32 | B_GMCD_REG_SRTP); =20 DEBUG ((DEBUG_INFO, "EnableDmar: waiting for RTPS bit to be set... \n")); do { - Reg32 =3D MmioRead32 ((UINTN)VTdUnitInfo->VtdUnitBaseAddress + R_GSTS_= REG); + Reg32 =3D MmioRead32 (VtdUnitBaseAddress + R_GSTS_REG); } while((Reg32 & B_GSTS_REG_RTPS) =3D=3D 0); DEBUG ((DEBUG_INFO, "EnableDmar: R_GSTS_REG =3D 0x%x \n", Reg32)); =20 // // Init DMAr Fault Event and Data registers // - Reg32 =3D MmioRead32 ((UINTN)VTdUnitInfo->VtdUnitBaseAddress + R_FEDATA_= REG); + Reg32 =3D MmioRead32 (VtdUnitBaseAddress + R_FEDATA_REG); =20 // // Write Buffer Flush before invalidation // - FlushWriteBuffer ((UINTN)VTdUnitInfo->VtdUnitBaseAddress); + FlushWriteBuffer (VtdUnitBaseAddress); =20 // // Invalidate the context cache @@ -490,11 +476,11 @@ EnableDmar ( // // Enable VTd // - Reg32 =3D MmioRead32 ((UINTN)VTdUnitInfo->VtdUnitBaseAddress + R_GSTS_RE= G); - MmioWrite32 ((UINTN)VTdUnitInfo->VtdUnitBaseAddress + R_GCMD_REG, Reg32 = | B_GMCD_REG_TE); + Reg32 =3D MmioRead32 (VtdUnitBaseAddress + R_GSTS_REG); + MmioWrite32 (VtdUnitBaseAddress + R_GCMD_REG, Reg32 | B_GMCD_REG_TE); DEBUG ((DEBUG_INFO, "EnableDmar: Waiting B_GSTS_REG_TE ...\n")); do { - Reg32 =3D MmioRead32 ((UINTN)VTdUnitInfo->VtdUnitBaseAddress + R_GSTS_= REG); + Reg32 =3D MmioRead32 (VtdUnitBaseAddress + R_GSTS_REG); } while ((Reg32 & B_GSTS_REG_TE) =3D=3D 0); =20 DEBUG ((DEBUG_INFO, "VTD () enabled!<<<<<<\n")); @@ -566,139 +552,52 @@ DisableDmar ( } =20 /** - Dump VTd version registers. + Enable VTd translation table protection for block DMA =20 - @param[in] VerReg The version register. -**/ -VOID -DumpVtdVerRegs ( - IN VTD_VER_REG *VerReg - ) -{ - DEBUG ((DEBUG_INFO, " VerReg:\n", VerReg->Uint32)); - DEBUG ((DEBUG_INFO, " Major - 0x%x\n", VerReg->Bits.Major)); - DEBUG ((DEBUG_INFO, " Minor - 0x%x\n", VerReg->Bits.Minor)); -} - -/** - Dump VTd capability registers. - - @param[in] CapReg The capability register. -**/ -VOID -DumpVtdCapRegs ( - IN VTD_CAP_REG *CapReg - ) -{ - DEBUG ((DEBUG_INFO, " CapReg:\n", CapReg->Uint64)); - DEBUG ((DEBUG_INFO, " ND - 0x%x\n", CapReg->Bits.ND)); - DEBUG ((DEBUG_INFO, " AFL - 0x%x\n", CapReg->Bits.AFL)); - DEBUG ((DEBUG_INFO, " RWBF - 0x%x\n", CapReg->Bits.RWBF)); - DEBUG ((DEBUG_INFO, " PLMR - 0x%x\n", CapReg->Bits.PLMR)); - DEBUG ((DEBUG_INFO, " PHMR - 0x%x\n", CapReg->Bits.PHMR)); - DEBUG ((DEBUG_INFO, " CM - 0x%x\n", CapReg->Bits.CM)); - DEBUG ((DEBUG_INFO, " SAGAW - 0x%x\n", CapReg->Bits.SAGAW)); - DEBUG ((DEBUG_INFO, " MGAW - 0x%x\n", CapReg->Bits.MGAW)); - DEBUG ((DEBUG_INFO, " ZLR - 0x%x\n", CapReg->Bits.ZLR)); - DEBUG ((DEBUG_INFO, " FRO - 0x%x\n", CapReg->Bits.FRO)); - DEBUG ((DEBUG_INFO, " SLLPS - 0x%x\n", CapReg->Bits.SLLPS)); - DEBUG ((DEBUG_INFO, " PSI - 0x%x\n", CapReg->Bits.PSI)); - DEBUG ((DEBUG_INFO, " NFR - 0x%x\n", CapReg->Bits.NFR)); - DEBUG ((DEBUG_INFO, " MAMV - 0x%x\n", CapReg->Bits.MAMV)); - DEBUG ((DEBUG_INFO, " DWD - 0x%x\n", CapReg->Bits.DWD)); - DEBUG ((DEBUG_INFO, " DRD - 0x%x\n", CapReg->Bits.DRD)); - DEBUG ((DEBUG_INFO, " FL1GP - 0x%x\n", CapReg->Bits.FL1GP)); - DEBUG ((DEBUG_INFO, " PI - 0x%x\n", CapReg->Bits.PI)); -} + @param[in] VtdUnitBaseAddress The base address of the VTd engine. =20 -/** - Dump VTd extended capability registers. - - @param[in] ECapReg The extended capability register. + @retval EFI_SUCCESS DMAR translation is enabled. + @retval EFI_DEVICE_ERROR DMAR translation is not enabled. **/ -VOID -DumpVtdECapRegs ( - IN VTD_ECAP_REG *ECapReg - ) -{ - DEBUG ((DEBUG_INFO, " ECapReg:\n", ECapReg->Uint64)); - DEBUG ((DEBUG_INFO, " C - 0x%x\n", ECapReg->Bits.C)); - DEBUG ((DEBUG_INFO, " QI - 0x%x\n", ECapReg->Bits.QI)); - DEBUG ((DEBUG_INFO, " DT - 0x%x\n", ECapReg->Bits.DT)); - DEBUG ((DEBUG_INFO, " IR - 0x%x\n", ECapReg->Bits.IR)); - DEBUG ((DEBUG_INFO, " EIM - 0x%x\n", ECapReg->Bits.EIM)); - DEBUG ((DEBUG_INFO, " PT - 0x%x\n", ECapReg->Bits.PT)); - DEBUG ((DEBUG_INFO, " SC - 0x%x\n", ECapReg->Bits.SC)); - DEBUG ((DEBUG_INFO, " IRO - 0x%x\n", ECapReg->Bits.IRO)); - DEBUG ((DEBUG_INFO, " MHMV - 0x%x\n", ECapReg->Bits.MHMV)); - DEBUG ((DEBUG_INFO, " MTS - 0x%x\n", ECapReg->Bits.MTS)); - DEBUG ((DEBUG_INFO, " NEST - 0x%x\n", ECapReg->Bits.NEST)); - DEBUG ((DEBUG_INFO, " PASID - 0x%x\n", ECapReg->Bits.PASID)); - DEBUG ((DEBUG_INFO, " PRS - 0x%x\n", ECapReg->Bits.PRS)); - DEBUG ((DEBUG_INFO, " ERS - 0x%x\n", ECapReg->Bits.ERS)); - DEBUG ((DEBUG_INFO, " SRS - 0x%x\n", ECapReg->Bits.SRS)); - DEBUG ((DEBUG_INFO, " NWFS - 0x%x\n", ECapReg->Bits.NWFS)); - DEBUG ((DEBUG_INFO, " EAFS - 0x%x\n", ECapReg->Bits.EAFS)); - DEBUG ((DEBUG_INFO, " PSS - 0x%x\n", ECapReg->Bits.PSS)); - DEBUG ((DEBUG_INFO, " ADMS - 0x%x\n", ECapReg->Bits.ADMS)); -} - - -/** - Enable VTd translation table protection for all. - - @param[in] VTdInfo The VTd engine context information. - @param[in] EngineMask The mask of the VTd engine to be accessed. -**/ -VOID -EnableVTdTranslationProtectionAll ( - IN VTD_INFO *VTdInfo, - IN UINT64 EngineMask +EFI_STATUS +EnableVTdTranslationProtectionBlockDma ( + IN UINTN VtdUnitBaseAddress ) { - EFI_STATUS Status; - EDKII_VTD_NULL_ROOT_ENTRY_TABLE_PPI *RootEntryTable; - UINTN Index; + EFI_STATUS Status; + VTD_ECAP_REG ECapReg; + EDKII_VTD_NULL_ROOT_ENTRY_TABLE_PPI *RootEntryTable; =20 - DEBUG ((DEBUG_INFO, "EnableVTdTranslationProtectionAll - 0x%lx\n", Engin= eMask)); + DEBUG ((DEBUG_INFO, "EnableVTdTranslationProtectionBlockDma - 0x%08x\n",= VtdUnitBaseAddress)); =20 - for (Index =3D 0; Index < VTdInfo->VTdEngineCount; Index++) { - if ((EngineMask & LShiftU64(1, Index)) =3D=3D 0) { - continue; - } + ECapReg.Uint64 =3D MmioRead64 (VtdUnitBaseAddress + R_ECAP_REG); + DEBUG ((DEBUG_INFO, "ECapReg : 0%016lx\n", ECapReg.Uint64)); =20 - VTdInfo->VtdUnitInfo[Index].VerReg.Uint32 =3D MmioRead32 (VTdInfo->Vtd= UnitInfo[Index].VtdUnitBaseAddress + R_VER_REG); - DumpVtdVerRegs (&VTdInfo->VtdUnitInfo[Index].VerReg); - VTdInfo->VtdUnitInfo[Index].CapReg.Uint64 =3D MmioRead64 (VTdInfo->Vtd= UnitInfo[Index].VtdUnitBaseAddress + R_CAP_REG); - DumpVtdCapRegs (&VTdInfo->VtdUnitInfo[Index].CapReg); - VTdInfo->VtdUnitInfo[Index].ECapReg.Uint64 =3D MmioRead64 (VTdInfo->Vt= dUnitInfo[Index].VtdUnitBaseAddress + R_ECAP_REG); - DumpVtdECapRegs (&VTdInfo->VtdUnitInfo[Index].ECapReg); - - if (VTdInfo->VtdUnitInfo[Index].ECapReg.Bits.ADMS =3D=3D 1) { - // - // Use Abort DMA Mode - // - Status =3D EnableDmarPreMem (VTdInfo->VtdUnitInfo[Index].VtdUnitBase= Address, V_RTADDR_REG_TTM_ADM); - } else { - // - // Use Null Root Entry Table - // - Status =3D PeiServicesLocatePpi ( - &gEdkiiVTdNullRootEntryTableGuid, - 0, - NULL, - (VOID **)&RootEntryTable - ); - if (EFI_ERROR(Status)) { - DEBUG ((DEBUG_ERROR, "Locate Null Root Entry Table Ppi Failed : %r= \n", Status)); - ASSERT (FALSE); - return; - } - EnableDmarPreMem (VTdInfo->VtdUnitInfo[Index].VtdUnitBaseAddress, (U= INTN) *RootEntryTable); + if (ECapReg.Bits.ADMS =3D=3D 1) { + // + // Use Abort DMA Mode + // + DEBUG ((DEBUG_INFO, "Enable abort DMA mode.\n")); + Status =3D EnableDmarPreMem (VtdUnitBaseAddress, V_RTADDR_REG_TTM_ADM); + } else { + // + // Use Null Root Entry Table + // + Status =3D PeiServicesLocatePpi ( + &gEdkiiVTdNullRootEntryTableGuid, + 0, + NULL, + (VOID **)&RootEntryTable + ); + if (EFI_ERROR(Status)) { + DEBUG ((DEBUG_ERROR, "Locate Null Root Entry Table Ppi Failed : %r\n= ", Status)); + ASSERT (FALSE); + return EFI_DEVICE_ERROR; } + Status =3D EnableDmarPreMem (VtdUnitBaseAddress, (UINT64) (*RootEntryT= able)); } =20 - return; + return Status; } =20 /** @@ -715,18 +614,25 @@ EnableVTdTranslationProtection ( ) { EFI_STATUS Status; - UINTN VtdIndex; + UINTN Index; + VTD_UNIT_INFO *VtdUnitInfo; =20 - for (VtdIndex =3D 0; VtdIndex < VTdInfo->VTdEngineCount; VtdIndex++) { - if (VTdInfo->VtdUnitInfo[VtdIndex].ExtRootEntryTable !=3D 0) { - DEBUG ((DEBUG_INFO, "EnableVtdDmar (%d) ExtRootEntryTable 0x%x\n", V= tdIndex, VTdInfo->VtdUnitInfo[VtdIndex].ExtRootEntryTable)); - Status =3D EnableDmar (&VTdInfo->VtdUnitInfo[VtdIndex], VTdInfo->Vtd= UnitInfo[VtdIndex].ExtRootEntryTable); + for (Index =3D 0; Index < VTdInfo->VTdEngineCount; Index++) { + VtdUnitInfo =3D &VTdInfo->VtdUnitInfo[Index]; + if (VtdUnitInfo->Done) { + DEBUG ((DEBUG_INFO, "EnableVtdDmar (%d) was enabled\n", Index)); + continue; + } + + if (VtdUnitInfo->ExtRootEntryTable !=3D 0) { + DEBUG ((DEBUG_INFO, "EnableVtdDmar (%d) ExtRootEntryTable 0x%x\n", I= ndex, VtdUnitInfo->ExtRootEntryTable)); + Status =3D EnableDmar (VtdUnitInfo, VtdUnitInfo->ExtRootEntryTable); } else { - DEBUG ((DEBUG_INFO, "EnableVtdDmar (%d) RootEntryTable 0x%x\n", VtdI= ndex, VTdInfo->VtdUnitInfo[VtdIndex].RootEntryTable)); - Status =3D EnableDmar (&VTdInfo->VtdUnitInfo[VtdIndex], VTdInfo->Vtd= UnitInfo[VtdIndex].RootEntryTable); + DEBUG ((DEBUG_INFO, "EnableVtdDmar (%d) RootEntryTable 0x%x\n", Inde= x, VtdUnitInfo->RootEntryTable)); + Status =3D EnableDmar (VtdUnitInfo, VtdUnitInfo->RootEntryTable); } if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "EnableVtdDmar (%d) Failed !\n", VtdIndex)); + DEBUG ((DEBUG_ERROR, "EnableVtdDmar (%d) Failed !\n", Index)); return Status; } } @@ -737,23 +643,22 @@ EnableVTdTranslationProtection ( Disable VTd translation table protection. =20 @param[in] VTdInfo The VTd engine context information. - @param[in] EngineMask The mask of the VTd engine to be accessed. **/ VOID DisableVTdTranslationProtection ( - IN VTD_INFO *VTdInfo, - IN UINT64 EngineMask + IN VTD_INFO *VTdInfo ) { UINTN Index; =20 - DEBUG ((DEBUG_INFO, "DisableVTdTranslationProtection - 0x%lx\n", EngineM= ask)); + if (VTdInfo =3D=3D NULL) { + return; + } + + DEBUG ((DEBUG_INFO, "DisableVTdTranslationProtection - %d Vtd Engine\n",= VTdInfo->VTdEngineCount)); =20 for (Index =3D 0; Index < VTdInfo->VTdEngineCount; Index++) { - if ((EngineMask & LShiftU64(1, Index)) =3D=3D 0) { - continue; - } - DisableDmar ((UINTN) VTdInfo->VtdUnitInfo[Index].VtdUnitBaseAddress); + DisableDmar (VTdInfo->VtdUnitInfo[Index].VtdUnitBaseAddress); =20 DisableQueuedInvalidationInterface(&VTdInfo->VtdUnitInfo[Index]); } @@ -786,6 +691,36 @@ PrepareVtdCacheInvalidationConfig ( return EFI_SUCCESS; } =20 +/** + +**/ +EFI_STATUS +VtdCheckUsing5LevelPaging ( + IN UINT8 HostAddressWidth, + IN VTD_UNIT_INFO *VtdUnitInfo, + OUT BOOLEAN *Is5LevelPaging + ) +{ + DEBUG((DEBUG_INFO, " CapReg SAGAW bits : 0x%02x\n", VtdUnitInfo->CapReg= .Bits.SAGAW)); + + *Is5LevelPaging =3D FALSE; + if ((VtdUnitInfo->CapReg.Bits.SAGAW & BIT3) !=3D 0) { + *Is5LevelPaging =3D TRUE; + if ((HostAddressWidth <=3D 48) && + ((VtdUnitInfo->CapReg.Bits.SAGAW & BIT2) !=3D 0)) { + *Is5LevelPaging =3D FALSE; + } else { + return EFI_UNSUPPORTED; + } + } + if ((VtdUnitInfo->CapReg.Bits.SAGAW & (BIT3 | BIT2)) =3D=3D 0) { + return EFI_UNSUPPORTED; + } + DEBUG((DEBUG_INFO, " Using %d Level Paging\n", *Is5LevelPaging ? 5 : 4)= ); + return EFI_SUCCESS; +} + + /** Prepare VTD configuration. =20 @@ -798,43 +733,37 @@ PrepareVtdConfig ( IN VTD_INFO *VTdInfo ) { + EFI_STATUS Status; UINTN Index; - UINTN DomainNumber; + VTD_UNIT_INFO *VtdUnitInfo; + UINTN VtdUnitBaseAddress; =20 for (Index =3D 0; Index < VTdInfo->VTdEngineCount; Index++) { - DEBUG ((DEBUG_ERROR, "Dump VTd Capability (%d)\n", Index)); - VTdInfo->VtdUnitInfo[Index].VerReg.Uint32 =3D MmioRead32 (VTdInfo->Vtd= UnitInfo[Index].VtdUnitBaseAddress + R_VER_REG); - DumpVtdVerRegs (&VTdInfo->VtdUnitInfo[Index].VerReg); - VTdInfo->VtdUnitInfo[Index].CapReg.Uint64 =3D MmioRead64 (VTdInfo->Vtd= UnitInfo[Index].VtdUnitBaseAddress + R_CAP_REG); - DumpVtdCapRegs (&VTdInfo->VtdUnitInfo[Index].CapReg); - VTdInfo->VtdUnitInfo[Index].ECapReg.Uint64 =3D MmioRead64 (VTdInfo->Vt= dUnitInfo[Index].VtdUnitBaseAddress + R_ECAP_REG); - DumpVtdECapRegs (&VTdInfo->VtdUnitInfo[Index].ECapReg); - - VTdInfo->VtdUnitInfo[Index].Is5LevelPaging =3D FALSE; - if ((VTdInfo->VtdUnitInfo[Index].CapReg.Bits.SAGAW & BIT2) !=3D 0) { - DEBUG ((DEBUG_INFO, "Support 4-level page-table on VTD %d\n", Index)= ); - } - if ((VTdInfo->VtdUnitInfo[Index].CapReg.Bits.SAGAW & BIT3) !=3D 0) { - DEBUG((DEBUG_INFO, "Support 5-level page-table on VTD %d\n", Index)); - VTdInfo->VtdUnitInfo[Index].Is5LevelPaging =3D TRUE; - - if ((VTdInfo->HostAddressWidth <=3D 48) && - ((VTdInfo->VtdUnitInfo[Index].CapReg.Bits.SAGAW & BIT2) !=3D 0))= { - DEBUG ((DEBUG_INFO, "Rollback to 4-level page-table on VTD %d\n", = Index)); - VTdInfo->VtdUnitInfo[Index].Is5LevelPaging =3D FALSE; - } + VtdUnitInfo =3D &VTdInfo->VtdUnitInfo[Index]; + if (VtdUnitInfo->Done) { + continue; } - if ((VTdInfo->VtdUnitInfo[Index].CapReg.Bits.SAGAW & (BIT3 | BIT2)) = =3D=3D 0) { - DEBUG ((DEBUG_ERROR, "!!!! Page-table type 0x%X is not supported on = VTD %d !!!!\n", Index, VTdInfo->VtdUnitInfo[Index].CapReg.Bits.SAGAW)); - return EFI_UNSUPPORTED; + VtdUnitBaseAddress =3D VtdUnitInfo->VtdUnitBaseAddress; + DEBUG((DEBUG_INFO, "VTd Engine: 0x%08X\n", VtdUnitBaseAddress)); + + VtdUnitInfo->VerReg.Uint32 =3D MmioRead32 (VtdUnitBaseAddress + R_VER_= REG); + VtdUnitInfo->CapReg.Uint64 =3D MmioRead64 (VtdUnitBaseAddress + R_CAP_= REG); + VtdUnitInfo->ECapReg.Uint64 =3D MmioRead64 (VtdUnitBaseAddress + R_ECA= P_REG); + DEBUG((DEBUG_INFO, " VerReg : 0x%08X\n", VtdUnitInfo->VerReg.Uint32)= ); + DEBUG((DEBUG_INFO, " CapReg : 0x%016lX\n", VtdUnitInfo->CapReg.Uint6= 4)); + DEBUG((DEBUG_INFO, " ECapReg : 0x%016lX\n", VtdUnitInfo->ECapReg.Uint= 64)); + + Status =3D VtdCheckUsing5LevelPaging (VTdInfo->HostAddressWidth, VtdUn= itInfo, &(VtdUnitInfo->Is5LevelPaging)); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "!!!! Page-table type 0x%X is not supported!!!!= \n", VtdUnitInfo->CapReg.Bits.SAGAW)); + return Status; } =20 - DomainNumber =3D (UINTN)1 << (UINT8) ((UINTN) VTdInfo->VtdUnitInfo[Ind= ex].CapReg.Bits.ND * 2 + 4); - if (VTdInfo->VtdUnitInfo[Index].PciDeviceInfo.PciDeviceDataNumber >=3D= DomainNumber) { - DEBUG ((DEBUG_ERROR, "!!!! Pci device Number(0x%x) >=3D DomainNumber= (0x%x) !!!!\n", VTdInfo->VtdUnitInfo[Index].PciDeviceInfo.PciDeviceDataNumb= er, DomainNumber)); - return EFI_UNSUPPORTED; + Status =3D PerpareCacheInvalidationInterface(VtdUnitInfo); + if (EFI_ERROR (Status)) { + return Status; } } + return EFI_SUCCESS; } - diff --git a/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/Inte= lVTdDmarPei.c b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/I= ntelVTdDmarPei.c index a8f7bfee..3d38cbee 100644 --- a/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/IntelVTdDma= rPei.c +++ b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/IntelVTdDma= rPei.c @@ -1,6 +1,6 @@ /** @file =20 - Copyright (c) 2020, Intel Corporation. All rights reserved.
+ Copyright (c) 2020 - 2021, Intel Corporation. All rights reserved.
=20 SPDX-License-Identifier: BSD-2-Clause-Patent =20 @@ -50,20 +50,20 @@ typedef struct { the device driver need use SetAttribute() to update the IOMMU attribute to request DMA access (read and/or write). =20 - @param[in] This The PPI instance pointer. - @param[in] DeviceHandle The device who initiates the DMA access re= quest. - @param[in] Mapping The mapping value returned from Map(). - @param[in] IoMmuAccess The IOMMU access. - - @retval EFI_SUCCESS The IoMmuAccess is set for the memory rang= e specified by DeviceAddress and Length. - @retval EFI_INVALID_PARAMETER Mapping is not a value that was returned b= y Map(). - @retval EFI_INVALID_PARAMETER IoMmuAccess specified an illegal combinati= on of access. - @retval EFI_UNSUPPORTED The bit mask of IoMmuAccess is not support= ed by the IOMMU. - @retval EFI_UNSUPPORTED The IOMMU does not support the memory rang= e specified by Mapping. - @retval EFI_OUT_OF_RESOURCES There are not enough resources available t= o modify the IOMMU access. - @retval EFI_DEVICE_ERROR The IOMMU device reported an error while a= ttempting the operation. - @retval EFI_NOT_AVAILABLE_YET DMA protection has been enabled, but DMA b= uffer are - not available to be allocated yet. + @param[in] This The PPI instance pointer. + @param[in] DeviceHandle The device who initiates the DMA acces= s request. + @param[in] Mapping The mapping value returned from Map(). + @param[in] IoMmuAccess The IOMMU access. + + @retval EFI_SUCCESS The IoMmuAccess is set for the memory = range specified by DeviceAddress and Length. + @retval EFI_INVALID_PARAMETER Mapping is not a value that was return= ed by Map(). + @retval EFI_INVALID_PARAMETER IoMmuAccess specified an illegal combi= nation of access. + @retval EFI_UNSUPPORTED The bit mask of IoMmuAccess is not sup= ported by the IOMMU. + @retval EFI_UNSUPPORTED The IOMMU does not support the memory = range specified by Mapping. + @retval EFI_OUT_OF_RESOURCES There are not enough resources availab= le to modify the IOMMU access. + @retval EFI_DEVICE_ERROR The IOMMU device reported an error whi= le attempting the operation. + @retval EFI_NOT_AVAILABLE_YET DMA protection has been enabled, but D= MA buffer are + not available to be allocated yet. **/ EFI_STATUS EFIAPI @@ -93,22 +93,22 @@ PeiIoMmuSetAttribute ( Provides the controller-specific addresses required to access system mem= ory from a DMA bus master. =20 - @param This The PPI instance pointer. - @param Operation Indicates if the bus master is going to re= ad or write to system memory. - @param HostAddress The system memory address to map to the PC= I controller. - @param NumberOfBytes On input the number of bytes to map. On ou= tput the number of bytes - that were mapped. - @param DeviceAddress The resulting map address for the bus mast= er PCI controller to use to - access the hosts HostAddress. - @param Mapping A resulting value to pass to Unmap(). - - @retval EFI_SUCCESS The range was mapped for the returned Numb= erOfBytes. - @retval EFI_UNSUPPORTED The HostAddress cannot be mapped as a comm= on buffer. - @retval EFI_INVALID_PARAMETER One or more parameters are invalid. - @retval EFI_OUT_OF_RESOURCES The request could not be completed due to = a lack of resources. - @retval EFI_DEVICE_ERROR The system hardware could not map the requ= ested address. - @retval EFI_NOT_AVAILABLE_YET DMA protection has been enabled, but DMA b= uffer are - not available to be allocated yet. + @param [in] This The PPI instance pointer. + @param [in] Operation Indicates if the bus master is going t= o read or write to system memory. + @param [in] HostAddress The system memory address to map to th= e PCI controller. + @param [in] [out] NumberOfBytes On input the number of bytes to map. O= n output the number of bytes + that were mapped. + @param [out] DeviceAddress The resulting map address for the bus = master PCI controller to use to + access the hosts HostAddress. + @param [out] Mapping A resulting value to pass to Unmap(). + + @retval EFI_SUCCESS The range was mapped for the returned = NumberOfBytes. + @retval EFI_UNSUPPORTED The HostAddress cannot be mapped as a = common buffer. + @retval EFI_INVALID_PARAMETER One or more parameters are invalid. + @retval EFI_OUT_OF_RESOURCES The request could not be completed due= to a lack of resources. + @retval EFI_DEVICE_ERROR The system hardware could not map the = requested address. + @retval EFI_NOT_AVAILABLE_YET DMA protection has been enabled, but D= MA buffer are + not available to be allocated yet. **/ EFI_STATUS EFIAPI @@ -140,7 +140,7 @@ PeiIoMmuMap ( =20 if (Operation =3D=3D EdkiiIoMmuOperationBusMasterCommonBuffer || Operation =3D=3D EdkiiIoMmuOperationBusMasterCommonBuffer64) { - *DeviceAddress =3D (UINTN)HostAddress; + *DeviceAddress =3D (UINTN) HostAddress; *Mapping =3D NULL; return EFI_SUCCESS; } @@ -184,14 +184,14 @@ PeiIoMmuMap ( /** Completes the Map() operation and releases any corresponding resources. =20 - @param This The PPI instance pointer. - @param Mapping The mapping value returned from Map(). + @param [in] This The PPI instance pointer. + @param [in] Mapping The mapping value returned from Map(). =20 - @retval EFI_SUCCESS The range was unmapped. - @retval EFI_INVALID_PARAMETER Mapping is not a value that was returned b= y Map(). - @retval EFI_DEVICE_ERROR The data was not committed to the target s= ystem memory. - @retval EFI_NOT_AVAILABLE_YET DMA protection has been enabled, but DMA b= uffer are - not available to be allocated yet. + @retval EFI_SUCCESS The range was unmapped. + @retval EFI_INVALID_PARAMETER Mapping is not a value that was return= ed by Map(). + @retval EFI_DEVICE_ERROR The data was not committed to the targ= et system memory. + @retval EFI_NOT_AVAILABLE_YET DMA protection has been enabled, but D= MA buffer are + not available to be allocated yet. **/ EFI_STATUS EFIAPI @@ -250,21 +250,21 @@ PeiIoMmuUnmap ( Allocates pages that are suitable for an OperationBusMasterCommonBuffer = or OperationBusMasterCommonBuffer64 mapping. =20 - @param This The PPI instance pointer. - @param MemoryType The type of memory to allocate, EfiBootSer= vicesData or - EfiRuntimeServicesData. - @param Pages The number of pages to allocate. - @param HostAddress A pointer to store the base system memory = address of the - allocated range. - @param Attributes The requested bit mask of attributes for t= he allocated range. - - @retval EFI_SUCCESS The requested memory pages were allocated. - @retval EFI_UNSUPPORTED Attributes is unsupported. The only legal = attribute bits are - MEMORY_WRITE_COMBINE, MEMORY_CACHED and DU= AL_ADDRESS_CYCLE. - @retval EFI_INVALID_PARAMETER One or more parameters are invalid. - @retval EFI_OUT_OF_RESOURCES The memory pages could not be allocated. - @retval EFI_NOT_AVAILABLE_YET DMA protection has been enabled, but DMA b= uffer are - not available to be allocated yet. + @param [in] This The PPI instance pointer. + @param [in] MemoryType The type of memory to allocate, EfiBoo= tServicesData or + EfiRuntimeServicesData. + @param [in] Pages The number of pages to allocate. + @param [in] [out] HostAddress A pointer to store the base system mem= ory address of the + allocated range. + @param [in] Attributes The requested bit mask of attributes f= or the allocated range. + + @retval EFI_SUCCESS The requested memory pages were alloca= ted. + @retval EFI_UNSUPPORTED Attributes is unsupported. The only le= gal attribute bits are + MEMORY_WRITE_COMBINE, MEMORY_CACHED an= d DUAL_ADDRESS_CYCLE. + @retval EFI_INVALID_PARAMETER One or more parameters are invalid. + @retval EFI_OUT_OF_RESOURCES The memory pages could not be allocate= d. + @retval EFI_NOT_AVAILABLE_YET DMA protection has been enabled, but D= MA buffer are + not available to be allocated yet. **/ EFI_STATUS EFIAPI @@ -307,15 +307,15 @@ PeiIoMmuAllocateBuffer ( /** Frees memory that was allocated with AllocateBuffer(). =20 - @param This The PPI instance pointer. - @param Pages The number of pages to free. - @param HostAddress The base system memory address of the allo= cated range. + @param [in] This The PPI instance pointer. + @param [in] Pages The number of pages to free. + @param [in] HostAddress The base system memory address of the = allocated range. =20 - @retval EFI_SUCCESS The requested memory pages were freed. - @retval EFI_INVALID_PARAMETER The memory range specified by HostAddress = and Pages - was not allocated with AllocateBuffer(). - @retval EFI_NOT_AVAILABLE_YET DMA protection has been enabled, but DMA b= uffer are - not available to be allocated yet. + @retval EFI_SUCCESS The requested memory pages were freed. + @retval EFI_INVALID_PARAMETER The memory range specified by HostAddr= ess and Pages + was not allocated with AllocateBuffer(= ). + @retval EFI_NOT_AVAILABLE_YET DMA protection has been enabled, but D= MA buffer are + not available to be allocated yet. **/ EFI_STATUS EFIAPI @@ -364,52 +364,147 @@ CONST EFI_PEI_PPI_DESCRIPTOR mIoMmuPpiList =3D { }; =20 /** - Release the momery in the Intel VTd Info + Get ACPI DMAT Table from EdkiiVTdInfo PPI =20 - @param[in] VTdInfo The VTd engine context information. + @retval Address ACPI DMAT Table address + @retval NULL Failed to get ACPI DMAT Table **/ -VOID -ReleaseVTdInfo ( - IN VTD_INFO *VTdInfo +EFI_ACPI_DMAR_HEADER * GetAcpiDmarTable ( + VOID ) { - UINTN Index; + EFI_STATUS Status; + EFI_ACPI_DMAR_HEADER *AcpiDmarTable; =20 - for (Index =3D 0; Index < VTdInfo->VTdEngineCount; Index++) { - DEBUG ((DEBUG_INFO, "Release momery in VTdInfo[%d]\n", Index)); + // + // Get the DMAR table + // + Status =3D PeiServicesLocatePpi ( + &gEdkiiVTdInfoPpiGuid, + 0, + NULL, + (VOID **)&AcpiDmarTable + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Fail to get ACPI DMAR Table : %r\n", Status)); + AcpiDmarTable =3D NULL; + } else { + DumpAcpiDMAR (AcpiDmarTable); + } =20 - if (VTdInfo->VtdUnitInfo[Index].FixedSecondLevelPagingEntry) { - FreePages ((VOID *) (UINTN) VTdInfo->VtdUnitInfo[Index].FixedSecondL= evelPagingEntry, 1); - VTdInfo->VtdUnitInfo[Index].FixedSecondLevelPagingEntry =3D 0; - } + return AcpiDmarTable; +} =20 - if (VTdInfo->VtdUnitInfo[Index].RmrrSecondLevelPagingEntry) { - FreePages ((VOID *) (UINTN) VTdInfo->VtdUnitInfo[Index].RmrrSecondLe= velPagingEntry, 1); - VTdInfo->VtdUnitInfo[Index].RmrrSecondLevelPagingEntry =3D 0; - } +/** + Get the VTd engine context information hob. =20 - if (VTdInfo->VtdUnitInfo[Index].RootEntryTable) { - FreePages ((VOID *) (UINTN) VTdInfo->VtdUnitInfo[Index].RootEntryTab= le, VTdInfo->VtdUnitInfo[Index].RootEntryTablePageSize); - VTdInfo->VtdUnitInfo[Index].RootEntryTable =3D 0; - } + @retval The VTd engine context information. =20 - if (VTdInfo->VtdUnitInfo[Index].ExtRootEntryTable) { - FreePages ((VOID *) (UINTN) VTdInfo->VtdUnitInfo[Index].ExtRootEntry= Table, VTdInfo->VtdUnitInfo[Index].ExtRootEntryTablePageSize); - VTdInfo->VtdUnitInfo[Index].RootEntryTable =3D 0; +**/ +VTD_INFO * +GetVTdInfoHob ( + VOID + ) +{ + VOID *Hob; + VTD_INFO *VTdInfo; + + Hob =3D GetFirstGuidHob (&mVTdInfoGuid); + if (Hob =3D=3D NULL) { + VTdInfo =3D BuildGuidHob (&mVTdInfoGuid, sizeof (VTD_INFO)); + if (VTdInfo !=3D NULL) { + ZeroMem (VTdInfo, sizeof (VTD_INFO)); } + } else { + VTdInfo =3D GET_GUID_HOB_DATA(Hob); + } + return VTdInfo; +} + +/** + Callback function of parse DMAR DRHD table in pre-memory phase. =20 - if (VTdInfo->VtdUnitInfo[Index].PciDeviceInfo.PciDeviceData) { - FreePages ((VOID *) (UINTN) VTdInfo->VtdUnitInfo[Index].PciDeviceInf= o.PciDeviceData, VTdInfo->VtdUnitInfo[Index].PciDeviceInfo.PciDeviceDataPag= eSize); - VTdInfo->VtdUnitInfo[Index].PciDeviceInfo.PciDeviceDataPageSize =3D = 0; - VTdInfo->VtdUnitInfo[Index].PciDeviceInfo.PciDeviceData =3D 0; - VTdInfo->VtdUnitInfo[Index].PciDeviceInfo.PciDeviceDataNumber =3D 0; - VTdInfo->VtdUnitInfo[Index].PciDeviceInfo.PciDeviceDataMaxNumber =3D= 0; + @param [in] [out] Context Callback function context. + @param [in] VTdIndex The VTd engine index. + @param [in] DmarDrhd The DRHD table. + +**/ +VOID +ProcessDhrdPreMemory ( + IN OUT VOID *Context, + IN UINT32 VTdIndex, + IN EFI_ACPI_DMAR_DRHD_HEADER *DmarDrhd + ) +{ + DEBUG ((DEBUG_INFO,"VTD (%d) BaseAddress - 0x%016lx\n", VTdIndex, DmarD= rhd->RegisterBaseAddress)); + + EnableVTdTranslationProtectionBlockDma ((UINTN) DmarDrhd->RegisterBaseAd= dress); +} + + +/** + Compare 2 RMRR contexts are same or not. + + @param[in] Destin Destiny RMRR Info + @param[in] Source Source RMRR Info + + @retval Same or not same + +**/ +BOOLEAN +CompareVTdRmrrInfo ( + IN VTD_RMRR_INFO *Destin, + IN VTD_RMRR_INFO *Source + ) +{ + UINTN InfoSize; + + if ((Destin =3D=3D NULL) && (Source =3D=3D NULL)) { + return TRUE; + } + + if ((Destin !=3D NULL) && (Source !=3D NULL)) { + if (Destin->DeviceNumber =3D=3D Source->DeviceNumber) { + InfoSize =3D sizeof (VTD_RMRR_INFO) - sizeof (VTD_SOURCE_ID) + sizeo= f (VTD_SOURCE_ID) * Destin->DeviceNumber; + if (CompareMem (Destin, Source, InfoSize) =3D=3D 0) { + return TRUE; + } } } + return FALSE; +} + +/** + Callback function of parse DMAR DRHD table in post memory phase. + + @param [in] [out] Context Callback function context. + @param [in] VTdIndex The VTd engine index. + @param [in] DmarDrhd The DRHD table. + +**/ +VOID +ProcessDrhdPostMemory ( + IN OUT VOID *Context, + IN UINT32 VTdIndex, + IN EFI_ACPI_DMAR_DRHD_HEADER *DmarDrhd + ) +{ + VTD_UNIT_INFO *VtdUnitInfo; + + VtdUnitInfo =3D (VTD_UNIT_INFO *) Context; + VtdUnitInfo +=3D VTdIndex; + + VtdUnitInfo->Done =3D FALSE; + VtdUnitInfo->VtdUnitBaseAddress =3D (UINTN) DmarDrhd->RegisterBaseAddres= s; + VtdUnitInfo->Segment =3D DmarDrhd->SegmentNumber; + VtdUnitInfo->Flags =3D DmarDrhd->Flags; + + DEBUG ((DEBUG_INFO,"VTD (%d) BaseAddress - 0x%016lx\n", VTdIndex, DmarD= rhd->RegisterBaseAddress)); + DEBUG ((DEBUG_INFO," Segment - %d, Flags - 0x%x\n", DmarDrhd->Segment= Number, DmarDrhd->Flags)); } =20 /** - Initializes the Intel VTd Info. + Initializes the Intel VTd Info in post memory phase. =20 @retval EFI_SUCCESS Usb bot driver is successfully initialized. @retval EFI_OUT_OF_RESOURCES Can't initialize the driver. @@ -419,89 +514,96 @@ InitVTdInfo ( VOID ) { - EFI_STATUS Status; EFI_ACPI_DMAR_HEADER *AcpiDmarTable; - VOID *Hob; + VTD_RMRR_INFO *RmrrInfo; + BOOLEAN RmrrInfoEqual; VTD_INFO *VTdInfo; - UINT64 EngineMask; - - Status =3D PeiServicesLocatePpi ( - &gEdkiiVTdInfoPpiGuid, - 0, - NULL, - (VOID **)&AcpiDmarTable - ); - ASSERT_EFI_ERROR (Status); + VTD_UNIT_INFO *VtdUnitInfo; + UINTN VtdUnitNumber; + EFI_STATUS Status; + UINTN i; + UINTN j; =20 - DumpAcpiDMAR (AcpiDmarTable); + VTdInfo =3D GetVTdInfoHob (); + ASSERT (VTdInfo !=3D NULL); =20 - // - // Clear old VTdInfo Hob. - // - Hob =3D GetFirstGuidHob (&mVTdInfoGuid); - if (Hob !=3D NULL) { - DEBUG ((DEBUG_INFO, " Find Hob : mVTdInfoGuid - 0x%x\n", Hob)); + AcpiDmarTable =3D GetAcpiDmarTable (); + ASSERT (AcpiDmarTable !=3D NULL); =20 - VTdInfo =3D GET_GUID_HOB_DATA(Hob); - EngineMask =3D LShiftU64 (1, VTdInfo->VTdEngineCount) - 1; - EnableVTdTranslationProtectionAll (VTdInfo, EngineMask); - - ReleaseVTdInfo (VTdInfo); - VTdInfo->VTdEngineCount =3D 0; + VtdUnitNumber =3D GetVtdEngineNumber (AcpiDmarTable); + if (VtdUnitNumber =3D=3D 0) { + return EFI_UNSUPPORTED; + } + RmrrInfo =3D GetVtdRmrrInfo (AcpiDmarTable); + RmrrInfoEqual =3D CompareVTdRmrrInfo (VTdInfo->VtdRmrrInfo, RmrrInfo); =20 - ZeroMem (&((EFI_HOB_GUID_TYPE *) Hob)->Name, sizeof (EFI_GUID)); + VtdUnitInfo =3D AllocateZeroPages (EFI_SIZE_TO_PAGES (sizeof (VTD_UNIT_I= NFO) * VtdUnitNumber)); + if (VtdUnitInfo =3D=3D NULL) { + DEBUG ((DEBUG_ERROR, "InitVTdInfo - OUT_OF_RESOURCE\n")); + ASSERT (FALSE); + return EFI_OUT_OF_RESOURCES; } =20 - // - // Get DMAR information to local VTdInfo - // - Status =3D ParseDmarAcpiTableDrhd (AcpiDmarTable); - if (EFI_ERROR(Status)) { - DEBUG ((DEBUG_ERROR, " ParseDmarAcpiTableDrhd : %r\n", Status)); + Status =3D ParseDmarAcpiTableDrhd (AcpiDmarTable, ProcessDrhdPostMemory,= VtdUnitInfo); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); return Status; } =20 // - // NOTE: Do not parse RMRR here, because RMRR may cause DMAR programming. + // Check Host Address Width // + if ((AcpiDmarTable->HostAddressWidth =3D=3D VTdInfo->HostAddressWidth) &= & RmrrInfoEqual) { + for (i =3D 0; i < VtdUnitNumber; i++) { + // + // Scan each new Vtd Unit + // + for (j =3D 0; j < VTdInfo->VTdEngineCount; j++) { + // + // Compare the new Vtd Unit with each exist VTd Unit + // + if (VtdUnitInfo[i].VtdUnitBaseAddress =3D=3D VTdInfo->VtdUnitInfo[= j].VtdUnitBaseAddress) { + DEBUG ((DEBUG_INFO,"Find VTD [0x%08x] Exist\n", VtdUnitInfo[i].V= tdUnitBaseAddress)); + CopyMem (&VtdUnitInfo[i], &VTdInfo->VtdUnitInfo[j], sizeof (VTD_= UNIT_INFO)); + VtdUnitInfo[i].Done =3D TRUE; + + break; + } + } + } + } + VTdInfo->AcpiDmarTable =3D AcpiDmarTable; + VTdInfo->HostAddressWidth =3D AcpiDmarTable->HostAddressWidth; + VTdInfo->VTdEngineCount =3D VtdUnitNumber; + VTdInfo->VtdUnitInfo =3D VtdUnitInfo; + VTdInfo->VtdRmrrInfo =3D RmrrInfo; =20 return EFI_SUCCESS; } =20 /** - Initializes the Intel VTd DMAR for all memory. + Initializes the Intel VTd DMAR for block all DMA. =20 @retval EFI_SUCCESS Driver is successfully initialized. @retval RETURN_NOT_READY Fail to get VTdInfo Hob . **/ EFI_STATUS -InitVTdDmarForAll ( +InitVTdDmarBlockAll ( VOID ) { - VOID *Hob; - VTD_INFO *VTdInfo; - UINT64 EngineMask; - EFI_STATUS Status; - - Hob =3D GetFirstGuidHob (&mVTdInfoGuid); - if (Hob =3D=3D NULL) { - DEBUG ((DEBUG_ERROR, "Fail to get VTdInfo Hob.\n")); - return RETURN_NOT_READY; - } - VTdInfo =3D GET_GUID_HOB_DATA (Hob); - EngineMask =3D LShiftU64 (1, VTdInfo->VTdEngineCount) - 1; - - DEBUG ((DEBUG_INFO, "PrepareVtdConfig\n")); - Status =3D PrepareVtdConfig (VTdInfo); - if (EFI_ERROR (Status)) { - ASSERT_EFI_ERROR (Status); - return Status; - } + EFI_ACPI_DMAR_HEADER *AcpiDmarTable; =20 - EnableVTdTranslationProtectionAll (VTdInfo, EngineMask); + // + // Get the DMAR table + // + AcpiDmarTable =3D GetAcpiDmarTable (); + ASSERT (AcpiDmarTable !=3D NULL); =20 - return EFI_SUCCESS; + // + // Parse the DMAR table and block all DMA + // + return ParseDmarAcpiTableDrhd (AcpiDmarTable, ProcessDhrdPreMemory, NULL= ); } =20 /** @@ -524,8 +626,8 @@ InitDmaBuffer( DEBUG ((DEBUG_INFO, "InitDmaBuffer :\n")); =20 Hob =3D GetFirstGuidHob (&mDmaBufferInfoGuid); + ASSERT(Hob !=3D NULL); DmaBufferInfo =3D GET_GUID_HOB_DATA (Hob); - VtdPmrHobPtr =3D GetFirstGuidHob (&gVtdPmrInfoDataHobGuid); =20 /** When gVtdPmrInfoDataHobGuid exists, it means: @@ -535,7 +637,7 @@ InitDmaBuffer( 4. Protection regions will be conveyed through VTD_PMR_INFO_HOB =20 When gVtdPmrInfoDataHobGuid dosen't exist, it means: - 1. IntelVTdDmar driver will calcuate the PMR memory alignment + 1. IntelVTdDmarPei driver will calcuate the protected memory alignment 2. Dma buffer is reserved by AllocateAlignedPages() **/ =20 @@ -545,33 +647,40 @@ InitDmaBuffer( return EFI_INVALID_PARAMETER; } =20 - if (VtdPmrHobPtr =3D=3D NULL) { - // - // Allocate memory for DMA buffer - // - DmaBufferInfo->DmaBufferBase =3D (UINT64) (UINTN) AllocateAlignedPages= (EFI_SIZE_TO_PAGES ((UINTN) DmaBufferInfo->DmaBufferSize), 0); - if (DmaBufferInfo->DmaBufferBase =3D=3D 0) { - DEBUG ((DEBUG_ERROR, " InitDmaBuffer : OutOfResource\n")); - return EFI_OUT_OF_RESOURCES; + if (DmaBufferInfo->DmaBufferBase =3D=3D 0) { + VtdPmrHobPtr =3D GetFirstGuidHob (&gVtdPmrInfoDataHobGuid); + if (VtdPmrHobPtr !=3D NULL) { + // + // Get the protected memory ranges information from the VTd PMR hob + // + VtdPmrHob =3D GET_GUID_HOB_DATA (VtdPmrHobPtr); + + if ((VtdPmrHob->ProtectedHighBase - VtdPmrHob->ProtectedLowLimit) < = DmaBufferInfo->DmaBufferSize) { + DEBUG ((DEBUG_ERROR, " DmaBufferSize not enough\n")); + return EFI_INVALID_PARAMETER; + } + DmaBufferInfo->DmaBufferBase =3D VtdPmrHob->ProtectedLowLimit; + } else { + // + // Allocate memory for DMA buffer + // + DmaBufferInfo->DmaBufferBase =3D (UINTN) AllocateAlignedPages (EFI_S= IZE_TO_PAGES (DmaBufferInfo->DmaBufferSize), 0); + if (DmaBufferInfo->DmaBufferBase =3D=3D 0) { + DEBUG ((DEBUG_ERROR, " InitDmaBuffer : OutOfResource\n")); + return EFI_OUT_OF_RESOURCES; + } + DEBUG ((DEBUG_INFO, "Alloc DMA buffer success.\n")); } - DmaBufferInfo->DmaBufferLimit =3D DmaBufferInfo->DmaBufferBase + DmaBu= fferInfo->DmaBufferSize; - DEBUG ((DEBUG_INFO, "Alloc DMA buffer success.\n")); - } else { - // - // Get the PMR ranges information for the VTd PMR hob - // - VtdPmrHob =3D GET_GUID_HOB_DATA (VtdPmrHobPtr); - DmaBufferInfo->DmaBufferBase =3D VtdPmrHob->ProtectedLowLimit; - DmaBufferInfo->DmaBufferLimit =3D VtdPmrHob->ProtectedHighBase; + + DmaBufferInfo->DmaBufferCurrentTop =3D DmaBufferInfo->DmaBufferBase + = DmaBufferInfo->DmaBufferSize; + DmaBufferInfo->DmaBufferCurrentBottom =3D DmaBufferInfo->DmaBufferBase; + + DEBUG ((DEBUG_INFO, " DmaBufferSize : 0x%x\n", DmaBufferInfo-= >DmaBufferSize)); + DEBUG ((DEBUG_INFO, " DmaBufferBase : 0x%x\n", DmaBufferInfo-= >DmaBufferBase)); } - DmaBufferInfo->DmaBufferCurrentTop =3D DmaBufferInfo->DmaBufferBase + Dm= aBufferInfo->DmaBufferSize; - DmaBufferInfo->DmaBufferCurrentBottom =3D DmaBufferInfo->DmaBufferBase; =20 - DEBUG ((DEBUG_INFO, " DmaBufferSize : 0x%lx\n", DmaBufferInfo->= DmaBufferSize)); - DEBUG ((DEBUG_INFO, " DmaBufferBase : 0x%lx\n", DmaBufferInfo->= DmaBufferBase)); - DEBUG ((DEBUG_INFO, " DmaBufferLimit : 0x%lx\n", DmaBufferInfo->= DmaBufferLimit)); - DEBUG ((DEBUG_INFO, " DmaBufferCurrentTop : 0x%lx\n", DmaBufferInfo->= DmaBufferCurrentTop)); - DEBUG ((DEBUG_INFO, " DmaBufferCurrentBottom : 0x%lx\n", DmaBufferInfo->= DmaBufferCurrentBottom)); + DEBUG ((DEBUG_INFO, " DmaBufferCurrentTop : 0x%x\n", DmaBufferInfo->D= maBufferCurrentTop)); + DEBUG ((DEBUG_INFO, " DmaBufferCurrentBottom : 0x%x\n", DmaBufferInfo->D= maBufferCurrentBottom)); =20 return EFI_SUCCESS; } @@ -588,14 +697,14 @@ InitVTdDmarForDma ( VOID ) { - VOID *Hob; VTD_INFO *VTdInfo; + EFI_STATUS Status; EFI_PEI_PPI_DESCRIPTOR *OldDescriptor; EDKII_IOMMU_PPI *OldIoMmuPpi; =20 - Hob =3D GetFirstGuidHob (&mVTdInfoGuid); - VTdInfo =3D GET_GUID_HOB_DATA (Hob); + VTdInfo =3D GetVTdInfoHob (); + ASSERT (VTdInfo !=3D NULL); =20 DEBUG ((DEBUG_INFO, "PrepareVtdConfig\n")); Status =3D PrepareVtdConfig (VTdInfo); @@ -604,13 +713,6 @@ InitVTdDmarForDma ( return Status; } =20 - DEBUG ((DEBUG_INFO, "PrepareVtdCacheInvalidationConfig\n")); - Status =3D PrepareVtdCacheInvalidationConfig (VTdInfo); - if (EFI_ERROR (Status)) { - ASSERT_EFI_ERROR (Status); - return Status; - } - // create root entry table DEBUG ((DEBUG_INFO, "SetupTranslationTable\n")); Status =3D SetupTranslationTable (VTdInfo); @@ -620,8 +722,11 @@ InitVTdDmarForDma ( } =20 // If there is RMRR memory, parse it here. - DEBUG ((DEBUG_INFO, "PeiParseDmarAcpiTableRmrr\n")); - ParseDmarAcpiTableRmrr (VTdInfo); + Status =3D SetupRmrr (VTdInfo); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return Status; + } =20 DEBUG ((DEBUG_INFO, "EnableVtdDmar\n")); Status =3D EnableVTdTranslationProtection(VTdInfo); @@ -668,21 +773,10 @@ S3EndOfPeiNotify( IN VOID *Ppi ) { - VOID *Hob; - VTD_INFO *VTdInfo; - UINT64 EngineMask; - DEBUG((DEBUG_INFO, "VTd DMAR PEI S3EndOfPeiNotify\n")); =20 if ((PcdGet8(PcdVTdPolicyPropertyMask) & BIT1) =3D=3D 0) { - Hob =3D GetFirstGuidHob (&mVTdInfoGuid); - if (Hob =3D=3D NULL) { - return EFI_SUCCESS; - } - VTdInfo =3D GET_GUID_HOB_DATA(Hob); - - EngineMask =3D LShiftU64 (1, VTdInfo->VTdEngineCount) - 1; - DisableVTdTranslationProtection (VTdInfo, EngineMask); + DisableVTdTranslationProtection (GetVTdInfoHob ()); } return EFI_SUCCESS; } @@ -733,18 +827,13 @@ VTdInfoNotify ( =20 DEBUG ((DEBUG_INFO, "MemoryInitialized - %x\n", MemoryInitialized)); =20 - // - // NOTE: We need reinit VTdInfo because previous information might be ov= erriden. - // - InitVTdInfo (); - if (!MemoryInitialized) { // // If the memory is not initialized, // Protect all system memory // =20 - InitVTdDmarForAll (); + InitVTdDmarBlockAll (); =20 // // Install PPI. @@ -758,9 +847,16 @@ VTdInfoNotify ( // =20 Status =3D InitDmaBuffer (); - ASSERT_EFI_ERROR(Status); + ASSERT_EFI_ERROR (Status); =20 - InitVTdDmarForDma (); + // + // NOTE: We need reinit VTdInfo because previous information might be = overriden. + // + Status =3D InitVTdInfo (); + ASSERT_EFI_ERROR (Status); + + Status =3D InitVTdDmarForDma (); + ASSERT_EFI_ERROR (Status); } =20 return EFI_SUCCESS; @@ -826,4 +922,3 @@ IntelVTdDmarInitialize ( =20 return EFI_SUCCESS; } - diff --git a/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/Inte= lVTdDmarPei.h b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/I= ntelVTdDmarPei.h index e23a6c8e..e1894e39 100644 --- a/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/IntelVTdDma= rPei.h +++ b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/IntelVTdDma= rPei.h @@ -9,68 +9,71 @@ #ifndef __DMA_ACCESS_LIB_H__ #define __DMA_ACCESS_LIB_H__ =20 -#define MAX_VTD_PCI_DATA_NUMBER 0x100 - #define VTD_64BITS_ADDRESS(Lo, Hi) (LShiftU64 (Lo, 12) | LShiftU64 (Hi, 32= )) =20 typedef struct { - UINT8 DeviceType; - VTD_SOURCE_ID PciSourceId; -} PEI_PCI_DEVICE_DATA; - -typedef struct { - BOOLEAN IncludeAllFlag; - UINT32 PciDeviceDataNumber; - UINT32 PciDeviceDataMaxNumber; - UINT32 PciDeviceDataPageSize; - UINT32 PciDeviceData; -} PEI_PCI_DEVICE_INFORMATION; + UINT16 SegmentNumber; + UINT64 ReservedMemoryRegionBaseAddress; + UINT64 ReservedMemoryRegionLimitAddress; + UINTN DeviceNumber; + VTD_SOURCE_ID SourceId[1]; +} VTD_RMRR_INFO; =20 typedef struct { - UINT32 VtdUnitBaseAddress; + BOOLEAN Done; + UINTN VtdUnitBaseAddress; UINT16 Segment; + UINT8 Flags; VTD_VER_REG VerReg; VTD_CAP_REG CapReg; VTD_ECAP_REG ECapReg; BOOLEAN Is5LevelPaging; - UINT32 FixedSecondLevelPagingEntry; - UINT32 RmrrSecondLevelPagingEntry; - UINT32 RootEntryTable; - UINT32 ExtRootEntryTable; - UINT16 RootEntryTablePageSize; - UINT16 ExtRootEntryTablePageSize; - PEI_PCI_DEVICE_INFORMATION PciDeviceInfo; UINT8 EnableQueuedInvalidation; - UINT16 QiDescLength; + UINT16 QueueSize; QI_DESC *QiDesc; UINT16 QiFreeHead; + UINTN FixedSecondLevelPagingEntry; + UINTN RootEntryTable; + UINTN ExtRootEntryTable; + UINTN RootEntryTablePageSize; + UINTN ExtRootEntryTablePageSize; + UINTN RmrrSecondLevelPagingEntry; } VTD_UNIT_INFO; =20 typedef struct { - UINT32 AcpiDmarTable; + EFI_ACPI_DMAR_HEADER *AcpiDmarTable; UINT8 HostAddressWidth; - UINT32 VTdEngineCount; - VTD_UNIT_INFO VtdUnitInfo[1]; + UINTN VTdEngineCount; + VTD_UNIT_INFO *VtdUnitInfo; + VTD_RMRR_INFO *VtdRmrrInfo; } VTD_INFO; =20 typedef struct { - UINT64 DmaBufferBase; - UINT64 DmaBufferSize; - UINT64 DmaBufferLimit; - UINT64 DmaBufferCurrentTop; - UINT64 DmaBufferCurrentBottom; + UINTN DmaBufferBase; + UINTN DmaBufferSize; + UINTN DmaBufferCurrentTop; + UINTN DmaBufferCurrentBottom; } DMA_BUFFER_INFO; =20 +typedef +VOID +(*PROCESS_DRHD_CALLBACK_FUNC) ( + IN OUT VOID *Context, + IN UINT32 VTdIndex, + IN EFI_ACPI_DMAR_DRHD_HEADER *DmarDrhd + ); + /** - Enable VTd translation table protection. + Enable VTd translation table protection for block DMA =20 - @param[in] VTdInfo The VTd engine context information. - @param[in] EngineMask The mask of the VTd engine to be accessed. + @param[in] VtdUnitBaseAddress The base address of the VTd engine. + + @retval EFI_SUCCESS DMAR translation is enabled. + @retval EFI_DEVICE_ERROR DMAR translation is not enabled. **/ -VOID -EnableVTdTranslationProtectionAll ( - IN VTD_INFO *VTdInfo, - IN UINT64 EngineMask +EFI_STATUS +EnableVTdTranslationProtectionBlockDma ( + IN UINTN VtdUnitBaseAddress ); =20 /** @@ -90,34 +93,39 @@ EnableVTdTranslationProtection ( Disable VTd translation table protection. =20 @param[in] VTdInfo The VTd engine context information. - @param[in] EngineMask The mask of the VTd engine to be accessed. **/ VOID DisableVTdTranslationProtection ( - IN VTD_INFO *VTdInfo, - IN UINT64 EngineMask + IN VTD_INFO *VTdInfo ); =20 /** Parse DMAR DRHD table. =20 @param[in] AcpiDmarTable DMAR ACPI table + @param[in] Callback Callback function for handle DRHD + @param[in] Context Callback function Context + + @return EFI_SUCCESS The DMAR DRHD table is parsed. =20 - @return EFI_SUCCESS The DMAR DRHD table is parsed. **/ EFI_STATUS ParseDmarAcpiTableDrhd ( - IN EFI_ACPI_DMAR_HEADER *AcpiDmarTable + IN EFI_ACPI_DMAR_HEADER *AcpiDmarTable, + IN PROCESS_DRHD_CALLBACK_FUNC Callback, + IN VOID *Context ); =20 /** - Parse DMAR DRHD table. + Get RMRR Info from ACPI DMAR Table. =20 - @param[in] VTdInfo The VTd engine context information. + @param[in] AcpiDmarTable DMAR ACPI table + + @return the VTd engine number. **/ -VOID -ParseDmarAcpiTableRmrr ( - IN VTD_INFO *VTdInfo +VTD_RMRR_INFO * +GetVtdRmrrInfo ( + IN EFI_ACPI_DMAR_HEADER *AcpiDmarTable ); =20 /** @@ -167,6 +175,30 @@ SetupTranslationTable ( IN VTD_INFO *VTdInfo ); =20 +/** + Get VTd engine number. + + @param[in] AcpiDmarTable DMAR ACPI table + + @return the VTd engine number. +**/ +UINTN +GetVtdEngineNumber ( + IN EFI_ACPI_DMAR_HEADER *AcpiDmarTable + ); + +/** + Setup VTd RMRR in translation table. + + @param[in] VTdInfo The VTd engine context information. + + @return the VTd engine number. +**/ +EFI_STATUS +SetupRmrr ( + IN VTD_INFO *VTdInfo + ); + /** Flush VTD page table and context table memory. =20 @@ -240,4 +272,3 @@ extern EFI_GUID mVTdInfoGuid; extern EFI_GUID mDmaBufferInfoGuid; =20 #endif - diff --git a/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/Tran= slationTable.c b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/= TranslationTable.c index a309d566..2e14632a 100644 --- a/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/Translation= Table.c +++ b/Silicon/Intel/IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/Translation= Table.c @@ -1,6 +1,7 @@ /** @file =20 Copyright (c) 2020 - 2021, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent =20 **/ @@ -129,12 +130,12 @@ CreateSecondLevelPagingEntryTable ( FlushPageTableMemory (VTdUnitInfo, (UINTN) SecondLevelPagingEntry, EFI= _PAGES_TO_SIZE (1)); } =20 - DEBUG ((DEBUG_INFO, " SecondLevelPagingEntry:0x%016lx\n", SecondLevelPag= ingEntry)); + DEBUG ((DEBUG_INFO, " SecondLevelPagingEntry:0x%016lx\n", (UINT64) (UINT= N) SecondLevelPagingEntry)); // // If no access is needed, just create not present entry. // if (IoMmuAccess =3D=3D 0) { - DEBUG ((DEBUG_INFO, " SecondLevelPagingEntry:0x%016lx\n", (UINTN) Seco= ndLevelPagingEntry)); + DEBUG ((DEBUG_INFO, " SecondLevelPagingEntry:0x%016lx Access 0\n", (UI= NT64) (UINTN) SecondLevelPagingEntry)); return SecondLevelPagingEntry; } =20 @@ -244,7 +245,7 @@ CreateSecondLevelPagingEntryTable ( } FlushPageTableMemory (VTdUnitInfo, (UINTN) &Lvl5PtEntry[Lvl5Start], (UIN= TN) &Lvl5PtEntry[Lvl5End + 1] - (UINTN) &Lvl5PtEntry[Lvl5Start]); =20 - DEBUG ((DEBUG_INFO, " SecondLevelPagingEntry:0x%016lx\n", (UINTN)SecondL= evelPagingEntry)); + DEBUG ((DEBUG_INFO, " SecondLevelPagingEntry:0x%016lx\n", (UINT64) (UINT= N) SecondLevelPagingEntry)); return SecondLevelPagingEntry; } =20 @@ -276,6 +277,10 @@ CreateContextEntry ( VTD_SECOND_LEVEL_PAGING_ENTRY *SecondLevelPagingEntry; UINT64 Pt; =20 + if (VTdUnitInfo->RootEntryTable !=3D 0) { + return EFI_SUCCESS; + } + RootPages =3D EFI_SIZE_TO_PAGES (sizeof (VTD_ROOT_ENTRY) * VTD_ROOT_ENTR= Y_NUMBER); ContextPages =3D EFI_SIZE_TO_PAGES (sizeof (VTD_CONTEXT_ENTRY) * VTD_CON= TEXT_ENTRY_NUMBER); EntryTablePages =3D RootPages + ContextPages * (VTD_ROOT_ENTRY_NUMBER); @@ -286,8 +291,8 @@ CreateContextEntry ( } =20 DEBUG ((DEBUG_ERROR, "RootEntryTable address - 0x%x\n", Buffer)); - VTdUnitInfo->RootEntryTable =3D (UINT32) (UINTN) Buffer; - VTdUnitInfo->RootEntryTablePageSize =3D (UINT16) EntryTablePages; + VTdUnitInfo->RootEntryTable =3D (UINTN) Buffer; + VTdUnitInfo->RootEntryTablePageSize =3D EntryTablePages; RootEntryBase =3D (VTD_ROOT_ENTRY *) Buffer; Buffer =3D (UINT8 *) Buffer + EFI_PAGES_TO_SIZE (RootPages); =20 @@ -317,7 +322,7 @@ CreateContextEntry ( ContextEntry->Bits.AddressWidth =3D VTdUnitInfo->Is5LevelPaging ? 0x= 3 : 0x2; =20 if (VTdUnitInfo->FixedSecondLevelPagingEntry !=3D 0) { - SecondLevelPagingEntry =3D (VTD_SECOND_LEVEL_PAGING_ENTRY *) (UINT= N) VTdUnitInfo->FixedSecondLevelPagingEntry; + SecondLevelPagingEntry =3D (VTD_SECOND_LEVEL_PAGING_ENTRY *) VTdUn= itInfo->FixedSecondLevelPagingEntry; Pt =3D (UINT64)RShiftU64 ((UINT64) (UINTN) SecondLevelPagingEntry,= 12); ContextEntry->Bits.SecondLevelPageTranslationPointerLo =3D (UINT32= ) Pt; ContextEntry->Bits.SecondLevelPageTranslationPointerHi =3D (UINT32= ) RShiftU64(Pt, 20); @@ -359,6 +364,10 @@ CreateExtContextEntry ( VTD_SECOND_LEVEL_PAGING_ENTRY *SecondLevelPagingEntry; UINT64 Pt; =20 + if (VTdUnitInfo->ExtRootEntryTable !=3D 0) { + return EFI_SUCCESS; + } + RootPages =3D EFI_SIZE_TO_PAGES (sizeof (VTD_EXT_ROOT_ENTRY) * VTD_ROOT_= ENTRY_NUMBER); ContextPages =3D EFI_SIZE_TO_PAGES (sizeof (VTD_EXT_CONTEXT_ENTRY) * VTD= _CONTEXT_ENTRY_NUMBER); EntryTablePages =3D RootPages + ContextPages * (VTD_ROOT_ENTRY_NUMBER); @@ -369,8 +378,8 @@ CreateExtContextEntry ( } =20 DEBUG ((DEBUG_ERROR, "ExtRootEntryTable address - 0x%x\n", Buffer)); - VTdUnitInfo->ExtRootEntryTable =3D (UINT32) (UINTN) Buffer; - VTdUnitInfo->ExtRootEntryTablePageSize =3D (UINT16) EntryTablePages; + VTdUnitInfo->ExtRootEntryTable =3D (UINTN) Buffer; + VTdUnitInfo->ExtRootEntryTablePageSize =3D EntryTablePages; ExtRootEntryBase =3D (VTD_EXT_ROOT_ENTRY *) Buffer; Buffer =3D (UINT8 *) Buffer + EFI_PAGES_TO_SIZE (RootPages); =20 @@ -403,7 +412,7 @@ CreateExtContextEntry ( ExtContextEntry->Bits.AddressWidth =3D VTdUnitInfo->Is5LevelPaging ?= 0x3 : 0x2; =20 if (VTdUnitInfo->FixedSecondLevelPagingEntry !=3D 0) { - SecondLevelPagingEntry =3D (VTD_SECOND_LEVEL_PAGING_ENTRY *) (UINT= N) VTdUnitInfo->FixedSecondLevelPagingEntry; + SecondLevelPagingEntry =3D (VTD_SECOND_LEVEL_PAGING_ENTRY *) VTdUn= itInfo->FixedSecondLevelPagingEntry; Pt =3D (UINT64)RShiftU64 ((UINT64) (UINTN) SecondLevelPagingEntry,= 12); =20 ExtContextEntry->Bits.SecondLevelPageTranslationPointerLo =3D (UIN= T32) Pt; @@ -791,9 +800,6 @@ SetSecondLevelPagingAttribute ( SplitAttribute =3D NeedSplitPage (BaseAddress, Length, PageAttribute); if (SplitAttribute =3D=3D PageNone) { ConvertSecondLevelPageEntryAttribute (VTdUnitInfo, PageEntry, IoMmuA= ccess, &IsEntryModified); - if (IsEntryModified) { - //mVtdUnitInformation[VtdIndex].HasDirtyPages =3D TRUE; - } // // Convert success, move to next // @@ -805,7 +811,6 @@ SetSecondLevelPagingAttribute ( DEBUG ((DEBUG_ERROR, "SplitSecondLevelPage - %r\n", Status)); return RETURN_UNSUPPORTED; } - //mVtdUnitInformation[VtdIndex].HasDirtyPages =3D TRUE; // // Just split current page // Convert success in next around @@ -837,7 +842,11 @@ CreateFixedSecondLevelPagingEntry ( VOID *Hob; DMA_BUFFER_INFO *DmaBufferInfo; =20 - VTdUnitInfo->FixedSecondLevelPagingEntry =3D (UINT32) (UINTN) CreateSeco= ndLevelPagingEntryTable (VTdUnitInfo, NULL, 0, SIZE_4GB, 0); + if (VTdUnitInfo->FixedSecondLevelPagingEntry !=3D 0) { + return EFI_SUCCESS; + } + + VTdUnitInfo->FixedSecondLevelPagingEntry =3D (UINTN) CreateSecondLevelPa= gingEntryTable (VTdUnitInfo, NULL, 0, SIZE_4GB, 0); if (VTdUnitInfo->FixedSecondLevelPagingEntry =3D=3D 0) { DEBUG ((DEBUG_ERROR, "FixedSecondLevelPagingEntry is empty\n")); return EFI_OUT_OF_RESOURCES; @@ -846,14 +855,14 @@ CreateFixedSecondLevelPagingEntry ( Hob =3D GetFirstGuidHob (&mDmaBufferInfoGuid); DmaBufferInfo =3D GET_GUID_HOB_DATA (Hob); BaseAddress =3D DmaBufferInfo->DmaBufferBase; - Length =3D DmaBufferInfo->DmaBufferLimit - DmaBufferInfo->DmaBufferBase; + Length =3D DmaBufferInfo->DmaBufferSize; IoMmuAccess =3D EDKII_IOMMU_ACCESS_READ | EDKII_IOMMU_ACCESS_WRITE; =20 DEBUG ((DEBUG_INFO, " BaseAddress =3D 0x%lx\n", BaseAddress)); DEBUG ((DEBUG_INFO, " Length =3D 0x%lx\n", Length)); DEBUG ((DEBUG_INFO, " IoMmuAccess =3D 0x%lx\n", IoMmuAccess)); =20 - Status =3D SetSecondLevelPagingAttribute (VTdUnitInfo, (VTD_SECOND_LEVEL= _PAGING_ENTRY*) (UINTN) VTdUnitInfo->FixedSecondLevelPagingEntry, BaseAddre= ss, Length, IoMmuAccess); + Status =3D SetSecondLevelPagingAttribute (VTdUnitInfo, (VTD_SECOND_LEVEL= _PAGING_ENTRY*) VTdUnitInfo->FixedSecondLevelPagingEntry, BaseAddress, Leng= th, IoMmuAccess); =20 return Status; } @@ -877,6 +886,9 @@ SetupTranslationTable ( =20 for (Index =3D 0; Index < VTdInfo->VTdEngineCount; Index++) { VtdUnitInfo =3D &VTdInfo->VtdUnitInfo[Index]; + if (VtdUnitInfo->Done) { + continue; + } =20 Status =3D CreateFixedSecondLevelPagingEntry (VtdUnitInfo); if (EFI_ERROR (Status)) { @@ -912,83 +924,45 @@ SetupTranslationTable ( } =20 /** - Find the VTd index by the Segment and SourceId. + Setup VTd RMRR in translation table. =20 @param[in] VTdInfo The VTd engine context information. - @param[in] Segment The segment of the source. - @param[in] SourceId The SourceId of the source. - @param[out] ExtContextEntry The ExtContextEntry of the source. - @param[out] ContextEntry The ContextEntry of the source. =20 - @return The index of the VTd engine. - @retval (UINTN)-1 The VTd engine is not found. + @return the VTd engine number. **/ -UINTN -FindVtdIndexBySegmentSourceId ( - IN VTD_INFO *VTdInfo, - IN UINT16 Segment, - IN VTD_SOURCE_ID SourceId, - OUT VTD_EXT_CONTEXT_ENTRY **ExtContextEntry, - OUT VTD_CONTEXT_ENTRY **ContextEntry +EFI_STATUS +SetupRmrr ( + IN VTD_INFO *VTdInfo ) { - UINTN VtdIndex; - VTD_ROOT_ENTRY *RootEntryBase; - VTD_ROOT_ENTRY *RootEntry; - VTD_CONTEXT_ENTRY *ContextEntryTable; - VTD_CONTEXT_ENTRY *ThisContextEntry; - VTD_EXT_ROOT_ENTRY *ExtRootEntryBase; - VTD_EXT_ROOT_ENTRY *ExtRootEntry; - VTD_EXT_CONTEXT_ENTRY *ExtContextEntryTable; - VTD_EXT_CONTEXT_ENTRY *ThisExtContextEntry; + EFI_STATUS Status; + UINTN Index; =20 - for (VtdIndex =3D 0; VtdIndex < VTdInfo->VTdEngineCount; VtdIndex++) { - if (GetPciDataIndex (&VTdInfo->VtdUnitInfo[VtdIndex], Segment, SourceI= d) !=3D (UINTN)-1) { - DEBUG ((DEBUG_INFO, "Find VtdIndex(0x%x) for S%04x B%02x D%02x F%02x= \n", VtdIndex, Segment, SourceId.Bits.Bus, SourceId.Bits.Device, SourceId.B= its.Function)); - break; - } + if (VTdInfo->VtdRmrrInfo =3D=3D NULL) { + return EFI_SUCCESS; } - if (VtdIndex >=3D VTdInfo->VTdEngineCount) { - for (VtdIndex =3D 0; VtdIndex < VTdInfo->VTdEngineCount; VtdIndex++) { - if (Segment !=3D VTdInfo->VtdUnitInfo[VtdIndex].Segment) { - continue; - } - if (VTdInfo->VtdUnitInfo[VtdIndex].PciDeviceInfo.IncludeAllFlag) { - DEBUG ((DEBUG_INFO, "Find IncludeAllFlag VtdIndex(0x%x) for S%04x = B%02x D%02x F%02x\n", VtdIndex, Segment, SourceId.Bits.Bus, SourceId.Bits.D= evice, SourceId.Bits.Function)); - break; - } - } + + if (VTdInfo->VtdRmrrInfo->DeviceNumber =3D=3D 0) { + return EFI_SUCCESS; } =20 - if (VtdIndex < VTdInfo->VTdEngineCount) { - ExtRootEntryBase =3D (VTD_EXT_ROOT_ENTRY *) (UINTN) VTdInfo->VtdUnitIn= fo[VtdIndex].ExtRootEntryTable; - if (ExtRootEntryBase !=3D 0) { - ExtRootEntry =3D &ExtRootEntryBase[SourceId.Index.RootIndex]; - ExtContextEntryTable =3D (VTD_EXT_CONTEXT_ENTRY *) (UINTN) VTD_64BIT= S_ADDRESS(ExtRootEntry->Bits.LowerContextTablePointerLo, ExtRootEntry->Bits= .LowerContextTablePointerHi) ; - ThisExtContextEntry =3D &ExtContextEntryTable[SourceId.Index.Contex= tIndex]; - if (ThisExtContextEntry->Bits.AddressWidth =3D=3D 0) { - DEBUG ((DEBUG_INFO, "ExtContextEntry AddressWidth : 0x%x\n", ThisE= xtContextEntry->Bits.AddressWidth)); - return (UINTN)-1; - } - *ExtContextEntry =3D ThisExtContextEntry; - *ContextEntry =3D NULL; - } else { - RootEntryBase =3D (VTD_ROOT_ENTRY*) (UINTN) VTdInfo->VtdUnitInfo[Vtd= Index].RootEntryTable; - RootEntry =3D &RootEntryBase[SourceId.Index.RootIndex]; - ContextEntryTable =3D (VTD_CONTEXT_ENTRY *) (UINTN) VTD_64BITS_ADDRE= SS(RootEntry->Bits.ContextTablePointerLo, RootEntry->Bits.ContextTablePoint= erHi) ; - ThisContextEntry =3D &ContextEntryTable[SourceId.Index.ContextIndex= ]; - if (ThisContextEntry->Bits.AddressWidth =3D=3D 0) { - DEBUG ((DEBUG_INFO, "ContextEntry AddressWidth : 0x%x\n", ThisCont= extEntry->Bits.AddressWidth)); - return (UINTN)-1; - } - *ExtContextEntry =3D NULL; - *ContextEntry =3D ThisContextEntry; + DEBUG ((DEBUG_INFO, "Setup Rmrr Info\n")); + + for (Index =3D 0; Index < VTdInfo->VtdRmrrInfo->DeviceNumber; Index++) { + Status =3D EnableRmrrPageAttribute ( + VTdInfo, + VTdInfo->VtdRmrrInfo->SegmentNumber, + VTdInfo->VtdRmrrInfo->SourceId[Index], + VTdInfo->VtdRmrrInfo->ReservedMemoryRegionBaseAddress, + VTdInfo->VtdRmrrInfo->ReservedMemoryRegionLimitAddress, + EDKII_IOMMU_ACCESS_READ | EDKII_IOMMU_ACCESS_WRITE + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "EnableRmrrPageAttribute : %r\n", Status)); } - - return VtdIndex; } =20 - return (UINTN)-1; + return EFI_SUCCESS; } =20 /** @@ -1013,8 +987,9 @@ EnableRmrrPageAttribute ( IN UINT64 IoMmuAccess ) { - EFI_STATUS Status; - UINTN VtdIndex; + UINTN Index; + VTD_UNIT_INFO *VtdUnitInfo; + EFI_STATUS Status; VTD_EXT_CONTEXT_ENTRY *ExtContextEntry; VTD_CONTEXT_ENTRY *ContextEntry; VTD_SECOND_LEVEL_PAGING_ENTRY *SecondLevelPagingEntry; @@ -1022,39 +997,41 @@ EnableRmrrPageAttribute ( =20 DEBUG ((DEBUG_INFO, "EnableRmrrPageAttribute (S%04x B%02x D%02x F%02x)\n= ", Segment, SourceId.Bits.Bus, SourceId.Bits.Device, SourceId.Bits.Function= )); =20 - VtdIndex =3D FindVtdIndexBySegmentSourceId (VTdInfo, Segment, SourceId, = &ExtContextEntry, &ContextEntry); - if (VtdIndex =3D=3D (UINTN)-1) { - DEBUG ((DEBUG_ERROR, "EnableRmrrPageAttribute - Can not locate Pci dev= ice (S%04x B%02x D%02x F%02x) !\n", Segment, SourceId.Bits.Bus, SourceId.Bi= ts.Device, SourceId.Bits.Function)); - return EFI_DEVICE_ERROR; - } - - if (VTdInfo->VtdUnitInfo[VtdIndex].RmrrSecondLevelPagingEntry =3D=3D 0) { - DEBUG ((DEBUG_INFO, "CreateSecondLevelPagingEntry - %d\n", VtdIndex)); - VTdInfo->VtdUnitInfo[VtdIndex].RmrrSecondLevelPagingEntry =3D (UINT32)= (UINTN)CreateSecondLevelPagingEntryTable (&VTdInfo->VtdUnitInfo[VtdIndex], = NULL, 0, SIZE_4GB, 0); - if (VTdInfo->VtdUnitInfo[VtdIndex].RmrrSecondLevelPagingEntry =3D=3D 0= ) { - return EFI_OUT_OF_RESOURCES; + for (Index =3D 0; Index < VTdInfo->VTdEngineCount; Index++) { + VtdUnitInfo =3D &VTdInfo->VtdUnitInfo[Index]; + if (VtdUnitInfo->Done) { + continue; } =20 - Status =3DSetSecondLevelPagingAttribute (&VTdInfo->VtdUnitInfo[VtdInde= x], (VTD_SECOND_LEVEL_PAGING_ENTRY*)(UINTN)VTdInfo->VtdUnitInfo[VtdIndex].R= mrrSecondLevelPagingEntry, MemoryBase, MemoryLimit + 1 - MemoryBase, IoMmuA= ccess); - if (EFI_ERROR (Status)) { - return Status; - } - } + if (VtdUnitInfo->RmrrSecondLevelPagingEntry =3D=3D 0) { + DEBUG ((DEBUG_INFO, "CreateSecondLevelPagingEntry - %d\n", Index)); + VtdUnitInfo->RmrrSecondLevelPagingEntry =3D (UINTN) CreateSecondLeve= lPagingEntryTable (VtdUnitInfo, NULL, 0, SIZE_4GB, 0); + if (VtdUnitInfo->RmrrSecondLevelPagingEntry =3D=3D 0) { + return EFI_OUT_OF_RESOURCES; + } =20 - SecondLevelPagingEntry =3D (VTD_SECOND_LEVEL_PAGING_ENTRY *) (UINTN) VTd= Info->VtdUnitInfo[VtdIndex].RmrrSecondLevelPagingEntry; - Pt =3D (UINT64) RShiftU64 ((UINT64) (UINTN) SecondLevelPagingEntry, 12); - if (ExtContextEntry !=3D NULL) { - ExtContextEntry->Bits.SecondLevelPageTranslationPointerLo =3D (UINT32)= Pt; - ExtContextEntry->Bits.SecondLevelPageTranslationPointerHi =3D (UINT32)= RShiftU64(Pt, 20); - ExtContextEntry->Bits.DomainIdentifier =3D ((1 << (UINT8) ((UINTN) VTd= Info->VtdUnitInfo[VtdIndex].CapReg.Bits.ND * 2 + 4)) - 1); - ExtContextEntry->Bits.Present =3D 1; - FlushPageTableMemory (&VTdInfo->VtdUnitInfo[VtdIndex], (UINTN) ExtCont= extEntry, sizeof(*ExtContextEntry)); - } else if (ContextEntry !=3D NULL) { - ContextEntry->Bits.SecondLevelPageTranslationPointerLo =3D (UINT32) Pt; - ContextEntry->Bits.SecondLevelPageTranslationPointerHi =3D (UINT32) RS= hiftU64 (Pt, 20); - ContextEntry->Bits.DomainIdentifier =3D ((1 << (UINT8) ((UINTN) VTdInf= o->VtdUnitInfo[VtdIndex].CapReg.Bits.ND * 2 + 4)) - 1); - ContextEntry->Bits.Present =3D 1; - FlushPageTableMemory (&VTdInfo->VtdUnitInfo[VtdIndex], (UINTN) Context= Entry, sizeof (*ContextEntry)); + Status =3D SetSecondLevelPagingAttribute (VtdUnitInfo, (VTD_SECOND_L= EVEL_PAGING_ENTRY*) VtdUnitInfo->RmrrSecondLevelPagingEntry, MemoryBase, Me= moryLimit + 1 - MemoryBase, IoMmuAccess); + if (EFI_ERROR (Status)) { + return Status; + } + } + SecondLevelPagingEntry =3D (VTD_SECOND_LEVEL_PAGING_ENTRY *) VtdUnitIn= fo->RmrrSecondLevelPagingEntry; + ExtContextEntry =3D (VTD_EXT_CONTEXT_ENTRY *) VtdUnitInfo->ExtRootEntr= yTable; + ContextEntry =3D (VTD_CONTEXT_ENTRY *) VtdUnitInfo->RootEntryTable; + Pt =3D (UINT64) RShiftU64 ((UINT64) (UINTN) SecondLevelPagingEntry, 12= ); + if (ExtContextEntry !=3D NULL) { + ExtContextEntry->Bits.SecondLevelPageTranslationPointerLo =3D (UINT3= 2) Pt; + ExtContextEntry->Bits.SecondLevelPageTranslationPointerHi =3D (UINT3= 2) RShiftU64(Pt, 20); + ExtContextEntry->Bits.DomainIdentifier =3D ((1 << (UINT8) ((UINTN) V= tdUnitInfo->CapReg.Bits.ND * 2 + 4)) - 1); + ExtContextEntry->Bits.Present =3D 1; + FlushPageTableMemory (VtdUnitInfo, (UINTN) ExtContextEntry, sizeof (= *ExtContextEntry)); + } else if (ContextEntry !=3D NULL) { + ContextEntry->Bits.SecondLevelPageTranslationPointerLo =3D (UINT32) = Pt; + ContextEntry->Bits.SecondLevelPageTranslationPointerHi =3D (UINT32) = RShiftU64 (Pt, 20); + ContextEntry->Bits.DomainIdentifier =3D ((1 << (UINT8) ((UINTN) VtdU= nitInfo->CapReg.Bits.ND * 2 + 4)) - 1); + ContextEntry->Bits.Present =3D 1; + FlushPageTableMemory (VtdUnitInfo, (UINTN) ContextEntry, sizeof (*Co= ntextEntry)); + } } =20 return EFI_SUCCESS; --=20 2.16.2.windows.1 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#84789): https://edk2.groups.io/g/devel/message/84789 Mute This Topic: https://groups.io/mt/87715958/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-