Home | History | Annotate | Download | only in tpm2
      1 // This file was extracted from the TCG Published
      2 // Trusted Platform Module Library
      3 // Part 4: Supporting Routines
      4 // Family "2.0"
      5 // Level 00 Revision 01.16
      6 // October 30, 2014
      7 
      8 #include "PlatformData.h"
      9 #include "Platform.h"
     10 
     11 #ifdef __linux__
     12 
     13 #include <sys/time.h>
     14 // Function clock() does not provide accurate wall clock time on linux, let's
     15 // substitite it with our own caclulations.
     16 //
     17 // Return current wall clock modulo milliseconds.
     18 static UINT64 clock(void)
     19 {
     20   struct timeval tv;
     21   gettimeofday(&tv, NULL);
     22   return (UINT64)tv.tv_sec * 1000 + tv.tv_usec / 1000;
     23 }
     24 #else
     25 #include <time.h>
     26 #endif
     27 //
     28 //
     29 //          Functions
     30 //
     31 //          _plat__ClockReset()
     32 //
     33 //     Set the current clock time as initial time. This function is called at a power on event to reset the clock
     34 //
     35 LIB_EXPORT void
     36 _plat__ClockReset(
     37      void
     38      )
     39 {
     40      // Implementation specific: Microsoft C set CLOCKS_PER_SEC to be 1/1000,
     41      // so here the measurement of clock() is in millisecond.
     42      s_initClock = clock();
     43      s_adjustRate = CLOCK_NOMINAL;
     44      return;
     45 }
     46 //
     47 //
     48 //          _plat__ClockTimeFromStart()
     49 //
     50 //     Function returns the compensated                time    from    the    start    of   the    command      when
     51 //     _plat__ClockTimeFromStart() was called.
     52 //
     53 unsigned long long
     54 _plat__ClockTimeFromStart(
     55      void
     56      )
     57 {
     58      unsigned long long currentClock = clock();
     59      return ((currentClock - s_initClock) * CLOCK_NOMINAL) / s_adjustRate;
     60 }
     61 //
     62 //
     63 //          _plat__ClockTimeElapsed()
     64 //
     65 //     Get the time elapsed from current to the last time the _plat__ClockTimeElapsed() is called. For the first
     66 //     _plat__ClockTimeElapsed() call after a power on event, this call report the elapsed time from power on to
     67 //     the current call
     68 //
     69 LIB_EXPORT unsigned long long
     70 _plat__ClockTimeElapsed(
     71      void
     72 //
     73     )
     74 {
     75     unsigned long long elapsed;
     76     unsigned long long currentClock = clock();
     77     elapsed = ((currentClock - s_initClock) * CLOCK_NOMINAL) / s_adjustRate;
     78     s_initClock += (elapsed * s_adjustRate) / CLOCK_NOMINAL;
     79 #ifdef DEBUGGING_TIME
     80    // Put this in so that TPM time will pass much faster than real time when
     81    // doing debug.
     82    // A value of 1000 for DEBUG_TIME_MULTIPLER will make each ms into a second
     83    // A good value might be 100
     84    elapsed *= DEBUG_TIME_MULTIPLIER
     85 #endif
     86               return elapsed;
     87 }
     88 //
     89 //
     90 //        _plat__ClockAdjustRate()
     91 //
     92 //     Adjust the clock rate
     93 //
     94 LIB_EXPORT void
     95 _plat__ClockAdjustRate(
     96     int                adjust         // IN: the adjust number.   It could be positive
     97                                       //     or negative
     98     )
     99 {
    100     // We expect the caller should only use a fixed set of constant values to
    101     // adjust the rate
    102     switch(adjust)
    103     {
    104         case CLOCK_ADJUST_COARSE:
    105             s_adjustRate += CLOCK_ADJUST_COARSE;
    106             break;
    107         case -CLOCK_ADJUST_COARSE:
    108             s_adjustRate -= CLOCK_ADJUST_COARSE;
    109             break;
    110         case CLOCK_ADJUST_MEDIUM:
    111             s_adjustRate += CLOCK_ADJUST_MEDIUM;
    112             break;
    113         case -CLOCK_ADJUST_MEDIUM:
    114             s_adjustRate -= CLOCK_ADJUST_MEDIUM;
    115             break;
    116         case CLOCK_ADJUST_FINE:
    117             s_adjustRate += CLOCK_ADJUST_FINE;
    118             break;
    119         case -CLOCK_ADJUST_FINE:
    120             s_adjustRate -= CLOCK_ADJUST_FINE;
    121             break;
    122         default:
    123             // ignore any other values;
    124             break;
    125     }
    126     if(s_adjustRate > (CLOCK_NOMINAL + CLOCK_ADJUST_LIMIT))
    127         s_adjustRate = CLOCK_NOMINAL + CLOCK_ADJUST_LIMIT;
    128     if(s_adjustRate < (CLOCK_NOMINAL - CLOCK_ADJUST_LIMIT))
    129         s_adjustRate = CLOCK_NOMINAL-CLOCK_ADJUST_LIMIT;
    130     return;
    131 }
    132