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
CharToUint(IN CHAR16 Char)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
CheckRtcTimeFields(IN EFI_TIME * Time)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
AdjustDefaultRtcTimeCallback(IN EFI_EVENT Event,IN VOID * Context)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