Home | History | Annotate | Download | only in PlatformDxe
      1 /** @file
      2   Adjust Default System Time.
      3 
      4   Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
      5 
      6   This program and the accompanying materials are licensed and made available under
      7   the terms and conditions of the BSD License that accompanies this distribution.
      8   The full text of the license may be found at
      9   http://opensource.org/licenses/bsd-license.php.
     10 
     11   THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
     12   WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     13 
     14 --*/
     15 
     16 #include <PlatformDxe.h>
     17 
     18 //
     19 // Date and time initial values.
     20 // They are used if the RTC values are invalid during driver initialization
     21 //
     22 #define RTC_INIT_SECOND 0
     23 #define RTC_INIT_MINUTE 0
     24 #define RTC_INIT_HOUR   0
     25 
     26 CHAR16  mBiosReleaseDate[20];
     27 
     28 /**
     29   Convert a single character to number.
     30   It assumes the input Char is in the scope of L'0' ~ L'9' and L'A' ~ L'F'
     31 
     32   @param Char    The input char which need to change to a hex number.
     33 
     34 **/
     35 UINTN
     36 CharToUint (
     37   IN CHAR16                           Char
     38   )
     39 {
     40   if ((Char >= L'0') && (Char <= L'9')) {
     41     return (UINTN) (Char - L'0');
     42   }
     43 
     44   if ((Char >= L'A') && (Char <= L'F')) {
     45     return (UINTN) (Char - L'A' + 0xA);
     46   }
     47 
     48   ASSERT (FALSE);
     49   return 0;
     50 }
     51 
     52 /**
     53   See if YEAR field of a variable of EFI_TIME type is correct.
     54 
     55   @param   Time   The time to be checked.
     56 
     57   @retval  EFI_INVALID_PARAMETER  Some fields of Time are not correct.
     58   @retval  EFI_SUCCESS            Time is a valid EFI_TIME variable.
     59 
     60 **/
     61 EFI_STATUS
     62 CheckRtcTimeFields (
     63   IN EFI_TIME *Time
     64   )
     65 {
     66   UINT16 YearBuilt;
     67 
     68   YearBuilt = (UINT16)(CharToUint(mBiosReleaseDate[8])*10 + CharToUint(mBiosReleaseDate[9]) + 2000);
     69 
     70   if ((Time->Year) < YearBuilt) {
     71     return EFI_INVALID_PARAMETER;
     72   }
     73 
     74   return EFI_SUCCESS;
     75 }
     76 
     77 /**
     78   ExitPmAuth Protocol notification event handler, which set initial system time to be
     79   the time when BIOS was built.
     80 
     81   @param[in] Event    Event whose notification function is being invoked.
     82   @param[in] Context  Pointer to the notification function's context.
     83 
     84 **/
     85 VOID
     86 EFIAPI
     87 AdjustDefaultRtcTimeCallback (
     88   IN EFI_EVENT        Event,
     89   IN VOID             *Context
     90   )
     91 {
     92   EFI_STATUS      Status;
     93   EFI_TIME        EfiTime;
     94   CHAR16          BiosVersion[60];
     95   CHAR16          BiosReleaseTime[20];
     96   //
     97   // Get BIOS built time from Bios-ID.
     98   //
     99 
    100   SetMem(BiosVersion, sizeof(BiosVersion), 0);
    101   SetMem(mBiosReleaseDate, sizeof(mBiosReleaseDate), 0);
    102   SetMem(BiosReleaseTime, sizeof(BiosReleaseTime), 0);
    103 
    104   Status = GetBiosVersionDateTime (BiosVersion, mBiosReleaseDate, BiosReleaseTime);
    105   ASSERT_EFI_ERROR(Status);
    106   if (EFI_ERROR (Status)) {
    107     return;
    108   }
    109 
    110   //
    111   // Get current RTC time.
    112   //
    113   Status = gRT->GetTime (&EfiTime, NULL);
    114 
    115   //
    116   // Validate RTC time fields
    117   //
    118   Status = CheckRtcTimeFields (&EfiTime);
    119 
    120   if (EFI_ERROR (Status)) {
    121     //
    122     // Date such as Dec 28th of 2015
    123     //
    124     // Month
    125     // BiosReleaseDate[0] = '1';
    126     // BiosReleaseDate[1] = '2';
    127     //
    128     // Day
    129     // BiosReleaseDate[3] = '2';
    130     // BiosReleaseDate[4] = '8';
    131     //
    132     //
    133     // Year
    134     //
    135     // BiosReleaseDate[6] = '2';
    136     // BiosReleaseDate[7] = '0';
    137     // BiosReleaseDate[8] = '1'
    138     // BiosReleaseDate[9] = '5';
    139 
    140     EfiTime.Second = RTC_INIT_SECOND;
    141     EfiTime.Minute = RTC_INIT_MINUTE;
    142     EfiTime.Hour   = RTC_INIT_HOUR;
    143     EfiTime.Day    = (UINT8)(CharToUint(mBiosReleaseDate[3])*10 + CharToUint(mBiosReleaseDate[4]));
    144     EfiTime.Month  = (UINT8)(CharToUint(mBiosReleaseDate[0])*10 + CharToUint(mBiosReleaseDate[1]));
    145     EfiTime.Year   = (UINT16)(CharToUint(mBiosReleaseDate[8])*10 + CharToUint(mBiosReleaseDate[9]) + 2000);
    146     EfiTime.Nanosecond  = 0;
    147     EfiTime.TimeZone = EFI_UNSPECIFIED_TIMEZONE;
    148     EfiTime.Daylight = 1;
    149 
    150     DEBUG ((EFI_D_INFO, "Day:%d Month:%d Year:%d \n", (UINT32)EfiTime.Day, (UINT32)EfiTime.Month, (UINT32)EfiTime.Year));
    151 
    152     //
    153     // Reset time value according to new RTC configuration
    154     //
    155     Status = gRT->SetTime (&EfiTime);
    156     ASSERT_EFI_ERROR(Status);
    157   }
    158 
    159   return;
    160 }
    161