/* Returns a timer value from one of the CPU's internal timers. There is no inherent time interval between ticks but is a function of the CPU frequency. */
EFI_STATUS EFIAPI CpuGetTimerValue(IN EFI_CPU_ARCH_PROTOCOL *This, IN UINT32 TimerIndex, OUT UINT64 *TimerValue, OUT UINT64 *TimerPeriod OPTIONAL)
/* Returns a timer value from one of the CPU's internal timers. There is no inherent time interval between ticks but is a function of the CPU frequency. */
EFI_STATUS EFIAPI CpuGetTimerValue(IN EFI_CPU_ARCH_PROTOCOL *This, IN UINT32 TimerIndex, OUT UINT64 *TimerValue, OUT UINT64 *TimerPeriod OPTIONAL)
{
  UINT64  BeginValue;
  UINT64  EndValue;
  if (TimerValue == NULL) {
    return EFI_INVALID_PARAMETER;
  }
  if (TimerIndex != 0) {
    return EFI_INVALID_PARAMETER;
  }
  *TimerValue = AsmReadTsc ();
  if (TimerPeriod != NULL) {
    if (mTimerPeriod == 0) {
      BeginValue = AsmReadTsc ();
      MicroSecondDelay (100);
      EndValue = AsmReadTsc ();
      mTimerPeriod = DivU64x64Remainder (
                       MultU64x32 (
                         1000 * 1000 * 1000,
                         100
                         ),
                       EndValue - BeginValue,
                       NULL
                       );
    }
    *TimerPeriod = mTimerPeriod;
  }
  return EFI_SUCCESS;
}