@@ -188,6 +188,67 @@ RtcWrite (
188
188
}
189
189
}
190
190
191
+ /**
192
+ Sets the current local timezone & daylight information.
193
+
194
+ @param TimeZone Timezone info.
195
+ @param Daylight Daylight info.
196
+ @param Global For global use inside this module.
197
+
198
+ @retval EFI_SUCCESS The operation completed successfully.
199
+ @retval EFI_DEVICE_ERROR The variable could not be set due due to hardware error.
200
+
201
+ **/
202
+ EFI_STATUS
203
+ PcRtcSetTimeZone (
204
+ IN INT16 TimeZone ,
205
+ IN UINT8 Daylight ,
206
+ IN PC_RTC_MODULE_GLOBALS * Global
207
+ )
208
+ {
209
+ EFI_STATUS Status ;
210
+ UINT32 TimerVar ;
211
+
212
+ ASSERT ((TimeZone == EFI_UNSPECIFIED_TIMEZONE ) || ((TimeZone >= -1440 ) && (TimeZone <= 1440 )));
213
+ ASSERT ((Daylight & (~(EFI_TIME_ADJUST_DAYLIGHT | EFI_TIME_IN_DAYLIGHT ))) == 0 );
214
+
215
+ //
216
+ // Write timezone and daylight to RTC variable
217
+ //
218
+ if ((TimeZone == EFI_UNSPECIFIED_TIMEZONE ) && (Daylight == 0 )) {
219
+ Status = EfiSetVariable (
220
+ mTimeZoneVariableName ,
221
+ & gEfiCallerIdGuid ,
222
+ 0 ,
223
+ 0 ,
224
+ NULL
225
+ );
226
+ if (Status == EFI_NOT_FOUND ) {
227
+ Status = EFI_SUCCESS ;
228
+ }
229
+ } else {
230
+ TimerVar = Daylight ;
231
+ TimerVar = (UINT32 )((TimerVar << 16 ) | (UINT16 )(TimeZone ));
232
+ Status = EfiSetVariable (
233
+ mTimeZoneVariableName ,
234
+ & gEfiCallerIdGuid ,
235
+ EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE ,
236
+ sizeof (TimerVar ),
237
+ & TimerVar
238
+ );
239
+ }
240
+
241
+ //
242
+ // Set the variable that contains the TimeZone and Daylight fields
243
+ //
244
+ if (!EFI_ERROR (Status )) {
245
+ Global -> SavedTimeZone = TimeZone ;
246
+ Global -> Daylight = Daylight ;
247
+ }
248
+
249
+ return Status ;
250
+ }
251
+
191
252
/**
192
253
Initialize RTC.
193
254
@@ -211,6 +272,9 @@ PcRtcInit (
211
272
UINT32 TimerVar ;
212
273
BOOLEAN Enabled ;
213
274
BOOLEAN Pending ;
275
+ BOOLEAN NeedRtcUpdate ;
276
+
277
+ NeedRtcUpdate = FALSE;
214
278
215
279
//
216
280
// Acquire RTC Lock to make access to RTC atomic
@@ -324,21 +388,32 @@ PcRtcInit (
324
388
Time .Nanosecond = 0 ;
325
389
Time .TimeZone = EFI_UNSPECIFIED_TIMEZONE ;
326
390
Time .Daylight = 0 ;
391
+ NeedRtcUpdate = TRUE;
327
392
}
328
393
329
394
//
330
395
// Set RTC configuration after get original time
331
396
// The value of bit AIE should be reserved.
332
397
//
333
- RegisterB .Data = FixedPcdGet8 (PcdInitialValueRtcRegisterB ) | (RegisterB .Data & BIT5 );
334
- RtcWrite (RTC_ADDRESS_REGISTER_B , RegisterB .Data );
398
+ if ((RegisterB .Data | BIT5 ) != (FixedPcdGet8 (PcdInitialValueRtcRegisterB ) | BIT5 )) {
399
+ RegisterB .Data = FixedPcdGet8 (PcdInitialValueRtcRegisterB ) | (RegisterB .Data & BIT5 );
400
+ RtcWrite (RTC_ADDRESS_REGISTER_B , RegisterB .Data );
401
+ NeedRtcUpdate = TRUE;
402
+ }
335
403
336
404
//
337
405
// Reset time value according to new RTC configuration
338
406
//
339
- Status = PcRtcSetTime (& Time , Global );
340
- if (EFI_ERROR (Status )) {
341
- return EFI_DEVICE_ERROR ;
407
+ if (NeedRtcUpdate ) {
408
+ Status = PcRtcSetTime (& Time , Global );
409
+ if (EFI_ERROR (Status )) {
410
+ return EFI_DEVICE_ERROR ;
411
+ }
412
+ } else {
413
+ Status = PcRtcSetTimeZone (Time .TimeZone , Time .Daylight , Global );
414
+ if (EFI_ERROR (Status )) {
415
+ return EFI_DEVICE_ERROR ;
416
+ }
342
417
}
343
418
344
419
//
@@ -563,7 +638,6 @@ PcRtcSetTime (
563
638
EFI_TIME RtcTime ;
564
639
RTC_REGISTER_A RegisterA ;
565
640
RTC_REGISTER_B RegisterB ;
566
- UINT32 TimerVar ;
567
641
568
642
if (Time == NULL ) {
569
643
return EFI_INVALID_PARAMETER ;
@@ -598,31 +672,7 @@ PcRtcSetTime (
598
672
return Status ;
599
673
}
600
674
601
- //
602
- // Write timezone and daylight to RTC variable
603
- //
604
- if ((Time -> TimeZone == EFI_UNSPECIFIED_TIMEZONE ) && (Time -> Daylight == 0 )) {
605
- Status = EfiSetVariable (
606
- mTimeZoneVariableName ,
607
- & gEfiCallerIdGuid ,
608
- 0 ,
609
- 0 ,
610
- NULL
611
- );
612
- if (Status == EFI_NOT_FOUND ) {
613
- Status = EFI_SUCCESS ;
614
- }
615
- } else {
616
- TimerVar = Time -> Daylight ;
617
- TimerVar = (UINT32 )((TimerVar << 16 ) | (UINT16 )(Time -> TimeZone ));
618
- Status = EfiSetVariable (
619
- mTimeZoneVariableName ,
620
- & gEfiCallerIdGuid ,
621
- EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE ,
622
- sizeof (TimerVar ),
623
- & TimerVar
624
- );
625
- }
675
+ Status = PcRtcSetTimeZone (Time -> TimeZone , Time -> Daylight , Global );
626
676
627
677
if (EFI_ERROR (Status )) {
628
678
if (!EfiAtRuntime ()) {
@@ -677,12 +727,6 @@ PcRtcSetTime (
677
727
EfiReleaseLock (& Global -> RtcLock );
678
728
}
679
729
680
- //
681
- // Set the variable that contains the TimeZone and Daylight fields
682
- //
683
- Global -> SavedTimeZone = Time -> TimeZone ;
684
- Global -> Daylight = Time -> Daylight ;
685
-
686
730
return EFI_SUCCESS ;
687
731
}
688
732
0 commit comments