Stall.c 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. /** @file
  2. Copyright (c) 2004 - 2014, Intel Corporation. All rights reserved.<BR>
  3. SPDX-License-Identifier: BSD-2-Clause-Patent
  4. Module Name:
  5. Stall.c
  6. Abstract:
  7. Produce Stall Ppi.
  8. --*/
  9. #include "PlatformEarlyInit.h"
  10. /**
  11. Waits for at least the given number of microseconds.
  12. @param PeiServices General purpose services available to every PEIM.
  13. @param This PPI instance structure.
  14. @param Microseconds Desired length of time to wait.
  15. @retval EFI_SUCCESS If the desired amount of time was passed.
  16. */
  17. EFI_STATUS
  18. EFIAPI
  19. Stall (
  20. IN CONST EFI_PEI_SERVICES **PeiServices,
  21. IN CONST EFI_PEI_STALL_PPI *This,
  22. IN UINTN Microseconds
  23. )
  24. {
  25. UINTN Ticks;
  26. UINTN Counts;
  27. UINT32 CurrentTick;
  28. UINT32 OriginalTick;
  29. UINT32 RemainingTick;
  30. if (Microseconds == 0) {
  31. return EFI_SUCCESS;
  32. }
  33. OriginalTick = IoRead32 (ACPI_BASE_ADDRESS + R_PCH_ACPI_PM1_TMR);
  34. OriginalTick &= (V_PCH_ACPI_PM1_TMR_MAX_VAL - 1);
  35. CurrentTick = OriginalTick;
  36. //
  37. // The timer frequency is 3.579545MHz, so 1 ms corresponds to 3.58 clocks
  38. //
  39. Ticks = Microseconds * 358 / 100 + OriginalTick + 1;
  40. //
  41. // The loops needed for timer overflow
  42. //
  43. Counts = (UINTN)RShiftU64((UINT64)Ticks, 24);
  44. //
  45. // Remaining clocks within one loop
  46. //
  47. RemainingTick = Ticks & 0xFFFFFF;
  48. //
  49. // Do not intend to use TMROF_STS bit of register PM1_STS, because this add extra
  50. // one I/O operation, and may generate SMI
  51. //
  52. while (Counts != 0) {
  53. CurrentTick = IoRead32 (ACPI_BASE_ADDRESS + R_PCH_ACPI_PM1_TMR) & B_PCH_ACPI_PM1_TMR_VAL;
  54. if (CurrentTick <= OriginalTick) {
  55. Counts--;
  56. }
  57. OriginalTick = CurrentTick;
  58. }
  59. while ((RemainingTick > CurrentTick) && (OriginalTick <= CurrentTick)) {
  60. OriginalTick = CurrentTick;
  61. CurrentTick = IoRead32 (ACPI_BASE_ADDRESS + R_PCH_ACPI_PM1_TMR) & B_PCH_ACPI_PM1_TMR_VAL;
  62. }
  63. return EFI_SUCCESS;
  64. }