/** @file\r
RTC Architectural Protocol GUID as defined in DxeCis 0.96.\r
\r
-Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.<BR>\r
-This program and the accompanying materials\r
-are licensed and made available under the terms and conditions of the BSD License\r
-which accompanies this distribution. The full text of the license may be found at\r
-http://opensource.org/licenses/bsd-license.php\r
+Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2017, AMD Inc. All rights reserved.<BR>\r
+Copyright (c) 2018 - 2020, ARM Limited. All rights reserved.<BR>\r
\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
\r
**/\r
\r
#include "PcRtc.h"\r
\r
+extern UINTN mRtcIndexRegister;\r
+extern UINTN mRtcTargetRegister;\r
+\r
+//\r
+// Days of month.\r
+//\r
+UINTN mDayOfMonth[] = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };\r
+\r
+//\r
+// The name of NV variable to store the timezone and daylight saving information.\r
+//\r
+CHAR16 mTimeZoneVariableName[] = L"RTC";\r
+\r
/**\r
Compare the Hour, Minute and Second of the From time and the To time.\r
- \r
+\r
Only compare H/M/S in EFI_TIME and ignore other fields here.\r
\r
@param From the first time\r
**/\r
INTN\r
CompareHMS (\r
- IN EFI_TIME *From,\r
- IN EFI_TIME *To\r
+ IN EFI_TIME *From,\r
+ IN EFI_TIME *To\r
);\r
\r
/**\r
**/\r
BOOLEAN\r
IsWithinOneDay (\r
- IN EFI_TIME *From,\r
- IN EFI_TIME *To\r
+ IN EFI_TIME *From,\r
+ IN EFI_TIME *To\r
);\r
\r
+/**\r
+ Read RTC content through its registers using IO access.\r
+\r
+ @param Address Address offset of RTC. It is recommended to use\r
+ macros such as RTC_ADDRESS_SECONDS.\r
+\r
+ @return The data of UINT8 type read from RTC.\r
+**/\r
+STATIC\r
+UINT8\r
+IoRtcRead (\r
+ IN UINTN Address\r
+ )\r
+{\r
+ IoWrite8 (\r
+ PcdGet8 (PcdRtcIndexRegister),\r
+ (UINT8)(Address | (UINT8)(IoRead8 (PcdGet8 (PcdRtcIndexRegister)) & 0x80))\r
+ );\r
+ return IoRead8 (PcdGet8 (PcdRtcTargetRegister));\r
+}\r
+\r
+/**\r
+ Write RTC through its registers using IO access.\r
+\r
+ @param Address Address offset of RTC. It is recommended to use\r
+ macros such as RTC_ADDRESS_SECONDS.\r
+ @param Data The content you want to write into RTC.\r
+\r
+**/\r
+STATIC\r
+VOID\r
+IoRtcWrite (\r
+ IN UINTN Address,\r
+ IN UINT8 Data\r
+ )\r
+{\r
+ IoWrite8 (\r
+ PcdGet8 (PcdRtcIndexRegister),\r
+ (UINT8)(Address | (UINT8)(IoRead8 (PcdGet8 (PcdRtcIndexRegister)) & 0x80))\r
+ );\r
+ IoWrite8 (PcdGet8 (PcdRtcTargetRegister), Data);\r
+}\r
+\r
+/**\r
+ Read RTC content through its registers using MMIO access.\r
+\r
+ @param Address Address offset of RTC. It is recommended to use\r
+ macros such as RTC_ADDRESS_SECONDS.\r
+\r
+ @return The data of UINT8 type read from RTC.\r
+**/\r
+STATIC\r
+UINT8\r
+MmioRtcRead (\r
+ IN UINTN Address\r
+ )\r
+{\r
+ MmioWrite8 (\r
+ mRtcIndexRegister,\r
+ (UINT8)(Address | (UINT8)(MmioRead8 (mRtcIndexRegister) & 0x80))\r
+ );\r
+ return MmioRead8 (mRtcTargetRegister);\r
+}\r
+\r
+/**\r
+ Write RTC through its registers using MMIO access.\r
+\r
+ @param Address Address offset of RTC. It is recommended to use\r
+ macros such as RTC_ADDRESS_SECONDS.\r
+ @param Data The content you want to write into RTC.\r
+\r
+**/\r
+STATIC\r
+VOID\r
+MmioRtcWrite (\r
+ IN UINTN Address,\r
+ IN UINT8 Data\r
+ )\r
+{\r
+ MmioWrite8 (\r
+ mRtcIndexRegister,\r
+ (UINT8)(Address | (UINT8)(MmioRead8 (mRtcIndexRegister) & 0x80))\r
+ );\r
+ MmioWrite8 (mRtcTargetRegister, Data);\r
+}\r
+\r
/**\r
Read RTC content through its registers.\r
\r
- @param Address Address offset of RTC. It is recommended to use macros such as\r
- RTC_ADDRESS_SECONDS.\r
+ @param Address Address offset of RTC. It is recommended to use\r
+ macros such as RTC_ADDRESS_SECONDS.\r
\r
@return The data of UINT8 type read from RTC.\r
**/\r
+STATIC\r
UINT8\r
RtcRead (\r
- IN UINT8 Address\r
+ IN UINTN Address\r
)\r
{\r
- IoWrite8 (PCAT_RTC_ADDRESS_REGISTER, (UINT8) (Address | (UINT8) (IoRead8 (PCAT_RTC_ADDRESS_REGISTER) & 0x80)));\r
- return IoRead8 (PCAT_RTC_DATA_REGISTER);\r
+ if (FeaturePcdGet (PcdRtcUseMmio)) {\r
+ return MmioRtcRead (Address);\r
+ }\r
+\r
+ return IoRtcRead (Address);\r
}\r
\r
/**\r
Write RTC through its registers.\r
\r
- @param Address Address offset of RTC. It is recommended to use macros such as\r
- RTC_ADDRESS_SECONDS.\r
- @param Data The content you want to write into RTC.\r
+ @param Address Address offset of RTC. It is recommended to use\r
+ macros such as RTC_ADDRESS_SECONDS.\r
+ @param Data The content you want to write into RTC.\r
\r
**/\r
+STATIC\r
VOID\r
RtcWrite (\r
- IN UINT8 Address,\r
- IN UINT8 Data\r
+ IN UINTN Address,\r
+ IN UINT8 Data\r
)\r
{\r
- IoWrite8 (PCAT_RTC_ADDRESS_REGISTER, (UINT8) (Address | (UINT8) (IoRead8 (PCAT_RTC_ADDRESS_REGISTER) & 0x80)));\r
- IoWrite8 (PCAT_RTC_DATA_REGISTER, Data);\r
+ if (FeaturePcdGet (PcdRtcUseMmio)) {\r
+ MmioRtcWrite (Address, Data);\r
+ } else {\r
+ IoRtcWrite (Address, Data);\r
+ }\r
}\r
\r
/**\r
if (!EfiAtRuntime ()) {\r
EfiAcquireLock (&Global->RtcLock);\r
}\r
+\r
//\r
// Initialize RTC Register\r
//\r
// Make sure Division Chain is properly configured,\r
// or RTC clock won't "tick" -- time won't increment\r
//\r
- RegisterA.Data = RTC_INIT_REGISTER_A;\r
+ RegisterA.Data = FixedPcdGet8 (PcdInitialValueRtcRegisterA);\r
RtcWrite (RTC_ADDRESS_REGISTER_A, RegisterA.Data);\r
\r
//\r
//\r
// Clear RTC register D\r
//\r
- RegisterD.Data = RTC_INIT_REGISTER_D;\r
+ RegisterD.Data = FixedPcdGet8 (PcdInitialValueRtcRegisterD);\r
RtcWrite (RTC_ADDRESS_REGISTER_D, RegisterD.Data);\r
\r
//\r
if (!EfiAtRuntime ()) {\r
EfiReleaseLock (&Global->RtcLock);\r
}\r
+\r
return EFI_DEVICE_ERROR;\r
}\r
+\r
//\r
// Get the Time/Date/Daylight Savings values.\r
//\r
Time.Month = RtcRead (RTC_ADDRESS_MONTH);\r
Time.Year = RtcRead (RTC_ADDRESS_YEAR);\r
\r
- //\r
- // Set RTC configuration after get original time\r
- // The value of bit AIE should be reserved.\r
- //\r
- RegisterB.Data = RTC_INIT_REGISTER_B | (RegisterB.Data & BIT5);\r
- RtcWrite (RTC_ADDRESS_REGISTER_B, RegisterB.Data);\r
-\r
//\r
// Release RTC Lock.\r
//\r
if (!EfiAtRuntime ()) {\r
EfiReleaseLock (&Global->RtcLock);\r
}\r
- \r
+\r
//\r
// Get the data of Daylight saving and time zone, if they have been\r
// stored in NV variable during previous boot.\r
//\r
DataSize = sizeof (UINT32);\r
- Status = EfiGetVariable (\r
- L"RTC",\r
- &gEfiCallerIdGuid,\r
- NULL,\r
- &DataSize,\r
- (VOID *) &TimerVar\r
- );\r
+ Status = EfiGetVariable (\r
+ mTimeZoneVariableName,\r
+ &gEfiCallerIdGuid,\r
+ NULL,\r
+ &DataSize,\r
+ &TimerVar\r
+ );\r
if (!EFI_ERROR (Status)) {\r
- Time.TimeZone = (INT16) TimerVar;\r
- Time.Daylight = (UINT8) (TimerVar >> 16);\r
+ Time.TimeZone = (INT16)TimerVar;\r
+ Time.Daylight = (UINT8)(TimerVar >> 16);\r
} else {\r
Time.TimeZone = EFI_UNSPECIFIED_TIMEZONE;\r
- Time.Daylight = 0; \r
+ Time.Daylight = 0;\r
}\r
\r
//\r
if (!EFI_ERROR (Status)) {\r
Status = RtcTimeFieldsValid (&Time);\r
}\r
+\r
if (EFI_ERROR (Status)) {\r
//\r
// Report Status Code to indicate that the RTC has bad date and time\r
EFI_ERROR_CODE | EFI_ERROR_MINOR,\r
(EFI_SOFTWARE_DXE_RT_DRIVER | EFI_SW_EC_BAD_DATE_TIME)\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 = PcdGet16 (PcdMinimalValidYear);\r
- Time.Nanosecond = 0;\r
- Time.TimeZone = EFI_UNSPECIFIED_TIMEZONE;\r
- Time.Daylight = 0;\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 = PcdGet16 (PcdMinimalValidYear);\r
+ Time.Nanosecond = 0;\r
+ Time.TimeZone = EFI_UNSPECIFIED_TIMEZONE;\r
+ Time.Daylight = 0;\r
}\r
\r
+ //\r
+ // Set RTC configuration after get original time\r
+ // The value of bit AIE should be reserved.\r
+ //\r
+ RegisterB.Data = FixedPcdGet8 (PcdInitialValueRtcRegisterB) | (RegisterB.Data & BIT5);\r
+ RtcWrite (RTC_ADDRESS_REGISTER_B, RegisterB.Data);\r
+\r
//\r
// Reset time value according to new RTC configuration\r
//\r
if (EFI_ERROR (Status)) {\r
return EFI_DEVICE_ERROR;\r
}\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
if ((Enabled) || (!EFI_ERROR (Status))) {\r
return EFI_SUCCESS;\r
}\r
- \r
+\r
//\r
- // When wakeup time is disabled and invalid, reset wakeup time register to valid state \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 = PcdGet16 (PcdMinimalValidYear);\r
- Time.Nanosecond = 0;\r
- Time.TimeZone = Global->SavedTimeZone;\r
- Time.Daylight = Global->Daylight;;\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 = PcdGet16 (PcdMinimalValidYear);\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
if (!EfiAtRuntime ()) {\r
EfiAcquireLock (&Global->RtcLock);\r
}\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
+ EfiReleaseLock (&Global->RtcLock);\r
}\r
+\r
return EFI_DEVICE_ERROR;\r
}\r
\r
if (!EfiAtRuntime ()) {\r
EfiReleaseLock (&Global->RtcLock);\r
}\r
+\r
return EFI_DEVICE_ERROR;\r
}\r
- \r
+\r
//\r
// Inhibit updates of the RTC\r
//\r
- RegisterB.Bits.Set = 1;\r
+ RegisterB.Bits.Set = 1;\r
RtcWrite (RTC_ADDRESS_REGISTER_B, RegisterB.Data);\r
- \r
+\r
//\r
// Set RTC alarm time registers\r
//\r
//\r
RegisterB.Bits.Set = 0;\r
RtcWrite (RTC_ADDRESS_REGISTER_B, RegisterB.Data);\r
- \r
+\r
//\r
// Release RTC Lock.\r
//\r
if (!EfiAtRuntime ()) {\r
EfiReleaseLock (&Global->RtcLock);\r
}\r
+\r
return EFI_SUCCESS;\r
}\r
\r
EFI_STATUS\r
PcRtcGetTime (\r
OUT EFI_TIME *Time,\r
- OUT EFI_TIME_CAPABILITIES *Capabilities, OPTIONAL\r
+ OUT EFI_TIME_CAPABILITIES *Capabilities OPTIONAL,\r
IN PC_RTC_MODULE_GLOBALS *Global\r
)\r
{\r
//\r
if (Time == NULL) {\r
return EFI_INVALID_PARAMETER;\r
-\r
}\r
+\r
//\r
// Acquire RTC Lock to make access to RTC atomic\r
//\r
if (!EfiAtRuntime ()) {\r
EfiAcquireLock (&Global->RtcLock);\r
}\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
+ if (!EfiAtRuntime ()) {\r
+ EfiReleaseLock (&Global->RtcLock);\r
+ }\r
+\r
return Status;\r
}\r
+\r
//\r
// Read Register B\r
//\r
//\r
// Get the Time/Date/Daylight Savings values.\r
//\r
- Time->Second = RtcRead (RTC_ADDRESS_SECONDS);\r
- Time->Minute = RtcRead (RTC_ADDRESS_MINUTES);\r
- Time->Hour = RtcRead (RTC_ADDRESS_HOURS);\r
- Time->Day = RtcRead (RTC_ADDRESS_DAY_OF_THE_MONTH);\r
- Time->Month = RtcRead (RTC_ADDRESS_MONTH);\r
- Time->Year = RtcRead (RTC_ADDRESS_YEAR);\r
+ Time->Second = RtcRead (RTC_ADDRESS_SECONDS);\r
+ Time->Minute = RtcRead (RTC_ADDRESS_MINUTES);\r
+ Time->Hour = RtcRead (RTC_ADDRESS_HOURS);\r
+ Time->Day = RtcRead (RTC_ADDRESS_DAY_OF_THE_MONTH);\r
+ Time->Month = RtcRead (RTC_ADDRESS_MONTH);\r
+ Time->Year = RtcRead (RTC_ADDRESS_YEAR);\r
\r
//\r
// Release RTC Lock.\r
//\r
// Get the variable that contains the TimeZone and Daylight fields\r
//\r
- Time->TimeZone = Global->SavedTimeZone;\r
- Time->Daylight = Global->Daylight;\r
+ Time->TimeZone = Global->SavedTimeZone;\r
+ Time->Daylight = Global->Daylight;\r
\r
//\r
// Make sure all field values are in correct range\r
if (!EFI_ERROR (Status)) {\r
Status = RtcTimeFieldsValid (Time);\r
}\r
+\r
if (EFI_ERROR (Status)) {\r
return EFI_DEVICE_ERROR;\r
}\r
**/\r
EFI_STATUS\r
PcRtcSetTime (\r
- IN EFI_TIME *Time,\r
- IN PC_RTC_MODULE_GLOBALS *Global\r
+ IN EFI_TIME *Time,\r
+ IN PC_RTC_MODULE_GLOBALS *Global\r
)\r
{\r
EFI_STATUS Status;\r
if (Time == NULL) {\r
return EFI_INVALID_PARAMETER;\r
}\r
+\r
//\r
// Make sure that the time fields are valid\r
//\r
if (!EfiAtRuntime ()) {\r
EfiAcquireLock (&Global->RtcLock);\r
}\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
+ if (!EfiAtRuntime ()) {\r
+ EfiReleaseLock (&Global->RtcLock);\r
+ }\r
+\r
return Status;\r
}\r
- \r
+\r
//\r
// Write timezone and daylight to RTC variable\r
//\r
- TimerVar = Time->Daylight;\r
- TimerVar = (UINT32) ((TimerVar << 16) | (UINT16)(Time->TimeZone));\r
- Status = EfiSetVariable (\r
- L"RTC",\r
- &gEfiCallerIdGuid,\r
- EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,\r
- sizeof (TimerVar),\r
- &TimerVar\r
- );\r
+ if ((Time->TimeZone == EFI_UNSPECIFIED_TIMEZONE) && (Time->Daylight == 0)) {\r
+ Status = EfiSetVariable (\r
+ mTimeZoneVariableName,\r
+ &gEfiCallerIdGuid,\r
+ 0,\r
+ 0,\r
+ NULL\r
+ );\r
+ if (Status == EFI_NOT_FOUND) {\r
+ Status = EFI_SUCCESS;\r
+ }\r
+ } else {\r
+ TimerVar = Time->Daylight;\r
+ TimerVar = (UINT32)((TimerVar << 16) | (UINT16)(Time->TimeZone));\r
+ Status = EfiSetVariable (\r
+ mTimeZoneVariableName,\r
+ &gEfiCallerIdGuid,\r
+ EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,\r
+ sizeof (TimerVar),\r
+ &TimerVar\r
+ );\r
+ }\r
+\r
if (EFI_ERROR (Status)) {\r
if (!EfiAtRuntime ()) {\r
EfiReleaseLock (&Global->RtcLock);\r
}\r
+\r
return EFI_DEVICE_ERROR;\r
}\r
\r
//\r
// Read Register B, and inhibit updates of the RTC\r
//\r
- RegisterB.Data = RtcRead (RTC_ADDRESS_REGISTER_B);\r
- RegisterB.Bits.Set = 1;\r
+ RegisterB.Data = RtcRead (RTC_ADDRESS_REGISTER_B);\r
+ RegisterB.Bits.Set = 1;\r
RtcWrite (RTC_ADDRESS_REGISTER_B, RegisterB.Data);\r
\r
//\r
// Store the century value to RTC before converting to BCD format.\r
//\r
if (Global->CenturyRtcAddress != 0) {\r
- RtcWrite (Global->CenturyRtcAddress, DecimalToBcd8 ((UINT8) (RtcTime.Year / 100)));\r
+ RtcWrite (Global->CenturyRtcAddress, DecimalToBcd8 ((UINT8)(RtcTime.Year / 100)));\r
}\r
\r
ConvertEfiTimeToRtcTime (&RtcTime, RegisterB);\r
RtcWrite (RTC_ADDRESS_HOURS, RtcTime.Hour);\r
RtcWrite (RTC_ADDRESS_DAY_OF_THE_MONTH, RtcTime.Day);\r
RtcWrite (RTC_ADDRESS_MONTH, RtcTime.Month);\r
- RtcWrite (RTC_ADDRESS_YEAR, (UINT8) RtcTime.Year);\r
+ RtcWrite (RTC_ADDRESS_YEAR, (UINT8)RtcTime.Year);\r
\r
//\r
// Allow updates of the RTC registers\r
if (!EfiAtRuntime ()) {\r
EfiReleaseLock (&Global->RtcLock);\r
}\r
+\r
//\r
// Set the variable that contains the TimeZone and Daylight fields\r
//\r
//\r
if ((Enabled == NULL) || (Pending == NULL) || (Time == NULL)) {\r
return EFI_INVALID_PARAMETER;\r
-\r
}\r
+\r
//\r
// Acquire RTC Lock to make access to RTC atomic\r
//\r
if (!EfiAtRuntime ()) {\r
EfiAcquireLock (&Global->RtcLock);\r
}\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
+ EfiReleaseLock (&Global->RtcLock);\r
}\r
+\r
return EFI_DEVICE_ERROR;\r
}\r
+\r
//\r
// Read Register B and Register C\r
//\r
- RegisterB.Data = RtcRead (RTC_ADDRESS_REGISTER_B);\r
- RegisterC.Data = RtcRead (RTC_ADDRESS_REGISTER_C);\r
+ RegisterB.Data = RtcRead (RTC_ADDRESS_REGISTER_B);\r
+ RegisterC.Data = RtcRead (RTC_ADDRESS_REGISTER_C);\r
\r
//\r
// Get the Time/Date/Daylight Savings values.\r
*Enabled = RegisterB.Bits.Aie;\r
*Pending = RegisterC.Bits.Af;\r
\r
- Time->Second = RtcRead (RTC_ADDRESS_SECONDS_ALARM);\r
- Time->Minute = RtcRead (RTC_ADDRESS_MINUTES_ALARM);\r
- Time->Hour = RtcRead (RTC_ADDRESS_HOURS_ALARM);\r
- Time->Day = RtcRead (RTC_ADDRESS_DAY_OF_THE_MONTH);\r
- Time->Month = RtcRead (RTC_ADDRESS_MONTH);\r
- Time->Year = RtcRead (RTC_ADDRESS_YEAR);\r
+ Time->Second = RtcRead (RTC_ADDRESS_SECONDS_ALARM);\r
+ Time->Minute = RtcRead (RTC_ADDRESS_MINUTES_ALARM);\r
+ Time->Hour = RtcRead (RTC_ADDRESS_HOURS_ALARM);\r
+ Time->Day = RtcRead (RTC_ADDRESS_DAY_OF_THE_MONTH);\r
+ Time->Month = RtcRead (RTC_ADDRESS_MONTH);\r
+ Time->Year = RtcRead (RTC_ADDRESS_YEAR);\r
Time->TimeZone = Global->SavedTimeZone;\r
Time->Daylight = Global->Daylight;\r
\r
// Get the alarm info from variable\r
//\r
DataSize = sizeof (EFI_TIME);\r
- Status = EfiGetVariable (\r
- L"RTCALARM",\r
- &gEfiCallerIdGuid,\r
- NULL,\r
- &DataSize,\r
- &RtcTime\r
- );\r
+ Status = EfiGetVariable (\r
+ L"RTCALARM",\r
+ &gEfiCallerIdGuid,\r
+ NULL,\r
+ &DataSize,\r
+ &RtcTime\r
+ );\r
if (!EFI_ERROR (Status)) {\r
//\r
// The alarm variable exists. In this case, we read variable to get info.\r
if (!EFI_ERROR (Status)) {\r
Status = RtcTimeFieldsValid (Time);\r
}\r
+\r
if (EFI_ERROR (Status)) {\r
return EFI_DEVICE_ERROR;\r
}\r
EFI_STATUS\r
PcRtcSetWakeupTime (\r
IN BOOLEAN Enable,\r
- IN EFI_TIME *Time, OPTIONAL\r
+ IN EFI_TIME *Time OPTIONAL,\r
IN PC_RTC_MODULE_GLOBALS *Global\r
)\r
{\r
- EFI_STATUS Status;\r
- EFI_TIME RtcTime;\r
- RTC_REGISTER_B RegisterB;\r
- EFI_TIME_CAPABILITIES Capabilities;\r
+ EFI_STATUS Status;\r
+ EFI_TIME RtcTime;\r
+ RTC_REGISTER_B RegisterB;\r
+ EFI_TIME_CAPABILITIES Capabilities;\r
\r
ZeroMem (&RtcTime, sizeof (RtcTime));\r
\r
if (Enable) {\r
-\r
if (Time == NULL) {\r
return EFI_INVALID_PARAMETER;\r
}\r
+\r
//\r
// Make sure that the time fields are valid\r
//\r
if (EFI_ERROR (Status)) {\r
return EFI_INVALID_PARAMETER;\r
}\r
+\r
//\r
// Just support set alarm time within 24 hours\r
//\r
if (EFI_ERROR (Status)) {\r
return EFI_DEVICE_ERROR;\r
}\r
+\r
if (!IsWithinOneDay (&RtcTime, Time)) {\r
return EFI_UNSUPPORTED;\r
}\r
+\r
//\r
// Make a local copy of the time and date\r
//\r
CopyMem (&RtcTime, Time, sizeof (EFI_TIME));\r
-\r
}\r
+\r
//\r
// Acquire RTC Lock to make access to RTC atomic\r
//\r
if (!EfiAtRuntime ()) {\r
EfiAcquireLock (&Global->RtcLock);\r
}\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
+ EfiReleaseLock (&Global->RtcLock);\r
}\r
+\r
return EFI_DEVICE_ERROR;\r
}\r
+\r
//\r
// Read Register B\r
//\r
//\r
// if the alarm is disable, record the current setting.\r
//\r
- RtcTime.Second = RtcRead (RTC_ADDRESS_SECONDS_ALARM);\r
- RtcTime.Minute = RtcRead (RTC_ADDRESS_MINUTES_ALARM);\r
- RtcTime.Hour = RtcRead (RTC_ADDRESS_HOURS_ALARM);\r
- RtcTime.Day = RtcRead (RTC_ADDRESS_DAY_OF_THE_MONTH);\r
- RtcTime.Month = RtcRead (RTC_ADDRESS_MONTH);\r
- RtcTime.Year = RtcRead (RTC_ADDRESS_YEAR);\r
+ RtcTime.Second = RtcRead (RTC_ADDRESS_SECONDS_ALARM);\r
+ RtcTime.Minute = RtcRead (RTC_ADDRESS_MINUTES_ALARM);\r
+ RtcTime.Hour = RtcRead (RTC_ADDRESS_HOURS_ALARM);\r
+ RtcTime.Day = RtcRead (RTC_ADDRESS_DAY_OF_THE_MONTH);\r
+ RtcTime.Month = RtcRead (RTC_ADDRESS_MONTH);\r
+ RtcTime.Year = RtcRead (RTC_ADDRESS_YEAR);\r
RtcTime.TimeZone = Global->SavedTimeZone;\r
RtcTime.Daylight = Global->Daylight;\r
}\r
if (!EfiAtRuntime ()) {\r
EfiReleaseLock (&Global->RtcLock);\r
}\r
+\r
return EFI_DEVICE_ERROR;\r
}\r
- \r
+\r
//\r
// Inhibit updates of the RTC\r
//\r
- RegisterB.Bits.Set = 1;\r
+ RegisterB.Bits.Set = 1;\r
RtcWrite (RTC_ADDRESS_REGISTER_B, RegisterB.Data);\r
\r
if (Enable) {\r
RtcWrite (RTC_ADDRESS_HOURS_ALARM, RtcTime.Hour);\r
\r
RegisterB.Bits.Aie = 1;\r
-\r
} else {\r
RegisterB.Bits.Aie = 0;\r
}\r
+\r
//\r
// Allow updates of the RTC registers\r
//\r
if (!EfiAtRuntime ()) {\r
EfiReleaseLock (&Global->RtcLock);\r
}\r
+\r
return EFI_SUCCESS;\r
}\r
\r
-\r
/**\r
Checks an 8-bit BCD value, and converts to an 8-bit value if valid.\r
\r
IN RTC_REGISTER_B RegisterB\r
)\r
{\r
- BOOLEAN IsPM;\r
- UINT8 Century;\r
+ BOOLEAN IsPM;\r
+ UINT8 Century;\r
\r
- if ((Time->Hour & 0x80) != 0) {\r
- IsPM = TRUE;\r
- } else {\r
- IsPM = FALSE;\r
- }\r
+ // IsPM only makes sense for 12-hour format.\r
+ if (RegisterB.Bits.Mil == 0) {\r
+ if ((Time->Hour & 0x80) != 0) {\r
+ IsPM = TRUE;\r
+ } else {\r
+ IsPM = FALSE;\r
+ }\r
\r
- Time->Hour = (UINT8) (Time->Hour & 0x7f);\r
+ Time->Hour = (UINT8)(Time->Hour & 0x7f);\r
+ }\r
\r
if (RegisterB.Bits.Dm == 0) {\r
- Time->Year = CheckAndConvertBcd8ToDecimal8 ((UINT8) Time->Year);\r
- Time->Month = CheckAndConvertBcd8ToDecimal8 (Time->Month);\r
- Time->Day = CheckAndConvertBcd8ToDecimal8 (Time->Day);\r
- Time->Hour = CheckAndConvertBcd8ToDecimal8 (Time->Hour);\r
- Time->Minute = CheckAndConvertBcd8ToDecimal8 (Time->Minute);\r
- Time->Second = CheckAndConvertBcd8ToDecimal8 (Time->Second);\r
+ Time->Year = CheckAndConvertBcd8ToDecimal8 ((UINT8)Time->Year);\r
+ Time->Month = CheckAndConvertBcd8ToDecimal8 (Time->Month);\r
+ Time->Day = CheckAndConvertBcd8ToDecimal8 (Time->Day);\r
+ Time->Hour = CheckAndConvertBcd8ToDecimal8 (Time->Hour);\r
+ Time->Minute = CheckAndConvertBcd8ToDecimal8 (Time->Minute);\r
+ Time->Second = CheckAndConvertBcd8ToDecimal8 (Time->Second);\r
}\r
\r
- if (Time->Year == 0xff || Time->Month == 0xff || Time->Day == 0xff ||\r
- Time->Hour == 0xff || Time->Minute == 0xff || Time->Second == 0xff) {\r
+ if ((Time->Year == 0xff) || (Time->Month == 0xff) || (Time->Day == 0xff) ||\r
+ (Time->Hour == 0xff) || (Time->Minute == 0xff) || (Time->Second == 0xff))\r
+ {\r
return EFI_INVALID_PARAMETER;\r
}\r
\r
// Century is 19 if RTC year >= 70,\r
// Century is 20 otherwise.\r
//\r
- Century = (UINT8) (PcdGet16 (PcdMinimalValidYear) / 100);\r
+ Century = (UINT8)(PcdGet16 (PcdMinimalValidYear) / 100);\r
if (Time->Year < PcdGet16 (PcdMinimalValidYear) % 100) {\r
Century++;\r
}\r
- Time->Year = (UINT16) (Century * 100 + Time->Year);\r
+\r
+ Time->Year = (UINT16)(Century * 100 + Time->Year);\r
\r
//\r
// If time is in 12 hour format, convert it to 24 hour format\r
//\r
if (RegisterB.Bits.Mil == 0) {\r
- if (IsPM && Time->Hour < 12) {\r
- Time->Hour = (UINT8) (Time->Hour + 12);\r
+ if (IsPM && (Time->Hour < 12)) {\r
+ Time->Hour = (UINT8)(Time->Hour + 12);\r
}\r
\r
- if (!IsPM && Time->Hour == 12) {\r
+ if (!IsPM && (Time->Hour == 12)) {\r
Time->Hour = 0;\r
}\r
}\r
\r
- Time->Nanosecond = 0;\r
+ Time->Nanosecond = 0;\r
\r
return EFI_SUCCESS;\r
}\r
@param Timeout Tell how long it should take to wait.\r
\r
@retval EFI_DEVICE_ERROR RTC device error.\r
- @retval EFI_SUCCESS RTC is updated and ready. \r
+ @retval EFI_SUCCESS RTC is updated and ready.\r
**/\r
EFI_STATUS\r
RtcWaitToUpdate (\r
- UINTN Timeout\r
+ UINTN Timeout\r
)\r
{\r
RTC_REGISTER_A RegisterA;\r
if (RegisterD.Bits.Vrt == 0) {\r
return EFI_DEVICE_ERROR;\r
}\r
+\r
//\r
// Wait for up to 0.1 seconds for the RTC to be ready.\r
//\r
- Timeout = (Timeout / 10) + 1;\r
- RegisterA.Data = RtcRead (RTC_ADDRESS_REGISTER_A);\r
+ Timeout = (Timeout / 10) + 1;\r
+ RegisterA.Data = RtcRead (RTC_ADDRESS_REGISTER_A);\r
while (RegisterA.Bits.Uip == 1 && Timeout > 0) {\r
MicroSecondDelay (10);\r
RegisterA.Data = RtcRead (RTC_ADDRESS_REGISTER_A);\r
}\r
\r
RegisterD.Data = RtcRead (RTC_ADDRESS_REGISTER_D);\r
- if (Timeout == 0 || RegisterD.Bits.Vrt == 0) {\r
+ if ((Timeout == 0) || (RegisterD.Bits.Vrt == 0)) {\r
return EFI_DEVICE_ERROR;\r
}\r
\r
**/\r
EFI_STATUS\r
RtcTimeFieldsValid (\r
- IN EFI_TIME *Time\r
+ IN EFI_TIME *Time\r
)\r
{\r
- if (Time->Year < PcdGet16 (PcdMinimalValidYear) ||\r
- Time->Year > PcdGet16 (PcdMaximalValidYear) ||\r
- Time->Month < 1 ||\r
- Time->Month > 12 ||\r
+ if ((Time->Year < PcdGet16 (PcdMinimalValidYear)) ||\r
+ (Time->Year > PcdGet16 (PcdMaximalValidYear)) ||\r
+ (Time->Month < 1) ||\r
+ (Time->Month > 12) ||\r
(!DayValid (Time)) ||\r
- Time->Hour > 23 ||\r
- Time->Minute > 59 ||\r
- Time->Second > 59 ||\r
- Time->Nanosecond > 999999999 ||\r
- (!(Time->TimeZone == EFI_UNSPECIFIED_TIMEZONE || (Time->TimeZone >= -1440 && Time->TimeZone <= 1440))) ||\r
- ((Time->Daylight & (~(EFI_TIME_ADJUST_DAYLIGHT | EFI_TIME_IN_DAYLIGHT))) != 0)) {\r
+ (Time->Hour > 23) ||\r
+ (Time->Minute > 59) ||\r
+ (Time->Second > 59) ||\r
+ (Time->Nanosecond > 999999999) ||\r
+ (!((Time->TimeZone == EFI_UNSPECIFIED_TIMEZONE) || ((Time->TimeZone >= -1440) && (Time->TimeZone <= 1440)))) ||\r
+ ((Time->Daylight & (~(EFI_TIME_ADJUST_DAYLIGHT | EFI_TIME_IN_DAYLIGHT))) != 0))\r
+ {\r
return EFI_INVALID_PARAMETER;\r
}\r
\r
IN EFI_TIME *Time\r
)\r
{\r
- INTN DayOfMonth[12];\r
-\r
- DayOfMonth[0] = 31;\r
- DayOfMonth[1] = 29;\r
- DayOfMonth[2] = 31;\r
- DayOfMonth[3] = 30;\r
- DayOfMonth[4] = 31;\r
- DayOfMonth[5] = 30;\r
- DayOfMonth[6] = 31;\r
- DayOfMonth[7] = 31;\r
- DayOfMonth[8] = 30;\r
- DayOfMonth[9] = 31;\r
- DayOfMonth[10] = 30;\r
- DayOfMonth[11] = 31;\r
-\r
//\r
// The validity of Time->Month field should be checked before\r
//\r
- ASSERT (Time->Month >=1);\r
- ASSERT (Time->Month <=12);\r
- if (Time->Day < 1 ||\r
- Time->Day > DayOfMonth[Time->Month - 1] ||\r
- (Time->Month == 2 && (!IsLeapYear (Time) && Time->Day > 28))\r
- ) {\r
+ ASSERT (Time->Month >= 1);\r
+ ASSERT (Time->Month <= 12);\r
+ if ((Time->Day < 1) ||\r
+ (Time->Day > mDayOfMonth[Time->Month - 1]) ||\r
+ ((Time->Month == 2) && (!IsLeapYear (Time) && (Time->Day > 28)))\r
+ )\r
+ {\r
return FALSE;\r
}\r
\r
**/\r
BOOLEAN\r
IsLeapYear (\r
- IN EFI_TIME *Time\r
+ IN EFI_TIME *Time\r
)\r
{\r
if (Time->Year % 4 == 0) {\r
}\r
\r
/**\r
- Converts time from EFI_TIME format defined by UEFI spec to RTC's.\r
+ Converts time from EFI_TIME format defined by UEFI spec to RTC format.\r
\r
- This function converts time from EFI_TIME format defined by UEFI spec to RTC's.\r
+ This function converts time from EFI_TIME format defined by UEFI spec to RTC format.\r
If data mode of RTC is BCD, then converts EFI_TIME to it.\r
If RTC is in 12-hour format, then converts EFI_TIME to it.\r
\r
IN RTC_REGISTER_B RegisterB\r
)\r
{\r
- BOOLEAN IsPM;\r
+ BOOLEAN IsPM;\r
\r
IsPM = TRUE;\r
//\r
}\r
\r
if (Time->Hour >= 13) {\r
- Time->Hour = (UINT8) (Time->Hour - 12);\r
+ Time->Hour = (UINT8)(Time->Hour - 12);\r
} else if (Time->Hour == 0) {\r
Time->Hour = 12;\r
}\r
}\r
+\r
//\r
// Set the Time/Date values.\r
//\r
- Time->Year = (UINT16) (Time->Year % 100);\r
+ Time->Year = (UINT16)(Time->Year % 100);\r
\r
if (RegisterB.Bits.Dm == 0) {\r
- Time->Year = DecimalToBcd8 ((UINT8) Time->Year);\r
- Time->Month = DecimalToBcd8 (Time->Month);\r
- Time->Day = DecimalToBcd8 (Time->Day);\r
- Time->Hour = DecimalToBcd8 (Time->Hour);\r
- Time->Minute = DecimalToBcd8 (Time->Minute);\r
- Time->Second = DecimalToBcd8 (Time->Second);\r
+ Time->Year = DecimalToBcd8 ((UINT8)Time->Year);\r
+ Time->Month = DecimalToBcd8 (Time->Month);\r
+ Time->Day = DecimalToBcd8 (Time->Day);\r
+ Time->Hour = DecimalToBcd8 (Time->Hour);\r
+ Time->Minute = DecimalToBcd8 (Time->Minute);\r
+ Time->Second = DecimalToBcd8 (Time->Second);\r
}\r
+\r
//\r
// If we are in 12 hour mode and PM is set, then set bit 7 of the Hour field.\r
//\r
- if (RegisterB.Bits.Mil == 0 && IsPM) {\r
- Time->Hour = (UINT8) (Time->Hour | 0x80);\r
+ if ((RegisterB.Bits.Mil == 0) && IsPM) {\r
+ Time->Hour = (UINT8)(Time->Hour | 0x80);\r
}\r
}\r
\r
/**\r
Compare the Hour, Minute and Second of the From time and the To time.\r
- \r
+\r
Only compare H/M/S in EFI_TIME and ignore other fields here.\r
\r
@param From the first time\r
**/\r
INTN\r
CompareHMS (\r
- IN EFI_TIME *From,\r
- IN EFI_TIME *To\r
+ IN EFI_TIME *From,\r
+ IN EFI_TIME *To\r
)\r
{\r
if ((From->Hour > To->Hour) ||\r
- ((From->Hour == To->Hour) && (From->Minute > To->Minute)) ||\r
- ((From->Hour == To->Hour) && (From->Minute == To->Minute) && (From->Second > To->Second))) {\r
+ ((From->Hour == To->Hour) && (From->Minute > To->Minute)) ||\r
+ ((From->Hour == To->Hour) && (From->Minute == To->Minute) && (From->Second > To->Second)))\r
+ {\r
return 1;\r
} else if ((From->Hour == To->Hour) && (From->Minute == To->Minute) && (From->Second == To->Second)) {\r
return 0;\r
IN EFI_TIME *To\r
)\r
{\r
- UINT8 DayOfMonth[12];\r
- BOOLEAN Adjacent;\r
-\r
- DayOfMonth[0] = 31;\r
- DayOfMonth[1] = 29;\r
- DayOfMonth[2] = 31;\r
- DayOfMonth[3] = 30;\r
- DayOfMonth[4] = 31;\r
- DayOfMonth[5] = 30;\r
- DayOfMonth[6] = 31;\r
- DayOfMonth[7] = 31;\r
- DayOfMonth[8] = 30;\r
- DayOfMonth[9] = 31;\r
- DayOfMonth[10] = 30;\r
- DayOfMonth[11] = 31;\r
+ BOOLEAN Adjacent;\r
\r
Adjacent = FALSE;\r
\r
//\r
// The validity of From->Month field should be checked before\r
//\r
- ASSERT (From->Month >=1);\r
- ASSERT (From->Month <=12);\r
- \r
+ ASSERT (From->Month >= 1);\r
+ ASSERT (From->Month <= 12);\r
+\r
if (From->Year == To->Year) {\r
if (From->Month == To->Month) {\r
if ((From->Day + 1) == To->Day) {\r
- if ((CompareHMS(From, To) >= 0)) {\r
+ if ((CompareHMS (From, To) >= 0)) {\r
Adjacent = TRUE;\r
}\r
} else if (From->Day == To->Day) {\r
- if ((CompareHMS(From, To) <= 0)) {\r
+ if ((CompareHMS (From, To) <= 0)) {\r
Adjacent = TRUE;\r
}\r
}\r
} else if (((From->Month + 1) == To->Month) && (To->Day == 1)) {\r
- if ((From->Month == 2) && !IsLeapYear(From)) {\r
+ if ((From->Month == 2) && !IsLeapYear (From)) {\r
if (From->Day == 28) {\r
- if ((CompareHMS(From, To) >= 0)) {\r
+ if ((CompareHMS (From, To) >= 0)) {\r
Adjacent = TRUE;\r
}\r
}\r
- } else if (From->Day == DayOfMonth[From->Month - 1]) {\r
- if ((CompareHMS(From, To) >= 0)) {\r
- Adjacent = TRUE;\r
+ } else if (From->Day == mDayOfMonth[From->Month - 1]) {\r
+ if ((CompareHMS (From, To) >= 0)) {\r
+ Adjacent = TRUE;\r
}\r
}\r
}\r
(From->Month == 12) &&\r
(From->Day == 31) &&\r
(To->Month == 1) &&\r
- (To->Day == 1)) {\r
- if ((CompareHMS(From, To) >= 0)) {\r
+ (To->Day == 1))\r
+ {\r
+ if ((CompareHMS (From, To) >= 0)) {\r
Adjacent = TRUE;\r
}\r
}\r
}\r
\r
/**\r
- This function find ACPI table with the specified signature in RSDT or XSDT.\r
-\r
- @param Sdt ACPI RSDT or XSDT.\r
- @param Signature ACPI table signature.\r
- @param TablePointerSize Size of table pointer: 4 or 8.\r
+ Get the century RTC address from the ACPI FADT table.\r
\r
- @return ACPI table or NULL if not found.\r
+ @return The century RTC address or 0 if not found.\r
**/\r
-VOID *\r
-ScanTableInSDT (\r
- IN EFI_ACPI_DESCRIPTION_HEADER *Sdt,\r
- IN UINT32 Signature,\r
- IN UINTN TablePointerSize\r
+UINT8\r
+GetCenturyRtcAddress (\r
+ VOID\r
)\r
{\r
- UINTN Index;\r
- UINTN EntryCount;\r
- UINTN EntryBase;\r
- EFI_ACPI_DESCRIPTION_HEADER *Table;\r
+ EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE *Fadt;\r
\r
- EntryCount = (Sdt->Length - sizeof (EFI_ACPI_DESCRIPTION_HEADER)) / TablePointerSize;\r
+ Fadt = (EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE *)EfiLocateFirstAcpiTable (\r
+ EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE\r
+ );\r
\r
- EntryBase = (UINTN) (Sdt + 1);\r
- for (Index = 0; Index < EntryCount; Index++) {\r
- //\r
- // When TablePointerSize is 4 while sizeof (VOID *) is 8, make sure the upper 4 bytes are zero.\r
- //\r
- Table = 0;\r
- CopyMem (&Table, (VOID *) (EntryBase + Index * TablePointerSize), TablePointerSize);\r
- if (Table->Signature == Signature) {\r
- return Table;\r
- }\r
+ if ((Fadt != NULL) &&\r
+ (Fadt->Century > RTC_ADDRESS_REGISTER_D) && (Fadt->Century < 0x80)\r
+ )\r
+ {\r
+ return Fadt->Century;\r
+ } else {\r
+ return 0;\r
}\r
-\r
- return NULL;\r
}\r
\r
/**\r
VOID\r
EFIAPI\r
PcRtcAcpiTableChangeCallback (\r
- IN EFI_EVENT Event,\r
- IN VOID *Context\r
+ IN EFI_EVENT Event,\r
+ IN VOID *Context\r
)\r
{\r
- EFI_STATUS Status;\r
- EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER *Rsdp;\r
- EFI_ACPI_DESCRIPTION_HEADER *Rsdt;\r
- EFI_ACPI_DESCRIPTION_HEADER *Xsdt;\r
- EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE *Fadt;\r
- EFI_TIME Time;\r
- UINT8 Century;\r
-\r
- Status = EfiGetSystemConfigurationTable (&gEfiAcpiTableGuid, (VOID **) &Rsdp);\r
- if (EFI_ERROR (Status)) {\r
- Status = EfiGetSystemConfigurationTable (&gEfiAcpi10TableGuid, (VOID **) &Rsdp);\r
- }\r
-\r
- if (EFI_ERROR (Status)) {\r
- return;\r
- }\r
-\r
- ASSERT (Rsdp != NULL);\r
-\r
- //\r
- // Find FADT in XSDT\r
- //\r
- Fadt = NULL;\r
- if (Rsdp->Revision >= EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER_REVISION) {\r
- Xsdt = (EFI_ACPI_DESCRIPTION_HEADER *) (UINTN) Rsdp->XsdtAddress;\r
- Fadt = ScanTableInSDT (Xsdt, EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE, sizeof (UINT64));\r
- }\r
-\r
- if (Fadt == NULL) {\r
- //\r
- // Find FADT in RSDT\r
- //\r
- Rsdt = (EFI_ACPI_DESCRIPTION_HEADER *) (UINTN) Rsdp->RsdtAddress;\r
- Fadt = ScanTableInSDT (Rsdt, EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE, sizeof (UINT32));\r
- }\r
-\r
- if ((Fadt != NULL) &&\r
- (Fadt->Century > RTC_ADDRESS_REGISTER_D) && (Fadt->Century < 0x80) &&\r
- (mModuleGlobal.CenturyRtcAddress != Fadt->Century)\r
- ) {\r
- mModuleGlobal.CenturyRtcAddress = Fadt->Century;\r
- Status = PcRtcGetTime (&Time, NULL, &mModuleGlobal);\r
+ EFI_STATUS Status;\r
+ EFI_TIME Time;\r
+ UINT8 CenturyRtcAddress;\r
+ UINT8 Century;\r
+\r
+ CenturyRtcAddress = GetCenturyRtcAddress ();\r
+ if ((CenturyRtcAddress != 0) && (mModuleGlobal.CenturyRtcAddress != CenturyRtcAddress)) {\r
+ mModuleGlobal.CenturyRtcAddress = CenturyRtcAddress;\r
+ Status = PcRtcGetTime (&Time, NULL, &mModuleGlobal);\r
if (!EFI_ERROR (Status)) {\r
- Century = (UINT8) (Time.Year / 100);\r
+ Century = (UINT8)(Time.Year / 100);\r
Century = DecimalToBcd8 (Century);\r
- DEBUG ((EFI_D_INFO, "PcRtc: Write 0x%x to CMOS location 0x%x\n", Century, mModuleGlobal.CenturyRtcAddress));\r
+ DEBUG ((DEBUG_INFO, "PcRtc: Write 0x%x to CMOS location 0x%x\n", Century, mModuleGlobal.CenturyRtcAddress));\r
RtcWrite (mModuleGlobal.CenturyRtcAddress, Century);\r
}\r
}\r