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