]> git.proxmox.com Git - mirror_edk2.git/blobdiff - Vlv2TbltDevicePkg/PlatformPei/Stall.c
Upload BSD-licensed Vlv2TbltDevicePkg and Vlv2DeviceRefCodePkg to
[mirror_edk2.git] / Vlv2TbltDevicePkg / PlatformPei / Stall.c
diff --git a/Vlv2TbltDevicePkg/PlatformPei/Stall.c b/Vlv2TbltDevicePkg/PlatformPei/Stall.c
new file mode 100644 (file)
index 0000000..8c2ab99
--- /dev/null
@@ -0,0 +1,95 @@
+/** @file\r
+\r
+  Copyright (c) 2004  - 2014, Intel Corporation. All rights reserved.<BR>\r
+                                                                                   \r\r
+  This program and the accompanying materials are licensed and made available under\r\r
+  the terms and conditions of the BSD License that accompanies this distribution.  \r\r
+  The full text of the license may be found at                                     \r\r
+  http://opensource.org/licenses/bsd-license.php.                                  \r\r
+                                                                                   \r\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,            \r\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.    \r\r
+                                                                                   \r\r
+\r
+\r
+Module Name:\r
+\r
+  Stall.c\r
+\r
+Abstract:\r
+\r
+  Produce Stall Ppi.\r
+\r
+--*/\r
+\r
+\r
+#include "CommonHeader.h"\r
+#include "PlatformBaseAddresses.h"\r
+#include "PchRegs.h"\r
+\r
+/**\r
+  Waits for at least the given number of microseconds.\r
+\r
+  @param PeiServices     General purpose services available to every PEIM.\r
+  @param This            PPI instance structure.\r
+  @param Microseconds    Desired length of time to wait.\r
+\r
+  @retval EFI_SUCCESS    If the desired amount of time was passed.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+Stall (\r
+  IN CONST EFI_PEI_SERVICES   **PeiServices,\r
+  IN CONST EFI_PEI_STALL_PPI      *This,\r
+  IN UINTN              Microseconds\r
+  )\r
+{\r
+  UINTN   Ticks;\r
+  UINTN   Counts;\r
+  UINT32  CurrentTick;\r
+  UINT32  OriginalTick;\r
+  UINT32  RemainingTick;\r
+\r
+  if (Microseconds == 0) {\r
+    return EFI_SUCCESS;\r
+  }\r
+\r
+  OriginalTick = IoRead32 (ACPI_BASE_ADDRESS + R_PCH_ACPI_PM1_TMR);\r
+  OriginalTick &= (V_PCH_ACPI_PM1_TMR_MAX_VAL - 1);\r
+  CurrentTick = OriginalTick;\r
+\r
+  //\r
+  // The timer frequency is 3.579545MHz, so 1 ms corresponds to 3.58 clocks\r
+  //\r
+  Ticks = Microseconds * 358 / 100 + OriginalTick + 1;\r
+\r
+  //\r
+  // The loops needed for timer overflow\r
+  //\r
+  Counts = (UINTN)RShiftU64((UINT64)Ticks, 24);\r
+\r
+  //\r
+  // Remaining clocks within one loop\r
+  //\r
+  RemainingTick = Ticks & 0xFFFFFF;\r
+\r
+  //\r
+  // Do not intend to use TMROF_STS bit of register PM1_STS, because this add extra\r
+  // one I/O operation, and may generate SMI\r
+  //\r
+  while (Counts != 0) {\r
+    CurrentTick = IoRead32 (ACPI_BASE_ADDRESS + R_PCH_ACPI_PM1_TMR) & B_PCH_ACPI_PM1_TMR_VAL;\r
+    if (CurrentTick <= OriginalTick) {\r
+      Counts--;\r
+    }\r
+    OriginalTick = CurrentTick;\r
+  }\r
+\r
+  while ((RemainingTick > CurrentTick) && (OriginalTick <= CurrentTick)) {\r
+    OriginalTick  = CurrentTick;\r
+    CurrentTick   = IoRead32 (ACPI_BASE_ADDRESS + R_PCH_ACPI_PM1_TMR) & B_PCH_ACPI_PM1_TMR_VAL;\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r