From nobody Thu Mar 28 15:21:50 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of groups.io designates 66.175.222.12 as permitted sender) client-ip=66.175.222.12; envelope-from=bounce+27952+45448+1787277+3901457@groups.io; helo=web01.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zoho.com: domain of groups.io designates 66.175.222.12 as permitted sender) smtp.mailfrom=bounce+27952+45448+1787277+3901457@groups.io; dmarc=fail(p=none dis=none) header.from=intel.com ARC-Seal: i=1; a=rsa-sha256; t=1565620980; cv=none; d=zoho.com; s=zohoarc; b=Ymd7kw/hQJolO5piO1BjPqwZ0ikURQQRuA/oQPV2PXaks6mYivvpZIU90WBQHdFhXMeUrZqKpbMcxZaMnj4TppJeOkx78I2Od4dJLyoMA95NtaiWlFCRpPDWlznAPr9E1oL2usHNUym+MeX1tPtpzBw5Y7/0s09kMwQ8o/wFqJ0= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1565620980; h=Cc:Date:From:List-Id:List-Unsubscribe:Message-ID:Reply-To:Sender:Subject:To:ARC-Authentication-Results; bh=OkmCh1678H+MMlakQ7NJyKKmZj6gRrAEwPcZkFb6jxA=; b=DBhIbglgOq640c6lFA+hYfLOd6vlRBBe26ET+s29vmOzmWanwbWr5JldZTPJm5ZGeQ3IvC0NTmeAJTeBcPDtVQGlv3L/590iTp/LbnI+pAJMb8q6HPr8dvNijX8DcGP1614rYv9QmHpWzxkW2oN4ZPq0BgiQznMVS9J+2UWT9mk= ARC-Authentication-Results: i=1; mx.zoho.com; dkim=pass; spf=pass (zoho.com: domain of groups.io designates 66.175.222.12 as permitted sender) smtp.mailfrom=bounce+27952+45448+1787277+3901457@groups.io; dmarc=fail header.from= (p=none dis=none) header.from= Received: from web01.groups.io (web01.groups.io [66.175.222.12]) by mx.zohomail.com with SMTPS id 1565620980534149.4072686662638; Mon, 12 Aug 2019 07:43:00 -0700 (PDT) Return-Path: X-Received: from mga14.intel.com (mga14.intel.com [192.55.52.115]) by groups.io with SMTP; Sun, 11 Aug 2019 22:24:45 -0700 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False X-Received: from orsmga005.jf.intel.com ([10.7.209.41]) by fmsmga103.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 11 Aug 2019 22:24:43 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.64,376,1559545200"; d="scan'208";a="351076290" X-Received: from dkuo18-mobl2.gar.corp.intel.com ([10.5.240.199]) by orsmga005.jf.intel.com with ESMTP; 11 Aug 2019 22:24:43 -0700 From: "Donald Kuo" To: devel@edk2.groups.io Cc: Ray Ni , Star Zeng , Eric Dong Subject: [edk2-devel] [PATCH] UefiCpuPkg: Adding a new TSC library by using CPUID(0x15) TSC leaf Date: Mon, 12 Aug 2019 13:24:41 +0800 Message-Id: <20190812052441.2120-1-donald.kuo@intel.com> Precedence: Bulk List-Unsubscribe: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,donald.kuo@intel.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1565620980; bh=+LT6rAPlPJ602RRv5k/psyXnhPfMS4KEiPXIaJ31DcA=; h=Cc:Date:From:Reply-To:Subject:To; b=vWdEVxgc+rtCsWNKaFwmHSzXxaSO9Cl9buWJohroub8HANqVCjm9qRBAJS/oI5//0R6 eGWZvYYWTc3Wn9PTQPiBQab9MqrMI9CL2BXMPGbXe7o9xiJ3uGzcf+LMwD3E8PqCrukR5 5aFtPG4DmZk1rDriPnsGxTjtPt89s/O4fMs= X-ZohoMail-DKIM: pass (identity @groups.io) Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3D1909 Cc: Ray Ni Cc: Star Zeng Cc: Eric Dong Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Donald Kuo --- .../Library/BaseCpuTimerLib/BaseCpuTimerLib.c | 40 +++ .../Library/BaseCpuTimerLib/BaseCpuTimerLib.inf | 35 +++ .../Library/BaseCpuTimerLib/BaseCpuTimerLib.uni | 17 ++ UefiCpuPkg/Library/BaseCpuTimerLib/CpuTimerLib.c | 290 +++++++++++++++++= ++++ UefiCpuPkg/UefiCpuPkg.dec | 8 + UefiCpuPkg/UefiCpuPkg.dsc | 4 +- 6 files changed, 393 insertions(+), 1 deletion(-) create mode 100644 UefiCpuPkg/Library/BaseCpuTimerLib/BaseCpuTimerLib.c create mode 100644 UefiCpuPkg/Library/BaseCpuTimerLib/BaseCpuTimerLib.inf create mode 100644 UefiCpuPkg/Library/BaseCpuTimerLib/BaseCpuTimerLib.uni create mode 100644 UefiCpuPkg/Library/BaseCpuTimerLib/CpuTimerLib.c diff --git a/UefiCpuPkg/Library/BaseCpuTimerLib/BaseCpuTimerLib.c b/UefiCpu= Pkg/Library/BaseCpuTimerLib/BaseCpuTimerLib.c new file mode 100644 index 0000000000..ccb92a95d3 --- /dev/null +++ b/UefiCpuPkg/Library/BaseCpuTimerLib/BaseCpuTimerLib.c @@ -0,0 +1,40 @@ +/** @file + CPUID Leaf 0x15 for Core Crystal Clock frequency instance of Timer Libra= ry. + + Copyright (c) 2019 Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include +#include + +/** + CPUID Leaf 0x15 for Core Crystal Clock Frequency. + + The TSC counting frequency is determined by using CPUID leaf 0x15. Frequ= ency in MHz =3D Core XTAL frequency * EBX/EAX. + In newer flavors of the CPU, core xtal frequency is returned in ECX or 0= if not supported. + @return The number of TSC counts per second. + +**/ +UINT64 +CpuidCoreClockCalculateTscFrequency ( + VOID + ); + +/** + Internal function to retrieves the 64-bit frequency in Hz. + + Internal function to retrieves the 64-bit frequency in Hz. + + @return The frequency in Hz. + +**/ +UINT64 +InternalGetPerformanceCounterFrequency ( + VOID + ) +{ + return CpuidCoreClockCalculateTscFrequency (); +} diff --git a/UefiCpuPkg/Library/BaseCpuTimerLib/BaseCpuTimerLib.inf b/UefiC= puPkg/Library/BaseCpuTimerLib/BaseCpuTimerLib.inf new file mode 100644 index 0000000000..c31dacd57a --- /dev/null +++ b/UefiCpuPkg/Library/BaseCpuTimerLib/BaseCpuTimerLib.inf @@ -0,0 +1,35 @@ +## @file +# Base CPU Timer Library +# +# Provides basic timer support using CPUID Leaf 0x15 XTAL frequency. The = performance +# counter features are provided by the processors time stamp counter. +# +# Copyright (c) 2019, Intel Corporation. All rights reserved.
+# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION =3D 0x00010005 + BASE_NAME =3D BaseCpuTimerLib + FILE_GUID =3D F10B5B91-D15A-496C-B044-B5235721AA08 + MODULE_TYPE =3D BASE + VERSION_STRING =3D 1.0 + LIBRARY_CLASS =3D TimerLib + MODULE_UNI_FILE =3D BaseCpuTimerLib.uni + +[Sources] + CpuTimerLib.c + BaseCpuTimerLib.c + +[Packages] + MdePkg/MdePkg.dec + UefiCpuPkg/UefiCpuPkg.dec + +[LibraryClasses] + BaseLib + PcdLib + DebugLib + +[Pcd] + gUefiCpuPkgTokenSpaceGuid.PcdCpuCoreCrystalClockFrequency ## CONSUMES \ No newline at end of file diff --git a/UefiCpuPkg/Library/BaseCpuTimerLib/BaseCpuTimerLib.uni b/UefiC= puPkg/Library/BaseCpuTimerLib/BaseCpuTimerLib.uni new file mode 100644 index 0000000000..fcf2b0fbcb --- /dev/null +++ b/UefiCpuPkg/Library/BaseCpuTimerLib/BaseCpuTimerLib.uni @@ -0,0 +1,17 @@ +// /** @file +// Base CPU Timer Library +// +// Provides basic timer support using CPUID Leaf 0x15 XTAL frequency. The= performance +// counter features are provided by the processors time stamp counter. +// +// Copyright (c) 2019, Intel Corporation. All rights reserved.
+// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// **/ + + +#string STR_MODULE_ABSTRACT #language en-US "CPU Timer Library" + +#string STR_MODULE_DESCRIPTION #language en-US "Provides basic ti= mer support using CPUID Leaf 0x15 XTAL frequency." + diff --git a/UefiCpuPkg/Library/BaseCpuTimerLib/CpuTimerLib.c b/UefiCpuPkg/= Library/BaseCpuTimerLib/CpuTimerLib.c new file mode 100644 index 0000000000..5ed01146cf --- /dev/null +++ b/UefiCpuPkg/Library/BaseCpuTimerLib/CpuTimerLib.c @@ -0,0 +1,290 @@ +/** @file + CPUID Leaf 0x15 for Core Crystal Clock frequency instance of Timer Libra= ry. + + Copyright (c) 2019 Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include +#include +#include +#include +#include + +/** + Internal function to retrieves the 64-bit frequency in Hz. + + Internal function to retrieves the 64-bit frequency in Hz. + + @return The frequency in Hz. + +**/ +UINT64 +InternalGetPerformanceCounterFrequency ( + VOID + ); + +/** + CPUID Leaf 0x15 for Core Crystal Clock Frequency. + + The TSC counting frequency is determined by using CPUID leaf 0x15. Frequ= ency in MHz =3D Core XTAL frequency * EBX/EAX. + In newer flavors of the CPU, core xtal frequency is returned in ECX or 0= if not supported. + @return The number of TSC counts per second. + +**/ +UINT64 +CpuidCoreClockCalculateTscFrequency ( + VOID + ) +{ + CPUID_VERSION_INFO_EAX Eax; + UINT64 TscFrequency; + UINT64 CoreXtalFrequency; + UINT32 RegEax; + UINT32 RegEbx; + UINT32 RegEcx; + + // + // Display CPU FAMILY / MODEL / STEPPING ID Info + // + AsmCpuid (CPUID_VERSION_INFO, &Eax.Uint32, NULL, NULL, NULL); + DEBUG ((DEBUG_INFO, "CPUID =3D %X\n", (Eax.Uint32 & 0x0FFF0FFF))); + =20 + // + // Use CPUID leaf 0x15 Time Stamp Counter and Nominal Core Crystal Clock= Information + // EBX returns 0 if not supported. ECX, if non zero, provides Core Xtal = Frequency in hertz. + // TSC frequency =3D (ECX, Core Xtal Frequency) * EBX/EAX. + // + AsmCpuid (CPUID_TIME_STAMP_COUNTER, &RegEax, &RegEbx, &RegEcx, NULL); + DEBUG ((DEBUG_INFO, "Denominator of the TSC ratio =3D %d\n", RegEax)); + DEBUG ((DEBUG_INFO, "Numerator of the TSC ratio =3D %d\n", RegEbx)); + DEBUG ((DEBUG_INFO, "Nominal frequency (hertz) =3D %d\n", RegEcx)); + + // + // If EBX returns 0, the XTAL ratio is not enumerated. + // + if (RegEbx =3D=3D 0) { + DEBUG ((DEBUG_ERROR, "The CPU is not capble for Core Crystal Clock Fre= quency !!\n")); + ASSERT (RegEbx !=3D 0); + } + // + // If ECX returns 0, the XTAL frequency is not enumerated. + // + if (RegEcx =3D=3D 0) { + DEBUG ((DEBUG_ERROR, "The CPU is not capble for Core Crystal Clock Fre= quency !!\n")); + CoreXtalFrequency =3D PcdGet64 (PcdCpuCoreCrystalClockFrequency); + DEBUG ((DEBUG_INFO, "CoreXtalFrequency (hertz) from PCD =3D %d\n", Cor= eXtalFrequency)); + //ASSERT (RegEcx !=3D 0); + } else { + CoreXtalFrequency =3D (UINT64) RegEcx; + } + + // + // Calculate TSC frequency =3D (ECX, Core Xtal Frequency) * EBX/EAX + // + TscFrequency =3D DivU64x32 (MultU64x32 (CoreXtalFrequency, RegEbx) + (UI= NT64)(RegEax >> 1), RegEax); + + return TscFrequency; +} + +/** + Stalls the CPU for at least the given number of ticks. + + Stalls the CPU for at least the given number of ticks. It's invoked by + MicroSecondDelay() and NanoSecondDelay(). + + @param Delay A period of time to delay in ticks. + +**/ +VOID +InternalCpuDelay ( + IN UINT64 Delay + ) +{ + UINT64 Ticks; + + // + // The target timer count is calculated here + // + Ticks =3D AsmReadTsc() + Delay; + + // + // Wait until time out + // Timer wrap-arounds are NOT handled correctly by this function. + // Thus, this function must be called within 10 years of reset since + // Intel guarantees a minimum of 10 years before the TSC wraps. + // + while (AsmReadTsc() <=3D Ticks) { + CpuPause(); + } +} + +/** + Stalls the CPU for at least the given number of microseconds. + + Stalls the CPU for the number of microseconds specified by MicroSeconds. + + @param[in] MicroSeconds The minimum number of microseconds to delay. + + @return MicroSeconds + +**/ +UINTN +EFIAPI +MicroSecondDelay ( + IN UINTN MicroSeconds + ) +{ + DEBUG ((DEBUG_INFO, "MicroSecDelay =3D %d\n", MicroSeconds)); + + InternalCpuDelay ( + DivU64x32 ( + MultU64x64 ( + MicroSeconds, + CpuidCoreClockCalculateTscFrequency () + ), + 1000000u + ) + ); + + return MicroSeconds; +} + +/** + Stalls the CPU for at least the given number of nanoseconds. + + Stalls the CPU for the number of nanoseconds specified by NanoSeconds. + + @param NanoSeconds The minimum number of nanoseconds to delay. + + @return NanoSeconds + +**/ +UINTN +EFIAPI +NanoSecondDelay ( + IN UINTN NanoSeconds + ) +{ + DEBUG ((DEBUG_INFO, "NanoSecDelay =3D %d\n", NanoSeconds)); + + InternalCpuDelay ( + DivU64x32 ( + MultU64x64 ( + NanoSeconds, + CpuidCoreClockCalculateTscFrequency () + ), + 1000000000u + ) + ); + + return NanoSeconds; +} + +/** + Retrieves the current value of a 64-bit free running performance counter. + + Retrieves the current value of a 64-bit free running performance counter= . The + counter can either count up by 1 or count down by 1. If the physical + performance counter counts by a larger increment, then the counter values + must be translated. The properties of the counter can be retrieved from + GetPerformanceCounterProperties(). + + @return The current value of the free running performance counter. + +**/ +UINT64 +EFIAPI +GetPerformanceCounter ( + VOID + ) +{ + return AsmReadTsc (); +} + +/** + Retrieves the 64-bit frequency in Hz and the range of performance counter + values. + + If StartValue is not NULL, then the value that the performance counter s= tarts + with immediately after is it rolls over is returned in StartValue. If + EndValue is not NULL, then the value that the performance counter end wi= th + immediately before it rolls over is returned in EndValue. The 64-bit + frequency of the performance counter in Hz is always returned. If StartV= alue + is less than EndValue, then the performance counter counts up. If StartV= alue + is greater than EndValue, then the performance counter counts down. For + example, a 64-bit free running counter that counts up would have a Start= Value + of 0 and an EndValue of 0xFFFFFFFFFFFFFFFF. A 24-bit free running counter + that counts down would have a StartValue of 0xFFFFFF and an EndValue of = 0. + + @param StartValue The value the performance counter starts with when it + rolls over. + @param EndValue The value that the performance counter ends with bef= ore + it rolls over. + + @return The frequency in Hz. + +**/ +UINT64 +EFIAPI +GetPerformanceCounterProperties ( + OUT UINT64 *StartValue, OPTIONAL + OUT UINT64 *EndValue OPTIONAL + ) +{ + if (StartValue !=3D NULL) { + *StartValue =3D 0; + } + + if (EndValue !=3D NULL) { + *EndValue =3D 0xffffffffffffffffULL; + } + return InternalGetPerformanceCounterFrequency (); +} + +/** + Converts elapsed ticks of performance counter to time in nanoseconds. + + This function converts the elapsed ticks of running performance counter = to + time value in unit of nanoseconds. + + @param Ticks The number of elapsed ticks of running performance cou= nter. + + @return The elapsed time in nanoseconds. + +**/ +UINT64 +EFIAPI +GetTimeInNanoSecond ( + IN UINT64 Ticks + ) +{ + UINT64 Frequency; + UINT64 NanoSeconds; + UINT64 Remainder; + INTN Shift; + + Frequency =3D GetPerformanceCounterProperties (NULL, NULL); + + // + // Ticks + // Time =3D --------- x 1,000,000,000 + // Frequency + // + NanoSeconds =3D MultU64x32 (DivU64x64Remainder (Ticks, Frequency, &Remai= nder), 1000000000u); + + // + // Ensure (Remainder * 1,000,000,000) will not overflow 64-bit. + // Since 2^29 < 1,000,000,000 =3D 0x3B9ACA00 < 2^30, Remainder should < = 2^(64-30) =3D 2^34, + // i.e. highest bit set in Remainder should <=3D 33. + // + Shift =3D MAX (0, HighBitSet64 (Remainder) - 33); + Remainder =3D RShiftU64 (Remainder, (UINTN) Shift); + Frequency =3D RShiftU64 (Frequency, (UINTN) Shift); + NanoSeconds +=3D DivU64x64Remainder (MultU64x32 (Remainder, 1000000000u)= , Frequency, NULL); + + return NanoSeconds; +} + diff --git a/UefiCpuPkg/UefiCpuPkg.dec b/UefiCpuPkg/UefiCpuPkg.dec index 14ddaa8633..a94bd2ea30 100644 --- a/UefiCpuPkg/UefiCpuPkg.dec +++ b/UefiCpuPkg/UefiCpuPkg.dec @@ -211,6 +211,14 @@ # @Prompt If CPU features will be initialized during S3 resume. gUefiCpuPkgTokenSpaceGuid.PcdCpuFeaturesInitOnS3Resume|FALSE|BOOLEAN|0x0= 000001D =20 + ## Specifies CPUID Leaf 0x15 Time Stamp Counter and Nominal Core Crystal= Clock Frequency. + # TSC Frequency =3D ECX (core crystal clock frequency) * EBX/EAX. + # Intel Xeon Processor Scalable Family with CPUID signature 06_55H =3D= 25000000 (25MHz) + # 6th and 7th generation Intel Core processors and Intel Xeon W Proces= sor Family =3D 24000000 (24MHz) + # Intel Atom processors based on Goldmont Microarchitecture with CPUID= signature 06_5CH =3D 19200000 (19.2MHz) + # @Prompt Core Crystal Clock Frequency is for CPUID Leaf 0x15.ECX + gUefiCpuPkgTokenSpaceGuid.PcdCpuCoreCrystalClockFrequency|24000000|UINT6= 4|0x32132113 + [PcdsFixedAtBuild, PcdsPatchableInModule, PcdsDynamic, PcdsDynamicEx] ## Specifies max supported number of Logical Processors. # @Prompt Configure max supported number of Logical Processors diff --git a/UefiCpuPkg/UefiCpuPkg.dsc b/UefiCpuPkg/UefiCpuPkg.dsc index bf690d3978..2d4eb931e1 100644 --- a/UefiCpuPkg/UefiCpuPkg.dsc +++ b/UefiCpuPkg/UefiCpuPkg.dsc @@ -42,7 +42,7 @@ PeimEntryPoint|MdePkg/Library/PeimEntryPoint/PeimEntryPoint.inf PeiServicesLib|MdePkg/Library/PeiServicesLib/PeiServicesLib.inf PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibN= ull.inf - TimerLib|MdePkg/Library/BaseTimerLibNullTemplate/BaseTimerLibNullTemplat= e.inf +# TimerLib|MdePkg/Library/BaseTimerLibNullTemplate/BaseTimerLibNullTempla= te.inf DebugAgentLib|MdeModulePkg/Library/DebugAgentLibNull/DebugAgentLibNull.i= nf LocalApicLib|UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.inf ReportStatusCodeLib|MdePkg/Library/BaseReportStatusCodeLibNull/BaseRepor= tStatusCodeLibNull.inf @@ -56,6 +56,7 @@ PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeC= offGetEntryPointLib.inf PeCoffExtraActionLib|MdePkg/Library/BasePeCoffExtraActionLibNull/BasePeC= offExtraActionLibNull.inf TpmMeasurementLib|MdeModulePkg/Library/TpmMeasurementLibNull/TpmMeasurem= entLibNull.inf + TimerLib|UefiCpuPkg/Library/BaseCpuTimerLib/BaseCpuTimerLib.inf =20 [LibraryClasses.common.SEC] PlatformSecLib|UefiCpuPkg/Library/PlatformSecLibNull/PlatformSecLibNull.= inf @@ -143,6 +144,7 @@ SmmCpuFeaturesLib|UefiCpuPkg/Library/SmmCpuFeaturesLib/SmmCpuFeature= sLibStm.inf } UefiCpuPkg/Universal/Acpi/S3Resume2Pei/S3Resume2Pei.inf + UefiCpuPkg/Library/BaseCpuTimerLib/BaseCpuTimerLib.inf =20 [BuildOptions] *_*_*_CC_FLAGS =3D -D DISABLE_NEW_DEPRECATED_INTERFACES --=20 2.14.2.windows.3 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#45448): https://edk2.groups.io/g/devel/message/45448 Mute This Topic: https://groups.io/mt/32839184/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-