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