From mboxrd@z Thu Jan 1 00:00:00 1970 Authentication-Results: mx.groups.io; dkim=missing; spf=pass (domain: intel.com, ip: 134.134.136.65, mailfrom: donald.kuo@intel.com) Received: from mga03.intel.com (mga03.intel.com [134.134.136.65]) by groups.io with SMTP; Wed, 14 Aug 2019 21:37:54 -0700 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by orsmga103.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 14 Aug 2019 21:37:53 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.64,387,1559545200"; d="scan'208";a="205779415" Received: from dkuo18-mobl2.gar.corp.intel.com ([10.5.240.222]) by fmsmga002.fm.intel.com with ESMTP; 14 Aug 2019 21:37:51 -0700 From: "Donald Kuo" To: devel@edk2.groups.io Cc: Ray Ni , Star Zeng , Eric Dong , Amy Chan , Rangasai V Chaganty Subject: [PATCH] UefiCpuPkg: Adding a new TSC library by using CPUID(0x15) TSC leaf Date: Thu, 15 Aug 2019 12:37:48 +0800 Message-Id: <20190815043748.1684-1-donald.kuo@intel.com> X-Mailer: git-send-email 2.14.2.windows.3 REF: https://bugzilla.tianocore.org/show_bug.cgi?id=1909 Cc: Ray Ni Cc: Star Zeng Cc: Eric Dong Cc: Amy Chan Cc: Rangasai V Chaganty Signed-off-by: Donald Kuo --- UefiCpuPkg/Library/CpuTimerLib/BaseCpuTimerLib.c | 41 +++ UefiCpuPkg/Library/CpuTimerLib/BaseCpuTimerLib.inf | 35 +++ UefiCpuPkg/Library/CpuTimerLib/BaseCpuTimerLib.uni | 17 ++ UefiCpuPkg/Library/CpuTimerLib/CpuTimerLib.c | 274 +++++++++++++++++++++ UefiCpuPkg/Library/CpuTimerLib/DxeCpuTimerLib.c | 81 ++++++ UefiCpuPkg/Library/CpuTimerLib/DxeCpuTimerLib.inf | 37 +++ UefiCpuPkg/Library/CpuTimerLib/DxeCpuTimerLib.uni | 17 ++ UefiCpuPkg/Library/CpuTimerLib/PeiCpuTimerLib.c | 58 +++++ UefiCpuPkg/Library/CpuTimerLib/PeiCpuTimerLib.inf | 36 +++ UefiCpuPkg/Library/CpuTimerLib/PeiCpuTimerLib.uni | 17 ++ UefiCpuPkg/UefiCpuPkg.dec | 8 + UefiCpuPkg/UefiCpuPkg.dsc | 3 + UefiCpuPkg/UefiCpuPkg.uni | 10 + 13 files changed, 634 insertions(+) create mode 100644 UefiCpuPkg/Library/CpuTimerLib/BaseCpuTimerLib.c create mode 100644 UefiCpuPkg/Library/CpuTimerLib/BaseCpuTimerLib.inf create mode 100644 UefiCpuPkg/Library/CpuTimerLib/BaseCpuTimerLib.uni create mode 100644 UefiCpuPkg/Library/CpuTimerLib/CpuTimerLib.c create mode 100644 UefiCpuPkg/Library/CpuTimerLib/DxeCpuTimerLib.c create mode 100644 UefiCpuPkg/Library/CpuTimerLib/DxeCpuTimerLib.inf create mode 100644 UefiCpuPkg/Library/CpuTimerLib/DxeCpuTimerLib.uni create mode 100644 UefiCpuPkg/Library/CpuTimerLib/PeiCpuTimerLib.c create mode 100644 UefiCpuPkg/Library/CpuTimerLib/PeiCpuTimerLib.inf create mode 100644 UefiCpuPkg/Library/CpuTimerLib/PeiCpuTimerLib.uni diff --git a/UefiCpuPkg/Library/CpuTimerLib/BaseCpuTimerLib.c b/UefiCpuPkg/Library/CpuTimerLib/BaseCpuTimerLib.c new file mode 100644 index 0000000000..6ddf917bad --- /dev/null +++ b/UefiCpuPkg/Library/CpuTimerLib/BaseCpuTimerLib.c @@ -0,0 +1,41 @@ +/** @file + CPUID Leaf 0x15 for Core Crystal Clock frequency instance as Base Timer Library. + + 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. Frequency in MHz = 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/CpuTimerLib/BaseCpuTimerLib.inf b/UefiCpuPkg/Library/CpuTimerLib/BaseCpuTimerLib.inf new file mode 100644 index 0000000000..fd93adc5f1 --- /dev/null +++ b/UefiCpuPkg/Library/CpuTimerLib/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 = 0x00010005 + BASE_NAME = BaseCpuTimerLib + FILE_GUID = F10B5B91-D15A-496C-B044-B5235721AA08 + MODULE_TYPE = BASE + VERSION_STRING = 1.0 + LIBRARY_CLASS = TimerLib|SEC PEI_CORE PEIM + MODULE_UNI_FILE = BaseCpuTimerLib.uni + +[Sources] + CpuTimerLib.c + BaseCpuTimerLib.c + +[Packages] + MdePkg/MdePkg.dec + UefiCpuPkg/UefiCpuPkg.dec + +[LibraryClasses] + BaseLib + PcdLib + DebugLib + +[Pcd] + gUefiCpuPkgTokenSpaceGuid.PcdCpuCoreCrystalClockFrequency ## CONSUMES diff --git a/UefiCpuPkg/Library/CpuTimerLib/BaseCpuTimerLib.uni b/UefiCpuPkg/Library/CpuTimerLib/BaseCpuTimerLib.uni new file mode 100644 index 0000000000..fcf2b0fbcb --- /dev/null +++ b/UefiCpuPkg/Library/CpuTimerLib/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 timer support using CPUID Leaf 0x15 XTAL frequency." + diff --git a/UefiCpuPkg/Library/CpuTimerLib/CpuTimerLib.c b/UefiCpuPkg/Library/CpuTimerLib/CpuTimerLib.c new file mode 100644 index 0000000000..0b9e9384f5 --- /dev/null +++ b/UefiCpuPkg/Library/CpuTimerLib/CpuTimerLib.c @@ -0,0 +1,274 @@ +/** @file + CPUID Leaf 0x15 for Core Crystal Clock frequency instance of Timer Library. + + Copyright (c) 2019 Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include +#include +#include +#include +#include + +GUID mCpuCrystalFrequencyHobGuid = { 0xe1ec5ad0, 0x8569, 0x46bd, { 0x8d, 0xcd, 0x3b, 0x9f, 0x6f, 0x45, 0x82, 0x7a } }; + +/** + 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. Frequency in MHz = 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 + ) +{ + UINT64 TscFrequency; + UINT64 CoreXtalFrequency; + UINT32 RegEax; + UINT32 RegEbx; + UINT32 RegEcx; + + // + // 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 = (ECX, Core Xtal Frequency) * EBX/EAX. + // + AsmCpuid (CPUID_TIME_STAMP_COUNTER, &RegEax, &RegEbx, &RegEcx, NULL); + + // + // If EBX returns 0, the XTAL ratio is not enumerated. + // + ASSERT (RegEbx != 0); + // + // If ECX returns 0, the XTAL frequency is not enumerated. + // + if (RegEcx == 0) { + CoreXtalFrequency = PcdGet64 (PcdCpuCoreCrystalClockFrequency); + } else { + CoreXtalFrequency = (UINT64) RegEcx; + } + + // + // Calculate TSC frequency = (ECX, Core Xtal Frequency) * EBX/EAX + // + TscFrequency = DivU64x32 (MultU64x32 (CoreXtalFrequency, RegEbx) + (UINT64)(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 = 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() <= 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 + ) +{ + + InternalCpuDelay ( + DivU64x32 ( + MultU64x64 ( + MicroSeconds, + InternalGetPerformanceCounterFrequency () + ), + 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 + ) +{ + + InternalCpuDelay ( + DivU64x32 ( + MultU64x64 ( + NanoSeconds, + InternalGetPerformanceCounterFrequency () + ), + 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 starts + with immediately after is it rolls over is returned in StartValue. If + EndValue is not NULL, then the value that the performance counter end with + immediately before it rolls over is returned in EndValue. The 64-bit + frequency of the performance counter in Hz is always returned. If StartValue + is less than EndValue, then the performance counter counts up. If StartValue + is greater than EndValue, then the performance counter counts down. For + example, a 64-bit free running counter that counts up would have a StartValue + 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 before + it rolls over. + + @return The frequency in Hz. + +**/ +UINT64 +EFIAPI +GetPerformanceCounterProperties ( + OUT UINT64 *StartValue, OPTIONAL + OUT UINT64 *EndValue OPTIONAL + ) +{ + if (StartValue != NULL) { + *StartValue = 0; + } + + if (EndValue != NULL) { + *EndValue = 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 counter. + + @return The elapsed time in nanoseconds. + +**/ +UINT64 +EFIAPI +GetTimeInNanoSecond ( + IN UINT64 Ticks + ) +{ + UINT64 Frequency; + UINT64 NanoSeconds; + UINT64 Remainder; + INTN Shift; + + Frequency = GetPerformanceCounterProperties (NULL, NULL); + + // + // Ticks + // Time = --------- x 1,000,000,000 + // Frequency + // + NanoSeconds = MultU64x32 (DivU64x64Remainder (Ticks, Frequency, &Remainder), 1000000000u); + + // + // Ensure (Remainder * 1,000,000,000) will not overflow 64-bit. + // Since 2^29 < 1,000,000,000 = 0x3B9ACA00 < 2^30, Remainder should < 2^(64-30) = 2^34, + // i.e. highest bit set in Remainder should <= 33. + // + Shift = MAX (0, HighBitSet64 (Remainder) - 33); + Remainder = RShiftU64 (Remainder, (UINTN) Shift); + Frequency = RShiftU64 (Frequency, (UINTN) Shift); + NanoSeconds += DivU64x64Remainder (MultU64x32 (Remainder, 1000000000u), Frequency, NULL); + + return NanoSeconds; +} + diff --git a/UefiCpuPkg/Library/CpuTimerLib/DxeCpuTimerLib.c b/UefiCpuPkg/Library/CpuTimerLib/DxeCpuTimerLib.c new file mode 100644 index 0000000000..2d0ef6ab07 --- /dev/null +++ b/UefiCpuPkg/Library/CpuTimerLib/DxeCpuTimerLib.c @@ -0,0 +1,81 @@ +/** @file + CPUID Leaf 0x15 for Core Crystal Clock frequency instance of Timer Library. + + Copyright (c) 2019 Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include +#include +#include + +extern GUID mCpuCrystalFrequencyHobGuid; + +/** + CPUID Leaf 0x15 for Core Crystal Clock Frequency. + + The TSC counting frequency is determined by using CPUID leaf 0x15. Frequency in MHz = 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 + ); + +// +// Cached CPU Crystal counter frequency +// +UINT64 mCpuCrystalCounterFrequency = 0; + + +/** + 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 mCpuCrystalCounterFrequency; +} + +/** + The constructor function is to initialize CpuCrystalCounterFrequency. + + @param ImageHandle The firmware allocated handle for the EFI image. + @param SystemTable A pointer to the EFI System Table. + + @retval EFI_SUCCESS The constructor always returns RETURN_SUCCESS. + +**/ +EFI_STATUS +EFIAPI +DxeCpuTimerLibConstructor ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_HOB_GUID_TYPE *GuidHob; + + // + // Initialize CpuCrystalCounterFrequency + // + GuidHob = GetFirstGuidHob (&mCpuCrystalFrequencyHobGuid); + if (GuidHob != NULL) { + mCpuCrystalCounterFrequency = *(UINT64*)GET_GUID_HOB_DATA (GuidHob); + } else { + mCpuCrystalCounterFrequency = CpuidCoreClockCalculateTscFrequency (); + } + + return EFI_SUCCESS; +} + diff --git a/UefiCpuPkg/Library/CpuTimerLib/DxeCpuTimerLib.inf b/UefiCpuPkg/Library/CpuTimerLib/DxeCpuTimerLib.inf new file mode 100644 index 0000000000..6c83549c87 --- /dev/null +++ b/UefiCpuPkg/Library/CpuTimerLib/DxeCpuTimerLib.inf @@ -0,0 +1,37 @@ +## @file +# DXE 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 = 0x00010005 + BASE_NAME = DxeCpuTimerLib + FILE_GUID = F22CC0DA-E7DB-4E4D-ABE2-A608188233A2 + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + LIBRARY_CLASS = TimerLib|DXE_CORE DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SMM_DRIVER UEFI_APPLICATION UEFI_DRIVER SMM_CORE + CONSTRUCTOR = DxeCpuTimerLibConstructor + MODULE_UNI_FILE = DxeCpuTimerLib.uni + +[Sources] + CpuTimerLib.c + DxeCpuTimerLib.c + +[Packages] + MdePkg/MdePkg.dec + UefiCpuPkg/UefiCpuPkg.dec + +[LibraryClasses] + BaseLib + PcdLib + DebugLib + HobLib + +[Pcd] + gUefiCpuPkgTokenSpaceGuid.PcdCpuCoreCrystalClockFrequency ## CONSUMES diff --git a/UefiCpuPkg/Library/CpuTimerLib/DxeCpuTimerLib.uni b/UefiCpuPkg/Library/CpuTimerLib/DxeCpuTimerLib.uni new file mode 100644 index 0000000000..f55b92abac --- /dev/null +++ b/UefiCpuPkg/Library/CpuTimerLib/DxeCpuTimerLib.uni @@ -0,0 +1,17 @@ +// /** @file +// DXE 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 timer support using CPUID Leaf 0x15 XTAL frequency." + diff --git a/UefiCpuPkg/Library/CpuTimerLib/PeiCpuTimerLib.c b/UefiCpuPkg/Library/CpuTimerLib/PeiCpuTimerLib.c new file mode 100644 index 0000000000..91a7212056 --- /dev/null +++ b/UefiCpuPkg/Library/CpuTimerLib/PeiCpuTimerLib.c @@ -0,0 +1,58 @@ +/** @file + CPUID Leaf 0x15 for Core Crystal Clock frequency instance as PEI Timer Library. + + Copyright (c) 2019 Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include +#include +#include +#include + +extern GUID mCpuCrystalFrequencyHobGuid; + +/** + CPUID Leaf 0x15 for Core Crystal Clock Frequency. + + The TSC counting frequency is determined by using CPUID leaf 0x15. Frequency in MHz = 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 + ) +{ + UINT64 *CpuCrystalCounterFrequency; + EFI_HOB_GUID_TYPE *GuidHob; + + CpuCrystalCounterFrequency = NULL; + GuidHob = GetFirstGuidHob (&mCpuCrystalFrequencyHobGuid); + if (GuidHob == NULL) { + CpuCrystalCounterFrequency = (UINT64*)BuildGuidHob(&mCpuCrystalFrequencyHobGuid, sizeof (*CpuCrystalCounterFrequency)); + ASSERT (CpuCrystalCounterFrequency != NULL); + *CpuCrystalCounterFrequency = CpuidCoreClockCalculateTscFrequency (); + } else { + CpuCrystalCounterFrequency = (UINT64*)GET_GUID_HOB_DATA (GuidHob); + } + + return *CpuCrystalCounterFrequency; +} + diff --git a/UefiCpuPkg/Library/CpuTimerLib/PeiCpuTimerLib.inf b/UefiCpuPkg/Library/CpuTimerLib/PeiCpuTimerLib.inf new file mode 100644 index 0000000000..7af0fc44a6 --- /dev/null +++ b/UefiCpuPkg/Library/CpuTimerLib/PeiCpuTimerLib.inf @@ -0,0 +1,36 @@ +## @file +# PEI 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 = 0x00010005 + BASE_NAME = PeiCpuTimerLib + FILE_GUID = 2B13DE00-1A5F-4DD7-A298-01B08AF1015A + MODULE_TYPE = BASE + VERSION_STRING = 1.0 + LIBRARY_CLASS = TimerLib|PEI_CORE PEIM + MODULE_UNI_FILE = PeiCpuTimerLib.uni + +[Sources] + CpuTimerLib.c + PeiCpuTimerLib.c + +[Packages] + MdePkg/MdePkg.dec + UefiCpuPkg/UefiCpuPkg.dec + +[LibraryClasses] + BaseLib + PcdLib + DebugLib + HobLib + +[Pcd] + gUefiCpuPkgTokenSpaceGuid.PcdCpuCoreCrystalClockFrequency ## CONSUMES diff --git a/UefiCpuPkg/Library/CpuTimerLib/PeiCpuTimerLib.uni b/UefiCpuPkg/Library/CpuTimerLib/PeiCpuTimerLib.uni new file mode 100644 index 0000000000..49beb44908 --- /dev/null +++ b/UefiCpuPkg/Library/CpuTimerLib/PeiCpuTimerLib.uni @@ -0,0 +1,17 @@ +// /** @file +// PEI 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 timer support using CPUID Leaf 0x15 XTAL frequency." + diff --git a/UefiCpuPkg/UefiCpuPkg.dec b/UefiCpuPkg/UefiCpuPkg.dec index 14ddaa8633..86ad61f64b 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|0x0000001D + ## Specifies CPUID Leaf 0x15 Time Stamp Counter and Nominal Core Crystal Clock Frequency. + # TSC Frequency = ECX (core crystal clock frequency) * EBX/EAX. + # Intel Xeon Processor Scalable Family with CPUID signature 06_55H = 25000000 (25MHz) + # 6th and 7th generation Intel Core processors and Intel Xeon W Processor Family = 24000000 (24MHz) + # Intel Atom processors based on Goldmont Microarchitecture with CPUID signature 06_5CH = 19200000 (19.2MHz) + # @Prompt This PCD is the nominal frequency of the core crystal clock in Hz as is CPUID Leaf 0x15:ECX + gUefiCpuPkgTokenSpaceGuid.PcdCpuCoreCrystalClockFrequency|24000000|UINT64|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..e7dfe30eda 100644 --- a/UefiCpuPkg/UefiCpuPkg.dsc +++ b/UefiCpuPkg/UefiCpuPkg.dsc @@ -101,6 +101,9 @@ UefiCpuPkg/CpuIoPei/CpuIoPei.inf UefiCpuPkg/Library/SecPeiDxeTimerLibUefiCpu/SecPeiDxeTimerLibUefiCpu.inf UefiCpuPkg/Application/Cpuid/Cpuid.inf + UefiCpuPkg/Library/CpuTimerLib/BaseCpuTimerLib.inf + UefiCpuPkg/Library/CpuTimerLib/DxeCpuTimerLib.inf + UefiCpuPkg/Library/CpuTimerLib/PeiCpuTimerLib.inf [Components.IA32, Components.X64] UefiCpuPkg/CpuDxe/CpuDxe.inf diff --git a/UefiCpuPkg/UefiCpuPkg.uni b/UefiCpuPkg/UefiCpuPkg.uni index 80af4fc1d2..fbf7680726 100644 --- a/UefiCpuPkg/UefiCpuPkg.uni +++ b/UefiCpuPkg/UefiCpuPkg.uni @@ -242,3 +242,13 @@ #string STR_gUefiCpuPkgTokenSpaceGuid_PcdCpuKnownGoodStackSize_HELP #language en-US "Size of good stack for an exception.\n" "This PCD will only take into effect if PcdCpuStackGuard is enabled.\n" +#string STR_gUefiCpuPkgTokenSpaceGuid_PcdCpuCoreCrystalClockFrequency_PROMPT #language en-US "Specifies CPUID Leaf 0x15 Time Stamp Counter and Nominal Core Crystal Clock Frequency." + +#string STR_gUefiCpuPkgTokenSpaceGuid_PcdCpuCoreCrystalClockFrequency_HELP #language en-US "Specifies CPUID Leaf 0x15 Time Stamp Counter and Nominal Core Crystal Clock Frequency.

\n" + "TSC Frequency = ECX (core crystal clock frequency) * EBX/EAX.

\n" + "This PCD is the nominal frequency of the core crystal clock in Hz as is CPUID Leaf 0x15:ECX.

\n" + "Default value is 24000000 for 6th and 7th generation Intel Core processors and Intel Xeon W Processor Family.
\n" + "25000000 - Intel Xeon Processor Scalable Family with CPUID signature 06_55H(25MHz).
\n" + "24000000 - 6th and 7th generation Intel Core processors and Intel Xeon W Processor Family(24MHz).
\n" + "19200000 - Intel Atom processors based on Goldmont Microarchitecture with CPUID signature 06_5CH(19.2MHz).
\n" + -- 2.14.2.windows.3