+++ /dev/null
-/*++\r
-\r
-Copyright (c) 2005 - 2007, Intel Corporation \r
-All rights reserved. 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
- \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
-\r
-Module Name:\r
- PcRtc.c\r
-\r
-Abstract:\r
-\r
- RTC Architectural Protocol GUID as defined in EFI 2.0\r
-\r
---*/\r
-\r
-#include "RealTimeClock.h"\r
-\r
-BOOLEAN\r
-DayValid (\r
- IN EFI_TIME *Time\r
- );\r
-\r
-BOOLEAN\r
-IsLeapYear (\r
- IN EFI_TIME *Time\r
- );\r
-\r
-BOOLEAN \r
-IsWithinOneDay (\r
- IN EFI_TIME *From,\r
- IN EFI_TIME *To\r
- );\r
-\r
-INTN\r
-CompareHMS (\r
- IN EFI_TIME *From,\r
- IN EFI_TIME *To\r
- );\r
-\r
-INTN mDayOfMonth[12] = {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};\r
- \r
-UINT8\r
-RtcRead (\r
- IN UINT8 Address\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- Address - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\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
-}\r
-\r
-INTN\r
-CompareHMS (\r
- IN EFI_TIME *From,\r
- IN EFI_TIME *To\r
- )\r
-/*++\r
-\r
-Routine Description: \r
-\r
- Compare the Hour, Minute and Second of the 'From' time and the 'To' time.\r
- Only compare H/M/S in EFI_TIME and ignore other fields here. \r
-\r
-Arguments:\r
-\r
- From - the first time\r
- To - the second time \r
-\r
-Returns:\r
-\r
- >0 : The H/M/S of the 'From' time is later than those of 'To' time\r
- ==0 : The H/M/S of the 'From' time is same as those of 'To' time\r
- <0 : The H/M/S of the 'From' time is earlier than those of 'To' time\r
-\r
---*/\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
- return 1; \r
- } else if ((From->Hour == To->Hour) && (From->Minute == To->Minute) && (From->Second == To->Second)) {\r
- return 0;\r
- } else {\r
- return -1;\r
- }\r
-}\r
-\r
-VOID\r
-RtcWrite (\r
- IN UINT8 Address,\r
- IN UINT8 Data\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- Address - TODO: add argument description\r
- Data - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\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
-}\r
-\r
-EFI_STATUS\r
-PcRtcInit (\r
- IN PC_RTC_MODULE_GLOBALS *Global\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- Global - TODO: add argument description\r
-\r
-Returns:\r
-\r
- EFI_DEVICE_ERROR - TODO: Add description for return value\r
- EFI_SUCCESS - TODO: Add description for return value\r
-\r
---*/\r
-{\r
- EFI_STATUS Status;\r
- RTC_REGISTER_A RegisterA;\r
- RTC_REGISTER_B RegisterB;\r
- //RTC_REGISTER_C RegisterC;\r
- RTC_REGISTER_D RegisterD;\r
- UINT8 Century;\r
- EFI_TIME Time;\r
-\r
- //\r
- // Acquire RTC Lock to make access to RTC atomic\r
- //\r
- EfiAcquireLock (&Global->RtcLock);\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
- RtcWrite (RTC_ADDRESS_REGISTER_A, RegisterA.Data);\r
-\r
- //\r
- // Read Register B\r
- //\r
- RegisterB.Data = RtcRead (RTC_ADDRESS_REGISTER_B);\r
-\r
- //\r
- // Clear RTC flag register\r
- //\r
- //RegisterC.Data = RtcRead (RTC_ADDRESS_REGISTER_C);\r
-\r
- //\r
- // Clear RTC register D\r
- //\r
- RegisterD.Data = RTC_INIT_REGISTER_D;\r
- RtcWrite (RTC_ADDRESS_REGISTER_D, RegisterD.Data);\r
-\r
- //\r
- // Wait for up to 0.1 seconds for the RTC to be updated\r
- //\r
- // KEN: BUGBUG following wait action will cause failure under vmware environment.\r
- //\r
- //Status = RtcWaitToUpdate (100000);\r
- //if (EFI_ERROR (Status)) {\r
- // EfiReleaseLock (&Global->RtcLock);\r
- // return EFI_DEVICE_ERROR;\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
-\r
- ConvertRtcTimeToEfiTime (&Time, RegisterB);\r
-\r
- Century = BcdToDecimal8 (RtcRead (RTC_ADDRESS_CENTURY));\r
-\r
- Time.Year = (UINT16) (Century * 100 + Time.Year);\r
-\r
- //\r
- // Set RTC configuration after get original time\r
- //\r
- RtcWrite (RTC_ADDRESS_REGISTER_B, RTC_INIT_REGISTER_B);\r
-\r
- //\r
- // Release RTC Lock.\r
- //\r
- EfiReleaseLock (&Global->RtcLock);\r
-\r
- //\r
- // Validate time fields\r
- //\r
- Status = RtcTimeFieldsValid (&Time);\r
- if (EFI_ERROR (Status)) {\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
- }\r
- //\r
- // Reset time value according to new RTC configuration\r
- //\r
- PcRtcSetTime (&Time, Global);\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-PcRtcGetTime (\r
- OUT EFI_TIME *Time,\r
- IN EFI_TIME_CAPABILITIES *Capabilities,\r
- IN PC_RTC_MODULE_GLOBALS *Global\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Arguments:\r
-\r
- Returns: \r
---*/\r
-// TODO: Time - add argument and description to function comment\r
-// TODO: Capabilities - add argument and description to function comment\r
-// TODO: Global - add argument and description to function comment\r
-// TODO: EFI_INVALID_PARAMETER - add return value to function comment\r
-// TODO: EFI_DEVICE_ERROR - add return value to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-{\r
- EFI_STATUS Status;\r
- RTC_REGISTER_B RegisterB;\r
- UINT8 Century;\r
- //UINTN BufferSize;\r
-\r
- //\r
- // Check parameters for null pointer\r
- //\r
- if (Time == NULL) {\r
- return EFI_INVALID_PARAMETER;\r
-\r
- }\r
- //\r
- // Acquire RTC Lock to make access to RTC atomic\r
- //\r
- EfiAcquireLock (&Global->RtcLock);\r
-\r
- //\r
- // Wait for up to 0.1 seconds for the RTC to be updated\r
- //\r
- Status = RtcWaitToUpdate (100000);\r
- if (EFI_ERROR (Status)) {\r
- EfiReleaseLock (&Global->RtcLock);\r
- return Status;\r
- }\r
- //\r
- // Read Register B\r
- //\r
- RegisterB.Data = RtcRead (RTC_ADDRESS_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
-\r
- ConvertRtcTimeToEfiTime (Time, RegisterB);\r
-\r
- Century = BcdToDecimal8 (RtcRead (RTC_ADDRESS_CENTURY));\r
-\r
- Time->Year = (UINT16) (Century * 100 + Time->Year);\r
-\r
- //\r
- // Release RTC Lock.\r
- //\r
- EfiReleaseLock (&Global->RtcLock);\r
-\r
- //\r
- // Get the variable that containts the TimeZone and Daylight fields\r
- //\r
- Time->TimeZone = Global->SavedTimeZone;\r
- Time->Daylight = Global->Daylight;\r
-\r
- //BufferSize = sizeof (INT16) + sizeof (UINT8);\r
-\r
- //\r
- // Make sure all field values are in correct range\r
- //\r
- Status = RtcTimeFieldsValid (Time);\r
- if (EFI_ERROR (Status)) {\r
- return EFI_DEVICE_ERROR;\r
- }\r
- //\r
- // Fill in Capabilities if it was passed in\r
- //\r
- if (Capabilities) {\r
- Capabilities->Resolution = 1;\r
- //\r
- // 1 hertz\r
- //\r
- Capabilities->Accuracy = 50000000;\r
- //\r
- // 50 ppm\r
- //\r
- Capabilities->SetsToZero = FALSE;\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-PcRtcSetTime (\r
- IN EFI_TIME *Time,\r
- IN PC_RTC_MODULE_GLOBALS *Global\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Arguments:\r
-\r
- Returns: \r
---*/\r
-// TODO: Time - add argument and description to function comment\r
-// TODO: Global - add argument and description to function comment\r
-// TODO: EFI_INVALID_PARAMETER - add return value to function comment\r
-{\r
- EFI_STATUS Status;\r
- EFI_TIME RtcTime;\r
- RTC_REGISTER_B RegisterB;\r
- UINT8 Century;\r
-\r
- if (Time == NULL) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
- //\r
- // Make sure that the time fields are valid\r
- //\r
- Status = RtcTimeFieldsValid (Time);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- CopyMem (&RtcTime, Time, sizeof (EFI_TIME));\r
-\r
- //\r
- // Acquire RTC Lock to make access to RTC atomic\r
- //\r
- EfiAcquireLock (&Global->RtcLock);\r
-\r
- //\r
- // Wait for up to 0.1 seconds for the RTC to be updated\r
- //\r
- Status = RtcWaitToUpdate (100000);\r
- if (EFI_ERROR (Status)) {\r
- EfiReleaseLock (&Global->RtcLock);\r
- return Status;\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
- RtcWrite (RTC_ADDRESS_REGISTER_B, RegisterB.Data);\r
-\r
- ConvertEfiTimeToRtcTime (&RtcTime, RegisterB, &Century);\r
-\r
- RtcWrite (RTC_ADDRESS_SECONDS, RtcTime.Second);\r
- RtcWrite (RTC_ADDRESS_MINUTES, RtcTime.Minute);\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_CENTURY, Century);\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
- EfiReleaseLock (&Global->RtcLock);\r
-\r
- //\r
- // Set the variable that containts the TimeZone and Daylight fields\r
- //\r
- Global->SavedTimeZone = Time->TimeZone;\r
- Global->Daylight = Time->Daylight;\r
- return Status;\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-PcRtcGetWakeupTime (\r
- OUT BOOLEAN *Enabled,\r
- OUT BOOLEAN *Pending,\r
- OUT EFI_TIME *Time,\r
- IN PC_RTC_MODULE_GLOBALS *Global\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Arguments:\r
-\r
- \r
-\r
-Returns: \r
---*/\r
-// TODO: Enabled - add argument and description to function comment\r
-// TODO: Pending - add argument and description to function comment\r
-// TODO: Time - add argument and description to function comment\r
-// TODO: Global - add argument and description to function comment\r
-// TODO: EFI_INVALID_PARAMETER - add return value to function comment\r
-// TODO: EFI_DEVICE_ERROR - add return value to function comment\r
-// TODO: EFI_DEVICE_ERROR - add return value to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-{\r
- EFI_STATUS Status;\r
- RTC_REGISTER_B RegisterB;\r
- RTC_REGISTER_C RegisterC;\r
- UINT8 Century;\r
-\r
- //\r
- // Check paramters for null pointers\r
- //\r
- if ((Enabled == NULL) || (Pending == NULL) || (Time == NULL)) {\r
- return EFI_INVALID_PARAMETER;\r
-\r
- }\r
- //\r
- // Acquire RTC Lock to make access to RTC atomic\r
- //\r
- EfiAcquireLock (&Global->RtcLock);\r
-\r
- //\r
- // Wait for up to 0.1 seconds for the RTC to be updated\r
- //\r
- Status = RtcWaitToUpdate (100000);\r
- if (EFI_ERROR (Status)) {\r
- EfiReleaseLock (&Global->RtcLock);\r
- return EFI_DEVICE_ERROR;\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
-\r
- //\r
- // Get the Time/Date/Daylight Savings values.\r
- //\r
- *Enabled = RegisterB.Bits.AIE;\r
- if (*Enabled) {\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
- } else {\r
- Time->Second = 0;\r
- Time->Minute = 0;\r
- Time->Hour = 0;\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
- ConvertRtcTimeToEfiTime (Time, RegisterB);\r
-\r
- Century = BcdToDecimal8 (RtcRead (RTC_ADDRESS_CENTURY));\r
-\r
- Time->Year = (UINT16) (Century * 100 + Time->Year);\r
-\r
- //\r
- // Release RTC Lock.\r
- //\r
- EfiReleaseLock (&Global->RtcLock);\r
-\r
- //\r
- // Make sure all field values are in correct range\r
- //\r
- Status = RtcTimeFieldsValid (Time);\r
- if (EFI_ERROR (Status)) {\r
- return EFI_DEVICE_ERROR;\r
- }\r
-\r
- *Pending = RegisterC.Bits.AF;\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-PcRtcSetWakeupTime (\r
- IN BOOLEAN Enable,\r
- OUT EFI_TIME *Time,\r
- IN PC_RTC_MODULE_GLOBALS *Global\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Arguments:\r
-\r
- \r
-\r
-Returns: \r
---*/\r
-// TODO: Enable - add argument and description to function comment\r
-// TODO: Time - add argument and description to function comment\r
-// TODO: Global - add argument and description to function comment\r
-// TODO: EFI_INVALID_PARAMETER - add return value to function comment\r
-// TODO: EFI_INVALID_PARAMETER - add return value to function comment\r
-// TODO: EFI_UNSUPPORTED - add return value to function comment\r
-// TODO: EFI_DEVICE_ERROR - add return value to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-{\r
- EFI_STATUS Status;\r
- EFI_TIME RtcTime;\r
- RTC_REGISTER_B RegisterB;\r
- UINT8 Century;\r
- EFI_TIME_CAPABILITIES Capabilities;\r
-\r
- if (Enable) {\r
-\r
- if (Time == NULL) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
- //\r
- // Make sure that the time fields are valid\r
- //\r
- Status = RtcTimeFieldsValid (Time);\r
- if (EFI_ERROR (Status)) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
- //\r
- // Just support set alarm time within 24 hours\r
- //\r
- PcRtcGetTime (&RtcTime, &Capabilities, Global);\r
- if (!IsWithinOneDay (&RtcTime, Time)) {\r
- return EFI_UNSUPPORTED;\r
- }\r
- //\r
- // Make a local copy of the time and date\r
- //\r
- CopyMem (&RtcTime, Time, sizeof (EFI_TIME));\r
-\r
- }\r
- //\r
- // Acquire RTC Lock to make access to RTC atomic\r
- //\r
- EfiAcquireLock (&Global->RtcLock);\r
-\r
- //\r
- // Wait for up to 0.1 seconds for the RTC to be updated\r
- //\r
- Status = RtcWaitToUpdate (100000);\r
- if (EFI_ERROR (Status)) {\r
- EfiReleaseLock (&Global->RtcLock);\r
- return EFI_DEVICE_ERROR;\r
- }\r
- //\r
- // Read Register B, and inhibit updates of the RTC\r
- //\r
- RegisterB.Data = RtcRead (RTC_ADDRESS_REGISTER_B);\r
-\r
- RegisterB.Bits.SET = 1;\r
- RtcWrite (RTC_ADDRESS_REGISTER_B, RegisterB.Data);\r
-\r
- if (Enable) {\r
- ConvertEfiTimeToRtcTime (&RtcTime, RegisterB, &Century);\r
-\r
- //\r
- // Set RTC alarm time\r
- //\r
- RtcWrite (RTC_ADDRESS_SECONDS_ALARM, RtcTime.Second);\r
- RtcWrite (RTC_ADDRESS_MINUTES_ALARM, RtcTime.Minute);\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
- // 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
- EfiReleaseLock (&Global->RtcLock);\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-VOID\r
-ConvertRtcTimeToEfiTime (\r
- IN EFI_TIME *Time,\r
- IN RTC_REGISTER_B RegisterB\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Arguments:\r
-\r
- \r
-\r
-Returns: \r
---*/\r
-// TODO: Time - add argument and description to function comment\r
-// TODO: RegisterB - add argument and description to function comment\r
-{\r
- BOOLEAN PM;\r
-\r
- if ((Time->Hour) & 0x80) {\r
- PM = TRUE;\r
- } else {\r
- PM = FALSE;\r
- }\r
-\r
- Time->Hour = (UINT8) (Time->Hour & 0x7f);\r
-\r
- if (RegisterB.Bits.DM == 0) {\r
- Time->Year = BcdToDecimal8 ((UINT8) Time->Year);\r
- Time->Month = BcdToDecimal8 (Time->Month);\r
- Time->Day = BcdToDecimal8 (Time->Day);\r
- Time->Hour = BcdToDecimal8 (Time->Hour);\r
- Time->Minute = BcdToDecimal8 (Time->Minute);\r
- Time->Second = BcdToDecimal8 (Time->Second);\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 (PM && Time->Hour < 12) {\r
- Time->Hour = (UINT8) (Time->Hour + 12);\r
- }\r
-\r
- if (!PM && Time->Hour == 12) {\r
- Time->Hour = 0;\r
- }\r
- }\r
-\r
- Time->Nanosecond = 0;\r
- Time->TimeZone = EFI_UNSPECIFIED_TIMEZONE;\r
- Time->Daylight = 0;\r
-}\r
-\r
-EFI_STATUS\r
-RtcWaitToUpdate (\r
- UINTN Timeout\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Arguments:\r
- \r
-\r
-Returns: \r
---*/\r
-// TODO: Timeout - add argument and description to function comment\r
-// TODO: EFI_DEVICE_ERROR - add return value to function comment\r
-// TODO: EFI_DEVICE_ERROR - add return value to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-{\r
- RTC_REGISTER_A RegisterA;\r
- RTC_REGISTER_D RegisterD;\r
-\r
- //\r
- // See if the RTC is functioning correctly\r
- //\r
- RegisterD.Data = RtcRead (RTC_ADDRESS_REGISTER_D);\r
-\r
- if (RegisterD.Bits.VRT == 0) {\r
- return EFI_DEVICE_ERROR;\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
- while (RegisterA.Bits.UIP == 1 && Timeout > 0) {\r
- MicroSecondDelay (10);\r
- RegisterA.Data = RtcRead (RTC_ADDRESS_REGISTER_A);\r
- Timeout--;\r
- }\r
-\r
- RegisterD.Data = RtcRead (RTC_ADDRESS_REGISTER_D);\r
- if (Timeout == 0 || RegisterD.Bits.VRT == 0) {\r
- return EFI_DEVICE_ERROR;\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-RtcTimeFieldsValid (\r
- IN EFI_TIME *Time\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Arguments:\r
- \r
- Returns: \r
---*/\r
-// TODO: Time - add argument and description to function comment\r
-// TODO: EFI_INVALID_PARAMETER - add return value to function comment\r
-// TODO: EFI_SUCCESS - add return value to function comment\r
-{\r
- if (Time->Year < 1998 ||\r
- Time->Year > 2099 ||\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)))\r
- ) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-BOOLEAN\r
-DayValid (\r
- IN EFI_TIME *Time\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- Time - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-{\r
-\r
-\r
- if (Time->Day < 1 ||\r
- Time->Day > mDayOfMonth[Time->Month - 1] ||\r
- (Time->Month == 2 && (!IsLeapYear (Time) && Time->Day > 28))\r
- ) {\r
- return FALSE;\r
- }\r
-\r
- return TRUE;\r
-}\r
-\r
-BOOLEAN\r
-IsLeapYear (\r
- IN EFI_TIME *Time\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- Time - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-{\r
- if (Time->Year % 4 == 0) {\r
- if (Time->Year % 100 == 0) {\r
- if (Time->Year % 400 == 0) {\r
- return TRUE;\r
- } else {\r
- return FALSE;\r
- }\r
- } else {\r
- return TRUE;\r
- }\r
- } else {\r
- return FALSE;\r
- }\r
-}\r
-\r
-VOID\r
-ConvertEfiTimeToRtcTime (\r
- IN EFI_TIME *Time,\r
- IN RTC_REGISTER_B RegisterB,\r
- IN UINT8 *Century\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Arguments:\r
-\r
-\r
-Returns: \r
---*/\r
-// TODO: Time - add argument and description to function comment\r
-// TODO: RegisterB - add argument and description to function comment\r
-// TODO: Century - add argument and description to function comment\r
-{\r
- BOOLEAN PM;\r
-\r
- PM = TRUE;\r
- //\r
- // Adjust hour field if RTC in in 12 hour mode\r
- //\r
- if (RegisterB.Bits.MIL == 0) {\r
- if (Time->Hour < 12) {\r
- PM = FALSE;\r
- }\r
-\r
- if (Time->Hour >= 13) {\r
- Time->Hour = (UINT8) (Time->Hour - 12);\r
- } else if (Time->Hour == 0) {\r
- Time->Hour = 12;\r
- }\r
- }\r
- //\r
- // Set the Time/Date/Daylight Savings values.\r
- //\r
- *Century = DecimaltoBcd ((UINT8) (Time->Year / 100));\r
-\r
- Time->Year = (UINT16) (Time->Year % 100);\r
-\r
- if (RegisterB.Bits.DM == 0) {\r
- Time->Year = DecimaltoBcd ((UINT8) Time->Year);\r
- Time->Month = DecimaltoBcd (Time->Month);\r
- Time->Day = DecimaltoBcd (Time->Day);\r
- Time->Hour = DecimaltoBcd (Time->Hour);\r
- Time->Minute = DecimaltoBcd (Time->Minute);\r
- Time->Second = DecimaltoBcd (Time->Second);\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 && PM) {\r
- Time->Hour = (UINT8) (Time->Hour | 0x80);\r
- }\r
-}\r
- \r
-BOOLEAN \r
-IsWithinOneDay (\r
- IN EFI_TIME *From,\r
- IN EFI_TIME *To\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Judge whether two days are adjacent.\r
-\r
-Arguments:\r
-\r
- From - the first day\r
- To - the second day\r
-\r
-Returns:\r
-\r
- TRUE - The interval of two days are within one day.\r
- FALSE - The interval of two days exceed ony day or parameter error.\r
-\r
---*/\r
-{\r
- BOOLEAN Adjacent = FALSE;\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
- Adjacent = TRUE;\r
- }\r
- } else if (From->Day == To->Day) {\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->Day == 28) {\r
- if ((CompareHMS(From, To) >= 0)) {\r
- Adjacent = TRUE;\r
- } \r
- }\r
- } else if (From->Day == mDayOfMonth[From->Month - 1]) {\r
- if ((CompareHMS(From, To) >= 0)) {\r
- Adjacent = TRUE;\r
- }\r
- }\r
- }\r
- } else if (((From->Year + 1) == To->Year) &&\r
- (From->Month == 12) &&\r
- (From->Day == 31) &&\r
- (To->Month == 1) &&\r
- (To->Day == 1)) {\r
- if ((CompareHMS(From, To) >= 0)) {\r
- Adjacent = TRUE;\r
- }\r
- }\r
-\r
- return Adjacent;\r
-}\r
-\r
-UINT8\r
-DecimaltoBcd (\r
- IN UINT8 DecValue\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Arguments: \r
-\r
-Returns: \r
-\r
---*/\r
-// TODO: DecValue - add argument and description to function comment\r
-{\r
- UINTN High;\r
- UINTN Low;\r
-\r
- High = DecValue / 10;\r
- Low = DecValue - (High * 10);\r
-\r
- return (UINT8) (Low + (High << 4));\r
-}\r
+++ /dev/null
-/*++\r
-\r
-Copyright (c) 2005, Intel Corporation \r
-All rights reserved. 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
- \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
-\r
-Module Name:\r
- PcRtc.h\r
-\r
-Abstract:\r
-\r
- Include for real time clock driver\r
-\r
-Revision History\r
-\r
-\r
---*/\r
-\r
-#ifndef _RTC_H_\r
-#define _RTC_H_\r
-\r
-#include <FrameworkDxe.h>\r
-\r
-#include <Protocol/RealTimeClock.h>\r
-\r
-#include <Library/UefiLib.h>\r
-#include <Library/UefiBootServicesTableLib.h>\r
-#include <Library/IoLib.h>\r
-#include <Library/TimerLib.h>\r
-#include <Library/BaseMemoryLib.h>\r
-\r
-typedef struct {\r
- EFI_LOCK RtcLock;\r
- UINT16 SavedTimeZone;\r
- UINT8 Daylight;\r
-} PC_RTC_MODULE_GLOBALS;\r
-\r
-#define PCAT_RTC_ADDRESS_REGISTER 0x70\r
-#define PCAT_RTC_DATA_REGISTER 0x71\r
-\r
-//\r
-// Dallas DS12C887 Real Time Clock\r
-//\r
-#define RTC_ADDRESS_SECONDS 0 // R/W Range 0..59\r
-#define RTC_ADDRESS_SECONDS_ALARM 1 // R/W Range 0..59\r
-#define RTC_ADDRESS_MINUTES 2 // R/W Range 0..59\r
-#define RTC_ADDRESS_MINUTES_ALARM 3 // R/W Range 0..59\r
-#define RTC_ADDRESS_HOURS 4 // R/W Range 1..12 or 0..23 Bit 7 is AM/PM\r
-#define RTC_ADDRESS_HOURS_ALARM 5 // R/W Range 1..12 or 0..23 Bit 7 is AM/PM\r
-#define RTC_ADDRESS_DAY_OF_THE_WEEK 6 // R/W Range 1..7\r
-#define RTC_ADDRESS_DAY_OF_THE_MONTH 7 // R/W Range 1..31\r
-#define RTC_ADDRESS_MONTH 8 // R/W Range 1..12\r
-#define RTC_ADDRESS_YEAR 9 // R/W Range 0..99\r
-#define RTC_ADDRESS_REGISTER_A 10 // R/W[0..6] R0[7]\r
-#define RTC_ADDRESS_REGISTER_B 11 // R/W\r
-#define RTC_ADDRESS_REGISTER_C 12 // RO\r
-#define RTC_ADDRESS_REGISTER_D 13 // RO\r
-#define RTC_ADDRESS_CENTURY 50 // R/W Range 19..20 Bit 8 is R/W\r
-//\r
-// Date and time initial values.\r
-// They are used if the RTC values are invalid during driver initialization\r
-//\r
-#define RTC_INIT_SECOND 0\r
-#define RTC_INIT_MINUTE 0\r
-#define RTC_INIT_HOUR 0\r
-#define RTC_INIT_DAY 1\r
-#define RTC_INIT_MONTH 1\r
-#define RTC_INIT_YEAR 2001\r
-\r
-//\r
-// Register initial values\r
-//\r
-#define RTC_INIT_REGISTER_A 0x26\r
-#define RTC_INIT_REGISTER_B 0x02\r
-#define RTC_INIT_REGISTER_D 0x0\r
-\r
-#pragma pack(1)\r
-//\r
-// Register A\r
-//\r
-typedef struct {\r
- UINT8 RS : 4; // Rate Selection Bits\r
- UINT8 DV : 3; // Divisor\r
- UINT8 UIP : 1; // Update in progress\r
-} RTC_REGISTER_A_BITS;\r
-\r
-typedef union {\r
- RTC_REGISTER_A_BITS Bits;\r
- UINT8 Data;\r
-} RTC_REGISTER_A;\r
-\r
-//\r
-// Register B\r
-//\r
-typedef struct {\r
- UINT8 DSE : 1; // 0 - Daylight saving disabled 1 - Daylight savings enabled\r
- UINT8 MIL : 1; // 0 - 12 hour mode 1 - 24 hour mode\r
- UINT8 DM : 1; // 0 - BCD Format 1 - Binary Format\r
- UINT8 SQWE : 1; // 0 - Disable SQWE output 1 - Enable SQWE output\r
- UINT8 UIE : 1; // 0 - Update INT disabled 1 - Update INT enabled\r
- UINT8 AIE : 1; // 0 - Alarm INT disabled 1 - Alarm INT Enabled\r
- UINT8 PIE : 1; // 0 - Periodic INT disabled 1 - Periodic INT Enabled\r
- UINT8 SET : 1; // 0 - Normal operation. 1 - Updates inhibited\r
-} RTC_REGISTER_B_BITS;\r
-\r
-typedef union {\r
- RTC_REGISTER_B_BITS Bits;\r
- UINT8 Data;\r
-} RTC_REGISTER_B;\r
-\r
-//\r
-// Register C\r
-//\r
-typedef struct {\r
- UINT8 Reserved : 4; // Read as zero. Can not be written.\r
- UINT8 UF : 1; // Update End Interrupt Flag\r
- UINT8 AF : 1; // Alarm Interrupt Flag\r
- UINT8 PF : 1; // Periodic Interrupt Flag\r
- UINT8 IRQF : 1; // Iterrupt Request Flag = PF & PIE | AF & AIE | UF & UIE\r
-} RTC_REGISTER_C_BITS;\r
-\r
-typedef union {\r
- RTC_REGISTER_C_BITS Bits;\r
- UINT8 Data;\r
-} RTC_REGISTER_C;\r
-\r
-//\r
-// Register D\r
-//\r
-typedef struct {\r
- UINT8 Reserved : 7; // Read as zero. Can not be written.\r
- UINT8 VRT : 1; // Valid RAM and Time\r
-} RTC_REGISTER_D_BITS;\r
-\r
-typedef union {\r
- RTC_REGISTER_D_BITS Bits;\r
- UINT8 Data;\r
-} RTC_REGISTER_D;\r
-\r
-#pragma pack()\r
-\r
-EFI_STATUS\r
-PcRtcInit (\r
- IN PC_RTC_MODULE_GLOBALS *Global\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- Global - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-EFI_STATUS\r
-PcRtcSetTime (\r
- IN EFI_TIME *Time,\r
- IN PC_RTC_MODULE_GLOBALS *Global\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- Time - TODO: add argument description\r
- Global - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-EFI_STATUS\r
-PcRtcGetTime (\r
- OUT EFI_TIME *Time,\r
- IN EFI_TIME_CAPABILITIES *Capabilities,\r
- IN PC_RTC_MODULE_GLOBALS *Global\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- Time - TODO: add argument description\r
- Capabilities - TODO: add argument description\r
- Global - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-PcRtcSetWakeupTime (\r
- IN BOOLEAN Enable,\r
- OUT EFI_TIME *Time,\r
- IN PC_RTC_MODULE_GLOBALS *Global\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- Enable - TODO: add argument description\r
- Time - TODO: add argument description\r
- Global - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-PcRtcGetWakeupTime (\r
- OUT BOOLEAN *Enabled,\r
- OUT BOOLEAN *Pending,\r
- OUT EFI_TIME *Time,\r
- IN PC_RTC_MODULE_GLOBALS *Global\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- Enabled - TODO: add argument description\r
- Pending - TODO: add argument description\r
- Time - TODO: add argument description\r
- Global - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-InitializePcRtc (\r
- IN EFI_HANDLE ImageHandle,\r
- IN EFI_SYSTEM_TABLE *SystemTable\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- ImageHandle - TODO: add argument description\r
- SystemTable - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-EFI_STATUS\r
-RtcTimeFieldsValid (\r
- IN EFI_TIME *Time\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- Time - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-UINT8\r
-DecimaltoBcd (\r
- IN UINT8 DecValue\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- DecValue - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-VOID\r
-ConvertEfiTimeToRtcTime (\r
- IN EFI_TIME *Time,\r
- IN RTC_REGISTER_B RegisterB,\r
- IN UINT8 *Century\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- Time - TODO: add argument description\r
- RegisterB - TODO: add argument description\r
- Century - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-VOID\r
-ConvertRtcTimeToEfiTime (\r
- IN EFI_TIME *Time,\r
- IN RTC_REGISTER_B RegisterB\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- Time - TODO: add argument description\r
- RegisterB - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-EFI_STATUS\r
-RtcWaitToUpdate (\r
- UINTN Timeout\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- Timeout - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-UINT8\r
-RtcSaveContext (\r
- IN PC_RTC_MODULE_GLOBALS *Global\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- Global - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-VOID\r
-RtcRestoreContext (\r
- IN UINT8 SavedAddressRegister,\r
- IN PC_RTC_MODULE_GLOBALS *Global\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- TODO: Add function description\r
-\r
-Arguments:\r
-\r
- SavedAddressRegister - TODO: add argument description\r
- Global - TODO: add argument description\r
-\r
-Returns:\r
-\r
- TODO: add return values\r
-\r
---*/\r
-;\r
-\r
-#endif\r