aboutsummaryrefslogtreecommitdiff
path: root/Clock.c
blob: c1663378b8a0899701642bcb4e849ae360b6c1ed (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
// This file was extracted from the TCG Published
// Trusted Platform Module Library
// Part 4: Supporting Routines
// Family "2.0"
// Level 00 Revision 01.16
// October 30, 2014

#include "PlatformData.h"
#include "Platform.h"

#ifdef __linux__

#include <sys/time.h>
// Function clock() does not provide accurate wall clock time on linux, let's
// substitite it with our own caclulations.
//
// Return current wall clock modulo milliseconds.
static UINT64 clock(void)
{
  struct timeval tv;
  gettimeofday(&tv, NULL);
  return (UINT64)tv.tv_sec * 1000 + tv.tv_usec / 1000;
}
#else
#include <time.h>
#endif
//
//
//          Functions
//
//          _plat__ClockReset()
//
//     Set the current clock time as initial time. This function is called at a power on event to reset the clock
//
LIB_EXPORT void
_plat__ClockReset(
     void
     )
{
     // Implementation specific: Microsoft C set CLOCKS_PER_SEC to be 1/1000,
     // so here the measurement of clock() is in millisecond.
     s_initClock = clock();
     s_adjustRate = CLOCK_NOMINAL;
     return;
}
//
//
//          _plat__ClockTimeFromStart()
//
//     Function returns the compensated                time    from    the    start    of   the    command      when
//     _plat__ClockTimeFromStart() was called.
//
unsigned long long
_plat__ClockTimeFromStart(
     void
     )
{
     unsigned long long currentClock = clock();
     return ((currentClock - s_initClock) * CLOCK_NOMINAL) / s_adjustRate;
}
//
//
//          _plat__ClockTimeElapsed()
//
//     Get the time elapsed from current to the last time the _plat__ClockTimeElapsed() is called. For the first
//     _plat__ClockTimeElapsed() call after a power on event, this call report the elapsed time from power on to
//     the current call
//
LIB_EXPORT unsigned long long
_plat__ClockTimeElapsed(
     void
//
    )
{
    unsigned long long elapsed;
    unsigned long long currentClock = clock();
    elapsed = ((currentClock - s_initClock) * CLOCK_NOMINAL) / s_adjustRate;
    s_initClock += (elapsed * s_adjustRate) / CLOCK_NOMINAL;
#ifdef DEBUGGING_TIME
   // Put this in so that TPM time will pass much faster than real time when
   // doing debug.
   // A value of 1000 for DEBUG_TIME_MULTIPLER will make each ms into a second
   // A good value might be 100
   elapsed *= DEBUG_TIME_MULTIPLIER
#endif
              return elapsed;
}
//
//
//        _plat__ClockAdjustRate()
//
//     Adjust the clock rate
//
LIB_EXPORT void
_plat__ClockAdjustRate(
    int                adjust         // IN: the adjust number.   It could be positive
                                      //     or negative
    )
{
    // We expect the caller should only use a fixed set of constant values to
    // adjust the rate
    switch(adjust)
    {
        case CLOCK_ADJUST_COARSE:
            s_adjustRate += CLOCK_ADJUST_COARSE;
            break;
        case -CLOCK_ADJUST_COARSE:
            s_adjustRate -= CLOCK_ADJUST_COARSE;
            break;
        case CLOCK_ADJUST_MEDIUM:
            s_adjustRate += CLOCK_ADJUST_MEDIUM;
            break;
        case -CLOCK_ADJUST_MEDIUM:
            s_adjustRate -= CLOCK_ADJUST_MEDIUM;
            break;
        case CLOCK_ADJUST_FINE:
            s_adjustRate += CLOCK_ADJUST_FINE;
            break;
        case -CLOCK_ADJUST_FINE:
            s_adjustRate -= CLOCK_ADJUST_FINE;
            break;
        default:
            // ignore any other values;
            break;
    }
    if(s_adjustRate > (CLOCK_NOMINAL + CLOCK_ADJUST_LIMIT))
        s_adjustRate = CLOCK_NOMINAL + CLOCK_ADJUST_LIMIT;
    if(s_adjustRate < (CLOCK_NOMINAL - CLOCK_ADJUST_LIMIT))
        s_adjustRate = CLOCK_NOMINAL-CLOCK_ADJUST_LIMIT;
    return;
}