Stall.c 2.2 KB

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