EFI_TIME Time;\r
UINTN DataSize;\r
UINT32 TimerVar;\r
+ BOOLEAN Enabled;\r
+ BOOLEAN Pending;\r
\r
//\r
// Acquire RTC Lock to make access to RTC atomic\r
// Reset time value according to new RTC configuration\r
//\r
Status = PcRtcSetTime (&Time, Global);\r
- if(!EFI_ERROR (Status)) {\r
+ if (EFI_ERROR (Status)) {\r
+ return EFI_DEVICE_ERROR;\r
+ }\r
+ \r
+ //\r
+ // Reset wakeup time value to valid state when wakeup alarm is disabled and wakeup time is invalid.\r
+ // Global variable has already had valid SavedTimeZone and Daylight,\r
+ // so we can use them to get and set wakeup time.\r
+ //\r
+ Status = PcRtcGetWakeupTime (&Enabled, &Pending, &Time, Global);\r
+ if ((Enabled) || (!EFI_ERROR (Status))) {\r
return EFI_SUCCESS;\r
- } else {\r
+ }\r
+ \r
+ //\r
+ // When wakeup time is disabled and invalid, reset wakeup time register to valid state \r
+ // but keep wakeup alarm disabled.\r
+ //\r
+ Time.Second = RTC_INIT_SECOND;\r
+ Time.Minute = RTC_INIT_MINUTE;\r
+ Time.Hour = RTC_INIT_HOUR;\r
+ Time.Day = RTC_INIT_DAY;\r
+ Time.Month = RTC_INIT_MONTH;\r
+ Time.Year = RTC_INIT_YEAR;\r
+ Time.Nanosecond = 0;\r
+ Time.TimeZone = Global->SavedTimeZone;\r
+ Time.Daylight = Global->Daylight;;\r
+\r
+ //\r
+ // Acquire RTC Lock to make access to RTC atomic\r
+ //\r
+ if (!EfiAtRuntime ()) {\r
+ EfiAcquireLock (&Global->RtcLock);\r
+ }\r
+ //\r
+ // Wait for up to 0.1 seconds for the RTC to be updated\r
+ //\r
+ Status = RtcWaitToUpdate (PcdGet32 (PcdRealTimeClockUpdateTimeout));\r
+ if (EFI_ERROR (Status)) {\r
+ if (!EfiAtRuntime ()) {\r
+ EfiReleaseLock (&Global->RtcLock);\r
+ }\r
return EFI_DEVICE_ERROR;\r
}\r
+ \r
+ ConvertEfiTimeToRtcTime (&Time, RegisterB, &Century);\r
+\r
+ //\r
+ // Set the Y/M/D info to variable as it has no corresponding hw registers.\r
+ //\r
+ Status = EfiSetVariable (\r
+ L"RTCALARM",\r
+ &gEfiCallerIdGuid,\r
+ EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,\r
+ sizeof (Time),\r
+ &Time\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ if (!EfiAtRuntime ()) {\r
+ EfiReleaseLock (&Global->RtcLock);\r
+ }\r
+ return EFI_DEVICE_ERROR;\r
+ }\r
+ \r
+ //\r
+ // Inhibit updates of the RTC\r
+ //\r
+ RegisterB.Bits.Set = 1;\r
+ RtcWrite (RTC_ADDRESS_REGISTER_B, RegisterB.Data);\r
+ \r
+ //\r
+ // Set RTC alarm time registers\r
+ //\r
+ RtcWrite (RTC_ADDRESS_SECONDS_ALARM, Time.Second);\r
+ RtcWrite (RTC_ADDRESS_MINUTES_ALARM, Time.Minute);\r
+ RtcWrite (RTC_ADDRESS_HOURS_ALARM, Time.Hour);\r
+\r
+ //\r
+ // Allow updates of the RTC registers\r
+ //\r
+ RegisterB.Bits.Set = 0;\r
+ RtcWrite (RTC_ADDRESS_REGISTER_B, RegisterB.Data);\r
+ \r
+ //\r
+ // Release RTC Lock.\r
+ //\r
+ if (!EfiAtRuntime ()) {\r
+ EfiReleaseLock (&Global->RtcLock);\r
+ }\r
+ return EFI_SUCCESS;\r
}\r
\r
/**\r