1529a5a860996b5e83941bab50a7b8604139264a1Michael Kinney/** @file
2529a5a860996b5e83941bab50a7b8604139264a1Michael KinneySMM Timer feature support
3529a5a860996b5e83941bab50a7b8604139264a1Michael Kinney
4529a5a860996b5e83941bab50a7b8604139264a1Michael KinneyCopyright (c) 2009 - 2015, Intel Corporation. All rights reserved.<BR>
5529a5a860996b5e83941bab50a7b8604139264a1Michael KinneyThis program and the accompanying materials
6529a5a860996b5e83941bab50a7b8604139264a1Michael Kinneyare licensed and made available under the terms and conditions of the BSD License
7529a5a860996b5e83941bab50a7b8604139264a1Michael Kinneywhich accompanies this distribution.  The full text of the license may be found at
8529a5a860996b5e83941bab50a7b8604139264a1Michael Kinneyhttp://opensource.org/licenses/bsd-license.php
9529a5a860996b5e83941bab50a7b8604139264a1Michael Kinney
10529a5a860996b5e83941bab50a7b8604139264a1Michael KinneyTHE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11529a5a860996b5e83941bab50a7b8604139264a1Michael KinneyWITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12529a5a860996b5e83941bab50a7b8604139264a1Michael Kinney
13529a5a860996b5e83941bab50a7b8604139264a1Michael Kinney**/
14529a5a860996b5e83941bab50a7b8604139264a1Michael Kinney
15529a5a860996b5e83941bab50a7b8604139264a1Michael Kinney#include "PiSmmCpuDxeSmm.h"
16529a5a860996b5e83941bab50a7b8604139264a1Michael Kinney
17529a5a860996b5e83941bab50a7b8604139264a1Michael KinneyUINT64   mTimeoutTicker = 0;
18529a5a860996b5e83941bab50a7b8604139264a1Michael Kinney//
19529a5a860996b5e83941bab50a7b8604139264a1Michael Kinney//  Number of counts in a roll-over cycle of the performance counter.
20529a5a860996b5e83941bab50a7b8604139264a1Michael Kinney//
21529a5a860996b5e83941bab50a7b8604139264a1Michael KinneyUINT64   mCycle = 0;
22529a5a860996b5e83941bab50a7b8604139264a1Michael Kinney//
23529a5a860996b5e83941bab50a7b8604139264a1Michael Kinney// Flag to indicate the performance counter is count-up or count-down.
24529a5a860996b5e83941bab50a7b8604139264a1Michael Kinney//
25529a5a860996b5e83941bab50a7b8604139264a1Michael KinneyBOOLEAN  mCountDown;
26529a5a860996b5e83941bab50a7b8604139264a1Michael Kinney
27529a5a860996b5e83941bab50a7b8604139264a1Michael Kinney/**
28529a5a860996b5e83941bab50a7b8604139264a1Michael Kinney  Initialize Timer for SMM AP Sync.
29529a5a860996b5e83941bab50a7b8604139264a1Michael Kinney
30529a5a860996b5e83941bab50a7b8604139264a1Michael Kinney**/
31529a5a860996b5e83941bab50a7b8604139264a1Michael KinneyVOID
32529a5a860996b5e83941bab50a7b8604139264a1Michael KinneyInitializeSmmTimer (
33529a5a860996b5e83941bab50a7b8604139264a1Michael Kinney  VOID
34529a5a860996b5e83941bab50a7b8604139264a1Michael Kinney  )
35529a5a860996b5e83941bab50a7b8604139264a1Michael Kinney{
36529a5a860996b5e83941bab50a7b8604139264a1Michael Kinney  UINT64  TimerFrequency;
37529a5a860996b5e83941bab50a7b8604139264a1Michael Kinney  UINT64  Start;
38529a5a860996b5e83941bab50a7b8604139264a1Michael Kinney  UINT64  End;
39529a5a860996b5e83941bab50a7b8604139264a1Michael Kinney
40529a5a860996b5e83941bab50a7b8604139264a1Michael Kinney  TimerFrequency = GetPerformanceCounterProperties (&Start, &End);
41529a5a860996b5e83941bab50a7b8604139264a1Michael Kinney  mTimeoutTicker = DivU64x32 (
42529a5a860996b5e83941bab50a7b8604139264a1Michael Kinney                     MultU64x64(TimerFrequency, PcdGet64 (PcdCpuSmmApSyncTimeout)),
43529a5a860996b5e83941bab50a7b8604139264a1Michael Kinney                     1000 * 1000
44529a5a860996b5e83941bab50a7b8604139264a1Michael Kinney                     );
45529a5a860996b5e83941bab50a7b8604139264a1Michael Kinney  if (End < Start) {
46529a5a860996b5e83941bab50a7b8604139264a1Michael Kinney    mCountDown = TRUE;
47529a5a860996b5e83941bab50a7b8604139264a1Michael Kinney    mCycle = Start - End;
48529a5a860996b5e83941bab50a7b8604139264a1Michael Kinney  } else {
49529a5a860996b5e83941bab50a7b8604139264a1Michael Kinney    mCountDown = FALSE;
50529a5a860996b5e83941bab50a7b8604139264a1Michael Kinney    mCycle = End - Start;
51529a5a860996b5e83941bab50a7b8604139264a1Michael Kinney  }
52529a5a860996b5e83941bab50a7b8604139264a1Michael Kinney}
53529a5a860996b5e83941bab50a7b8604139264a1Michael Kinney
54529a5a860996b5e83941bab50a7b8604139264a1Michael Kinney/**
55529a5a860996b5e83941bab50a7b8604139264a1Michael Kinney  Start Timer for SMM AP Sync.
56529a5a860996b5e83941bab50a7b8604139264a1Michael Kinney
57529a5a860996b5e83941bab50a7b8604139264a1Michael Kinney**/
58529a5a860996b5e83941bab50a7b8604139264a1Michael KinneyUINT64
59529a5a860996b5e83941bab50a7b8604139264a1Michael KinneyEFIAPI
60529a5a860996b5e83941bab50a7b8604139264a1Michael KinneyStartSyncTimer (
61529a5a860996b5e83941bab50a7b8604139264a1Michael Kinney  VOID
62529a5a860996b5e83941bab50a7b8604139264a1Michael Kinney  )
63529a5a860996b5e83941bab50a7b8604139264a1Michael Kinney{
64529a5a860996b5e83941bab50a7b8604139264a1Michael Kinney  return GetPerformanceCounter ();
65529a5a860996b5e83941bab50a7b8604139264a1Michael Kinney}
66529a5a860996b5e83941bab50a7b8604139264a1Michael Kinney
67529a5a860996b5e83941bab50a7b8604139264a1Michael Kinney
68529a5a860996b5e83941bab50a7b8604139264a1Michael Kinney/**
69529a5a860996b5e83941bab50a7b8604139264a1Michael Kinney  Check if the SMM AP Sync timer is timeout.
70529a5a860996b5e83941bab50a7b8604139264a1Michael Kinney
71529a5a860996b5e83941bab50a7b8604139264a1Michael Kinney  @param Timer  The start timer from the begin.
72529a5a860996b5e83941bab50a7b8604139264a1Michael Kinney
73529a5a860996b5e83941bab50a7b8604139264a1Michael Kinney**/
74529a5a860996b5e83941bab50a7b8604139264a1Michael KinneyBOOLEAN
75529a5a860996b5e83941bab50a7b8604139264a1Michael KinneyEFIAPI
76529a5a860996b5e83941bab50a7b8604139264a1Michael KinneyIsSyncTimerTimeout (
77529a5a860996b5e83941bab50a7b8604139264a1Michael Kinney  IN      UINT64                    Timer
78529a5a860996b5e83941bab50a7b8604139264a1Michael Kinney  )
79529a5a860996b5e83941bab50a7b8604139264a1Michael Kinney{
80529a5a860996b5e83941bab50a7b8604139264a1Michael Kinney  UINT64  CurrentTimer;
81529a5a860996b5e83941bab50a7b8604139264a1Michael Kinney  UINT64  Delta;
82529a5a860996b5e83941bab50a7b8604139264a1Michael Kinney
83529a5a860996b5e83941bab50a7b8604139264a1Michael Kinney  CurrentTimer = GetPerformanceCounter ();
84529a5a860996b5e83941bab50a7b8604139264a1Michael Kinney  //
85529a5a860996b5e83941bab50a7b8604139264a1Michael Kinney  // We need to consider the case that CurrentTimer is equal to Timer
86529a5a860996b5e83941bab50a7b8604139264a1Michael Kinney  // when some timer runs too slow and CPU runs fast. We think roll over
87529a5a860996b5e83941bab50a7b8604139264a1Michael Kinney  // condition does not happen on this case.
88529a5a860996b5e83941bab50a7b8604139264a1Michael Kinney  //
89529a5a860996b5e83941bab50a7b8604139264a1Michael Kinney  if (mCountDown) {
90529a5a860996b5e83941bab50a7b8604139264a1Michael Kinney    //
91529a5a860996b5e83941bab50a7b8604139264a1Michael Kinney    // The performance counter counts down.  Check for roll over condition.
92529a5a860996b5e83941bab50a7b8604139264a1Michael Kinney    //
93529a5a860996b5e83941bab50a7b8604139264a1Michael Kinney    if (CurrentTimer <= Timer) {
94529a5a860996b5e83941bab50a7b8604139264a1Michael Kinney      Delta = Timer - CurrentTimer;
95529a5a860996b5e83941bab50a7b8604139264a1Michael Kinney    } else {
96529a5a860996b5e83941bab50a7b8604139264a1Michael Kinney      //
97529a5a860996b5e83941bab50a7b8604139264a1Michael Kinney      // Handle one roll-over.
98529a5a860996b5e83941bab50a7b8604139264a1Michael Kinney      //
99529a5a860996b5e83941bab50a7b8604139264a1Michael Kinney      Delta = mCycle - (CurrentTimer - Timer) + 1;
100529a5a860996b5e83941bab50a7b8604139264a1Michael Kinney    }
101529a5a860996b5e83941bab50a7b8604139264a1Michael Kinney  } else {
102529a5a860996b5e83941bab50a7b8604139264a1Michael Kinney    //
103529a5a860996b5e83941bab50a7b8604139264a1Michael Kinney    // The performance counter counts up.  Check for roll over condition.
104529a5a860996b5e83941bab50a7b8604139264a1Michael Kinney    //
105529a5a860996b5e83941bab50a7b8604139264a1Michael Kinney    if (CurrentTimer >= Timer) {
106529a5a860996b5e83941bab50a7b8604139264a1Michael Kinney      Delta = CurrentTimer - Timer;
107529a5a860996b5e83941bab50a7b8604139264a1Michael Kinney    } else {
108529a5a860996b5e83941bab50a7b8604139264a1Michael Kinney      //
109529a5a860996b5e83941bab50a7b8604139264a1Michael Kinney      // Handle one roll-over.
110529a5a860996b5e83941bab50a7b8604139264a1Michael Kinney      //
111529a5a860996b5e83941bab50a7b8604139264a1Michael Kinney      Delta = mCycle - (Timer - CurrentTimer) + 1;
112529a5a860996b5e83941bab50a7b8604139264a1Michael Kinney    }
113529a5a860996b5e83941bab50a7b8604139264a1Michael Kinney  }
114529a5a860996b5e83941bab50a7b8604139264a1Michael Kinney
115529a5a860996b5e83941bab50a7b8604139264a1Michael Kinney  return (BOOLEAN) (Delta >= mTimeoutTicker);
116529a5a860996b5e83941bab50a7b8604139264a1Michael Kinney}
117