public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
* [PATCH] UefiCpuPkg/SecPeiDxeTimerLibUefiCpu: Add GetIntendFsbFrequency()
@ 2017-07-06  7:39 Jeff Fan
  0 siblings, 0 replies; only message in thread
From: Jeff Fan @ 2017-07-06  7:39 UTC (permalink / raw)
  To: edk2-devel; +Cc: Michael D Kinney, Eric Dong, Ruiyu Ni

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



^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2017-07-06  7:37 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2017-07-06  7:39 [PATCH] UefiCpuPkg/SecPeiDxeTimerLibUefiCpu: Add GetIntendFsbFrequency() Jeff Fan

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox