]> git.proxmox.com Git - mirror_edk2.git/commitdiff
Add a new Timer Library instance SecPeiDxeTimerLibUefiCpu into UefiCpuPkg. This libra...
authorrsun3 <rsun3@6f19259b-4bc3-4df7-8a09-765794883524>
Mon, 29 Nov 2010 03:30:38 +0000 (03:30 +0000)
committerrsun3 <rsun3@6f19259b-4bc3-4df7-8a09-765794883524>
Mon, 29 Nov 2010 03:30:38 +0000 (03:30 +0000)
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@11100 6f19259b-4bc3-4df7-8a09-765794883524

MdePkg/Library/SecPeiDxeTimerLibCpu/SecPeiDxeTimerLibCpu.inf
UefiCpuPkg/Library/SecPeiDxeTimerLibUefiCpu/SecPeiDxeTimerLibUefiCpu.inf [new file with mode: 0644]
UefiCpuPkg/Library/SecPeiDxeTimerLibUefiCpu/X86TimerLib.c [new file with mode: 0644]
UefiCpuPkg/UefiCpuPkg.dsc

index 385eec9ed4a7e3ef59bdb040cfeff14fe2cd0f0f..7021e54274617a39cdd0245a4141eb8df25f6c76 100644 (file)
@@ -7,6 +7,9 @@
 #  used by SMM drivers and runtime drivers, ACPI timer is recommended for SMM\r
 #  drivers and runtime drivers.\r
 #\r
+# Note that for IA-32 and x64, this library only supports xAPIC mode. If x2APIC\r
+# support is desired, the SecPeiDxeTimerLibUefiCpu library can be used.\r
+#\r
 # Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.<BR>\r
 #\r
 #  This program and the accompanying materials\r
diff --git a/UefiCpuPkg/Library/SecPeiDxeTimerLibUefiCpu/SecPeiDxeTimerLibUefiCpu.inf b/UefiCpuPkg/Library/SecPeiDxeTimerLibUefiCpu/SecPeiDxeTimerLibUefiCpu.inf
new file mode 100644 (file)
index 0000000..bf76f35
--- /dev/null
@@ -0,0 +1,63 @@
+## @file\r
+# Instance of Timer Library only using CPU resources.\r
+#\r
+# Timer Library that only uses CPU resources to provide calibrated delays\r
+#  on IA-32, x64, and IPF.\r
+# Note: Because CPU Local APIC and ITC could be programmed by OS, it cannot be\r
+#  used by SMM drivers and runtime drivers, ACPI timer is recommended for SMM\r
+#  drivers and runtime drivers.\r
+#\r
+# This library differs with the SecPeiDxeTimerLibCpu library in the MdePkg in\r
+# that it uses the local APIC library so that it supports x2APIC mode.\r
+#\r
+# Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>\r
+#\r
+#  This program and the accompanying materials\r
+#  are licensed and made available under the terms and conditions of the BSD License\r
+#  which accompanies this distribution. The full text of the license may be found at\r
+#  http://opensource.org/licenses/bsd-license.php.\r
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+#\r
+#\r
+##\r
+\r
+[Defines]\r
+  INF_VERSION                    = 0x00010005\r
+  BASE_NAME                      = SecPeiDxeTimerLibUefiCpu\r
+  FILE_GUID                      = 4FFF2014-2086-4ee6-9B58-886D1967861C\r
+  MODULE_TYPE                    = BASE\r
+  VERSION_STRING                 = 1.0\r
+  LIBRARY_CLASS                  = TimerLib|BASE DXE_CORE DXE_DRIVER DXE_SAL_DRIVER PEIM PEI_CORE SEC UEFI_APPLICATION UEFI_DRIVER\r
+\r
+\r
+#\r
+#  VALID_ARCHITECTURES           = IA32 X64 IPF\r
+#\r
+\r
+[Sources.Ia32, Sources.X64]\r
+  X86TimerLib.c\r
+\r
+[Sources.IPF]\r
+  IpfTimerLib.c\r
+\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+  UefiCpuPkg/UefiCpuPkg.dec\r
+\r
+[LibraryClasses]\r
+  BaseLib\r
+\r
+[LibraryClasses.IA32, LibraryClasses.X64]\r
+  PcdLib\r
+  DebugLib\r
+  LocalApicLib\r
+\r
+[LibraryClasses.IPF]\r
+  PalLib\r
+\r
+\r
+[Pcd.IA32, Pcd.X64]\r
+  gEfiMdePkgTokenSpaceGuid.PcdFSBClock  ## CONSUMES\r
+\r
diff --git a/UefiCpuPkg/Library/SecPeiDxeTimerLibUefiCpu/X86TimerLib.c b/UefiCpuPkg/Library/SecPeiDxeTimerLibUefiCpu/X86TimerLib.c
new file mode 100644 (file)
index 0000000..3ca3ca8
--- /dev/null
@@ -0,0 +1,195 @@
+/** @file\r
+  Timer Library functions built upon local APIC on IA32/x64.\r
+\r
+  This library uses the local APIC library so that it supports x2APIC mode.\r
+  \r
+  Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>\r
+  This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php.\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include <Base.h>\r
+#include <Library/TimerLib.h>\r
+#include <Library/BaseLib.h>\r
+#include <Library/PcdLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/LocalApicLib.h>\r
+\r
+/**\r
+  Internal function to return the frequency of the local APIC timer.\r
+\r
+  @return The frequency of the timer in Hz.\r
+\r
+**/\r
+UINT32\r
+EFIAPI\r
+InternalX86GetTimerFrequency (\r
+  VOID\r
+  )\r
+{\r
+  UINTN Divisor;\r
+\r
+  GetApicTimerState (&Divisor, NULL, NULL);\r
+  return PcdGet32(PcdFSBClock) / (UINT32)Divisor;\r
+}\r
+\r
+/**\r
+  Stalls the CPU for at least the given number of ticks.\r
+\r
+  Stalls the CPU for at least the given number of ticks. It's invoked by\r
+  MicroSecondDelay() and NanoSecondDelay().\r
+\r
+  @param  Delay     A period of time to delay in ticks.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+InternalX86Delay (\r
+  IN      UINT32                    Delay\r
+  )\r
+{\r
+  INT32                             Ticks;\r
+  UINT32                            PowerOfTwoCounter;\r
+\r
+  //\r
+  // The target timer count is calculated here\r
+  //\r
+  Ticks = GetApicTimerCurrentCount () - Delay;\r
+\r
+  //\r
+  // Wait until time out\r
+  // Delay > 2^31 could not be handled by this function\r
+  // Timer wrap-arounds are handled correctly by this function\r
+  //\r
+  PowerOfTwoCounter = GetPowerOfTwo32 (GetApicTimerInitCount ());\r
+  while (((UINT32)(GetApicTimerCurrentCount () - Ticks) & PowerOfTwoCounter) == 0) {\r
+    CpuPause ();\r
+  }\r
+}\r
+\r
+/**\r
+  Stalls the CPU for at least the given number of microseconds.\r
+\r
+  Stalls the CPU for the number of microseconds specified by MicroSeconds.\r
+\r
+  @param  MicroSeconds  The minimum number of microseconds to delay.\r
+\r
+  @return The value of MicroSeconds inputted.\r
+\r
+**/\r
+UINTN\r
+EFIAPI\r
+MicroSecondDelay (\r
+  IN      UINTN                     MicroSeconds\r
+  )\r
+{\r
+  InternalX86Delay (\r
+    (UINT32)DivU64x32 (\r
+              MultU64x64 (\r
+                InternalX86GetTimerFrequency (),\r
+                MicroSeconds\r
+                ),\r
+              1000000u\r
+              )\r
+    );\r
+  return MicroSeconds;\r
+}\r
+\r
+/**\r
+  Stalls the CPU for at least the given number of nanoseconds.\r
+\r
+  Stalls the CPU for the number of nanoseconds specified by NanoSeconds.\r
+\r
+  @param  NanoSeconds The minimum number of nanoseconds to delay.\r
+\r
+  @return The value of NanoSeconds inputted.\r
+\r
+**/\r
+UINTN\r
+EFIAPI\r
+NanoSecondDelay (\r
+  IN      UINTN                     NanoSeconds\r
+  )\r
+{\r
+  InternalX86Delay (\r
+    (UINT32)DivU64x32 (\r
+              MultU64x64 (\r
+                InternalX86GetTimerFrequency (),\r
+                NanoSeconds\r
+                ),\r
+              1000000000u\r
+              )\r
+    );\r
+  return NanoSeconds;\r
+}\r
+\r
+/**\r
+  Retrieves the current value of a 64-bit free running performance counter.\r
+\r
+  The counter can either count up by 1 or count down by 1. If the physical\r
+  performance counter counts by a larger increment, then the counter values\r
+  must be translated. The properties of the counter can be retrieved from\r
+  GetPerformanceCounterProperties().\r
+\r
+  @return The current value of the free running performance counter.\r
+\r
+**/\r
+UINT64\r
+EFIAPI\r
+GetPerformanceCounter (\r
+  VOID\r
+  )\r
+{\r
+  return (UINT64)GetApicTimerCurrentCount ();\r
+}\r
+\r
+/**\r
+  Retrieves the 64-bit frequency in Hz and the range of performance counter\r
+  values.\r
+\r
+  If StartValue is not NULL, then the value that the performance counter starts\r
+  with immediately after is it rolls over is returned in StartValue. If\r
+  EndValue is not NULL, then the value that the performance counter end with\r
+  immediately before it rolls over is returned in EndValue. The 64-bit\r
+  frequency of the performance counter in Hz is always returned. If StartValue\r
+  is less than EndValue, then the performance counter counts up. If StartValue\r
+  is greater than EndValue, then the performance counter counts down. For\r
+  example, a 64-bit free running counter that counts up would have a StartValue\r
+  of 0 and an EndValue of 0xFFFFFFFFFFFFFFFF. A 24-bit free running counter\r
+  that counts down would have a StartValue of 0xFFFFFF and an EndValue of 0.\r
+\r
+  @param  StartValue  The value the performance counter starts with when it\r
+                      rolls over.\r
+  @param  EndValue    The value that the performance counter ends with before\r
+                      it rolls over.\r
+\r
+  @return The frequency in Hz.\r
+\r
+**/\r
+UINT64\r
+EFIAPI\r
+GetPerformanceCounterProperties (\r
+  OUT      UINT64                    *StartValue,  OPTIONAL\r
+  OUT      UINT64                    *EndValue     OPTIONAL\r
+  )\r
+{\r
+  if (StartValue != NULL) {\r
+    *StartValue = (UINT64)GetApicTimerInitCount ();\r
+    //\r
+    // make sure StartValue is all 1s from High Bit\r
+    //\r
+    ASSERT ((*StartValue & (*StartValue + 1)) == 0);\r
+  }\r
+\r
+  if (EndValue != NULL) {\r
+    *EndValue = 0;\r
+  }\r
+\r
+  return (UINT64) InternalX86GetTimerFrequency ();\r
+}\r
index c414ae8b295c0211988815ddc5c0358aa7fd12e1..12207f603062c28ff41c33bf6042b7c2eb4e1155 100644 (file)
@@ -68,6 +68,7 @@
 [Components]\r
   UefiCpuPkg/CpuIo2Dxe/CpuIo2Dxe.inf\r
   UefiCpuPkg/CpuIoPei/CpuIoPei.inf\r
+  UefiCpuPkg/Library/SecPeiDxeTimerLibUefiCpu/SecPeiDxeTimerLibUefiCpu.inf\r
 \r
 [Components.IA32, Components.X64]\r
   UefiCpuPkg/CpuDxe/CpuDxe.inf\r