Home | History | Annotate | Download | only in PiSmmCpuDxeSmm
      1 /** @file
      2 SMM Timer feature support
      3 
      4 Copyright (c) 2009 - 2015, Intel Corporation. All rights reserved.<BR>
      5 This program and the accompanying materials
      6 are licensed and made available under the terms and conditions of the BSD License
      7 which accompanies this distribution.  The full text of the license may be found at
      8 http://opensource.org/licenses/bsd-license.php
      9 
     10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
     11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     12 
     13 **/
     14 
     15 #include "PiSmmCpuDxeSmm.h"
     16 
     17 UINT64   mTimeoutTicker = 0;
     18 //
     19 //  Number of counts in a roll-over cycle of the performance counter.
     20 //
     21 UINT64   mCycle = 0;
     22 //
     23 // Flag to indicate the performance counter is count-up or count-down.
     24 //
     25 BOOLEAN  mCountDown;
     26 
     27 /**
     28   Initialize Timer for SMM AP Sync.
     29 
     30 **/
     31 VOID
     32 InitializeSmmTimer (
     33   VOID
     34   )
     35 {
     36   UINT64  TimerFrequency;
     37   UINT64  Start;
     38   UINT64  End;
     39 
     40   TimerFrequency = GetPerformanceCounterProperties (&Start, &End);
     41   mTimeoutTicker = DivU64x32 (
     42                      MultU64x64(TimerFrequency, PcdGet64 (PcdCpuSmmApSyncTimeout)),
     43                      1000 * 1000
     44                      );
     45   if (End < Start) {
     46     mCountDown = TRUE;
     47     mCycle = Start - End;
     48   } else {
     49     mCountDown = FALSE;
     50     mCycle = End - Start;
     51   }
     52 }
     53 
     54 /**
     55   Start Timer for SMM AP Sync.
     56 
     57 **/
     58 UINT64
     59 EFIAPI
     60 StartSyncTimer (
     61   VOID
     62   )
     63 {
     64   return GetPerformanceCounter ();
     65 }
     66 
     67 
     68 /**
     69   Check if the SMM AP Sync timer is timeout.
     70 
     71   @param Timer  The start timer from the begin.
     72 
     73 **/
     74 BOOLEAN
     75 EFIAPI
     76 IsSyncTimerTimeout (
     77   IN      UINT64                    Timer
     78   )
     79 {
     80   UINT64  CurrentTimer;
     81   UINT64  Delta;
     82 
     83   CurrentTimer = GetPerformanceCounter ();
     84   //
     85   // We need to consider the case that CurrentTimer is equal to Timer
     86   // when some timer runs too slow and CPU runs fast. We think roll over
     87   // condition does not happen on this case.
     88   //
     89   if (mCountDown) {
     90     //
     91     // The performance counter counts down.  Check for roll over condition.
     92     //
     93     if (CurrentTimer <= Timer) {
     94       Delta = Timer - CurrentTimer;
     95     } else {
     96       //
     97       // Handle one roll-over.
     98       //
     99       Delta = mCycle - (CurrentTimer - Timer) + 1;
    100     }
    101   } else {
    102     //
    103     // The performance counter counts up.  Check for roll over condition.
    104     //
    105     if (CurrentTimer >= Timer) {
    106       Delta = CurrentTimer - Timer;
    107     } else {
    108       //
    109       // Handle one roll-over.
    110       //
    111       Delta = mCycle - (Timer - CurrentTimer) + 1;
    112     }
    113   }
    114 
    115   return (BOOLEAN) (Delta >= mTimeoutTicker);
    116 }
    117