blob: c1663378b8a0899701642bcb4e849ae360b6c1ed [file] [log] [blame]
Vadim Bendebury56797522015-05-20 10:32:25 -07001// 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
Vadim Bendebury56797522015-05-20 10:32:25 -07008#include "PlatformData.h"
9#include "Platform.h"
Vadim Bendebury01cb92e2015-10-21 11:31:37 -070010
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.
18static 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
Vadim Bendebury56797522015-05-20 10:32:25 -070027//
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//
35LIB_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//
53unsigned 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//
69LIB_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//
94LIB_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}