From nobody Sun Apr 28 21:46:16 2024 Delivered-To: importer@patchew.org Received-SPF: none (zoho.com: 198.145.21.10 is neither permitted nor denied by domain of lists.01.org) client-ip=198.145.21.10; envelope-from=edk2-devel-bounces@lists.01.org; helo=ml01.01.org; Authentication-Results: mx.zohomail.com; spf=none (zoho.com: 198.145.21.10 is neither permitted nor denied by domain of lists.01.org) smtp.mailfrom=edk2-devel-bounces@lists.01.org Return-Path: Received: from ml01.01.org (ml01.01.org [198.145.21.10]) by mx.zohomail.com with SMTPS id 1502460601454675.619930253502; Fri, 11 Aug 2017 07:10:01 -0700 (PDT) Received: from [127.0.0.1] (localhost [IPv6:::1]) by ml01.01.org (Postfix) with ESMTP id 9C9F521C9127A; Fri, 11 Aug 2017 07:07:37 -0700 (PDT) Received: from mga11.intel.com (mga11.intel.com [192.55.52.93]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id 0B47021D49117 for ; Fri, 11 Aug 2017 07:07:36 -0700 (PDT) Received: from orsmga005.jf.intel.com ([10.7.209.41]) by fmsmga102.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 11 Aug 2017 07:09:56 -0700 Received: from jyao1-mobl.ccr.corp.intel.com ([10.254.211.254]) by orsmga005.jf.intel.com with ESMTP; 11 Aug 2017 07:09:55 -0700 X-Original-To: edk2-devel@lists.01.org X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.41,358,1498546800"; d="scan'208";a="136371821" From: Jiewen Yao To: edk2-devel@lists.01.org Date: Fri, 11 Aug 2017 22:09:48 +0800 Message-Id: <1502460591-14428-2-git-send-email-jiewen.yao@intel.com> X-Mailer: git-send-email 2.7.4.windows.1 In-Reply-To: <1502460591-14428-1-git-send-email-jiewen.yao@intel.com> References: <1502460591-14428-1-git-send-email-jiewen.yao@intel.com> Subject: [edk2] [PATCH 1/4] MdePkg/CpuLib.h: Add CacheLineFlush function. X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Star Zeng , Liming Gao MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Errors-To: edk2-devel-bounces@lists.01.org Sender: "edk2-devel" X-ZohoMail: RSF_4 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" This function will be used by IntelVTd driver. Cc: Liming Gao Cc: Star Zeng Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Jiewen Yao --- MdePkg/Include/Library/CpuLib.h | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/MdePkg/Include/Library/CpuLib.h b/MdePkg/Include/Library/CpuLi= b.h index 100020a..1b2f7e8 100644 --- a/MdePkg/Include/Library/CpuLib.h +++ b/MdePkg/Include/Library/CpuLib.h @@ -7,7 +7,7 @@ PAL Calls require PEI and DXE specific mechanisms to look up PAL Entry P= oint. As a result, these services could not be defined in the Base Library. =20 -Copyright (c) 2006 - 2008, Intel Corporation. All rights reserved.
+Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.
This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD = License which accompanies this distribution. The full text of the license may be = found at @@ -47,5 +47,15 @@ CpuFlushTlb ( VOID ); =20 +/** + Flushes one cache line. + + Flushes one cache line. The size of cache line can be got by CPU registe= r. +**/ +VOID +EFIAPI +CacheLineFlush ( + IN UINTN Address + ); =20 #endif --=20 2.7.4.windows.1 _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel From nobody Sun Apr 28 21:46:16 2024 Delivered-To: importer@patchew.org Received-SPF: none (zoho.com: 198.145.21.10 is neither permitted nor denied by domain of lists.01.org) client-ip=198.145.21.10; envelope-from=edk2-devel-bounces@lists.01.org; helo=ml01.01.org; Authentication-Results: mx.zohomail.com; spf=none (zoho.com: 198.145.21.10 is neither permitted nor denied by domain of lists.01.org) smtp.mailfrom=edk2-devel-bounces@lists.01.org Return-Path: Received: from ml01.01.org (ml01.01.org [198.145.21.10]) by mx.zohomail.com with SMTPS id 1502460604242112.32870120262669; Fri, 11 Aug 2017 07:10:04 -0700 (PDT) Received: from [127.0.0.1] (localhost [IPv6:::1]) by ml01.01.org (Postfix) with ESMTP id D8FF821E2571B; Fri, 11 Aug 2017 07:07:38 -0700 (PDT) Received: from mga11.intel.com (mga11.intel.com [192.55.52.93]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id 2CB602095DE50 for ; Fri, 11 Aug 2017 07:07:37 -0700 (PDT) Received: from orsmga005.jf.intel.com ([10.7.209.41]) by fmsmga102.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 11 Aug 2017 07:09:57 -0700 Received: from jyao1-mobl.ccr.corp.intel.com ([10.254.211.254]) by orsmga005.jf.intel.com with ESMTP; 11 Aug 2017 07:09:56 -0700 X-Original-To: edk2-devel@lists.01.org X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.41,358,1498546800"; d="scan'208";a="136371828" From: Jiewen Yao To: edk2-devel@lists.01.org Date: Fri, 11 Aug 2017 22:09:49 +0800 Message-Id: <1502460591-14428-3-git-send-email-jiewen.yao@intel.com> X-Mailer: git-send-email 2.7.4.windows.1 In-Reply-To: <1502460591-14428-1-git-send-email-jiewen.yao@intel.com> References: <1502460591-14428-1-git-send-email-jiewen.yao@intel.com> Subject: [edk2] [PATCH 2/4] MdePkg/BaseCpuLib: Add CacheLineFlush function. X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Star Zeng , Liming Gao MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Errors-To: edk2-devel-bounces@lists.01.org Sender: "edk2-devel" X-ZohoMail: RSF_4 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" This function will be used by IntelVTd driver. Cc: Liming Gao Cc: Star Zeng Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Jiewen Yao --- MdePkg/Library/BaseCpuLib/BaseCpuLib.inf | 5 ++- MdePkg/Library/BaseCpuLib/Ebc/CpuSleepFlushTlb.c | 16 ++++++++- MdePkg/Library/BaseCpuLib/Ia32/CacheLineFlush.nasm | 37 ++++++++++++++++++= ++ MdePkg/Library/BaseCpuLib/X64/CacheLineFlush.nasm | 37 ++++++++++++++++++= ++ 4 files changed, 93 insertions(+), 2 deletions(-) diff --git a/MdePkg/Library/BaseCpuLib/BaseCpuLib.inf b/MdePkg/Library/Base= CpuLib/BaseCpuLib.inf index 637a3c5..b43b393 100644 --- a/MdePkg/Library/BaseCpuLib/BaseCpuLib.inf +++ b/MdePkg/Library/BaseCpuLib/BaseCpuLib.inf @@ -4,7 +4,7 @@ # CPU Library implemented using ASM functions for IA-32 and X64, # PAL CALLs for IPF, and empty functions for EBC. # -# Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.
+# Copyright (c) 2007 - 2017, Intel Corporation. All rights reserved.
# Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.
# Portions copyright (c) 2011 - 2013, ARM Ltd. All rights reserved.
# @@ -33,6 +33,8 @@ # =20 [Sources.IA32] + Ia32/CacheLineFlush.nasm + Ia32/CpuSleep.c | MSFT=20 Ia32/CpuFlushTlb.c | MSFT=20 =20 @@ -45,6 +47,7 @@ Ia32/CpuFlushTlbGcc.c | GCC=20 =20 [Sources.X64] + X64/CacheLineFlush.nasm X64/CpuFlushTlb.nasm X64/CpuFlushTlb.asm=20 X64/CpuSleep.nasm diff --git a/MdePkg/Library/BaseCpuLib/Ebc/CpuSleepFlushTlb.c b/MdePkg/Libr= ary/BaseCpuLib/Ebc/CpuSleepFlushTlb.c index de63d63..0c554c2 100644 --- a/MdePkg/Library/BaseCpuLib/Ebc/CpuSleepFlushTlb.c +++ b/MdePkg/Library/BaseCpuLib/Ebc/CpuSleepFlushTlb.c @@ -1,7 +1,7 @@ /** @file Base Library CPU Functions for EBC =20 - Copyright (c) 2006 - 2008, Intel Corporation. All rights reserved.
+ Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.
This program and the accompanying materials are licensed and made available under the terms and conditions of the BS= D License which accompanies this distribution. The full text of the license may b= e found at @@ -15,6 +15,20 @@ #include =20 /** + Flushes one cache line. + + Flushes one cache line. The size of cache line can be got by CPU registe= r. +**/ +VOID +EFIAPI +CacheLineFlush ( + IN UINTN Address + ) +{ + ASSERT (FALSE); +} + +/** Flushes all the Translation Lookaside Buffers(TLB) entries in a CPU. =20 Flushes all the Translation Lookaside Buffers(TLB) entries in a CPU. diff --git a/MdePkg/Library/BaseCpuLib/Ia32/CacheLineFlush.nasm b/MdePkg/Li= brary/BaseCpuLib/Ia32/CacheLineFlush.nasm new file mode 100644 index 0000000..a2557ab --- /dev/null +++ b/MdePkg/Library/BaseCpuLib/Ia32/CacheLineFlush.nasm @@ -0,0 +1,37 @@ +;-------------------------------------------------------------------------= ----- ; +; Copyright (c) 2017, Intel Corporation. All rights reserved.
+; This program and the accompanying materials +; are licensed and made available under the terms and conditions of the BS= D License +; which accompanies this distribution. The full text of the license may b= e found at +; http://opensource.org/licenses/bsd-license.php. +; +; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMP= LIED. +; +; Module Name: +; +; CacheLineFlush.Asm +; +; Abstract: +; +; CacheLineFlush function +; +; Notes: +; +;-------------------------------------------------------------------------= ----- + + SECTION .text + +;-------------------------------------------------------------------------= ----- +; VOID +; EFIAPI +; CacheLineFlush ( +; IN UINTN Address +; ); +;-------------------------------------------------------------------------= ----- +global ASM_PFX(CacheLineFlush) +ASM_PFX(CacheLineFlush): + mov eax, [esp + 4] + clflush [eax] + ret + diff --git a/MdePkg/Library/BaseCpuLib/X64/CacheLineFlush.nasm b/MdePkg/Lib= rary/BaseCpuLib/X64/CacheLineFlush.nasm new file mode 100644 index 0000000..7cf736e --- /dev/null +++ b/MdePkg/Library/BaseCpuLib/X64/CacheLineFlush.nasm @@ -0,0 +1,37 @@ +;-------------------------------------------------------------------------= ----- ; +; Copyright (c) 2017, Intel Corporation. All rights reserved.
+; This program and the accompanying materials +; are licensed and made available under the terms and conditions of the BS= D License +; which accompanies this distribution. The full text of the license may b= e found at +; http://opensource.org/licenses/bsd-license.php. +; +; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMP= LIED. +; +; Module Name: +; +; CacheLineFlush.Asm +; +; Abstract: +; +; CacheLineFlush function +; +; Notes: +; +;-------------------------------------------------------------------------= ----- + + DEFAULT REL + SECTION .text + +;-------------------------------------------------------------------------= ----- +; VOID +; EFIAPI +; CacheLineFlush ( +; IN UINTN Address +; ); +;-------------------------------------------------------------------------= ----- +global ASM_PFX(CacheLineFlush) +ASM_PFX(CacheLineFlush): + clflush [rcx] + ret + --=20 2.7.4.windows.1 _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel From nobody Sun Apr 28 21:46:16 2024 Delivered-To: importer@patchew.org Received-SPF: none (zoho.com: 198.145.21.10 is neither permitted nor denied by domain of lists.01.org) client-ip=198.145.21.10; envelope-from=edk2-devel-bounces@lists.01.org; helo=ml01.01.org; Authentication-Results: mx.zohomail.com; spf=none (zoho.com: 198.145.21.10 is neither permitted nor denied by domain of lists.01.org) smtp.mailfrom=edk2-devel-bounces@lists.01.org Return-Path: Received: from ml01.01.org (ml01.01.org [198.145.21.10]) by mx.zohomail.com with SMTPS id 1502460607395121.02192870016779; Fri, 11 Aug 2017 07:10:07 -0700 (PDT) Received: from [127.0.0.1] (localhost [IPv6:::1]) by ml01.01.org (Postfix) with ESMTP id 224852095DE50; Fri, 11 Aug 2017 07:07:40 -0700 (PDT) Received: from mga11.intel.com (mga11.intel.com [192.55.52.93]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id 16A8D21DF37A3 for ; Fri, 11 Aug 2017 07:07:38 -0700 (PDT) Received: from orsmga005.jf.intel.com ([10.7.209.41]) by fmsmga102.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 11 Aug 2017 07:09:58 -0700 Received: from jyao1-mobl.ccr.corp.intel.com ([10.254.211.254]) by orsmga005.jf.intel.com with ESMTP; 11 Aug 2017 07:09:57 -0700 X-Original-To: edk2-devel@lists.01.org X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.41,358,1498546800"; d="scan'208";a="136371840" From: Jiewen Yao To: edk2-devel@lists.01.org Date: Fri, 11 Aug 2017 22:09:50 +0800 Message-Id: <1502460591-14428-4-git-send-email-jiewen.yao@intel.com> X-Mailer: git-send-email 2.7.4.windows.1 In-Reply-To: <1502460591-14428-1-git-send-email-jiewen.yao@intel.com> References: <1502460591-14428-1-git-send-email-jiewen.yao@intel.com> Subject: [edk2] [PATCH 3/4] IntelSiliconPkg/dsc: Add CpuLib. X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Star Zeng MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Errors-To: edk2-devel-bounces@lists.01.org Sender: "edk2-devel" X-ZohoMail: RSF_4 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" It will be used by IntelVTdDxe. Cc: Star Zeng Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Jiewen Yao --- IntelSiliconPkg/IntelSiliconPkg.dsc | 1 + 1 file changed, 1 insertion(+) diff --git a/IntelSiliconPkg/IntelSiliconPkg.dsc b/IntelSiliconPkg/IntelSil= iconPkg.dsc index d837d84..7d7981e 100644 --- a/IntelSiliconPkg/IntelSiliconPkg.dsc +++ b/IntelSiliconPkg/IntelSiliconPkg.dsc @@ -38,6 +38,7 @@ UefiDecompressLib|MdePkg/Library/BaseUefiDecompressLib/BaseUefiDecompres= sLib.inf PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibN= ull.inf SerialPortLib|MdePkg/Library/BaseSerialPortLibNull/BaseSerialPortLibNull= .inf + CpuLib|MdePkg/Library/BaseCpuLib/BaseCpuLib.inf =20 [LibraryClasses.common.DXE_DRIVER] UefiDriverEntryPoint|MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntry= Point.inf --=20 2.7.4.windows.1 _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel From nobody Sun Apr 28 21:46:16 2024 Delivered-To: importer@patchew.org Received-SPF: none (zoho.com: 198.145.21.10 is neither permitted nor denied by domain of lists.01.org) client-ip=198.145.21.10; envelope-from=edk2-devel-bounces@lists.01.org; helo=ml01.01.org; Authentication-Results: mx.zohomail.com; spf=none (zoho.com: 198.145.21.10 is neither permitted nor denied by domain of lists.01.org) smtp.mailfrom=edk2-devel-bounces@lists.01.org Return-Path: Received: from ml01.01.org (ml01.01.org [198.145.21.10]) by mx.zohomail.com with SMTPS id 150246061055850.87550260961996; Fri, 11 Aug 2017 07:10:10 -0700 (PDT) Received: from [127.0.0.1] (localhost [IPv6:::1]) by ml01.01.org (Postfix) with ESMTP id 6B52221E25738; Fri, 11 Aug 2017 07:07:42 -0700 (PDT) Received: from mga11.intel.com (mga11.intel.com [192.55.52.93]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id 9B2F821E25732 for ; Fri, 11 Aug 2017 07:07:39 -0700 (PDT) Received: from orsmga005.jf.intel.com ([10.7.209.41]) by fmsmga102.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 11 Aug 2017 07:09:59 -0700 Received: from jyao1-mobl.ccr.corp.intel.com ([10.254.211.254]) by orsmga005.jf.intel.com with ESMTP; 11 Aug 2017 07:09:58 -0700 X-Original-To: edk2-devel@lists.01.org X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.41,358,1498546800"; d="scan'208";a="136371849" From: Jiewen Yao To: edk2-devel@lists.01.org Date: Fri, 11 Aug 2017 22:09:51 +0800 Message-Id: <1502460591-14428-5-git-send-email-jiewen.yao@intel.com> X-Mailer: git-send-email 2.7.4.windows.1 In-Reply-To: <1502460591-14428-1-git-send-email-jiewen.yao@intel.com> References: <1502460591-14428-1-git-send-email-jiewen.yao@intel.com> Subject: [edk2] [PATCH 4/4] IntelSiliconPkg/IntelVTdDxe: Improve performance. X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Star Zeng MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Errors-To: edk2-devel-bounces@lists.01.org Sender: "edk2-devel" X-ZohoMail: RSF_4 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" This patch is to improve IOMMU performance. All WBINVD is removed due to performance issue. CLFLUSH is used to to only flush the context table or second level page table if they are changed. This patch also removed some unused functions. Cc: Star Zeng Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Jiewen Yao --- IntelSiliconPkg/IntelVTdDxe/DmaProtection.c | 6 + IntelSiliconPkg/IntelVTdDxe/DmaProtection.h | 61 ++--- IntelSiliconPkg/IntelVTdDxe/IntelVTdDxe.c | 10 + IntelSiliconPkg/IntelVTdDxe/IntelVTdDxe.inf | 4 + IntelSiliconPkg/IntelVTdDxe/PciInfo.c | 12 + IntelSiliconPkg/IntelVTdDxe/TranslationTable.c | 58 +++- IntelSiliconPkg/IntelVTdDxe/TranslationTableEx.c | 2 + IntelSiliconPkg/IntelVTdDxe/VtdReg.c | 283 +++++++------------- 8 files changed, 213 insertions(+), 223 deletions(-) diff --git a/IntelSiliconPkg/IntelVTdDxe/DmaProtection.c b/IntelSiliconPkg/= IntelVTdDxe/DmaProtection.c index f0628b5..91f34d7 100644 --- a/IntelSiliconPkg/IntelVTdDxe/DmaProtection.c +++ b/IntelSiliconPkg/IntelVTdDxe/DmaProtection.c @@ -17,6 +17,8 @@ EFI_ACPI_SDT_PROTOCOL *mAcpiSdt; UINT64 mBelow4GMemoryLimit; UINT64 mAbove4GMemoryLimit; =20 +UINTN mCacheLineSize; + EDKII_PLATFORM_VTD_POLICY_PROTOCOL *mPlatformVTdPolicy; =20 /** @@ -196,6 +198,7 @@ SetupVtd ( UINTN Index; UINT64 Below4GMemoryLimit; UINT64 Above4GMemoryLimit; + CPUID_VERSION_INFO_EBX Ebx; =20 // // PCI Enumeration must be done @@ -207,6 +210,9 @@ SetupVtd ( ); ASSERT_EFI_ERROR (Status); =20 + AsmCpuid (CPUID_VERSION_INFO, NULL, &Ebx.Uint32, NULL, NULL); + mCacheLineSize =3D Ebx.Bits.CacheLineSize; + ReturnUefiMemoryMap (&Below4GMemoryLimit, &Above4GMemoryLimit); Below4GMemoryLimit =3D ALIGN_VALUE_UP(Below4GMemoryLimit, SIZE_256MB); DEBUG ((DEBUG_INFO, " Adjusted Below4GMemoryLimit: 0x%016lx\n", Below4GM= emoryLimit)); diff --git a/IntelSiliconPkg/IntelVTdDxe/DmaProtection.h b/IntelSiliconPkg/= IntelVTdDxe/DmaProtection.h index 8cfa69c..f6ce365 100644 --- a/IntelSiliconPkg/IntelVTdDxe/DmaProtection.h +++ b/IntelSiliconPkg/IntelVTdDxe/DmaProtection.h @@ -25,6 +25,9 @@ #include #include #include +#include +#include +#include =20 #include #include @@ -41,6 +44,8 @@ #include #include =20 +#include + #define VTD_64BITS_ADDRESS(Lo, Hi) (LShiftU64 (Lo, 12) | LShiftU64 (Hi, 32= )) =20 #define ALIGN_VALUE_UP(Value, Alignment) (((Value) + (Alignment) - 1) & (= ~((Alignment) - 1))) @@ -58,6 +63,8 @@ typedef struct { UINTN PciDescriptorMaxNumber; BOOLEAN *IsRealPciDevice; VTD_SOURCE_ID *PciDescriptors; + // for statistic analysis + UINTN *AccessCount; } PCI_DEVICE_INFORMATION; =20 typedef struct { @@ -68,6 +75,7 @@ typedef struct { VTD_ROOT_ENTRY *RootEntryTable; VTD_EXT_ROOT_ENTRY *ExtRootEntryTable; VTD_SECOND_LEVEL_PAGING_ENTRY *FixedSecondLevelPagingEntry; + BOOLEAN HasDirtyContext; BOOLEAN HasDirtyPages; PCI_DEVICE_INFORMATION PciDeviceInfo; } VTD_UNIT_INFORMATION; @@ -81,6 +89,8 @@ extern VTD_UNIT_INFORMATION *mVtdUnitInformat= ion; extern UINT64 mBelow4GMemoryLimit; extern UINT64 mAbove4GMemoryLimit; =20 +extern UINTN mCacheLineSize; + extern EDKII_PLATFORM_VTD_POLICY_PROTOCOL *mPlatformVTdPolicy; =20 /** @@ -125,40 +135,6 @@ DisableDmar ( ); =20 /** - Invalid VTd IOTLB page. - - @param[in] VtdIndex The index of VTd engine. - @param[in] Address The address of IOTLB page. - @param[in] AddressMode The address mode of IOTLB page. - @param[in] DomainIdentifier The domain ID of the source. - - @retval EFI_SUCCESS VTd IOTLB page is invalidated. - @retval EFI_DEVICE_ERROR VTd IOTLB page is not invalidated. -**/ -EFI_STATUS -InvalidateVtdIOTLBPage ( - IN UINTN VtdIndex, - IN UINT64 Address, - IN UINT8 AddressMode, - IN UINT16 DomainIdentifier - ); - -/** - Invalid VTd IOTLB domain. - - @param[in] VtdIndex The index of VTd engine. - @param[in] DomainIdentifier The domain ID of the source. - - @retval EFI_SUCCESS VTd IOTLB domain is invalidated. - @retval EFI_DEVICE_ERROR VTd IOTLB domain is not invalidated. -**/ -EFI_STATUS -InvalidateVtdIOTLBDomain ( - IN UINTN VtdIndex, - IN UINT16 DomainIdentifier - ); - -/** Invalid VTd global IOTLB. =20 @param[in] VtdIndex The index of VTd engine. @@ -362,6 +338,7 @@ DumpSecondLevelPagingEntry ( EFI_STATUS SetPageAttribute ( IN UINTN VtdIndex, + IN UINT16 DomainIdentifier, IN VTD_SECOND_LEVEL_PAGING_ENTRY *SecondLevelPagingEntry, IN UINT64 BaseAddress, IN UINT64 Length, @@ -500,4 +477,20 @@ AllocateZeroPages ( IN UINTN Pages ); =20 +/** + Flush VTD page table and context table memory. + + This action is to make sure the IOMMU engine can get final data in memor= y. + + @param[in] VtdIndex The index used to identify a VTd engine. + @param[in] Base The base address of memory to be flushed. + @param[in] Size The size of memory in bytes to be flushed. +**/ +VOID +FlushPageTableMemory ( + IN UINTN VtdIndex, + IN UINTN Base, + IN UINTN Size + ); + #endif diff --git a/IntelSiliconPkg/IntelVTdDxe/IntelVTdDxe.c b/IntelSiliconPkg/In= telVTdDxe/IntelVTdDxe.c index d22222d..7feaaf5 100644 --- a/IntelSiliconPkg/IntelVTdDxe/IntelVTdDxe.c +++ b/IntelSiliconPkg/IntelVTdDxe/IntelVTdDxe.c @@ -227,6 +227,7 @@ VTdSetAttribute ( EFI_STATUS Status; UINT16 Segment; VTD_SOURCE_ID SourceId; + CHAR8 PerfToken[sizeof("VTD(S0000.B00.D00.F00)")]; =20 DumpVtdIfError (); =20 @@ -239,8 +240,17 @@ VTdSetAttribute ( DEBUG ((DEBUG_VERBOSE, "PCI(S%x.B%x.D%x.F%x) ", Segment, SourceId.Bits.B= us, SourceId.Bits.Device, SourceId.Bits.Function)); DEBUG ((DEBUG_VERBOSE, "(0x%lx~0x%lx) - %lx\n", DeviceAddress, Length, I= oMmuAccess)); =20 + PERF_CODE_BEGIN(); + AsciiSPrint (PerfToken, sizeof(PerfToken), "VTD(S%04x.B%02x.D%02x.F%02= x)", Segment, SourceId.Bits.Bus, SourceId.Bits.Device, SourceId.Bits.Functi= on); + PERF_START (gImageHandle, PerfToken, "IntelVTD", 0); + PERF_CODE_END(); + Status =3D SetAccessAttribute (Segment, SourceId, DeviceAddress, Length,= IoMmuAccess); =20 + PERF_CODE_BEGIN(); + PERF_END (gImageHandle, PerfToken, "IntelVTD", 0); + PERF_CODE_END(); + return Status; } =20 diff --git a/IntelSiliconPkg/IntelVTdDxe/IntelVTdDxe.inf b/IntelSiliconPkg/= IntelVTdDxe/IntelVTdDxe.inf index 6a61c13..b8ac3cf 100644 --- a/IntelSiliconPkg/IntelVTdDxe/IntelVTdDxe.inf +++ b/IntelSiliconPkg/IntelVTdDxe/IntelVTdDxe.inf @@ -45,6 +45,7 @@ [Packages] MdePkg/MdePkg.dec MdeModulePkg/MdeModulePkg.dec + UefiCpuPkg/UefiCpuPkg.dec IntelSiliconPkg/IntelSiliconPkg.dec =20 [LibraryClasses] @@ -57,6 +58,9 @@ BaseMemoryLib MemoryAllocationLib UefiLib + CpuLib + PerformanceLib + PrintLib =20 [Guids] gEfiEventExitBootServicesGuid ## CONSUMES ## Event diff --git a/IntelSiliconPkg/IntelVTdDxe/PciInfo.c b/IntelSiliconPkg/IntelV= TdDxe/PciInfo.c index d5f096f..27e253d 100644 --- a/IntelSiliconPkg/IntelVTdDxe/PciInfo.c +++ b/IntelSiliconPkg/IntelVTdDxe/PciInfo.c @@ -77,6 +77,7 @@ RegisterPciDevice ( UINTN Index; BOOLEAN *NewIsRealPciDevice; VTD_SOURCE_ID *NewPciDescriptors; + UINTN *NewAccessCount; =20 PciDeviceInfo =3D &mVtdUnitInformation[VtdIndex].PciDeviceInfo; =20 @@ -112,6 +113,12 @@ RegisterPciDevice ( FreePool (NewIsRealPciDevice); return EFI_OUT_OF_RESOURCES; } + NewAccessCount =3D AllocateZeroPool (sizeof(*NewAccessCount) * (PciD= eviceInfo->PciDescriptorMaxNumber + MAX_PCI_DESCRIPTORS)); + if (NewAccessCount =3D=3D NULL) { + FreePool (NewIsRealPciDevice); + FreePool (NewPciDescriptors); + return EFI_OUT_OF_RESOURCES; + } PciDeviceInfo->PciDescriptorMaxNumber +=3D MAX_PCI_DESCRIPTORS; if (PciDeviceInfo->IsRealPciDevice !=3D NULL) { CopyMem (NewIsRealPciDevice, PciDeviceInfo->IsRealPciDevice, sizeo= f(*NewIsRealPciDevice) * PciDeviceInfo->PciDescriptorNumber); @@ -123,6 +130,11 @@ RegisterPciDevice ( FreePool (PciDeviceInfo->PciDescriptors); } PciDeviceInfo->PciDescriptors =3D NewPciDescriptors; + if (PciDeviceInfo->AccessCount !=3D NULL) { + CopyMem (NewAccessCount, PciDeviceInfo->AccessCount, sizeof(*NewAc= cessCount) * PciDeviceInfo->PciDescriptorNumber); + FreePool (PciDeviceInfo->AccessCount); + } + PciDeviceInfo->AccessCount =3D NewAccessCount; } =20 ASSERT (PciDeviceInfo->PciDescriptorNumber < PciDeviceInfo->PciDescrip= torMaxNumber); diff --git a/IntelSiliconPkg/IntelVTdDxe/TranslationTable.c b/IntelSiliconP= kg/IntelVTdDxe/TranslationTable.c index 961d7ca..80fc823 100644 --- a/IntelSiliconPkg/IntelVTdDxe/TranslationTable.c +++ b/IntelSiliconPkg/IntelVTdDxe/TranslationTable.c @@ -124,6 +124,7 @@ CreateContextEntry ( RootEntry->Bits.ContextTablePointerHi =3D (UINT32) RShiftU64 ((UINT= 64)(UINTN)Buffer, 32); RootEntry->Bits.Present =3D 1; Buffer =3D (UINT8 *)Buffer + EFI_PAGES_TO_SIZE (ContextPages); + FlushPageTableMemory (VtdIndex, (UINTN)RootEntry, sizeof(*RootEntry)= ); } =20 ContextEntryTable =3D (VTD_CONTEXT_ENTRY *)(UINTN)VTD_64BITS_ADDRESS(R= ootEntry->Bits.ContextTablePointerLo, RootEntry->Bits.ContextTablePointerHi= ) ; @@ -142,6 +143,7 @@ CreateContextEntry ( ContextEntry->Bits.AddressWidth =3D 0x2; break; } + FlushPageTableMemory (VtdIndex, (UINTN)ContextEntry, sizeof(*ContextEn= try)); } =20 return EFI_SUCCESS; @@ -250,8 +252,11 @@ CreateSecondLevelPagingEntryTable ( goto Done; } } + FlushPageTableMemory (VtdIndex, (UINTN)Lvl2PtEntry, SIZE_4KB); } + FlushPageTableMemory (VtdIndex, (UINTN)&Lvl3PtEntry[Lvl3Start], (UINTN= )&Lvl3PtEntry[Lvl3End + 1] - (UINTN)&Lvl3PtEntry[Lvl3Start]); } + FlushPageTableMemory (VtdIndex, (UINTN)&Lvl4PtEntry[Lvl4Start], (UINTN)&= Lvl4PtEntry[Lvl4End + 1] - (UINTN)&Lvl4PtEntry[Lvl4Start]); =20 Done: return SecondLevelPagingEntry; @@ -429,9 +434,10 @@ InvalidatePageEntry ( IN UINTN VtdIndex ) { - if (mVtdUnitInformation[VtdIndex].HasDirtyPages) { + if (mVtdUnitInformation[VtdIndex].HasDirtyContext || mVtdUnitInformation= [VtdIndex].HasDirtyPages) { InvalidateVtdIOTLBGlobal (VtdIndex); } + mVtdUnitInformation[VtdIndex].HasDirtyContext =3D FALSE; mVtdUnitInformation[VtdIndex].HasDirtyPages =3D FALSE; } =20 @@ -498,6 +504,7 @@ PageAttributeToLength ( /** Return page table entry to match the address. =20 + @param[in] VtdIndex The index used to identify a VTd e= ngine. @param[in] SecondLevelPagingEntry The second level paging entry in V= Td table for the device. @param[in] Address The address to be checked. @param[out] PageAttributes The page attribute of the page ent= ry. @@ -506,6 +513,7 @@ PageAttributeToLength ( **/ VOID * GetSecondLevelPageTableEntry ( + IN UINTN VtdIndex, IN VTD_SECOND_LEVEL_PAGING_ENTRY *SecondLevelPagingEntry, IN PHYSICAL_ADDRESS Address, OUT PAGE_ATTRIBUTE *PageAttribute @@ -535,6 +543,7 @@ GetSecondLevelPageTableEntry ( return NULL; } SetSecondLevelPagingEntryAttribute ((VTD_SECOND_LEVEL_PAGING_ENTRY *)&= L4PageTable[Index4], EDKII_IOMMU_ACCESS_READ | EDKII_IOMMU_ACCESS_WRITE); + FlushPageTableMemory (VtdIndex, (UINTN)&L4PageTable[Index4], sizeof(L4= PageTable[Index4])); } =20 L3PageTable =3D (UINT64 *)(UINTN)(L4PageTable[Index4] & PAGING_4K_ADDRES= S_MASK_64); @@ -547,6 +556,7 @@ GetSecondLevelPageTableEntry ( return NULL; } SetSecondLevelPagingEntryAttribute ((VTD_SECOND_LEVEL_PAGING_ENTRY *)&= L3PageTable[Index3], EDKII_IOMMU_ACCESS_READ | EDKII_IOMMU_ACCESS_WRITE); + FlushPageTableMemory (VtdIndex, (UINTN)&L3PageTable[Index3], sizeof(L3= PageTable[Index3])); } if ((L3PageTable[Index3] & VTD_PG_PS) !=3D 0) { // 1G @@ -559,6 +569,7 @@ GetSecondLevelPageTableEntry ( L2PageTable[Index2] =3D Address & PAGING_2M_ADDRESS_MASK_64; SetSecondLevelPagingEntryAttribute ((VTD_SECOND_LEVEL_PAGING_ENTRY *)&= L2PageTable[Index2], 0); L2PageTable[Index2] |=3D VTD_PG_PS; + FlushPageTableMemory (VtdIndex, (UINTN)&L2PageTable[Index2], sizeof(L2= PageTable[Index2])); } if ((L2PageTable[Index2] & VTD_PG_PS) !=3D 0) { // 2M @@ -579,12 +590,14 @@ GetSecondLevelPageTableEntry ( /** Modify memory attributes of page entry. =20 + @param[in] VtdIndex The index used to identify a VTd engine. @param[in] PageEntry The page entry. @param[in] IoMmuAccess The IOMMU access. @param[out] IsModified TRUE means page table modified. FALSE mean= s page table not modified. **/ VOID ConvertSecondLevelPageEntryAttribute ( + IN UINTN VtdIndex, IN VTD_SECOND_LEVEL_PAGING_ENTRY *PageEntry, IN UINT64 IoMmuAccess, OUT BOOLEAN *IsModified @@ -595,6 +608,7 @@ ConvertSecondLevelPageEntryAttribute ( =20 CurrentPageEntry =3D PageEntry->Uint64; SetSecondLevelPagingEntryAttribute (PageEntry, IoMmuAccess); + FlushPageTableMemory (VtdIndex, (UINTN)PageEntry, sizeof(*PageEntry)); NewPageEntry =3D PageEntry->Uint64; if (CurrentPageEntry !=3D NewPageEntry) { *IsModified =3D TRUE; @@ -639,6 +653,7 @@ NeedSplitPage ( /** This function splits one page entry to small page entries. =20 + @param[in] VtdIndex The index used to identify a VTd engine. @param[in] PageEntry The page entry to be splitted. @param[in] PageAttribute The page attribute of the page entry. @param[in] SplitAttribute How to split the page entry. @@ -649,6 +664,7 @@ NeedSplitPage ( **/ RETURN_STATUS SplitSecondLevelPage ( + IN UINTN VtdIndex, IN VTD_SECOND_LEVEL_PAGING_ENTRY *PageEntry, IN PAGE_ATTRIBUTE PageAttribute, IN PAGE_ATTRIBUTE SplitAttribute @@ -675,8 +691,11 @@ SplitSecondLevelPage ( for (Index =3D 0; Index < SIZE_4KB / sizeof(UINT64); Index++) { NewPageEntry[Index] =3D (BaseAddress + SIZE_4KB * Index) | (PageEn= try->Uint64 & PAGE_PROGATE_BITS); } + FlushPageTableMemory (VtdIndex, (UINTN)NewPageEntry, SIZE_4KB); + PageEntry->Uint64 =3D (UINT64)(UINTN)NewPageEntry; SetSecondLevelPagingEntryAttribute (PageEntry, EDKII_IOMMU_ACCESS_RE= AD | EDKII_IOMMU_ACCESS_WRITE); + FlushPageTableMemory (VtdIndex, (UINTN)PageEntry, sizeof(*PageEntry)= ); return RETURN_SUCCESS; } else { return RETURN_UNSUPPORTED; @@ -697,8 +716,11 @@ SplitSecondLevelPage ( for (Index =3D 0; Index < SIZE_4KB / sizeof(UINT64); Index++) { NewPageEntry[Index] =3D (BaseAddress + SIZE_2MB * Index) | VTD_PG_= PS | (PageEntry->Uint64 & PAGE_PROGATE_BITS); } + FlushPageTableMemory (VtdIndex, (UINTN)NewPageEntry, SIZE_4KB); + PageEntry->Uint64 =3D (UINT64)(UINTN)NewPageEntry; SetSecondLevelPagingEntryAttribute (PageEntry, EDKII_IOMMU_ACCESS_RE= AD | EDKII_IOMMU_ACCESS_WRITE); + FlushPageTableMemory (VtdIndex, (UINTN)PageEntry, sizeof(*PageEntry)= ); return RETURN_SUCCESS; } else { return RETURN_UNSUPPORTED; @@ -730,6 +752,7 @@ SplitSecondLevelPage ( EFI_STATUS SetSecondLevelPagingAttribute ( IN UINTN VtdIndex, + IN UINT16 DomainIdentifier, IN VTD_SECOND_LEVEL_PAGING_ENTRY *SecondLevelPagingEntry, IN UINT64 BaseAddress, IN UINT64 Length, @@ -756,7 +779,7 @@ SetSecondLevelPagingAttribute ( } =20 while (Length !=3D 0) { - PageEntry =3D GetSecondLevelPageTableEntry (SecondLevelPagingEntry, Ba= seAddress, &PageAttribute); + PageEntry =3D GetSecondLevelPageTableEntry (VtdIndex, SecondLevelPagin= gEntry, BaseAddress, &PageAttribute); if (PageEntry =3D=3D NULL) { DEBUG ((DEBUG_ERROR, "PageEntry - NULL\n")); return RETURN_UNSUPPORTED; @@ -764,7 +787,7 @@ SetSecondLevelPagingAttribute ( PageEntryLength =3D PageAttributeToLength (PageAttribute); SplitAttribute =3D NeedSplitPage (BaseAddress, Length, PageAttribute); if (SplitAttribute =3D=3D PageNone) { - ConvertSecondLevelPageEntryAttribute (PageEntry, IoMmuAccess, &IsEnt= ryModified); + ConvertSecondLevelPageEntryAttribute (VtdIndex, PageEntry, IoMmuAcce= ss, &IsEntryModified); if (IsEntryModified) { mVtdUnitInformation[VtdIndex].HasDirtyPages =3D TRUE; } @@ -774,7 +797,7 @@ SetSecondLevelPagingAttribute ( BaseAddress +=3D PageEntryLength; Length -=3D PageEntryLength; } else { - Status =3D SplitSecondLevelPage (PageEntry, PageAttribute, SplitAttr= ibute); + Status =3D SplitSecondLevelPage (VtdIndex, PageEntry, PageAttribute,= SplitAttribute); if (RETURN_ERROR (Status)) { DEBUG ((DEBUG_ERROR, "SplitSecondLevelPage - %r\n", Status)); return RETURN_UNSUPPORTED; @@ -787,8 +810,6 @@ SetSecondLevelPagingAttribute ( } } =20 - InvalidatePageEntry (VtdIndex); - return EFI_SUCCESS; } =20 @@ -814,6 +835,7 @@ SetSecondLevelPagingAttribute ( EFI_STATUS SetPageAttribute ( IN UINTN VtdIndex, + IN UINT16 DomainIdentifier, IN VTD_SECOND_LEVEL_PAGING_ENTRY *SecondLevelPagingEntry, IN UINT64 BaseAddress, IN UINT64 Length, @@ -823,7 +845,7 @@ SetPageAttribute ( EFI_STATUS Status; Status =3D EFI_NOT_FOUND; if (SecondLevelPagingEntry !=3D NULL) { - Status =3D SetSecondLevelPagingAttribute (VtdIndex, SecondLevelPagingE= ntry, BaseAddress, Length, IoMmuAccess); + Status =3D SetSecondLevelPagingAttribute (VtdIndex, DomainIdentifier, = SecondLevelPagingEntry, BaseAddress, Length, IoMmuAccess); } return Status; } @@ -862,6 +884,8 @@ SetAccessAttribute ( VTD_CONTEXT_ENTRY *ContextEntry; VTD_SECOND_LEVEL_PAGING_ENTRY *SecondLevelPagingEntry; UINT64 Pt; + UINTN PciDescriptorIndex; + UINT16 DomainIdentifier; =20 SecondLevelPagingEntry =3D NULL; =20 @@ -873,6 +897,13 @@ SetAccessAttribute ( return EFI_DEVICE_ERROR; } =20 + PciDescriptorIndex =3D GetPciDescriptor (VtdIndex, Segment, SourceId); + mVtdUnitInformation[VtdIndex].PciDeviceInfo.AccessCount[PciDescriptorInd= ex]++; + // + // DomainId should not be 0. + // + DomainIdentifier =3D (UINT16)(PciDescriptorIndex + 1); + if (ExtContextEntry !=3D NULL) { if (ExtContextEntry->Bits.Present =3D=3D 0) { SecondLevelPagingEntry =3D CreateSecondLevelPagingEntry (VtdIndex, 0= ); @@ -881,9 +912,11 @@ SetAccessAttribute ( =20 ExtContextEntry->Bits.SecondLevelPageTranslationPointerLo =3D (UINT3= 2) Pt; ExtContextEntry->Bits.SecondLevelPageTranslationPointerHi =3D (UINT3= 2) RShiftU64(Pt, 20); - ExtContextEntry->Bits.DomainIdentifier =3D (UINT16) GetPciDescriptor= (VtdIndex, Segment, SourceId); + ExtContextEntry->Bits.DomainIdentifier =3D DomainIdentifier; ExtContextEntry->Bits.Present =3D 1; + FlushPageTableMemory (VtdIndex, (UINTN)ExtContextEntry, sizeof(*ExtC= ontextEntry)); DumpDmarExtContextEntryTable (mVtdUnitInformation[VtdIndex].ExtRootE= ntryTable); + mVtdUnitInformation[VtdIndex].HasDirtyContext =3D TRUE; } else { SecondLevelPagingEntry =3D (VOID *)(UINTN)VTD_64BITS_ADDRESS(ExtCont= extEntry->Bits.SecondLevelPageTranslationPointerLo, ExtContextEntry->Bits.S= econdLevelPageTranslationPointerHi); DEBUG ((DEBUG_VERBOSE,"SecondLevelPagingEntry - 0x%x (S%04x B%02x D%= 02x F%02x)\n", SecondLevelPagingEntry, Segment, SourceId.Bits.Bus, SourceId= .Bits.Device, SourceId.Bits.Function)); @@ -896,9 +929,11 @@ SetAccessAttribute ( =20 ContextEntry->Bits.SecondLevelPageTranslationPointerLo =3D (UINT32) = Pt; ContextEntry->Bits.SecondLevelPageTranslationPointerHi =3D (UINT32) = RShiftU64(Pt, 20); - ContextEntry->Bits.DomainIdentifier =3D (UINT16) GetPciDescriptor (V= tdIndex, Segment, SourceId); + ContextEntry->Bits.DomainIdentifier =3D DomainIdentifier; ContextEntry->Bits.Present =3D 1; + FlushPageTableMemory (VtdIndex, (UINTN)ContextEntry, sizeof(*Context= Entry)); DumpDmarContextEntryTable (mVtdUnitInformation[VtdIndex].RootEntryTa= ble); + mVtdUnitInformation[VtdIndex].HasDirtyContext =3D TRUE; } else { SecondLevelPagingEntry =3D (VOID *)(UINTN)VTD_64BITS_ADDRESS(Context= Entry->Bits.SecondLevelPageTranslationPointerLo, ContextEntry->Bits.SecondL= evelPageTranslationPointerHi); DEBUG ((DEBUG_VERBOSE,"SecondLevelPagingEntry - 0x%x (S%04x B%02x D%= 02x F%02x)\n", SecondLevelPagingEntry, Segment, SourceId.Bits.Bus, SourceId= .Bits.Device, SourceId.Bits.Function)); @@ -911,6 +946,7 @@ SetAccessAttribute ( if (SecondLevelPagingEntry !=3D mVtdUnitInformation[VtdIndex].FixedSecon= dLevelPagingEntry) { Status =3D SetPageAttribute ( VtdIndex, + DomainIdentifier, SecondLevelPagingEntry, BaseAddress, Length, @@ -922,6 +958,8 @@ SetAccessAttribute ( } } =20 + InvalidatePageEntry (VtdIndex); + return EFI_SUCCESS; } =20 @@ -965,11 +1003,13 @@ AlwaysEnablePageAttribute ( ExtContextEntry->Bits.SecondLevelPageTranslationPointerHi =3D (UINT32)= RShiftU64(Pt, 20); ExtContextEntry->Bits.DomainIdentifier =3D ((1 << (UINT8)((UINTN)mVtdU= nitInformation[VtdIndex].CapReg.Bits.ND * 2 + 4)) - 1); ExtContextEntry->Bits.Present =3D 1; + FlushPageTableMemory (VtdIndex, (UINTN)ExtContextEntry, sizeof(*ExtCon= textEntry)); } 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)mVtdUnit= Information[VtdIndex].CapReg.Bits.ND * 2 + 4)) - 1); ContextEntry->Bits.Present =3D 1; + FlushPageTableMemory (VtdIndex, (UINTN)ContextEntry, sizeof(*ContextEn= try)); } =20 return EFI_SUCCESS; diff --git a/IntelSiliconPkg/IntelVTdDxe/TranslationTableEx.c b/IntelSilico= nPkg/IntelVTdDxe/TranslationTableEx.c index 65ed16e..9d4e6ea 100644 --- a/IntelSiliconPkg/IntelVTdDxe/TranslationTableEx.c +++ b/IntelSiliconPkg/IntelVTdDxe/TranslationTableEx.c @@ -73,6 +73,7 @@ CreateExtContextEntry ( ExtRootEntry->Bits.UpperContextTablePointerLo =3D (UINT32) RShiftU6= 4 ((UINT64)(UINTN)Buffer, 12) + 1; ExtRootEntry->Bits.UpperContextTablePointerHi =3D (UINT32) RShiftU6= 4 (RShiftU64 ((UINT64)(UINTN)Buffer, 12) + 1, 20); ExtRootEntry->Bits.UpperPresent =3D 1; + FlushPageTableMemory (VtdIndex, (UINTN)ExtRootEntry, sizeof(*ExtRoot= Entry)); Buffer =3D (UINT8 *)Buffer + EFI_PAGES_TO_SIZE (ContextPages); } =20 @@ -92,6 +93,7 @@ CreateExtContextEntry ( ExtContextEntry->Bits.AddressWidth =3D 0x2; break; } + FlushPageTableMemory (VtdIndex, (UINTN)ExtContextEntry, sizeof(*ExtCon= textEntry)); } =20 return EFI_SUCCESS; diff --git a/IntelSiliconPkg/IntelVTdDxe/VtdReg.c b/IntelSiliconPkg/IntelVT= dDxe/VtdReg.c index f36e3de..d95a8a7 100644 --- a/IntelSiliconPkg/IntelVTdDxe/VtdReg.c +++ b/IntelSiliconPkg/IntelVTdDxe/VtdReg.c @@ -20,145 +20,105 @@ VTD_UNIT_INFORMATION *mVtdUnitInformation; BOOLEAN mVtdEnabled; =20 /** - Invalid VTd global IOTLB. + Flush VTD page table and context table memory. =20 - @param[in] VtdIndex The index of VTd engine. + This action is to make sure the IOMMU engine can get final data in memor= y. =20 - @retval EFI_SUCCESS VTd global IOTLB is invalidated. - @retval EFI_DEVICE_ERROR VTd global IOTLB is not invalidated. + @param[in] VtdIndex The index used to identify a VTd engine. + @param[in] Base The base address of memory to be flushed. + @param[in] Size The size of memory in bytes to be flushed. **/ -EFI_STATUS -InvalidateVtdIOTLBGlobal ( - IN UINTN VtdIndex +VOID +FlushPageTableMemory ( + IN UINTN VtdIndex, + IN UINTN Base, + IN UINTN Size ) { - UINT64 Reg64; - UINT32 Reg32; + UINTN Address; + UINTN AddressEnd; =20 - if (!mVtdEnabled) { - return EFI_SUCCESS; + if (mVtdUnitInformation[VtdIndex].ECapReg.Bits.C =3D=3D 0) { + Address =3D Base & ~(mCacheLineSize - 1); + AddressEnd =3D Base + Size; + + for (; Address <=3D AddressEnd; Address +=3D mCacheLineSize) { + CacheLineFlush (Address); + } } +} =20 - DEBUG((DEBUG_VERBOSE, "InvalidateVtdIOTLBGlobal(%d)\n", VtdIndex)); +/** + Flush VTd engine write buffer. =20 - AsmWbinvd(); + @param[in] VtdIndex The index used to identify a VTd engine. +**/ +VOID +FlushWriteBuffer ( + IN UINTN VtdIndex + ) +{ + UINT32 Reg32; =20 - // - // Write Buffer Flush before invalidation - // - Reg32 =3D MmioRead32 (mVtdUnitInformation[VtdIndex].VtdUnitBaseAddress += R_CAP_REG); - if ((Reg32 & B_CAP_REG_RWBF) !=3D 0) { - MmioWrite32 (mVtdUnitInformation[VtdIndex].VtdUnitBaseAddress + R_GCMD= _REG, B_GMCD_REG_WBF); + if (mVtdUnitInformation[VtdIndex].CapReg.Bits.RWBF !=3D 0) { + Reg32 =3D MmioRead32 (mVtdUnitInformation[VtdIndex].VtdUnitBaseAddress= + R_GSTS_REG); + MmioWrite32 (mVtdUnitInformation[VtdIndex].VtdUnitBaseAddress + R_GCMD= _REG, Reg32 | B_GMCD_REG_WBF); + do { + Reg32 =3D MmioRead32 (mVtdUnitInformation[VtdIndex].VtdUnitBaseAddre= ss + R_GSTS_REG); + } while ((Reg32 & B_GSTS_REG_WBF) !=3D 0); } +} =20 - // - // Invalidate the context cache - // - Reg64 =3D MmioRead64 (mVtdUnitInformation[VtdIndex].VtdUnitBaseAddress += R_CCMD_REG); - if ((Reg64 & B_CCMD_REG_ICC) !=3D 0) { - DEBUG ((DEBUG_ERROR,"ERROR: InvalidateVtdIOTLBGlobal: B_CCMD_REG_ICC i= s set for VTD(%d)\n",VtdIndex)); - return EFI_DEVICE_ERROR; - } +/** + Invalidate VTd context cache. =20 - Reg64 &=3D ((~B_CCMD_REG_ICC) & (~B_CCMD_REG_CIRG_MASK)); - Reg64 |=3D (B_CCMD_REG_ICC | V_CCMD_REG_CIRG_GLOBAL); - MmioWrite64 (mVtdUnitInformation[VtdIndex].VtdUnitBaseAddress + R_CCMD_R= EG, Reg64); + @param[in] VtdIndex The index used to identify a VTd engine. +**/ +EFI_STATUS +InvalidateContextCache ( + IN UINTN VtdIndex + ) +{ + UINT64 Reg64; =20 - do { + if (mVtdUnitInformation[VtdIndex].HasDirtyContext) { Reg64 =3D MmioRead64 (mVtdUnitInformation[VtdIndex].VtdUnitBaseAddress= + R_CCMD_REG); - } while ((Reg64 & B_CCMD_REG_ICC) !=3D 0); + if ((Reg64 & B_CCMD_REG_ICC) !=3D 0) { + DEBUG ((DEBUG_ERROR,"ERROR: InvalidateContextCache: B_CCMD_REG_ICC i= s set for VTD(%d)\n",VtdIndex)); + return EFI_DEVICE_ERROR; + } =20 - // - // Invalidate the IOTLB cache - // + Reg64 &=3D ((~B_CCMD_REG_ICC) & (~B_CCMD_REG_CIRG_MASK)); + Reg64 |=3D (B_CCMD_REG_ICC | V_CCMD_REG_CIRG_GLOBAL); + MmioWrite64 (mVtdUnitInformation[VtdIndex].VtdUnitBaseAddress + R_CCMD= _REG, Reg64); =20 - Reg64 =3D MmioRead64 (mVtdUnitInformation[VtdIndex].VtdUnitBaseAddress += (mVtdUnitInformation[VtdIndex].ECapReg.Bits.IRO * 16) + R_IOTLB_REG); - if ((Reg64 & B_IOTLB_REG_IVT) !=3D 0) { - DEBUG ((DEBUG_ERROR,"ERROR: InvalidateVtdIOTLBGlobal: B_IOTLB_REG_IVT = is set for VTD(%d)\n", VtdIndex)); - return EFI_DEVICE_ERROR; + do { + Reg64 =3D MmioRead64 (mVtdUnitInformation[VtdIndex].VtdUnitBaseAddre= ss + R_CCMD_REG); + } while ((Reg64 & B_CCMD_REG_ICC) !=3D 0); } - - Reg64 &=3D ((~B_IOTLB_REG_IVT) & (~B_IOTLB_REG_IIRG_MASK)); - Reg64 |=3D (B_IOTLB_REG_IVT | V_IOTLB_REG_IIRG_GLOBAL); - MmioWrite64 (mVtdUnitInformation[VtdIndex].VtdUnitBaseAddress + (mVtdUni= tInformation[VtdIndex].ECapReg.Bits.IRO * 16) + R_IOTLB_REG, Reg64); - - do { - Reg64 =3D MmioRead64 (mVtdUnitInformation[VtdIndex].VtdUnitBaseAddress= + (mVtdUnitInformation[VtdIndex].ECapReg.Bits.IRO * 16) + R_IOTLB_REG); - } while ((Reg64 & B_IOTLB_REG_IVT) !=3D 0); - - // - // Disable VTd - // - MmioWrite32 (mVtdUnitInformation[VtdIndex].VtdUnitBaseAddress + R_GCMD_R= EG, B_GMCD_REG_SRTP); - do { - Reg32 =3D MmioRead32 (mVtdUnitInformation[VtdIndex].VtdUnitBaseAddress= + R_GSTS_REG); - } while((Reg32 & B_GSTS_REG_RTPS) =3D=3D 0); - - // - // Enable VTd - // - MmioWrite32 (mVtdUnitInformation[VtdIndex].VtdUnitBaseAddress + R_GCMD_R= EG, B_GMCD_REG_TE); - do { - Reg32 =3D MmioRead32 (mVtdUnitInformation[VtdIndex].VtdUnitBaseAddress= + R_GSTS_REG); - } while ((Reg32 & B_GSTS_REG_TE) =3D=3D 0); - return EFI_SUCCESS; } =20 /** - Invalid VTd IOTLB domain. + Invalidate VTd IOTLB. =20 - @param[in] VtdIndex The index of VTd engine. - @param[in] DomainIdentifier The domain ID of the source. - - @retval EFI_SUCCESS VTd IOTLB domain is invalidated. - @retval EFI_DEVICE_ERROR VTd IOTLB domain is not invalidated. + @param[in] VtdIndex The index used to identify a VTd engine. **/ EFI_STATUS -InvalidateVtdIOTLBDomain ( - IN UINTN VtdIndex, - IN UINT16 DomainIdentifier +InvalidateIOTLB ( + IN UINTN VtdIndex ) { UINT64 Reg64; =20 - if (!mVtdEnabled) { - return EFI_SUCCESS; - } - - DEBUG((DEBUG_VERBOSE, "InvalidateVtdIOTLBDomain(%d): 0x%016lx (0x%04x)\n= ", VtdIndex, DomainIdentifier)); - - // - // Invalidate the context cache - // - Reg64 =3D MmioRead64 (mVtdUnitInformation[VtdIndex].VtdUnitBaseAddress += R_CCMD_REG); - if ((Reg64 & B_CCMD_REG_ICC) !=3D 0) { - DEBUG ((DEBUG_ERROR,"ERROR: InvalidateVtdIOTLBDomain: B_CCMD_REG_ICC i= s set for VTD(%d)\n",VtdIndex)); - return EFI_DEVICE_ERROR; - } - - Reg64 &=3D ((~B_CCMD_REG_ICC) & (~B_CCMD_REG_CIRG_MASK)); - Reg64 |=3D (B_CCMD_REG_ICC | V_CCMD_REG_CIRG_DOMAIN); - Reg64 |=3D (B_CCMD_REG_ICC | V_CCMD_REG_CIRG_DOMAIN); - MmioWrite64 (mVtdUnitInformation[VtdIndex].VtdUnitBaseAddress + R_CCMD_R= EG, Reg64); - - do { - Reg64 =3D MmioRead64 (mVtdUnitInformation[VtdIndex].VtdUnitBaseAddress= + R_CCMD_REG); - } while ((Reg64 & B_CCMD_REG_ICC) !=3D 0); - - // - // Invalidate the IOTLB cache - // - Reg64 =3D MmioRead64 (mVtdUnitInformation[VtdIndex].VtdUnitBaseAddress += (mVtdUnitInformation[VtdIndex].ECapReg.Bits.IRO * 16) + R_IOTLB_REG); if ((Reg64 & B_IOTLB_REG_IVT) !=3D 0) { - DEBUG ((DEBUG_ERROR,"ERROR: InvalidateVtdIOTLBDomain: B_IOTLB_REG_IVT = is set for VTD(%d)\n", VtdIndex)); + DEBUG ((DEBUG_ERROR,"ERROR: InvalidateIOTLB: B_IOTLB_REG_IVT is set fo= r VTD(%d)\n", VtdIndex)); 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_DOMAIN); - Reg64 |=3D LShiftU64 (DomainIdentifier, 32); + Reg64 |=3D (B_IOTLB_REG_IVT | V_IOTLB_REG_IIRG_GLOBAL); MmioWrite64 (mVtdUnitInformation[VtdIndex].VtdUnitBaseAddress + (mVtdUni= tInformation[VtdIndex].ECapReg.Bits.IRO * 16) + R_IOTLB_REG, Reg64); =20 do { @@ -169,53 +129,41 @@ InvalidateVtdIOTLBDomain ( } =20 /** - Invalid VTd IOTLB page. + Invalid VTd global IOTLB. =20 @param[in] VtdIndex The index of VTd engine. - @param[in] Address The address of IOTLB page. - @param[in] AddressMode The address mode of IOTLB page. - @param[in] DomainIdentifier The domain ID of the source. =20 - @retval EFI_SUCCESS VTd IOTLB page is invalidated. - @retval EFI_DEVICE_ERROR VTd IOTLB page is not invalidated. + @retval EFI_SUCCESS VTd global IOTLB is invalidated. + @retval EFI_DEVICE_ERROR VTd global IOTLB is not invalidated. **/ EFI_STATUS -InvalidateVtdIOTLBPage ( - IN UINTN VtdIndex, - IN UINT64 Address, - IN UINT8 AddressMode, - IN UINT16 DomainIdentifier +InvalidateVtdIOTLBGlobal ( + IN UINTN VtdIndex ) { - UINT64 Reg64; - UINT64 Data64; - if (!mVtdEnabled) { return EFI_SUCCESS; } =20 - DEBUG((DEBUG_VERBOSE, "InvalidateVtdIOTLBPage(%d): 0x%016lx (0x%02x)\n",= VtdIndex, Address, AddressMode)); - - if (mVtdUnitInformation[VtdIndex].CapReg.Bits.PSI !=3D 0) { - Reg64 =3D MmioRead64 (mVtdUnitInformation[VtdIndex].VtdUnitBaseAddress= + (mVtdUnitInformation[VtdIndex].ECapReg.Bits.IRO * 16) + R_IOTLB_REG); - if ((Reg64 & B_IOTLB_REG_IVT) !=3D 0) { - DEBUG ((DEBUG_ERROR,"ERROR: InvalidateVtdIOTLBPage: B_IOTLB_REG_IVT = is set for VTD(%d)\n", VtdIndex)); - return EFI_DEVICE_ERROR; - } + DEBUG((DEBUG_VERBOSE, "InvalidateVtdIOTLBGlobal(%d)\n", VtdIndex)); =20 - Data64 =3D Address | AddressMode; - MmioWrite64 (mVtdUnitInformation[VtdIndex].VtdUnitBaseAddress + (mVtdU= nitInformation[VtdIndex].ECapReg.Bits.IRO * 16) + R_IVA_REG, Data64); + // + // Write Buffer Flush before invalidation + // + FlushWriteBuffer (VtdIndex); =20 - Reg64 &=3D ((~B_IOTLB_REG_IVT) & (~B_IOTLB_REG_IIRG_MASK)); - Reg64 |=3D (B_IOTLB_REG_IVT | V_IOTLB_REG_IIRG_PAGE); - Reg64 |=3D LShiftU64 (DomainIdentifier, 32); - MmioWrite64 (mVtdUnitInformation[VtdIndex].VtdUnitBaseAddress + (mVtdU= nitInformation[VtdIndex].ECapReg.Bits.IRO * 16) + R_IOTLB_REG, Reg64); + // + // Invalidate the context cache + // + if (mVtdUnitInformation[VtdIndex].HasDirtyContext) { + InvalidateContextCache (VtdIndex); + } =20 - do { - Reg64 =3D MmioRead64 (mVtdUnitInformation[VtdIndex].VtdUnitBaseAddre= ss + (mVtdUnitInformation[VtdIndex].ECapReg.Bits.IRO * 16) + R_IOTLB_REG); - } while ((Reg64 & B_IOTLB_REG_IVT) !=3D 0); - } else { - InvalidateVtdIOTLBGlobal (VtdIndex); + // + // Invalidate the IOTLB cache + // + if (mVtdUnitInformation[VtdIndex].HasDirtyContext || mVtdUnitInformation= [VtdIndex].HasDirtyPages) { + InvalidateIOTLB (VtdIndex); } =20 return EFI_SUCCESS; @@ -268,11 +216,8 @@ EnableDmar ( ) { UINTN Index; - UINT64 Reg64; UINT32 Reg32; =20 - AsmWbinvd(); - for (Index =3D 0; Index < mVtdUnitNumber; Index++) { DEBUG((DEBUG_INFO, ">>>>>>EnableDmar() for engine [%d] \n", Index)); =20 @@ -299,48 +244,17 @@ EnableDmar ( // // Write Buffer Flush before invalidation // - Reg32 =3D MmioRead32 (mVtdUnitInformation[Index].VtdUnitBaseAddress + = R_CAP_REG); - if ((Reg32 & B_CAP_REG_RWBF) !=3D 0) { - MmioWrite32 (mVtdUnitInformation[Index].VtdUnitBaseAddress + R_GCMD_= REG, B_GMCD_REG_WBF); - } + FlushWriteBuffer (Index); =20 // // Invalidate the context cache // - Reg64 =3D MmioRead64 (mVtdUnitInformation[Index].VtdUnitBaseAddress + = R_CCMD_REG); - if ((Reg64 & B_CCMD_REG_ICC) !=3D 0) { - DEBUG ((DEBUG_INFO,"ERROR: EnableDmar: B_CCMD_REG_ICC is set for VTD= (%d)\n",Index)); - return EFI_DEVICE_ERROR; - } - - Reg64 &=3D ((~B_CCMD_REG_ICC) & (~B_CCMD_REG_CIRG_MASK)); - Reg64 |=3D (B_CCMD_REG_ICC | V_CCMD_REG_CIRG_GLOBAL); - MmioWrite64 (mVtdUnitInformation[Index].VtdUnitBaseAddress + R_CCMD_RE= G, Reg64); - - DEBUG((DEBUG_INFO, "EnableDmar: Waiting B_CCMD_REG_ICC ...\n")); - do { - Reg64 =3D MmioRead64 (mVtdUnitInformation[Index].VtdUnitBaseAddress = + R_CCMD_REG); - } while ((Reg64 & B_CCMD_REG_ICC) !=3D 0); + InvalidateContextCache (Index); =20 // // Invalidate the IOTLB cache // - DEBUG((DEBUG_INFO, "EnableDmar: IRO 0x%x\n", mVtdUnitInformation[Index= ].ECapReg.Bits.IRO)); - - Reg64 =3D MmioRead64 (mVtdUnitInformation[Index].VtdUnitBaseAddress + = (mVtdUnitInformation[Index].ECapReg.Bits.IRO * 16) + R_IOTLB_REG); - if ((Reg64 & B_IOTLB_REG_IVT) !=3D 0) { - DEBUG ((DEBUG_INFO,"ERROR: EnableDmar: B_IOTLB_REG_IVT is set for VT= D(%d)\n", Index)); - return EFI_DEVICE_ERROR; - } - - Reg64 &=3D ((~B_IOTLB_REG_IVT) & (~B_IOTLB_REG_IIRG_MASK)); - Reg64 |=3D (B_IOTLB_REG_IVT | V_IOTLB_REG_IIRG_GLOBAL); - MmioWrite64 (mVtdUnitInformation[Index].VtdUnitBaseAddress + (mVtdUnit= Information[Index].ECapReg.Bits.IRO * 16) + R_IOTLB_REG, Reg64); - - DEBUG((DEBUG_INFO, "EnableDmar: Waiting B_IOTLB_REG_IVT ...\n")); - do { - Reg64 =3D MmioRead64 (mVtdUnitInformation[Index].VtdUnitBaseAddress = + (mVtdUnitInformation[Index].ECapReg.Bits.IRO * 16) + R_IOTLB_REG); - } while ((Reg64 & B_IOTLB_REG_IVT) !=3D 0); + InvalidateIOTLB (Index); =20 // // Enable VTd @@ -371,20 +285,16 @@ DisableDmar ( ) { UINTN Index; + UINTN SubIndex; UINT32 Reg32; =20 - AsmWbinvd(); - for (Index =3D 0; Index < mVtdUnitNumber; Index++) { DEBUG((DEBUG_INFO, ">>>>>>DisableDmar() for engine [%d] \n", Index)); =20 // // Write Buffer Flush before invalidation // - Reg32 =3D MmioRead32 (mVtdUnitInformation[Index].VtdUnitBaseAddress + = R_CAP_REG); - if ((Reg32 & B_CAP_REG_RWBF) !=3D 0) { - MmioWrite32 (mVtdUnitInformation[Index].VtdUnitBaseAddress + R_GCMD_= REG, B_GMCD_REG_WBF); - } + FlushWriteBuffer (Index); =20 // // Disable VTd @@ -402,6 +312,19 @@ DisableDmar ( =20 mVtdEnabled =3D FALSE; =20 + for (Index =3D 0; Index < mVtdUnitNumber; Index++) { + DEBUG((DEBUG_INFO, "engine [%d] access\n", Index)); + for (SubIndex =3D 0; SubIndex < mVtdUnitInformation[Index].PciDeviceIn= fo.PciDescriptorNumber; SubIndex++) { + DEBUG ((DEBUG_INFO, " PCI S%04X B%02x D%02x F%02x - %d\n", + mVtdUnitInformation[Index].Segment, + mVtdUnitInformation[Index].PciDeviceInfo.PciDescriptors[SubIndex].= Bits.Bus, + mVtdUnitInformation[Index].PciDeviceInfo.PciDescriptors[SubIndex].= Bits.Device, + mVtdUnitInformation[Index].PciDeviceInfo.PciDescriptors[SubIndex].= Bits.Function, + mVtdUnitInformation[Index].PciDeviceInfo.AccessCount[SubIndex] + )); + } + } + return EFI_SUCCESS; } =20 --=20 2.7.4.windows.1 _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel