Home | History | Annotate | Download | only in TimestampDxe
      1 /** @file
      2   Implementation of Timestamp Protocol using UEFI APIs.
      3 
      4 Copyright (c) 2013, Intel Corporation. All rights reserved.<BR>
      5 This program and the accompanying materials
      6 are licensed and made available under the terms and conditions of the BSD License
      7 which accompanies this distribution.  The full text of the license may be found at
      8 http://opensource.org/licenses/bsd-license.php
      9 
     10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
     11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     12 
     13 **/
     14 
     15 #include <Uefi.h>
     16 #include <Library/DebugLib.h>
     17 #include <Library/UefiDriverEntryPoint.h>
     18 #include <Library/UefiBootServicesTableLib.h>
     19 #include <Library/TimerLib.h>
     20 #include <Library/BaseMemoryLib.h>
     21 #include <Protocol/Timestamp.h>
     22 
     23 //
     24 // The StartValue in TimerLib
     25 //
     26 UINT64 mTimerLibStartValue = 0;
     27 
     28 //
     29 // The EndValue in TimerLib
     30 //
     31 UINT64 mTimerLibEndValue = 0;
     32 
     33 //
     34 // The properties of timestamp
     35 //
     36 EFI_TIMESTAMP_PROPERTIES mTimestampProperties = {
     37   0,
     38   0
     39 };
     40 
     41 /**
     42   Retrieves the current value of a 64-bit free running timestamp counter.
     43 
     44   The counter shall count up in proportion to the amount of time that has passed. The counter value
     45   will always roll over to zero. The properties of the counter can be retrieved from GetProperties().
     46   The caller should be prepared for the function to return the same value twice across successive calls.
     47   The counter value will not go backwards other than when wrapping, as defined by EndValue in GetProperties().
     48   The frequency of the returned timestamp counter value must remain constant. Power management operations that
     49   affect clocking must not change the returned counter frequency. The quantization of counter value updates may
     50   vary as long as the value reflecting time passed remains consistent.
     51 
     52   @retval The current value of the free running timestamp counter.
     53 
     54 **/
     55 UINT64
     56 EFIAPI
     57 TimestampDriverGetTimestamp (
     58   VOID
     59   )
     60 {
     61   //
     62   // The timestamp of Timestamp Protocol
     63   //
     64   UINT64  TimestampValue;
     65   TimestampValue = 0;
     66 
     67   //
     68   // Get the timestamp
     69   //
     70   if (mTimerLibStartValue > mTimerLibEndValue) {
     71     TimestampValue = mTimerLibStartValue - GetPerformanceCounter();
     72   } else {
     73     TimestampValue = GetPerformanceCounter() - mTimerLibStartValue;
     74   }
     75 
     76   return TimestampValue;
     77 }
     78 
     79 /**
     80   Obtains timestamp counter properties including frequency and value limits.
     81 
     82   @param[out]  Properties              The properties of the timestamp counter.
     83 
     84   @retval      EFI_SUCCESS             The properties were successfully retrieved.
     85   @retval      EFI_DEVICE_ERROR        An error occurred trying to retrieve the properties of the timestamp
     86                                        counter subsystem. Properties is not pedated.
     87   @retval      EFI_INVALID_PARAMETER   Properties is NULL.
     88 
     89 **/
     90 EFI_STATUS
     91 EFIAPI
     92 TimestampDriverGetProperties(
     93   OUT   EFI_TIMESTAMP_PROPERTIES       *Properties
     94   )
     95 {
     96   if (Properties == NULL) {
     97     return EFI_INVALID_PARAMETER;
     98   }
     99 
    100   //
    101   // Get timestamp properties
    102   //
    103   CopyMem((VOID *) Properties, (VOID *) &mTimestampProperties, sizeof (mTimestampProperties));
    104 
    105   return EFI_SUCCESS;
    106 }
    107 
    108 //
    109 // The Timestamp Protocol instance produced by this driver
    110 //
    111 EFI_TIMESTAMP_PROTOCOL  mTimestamp = {
    112   TimestampDriverGetTimestamp,
    113   TimestampDriverGetProperties
    114 };
    115 
    116 /**
    117   Entry point of the Timestamp Protocol driver.
    118 
    119   @param  ImageHandle   The image handle of this driver.
    120   @param  SystemTable   The pointer of EFI_SYSTEM_TABLE.
    121 
    122   @retval EFI_SUCCESS   Watchdog Timer Architectural Protocol successfully installed.
    123 
    124 **/
    125 EFI_STATUS
    126 EFIAPI
    127 TimestampDriverInitialize (
    128   IN EFI_HANDLE        ImageHandle,
    129   IN EFI_SYSTEM_TABLE  *SystemTable
    130   )
    131 {
    132   EFI_STATUS  Status;
    133 
    134   EFI_HANDLE  TimestampHandle;
    135   TimestampHandle = NULL;
    136 
    137   //
    138   // Get the start value, end value and frequency in Timerlib
    139   //
    140   mTimestampProperties.Frequency = GetPerformanceCounterProperties(&mTimerLibStartValue, &mTimerLibEndValue);
    141 
    142   //
    143   // Set the EndValue
    144   //
    145   if (mTimerLibEndValue > mTimerLibStartValue) {
    146     mTimestampProperties.EndValue = mTimerLibEndValue - mTimerLibStartValue;
    147   } else {
    148     mTimestampProperties.EndValue = mTimerLibStartValue - mTimerLibEndValue;
    149   }
    150 
    151   DEBUG ((EFI_D_INFO, "TimerFrequency:0x%lx, TimerLibStartTime:0x%lx, TimerLibEndtime:0x%lx\n", mTimestampProperties.Frequency, mTimerLibStartValue, mTimerLibEndValue));
    152 
    153   //
    154   // Install the Timestamp Protocol onto a new handle
    155   //
    156   Status = gBS->InstallMultipleProtocolInterfaces (
    157                   &TimestampHandle,
    158                   &gEfiTimestampProtocolGuid,
    159                   &mTimestamp,
    160                   NULL
    161                   );
    162 
    163   ASSERT_EFI_ERROR (Status);
    164 
    165   return EFI_SUCCESS;
    166 }
    167