From: Jeff Fan <jeff.fan@intel.com>
To: edk2-devel@lists.01.org
Cc: Michael D Kinney <michael.d.kinney@intel.com>,
Eric Dong <eric.dong@intel.com>, Ruiyu Ni <ruiyu.ni@intel.com>
Subject: [PATCH] UefiCpuPkg/SecPeiDxeTimerLibUefiCpu: Add GetIntendFsbFrequency()
Date: Thu, 6 Jul 2017 15:39:23 +0800 [thread overview]
Message-ID: <20170706073923.12400-1-jeff.fan@intel.com> (raw)
The current implementation gets CPU FSB frequency by PcdFSBClock. However, IA32
SDM defined accurate FSB for some specific processors. Actually, we could try to
get FSB frequency by hardware instead of by PcdFSBClock. If FSB frequency is not
documented by IA32 SDM, we still could get it by PcdFSBClock.
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Eric Dong <eric.dong@intel.com>
Cc: Ruiyu Ni <ruiyu.ni@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Jeff Fan <jeff.fan@intel.com>
---
.../Library/SecPeiDxeTimerLibUefiCpu/X86TimerLib.c | 114 ++++++++++++++++++++-
1 file changed, 111 insertions(+), 3 deletions(-)
diff --git a/UefiCpuPkg/Library/SecPeiDxeTimerLibUefiCpu/X86TimerLib.c b/UefiCpuPkg/Library/SecPeiDxeTimerLibUefiCpu/X86TimerLib.c
index f703d7e..606ad0a 100644
--- a/UefiCpuPkg/Library/SecPeiDxeTimerLibUefiCpu/X86TimerLib.c
+++ b/UefiCpuPkg/Library/SecPeiDxeTimerLibUefiCpu/X86TimerLib.c
@@ -3,7 +3,7 @@
This library uses the local APIC library so that it supports x2APIC mode.
- Copyright (c) 2010 - 2015, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2010 - 2017, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
@@ -20,6 +20,108 @@
#include <Library/PcdLib.h>
#include <Library/DebugLib.h>
#include <Library/LocalApicLib.h>
+#include <Register/Cpuid.h>
+#include <Register/Msr.h>
+
+//
+// The following array is FSB frequencies defined in Pentinum 4 family, Core, Core 2
+// and Atom CPUs, its value unit is HZ.
+//
+GLOBAL_REMOVE_IF_UNREFERENCED
+CONST UINT32 mPentinum4FSBFrequencies[] = {
+ 266666667,
+ 133333333,
+ 200000000,
+ 166666667,
+ 333333333,
+ 100000000,
+ 400000000
+};
+
+//
+// The following array is FSB frequencies defined in SivlerMont, Airmont
+// CPUs, its value unit is HZ.
+//
+GLOBAL_REMOVE_IF_UNREFERENCED
+CONST UINT32 mSivlerMontFSBFrequencies[] = {
+ 83333333,
+ 100000000,
+ 133333333,
+ 116666667,
+ 80000000,
+ 93333333,
+ 90000000,
+ 88888889,
+ 87500000
+};
+
+/**
+ The function to get CPU intended FSB frequency.
+
+ This function reads the type of CPU by CPUID and returns FSB frequecny,
+
+ @retval CPU intended FSB frequency.
+
+**/
+UINT32
+GetIntendFsbFrequency (
+ VOID
+ )
+{
+ CPUID_VERSION_INFO_EAX Eax;
+ CPUID_VERSION_INFO_ECX Ecx;
+ CPUID_VERSION_INFO_EDX Edx;
+ UINT32 DisplayedFamily;
+ UINT32 DisplayedModel;
+ MSR_PENTIUM_4_EBC_FREQUENCY_ID_REGISTER Pentium4Msr;
+ MSR_CORE_FSB_FREQ_REGISTER CoreMsr;
+ MSR_SILVERMONT_FSB_FREQ_REGISTER SilvermontMsr;
+ UINT32 Freq;
+ UINTN FrequencyIndex;
+
+ AsmCpuid (CPUID_VERSION_INFO, &Eax.Uint32, NULL, &Ecx.Uint32, &Edx.Uint32);
+
+ DisplayedFamily = Eax.Bits.FamilyId;
+ if (Eax.Bits.FamilyId == 0x0F) {
+ DisplayedFamily |= (Eax.Bits.ExtendedFamilyId << 4);
+ }
+
+ DisplayedModel = Eax.Bits.Model;
+ if (Eax.Bits.FamilyId == 0x06 || Eax.Bits.FamilyId == 0x0f) {
+ DisplayedModel |= (Eax.Bits.ExtendedModelId << 4);
+ }
+
+ Freq = 0;
+ if (IS_PENTIUM_4_PROCESSOR (DisplayedFamily, DisplayedModel)) {
+ Pentium4Msr.Uint64 = AsmReadMsr64 (MSR_PENTIUM_4_EBC_FREQUENCY_ID);
+ FrequencyIndex = Pentium4Msr.Bits.ScalableBusSpeed;
+ if (FrequencyIndex == 0 && DisplayedModel == 0x02) {
+ //
+ // FrequencyIndex:000B DisplayedModel:2 is 100 MHz
+ //
+ Freq = 100000000;
+ }
+ ASSERT (FrequencyIndex < (sizeof (mPentinum4FSBFrequencies) / sizeof (UINT32)));
+ Freq = mPentinum4FSBFrequencies[FrequencyIndex];
+ } else if (IS_CORE_PROCESSOR (DisplayedFamily, DisplayedModel) ||
+ IS_CORE2_PROCESSOR (DisplayedFamily, DisplayedModel) ||
+ IS_ATOM_PROCESSOR (DisplayedFamily, DisplayedModel)) {
+ CoreMsr.Uint64 = AsmReadMsr64 (MSR_CORE_FSB_FREQ);
+ FrequencyIndex = CoreMsr.Bits.ScalableBusSpeed;
+ ASSERT (FrequencyIndex < (sizeof (mPentinum4FSBFrequencies) / sizeof (UINT32)));
+ Freq = mPentinum4FSBFrequencies[FrequencyIndex];
+ } else if (IS_SILVERMONT_PROCESSOR (DisplayedFamily, DisplayedModel)) {
+ SilvermontMsr.Uint64 = AsmReadMsr64 (MSR_SILVERMONT_FSB_FREQ);
+ FrequencyIndex = SilvermontMsr.Bits.ScalableBusSpeed;
+ ASSERT (FrequencyIndex < (sizeof (mSivlerMontFSBFrequencies) / sizeof (UINT32)));
+ Freq = mSivlerMontFSBFrequencies[FrequencyIndex];
+ }
+
+ //
+ // If processor is not in supported list, then 0 will be return
+ //
+ return Freq;
+}
/**
Internal function to return the frequency of the local APIC timer.
@@ -33,10 +135,16 @@ InternalX86GetTimerFrequency (
VOID
)
{
- UINTN Divisor;
+ UINT32 Freq;
+ UINTN Divisor;
+
+ Freq = GetIntendFsbFrequency ();
+ if (Freq == 0) {
+ Freq = PcdGet32(PcdFSBClock);
+ }
GetApicTimerState (&Divisor, NULL, NULL);
- return PcdGet32(PcdFSBClock) / (UINT32)Divisor;
+ return Freq / (UINT32)Divisor;
}
/**
--
2.9.3.windows.2
reply other threads:[~2017-07-06 7:37 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-list from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20170706073923.12400-1-jeff.fan@intel.com \
--to=devel@edk2.groups.io \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox