SyncTimer.c 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. /** @file
  2. SMM Timer feature support
  3. Copyright (c) 2009 - 2015, Intel Corporation. All rights reserved.<BR>
  4. SPDX-License-Identifier: BSD-2-Clause-Patent
  5. **/
  6. #include "PiSmmCpuDxeSmm.h"
  7. UINT64 mTimeoutTicker = 0;
  8. //
  9. // Number of counts in a roll-over cycle of the performance counter.
  10. //
  11. UINT64 mCycle = 0;
  12. //
  13. // Flag to indicate the performance counter is count-up or count-down.
  14. //
  15. BOOLEAN mCountDown;
  16. /**
  17. Initialize Timer for SMM AP Sync.
  18. **/
  19. VOID
  20. InitializeSmmTimer (
  21. VOID
  22. )
  23. {
  24. UINT64 TimerFrequency;
  25. UINT64 Start;
  26. UINT64 End;
  27. TimerFrequency = GetPerformanceCounterProperties (&Start, &End);
  28. mTimeoutTicker = DivU64x32 (
  29. MultU64x64 (TimerFrequency, PcdGet64 (PcdCpuSmmApSyncTimeout)),
  30. 1000 * 1000
  31. );
  32. if (End < Start) {
  33. mCountDown = TRUE;
  34. mCycle = Start - End;
  35. } else {
  36. mCountDown = FALSE;
  37. mCycle = End - Start;
  38. }
  39. }
  40. /**
  41. Start Timer for SMM AP Sync.
  42. **/
  43. UINT64
  44. EFIAPI
  45. StartSyncTimer (
  46. VOID
  47. )
  48. {
  49. return GetPerformanceCounter ();
  50. }
  51. /**
  52. Check if the SMM AP Sync timer is timeout.
  53. @param Timer The start timer from the begin.
  54. **/
  55. BOOLEAN
  56. EFIAPI
  57. IsSyncTimerTimeout (
  58. IN UINT64 Timer
  59. )
  60. {
  61. UINT64 CurrentTimer;
  62. UINT64 Delta;
  63. CurrentTimer = GetPerformanceCounter ();
  64. //
  65. // We need to consider the case that CurrentTimer is equal to Timer
  66. // when some timer runs too slow and CPU runs fast. We think roll over
  67. // condition does not happen on this case.
  68. //
  69. if (mCountDown) {
  70. //
  71. // The performance counter counts down. Check for roll over condition.
  72. //
  73. if (CurrentTimer <= Timer) {
  74. Delta = Timer - CurrentTimer;
  75. } else {
  76. //
  77. // Handle one roll-over.
  78. //
  79. Delta = mCycle - (CurrentTimer - Timer) + 1;
  80. }
  81. } else {
  82. //
  83. // The performance counter counts up. Check for roll over condition.
  84. //
  85. if (CurrentTimer >= Timer) {
  86. Delta = CurrentTimer - Timer;
  87. } else {
  88. //
  89. // Handle one roll-over.
  90. //
  91. Delta = mCycle - (Timer - CurrentTimer) + 1;
  92. }
  93. }
  94. return (BOOLEAN)(Delta >= mTimeoutTicker);
  95. }