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.
clock(void)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
_plat__ClockReset(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
_plat__ClockTimeFromStart(void)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
_plat__ClockTimeElapsed(void)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
_plat__ClockAdjustRate(int adjust)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