// 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; }