From nobody Mon May 6 19:41:26 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.zoho.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 14907566351751013.9070471075726; Tue, 28 Mar 2017 20:03:55 -0700 (PDT) Received: from [127.0.0.1] (localhost [IPv6:::1]) by ml01.01.org (Postfix) with ESMTP id 41DC020D2C3B9; Tue, 28 Mar 2017 20:03:52 -0700 (PDT) Received: from mga07.intel.com (mga07.intel.com [134.134.136.100]) (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 E4E0C21BC6A25 for ; Tue, 28 Mar 2017 20:03:50 -0700 (PDT) Received: from orsmga001.jf.intel.com ([10.7.209.18]) by orsmga105.jf.intel.com with ESMTP; 28 Mar 2017 20:03:50 -0700 Received: from ray-dev.ccr.corp.intel.com ([10.239.9.25]) by orsmga001.jf.intel.com with ESMTP; 28 Mar 2017 20:03:50 -0700 X-Original-To: edk2-devel@lists.01.org X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.36,239,1486454400"; d="scan'208";a="1113146579" From: Ruiyu Ni To: edk2-devel@lists.01.org Date: Wed, 29 Mar 2017 11:03:37 +0800 Message-Id: <20170329030346.249872-2-ruiyu.ni@intel.com> X-Mailer: git-send-email 2.9.0.windows.1 In-Reply-To: <20170329030346.249872-1-ruiyu.ni@intel.com> References: <20170329030346.249872-1-ruiyu.ni@intel.com> Subject: [edk2] [PATCH 01/10] UefiCpuPkg/MtrrLib: Correct typo in comments and remove TABs 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: Jeff Fan 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" Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Ruiyu Ni Cc: Jeff Fan --- UefiCpuPkg/Include/Library/MtrrLib.h | 14 +++++++------- UefiCpuPkg/Library/MtrrLib/MtrrLib.c | 4 ++-- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/UefiCpuPkg/Include/Library/MtrrLib.h b/UefiCpuPkg/Include/Libr= ary/MtrrLib.h index 4973d84..a769279 100644 --- a/UefiCpuPkg/Include/Library/MtrrLib.h +++ b/UefiCpuPkg/Include/Library/MtrrLib.h @@ -1,7 +1,7 @@ /** @file MTRR setting library =20 - Copyright (c) 2008 - 2015, Intel Corporation. All rights reserved.
+ Copyright (c) 2008 - 2016, 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 @@ -16,7 +16,7 @@ #define _MTRR_LIB_H_ =20 // -// According to IA32 SDM, MTRRs number and msr offset are always consistent +// According to IA32 SDM, MTRRs number and MSR offset are always consistent // for IA32 processor family // =20 @@ -92,11 +92,11 @@ typedef struct _MTRR_VARIABLE_SETTING_ { // Array for variable MTRRs // typedef struct _MTRR_VARIABLE_SETTINGS_ { - MTRR_VARIABLE_SETTING Mtrr[MTRR_NUMBER_OF_VARIABLE_MTRR]; -} MTRR_VARIABLE_SETTINGS; + MTRR_VARIABLE_SETTING Mtrr[MTRR_NUMBER_OF_VARIABLE_MTRR]; +} MTRR_VARIABLE_SETTINGS; =20 // -// Array for fixed mtrrs +// Array for fixed MTRRs // typedef struct _MTRR_FIXED_SETTINGS_ { UINT64 Mtrr[MTRR_NUMBER_OF_FIXED_MTRR]; @@ -209,7 +209,7 @@ MtrrGetMemoryAttribute ( =20 @param[out] VariableSettings A buffer to hold variable MTRRs content. =20 - @return The buffer point to MTRR_VARIABLE_SETTINGS in which holds the co= ntent of the variable mtrr + @return The buffer point to MTRR_VARIABLE_SETTINGS in which holds the co= ntent of the variable MTRR =20 **/ MTRR_VARIABLE_SETTINGS* @@ -220,7 +220,7 @@ MtrrGetVariableMtrr ( =20 =20 /** - This function sets fixed MTRRs + This function sets variable MTRRs =20 @param[in] VariableSettings A buffer to hold variable MTRRs content. =20 diff --git a/UefiCpuPkg/Library/MtrrLib/MtrrLib.c b/UefiCpuPkg/Library/Mtrr= Lib/MtrrLib.c index 7783b63..2647dda 100644 --- a/UefiCpuPkg/Library/MtrrLib/MtrrLib.c +++ b/UefiCpuPkg/Library/MtrrLib/MtrrLib.c @@ -786,7 +786,7 @@ CombineMemoryAttribute ( continue; } else { // - // The cache type is different, but the range is convered by one MTRR + // The cache type is different, but the range is covered by one MTRR // if (VariableMtrr[Index].BaseAddress =3D=3D *Base && MtrrEnd =3D=3D E= ndAddress) { InvalidateShadowMtrr (Index, VariableMtrr, UsedMtrr); @@ -1278,7 +1278,7 @@ MtrrGetMemoryAttribute ( /** Worker function prints all MTRRs for debugging. =20 - If MtrrSetting is not NULL, print MTRR settings from from input MTRR + If MtrrSetting is not NULL, print MTRR settings from input MTRR settings buffer. If MtrrSetting is NULL, print MTRR settings from MTRRs. =20 --=20 2.9.0.windows.1 _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel From nobody Mon May 6 19:41:26 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.zoho.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 1490756637363979.3205221766563; Tue, 28 Mar 2017 20:03:57 -0700 (PDT) Received: from [127.0.0.1] (localhost [IPv6:::1]) by ml01.01.org (Postfix) with ESMTP id 71AA0208F7A02; Tue, 28 Mar 2017 20:03:52 -0700 (PDT) Received: from mga07.intel.com (mga07.intel.com [134.134.136.100]) (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 CDA0920D2C3B9 for ; Tue, 28 Mar 2017 20:03:51 -0700 (PDT) Received: from orsmga001.jf.intel.com ([10.7.209.18]) by orsmga105.jf.intel.com with ESMTP; 28 Mar 2017 20:03:51 -0700 Received: from ray-dev.ccr.corp.intel.com ([10.239.9.25]) by orsmga001.jf.intel.com with ESMTP; 28 Mar 2017 20:03:50 -0700 X-Original-To: edk2-devel@lists.01.org X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.36,239,1486454400"; d="scan'208";a="1113146587" From: Ruiyu Ni To: edk2-devel@lists.01.org Date: Wed, 29 Mar 2017 11:03:38 +0800 Message-Id: <20170329030346.249872-3-ruiyu.ni@intel.com> X-Mailer: git-send-email 2.9.0.windows.1 In-Reply-To: <20170329030346.249872-1-ruiyu.ni@intel.com> References: <20170329030346.249872-1-ruiyu.ni@intel.com> Subject: [edk2] [PATCH 02/10] UefiCpuPkg/MtrrLib: Add CacheInvalid enum type to MtrrLib.h 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: Jeff Fan 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" Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Ruiyu Ni Cc: Jeff Fan --- UefiCpuPkg/Include/Library/MtrrLib.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/UefiCpuPkg/Include/Library/MtrrLib.h b/UefiCpuPkg/Include/Libr= ary/MtrrLib.h index a769279..573c14c 100644 --- a/UefiCpuPkg/Include/Library/MtrrLib.h +++ b/UefiCpuPkg/Include/Library/MtrrLib.h @@ -119,7 +119,8 @@ typedef enum { CacheWriteCombining =3D 1, CacheWriteThrough =3D 4, CacheWriteProtected =3D 5, - CacheWriteBack =3D 6 + CacheWriteBack =3D 6, + CacheInvalid =3D 7 } MTRR_MEMORY_CACHE_TYPE; =20 #define MTRR_CACHE_UNCACHEABLE 0 --=20 2.9.0.windows.1 _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel From nobody Mon May 6 19:41:26 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.zoho.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 1490756639984574.1321076588954; Tue, 28 Mar 2017 20:03:59 -0700 (PDT) Received: from [127.0.0.1] (localhost [IPv6:::1]) by ml01.01.org (Postfix) with ESMTP id A5A702041FBE2; Tue, 28 Mar 2017 20:03:55 -0700 (PDT) Received: from mga07.intel.com (mga07.intel.com [134.134.136.100]) (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 B944C20084778 for ; Tue, 28 Mar 2017 20:03:52 -0700 (PDT) Received: from orsmga001.jf.intel.com ([10.7.209.18]) by orsmga105.jf.intel.com with ESMTP; 28 Mar 2017 20:03:52 -0700 Received: from ray-dev.ccr.corp.intel.com ([10.239.9.25]) by orsmga001.jf.intel.com with ESMTP; 28 Mar 2017 20:03:51 -0700 X-Original-To: edk2-devel@lists.01.org X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.36,239,1486454400"; d="scan'208";a="1113146591" From: Ruiyu Ni To: edk2-devel@lists.01.org Date: Wed, 29 Mar 2017 11:03:39 +0800 Message-Id: <20170329030346.249872-4-ruiyu.ni@intel.com> X-Mailer: git-send-email 2.9.0.windows.1 In-Reply-To: <20170329030346.249872-1-ruiyu.ni@intel.com> References: <20170329030346.249872-1-ruiyu.ni@intel.com> Subject: [edk2] [PATCH 03/10] UefiCpuPkg/MtrrLib: IsMtrrSupported uses definitions in Msr.h 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: Jeff Fan 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" Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Ruiyu Ni Cc: Jeff Fan --- UefiCpuPkg/Library/MtrrLib/MtrrLib.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/UefiCpuPkg/Library/MtrrLib/MtrrLib.c b/UefiCpuPkg/Library/Mtrr= Lib/MtrrLib.c index 2647dda..38083d4 100644 --- a/UefiCpuPkg/Library/MtrrLib/MtrrLib.c +++ b/UefiCpuPkg/Library/MtrrLib/MtrrLib.c @@ -18,6 +18,9 @@ =20 #include =20 +#include +#include + #include #include #include @@ -2124,26 +2127,25 @@ IsMtrrSupported ( VOID ) { - UINT32 RegEdx; - UINT64 MtrrCap; + CPUID_VERSION_INFO_EDX Edx; + MSR_IA32_MTRRCAP_REGISTER MtrrCap; =20 // // Check CPUID(1).EDX[12] for MTRR capability // - AsmCpuid (1, NULL, NULL, NULL, &RegEdx); - if (BitFieldRead32 (RegEdx, 12, 12) =3D=3D 0) { + AsmCpuid (CPUID_VERSION_INFO, NULL, NULL, NULL, &Edx.Uint32); + if (Edx.Bits.MTRR =3D=3D 0) { return FALSE; } =20 // - // Check IA32_MTRRCAP.[0..7] for number of variable MTRRs and IA32_MTRRC= AP[8] for - // fixed MTRRs existence. If number of variable MTRRs is zero, or fixed = MTRRs do not + // Check number of variable MTRRs and fixed MTRRs existence. + // If number of variable MTRRs is zero, or fixed MTRRs do not // exist, return false. // - MtrrCap =3D AsmReadMsr64 (MTRR_LIB_IA32_MTRR_CAP); - if ((BitFieldRead64 (MtrrCap, 0, 7) =3D=3D 0) || (BitFieldRead64 (MtrrC= ap, 8, 8) =3D=3D 0)) { + MtrrCap.Uint64 =3D AsmReadMsr64 (MSR_IA32_MTRRCAP); + if ((MtrrCap.Bits.VCNT =3D=3D 0) || (MtrrCap.Bits.FIX =3D=3D 0)) { return FALSE; } - return TRUE; } --=20 2.9.0.windows.1 _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel From nobody Mon May 6 19:41:26 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.zoho.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 1490756642327571.5063507846106; Tue, 28 Mar 2017 20:04:02 -0700 (PDT) Received: from [127.0.0.1] (localhost [IPv6:::1]) by ml01.01.org (Postfix) with ESMTP id D8E8D2041FBFD; Tue, 28 Mar 2017 20:03:55 -0700 (PDT) Received: from mga07.intel.com (mga07.intel.com [134.134.136.100]) (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 A66FA20084778 for ; Tue, 28 Mar 2017 20:03:53 -0700 (PDT) Received: from orsmga001.jf.intel.com ([10.7.209.18]) by orsmga105.jf.intel.com with ESMTP; 28 Mar 2017 20:03:53 -0700 Received: from ray-dev.ccr.corp.intel.com ([10.239.9.25]) by orsmga001.jf.intel.com with ESMTP; 28 Mar 2017 20:03:52 -0700 X-Original-To: edk2-devel@lists.01.org X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.36,239,1486454400"; d="scan'208";a="1113146597" From: Ruiyu Ni To: edk2-devel@lists.01.org Date: Wed, 29 Mar 2017 11:03:40 +0800 Message-Id: <20170329030346.249872-5-ruiyu.ni@intel.com> X-Mailer: git-send-email 2.9.0.windows.1 In-Reply-To: <20170329030346.249872-1-ruiyu.ni@intel.com> References: <20170329030346.249872-1-ruiyu.ni@intel.com> Subject: [edk2] [PATCH 04/10] UefiCpuPkg/MtrrLib: GetVariableMtrrCountWorker uses definitions in Msr.h 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: Jeff Fan 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" Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Ruiyu Ni Cc: Jeff Fan --- UefiCpuPkg/Library/MtrrLib/MtrrLib.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/UefiCpuPkg/Library/MtrrLib/MtrrLib.c b/UefiCpuPkg/Library/Mtrr= Lib/MtrrLib.c index 38083d4..7e8a19a 100644 --- a/UefiCpuPkg/Library/MtrrLib/MtrrLib.c +++ b/UefiCpuPkg/Library/MtrrLib/MtrrLib.c @@ -124,11 +124,11 @@ GetVariableMtrrCountWorker ( VOID ) { - UINT32 VariableMtrrCount; + MSR_IA32_MTRRCAP_REGISTER MtrrCap; =20 - VariableMtrrCount =3D (UINT32)(AsmReadMsr64 (MTRR_LIB_IA32_MTRR_CAP) & M= TRR_LIB_IA32_MTRR_CAP_VCNT_MASK); - ASSERT (VariableMtrrCount <=3D MTRR_NUMBER_OF_VARIABLE_MTRR); - return VariableMtrrCount; + MtrrCap.Uint64 =3D AsmReadMsr64 (MSR_IA32_MTRRCAP); + ASSERT (MtrrCap.Bits.VCNT <=3D MTRR_NUMBER_OF_VARIABLE_MTRR); + return MtrrCap.Bits.VCNT; } =20 /** --=20 2.9.0.windows.1 _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel From nobody Mon May 6 19:41:26 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.zoho.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 1490756645184521.7633151356379; Tue, 28 Mar 2017 20:04:05 -0700 (PDT) Received: from [127.0.0.1] (localhost [IPv6:::1]) by ml01.01.org (Postfix) with ESMTP id 1831821940D03; Tue, 28 Mar 2017 20:03:58 -0700 (PDT) Received: from mga07.intel.com (mga07.intel.com [134.134.136.100]) (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 9626520084778 for ; Tue, 28 Mar 2017 20:03:54 -0700 (PDT) Received: from orsmga001.jf.intel.com ([10.7.209.18]) by orsmga105.jf.intel.com with ESMTP; 28 Mar 2017 20:03:54 -0700 Received: from ray-dev.ccr.corp.intel.com ([10.239.9.25]) by orsmga001.jf.intel.com with ESMTP; 28 Mar 2017 20:03:53 -0700 X-Original-To: edk2-devel@lists.01.org X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.36,239,1486454400"; d="scan'208";a="1113146600" From: Ruiyu Ni To: edk2-devel@lists.01.org Date: Wed, 29 Mar 2017 11:03:41 +0800 Message-Id: <20170329030346.249872-6-ruiyu.ni@intel.com> X-Mailer: git-send-email 2.9.0.windows.1 In-Reply-To: <20170329030346.249872-1-ruiyu.ni@intel.com> References: <20170329030346.249872-1-ruiyu.ni@intel.com> Subject: [edk2] [PATCH 05/10] UefiCpuPkg/MtrrLib: Add MtrrLib prefix to ProgramFixedMtrr 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: Jeff Fan 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" Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Ruiyu Ni Cc: Jeff Fan --- UefiCpuPkg/Library/MtrrLib/MtrrLib.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/UefiCpuPkg/Library/MtrrLib/MtrrLib.c b/UefiCpuPkg/Library/Mtrr= Lib/MtrrLib.c index 7e8a19a..4adc41f 100644 --- a/UefiCpuPkg/Library/MtrrLib/MtrrLib.c +++ b/UefiCpuPkg/Library/MtrrLib/MtrrLib.c @@ -445,7 +445,7 @@ MtrrGetVariableMtrr ( /** Programs fixed MTRRs registers. =20 - @param[in] MemoryCacheType The memory type to set. + @param[in] Type The memory type to set. @param[in, out] Base The base address of memory range. @param[in, out] Length The length of memory range. @param[in, out] LastMsrNum On input, the last index of the fixed M= TRR MSR to program. @@ -459,13 +459,13 @@ MtrrGetVariableMtrr ( =20 **/ RETURN_STATUS -ProgramFixedMtrr ( - IN UINT64 MemoryCacheType, - IN OUT UINT64 *Base, - IN OUT UINT64 *Length, - IN OUT UINT32 *LastMsrNum, - OUT UINT64 *ReturnClearMask, - OUT UINT64 *ReturnOrMask +MtrrLibProgramFixedMtrr ( + IN MTRR_MEMORY_CACHE_TYPE Type, + IN OUT UINT64 *Base, + IN OUT UINT64 *Length, + IN OUT UINT32 *LastMsrNum, + OUT UINT64 *ReturnClearMask, + OUT UINT64 *ReturnOrMask ) { UINT32 MsrNum; @@ -491,7 +491,7 @@ ProgramFixedMtrr ( } } =20 - if (MsrNum >=3D MTRR_NUMBER_OF_FIXED_MTRR) { + if (MsrNum =3D=3D MTRR_NUMBER_OF_FIXED_MTRR) { return RETURN_UNSUPPORTED; } =20 @@ -526,7 +526,7 @@ ProgramFixedMtrr ( } =20 ClearMask =3D CLEAR_SEED; - OrMask =3D MultU64x32 (OR_SEED, (UINT32)MemoryCacheType); + OrMask =3D MultU64x32 (OR_SEED, (UINT32) Type); =20 if (LeftByteShift !=3D 0) { // @@ -1562,7 +1562,7 @@ MtrrSetMemoryAttributeWorker ( if (BaseAddress < BASE_1MB) { MsrNum =3D (UINT32)-1; while ((BaseAddress < BASE_1MB) && (Length > 0) && Status =3D=3D RETUR= N_SUCCESS) { - Status =3D ProgramFixedMtrr (MemoryType, &BaseAddress, &Length, &Msr= Num, &ClearMask, &OrMask); + Status =3D MtrrLibProgramFixedMtrr (Attribute, &BaseAddress, &Length= , &MsrNum, &ClearMask, &OrMask); if (RETURN_ERROR (Status)) { goto Done; } --=20 2.9.0.windows.1 _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel From nobody Mon May 6 19:41:26 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.zoho.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 1490756647652154.5460379687138; Tue, 28 Mar 2017 20:04:07 -0700 (PDT) Received: from [127.0.0.1] (localhost [IPv6:::1]) by ml01.01.org (Postfix) with ESMTP id 4766221940D07; Tue, 28 Mar 2017 20:03:58 -0700 (PDT) Received: from mga07.intel.com (mga07.intel.com [134.134.136.100]) (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 870CA21DFA7BD for ; Tue, 28 Mar 2017 20:03:55 -0700 (PDT) Received: from orsmga001.jf.intel.com ([10.7.209.18]) by orsmga105.jf.intel.com with ESMTP; 28 Mar 2017 20:03:55 -0700 Received: from ray-dev.ccr.corp.intel.com ([10.239.9.25]) by orsmga001.jf.intel.com with ESMTP; 28 Mar 2017 20:03:54 -0700 X-Original-To: edk2-devel@lists.01.org X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.36,239,1486454400"; d="scan'208";a="1113146605" From: Ruiyu Ni To: edk2-devel@lists.01.org Date: Wed, 29 Mar 2017 11:03:42 +0800 Message-Id: <20170329030346.249872-7-ruiyu.ni@intel.com> X-Mailer: git-send-email 2.9.0.windows.1 In-Reply-To: <20170329030346.249872-1-ruiyu.ni@intel.com> References: <20170329030346.249872-1-ruiyu.ni@intel.com> Subject: [edk2] [PATCH 06/10] UefiCpuPkg/MtrrLib: Add MtrrLib prefix to several internal functions 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: Jeff Fan 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" Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Ruiyu Ni Cc: Jeff Fan --- UefiCpuPkg/Library/MtrrLib/MtrrLib.c | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/UefiCpuPkg/Library/MtrrLib/MtrrLib.c b/UefiCpuPkg/Library/Mtrr= Lib/MtrrLib.c index 4adc41f..d7e6f05 100644 --- a/UefiCpuPkg/Library/MtrrLib/MtrrLib.c +++ b/UefiCpuPkg/Library/MtrrLib/MtrrLib.c @@ -243,7 +243,7 @@ MtrrGetDefaultMemoryType ( =20 **/ VOID -PreMtrrChange ( +MtrrLibPreMtrrChange ( OUT MTRR_CONTEXT *MtrrContext ) { @@ -284,7 +284,7 @@ PreMtrrChange ( =20 **/ VOID -PostMtrrChangeEnableCache ( +MtrrLibPostMtrrChangeEnableCache ( IN MTRR_CONTEXT *MtrrContext ) { @@ -319,7 +319,7 @@ PostMtrrChangeEnableCache ( =20 **/ VOID -PostMtrrChange ( +MtrrLibPostMtrrChange ( IN MTRR_CONTEXT *MtrrContext ) { @@ -328,7 +328,7 @@ PostMtrrChange ( // AsmMsrBitFieldWrite64 (MTRR_LIB_IA32_MTRR_DEF_TYPE, 10, 11, 3); =20 - PostMtrrChangeEnableCache (MtrrContext); + MtrrLibPostMtrrChangeEnableCache (MtrrContext); } =20 /** @@ -1086,7 +1086,7 @@ MtrrLibInitializeMtrrMask ( =20 **/ UINT64 -MtrrPrecedence ( +MtrrLibPrecedence ( IN UINT64 MtrrType1, IN UINT64 MtrrType2 ) @@ -1245,7 +1245,7 @@ MtrrGetMemoryAttributeByAddressWorker ( if (Address >=3D VariableMtrr[Index].BaseAddress && Address < VariableMtrr[Index].BaseAddress+VariableMtrr[Index].Le= ngth) { TempMtrrType =3D VariableMtrr[Index].Type; - MtrrType =3D MtrrPrecedence (MtrrType, TempMtrrType); + MtrrType =3D MtrrLibPrecedence (MtrrType, TempMtrrType); } } } @@ -1791,7 +1791,7 @@ Done: for (Index =3D 0; Index < MTRR_NUMBER_OF_FIXED_MTRR; Index++) { if (FixedSettingsModified[Index]) { if (!MtrrContextValid) { - PreMtrrChange (&MtrrContext); + MtrrLibPreMtrrChange (&MtrrContext); MtrrContextValid =3D TRUE; } AsmWriteMsr64 ( @@ -1809,7 +1809,7 @@ Done: if (WorkingVariableSettings.Mtrr[Index].Base !=3D OriginalVariableSe= ttings.Mtrr[Index].Base || WorkingVariableSettings.Mtrr[Index].Mask !=3D OriginalVariableSe= ttings.Mtrr[Index].Mask ) { if (!MtrrContextValid) { - PreMtrrChange (&MtrrContext); + MtrrLibPreMtrrChange (&MtrrContext); MtrrContextValid =3D TRUE; } AsmWriteMsr64 ( @@ -1824,7 +1824,7 @@ Done: } } if (MtrrContextValid) { - PostMtrrChange (&MtrrContext); + MtrrLibPostMtrrChange (&MtrrContext); } =20 DEBUG((DEBUG_CACHE, " Status =3D %r\n", Status)); @@ -1971,9 +1971,9 @@ MtrrSetVariableMtrr ( return VariableSettings; } =20 - PreMtrrChange (&MtrrContext); + MtrrLibPreMtrrChange (&MtrrContext); MtrrSetVariableMtrrWorker (VariableSettings); - PostMtrrChange (&MtrrContext); + MtrrLibPostMtrrChange (&MtrrContext); MtrrDebugPrintAllMtrrs (); =20 return VariableSettings; @@ -2021,9 +2021,9 @@ MtrrSetFixedMtrr ( return FixedSettings; } =20 - PreMtrrChange (&MtrrContext); + MtrrLibPreMtrrChange (&MtrrContext); MtrrSetFixedMtrrWorker (FixedSettings); - PostMtrrChange (&MtrrContext); + MtrrLibPostMtrrChange (&MtrrContext); MtrrDebugPrintAllMtrrs (); =20 return FixedSettings; @@ -2091,7 +2091,7 @@ MtrrSetAllMtrrs ( return MtrrSetting; } =20 - PreMtrrChange (&MtrrContext); + MtrrLibPreMtrrChange (&MtrrContext); =20 // // Set fixed MTRRs @@ -2108,7 +2108,7 @@ MtrrSetAllMtrrs ( // AsmWriteMsr64 (MTRR_LIB_IA32_MTRR_DEF_TYPE, MtrrSetting->MtrrDefType); =20 - PostMtrrChangeEnableCache (&MtrrContext); + MtrrLibPostMtrrChangeEnableCache (&MtrrContext); =20 return MtrrSetting; } --=20 2.9.0.windows.1 _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel From nobody Mon May 6 19:41:26 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.zoho.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 1490756650089227.2135999010883; Tue, 28 Mar 2017 20:04:10 -0700 (PDT) Received: from [127.0.0.1] (localhost [IPv6:::1]) by ml01.01.org (Postfix) with ESMTP id 7703F21940D0A; Tue, 28 Mar 2017 20:03:58 -0700 (PDT) Received: from mga07.intel.com (mga07.intel.com [134.134.136.100]) (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 75EE02041FBD3 for ; Tue, 28 Mar 2017 20:03:56 -0700 (PDT) Received: from orsmga001.jf.intel.com ([10.7.209.18]) by orsmga105.jf.intel.com with ESMTP; 28 Mar 2017 20:03:56 -0700 Received: from ray-dev.ccr.corp.intel.com ([10.239.9.25]) by orsmga001.jf.intel.com with ESMTP; 28 Mar 2017 20:03:55 -0700 X-Original-To: edk2-devel@lists.01.org X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.36,239,1486454400"; d="scan'208";a="1113146611" From: Ruiyu Ni To: edk2-devel@lists.01.org Date: Wed, 29 Mar 2017 11:03:43 +0800 Message-Id: <20170329030346.249872-8-ruiyu.ni@intel.com> X-Mailer: git-send-email 2.9.0.windows.1 In-Reply-To: <20170329030346.249872-1-ruiyu.ni@intel.com> References: <20170329030346.249872-1-ruiyu.ni@intel.com> Subject: [edk2] [PATCH 07/10] UefiCpuPkg/MtrrLib: MtrrLibInitializeMtrrMask() uses definitions in CpuId.h 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: Jeff Fan 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" Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Ruiyu Ni Cc: Jeff Fan --- UefiCpuPkg/Library/MtrrLib/MtrrLib.c | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/UefiCpuPkg/Library/MtrrLib/MtrrLib.c b/UefiCpuPkg/Library/Mtrr= Lib/MtrrLib.c index d7e6f05..bcc2df5 100644 --- a/UefiCpuPkg/Library/MtrrLib/MtrrLib.c +++ b/UefiCpuPkg/Library/MtrrLib/MtrrLib.c @@ -1054,22 +1054,20 @@ MtrrLibInitializeMtrrMask ( OUT UINT64 *MtrrValidAddressMask ) { - UINT32 RegEax; - UINT8 PhysicalAddressBits; + UINT32 MaxExtendedFunction; + CPUID_VIR_PHY_ADDRESS_SIZE_EAX VirPhyAddressSize; =20 - AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL); =20 - if (RegEax >=3D 0x80000008) { - AsmCpuid (0x80000008, &RegEax, NULL, NULL, NULL); + AsmCpuid (CPUID_EXTENDED_FUNCTION, &MaxExtendedFunction, NULL, NULL, NUL= L); =20 - PhysicalAddressBits =3D (UINT8) RegEax; - - *MtrrValidBitsMask =3D LShiftU64 (1, PhysicalAddressBits) - 1; - *MtrrValidAddressMask =3D *MtrrValidBitsMask & 0xfffffffffffff000ULL; + if (MaxExtendedFunction >=3D CPUID_VIR_PHY_ADDRESS_SIZE) { + AsmCpuid (CPUID_VIR_PHY_ADDRESS_SIZE, &VirPhyAddressSize.Uint32, NULL,= NULL, NULL); } else { - *MtrrValidBitsMask =3D MTRR_LIB_MSR_VALID_MASK; - *MtrrValidAddressMask =3D MTRR_LIB_CACHE_VALID_ADDRESS; + VirPhyAddressSize.Bits.PhysicalAddressBits =3D 36; } + + *MtrrValidBitsMask =3D LShiftU64 (1, VirPhyAddressSize.Bits.PhysicalAddr= essBits) - 1; + *MtrrValidAddressMask =3D *MtrrValidBitsMask & 0xfffffffffffff000ULL; } =20 =20 --=20 2.9.0.windows.1 _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel From nobody Mon May 6 19:41:26 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.zoho.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 1490756652473436.8645426960966; Tue, 28 Mar 2017 20:04:12 -0700 (PDT) Received: from [127.0.0.1] (localhost [IPv6:::1]) by ml01.01.org (Postfix) with ESMTP id B3BE021940D10; Tue, 28 Mar 2017 20:04:02 -0700 (PDT) Received: from mga07.intel.com (mga07.intel.com [134.134.136.100]) (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 D2CEB20084778 for ; Tue, 28 Mar 2017 20:03:57 -0700 (PDT) Received: from orsmga001.jf.intel.com ([10.7.209.18]) by orsmga105.jf.intel.com with ESMTP; 28 Mar 2017 20:03:57 -0700 Received: from ray-dev.ccr.corp.intel.com ([10.239.9.25]) by orsmga001.jf.intel.com with ESMTP; 28 Mar 2017 20:03:56 -0700 X-Original-To: edk2-devel@lists.01.org X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.36,239,1486454400"; d="scan'208";a="1113146618" From: Ruiyu Ni To: edk2-devel@lists.01.org Date: Wed, 29 Mar 2017 11:03:44 +0800 Message-Id: <20170329030346.249872-9-ruiyu.ni@intel.com> X-Mailer: git-send-email 2.9.0.windows.1 In-Reply-To: <20170329030346.249872-1-ruiyu.ni@intel.com> References: <20170329030346.249872-1-ruiyu.ni@intel.com> Subject: [edk2] [PATCH 08/10] UefiCpuPkg/MtrrLib: Use a better algorithm to calculate MTRR 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: Jeff Fan 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" The new algorithm finds out the more optimal MTRR solution for current memory type settings. Compare against the original algorithm, the new one guarantees to find the correct MTRR solution, but doesn't guarantee to find the most optimal MTRR solution. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Ruiyu Ni Cc: Jeff Fan --- UefiCpuPkg/Library/MtrrLib/MtrrLib.c | 1466 +++++++++++++++++++++---------= ---- 1 file changed, 906 insertions(+), 560 deletions(-) diff --git a/UefiCpuPkg/Library/MtrrLib/MtrrLib.c b/UefiCpuPkg/Library/Mtrr= Lib/MtrrLib.c index bcc2df5..34e6ad6 100644 --- a/UefiCpuPkg/Library/MtrrLib/MtrrLib.c +++ b/UefiCpuPkg/Library/MtrrLib/MtrrLib.c @@ -30,6 +30,7 @@ #define OR_SEED 0x0101010101010101ull #define CLEAR_SEED 0xFFFFFFFFFFFFFFFFull =20 +#define MTRR_LIB_ASSERT_ALIGNED(B, L) ASSERT ((B & ~(L - 1)) =3D=3D B); // // Context to save and restore when MTRRs are programmed // @@ -38,6 +39,12 @@ typedef struct { BOOLEAN InterruptState; } MTRR_CONTEXT; =20 +typedef struct { + UINT64 BaseAddress; + UINT64 Length; + MTRR_MEMORY_CACHE_TYPE Type; +} MEMORY_RANGE; + // // This table defines the offset, base and length of the fixed MTRRs // @@ -642,361 +649,309 @@ MtrrGetMemoryAttributeInVariableMtrr ( ); } =20 - /** - Checks overlap between given memory range and MTRRs. - - @param[in] FirmwareVariableMtrrCount The number of variable MTRRs avai= lable - to firmware. - @param[in] Start The start address of memory range. - @param[in] End The end address of memory range. - @param[in] VariableMtrr The array to shadow variable MTRR= s content + Return the least alignment of address. =20 - @retval TRUE Overlap exists. - @retval FALSE No overlap. + @param Address The address to return the alignment. + @param Alignment0 The alignment to return when Address is 0. =20 + @return The least alignment of the Address. **/ -BOOLEAN -CheckMemoryAttributeOverlap ( - IN UINTN FirmwareVariableMtrrCount, - IN PHYSICAL_ADDRESS Start, - IN PHYSICAL_ADDRESS End, - IN VARIABLE_MTRR *VariableMtrr - ) +UINT64 +MtrrLibLeastAlignment ( + UINT64 Address, + UINT64 Alignment0 +) { - UINT32 Index; - - for (Index =3D 0; Index < FirmwareVariableMtrrCount; Index++) { - if ( - VariableMtrr[Index].Valid && - !( - (Start > (VariableMtrr[Index].BaseAddress + - VariableMtrr[Index].Length - 1) - ) || - (End < VariableMtrr[Index].BaseAddress) - ) - ) { - return TRUE; - } + if (Address =3D=3D 0) { + return Alignment0; } =20 - return FALSE; -} - - -/** - Marks a variable MTRR as non-valid. - - @param[in] Index The index of the array VariableMtrr to be inv= alidated - @param[in] VariableMtrr The array to shadow variable MTRRs content - @param[out] UsedMtrr The number of MTRRs which has already been us= ed - -**/ -VOID -InvalidateShadowMtrr ( - IN UINTN Index, - IN VARIABLE_MTRR *VariableMtrr, - OUT UINT32 *UsedMtrr - ) -{ - VariableMtrr[Index].Valid =3D FALSE; - *UsedMtrr =3D *UsedMtrr - 1; + return LShiftU64 (1, (UINTN) LowBitSet64 (Address)); } =20 - /** - Combines memory attributes. + Return the number of required variable MTRRs to positively cover the + specified range. =20 - If overlap exists between given memory range and MTRRs, try to combine t= hem. - - @param[in] FirmwareVariableMtrrCount The number of variable MTRRs - available to firmware. - @param[in] Attributes The memory type to set. - @param[in, out] Base The base address of memory r= ange. - @param[in, out] Length The length of memory range. - @param[in] VariableMtrr The array to shadow variable= MTRRs content - @param[in, out] UsedMtrr The number of MTRRs which ha= s already been used - @param[out] OverwriteExistingMtrr Returns whether an existing = MTRR was used - - @retval EFI_SUCCESS Memory region successfully combined. - @retval EFI_ACCESS_DENIED Memory region cannot be combined. + @param BaseAddress Base address of the range. + @param Length Length of the range. + @param Alignment0 Alignment of 0. =20 + @return The number of the required variable MTRRs. **/ -RETURN_STATUS -CombineMemoryAttribute ( - IN UINT32 FirmwareVariableMtrrCount, - IN UINT64 Attributes, - IN OUT UINT64 *Base, - IN OUT UINT64 *Length, - IN VARIABLE_MTRR *VariableMtrr, - IN OUT UINT32 *UsedMtrr, - OUT BOOLEAN *OverwriteExistingMtrr - ) +UINT32 +MtrrLibGetPositiveMtrrNumber ( + IN UINT64 BaseAddress, + IN UINT64 Length, + IN UINT64 Alignment0 +) { - UINT32 Index; - UINT64 CombineStart; - UINT64 CombineEnd; - UINT64 MtrrEnd; - UINT64 EndAddress; - BOOLEAN CoveredByExistingMtrr; - - *OverwriteExistingMtrr =3D FALSE; - CoveredByExistingMtrr =3D FALSE; - EndAddress =3D *Base +*Length - 1; - - for (Index =3D 0; Index < FirmwareVariableMtrrCount; Index++) { + UINT64 SubLength; + UINT32 MtrrNumber; + BOOLEAN UseLeastAlignment; =20 - MtrrEnd =3D VariableMtrr[Index].BaseAddress + VariableMtrr[Index].Leng= th - 1; - if ( - !VariableMtrr[Index].Valid || - ( - *Base > (MtrrEnd) || - (EndAddress < VariableMtrr[Index].BaseAddress) - ) - ) { - continue; - } + UseLeastAlignment =3D TRUE; =20 - // - // Combine same attribute MTRR range - // - if (Attributes =3D=3D VariableMtrr[Index].Type) { - // - // if the MTRR range contain the request range, set a flag, then con= tinue to - // invalidate any MTRR of the same request range with higher priorit= y cache type. - // - if (VariableMtrr[Index].BaseAddress <=3D *Base && MtrrEnd >=3D EndAd= dress) { - CoveredByExistingMtrr =3D TRUE; - continue; - } - // - // invalid this MTRR, and program the combine range - // - CombineStart =3D - (*Base) < VariableMtrr[Index].BaseAddress ? - (*Base) : - VariableMtrr[Index].BaseAddress; - CombineEnd =3D EndAddress > MtrrEnd ? EndAddress : MtrrEnd; + // + // Calculate the alignment of the base address. + // + for (MtrrNumber =3D 0; Length !=3D 0; MtrrNumber++) { + if (UseLeastAlignment) { + SubLength =3D MtrrLibLeastAlignment (BaseAddress, Alignment0); =20 - // - // Record the MTRR usage status in VariableMtrr array. - // - InvalidateShadowMtrr (Index, VariableMtrr, UsedMtrr); - *Base =3D CombineStart; - *Length =3D CombineEnd - CombineStart + 1; - EndAddress =3D CombineEnd; - *OverwriteExistingMtrr =3D TRUE; - continue; - } else { - // - // The cache type is different, but the range is covered by one MTRR - // - if (VariableMtrr[Index].BaseAddress =3D=3D *Base && MtrrEnd =3D=3D E= ndAddress) { - InvalidateShadowMtrr (Index, VariableMtrr, UsedMtrr); - continue; + if (SubLength > Length) { + // + // Set a flag when remaining length is too small + // so that MtrrLibLeastAlignment() is not called in following loo= ps. + // + UseLeastAlignment =3D FALSE; } - } =20 - if ((Attributes=3D=3D MTRR_CACHE_WRITE_THROUGH && - VariableMtrr[Index].Type =3D=3D MTRR_CACHE_WRITE_BACK) || - (Attributes =3D=3D MTRR_CACHE_WRITE_BACK && - VariableMtrr[Index].Type =3D=3D MTRR_CACHE_WRITE_THROUGH) || - (Attributes =3D=3D MTRR_CACHE_UNCACHEABLE) || - (VariableMtrr[Index].Type =3D=3D MTRR_CACHE_UNCACHEABLE) - ) { - *OverwriteExistingMtrr =3D TRUE; - continue; + if (!UseLeastAlignment) { + SubLength =3D GetPowerOfTwo64 (Length); } - // - // Other type memory overlap is invalid - // - return RETURN_ACCESS_DENIED; - } =20 - if (CoveredByExistingMtrr) { - *Length =3D 0; + BaseAddress +=3D SubLength; + Length -=3D SubLength; } =20 - return RETURN_SUCCESS; + return MtrrNumber; } =20 - /** - Calculates the maximum value which is a power of 2, but less the MemoryL= ength. + Return whether the left MTRR type precedes the right MTRR type. =20 - @param[in] MemoryLength The number to pass in. + The MTRR type precedence rules are: + 1. UC precedes any other type + 2. WT precedes WB =20 - @return The maximum value which is align to power of 2 and less the Memo= ryLength + @param Left The left MTRR type. + @param Right The right MTRR type. =20 + @retval TRUE Left precedes Right. + @retval FALSE Left doesn't precede Right. **/ -UINT64 -Power2MaxMemory ( - IN UINT64 MemoryLength - ) +BOOLEAN +MtrrLibTypeLeftPrecedeRight ( + IN MTRR_MEMORY_CACHE_TYPE Left, + IN MTRR_MEMORY_CACHE_TYPE Right +) { - UINT64 Result; - - if (RShiftU64 (MemoryLength, 32) !=3D 0) { - Result =3D LShiftU64 ( - (UINT64) GetPowerOfTwo32 ( - (UINT32) RShiftU64 (MemoryLength, 32) - ), - 32 - ); - } else { - Result =3D (UINT64) GetPowerOfTwo32 ((UINT32) MemoryLength); - } - - return Result; + return (BOOLEAN) (Left =3D=3D CacheUncacheable || (Left =3D=3D CacheWrit= eThrough && Right =3D=3D CacheWriteBack)); } =20 =20 /** - Determines the MTRR numbers used to program a memory range. + Return whether the type of the specified range can precede the specified= type. + + @param Ranges Memory range array holding memory type settings for all + the memory address. + @param RangeCount Count of memory ranges. + @param Type Type to check precedence. + @param SubBase Base address of the specified range. + @param SubLength Length of the specified range. + + @retval TRUE The type of the specified range can precede the Type. + @retval FALSE The type of the specified range cannot precede the Type. + So the subtraction is not applicable. +**/ +BOOLEAN +MtrrLibSubstractable ( + IN CONST MEMORY_RANGE *Ranges, + IN UINT32 RangeCount, + IN MTRR_MEMORY_CACHE_TYPE Type, + IN UINT64 SubBase, + IN UINT64 SubLength +) +{ + UINT32 Index; + UINT64 Length; + // WT > WB + // UC > * + for (Index =3D 0; Index < RangeCount; Index++) { + if (Ranges[Index].BaseAddress <=3D SubBase && SubBase < Ranges[Index].= BaseAddress + Ranges[Index].Length) { =20 - This function first checks the alignment of the base address. - If the alignment of the base address <=3D Length, cover the memory range - (BaseAddress, alignment) by a MTRR, then BaseAddress +=3D alignment and - Length -=3D alignment. Repeat the step until alignment > Length. + if (Ranges[Index].BaseAddress + Ranges[Index].Length >=3D SubBase + = SubLength) { + return MtrrLibTypeLeftPrecedeRight (Ranges[Index].Type, Type); =20 - Then this function determines which direction of programming the variable - MTRRs for the remaining length will use fewer MTRRs. + } else { + if (!MtrrLibTypeLeftPrecedeRight (Ranges[Index].Type, Type)) { + return FALSE; + } =20 - @param[in] BaseAddress Length of Memory to program MTRR - @param[in] Length Length of Memory to program MTRR - @param[in] MtrrNumber Pointer to the number of necessary MTRRs + Length =3D Ranges[Index].BaseAddress + Ranges[Index].Length - SubB= ase; + SubBase +=3D Length; + SubLength -=3D Length; + } + } + } =20 - @retval TRUE Positive direction is better. - FALSE Negative direction is better. + ASSERT (FALSE); + return FALSE; +} =20 +/** + Return the number of required variable MTRRs to cover the specified rang= e. + + The routine considers subtraction in the both side of the range to find = out + the most optimal solution (which uses the least MTRRs). + + @param Ranges Array holding memory type settings of all memory + address. + @param RangeCount Count of memory ranges. + @param VariableMtrr Array holding allocated variable MTRRs. + @param VariableMtrrCount Count of allocated variable MTRRs. + @param BaseAddress Base address of the specified range. + @param Length Length of the specified range. + @param Type MTRR type of the specified range. + @param Alignment0 Alignment of 0. + @param SubLeft Return the count of left subtraction. + @param SubRight Return the count of right subtraction. + + @return Number of required variable MTRRs. **/ -BOOLEAN -GetMtrrNumberAndDirection ( - IN UINT64 BaseAddress, - IN UINT64 Length, - IN UINTN *MtrrNumber - ) +UINT32 +MtrrLibGetMtrrNumber ( + IN CONST MEMORY_RANGE *Ranges, + IN UINT32 RangeCount, + IN CONST VARIABLE_MTRR *VariableMtrr, + IN UINT32 VariableMtrrCount, + IN UINT64 BaseAddress, + IN UINT64 Length, + IN MTRR_MEMORY_CACHE_TYPE Type, + IN UINT64 Alignment0, + OUT UINT32 *SubLeft, // subtractive from BaseAddress to g= et more aligned address, to save MTRR + OUT UINT32 *SubRight // subtractive from BaseAddress + Le= ngth, to save MTRR +) { - UINT64 TempQword; UINT64 Alignment; - UINT32 Positive; - UINT32 Subtractive; + UINT32 LeastLeftMtrrNumber; + UINT32 MiddleMtrrNumber; + UINT32 LeastRightMtrrNumber; + UINT32 CurrentMtrrNumber; + UINT32 SubtractiveCount; + UINT32 SubtractiveMtrrNumber; + UINT32 LeastSubtractiveMtrrNumber; + UINT64 SubtractiveBaseAddress; + UINT64 SubtractiveLength; + UINT64 BaseAlignment; + UINT32 Index; =20 - *MtrrNumber =3D 0; + *SubLeft =3D 0; + *SubRight =3D 0; + LeastSubtractiveMtrrNumber =3D 0; =20 + // + // Get the optimal left subtraction solution. + // if (BaseAddress !=3D 0) { - do { + // + // Get the MTRR number needed without left subtraction. + // + LeastLeftMtrrNumber =3D MtrrLibGetPositiveMtrrNumber (BaseAddress, Len= gth, Alignment0); + + // + // Left subtraction bit by bit, to find the optimal left subtraction s= olution. + // + for (SubtractiveMtrrNumber =3D 0, SubtractiveCount =3D 1; BaseAddress = !=3D 0; SubtractiveCount++) { + Alignment =3D MtrrLibLeastAlignment (BaseAddress, Alignment0); + // - // Calculate the alignment of the base address. + // Check whether the memory type of [BaseAddress - Alignment, BaseAd= dress) can override Type. + // IA32 Manual defines the following override rules: + // WT > WB + // UC > * (any) // - Alignment =3D LShiftU64 (1, (UINTN)LowBitSet64 (BaseAddress)); - - if (Alignment > Length) { + if (!MtrrLibSubstractable (Ranges, RangeCount, Type, BaseAddress - A= lignment, Alignment)) { break; } =20 - (*MtrrNumber)++; - BaseAddress +=3D Alignment; - Length -=3D Alignment; - } while (TRUE); - - if (Length =3D=3D 0) { - return TRUE; - } - } - - TempQword =3D Length; - Positive =3D 0; - Subtractive =3D 0; + for (Index =3D 0; Index < VariableMtrrCount; Index++) { + if ((VariableMtrr[Index].BaseAddress =3D=3D BaseAddress - Alignmen= t) && + (VariableMtrr[Index].Length =3D=3D Alignment)) { + break; + } + } + if (Index =3D=3D VariableMtrrCount) { + // + // Increment SubtractiveMtrrNumber when [BaseAddress - Alignment, = BaseAddress) is not be planed as a MTRR + // + SubtractiveMtrrNumber++; + } =20 - do { - TempQword -=3D Power2MaxMemory (TempQword); - Positive++; - } while (TempQword !=3D 0); + BaseAddress -=3D Alignment; + Length +=3D Alignment; =20 - TempQword =3D Power2MaxMemory (LShiftU64 (Length, 1)) - Length; - Subtractive++; - do { - TempQword -=3D Power2MaxMemory (TempQword); - Subtractive++; - } while (TempQword !=3D 0); + CurrentMtrrNumber =3D SubtractiveMtrrNumber + MtrrLibGetPositiveMtrr= Number (BaseAddress, Length, Alignment0); + if (CurrentMtrrNumber <=3D LeastLeftMtrrNumber) { + LeastLeftMtrrNumber =3D CurrentMtrrNumber; + LeastSubtractiveMtrrNumber =3D SubtractiveMtrrNumber; + *SubLeft =3D SubtractiveCount; + SubtractiveBaseAddress =3D BaseAddress; + SubtractiveLength =3D Length; + } + } =20 - if (Positive <=3D Subtractive) { - *MtrrNumber +=3D Positive; - return TRUE; - } else { - *MtrrNumber +=3D Subtractive; - return FALSE; + // + // If left subtraction is better, subtract BaseAddress to left, and en= large Length + // + if (*SubLeft !=3D 0) { + BaseAddress =3D SubtractiveBaseAddress; + Length =3D SubtractiveLength; + } } -} - -/** - Invalid variable MTRRs according to the value in the shadow array. - - This function programs MTRRs according to the values specified - in the shadow array. - - @param[in, out] VariableSettings Variable MTRR settings - @param[in] VariableMtrrCount Number of variable MTRRs - @param[in, out] VariableMtrr Shadow of variable MTRR contents - -**/ -VOID -InvalidateMtrr ( - IN OUT MTRR_VARIABLE_SETTINGS *VariableSettings, - IN UINTN VariableMtrrCount, - IN OUT VARIABLE_MTRR *VariableMtrr - ) -{ - UINTN Index; =20 - for (Index =3D 0; Index < VariableMtrrCount; Index++) { - if (!VariableMtrr[Index].Valid && VariableMtrr[Index].Used) { - VariableSettings->Mtrr[Index].Base =3D 0; - VariableSettings->Mtrr[Index].Mask =3D 0; - VariableMtrr[Index].Used =3D FALSE; + // + // Increment BaseAddress greedily until (BaseAddress + Alignment) exceed= s (BaseAddress + Length) + // + MiddleMtrrNumber =3D 0; + while (Length !=3D 0) { + BaseAlignment =3D MtrrLibLeastAlignment (BaseAddress, Alignment0); + if (BaseAlignment > Length) { + break; } + BaseAddress +=3D BaseAlignment; + Length -=3D BaseAlignment; + MiddleMtrrNumber++; } -} =20 =20 -/** - Programs variable MTRRs - - This function programs variable MTRRs - - @param[in, out] VariableSettings Variable MTRR settings. - @param[in] MtrrNumber Index of MTRR to program. - @param[in] BaseAddress Base address of memory region. - @param[in] Length Length of memory region. - @param[in] MemoryCacheType Memory type to set. - @param[in] MtrrValidAddressMask The valid address mask for MTRR + if (Length =3D=3D 0) { + return LeastSubtractiveMtrrNumber + MiddleMtrrNumber; + } =20 -**/ -VOID -ProgramVariableMtrr ( - IN OUT MTRR_VARIABLE_SETTINGS *VariableSettings, - IN UINTN MtrrNumber, - IN PHYSICAL_ADDRESS BaseAddress, - IN UINT64 Length, - IN UINT64 MemoryCacheType, - IN UINT64 MtrrValidAddressMask - ) -{ - UINT64 TempQword; =20 // - // MTRR Physical Base + // Get the optimal right subtraction solution. // - TempQword =3D (BaseAddress & MtrrValidAddressMask) | MemoryCacheType; - VariableSettings->Mtrr[MtrrNumber].Base =3D TempQword; =20 // - // MTRR Physical Mask + // Get the MTRR number needed without right subtraction. // - TempQword =3D ~(Length - 1); - VariableSettings->Mtrr[MtrrNumber].Mask =3D (TempQword & MtrrValidAddres= sMask) | MTRR_LIB_CACHE_MTRR_ENABLED; + LeastRightMtrrNumber =3D MtrrLibGetPositiveMtrrNumber (BaseAddress, Leng= th, Alignment0); + + for (SubtractiveCount =3D 1; Length < BaseAlignment; SubtractiveCount++)= { + Alignment =3D MtrrLibLeastAlignment (BaseAddress + Length, Alignment0); + if (!MtrrLibSubstractable (Ranges, RangeCount, Type, BaseAddress + Len= gth, Alignment)) { + break; + } + + Length +=3D Alignment; + + // + // SubtractiveCount =3D Number of MTRRs used for subtraction + // + CurrentMtrrNumber =3D SubtractiveCount + MtrrLibGetPositiveMtrrNumber = (BaseAddress, Length, Alignment0); + if (CurrentMtrrNumber <=3D LeastRightMtrrNumber) { + LeastRightMtrrNumber =3D CurrentMtrrNumber; + *SubRight =3D SubtractiveCount; + SubtractiveLength =3D Length; + } + } + + return LeastSubtractiveMtrrNumber + MiddleMtrrNumber + LeastRightMtrrNum= ber; } =20 =20 @@ -1448,33 +1403,461 @@ MtrrDebugPrintAllMtrrs ( MtrrDebugPrintAllMtrrsWorker (NULL); } =20 +/** + Update the Ranges array to change the specified range identified by + BaseAddress and Length to Type. + + @param Ranges Array holding memory type settings for all memory reg= ions. + @param Capacity The maximum count of memory ranges the array can hold. + @param Count Return the new memory range count in the array. + @param BaseAddress The base address of the memory range to change type. + @param Length The length of the memory range to change type. + @param Type The new type of the specified memory range. + + @retval RETURN_SUCCESS The type of the specified memory range is + changed successfully. + @retval RETURN_OUT_OF_RESOURCES The new type set causes the count of mem= ory + range exceeds capacity. +**/ +RETURN_STATUS +MtrrLibSetMemoryType ( + IN MEMORY_RANGE *Ranges, + IN UINT32 Capacity, + IN OUT UINT32 *Count, + IN UINT64 BaseAddress, + IN UINT64 Length, + IN MTRR_MEMORY_CACHE_TYPE Type + ) +{ + UINT32 Index; + UINT64 Limit; + UINT64 LengthLeft; + UINT64 LengthRight; + UINT32 StartIndex; + UINT32 EndIndex; + UINT32 DeltaCount; + + Limit =3D BaseAddress + Length; + StartIndex =3D *Count; + EndIndex =3D *Count; + for (Index =3D 0; Index < *Count; Index++) { + if ((StartIndex =3D=3D *Count) && + (Ranges[Index].BaseAddress <=3D BaseAddress) && + (BaseAddress < Ranges[Index].BaseAddress + Ranges[Index].Length)) { + StartIndex =3D Index; + LengthLeft =3D BaseAddress - Ranges[Index].BaseAddress; + } + + if ((EndIndex =3D=3D *Count) && + (Ranges[Index].BaseAddress < Limit) && + (Limit <=3D Ranges[Index].BaseAddress + Ranges[Index].Length)) { + EndIndex =3D Index; + LengthRight =3D Ranges[Index].BaseAddress + Ranges[Index].Length - L= imit; + break; + } + } + + ASSERT (StartIndex !=3D *Count && EndIndex !=3D *Count); + if (StartIndex =3D=3D EndIndex && Ranges[StartIndex].Type =3D=3D Type) { + return RETURN_SUCCESS; + } + + // + // The type change may cause merging with previous range or next range. + // Update the StartIndex, EndIndex, BaseAddress, Length so that following + // logic doesn't need to consider merging. + // + if (StartIndex !=3D 0) { + if (LengthLeft =3D=3D 0 && Ranges[StartIndex - 1].Type =3D=3D Type) { + StartIndex--; + Length +=3D Ranges[StartIndex].Length; + BaseAddress -=3D Ranges[StartIndex].Length; + } + } + if (EndIndex !=3D (*Count) - 1) { + if (LengthRight =3D=3D 0 && Ranges[EndIndex + 1].Type =3D=3D Type) { + EndIndex++; + Length +=3D Ranges[EndIndex].Length; + } + } + + // + // |- 0 -|- 1 -|- 2 -|- 3 -| StartIndex EndIndex DeltaCount Count (Coun= t =3D 4) + // |++++++++++++++++++| 0 3 1=3D3-0-2 3 + // |+++++++| 0 1 -1=3D1-0-2 5 + // |+| 0 0 -2=3D0-0-2 6 + // |+++| 0 0 -1=3D0-0-2+1 5 + // + // + DeltaCount =3D EndIndex - StartIndex - 2; + if (LengthLeft =3D=3D 0) { + DeltaCount++; + } + if (LengthRight =3D=3D 0) { + DeltaCount++; + } + if (*Count - DeltaCount > Capacity) { + return RETURN_OUT_OF_RESOURCES; + } + + // + // Reserve (-DeltaCount) space + // + CopyMem (&Ranges[EndIndex + 1 - DeltaCount], &Ranges[EndIndex + 1], (*Co= unt - EndIndex - 1) * sizeof (Ranges[0])); + *Count -=3D DeltaCount; + + if (LengthLeft !=3D 0) { + Ranges[StartIndex].Length =3D LengthLeft; + StartIndex++; + } + if (LengthRight !=3D 0) { + Ranges[EndIndex - DeltaCount].BaseAddress =3D BaseAddress + Length; + Ranges[EndIndex - DeltaCount].Length =3D LengthRight; + Ranges[EndIndex - DeltaCount].Type =3D Ranges[EndIndex].Type; + } + Ranges[StartIndex].BaseAddress =3D BaseAddress; + Ranges[StartIndex].Length =3D Length; + Ranges[StartIndex].Type =3D Type; + return RETURN_SUCCESS; +} + +/** + Allocate one or more variable MTRR to cover the range identified by + BaseAddress and Length. + + @param Ranges Memory range array holding the memory type + settings for all memory address. + @param RangeCount Count of memory ranges. + @param VariableMtrr Variable MTRR array. + @param VariableMtrrCapacity Capacity of variable MTRR array. + @param VariableMtrrCount Count of variable MTRR. + @param BaseAddress Base address of the memory range. + @param Length Length of the memory range. + @param Type MTRR type of the memory range. + @param Alignment0 Alignment of 0. + + @retval RETURN_SUCCESS Variable MTRRs are allocated successfull= y. + @retval RETURN_OUT_OF_RESOURCES Count of variable MTRRs exceeds capacity. +**/ +RETURN_STATUS +MtrrLibSetMemoryAttributeInVariableMtrr ( + IN CONST MEMORY_RANGE *Ranges, + IN UINT32 RangeCount, + IN OUT VARIABLE_MTRR *VariableMtrr, + IN UINT32 VariableMtrrCapacity, + IN OUT UINT32 *VariableMtrrCount, + IN UINT64 BaseAddress, + IN UINT64 Length, + IN MTRR_MEMORY_CACHE_TYPE Type, + IN UINT64 Alignment0 + ); + +/** + Allocate one or more variable MTRR to cover the range identified by + BaseAddress and Length. + + The routine recursively calls MtrrLibSetMemoryAttributeInVariableMtrr() + to allocate variable MTRRs when the range contains several sub-ranges + with different attributes. + + @param Ranges Memory range array holding the memory type + settings for all memory address. + @param RangeCount Count of memory ranges. + @param VariableMtrr Variable MTRR array. + @param VariableMtrrCapacity Capacity of variable MTRR array. + @param VariableMtrrCount Count of variable MTRR. + @param BaseAddress Base address of the memory range. + @param Length Length of the memory range. + @param Type MTRR type of the range. + If it's CacheInvalid, the memory range may + contains several sub-ranges with different + attributes. + @param Alignment0 Alignment of 0. + + @retval RETURN_SUCCESS Variable MTRRs are allocated successfull= y. + @retval RETURN_OUT_OF_RESOURCES Count of variable MTRRs exceeds capacity. +**/ +RETURN_STATUS +MtrrLibAddVariableMtrr ( + IN CONST MEMORY_RANGE *Ranges, + IN UINT32 RangeCount, + IN OUT VARIABLE_MTRR *VariableMtrr, + IN UINT32 VariableMtrrCapacity, + IN OUT UINT32 *VariableMtrrCount, + IN PHYSICAL_ADDRESS BaseAddress, + IN UINT64 Length, + IN MTRR_MEMORY_CACHE_TYPE Type, + IN UINT64 Alignment0 +) +{ + RETURN_STATUS Status; + UINT32 Index; + UINT64 SubLength; + + MTRR_LIB_ASSERT_ALIGNED (BaseAddress, Length); + if (Type =3D=3D CacheInvalid) { + for (Index =3D 0; Index < RangeCount; Index++) { + if (Ranges[Index].BaseAddress <=3D BaseAddress && BaseAddress < Rang= es[Index].BaseAddress + Ranges[Index].Length) { + + // + // Because the Length may not be aligned to BaseAddress, below cod= e calls + // MtrrLibSetMemoryAttributeInVariableMtrr() instead of itself. + // MtrrLibSetMemoryAttributeInVariableMtrr() splits the range to s= everal + // aligned ranges. + // + if (Ranges[Index].BaseAddress + Ranges[Index].Length >=3D BaseAddr= ess + Length) { + return MtrrLibSetMemoryAttributeInVariableMtrr ( + Ranges, RangeCount, VariableMtrr, VariableMtrrCapacity, Variab= leMtrrCount, + BaseAddress, Length, Ranges[Index].Type, Alignment0 + ); + } else { + SubLength =3D Ranges[Index].BaseAddress + Ranges[Index].Length -= BaseAddress; + Status =3D MtrrLibSetMemoryAttributeInVariableMtrr ( + Ranges, RangeCount, VariableMtrr, VariableMtrrCapacity, Variab= leMtrrCount, + BaseAddress, SubLength, Ranges[Index].Type, Alignment0 + ); + if (RETURN_ERROR (Status)) { + return Status; + } + BaseAddress +=3D SubLength; + Length -=3D SubLength; + } + } + } + + // + // Because memory ranges cover all the memory addresses, it's impossib= le to be here. + // + ASSERT (FALSE); + return RETURN_DEVICE_ERROR; + } else { + for (Index =3D 0; Index < *VariableMtrrCount; Index++) { + if (VariableMtrr[Index].BaseAddress =3D=3D BaseAddress && VariableMt= rr[Index].Length =3D=3D Length) { + ASSERT (VariableMtrr[Index].Type =3D=3D Type); + break; + } + } + if (Index =3D=3D *VariableMtrrCount) { + if (*VariableMtrrCount =3D=3D VariableMtrrCapacity) { + return RETURN_OUT_OF_RESOURCES; + } + VariableMtrr[Index].BaseAddress =3D BaseAddress; + VariableMtrr[Index].Length =3D Length; + VariableMtrr[Index].Type =3D Type; + VariableMtrr[Index].Valid =3D TRUE; + VariableMtrr[Index].Used =3D TRUE; + (*VariableMtrrCount)++; + } + return RETURN_SUCCESS; + } +} + +/** + Allocate one or more variable MTRR to cover the range identified by + BaseAddress and Length. + + @param Ranges Memory range array holding the memory type + settings for all memory address. + @param RangeCount Count of memory ranges. + @param VariableMtrr Variable MTRR array. + @param VariableMtrrCapacity Capacity of variable MTRR array. + @param VariableMtrrCount Count of variable MTRR. + @param BaseAddress Base address of the memory range. + @param Length Length of the memory range. + @param Type MTRR type of the memory range. + @param Alignment0 Alignment of 0. + + @retval RETURN_SUCCESS Variable MTRRs are allocated successfull= y. + @retval RETURN_OUT_OF_RESOURCES Count of variable MTRRs exceeds capacity. +**/ +RETURN_STATUS +MtrrLibSetMemoryAttributeInVariableMtrr ( + IN CONST MEMORY_RANGE *Ranges, + IN UINT32 RangeCount, + IN OUT VARIABLE_MTRR *VariableMtrr, + IN UINT32 VariableMtrrCapacity, + IN OUT UINT32 *VariableMtrrCount, + IN UINT64 BaseAddress, + IN UINT64 Length, + IN MTRR_MEMORY_CACHE_TYPE Type, + IN UINT64 Alignment0 +) +{ + UINT64 Alignment; + UINT32 MtrrNumber; + UINT32 SubtractiveLeft; + UINT32 SubtractiveRight; + BOOLEAN UseLeastAlignment; + + MtrrNumber =3D MtrrLibGetMtrrNumber (Ranges, RangeCount, VariableMtrr, *= VariableMtrrCount, + BaseAddress, Length, Type, Alignment0= , &SubtractiveLeft, &SubtractiveRight); + + if (MtrrNumber + *VariableMtrrCount > VariableMtrrCapacity) { + return RETURN_OUT_OF_RESOURCES; + } + + while (SubtractiveLeft-- !=3D 0) { + Alignment =3D MtrrLibLeastAlignment (BaseAddress, Alignment0); + ASSERT (Alignment <=3D Length); + + MtrrLibAddVariableMtrr (Ranges, RangeCount, VariableMtrr, VariableMtrr= Capacity, VariableMtrrCount, + BaseAddress - Alignment, Alignment, CacheInval= id, Alignment0); + BaseAddress -=3D Alignment; + Length +=3D Alignment; + } + + while (Length !=3D 0) { + Alignment =3D MtrrLibLeastAlignment (BaseAddress, Alignment0); + if (Alignment > Length) { + break; + } + MtrrLibAddVariableMtrr (NULL, 0, VariableMtrr, VariableMtrrCapacity, V= ariableMtrrCount, + BaseAddress, Alignment, Type, Alignment0); + BaseAddress +=3D Alignment; + Length -=3D Alignment; + } + + while (SubtractiveRight-- !=3D 0) { + Alignment =3D MtrrLibLeastAlignment (BaseAddress + Length, Alignment0); + MtrrLibAddVariableMtrr (Ranges, RangeCount, VariableMtrr, VariableMtrr= Capacity, VariableMtrrCount, + BaseAddress + Length, Alignment, CacheInvalid,= Alignment0); + Length +=3D Alignment; + } + + UseLeastAlignment =3D TRUE; + while (Length !=3D 0) { + if (UseLeastAlignment) { + Alignment =3D MtrrLibLeastAlignment (BaseAddress, Alignment0); + if (Alignment > Length) { + UseLeastAlignment =3D FALSE; + } + } + + if (!UseLeastAlignment) { + Alignment =3D GetPowerOfTwo64 (Length); + } + + MtrrLibAddVariableMtrr (NULL, 0, VariableMtrr, VariableMtrrCapacity, V= ariableMtrrCount, + BaseAddress, Alignment, Type, Alignment0); + BaseAddress +=3D Alignment; + Length -=3D Alignment; + } + return RETURN_SUCCESS; +} + +/** + Return an array of memory ranges holding memory type settings for all me= mory + address. + + @param DefaultType The default memory type. + @param TotalLength The total length of the memory. + @param VariableMtrr The variable MTRR array. + @param VariableMtrrCount The count of variable MTRRs. + @param Ranges Return the memory range array holding memory ty= pe + settings for all memory address. + @param RangeCapacity The capacity of memory range array. + @param RangeCount Return the count of memory range. + + @retval RETURN_SUCCESS The memory range array is returned succe= ssfully. + @retval RETURN_OUT_OF_RESOURCES The count of memory ranges exceeds capac= ity. +**/ +RETURN_STATUS +MtrrLibGetMemoryTypes ( + IN MTRR_MEMORY_CACHE_TYPE DefaultType, + IN UINT64 TotalLength, + IN CONST VARIABLE_MTRR *VariableMtrr, + IN UINT32 VariableMtrrCount, + OUT MEMORY_RANGE *Ranges, + IN UINT32 RangeCapacity, + OUT UINT32 *RangeCount +) +{ + RETURN_STATUS Status; + UINTN Index; + + // + // WT > WB + // UC > * + // UC > * (except WB, UC) > WB + // + + // + // 0. Set whole range as DefaultType + // + *RangeCount =3D 1; + Ranges[0].BaseAddress =3D 0; + Ranges[0].Length =3D TotalLength; + Ranges[0].Type =3D DefaultType; + + // + // 1. Set WB + // + for (Index =3D 0; Index < VariableMtrrCount; Index++) { + if (VariableMtrr[Index].Valid && VariableMtrr[Index].Type =3D=3D Cache= WriteBack) { + Status =3D MtrrLibSetMemoryType ( + Ranges, RangeCapacity, RangeCount, + VariableMtrr[Index].BaseAddress, VariableMtrr[Index].Length, (MTRR= _MEMORY_CACHE_TYPE) VariableMtrr[Index].Type + ); + if (RETURN_ERROR (Status)) { + return Status; + } + } + } + + // + // 2. Set other types than WB or UC + // + for (Index =3D 0; Index < VariableMtrrCount; Index++) { + if (VariableMtrr[Index].Valid && VariableMtrr[Index].Type !=3D CacheWr= iteBack && VariableMtrr[Index].Type !=3D CacheUncacheable) { + Status =3D MtrrLibSetMemoryType ( + Ranges, RangeCapacity, RangeCount, + VariableMtrr[Index].BaseAddress, VariableMtrr[Index].Length, (MTRR= _MEMORY_CACHE_TYPE) VariableMtrr[Index].Type + ); + if (RETURN_ERROR (Status)) { + return Status; + } + } + } + + // + // 3. Set UC + // + for (Index =3D 0; Index < VariableMtrrCount; Index++) { + if (VariableMtrr[Index].Valid && VariableMtrr[Index].Type =3D=3D Cache= Uncacheable) { + Status =3D MtrrLibSetMemoryType ( + Ranges, RangeCapacity, RangeCount, + VariableMtrr[Index].BaseAddress, VariableMtrr[Index].Length, (MTRR= _MEMORY_CACHE_TYPE) VariableMtrr[Index].Type + ); + if (RETURN_ERROR (Status)) { + return Status; + } + } + } + return RETURN_SUCCESS; +} =20 /** Worker function attempts to set the attributes for a memory range. =20 - If MtrrSettings is not NULL, set the attributes into the input MTRR + If MtrrSetting is not NULL, set the attributes into the input MTRR settings buffer. - If MtrrSettings is NULL, set the attributes into MTRRs registers. + If MtrrSetting is NULL, set the attributes into MTRRs registers. =20 @param[in, out] MtrrSetting A buffer holding all MTRRs content. @param[in] BaseAddress The physical address that is the start - address of a memory region. - @param[in] Length The size in bytes of the memory regio= n. - @param[in] Attribute The bit mask of attributes to set for= the - memory region. + address of a memory range. + @param[in] Length The size in bytes of the memory range. + @param[in] Type The MTRR type to set for the memory r= ange. =20 @retval RETURN_SUCCESS The attributes were set for the memory - region. + range. @retval RETURN_INVALID_PARAMETER Length is zero. @retval RETURN_UNSUPPORTED The processor does not support one or more bytes of the memory resource range specified by BaseAddress and Length. - @retval RETURN_UNSUPPORTED The bit mask of attributes is not supp= ort - for the memory resource range specified + @retval RETURN_UNSUPPORTED The MTRR type is not support for the + memory resource range specified by BaseAddress and Length. - @retval RETURN_ACCESS_DENIED The attributes for the memory resource - range specified by BaseAddress and Len= gth - cannot be modified. @retval RETURN_OUT_OF_RESOURCES There are not enough system resources = to modify the attributes of the memory resource range. @@ -1485,97 +1868,80 @@ MtrrSetMemoryAttributeWorker ( IN OUT MTRR_SETTINGS *MtrrSetting, IN PHYSICAL_ADDRESS BaseAddress, IN UINT64 Length, - IN MTRR_MEMORY_CACHE_TYPE Attribute + IN MTRR_MEMORY_CACHE_TYPE Type ) { - UINT64 TempQword; RETURN_STATUS Status; - UINT64 MemoryType; - UINT64 Alignment; - BOOLEAN OverLap; - BOOLEAN Positive; - UINT32 MsrNum; - UINTN MtrrNumber; - VARIABLE_MTRR VariableMtrr[MTRR_NUMBER_OF_VARIABLE_MTRR]; - UINT32 UsedMtrr; + UINT32 Index; + UINT32 WorkingIndex; + // + // N variable MTRRs can maximumly separate (2N + 1) Ranges, plus 1 range= for [0, 1M). + // + MEMORY_RANGE Ranges[MTRR_NUMBER_OF_VARIABLE_MTRR * 2 + 2]; + UINT32 RangeCount; UINT64 MtrrValidBitsMask; UINT64 MtrrValidAddressMask; - BOOLEAN OverwriteExistingMtrr; - UINT32 FirmwareVariableMtrrCount; + UINT64 Alignment0; MTRR_CONTEXT MtrrContext; BOOLEAN MtrrContextValid; - BOOLEAN FixedSettingsValid[MTRR_NUMBER_OF_FIXED_MTRR]; - BOOLEAN FixedSettingsModified[MTRR_NUMBER_OF_FIXED_MTR= R]; - MTRR_FIXED_SETTINGS WorkingFixedSettings; - UINT32 VariableMtrrCount; - MTRR_VARIABLE_SETTINGS OriginalVariableSettings; - BOOLEAN ProgramVariableSettings; - MTRR_VARIABLE_SETTINGS WorkingVariableSettings; - UINT32 Index; + + MTRR_MEMORY_CACHE_TYPE DefaultType; + + UINT32 MsrIndex; UINT64 ClearMask; UINT64 OrMask; UINT64 NewValue; - MTRR_VARIABLE_SETTINGS *VariableSettings; + BOOLEAN FixedSettingsValid[MTRR_NUMBER_OF_FIXED_MTRR]; + BOOLEAN FixedSettingsModified[MTRR_NUMBER_OF_FIXED_MTR= R]; + MTRR_FIXED_SETTINGS WorkingFixedSettings; =20 - MtrrContextValid =3D FALSE; - VariableMtrrCount =3D 0; - ZeroMem (&WorkingFixedSettings, sizeof (WorkingFixedSettings)); - for (Index =3D 0; Index < MTRR_NUMBER_OF_FIXED_MTRR; Index++) { - FixedSettingsValid[Index] =3D FALSE; - FixedSettingsModified[Index] =3D FALSE; - } - ProgramVariableSettings =3D FALSE; + UINT32 FirmwareVariableMtrrCount; + MTRR_VARIABLE_SETTINGS *VariableSettings; + MTRR_VARIABLE_SETTINGS OriginalVariableSettings; + UINT32 OriginalVariableMtrrCount; + VARIABLE_MTRR OriginalVariableMtrr[MTRR_NUMBER_OF_VARIABLE_M= TRR]; + UINT32 WorkingVariableMtrrCount; + VARIABLE_MTRR WorkingVariableMtrr[MTRR_NUMBER_OF_VARIABLE_MT= RR]; + BOOLEAN VariableSettingModified[MTRR_NUMBER_OF_VARIABL= E_MTRR]; + UINTN FreeVariableMtrrCount; =20 - if (!IsMtrrSupported ()) { - Status =3D RETURN_UNSUPPORTED; - goto Done; + if (Length =3D=3D 0) { + return RETURN_INVALID_PARAMETER; } =20 MtrrLibInitializeMtrrMask (&MtrrValidBitsMask, &MtrrValidAddressMask); - - TempQword =3D 0; - MemoryType =3D (UINT64)Attribute; - OverwriteExistingMtrr =3D FALSE; - - // - // Check for an invalid parameter - // - if (Length =3D=3D 0) { - Status =3D RETURN_INVALID_PARAMETER; - goto Done; + if (((BaseAddress & ~MtrrValidAddressMask) !=3D 0) || (Length & ~MtrrVal= idAddressMask) !=3D 0) { + return RETURN_UNSUPPORTED; } =20 - if ( - (BaseAddress & ~MtrrValidAddressMask) !=3D 0 || - (Length & ~MtrrValidAddressMask) !=3D 0 - ) { - Status =3D RETURN_UNSUPPORTED; - goto Done; + ZeroMem (&WorkingFixedSettings, sizeof (WorkingFixedSettings)); + for (Index =3D 0; Index < MTRR_NUMBER_OF_FIXED_MTRR; Index++) { + FixedSettingsValid[Index] =3D FALSE; + FixedSettingsModified[Index] =3D FALSE; } =20 // // Check if Fixed MTRR // - Status =3D RETURN_SUCCESS; if (BaseAddress < BASE_1MB) { - MsrNum =3D (UINT32)-1; - while ((BaseAddress < BASE_1MB) && (Length > 0) && Status =3D=3D RETUR= N_SUCCESS) { - Status =3D MtrrLibProgramFixedMtrr (Attribute, &BaseAddress, &Length= , &MsrNum, &ClearMask, &OrMask); + MsrIndex =3D (UINT32)-1; + while ((BaseAddress < BASE_1MB) && (Length !=3D 0)) { + Status =3D MtrrLibProgramFixedMtrr (Type, &BaseAddress, &Length, &Ms= rIndex, &ClearMask, &OrMask); if (RETURN_ERROR (Status)) { - goto Done; + return Status; } if (MtrrSetting !=3D NULL) { - MtrrSetting->Fixed.Mtrr[MsrNum] =3D (MtrrSetting->Fixed.Mtrr[MsrNu= m] & ~ClearMask) | OrMask; - MtrrSetting->MtrrDefType |=3D MTRR_LIB_CACHE_FIXED_MTRR_ENABLED; + MtrrSetting->Fixed.Mtrr[MsrIndex] =3D (MtrrSetting->Fixed.Mtrr[Msr= Index] & ~ClearMask) | OrMask; + ((MSR_IA32_MTRR_DEF_TYPE_REGISTER *) &MtrrSetting->MtrrDefType)->B= its.FE =3D 1; } else { - if (!FixedSettingsValid[MsrNum]) { - WorkingFixedSettings.Mtrr[MsrNum] =3D AsmReadMsr64 (mMtrrLibFixe= dMtrrTable[MsrNum].Msr); - FixedSettingsValid[MsrNum] =3D TRUE; + if (!FixedSettingsValid[MsrIndex]) { + WorkingFixedSettings.Mtrr[MsrIndex] =3D AsmReadMsr64 (mMtrrLibFi= xedMtrrTable[MsrIndex].Msr); + FixedSettingsValid[MsrIndex] =3D TRUE; } - NewValue =3D (WorkingFixedSettings.Mtrr[MsrNum] & ~ClearMask) | Or= Mask; - if (WorkingFixedSettings.Mtrr[MsrNum] !=3D NewValue) { - WorkingFixedSettings.Mtrr[MsrNum] =3D NewValue; - FixedSettingsModified[MsrNum] =3D TRUE; + NewValue =3D (WorkingFixedSettings.Mtrr[MsrIndex] & ~ClearMask) | = OrMask; + if (WorkingFixedSettings.Mtrr[MsrIndex] !=3D NewValue) { + WorkingFixedSettings.Mtrr[MsrIndex] =3D NewValue; + FixedSettingsModified[MsrIndex] =3D TRUE; } } } @@ -1591,198 +1957,178 @@ MtrrSetMemoryAttributeWorker ( } =20 // - // Since memory ranges below 1MB will be overridden by the fixed MTRRs, - // we can set the base to 0 to save variable MTRRs. + // Read the default MTRR type // - if (BaseAddress =3D=3D BASE_1MB) { - BaseAddress =3D 0; - Length +=3D SIZE_1MB; - } + DefaultType =3D MtrrGetDefaultMemoryTypeWorker (MtrrSetting); =20 // - // Read all variable MTRRs + // Read all variable MTRRs and convert to Ranges. // - VariableMtrrCount =3D GetVariableMtrrCountWorker (); - FirmwareVariableMtrrCount =3D GetFirmwareVariableMtrrCountWorker (); - if (MtrrSetting !=3D NULL) { - VariableSettings =3D &MtrrSetting->Variables; + OriginalVariableMtrrCount =3D GetVariableMtrrCountWorker (); + if (MtrrSetting =3D=3D NULL) { + ZeroMem (&OriginalVariableSettings, sizeof (OriginalVariableSettings)); + MtrrGetVariableMtrrWorker (NULL, OriginalVariableMtrrCount, &OriginalV= ariableSettings); + VariableSettings =3D &OriginalVariableSettings; } else { - MtrrGetVariableMtrrWorker (NULL, VariableMtrrCount, &OriginalVariableS= ettings); - CopyMem (&WorkingVariableSettings, &OriginalVariableSettings, sizeof (= WorkingVariableSettings)); - ProgramVariableSettings =3D TRUE; - VariableSettings =3D &WorkingVariableSettings; - } - - // - // Check for overlap - // - UsedMtrr =3D MtrrGetMemoryAttributeInVariableMtrrWorker ( - VariableSettings, - FirmwareVariableMtrrCount, - MtrrValidBitsMask, - MtrrValidAddressMask, - VariableMtrr - ); - OverLap =3D CheckMemoryAttributeOverlap ( - FirmwareVariableMtrrCount, - BaseAddress, - BaseAddress + Length - 1, - VariableMtrr - ); - if (OverLap) { - Status =3D CombineMemoryAttribute ( - FirmwareVariableMtrrCount, - MemoryType, - &BaseAddress, - &Length, - VariableMtrr, - &UsedMtrr, - &OverwriteExistingMtrr - ); - if (RETURN_ERROR (Status)) { - goto Done; - } - - if (Length =3D=3D 0) { - // - // Combined successfully, invalidate the now-unused MTRRs - // - InvalidateMtrr (VariableSettings, VariableMtrrCount, VariableMtrr); - Status =3D RETURN_SUCCESS; - goto Done; - } + VariableSettings =3D &MtrrSetting->Variables; } + MtrrGetMemoryAttributeInVariableMtrrWorker (VariableSettings, OriginalVa= riableMtrrCount, MtrrValidBitsMask, MtrrValidAddressMask, OriginalVariableM= trr); + + Status =3D MtrrLibGetMemoryTypes ( + DefaultType, MtrrValidBitsMask + 1, OriginalVariableMtrr, OriginalVari= ableMtrrCount, + Ranges, 2 * OriginalVariableMtrrCount + 1, &RangeCount + ); + ASSERT (Status =3D=3D RETURN_SUCCESS); + + FirmwareVariableMtrrCount =3D GetFirmwareVariableMtrrCountWorker (); + ASSERT (RangeCount <=3D 2 * FirmwareVariableMtrrCount + 1); =20 // - // The memory type is the same with the type specified by - // MTRR_LIB_IA32_MTRR_DEF_TYPE. + // Force [0, 1M) to UC, so that it doesn't impact left subtraction algor= ithm. // - if ((!OverwriteExistingMtrr) && (Attribute =3D=3D MtrrGetDefaultMemoryTy= peWorker (MtrrSetting))) { - // - // Invalidate the now-unused MTRRs - // - InvalidateMtrr (VariableSettings, VariableMtrrCount, VariableMtrr); - goto Done; + Status =3D MtrrLibSetMemoryType (Ranges, 2 * FirmwareVariableMtrrCount += 2, &RangeCount, 0, SIZE_1MB, CacheUncacheable); + ASSERT (Status =3D=3D RETURN_SUCCESS); + // + // Apply Type to [BaseAddress, BaseAddress + Length) + // + Status =3D MtrrLibSetMemoryType (Ranges, 2 * FirmwareVariableMtrrCount += 2, &RangeCount, BaseAddress, Length, Type); + if (RETURN_ERROR (Status)) { + return Status; } =20 - Positive =3D GetMtrrNumberAndDirection (BaseAddress, Length, &MtrrNumber= ); - - if ((UsedMtrr + MtrrNumber) > FirmwareVariableMtrrCount) { - Status =3D RETURN_OUT_OF_RESOURCES; - goto Done; + Alignment0 =3D LShiftU64 (1, (UINTN) HighBitSet64 (MtrrValidBitsMask)); + WorkingVariableMtrrCount =3D 0; + ZeroMem (&WorkingVariableMtrr, sizeof (WorkingVariableMtrr)); + for (Index =3D 0; Index < RangeCount; Index++) { + if (Ranges[Index].Type !=3D DefaultType) { + // + // Maximum allowed MTRR count is (FirmwareVariableMtrrCount + 1) + // Because potentially the range [0, 1MB) is not merged, but can be = ignored because fixed MTRR covers that + // + Status =3D MtrrLibSetMemoryAttributeInVariableMtrr ( + Ranges, RangeCount, + WorkingVariableMtrr, FirmwareVariableMtrrCount + 1, &WorkingVariab= leMtrrCount, + Ranges[Index].BaseAddress, Ranges[Index].Length, + Ranges[Index].Type, Alignment0 + ); + if (RETURN_ERROR (Status)) { + return Status; + } + } } =20 // - // Invalidate the now-unused MTRRs + // Remove the [0, 1MB) MTRR if it still exists (not merged with other ra= nge) // - InvalidateMtrr (VariableSettings, VariableMtrrCount, VariableMtrr); + if (WorkingVariableMtrr[0].BaseAddress =3D=3D 0 && WorkingVariableMtrr[0= ].Length =3D=3D SIZE_1MB) { + ASSERT (WorkingVariableMtrr[0].Type =3D=3D CacheUncacheable); + WorkingVariableMtrrCount--; + CopyMem (&WorkingVariableMtrr[0], &WorkingVariableMtrr[1], WorkingVari= ableMtrrCount * sizeof (VARIABLE_MTRR)); + } =20 - // - // Find first unused MTRR - // - for (MsrNum =3D 0; MsrNum < VariableMtrrCount; MsrNum++) { - if ((VariableSettings->Mtrr[MsrNum].Mask & MTRR_LIB_CACHE_MTRR_ENABLED= ) =3D=3D 0) { - break; - } + if (WorkingVariableMtrrCount > FirmwareVariableMtrrCount) { + return RETURN_OUT_OF_RESOURCES; } =20 - if (BaseAddress !=3D 0) { - do { - // - // Calculate the alignment of the base address. - // - Alignment =3D LShiftU64 (1, (UINTN)LowBitSet64 (BaseAddress)); + for (Index =3D 0; Index < OriginalVariableMtrrCount; Index++) { + VariableSettingModified[Index] =3D FALSE; =20 - if (Alignment > Length) { + if (!OriginalVariableMtrr[Index].Valid) { + continue; + } + for (WorkingIndex =3D 0; WorkingIndex < WorkingVariableMtrrCount; Work= ingIndex++) { + if (OriginalVariableMtrr[Index].BaseAddress =3D=3D WorkingVariableMt= rr[WorkingIndex].BaseAddress && + OriginalVariableMtrr[Index].Length =3D=3D WorkingVariableMtrr[Wo= rkingIndex].Length && + OriginalVariableMtrr[Index].Type =3D=3D WorkingVariableMtrr[Work= ingIndex].Type) { break; } + } =20 + if (WorkingIndex =3D=3D WorkingVariableMtrrCount) { // - // Find unused MTRR + // Remove the one from OriginalVariableMtrr which is not in WorkingV= ariableMtrr // - for (; MsrNum < VariableMtrrCount; MsrNum++) { - if ((VariableSettings->Mtrr[MsrNum].Mask & MTRR_LIB_CACHE_MTRR_ENA= BLED) =3D=3D 0) { + OriginalVariableMtrr[Index].Valid =3D FALSE; + VariableSettingModified[Index] =3D TRUE; + } else { + // + // Remove the one from WorkingVariableMtrr which is also in Original= VariableMtrr + // + WorkingVariableMtrr[WorkingIndex].Valid =3D FALSE; + } + // + // The above two operations cause that valid MTRR only exists in eithe= r OriginalVariableMtrr or WorkingVariableMtrr. + // + } + + // + // Merge remaining MTRRs from WorkingVariableMtrr to OriginalVariableMtrr + // + for (FreeVariableMtrrCount =3D 0, WorkingIndex =3D 0, Index =3D 0; Index= < OriginalVariableMtrrCount; Index++) { + if (!OriginalVariableMtrr[Index].Valid) { + for (; WorkingIndex < WorkingVariableMtrrCount; WorkingIndex++) { + if (WorkingVariableMtrr[WorkingIndex].Valid) { break; } } - - ProgramVariableMtrr ( - VariableSettings, - MsrNum, - BaseAddress, - Alignment, - MemoryType, - MtrrValidAddressMask - ); - BaseAddress +=3D Alignment; - Length -=3D Alignment; - } while (TRUE); - - if (Length =3D=3D 0) { - goto Done; + if (WorkingIndex =3D=3D WorkingVariableMtrrCount) { + FreeVariableMtrrCount++; + } else { + CopyMem (&OriginalVariableMtrr[Index], &WorkingVariableMtrr[Workin= gIndex], sizeof (VARIABLE_MTRR)); + VariableSettingModified[Index] =3D TRUE; + WorkingIndex++; + } } } + ASSERT (OriginalVariableMtrrCount - FreeVariableMtrrCount <=3D FirmwareV= ariableMtrrCount); =20 - TempQword =3D Length; - - if (!Positive) { - Length =3D Power2MaxMemory (LShiftU64 (TempQword, 1)); + // + // Move MTRRs after the FirmwraeVariableMtrrCount position to beginning + // + WorkingIndex =3D FirmwareVariableMtrrCount; + for (Index =3D 0; Index < FirmwareVariableMtrrCount; Index++) { + if (!OriginalVariableMtrr[Index].Valid) { + // + // Found an empty MTRR in WorkingIndex position + // + for (; WorkingIndex < OriginalVariableMtrrCount; WorkingIndex++) { + if (OriginalVariableMtrr[WorkingIndex].Valid) { + break; + } + } =20 - // - // Find unused MTRR - // - for (; MsrNum < VariableMtrrCount; MsrNum++) { - if ((VariableSettings->Mtrr[MsrNum].Mask & MTRR_LIB_CACHE_MTRR_ENABL= ED) =3D=3D 0) { - break; + if (WorkingIndex !=3D OriginalVariableMtrrCount) { + CopyMem (&OriginalVariableMtrr[Index], &OriginalVariableMtrr[Worki= ngIndex], sizeof (VARIABLE_MTRR)); + VariableSettingModified[Index] =3D TRUE; + VariableSettingModified[WorkingIndex] =3D TRUE; + OriginalVariableMtrr[WorkingIndex].Valid =3D FALSE; } } - - ProgramVariableMtrr ( - VariableSettings, - MsrNum, - BaseAddress, - Length, - MemoryType, - MtrrValidAddressMask - ); - BaseAddress +=3D Length; - TempQword =3D Length - TempQword; - MemoryType =3D MTRR_CACHE_UNCACHEABLE; } =20 - do { - // - // Find unused MTRR - // - for (; MsrNum < VariableMtrrCount; MsrNum++) { - if ((VariableSettings->Mtrr[MsrNum].Mask & MTRR_LIB_CACHE_MTRR_ENABL= ED) =3D=3D 0) { - break; + // + // Convert OriginalVariableMtrr to VariableSettings + // NOTE: MTRR from FirmwareVariableMtrr to OriginalVariableMtrr need to = update as well. + // + for (Index =3D 0; Index < OriginalVariableMtrrCount; Index++) { + if (VariableSettingModified[Index]) { + if (OriginalVariableMtrr[Index].Valid) { + VariableSettings->Mtrr[Index].Base =3D (OriginalVariableMtrr[Index= ].BaseAddress & MtrrValidAddressMask) | (UINT8) OriginalVariableMtrr[Index]= .Type; + VariableSettings->Mtrr[Index].Mask =3D (~(OriginalVariableMtrr[Ind= ex].Length - 1)) & MtrrValidAddressMask | BIT11; + } else { + VariableSettings->Mtrr[Index].Base =3D 0; + VariableSettings->Mtrr[Index].Mask =3D 0; } } - - Length =3D Power2MaxMemory (TempQword); - if (!Positive) { - BaseAddress -=3D Length; - } - - ProgramVariableMtrr ( - VariableSettings, - MsrNum, - BaseAddress, - Length, - MemoryType, - MtrrValidAddressMask - ); - - if (Positive) { - BaseAddress +=3D Length; - } - TempQword -=3D Length; - - } while (TempQword > 0); + } =20 Done: + if (MtrrSetting !=3D NULL) { + ((MSR_IA32_MTRR_DEF_TYPE_REGISTER *) &MtrrSetting->MtrrDefType)->Bits.= E =3D 1; + return RETURN_SUCCESS; + } =20 + MtrrContextValid =3D FALSE; // // Write fixed MTRRs that have been modified // @@ -1802,37 +2148,26 @@ Done: // // Write variable MTRRs // - if (ProgramVariableSettings) { - for (Index =3D 0; Index < VariableMtrrCount; Index++) { - if (WorkingVariableSettings.Mtrr[Index].Base !=3D OriginalVariableSe= ttings.Mtrr[Index].Base || - WorkingVariableSettings.Mtrr[Index].Mask !=3D OriginalVariableSe= ttings.Mtrr[Index].Mask ) { - if (!MtrrContextValid) { - MtrrLibPreMtrrChange (&MtrrContext); - MtrrContextValid =3D TRUE; - } - AsmWriteMsr64 ( - MTRR_LIB_IA32_VARIABLE_MTRR_BASE + (Index << 1), - WorkingVariableSettings.Mtrr[Index].Base - ); - AsmWriteMsr64 ( - MTRR_LIB_IA32_VARIABLE_MTRR_BASE + (Index << 1) + 1, - WorkingVariableSettings.Mtrr[Index].Mask - ); + for (Index =3D 0; Index < OriginalVariableMtrrCount; Index++) { + if (VariableSettingModified[Index]) { + if (!MtrrContextValid) { + MtrrLibPreMtrrChange (&MtrrContext); + MtrrContextValid =3D TRUE; } + AsmWriteMsr64 ( + MSR_IA32_MTRR_PHYSBASE0 + (Index << 1), + VariableSettings->Mtrr[Index].Base + ); + AsmWriteMsr64 ( + MSR_IA32_MTRR_PHYSMASK0 + (Index << 1), + VariableSettings->Mtrr[Index].Mask + ); } } if (MtrrContextValid) { MtrrLibPostMtrrChange (&MtrrContext); } =20 - DEBUG((DEBUG_CACHE, " Status =3D %r\n", Status)); - if (!RETURN_ERROR (Status)) { - if (MtrrSetting !=3D NULL) { - MtrrSetting->MtrrDefType |=3D MTRR_LIB_CACHE_MTRR_ENABLED; - } - MtrrDebugPrintAllMtrrsWorker (MtrrSetting); - } - return Status; } =20 @@ -1840,13 +2175,13 @@ Done: This function attempts to set the attributes for a memory range. =20 @param[in] BaseAddress The physical address that is the start - address of a memory region. - @param[in] Length The size in bytes of the memory region. + address of a memory range. + @param[in] Length The size in bytes of the memory range. @param[in] Attributes The bit mask of attributes to set for the - memory region. + memory range. =20 @retval RETURN_SUCCESS The attributes were set for the memory - region. + range. @retval RETURN_INVALID_PARAMETER Length is zero. @retval RETURN_UNSUPPORTED The processor does not support one or more bytes of the memory resource range @@ -1870,13 +2205,20 @@ MtrrSetMemoryAttribute ( IN MTRR_MEMORY_CACHE_TYPE Attribute ) { - DEBUG((DEBUG_CACHE, "MtrrSetMemoryAttribute() %a:%016lx-%016lx\n", mMtrr= MemoryCacheTypeShortName[Attribute], BaseAddress, Length)); - return MtrrSetMemoryAttributeWorker ( - NULL, - BaseAddress, - Length, - Attribute - ); + RETURN_STATUS Status; + + if (!IsMtrrSupported ()) { + return RETURN_UNSUPPORTED; + } + + Status =3D MtrrSetMemoryAttributeWorker (NULL, BaseAddress, Length, Attr= ibute); + DEBUG ((DEBUG_CACHE, "MtrrSetMemoryAttribute() %a: [%016lx, %016lx) - %r= \n", + mMtrrMemoryCacheTypeShortName[Attribute], BaseAddress, BaseAddre= ss + Length, Status)); + + if (!RETURN_ERROR (Status)) { + MtrrDebugPrintAllMtrrsWorker (NULL); + } + return Status; } =20 /** @@ -1884,12 +2226,12 @@ MtrrSetMemoryAttribute ( =20 @param[in, out] MtrrSetting MTRR setting buffer to be set. @param[in] BaseAddress The physical address that is the start add= ress - of a memory region. - @param[in] Length The size in bytes of the memory region. + of a memory range. + @param[in] Length The size in bytes of the memory range. @param[in] Attribute The bit mask of attributes to set for the - memory region. + memory range. =20 - @retval RETURN_SUCCESS The attributes were set for the memory= region. + @retval RETURN_SUCCESS The attributes were set for the memory= range. @retval RETURN_INVALID_PARAMETER Length is zero. @retval RETURN_UNSUPPORTED The processor does not support one or = more bytes of the memory resource range specified by Bas= eAddress and Length. @@ -1910,13 +2252,16 @@ MtrrSetMemoryAttributeInMtrrSettings ( IN MTRR_MEMORY_CACHE_TYPE Attribute ) { - DEBUG((DEBUG_CACHE, "MtrrSetMemoryAttributeMtrrSettings(%p) %a:%016lx-%0= 16lx\n", MtrrSetting, mMtrrMemoryCacheTypeShortName[Attribute], BaseAddress= , Length)); - return MtrrSetMemoryAttributeWorker ( - MtrrSetting, - BaseAddress, - Length, - Attribute - ); + RETURN_STATUS Status; + Status =3D MtrrSetMemoryAttributeWorker (MtrrSetting, BaseAddress, Lengt= h, Attribute); + DEBUG((DEBUG_CACHE, "MtrrSetMemoryAttributeMtrrSettings(%p) %a: [%016lx,= %016lx) - %r\n", + MtrrSetting, mMtrrMemoryCacheTypeShortName[Attribute], BaseAddres= s, BaseAddress + Length, Status)); + + if (!RETURN_ERROR (Status)) { + MtrrDebugPrintAllMtrrsWorker (MtrrSetting); + } + + return Status; } =20 /** @@ -2147,3 +2492,4 @@ IsMtrrSupported ( } return TRUE; } + --=20 2.9.0.windows.1 _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel From nobody Mon May 6 19:41:26 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.zoho.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 1490756655256784.2803992014433; Tue, 28 Mar 2017 20:04:15 -0700 (PDT) Received: from [127.0.0.1] (localhost [IPv6:::1]) by ml01.01.org (Postfix) with ESMTP id ED51F21940D13; Tue, 28 Mar 2017 20:04:02 -0700 (PDT) Received: from mga07.intel.com (mga07.intel.com [134.134.136.100]) (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 A7A8C21940D01 for ; Tue, 28 Mar 2017 20:03:58 -0700 (PDT) Received: from orsmga001.jf.intel.com ([10.7.209.18]) by orsmga105.jf.intel.com with ESMTP; 28 Mar 2017 20:03:58 -0700 Received: from ray-dev.ccr.corp.intel.com ([10.239.9.25]) by orsmga001.jf.intel.com with ESMTP; 28 Mar 2017 20:03:57 -0700 X-Original-To: edk2-devel@lists.01.org X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.36,239,1486454400"; d="scan'208";a="1113146624" From: Ruiyu Ni To: edk2-devel@lists.01.org Date: Wed, 29 Mar 2017 11:03:45 +0800 Message-Id: <20170329030346.249872-10-ruiyu.ni@intel.com> X-Mailer: git-send-email 2.9.0.windows.1 In-Reply-To: <20170329030346.249872-1-ruiyu.ni@intel.com> References: <20170329030346.249872-1-ruiyu.ni@intel.com> Subject: [edk2] [PATCH 09/10] UefiCpuPkg/MtrrLib: Refine MtrrGetMemoryAttributeByAddressWorker 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: Jeff Fan 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" Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Ruiyu Ni Cc: Jeff Fan --- UefiCpuPkg/Library/MtrrLib/MtrrLib.c | 237 ++++++++++++-------------------= ---- 1 file changed, 80 insertions(+), 157 deletions(-) diff --git a/UefiCpuPkg/Library/MtrrLib/MtrrLib.c b/UefiCpuPkg/Library/Mtrr= Lib/MtrrLib.c index 34e6ad6..920cc5f 100644 --- a/UefiCpuPkg/Library/MtrrLib/MtrrLib.c +++ b/UefiCpuPkg/Library/MtrrLib/MtrrLib.c @@ -568,20 +568,19 @@ MtrrLibProgramFixedMtrr ( This function shadows the content of variable MTRRs into an internal array: VariableMtrr. =20 - @param[in] VariableSettings The variable MTRR values to shad= ow - @param[in] FirmwareVariableMtrrCount The number of variable MTRRs ava= ilable to firmware - @param[in] MtrrValidBitsMask The mask for the valid bit of th= e MTRR - @param[in] MtrrValidAddressMask The valid address mask for MTRR - @param[out] VariableMtrr The array to shadow variable MTR= Rs content + @param[in] VariableSettings The variable MTRR values to shadow + @param[in] VariableMtrrCount The number of variable MTRRs + @param[in] MtrrValidBitsMask The mask for the valid bit of the MTRR + @param[in] MtrrValidAddressMask The valid address mask for MTRR + @param[out] VariableMtrr The array to shadow variable MTRRs co= ntent =20 - @return The return value of this parameter indicat= es the - number of MTRRs which has been used. + @return Number of MTRRs which has been used. =20 **/ UINT32 MtrrGetMemoryAttributeInVariableMtrrWorker ( IN MTRR_VARIABLE_SETTINGS *VariableSettings, - IN UINTN FirmwareVariableMtrrCount, + IN UINTN VariableMtrrCount, IN UINT64 MtrrValidBitsMask, IN UINT64 MtrrValidAddressMask, OUT VARIABLE_MTRR *VariableMtrr @@ -591,7 +590,7 @@ MtrrGetMemoryAttributeInVariableMtrrWorker ( UINT32 UsedMtrr; =20 ZeroMem (VariableMtrr, sizeof (VARIABLE_MTRR) * MTRR_NUMBER_OF_VARIABLE_= MTRR); - for (Index =3D 0, UsedMtrr =3D 0; Index < FirmwareVariableMtrrCount; Ind= ex++) { + for (Index =3D 0, UsedMtrr =3D 0; Index < VariableMtrrCount; Index++) { if ((VariableSettings->Mtrr[Index].Mask & MTRR_LIB_CACHE_MTRR_ENABLED)= !=3D 0) { VariableMtrr[Index].Msr =3D (UINT32)Index; VariableMtrr[Index].BaseAddress =3D (VariableSettings->Mtrr[Index].B= ase & MtrrValidAddressMask); @@ -724,8 +723,10 @@ MtrrLibGetPositiveMtrrNumber ( Return whether the left MTRR type precedes the right MTRR type. =20 The MTRR type precedence rules are: - 1. UC precedes any other type - 2. WT precedes WB + 1. UC precedes any other type + 2. WT precedes WB + For further details, please refer the IA32 Software Developer's Manual, + Volume 3, Section "MTRR Precedences". =20 @param Left The left MTRR type. @param Right The right MTRR type. @@ -954,46 +955,6 @@ MtrrLibGetMtrrNumber ( return LeastSubtractiveMtrrNumber + MiddleMtrrNumber + LeastRightMtrrNum= ber; } =20 - -/** - Converts the Memory attribute value to MTRR_MEMORY_CACHE_TYPE. - - If MtrrSetting is not NULL, gets the default memory attribute from input - MTRR settings buffer. - If MtrrSetting is NULL, gets the default memory attribute from MSR. - - @param[in] MtrrSetting A buffer holding all MTRRs content. - @param[in] MtrrType MTRR memory type - - @return The enum item in MTRR_MEMORY_CACHE_TYPE - -**/ -MTRR_MEMORY_CACHE_TYPE -GetMemoryCacheTypeFromMtrrType ( - IN MTRR_SETTINGS *MtrrSetting, - IN UINT64 MtrrType - ) -{ - switch (MtrrType) { - case MTRR_CACHE_UNCACHEABLE: - return CacheUncacheable; - case MTRR_CACHE_WRITE_COMBINING: - return CacheWriteCombining; - case MTRR_CACHE_WRITE_THROUGH: - return CacheWriteThrough; - case MTRR_CACHE_WRITE_PROTECTED: - return CacheWriteProtected; - case MTRR_CACHE_WRITE_BACK: - return CacheWriteBack; - default: - // - // MtrrType is MTRR_CACHE_INVALID_TYPE, that means - // no MTRR covers the range - // - return MtrrGetDefaultMemoryTypeWorker (MtrrSetting); - } -} - /** Initializes the valid bits mask and valid address mask for MTRRs. =20 @@ -1030,71 +991,34 @@ MtrrLibInitializeMtrrMask ( Determines the real attribute of a memory range. =20 This function is to arbitrate the real attribute of the memory when - there are 2 MTRRs covers the same memory range. For further details, + there are 2 MTRRs covers the same memory range. For further details, please refer the IA32 Software Developer's Manual, Volume 3, - Section 10.11.4.1. + Section "MTRR Precedences". =20 @param[in] MtrrType1 The first kind of Memory type @param[in] MtrrType2 The second kind of memory type =20 **/ -UINT64 +MTRR_MEMORY_CACHE_TYPE MtrrLibPrecedence ( - IN UINT64 MtrrType1, - IN UINT64 MtrrType2 + IN MTRR_MEMORY_CACHE_TYPE MtrrType1, + IN MTRR_MEMORY_CACHE_TYPE MtrrType2 ) { - UINT64 MtrrType; - - MtrrType =3D MTRR_CACHE_INVALID_TYPE; - switch (MtrrType1) { - case MTRR_CACHE_UNCACHEABLE: - MtrrType =3D MTRR_CACHE_UNCACHEABLE; - break; - case MTRR_CACHE_WRITE_COMBINING: - if ( - MtrrType2=3D=3DMTRR_CACHE_WRITE_COMBINING || - MtrrType2=3D=3DMTRR_CACHE_UNCACHEABLE - ) { - MtrrType =3D MtrrType2; - } - break; - case MTRR_CACHE_WRITE_THROUGH: - if ( - MtrrType2=3D=3DMTRR_CACHE_WRITE_THROUGH || - MtrrType2=3D=3DMTRR_CACHE_WRITE_BACK - ) { - MtrrType =3D MTRR_CACHE_WRITE_THROUGH; - } else if(MtrrType2=3D=3DMTRR_CACHE_UNCACHEABLE) { - MtrrType =3D MTRR_CACHE_UNCACHEABLE; - } - break; - case MTRR_CACHE_WRITE_PROTECTED: - if (MtrrType2 =3D=3D MTRR_CACHE_WRITE_PROTECTED || - MtrrType2 =3D=3D MTRR_CACHE_UNCACHEABLE) { - MtrrType =3D MtrrType2; - } - break; - case MTRR_CACHE_WRITE_BACK: - if ( - MtrrType2=3D=3D MTRR_CACHE_UNCACHEABLE || - MtrrType2=3D=3DMTRR_CACHE_WRITE_THROUGH || - MtrrType2=3D=3D MTRR_CACHE_WRITE_BACK - ) { - MtrrType =3D MtrrType2; - } - break; - case MTRR_CACHE_INVALID_TYPE: - MtrrType =3D MtrrType2; - break; - default: - break; + if (MtrrType1 =3D=3D MtrrType2) { + return MtrrType1; } =20 - if (MtrrType2 =3D=3D MTRR_CACHE_INVALID_TYPE) { - MtrrType =3D MtrrType1; + ASSERT ( + MtrrLibTypeLeftPrecedeRight (MtrrType1, MtrrType2) || + MtrrLibTypeLeftPrecedeRight (MtrrType2, MtrrType1) + ); + + if (MtrrLibTypeLeftPrecedeRight (MtrrType1, MtrrType2)) { + return MtrrType1; + } else { + return MtrrType2; } - return MtrrType; } =20 /** @@ -1116,29 +1040,27 @@ MtrrGetMemoryAttributeByAddressWorker ( IN PHYSICAL_ADDRESS Address ) { - UINT64 TempQword; - UINTN Index; - UINTN SubIndex; - UINT64 MtrrType; - UINT64 TempMtrrType; - MTRR_MEMORY_CACHE_TYPE CacheType; - VARIABLE_MTRR VariableMtrr[MTRR_NUMBER_OF_VARIABLE_MTRR]; - UINT64 MtrrValidBitsMask; - UINT64 MtrrValidAddressMask; - UINTN VariableMtrrCount; - MTRR_VARIABLE_SETTINGS VariableSettings; + MSR_IA32_MTRR_DEF_TYPE_REGISTER DefType; + UINT64 FixedMtrr; + UINTN Index; + UINTN SubIndex; + MTRR_MEMORY_CACHE_TYPE MtrrType; + VARIABLE_MTRR VariableMtrr[MTRR_NUMBER_OF_VARIABLE_MTR= R]; + UINT64 MtrrValidBitsMask; + UINT64 MtrrValidAddressMask; + UINT32 VariableMtrrCount; + MTRR_VARIABLE_SETTINGS VariableSettings; =20 // // Check if MTRR is enabled, if not, return UC as attribute // if (MtrrSetting =3D=3D NULL) { - TempQword =3D AsmReadMsr64 (MTRR_LIB_IA32_MTRR_DEF_TYPE); + DefType.Uint64 =3D AsmReadMsr64 (MSR_IA32_MTRR_DEF_TYPE); } else { - TempQword =3D MtrrSetting->MtrrDefType; + DefType.Uint64 =3D MtrrSetting->MtrrDefType; } - MtrrType =3D MTRR_CACHE_INVALID_TYPE; =20 - if ((TempQword & MTRR_LIB_CACHE_MTRR_ENABLED) =3D=3D 0) { + if (DefType.Bits.E =3D=3D 0) { return CacheUncacheable; } =20 @@ -1146,65 +1068,66 @@ MtrrGetMemoryAttributeByAddressWorker ( // If address is less than 1M, then try to go through the fixed MTRR // if (Address < BASE_1MB) { - if ((TempQword & MTRR_LIB_CACHE_FIXED_MTRR_ENABLED) !=3D 0) { + if (DefType.Bits.FE !=3D 0) { // // Go through the fixed MTRR // for (Index =3D 0; Index < MTRR_NUMBER_OF_FIXED_MTRR; Index++) { - if (Address >=3D mMtrrLibFixedMtrrTable[Index].BaseAddress && - Address < ( - mMtrrLibFixedMtrrTable[Index].BaseAddress + - (mMtrrLibFixedMtrrTable[Index].Length * 8) - ) - ) { - SubIndex =3D - ((UINTN)Address - mMtrrLibFixedMtrrTable[Index].BaseAddress) / - mMtrrLibFixedMtrrTable[Index].Length; - if (MtrrSetting =3D=3D NULL) { - TempQword =3D AsmReadMsr64 (mMtrrLibFixedMtrrTable[Index].Msr= ); - } else { - TempQword =3D MtrrSetting->Fixed.Mtrr[Index]; - } - MtrrType =3D RShiftU64 (TempQword, SubIndex * 8) & 0xFF; - return GetMemoryCacheTypeFromMtrrType (MtrrSetting, MtrrType); - } + if (Address >=3D mMtrrLibFixedMtrrTable[Index].BaseAddress && + Address < mMtrrLibFixedMtrrTable[Index].BaseAddress + + (mMtrrLibFixedMtrrTable[Index].Length * 8)) { + SubIndex =3D + ((UINTN) Address - mMtrrLibFixedMtrrTable[Index].BaseAddress) / + mMtrrLibFixedMtrrTable[Index].Length; + if (MtrrSetting =3D=3D NULL) { + FixedMtrr =3D AsmReadMsr64 (mMtrrLibFixedMtrrTable[Index].Msr); + } else { + FixedMtrr =3D MtrrSetting->Fixed.Mtrr[Index]; + } + return (MTRR_MEMORY_CACHE_TYPE) (RShiftU64 (FixedMtrr, SubIndex = * 8) & 0xFF); + } } } } - MtrrLibInitializeMtrrMask(&MtrrValidBitsMask, &MtrrValidAddressMask); =20 - MtrrGetVariableMtrrWorker ( - MtrrSetting, - GetVariableMtrrCountWorker (), - &VariableSettings - ); + VariableMtrrCount =3D GetVariableMtrrCountWorker (); + ASSERT (VariableMtrrCount <=3D MTRR_NUMBER_OF_VARIABLE_MTRR); + MtrrGetVariableMtrrWorker (MtrrSetting, VariableMtrrCount, &VariableSett= ings); =20 + MtrrLibInitializeMtrrMask (&MtrrValidBitsMask, &MtrrValidAddressMask); MtrrGetMemoryAttributeInVariableMtrrWorker ( - &VariableSettings, - GetFirmwareVariableMtrrCountWorker (), - MtrrValidBitsMask, - MtrrValidAddressMask, - VariableMtrr - ); + &VariableSettings, + VariableMtrrCount, + MtrrValidBitsMask, + MtrrValidAddressMask, + VariableMtrr + ); =20 // // Go through the variable MTRR // - VariableMtrrCount =3D GetVariableMtrrCountWorker (); - ASSERT (VariableMtrrCount <=3D MTRR_NUMBER_OF_VARIABLE_MTRR); - + MtrrType =3D CacheInvalid; for (Index =3D 0; Index < VariableMtrrCount; Index++) { if (VariableMtrr[Index].Valid) { if (Address >=3D VariableMtrr[Index].BaseAddress && - Address < VariableMtrr[Index].BaseAddress+VariableMtrr[Index].Le= ngth) { - TempMtrrType =3D VariableMtrr[Index].Type; - MtrrType =3D MtrrLibPrecedence (MtrrType, TempMtrrType); + Address < VariableMtrr[Index].BaseAddress + VariableMtrr[Index].= Length) { + if (MtrrType =3D=3D CacheInvalid) { + MtrrType =3D (MTRR_MEMORY_CACHE_TYPE) VariableMtrr[Index].Type; + } else { + MtrrType =3D MtrrLibPrecedence (MtrrType, (MTRR_MEMORY_CACHE_TYP= E) VariableMtrr[Index].Type); + } } } } - CacheType =3D GetMemoryCacheTypeFromMtrrType (MtrrSetting, MtrrType); =20 - return CacheType; + // + // If there is no MTRR which covers the Address, use the default MTRR ty= pe. + // + if (MtrrType =3D=3D CacheInvalid) { + MtrrType =3D (MTRR_MEMORY_CACHE_TYPE) DefType.Bits.Type; + } + + return MtrrType; } =20 =20 --=20 2.9.0.windows.1 _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel From nobody Mon May 6 19:41:26 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.zoho.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 1490756658228588.5920277835194; Tue, 28 Mar 2017 20:04:18 -0700 (PDT) Received: from [127.0.0.1] (localhost [IPv6:::1]) by ml01.01.org (Postfix) with ESMTP id 2A2F221940D15; Tue, 28 Mar 2017 20:04:03 -0700 (PDT) Received: from mga07.intel.com (mga07.intel.com [134.134.136.100]) (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 9070C21940D01 for ; Tue, 28 Mar 2017 20:03:59 -0700 (PDT) Received: from orsmga001.jf.intel.com ([10.7.209.18]) by orsmga105.jf.intel.com with ESMTP; 28 Mar 2017 20:03:59 -0700 Received: from ray-dev.ccr.corp.intel.com ([10.239.9.25]) by orsmga001.jf.intel.com with ESMTP; 28 Mar 2017 20:03:58 -0700 X-Original-To: edk2-devel@lists.01.org X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.36,239,1486454400"; d="scan'208";a="1113146627" From: Ruiyu Ni To: edk2-devel@lists.01.org Date: Wed, 29 Mar 2017 11:03:46 +0800 Message-Id: <20170329030346.249872-11-ruiyu.ni@intel.com> X-Mailer: git-send-email 2.9.0.windows.1 In-Reply-To: <20170329030346.249872-1-ruiyu.ni@intel.com> References: <20170329030346.249872-1-ruiyu.ni@intel.com> Subject: [edk2] [PATCH 10/10] UefiCpuPkg/MtrrLib: All functions use definitions in Msr.h 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: Jeff Fan 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" Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Ruiyu Ni Cc: Jeff Fan --- UefiCpuPkg/Library/MtrrLib/MtrrLib.c | 55 +++++++++++++++++++++-----------= ---- 1 file changed, 33 insertions(+), 22 deletions(-) diff --git a/UefiCpuPkg/Library/MtrrLib/MtrrLib.c b/UefiCpuPkg/Library/Mtrr= Lib/MtrrLib.c index 920cc5f..b7af838 100644 --- a/UefiCpuPkg/Library/MtrrLib/MtrrLib.c +++ b/UefiCpuPkg/Library/MtrrLib/MtrrLib.c @@ -50,57 +50,57 @@ typedef struct { // CONST FIXED_MTRR mMtrrLibFixedMtrrTable[] =3D { { - MTRR_LIB_IA32_MTRR_FIX64K_00000, + MSR_IA32_MTRR_FIX64K_00000, 0, SIZE_64KB }, { - MTRR_LIB_IA32_MTRR_FIX16K_80000, + MSR_IA32_MTRR_FIX16K_80000, 0x80000, SIZE_16KB }, { - MTRR_LIB_IA32_MTRR_FIX16K_A0000, + MSR_IA32_MTRR_FIX16K_A0000, 0xA0000, SIZE_16KB }, { - MTRR_LIB_IA32_MTRR_FIX4K_C0000, + MSR_IA32_MTRR_FIX4K_C0000, 0xC0000, SIZE_4KB }, { - MTRR_LIB_IA32_MTRR_FIX4K_C8000, + MSR_IA32_MTRR_FIX4K_C8000, 0xC8000, SIZE_4KB }, { - MTRR_LIB_IA32_MTRR_FIX4K_D0000, + MSR_IA32_MTRR_FIX4K_D0000, 0xD0000, SIZE_4KB }, { - MTRR_LIB_IA32_MTRR_FIX4K_D8000, + MSR_IA32_MTRR_FIX4K_D8000, 0xD8000, SIZE_4KB }, { - MTRR_LIB_IA32_MTRR_FIX4K_E0000, + MSR_IA32_MTRR_FIX4K_E0000, 0xE0000, SIZE_4KB }, { - MTRR_LIB_IA32_MTRR_FIX4K_E8000, + MSR_IA32_MTRR_FIX4K_E8000, 0xE8000, SIZE_4KB }, { - MTRR_LIB_IA32_MTRR_FIX4K_F0000, + MSR_IA32_MTRR_FIX4K_F0000, 0xF0000, SIZE_4KB }, { - MTRR_LIB_IA32_MTRR_FIX4K_F8000, + MSR_IA32_MTRR_FIX4K_F8000, 0xF8000, SIZE_4KB } @@ -214,11 +214,15 @@ MtrrGetDefaultMemoryTypeWorker ( IN MTRR_SETTINGS *MtrrSetting ) { + MSR_IA32_MTRR_DEF_TYPE_REGISTER DefType; + if (MtrrSetting =3D=3D NULL) { - return (MTRR_MEMORY_CACHE_TYPE) (AsmReadMsr64 (MTRR_LIB_IA32_MTRR_DEF_= TYPE) & 0x7); + DefType.Uint64 =3D AsmReadMsr64 (MSR_IA32_MTRR_DEF_TYPE); } else { - return (MTRR_MEMORY_CACHE_TYPE) (MtrrSetting->MtrrDefType & 0x7); + DefType.Uint64 =3D MtrrSetting->MtrrDefType; } + + return (MTRR_MEMORY_CACHE_TYPE) DefType.Bits.Type; } =20 =20 @@ -254,6 +258,7 @@ MtrrLibPreMtrrChange ( OUT MTRR_CONTEXT *MtrrContext ) { + MSR_IA32_MTRR_DEF_TYPE_REGISTER DefType; // // Disable interrupts and save current interrupt state // @@ -278,7 +283,9 @@ MtrrLibPreMtrrChange ( // // Disable MTRRs // - AsmMsrBitFieldWrite64 (MTRR_LIB_IA32_MTRR_DEF_TYPE, 10, 11, 0); + DefType.Uint64 =3D AsmReadMsr64 (MSR_IA32_MTRR_DEF_TYPE); + DefType.Bits.E =3D 0; + AsmWriteMsr64 (MSR_IA32_MTRR_DEF_TYPE, DefType.Uint64); } =20 /** @@ -330,10 +337,14 @@ MtrrLibPostMtrrChange ( IN MTRR_CONTEXT *MtrrContext ) { + MSR_IA32_MTRR_DEF_TYPE_REGISTER DefType; // // Enable Cache MTRR // - AsmMsrBitFieldWrite64 (MTRR_LIB_IA32_MTRR_DEF_TYPE, 10, 11, 3); + DefType.Uint64 =3D AsmReadMsr64 (MSR_IA32_MTRR_DEF_TYPE); + DefType.Bits.E =3D 1; + DefType.Bits.FE =3D 1; + AsmWriteMsr64 (MSR_IA32_MTRR_DEF_TYPE, DefType.Uint64); =20 MtrrLibPostMtrrChangeEnableCache (MtrrContext); } @@ -412,9 +423,9 @@ MtrrGetVariableMtrrWorker ( for (Index =3D 0; Index < VariableMtrrCount; Index++) { if (MtrrSetting =3D=3D NULL) { VariableSettings->Mtrr[Index].Base =3D - AsmReadMsr64 (MTRR_LIB_IA32_VARIABLE_MTRR_BASE + (Index << 1)); + AsmReadMsr64 (MSR_IA32_MTRR_PHYSBASE0 + (Index << 1)); VariableSettings->Mtrr[Index].Mask =3D - AsmReadMsr64 (MTRR_LIB_IA32_VARIABLE_MTRR_BASE + (Index << 1) + 1); + AsmReadMsr64 (MSR_IA32_MTRR_PHYSMASK0 + (Index << 1)); } else { VariableSettings->Mtrr[Index].Base =3D MtrrSetting->Variables.Mtrr[I= ndex].Base; VariableSettings->Mtrr[Index].Mask =3D MtrrSetting->Variables.Mtrr[I= ndex].Mask; @@ -591,7 +602,7 @@ MtrrGetMemoryAttributeInVariableMtrrWorker ( =20 ZeroMem (VariableMtrr, sizeof (VARIABLE_MTRR) * MTRR_NUMBER_OF_VARIABLE_= MTRR); for (Index =3D 0, UsedMtrr =3D 0; Index < VariableMtrrCount; Index++) { - if ((VariableSettings->Mtrr[Index].Mask & MTRR_LIB_CACHE_MTRR_ENABLED)= !=3D 0) { + if (((MSR_IA32_MTRR_PHYSMASK_REGISTER *) &VariableSettings->Mtrr[Index= ].Mask)->Bits.V !=3D 0) { VariableMtrr[Index].Msr =3D (UINT32)Index; VariableMtrr[Index].BaseAddress =3D (VariableSettings->Mtrr[Index].B= ase & MtrrValidAddressMask); VariableMtrr[Index].Length =3D ((~(VariableSettings->Mtrr[Index= ].Mask & MtrrValidAddressMask)) & MtrrValidBitsMask) + 1; @@ -2206,11 +2217,11 @@ MtrrSetVariableMtrrWorker ( =20 for (Index =3D 0; Index < VariableMtrrCount; Index++) { AsmWriteMsr64 ( - MTRR_LIB_IA32_VARIABLE_MTRR_BASE + (Index << 1), + MSR_IA32_MTRR_PHYSBASE0 + (Index << 1), VariableSettings->Mtrr[Index].Base ); AsmWriteMsr64 ( - MTRR_LIB_IA32_VARIABLE_MTRR_BASE + (Index << 1) + 1, + MSR_IA32_MTRR_PHYSMASK0 + (Index << 1), VariableSettings->Mtrr[Index].Mask ); } @@ -2331,7 +2342,7 @@ MtrrGetAllMtrrs ( // // Get MTRR_DEF_TYPE value // - MtrrSetting->MtrrDefType =3D AsmReadMsr64 (MTRR_LIB_IA32_MTRR_DEF_TYPE); + MtrrSetting->MtrrDefType =3D AsmReadMsr64 (MSR_IA32_MTRR_DEF_TYPE); =20 return MtrrSetting; } @@ -2372,7 +2383,7 @@ MtrrSetAllMtrrs ( // // Set MTRR_DEF_TYPE value // - AsmWriteMsr64 (MTRR_LIB_IA32_MTRR_DEF_TYPE, MtrrSetting->MtrrDefType); + AsmWriteMsr64 (MSR_IA32_MTRR_DEF_TYPE, MtrrSetting->MtrrDefType); =20 MtrrLibPostMtrrChangeEnableCache (&MtrrContext); =20 --=20 2.9.0.windows.1 _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel