Rtc.c 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. /** @file
  2. Adjust Default System Time.
  3. Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
  4. SPDX-License-Identifier: BSD-2-Clause-Patent
  5. --*/
  6. #include <PlatformDxe.h>
  7. //
  8. // Date and time initial values.
  9. // They are used if the RTC values are invalid during driver initialization
  10. //
  11. #define RTC_INIT_SECOND 0
  12. #define RTC_INIT_MINUTE 0
  13. #define RTC_INIT_HOUR 0
  14. CHAR16 mBiosReleaseDate[20];
  15. /**
  16. Convert a single character to number.
  17. It assumes the input Char is in the scope of L'0' ~ L'9' and L'A' ~ L'F'
  18. @param Char The input char which need to change to a hex number.
  19. **/
  20. UINTN
  21. CharToUint (
  22. IN CHAR16 Char
  23. )
  24. {
  25. if ((Char >= L'0') && (Char <= L'9')) {
  26. return (UINTN) (Char - L'0');
  27. }
  28. if ((Char >= L'A') && (Char <= L'F')) {
  29. return (UINTN) (Char - L'A' + 0xA);
  30. }
  31. ASSERT (FALSE);
  32. return 0;
  33. }
  34. /**
  35. See if YEAR field of a variable of EFI_TIME type is correct.
  36. @param Time The time to be checked.
  37. @retval EFI_INVALID_PARAMETER Some fields of Time are not correct.
  38. @retval EFI_SUCCESS Time is a valid EFI_TIME variable.
  39. **/
  40. EFI_STATUS
  41. CheckRtcTimeFields (
  42. IN EFI_TIME *Time
  43. )
  44. {
  45. UINT16 YearBuilt;
  46. YearBuilt = (UINT16)(CharToUint(mBiosReleaseDate[8])*10 + CharToUint(mBiosReleaseDate[9]) + 2000);
  47. if ((Time->Year) < YearBuilt) {
  48. return EFI_INVALID_PARAMETER;
  49. }
  50. return EFI_SUCCESS;
  51. }
  52. /**
  53. ExitPmAuth Protocol notification event handler, which set initial system time to be
  54. the time when BIOS was built.
  55. @param[in] Event Event whose notification function is being invoked.
  56. @param[in] Context Pointer to the notification function's context.
  57. **/
  58. VOID
  59. EFIAPI
  60. AdjustDefaultRtcTimeCallback (
  61. IN EFI_EVENT Event,
  62. IN VOID *Context
  63. )
  64. {
  65. EFI_STATUS Status;
  66. EFI_TIME EfiTime;
  67. CHAR16 BiosVersion[60];
  68. CHAR16 BiosReleaseTime[20];
  69. //
  70. // Get BIOS built time from Bios-ID.
  71. //
  72. SetMem(BiosVersion, sizeof(BiosVersion), 0);
  73. SetMem(mBiosReleaseDate, sizeof(mBiosReleaseDate), 0);
  74. SetMem(BiosReleaseTime, sizeof(BiosReleaseTime), 0);
  75. Status = GetBiosVersionDateTime (BiosVersion, mBiosReleaseDate, BiosReleaseTime);
  76. ASSERT_EFI_ERROR(Status);
  77. if (EFI_ERROR (Status)) {
  78. return;
  79. }
  80. //
  81. // Get current RTC time.
  82. //
  83. Status = gRT->GetTime (&EfiTime, NULL);
  84. //
  85. // Validate RTC time fields
  86. //
  87. Status = CheckRtcTimeFields (&EfiTime);
  88. if (EFI_ERROR (Status)) {
  89. //
  90. // Date such as Dec 28th of 2015
  91. //
  92. // Month
  93. // BiosReleaseDate[0] = '1';
  94. // BiosReleaseDate[1] = '2';
  95. //
  96. // Day
  97. // BiosReleaseDate[3] = '2';
  98. // BiosReleaseDate[4] = '8';
  99. //
  100. //
  101. // Year
  102. //
  103. // BiosReleaseDate[6] = '2';
  104. // BiosReleaseDate[7] = '0';
  105. // BiosReleaseDate[8] = '1'
  106. // BiosReleaseDate[9] = '5';
  107. EfiTime.Second = RTC_INIT_SECOND;
  108. EfiTime.Minute = RTC_INIT_MINUTE;
  109. EfiTime.Hour = RTC_INIT_HOUR;
  110. EfiTime.Day = (UINT8)(CharToUint(mBiosReleaseDate[3])*10 + CharToUint(mBiosReleaseDate[4]));
  111. EfiTime.Month = (UINT8)(CharToUint(mBiosReleaseDate[0])*10 + CharToUint(mBiosReleaseDate[1]));
  112. EfiTime.Year = (UINT16)(CharToUint(mBiosReleaseDate[8])*10 + CharToUint(mBiosReleaseDate[9]) + 2000);
  113. EfiTime.Nanosecond = 0;
  114. EfiTime.TimeZone = EFI_UNSPECIFIED_TIMEZONE;
  115. EfiTime.Daylight = 1;
  116. DEBUG ((EFI_D_INFO, "Day:%d Month:%d Year:%d \n", (UINT32)EfiTime.Day, (UINT32)EfiTime.Month, (UINT32)EfiTime.Year));
  117. //
  118. // Reset time value according to new RTC configuration
  119. //
  120. Status = gRT->SetTime (&EfiTime);
  121. ASSERT_EFI_ERROR(Status);
  122. }
  123. return;
  124. }