]> git.proxmox.com Git - mirror_edk2.git/commitdiff
Move PcatRealTimeClockRuntimeDxe driver to PcAtChipsetPkg
authorklu2 <klu2@6f19259b-4bc3-4df7-8a09-765794883524>
Tue, 7 Jul 2009 02:48:17 +0000 (02:48 +0000)
committerklu2 <klu2@6f19259b-4bc3-4df7-8a09-765794883524>
Tue, 7 Jul 2009 02:48:17 +0000 (02:48 +0000)
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@8766 6f19259b-4bc3-4df7-8a09-765794883524

MdeModulePkg/Universal/PcatRealTimeClockRuntimeDxe/PcRtc.c [deleted file]
MdeModulePkg/Universal/PcatRealTimeClockRuntimeDxe/PcRtc.h [deleted file]
MdeModulePkg/Universal/PcatRealTimeClockRuntimeDxe/PcRtcEntry.c [deleted file]
MdeModulePkg/Universal/PcatRealTimeClockRuntimeDxe/PcatRealTimeClockRuntimeDxe.inf [deleted file]
PcAtChipsetPkg/PcatRealTimeClockRuntimeDxe/PcRtc.c [new file with mode: 0644]
PcAtChipsetPkg/PcatRealTimeClockRuntimeDxe/PcRtc.h [new file with mode: 0644]
PcAtChipsetPkg/PcatRealTimeClockRuntimeDxe/PcRtcEntry.c [new file with mode: 0644]
PcAtChipsetPkg/PcatRealTimeClockRuntimeDxe/PcatRealTimeClockRuntimeDxe.inf [new file with mode: 0644]

diff --git a/MdeModulePkg/Universal/PcatRealTimeClockRuntimeDxe/PcRtc.c b/MdeModulePkg/Universal/PcatRealTimeClockRuntimeDxe/PcRtc.c
deleted file mode 100644 (file)
index d26e923..0000000
+++ /dev/null
@@ -1,1059 +0,0 @@
-/** @file\r
-  RTC Architectural Protocol GUID as defined in DxeCis 0.96.\r
-\r
-Copyright (c) 2006 - 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
-**/\r
-\r
-#include "PcRtc.h"\r
-\r
-/**\r
-  Compare the Hour, Minute and Second of the From time and the To time.\r
-  \r
-  Only compare H/M/S in EFI_TIME and ignore other fields here.\r
-\r
-  @param From   the first time\r
-  @param To     the second time\r
-\r
-  @return  >0   The H/M/S of the From time is later than those of To time\r
-  @return  ==0  The H/M/S of the From time is same as those of To time\r
-  @return  <0   The H/M/S of the From time is earlier than those of To time\r
-**/\r
-INTN\r
-CompareHMS (\r
-  IN EFI_TIME   *From,\r
-  IN EFI_TIME   *To\r
-  );\r
-\r
-/**\r
-  To check if second date is later than first date within 24 hours.\r
-\r
-  @param  From   the first date\r
-  @param  To     the second date\r
-\r
-  @retval TRUE   From is previous to To within 24 hours.\r
-  @retval FALSE  From is later, or it is previous to To more than 24 hours.\r
-**/\r
-BOOLEAN\r
-IsWithinOneDay (\r
-  IN EFI_TIME   *From,\r
-  IN EFI_TIME   *To\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
-\r
-  @return The data of UINT8 type read from RTC.\r
-**/\r
-UINT8\r
-RtcRead (\r
-  IN  UINT8 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
-}\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
-\r
-**/\r
-VOID\r
-RtcWrite (\r
-  IN  UINT8   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
-}\r
-\r
-/**\r
-  Initialize RTC.\r
-\r
-  @param  Global            For global use inside this module.\r
-\r
-  @retval EFI_DEVICE_ERROR  Initialization failed due to device error.\r
-  @retval EFI_SUCCESS       Initialization successful.\r
-\r
-**/\r
-EFI_STATUS\r
-PcRtcInit (\r
-  IN PC_RTC_MODULE_GLOBALS  *Global\r
-  )\r
-{\r
-  EFI_STATUS      Status;\r
-  RTC_REGISTER_A  RegisterA;\r
-  RTC_REGISTER_B  RegisterB;\r
-  RTC_REGISTER_D  RegisterD;\r
-  UINT8           Century;\r
-  EFI_TIME        Time;\r
-  UINTN           DataSize;\r
-  UINT32          TimerVar;\r
-\r
-  //\r
-  // Acquire RTC Lock to make access to RTC atomic\r
-  //\r
-  //Code here doesn't consider the runtime environment.\r
-  if (!EfiAtRuntime ()) {\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
-  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
-  Status = RtcWaitToUpdate (PcdGet32 (PcdRealTimeClockUpdateTimeout));\r
-  if (EFI_ERROR (Status)) {\r
-    //Code here doesn't consider the runtime environment.\r
-    if (!EfiAtRuntime ()) {\r
-      EfiReleaseLock (&Global->RtcLock);\r
-    }\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
-  Century = RtcRead (RTC_ADDRESS_CENTURY);\r
-  \r
-  //\r
-  // Set RTC configuration after get original time\r
-  // The value of bit AIE should be reserved.\r
-  //\r
-  RtcWrite (RTC_ADDRESS_REGISTER_B, (UINT8)(RTC_INIT_REGISTER_B | (RegisterB.Data & BIT5)));\r
-\r
-  //\r
-  // Release RTC Lock.\r
-  //\r
-  //Code here doesn't consider the runtime environment.\r
-  if (!EfiAtRuntime ()) {\r
-    EfiReleaseLock (&Global->RtcLock);\r
-  }\r
\r
-  //\r
-  // Validate time fields\r
-  //\r
-  Status = ConvertRtcTimeToEfiTime (&Time, Century, RegisterB);\r
-  if (!EFI_ERROR (Status)) {\r
-    Status = RtcTimeFieldsValid (&Time);\r
-  }\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
-  // 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
-  if (!EFI_ERROR (Status)) {\r
-    Global->SavedTimeZone = (INT16) TimerVar;\r
-    Global->Daylight      = (UINT8) (TimerVar >> 16);\r
-\r
-    Time.TimeZone = Global->SavedTimeZone;\r
-    Time.Daylight = Global->Daylight;\r
-  }\r
-  //\r
-  // Reset time value according to new RTC configuration\r
-  //\r
-  PcRtcSetTime (&Time, Global);\r
-\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
-  Returns the current time and date information, and the time-keeping capabilities\r
-  of the hardware platform.\r
-\r
-  @param  Time          A pointer to storage to receive a snapshot of the current time.\r
-  @param  Capabilities  An optional pointer to a buffer to receive the real time clock\r
-                        device's capabilities.\r
-  @param  Global        For global use inside this module.\r
-\r
-  @retval EFI_SUCCESS            The operation completed successfully.\r
-  @retval EFI_INVALID_PARAMETER  Time is NULL.\r
-  @retval EFI_DEVICE_ERROR       The time could not be retrieved due to hardware error.\r
-\r
-**/\r
-EFI_STATUS\r
-PcRtcGetTime (\r
-  OUT  EFI_TIME               *Time,\r
-  OUT  EFI_TIME_CAPABILITIES  *Capabilities,  OPTIONAL\r
-  IN   PC_RTC_MODULE_GLOBALS  *Global\r
-  )\r
-{\r
-  EFI_STATUS      Status;\r
-  RTC_REGISTER_B  RegisterB;\r
-  UINT8           Century;\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
-  //Code here doesn't consider the runtime environment.\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
-      //Code here doesn't consider the runtime environment.\r
-      if (!EfiAtRuntime ()) {\r
-        EfiReleaseLock (&Global->RtcLock);\r
-      }\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
-  Century = RtcRead (RTC_ADDRESS_CENTURY);\r
-  \r
-  //\r
-  // Release RTC Lock.\r
-  //\r
-  //Code here doesn't consider the runtime environment.\r
-  if (!EfiAtRuntime ()) {\r
-    EfiReleaseLock (&Global->RtcLock);\r
-  }\r
-  //\r
-  // Get the variable that contains the TimeZone and Daylight fields\r
-  //\r
-  Time->TimeZone  = Global->SavedTimeZone;\r
-  Time->Daylight  = Global->Daylight;\r
-\r
-  //\r
-  // Make sure all field values are in correct range\r
-  //\r
-  Status = ConvertRtcTimeToEfiTime (Time, Century, RegisterB);\r
-  if (!EFI_ERROR (Status)) {\r
-    Status = RtcTimeFieldsValid (Time);\r
-  }\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 != NULL) {\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
-/**\r
-  Sets the current local time and date information.\r
-\r
-  @param  Time                  A pointer to the current time.\r
-  @param  Global                For global use inside this module.\r
-\r
-  @retval EFI_SUCCESS           The operation completed successfully.\r
-  @retval EFI_INVALID_PARAMETER A time field is out of range.\r
-  @retval EFI_DEVICE_ERROR      The time could not be set due due to hardware error.\r
-\r
-**/\r
-EFI_STATUS\r
-PcRtcSetTime (\r
-  IN EFI_TIME                *Time,\r
-  IN PC_RTC_MODULE_GLOBALS   *Global\r
-  )\r
-{\r
-  EFI_STATUS      Status;\r
-  EFI_TIME        RtcTime;\r
-  RTC_REGISTER_B  RegisterB;\r
-  UINT8           Century;\r
-  UINT32          TimerVar;\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
-  //Code here doesn't consider the runtime environment.\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
-     //Code here doesn't consider the runtime environment.\r
-     if (!EfiAtRuntime ()) {\r
-       EfiReleaseLock (&Global->RtcLock);\r
-     }\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
-  //Code here doesn't consider the runtime environment.\r
-  if (!EfiAtRuntime ()) {\r
-    EfiReleaseLock (&Global->RtcLock);\r
-  }\r
-  //\r
-  // Set the variable that contains the TimeZone and Daylight fields\r
-  //\r
-  Global->SavedTimeZone = Time->TimeZone;\r
-  Global->Daylight      = Time->Daylight;\r
-\r
-  TimerVar = Time->Daylight;\r
-  TimerVar = (UINT32) ((TimerVar << 16) | 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
-  ASSERT_EFI_ERROR (Status);\r
-\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
-  Returns the current wakeup alarm clock setting.\r
-\r
-  @param  Enabled  Indicates if the alarm is currently enabled or disabled.\r
-  @param  Pending  Indicates if the alarm signal is pending and requires acknowledgment.\r
-  @param  Time     The current alarm setting.\r
-  @param  Global   For global use inside this module.\r
-\r
-  @retval EFI_SUCCESS           The alarm settings were returned.\r
-  @retval EFI_INVALID_PARAMETER Enabled is NULL.\r
-  @retval EFI_INVALID_PARAMETER Pending is NULL.\r
-  @retval EFI_INVALID_PARAMETER Time is NULL.\r
-  @retval EFI_DEVICE_ERROR      The wakeup time could not be retrieved due to a hardware error.\r
-  @retval EFI_UNSUPPORTED       A wakeup timer is not supported on this platform.\r
-\r
-**/\r
-EFI_STATUS\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
-  EFI_STATUS      Status;\r
-  RTC_REGISTER_B  RegisterB;\r
-  RTC_REGISTER_C  RegisterC;\r
-  UINT8           Century;\r
-\r
-  //\r
-  // Check parameters 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
-  //Code here doesn't consider the runtime environment.\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
-    //Code here doesn't consider the runtime environment.\r
-    if (!EfiAtRuntime ()) {\r
-    EfiReleaseLock (&Global->RtcLock);\r
-    }\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
-  Century = RtcRead (RTC_ADDRESS_CENTURY);\r
-  \r
-  //\r
-  // Release RTC Lock.\r
-  //\r
-  //Code here doesn't consider the runtime environment.\r
-  if (!EfiAtRuntime ()) {\r
-    EfiReleaseLock (&Global->RtcLock);\r
-  }\r
-  //\r
-  // Make sure all field values are in correct range\r
-  //\r
-  Status = ConvertRtcTimeToEfiTime (Time, Century, RegisterB);\r
-  if (!EFI_ERROR (Status)) {\r
-    Status = RtcTimeFieldsValid (Time);\r
-  }\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
-/**\r
-  Sets the system wakeup alarm clock time.\r
-\r
-  @param  Enabled  Enable or disable the wakeup alarm.\r
-  @param  Time     If Enable is TRUE, the time to set the wakeup alarm for.\r
-                   If Enable is FALSE, then this parameter is optional, and may be NULL.\r
-  @param  Global   For global use inside this module.\r
-\r
-  @retval EFI_SUCCESS           If Enable is TRUE, then the wakeup alarm was enabled.\r
-                                If Enable is FALSE, then the wakeup alarm was disabled.\r
-  @retval EFI_INVALID_PARAMETER A time field is out of range.\r
-  @retval EFI_DEVICE_ERROR      The wakeup time could not be set due to a hardware error.\r
-  @retval EFI_UNSUPPORTED       A wakeup timer is not supported on this platform.\r
-\r
-**/\r
-EFI_STATUS\r
-PcRtcSetWakeupTime (\r
-  IN BOOLEAN                Enable,\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
-  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
-    Status = RtcTimeFieldsValid (&RtcTime);\r
-    if (EFI_ERROR (Status)) {\r
-      return EFI_DEVICE_ERROR;\r
-    }\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
-  //Code here doesn't consider the runtime environment.\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
-    //Code here doesn't consider the runtime environment.\r
-    if (!EfiAtRuntime ()) {\r
-    EfiReleaseLock (&Global->RtcLock);\r
-    }\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
-  //Code here doesn't consider the runtime environment.\r
-  if (!EfiAtRuntime ()) {\r
-    EfiReleaseLock (&Global->RtcLock);\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
-  This function checks the 8-bit BCD value specified by Value.\r
-  If valid, the function converts it to an 8-bit value and returns it.\r
-  Otherwise, return 0xff.\r
-\r
-  @param   Value The 8-bit BCD value to check and convert\r
-\r
-  @return  The 8-bit value converted. Or 0xff if Value is invalid.\r
-\r
-**/\r
-UINT8\r
-CheckAndConvertBcd8ToDecimal8 (\r
-  IN  UINT8  Value\r
-  )\r
-{\r
-  if ((Value < 0xa0) && ((Value & 0xf) < 0xa)) {\r
-    return BcdToDecimal8 (Value);\r
-  }\r
-\r
-  return 0xff;\r
-}\r
-\r
-/**\r
-  Converts time read from RTC to EFI_TIME format defined by UEFI spec.\r
-\r
-  This function converts raw time data read from RTC to the EFI_TIME format\r
-  defined by UEFI spec.\r
-  If data mode of RTC is BCD, then converts it to decimal,\r
-  If RTC is in 12-hour format, then converts it to 24-hour format.\r
-\r
-  @param   Time       On input, the time data read from RTC to convert\r
-                      On output, the time converted to UEFI format\r
-  @param   Century    Value of century read from RTC.\r
-  @param   RegisterB  Value of Register B of RTC, indicating data mode\r
-                      and hour format.\r
-\r
-  @retval  EFI_INVALID_PARAMETER  Parameters passed in are invalid.\r
-  @retval  EFI_SUCCESS            Convert RTC time to EFI time successfully.\r
-\r
-**/\r
-EFI_STATUS\r
-ConvertRtcTimeToEfiTime (\r
-  IN OUT EFI_TIME        *Time,\r
-  IN     UINT8           Century,\r
-  IN     RTC_REGISTER_B  RegisterB\r
-  )\r
-{\r
-  BOOLEAN IsPM;\r
-\r
-  if ((Time->Hour & 0x80) != 0) {\r
-    IsPM = TRUE;\r
-  } else {\r
-    IsPM = FALSE;\r
-  }\r
-\r
-  Time->Hour = (UINT8) (Time->Hour & 0x7f);\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
-  }\r
-  Century       = CheckAndConvertBcd8ToDecimal8 (Century);\r
-\r
-  if (Time->Year == 0xff || Time->Month == 0xff || Time->Day == 0xff ||\r
-      Time->Hour == 0xff || Time->Minute == 0xff || Time->Second == 0xff ||\r
-      Century == 0xff) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\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
-    }\r
-\r
-    if (!IsPM && 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
-  return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
-  Wait for a period for the RTC to be ready.\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
-**/\r
-EFI_STATUS\r
-RtcWaitToUpdate (\r
-  UINTN Timeout\r
-  )\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
-/**\r
-  See if all fields of a variable of EFI_TIME type is correct.\r
-\r
-  @param   Time   The time to be checked.\r
-\r
-  @retval  EFI_INVALID_PARAMETER  Some fields of Time are not correct.\r
-  @retval  EFI_SUCCESS            Time is a valid EFI_TIME variable.\r
-\r
-**/\r
-EFI_STATUS\r
-RtcTimeFieldsValid (\r
-  IN EFI_TIME *Time\r
-  )\r
-{\r
-  if (Time->Year < 1998 ||\r
-      Time->Year > 2099 ||\r
-      Time->Month < 1 ||\r
-      Time->Month > 12 ||\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
-    if (!DayValid (Time)) {\r
-      return EFI_INVALID_PARAMETER;\r
-    }\r
-  }\r
-\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
-  See if field Day of an EFI_TIME is correct.\r
-\r
-  @param    Time   Its Day field is to be checked.\r
-\r
-  @retval   TRUE   Day field of Time is correct.\r
-  @retval   FALSE  Day field of Time is NOT correct.\r
-**/\r
-BOOLEAN\r
-DayValid (\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
-    return FALSE;\r
-  }\r
-\r
-  return TRUE;\r
-}\r
-\r
-/**\r
-  Check if it is a leap year.\r
-\r
-  @param    Time   The time to be checked.\r
-\r
-  @retval   TRUE   It is a leap year.\r
-  @retval   FALSE  It is NOT a leap year.\r
-**/\r
-BOOLEAN\r
-IsLeapYear (\r
-  IN EFI_TIME   *Time\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
-/**\r
-  Converts time from EFI_TIME format defined by UEFI spec to RTC's.\r
-\r
-  This function converts time from EFI_TIME format defined by UEFI spec to RTC's.\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
-  @param   Time       On input, the time data read from UEFI to convert\r
-                      On output, the time converted to RTC format\r
-  @param   RegisterB  Value of Register B of RTC, indicating data mode\r
-  @param   Century    It is set according to EFI_TIME Time.\r
-\r
-**/\r
-VOID\r
-ConvertEfiTimeToRtcTime (\r
-  IN OUT EFI_TIME        *Time,\r
-  IN     RTC_REGISTER_B  RegisterB,\r
-     OUT UINT8           *Century\r
-  )\r
-{\r
-  BOOLEAN IsPM;\r
-\r
-  IsPM = TRUE;\r
-  //\r
-  // Adjust hour field if RTC is in 12 hour mode\r
-  //\r
-  if (RegisterB.Bits.MIL == 0) {\r
-    if (Time->Hour < 12) {\r
-      IsPM = 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    = DecimalToBcd8 ((UINT8) (Time->Year / 100));\r
-\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
-  }\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
-  }\r
-}\r
-\r
-/**\r
-  Compare the Hour, Minute and Second of the From time and the To time.\r
-  \r
-  Only compare H/M/S in EFI_TIME and ignore other fields here.\r
-\r
-  @param From   the first time\r
-  @param To     the second time\r
-\r
-  @return  >0   The H/M/S of the From time is later than those of To time\r
-  @return  ==0  The H/M/S of the From time is same as those of To time\r
-  @return  <0   The H/M/S of the From time is earlier than those of To time\r
-**/\r
-INTN\r
-CompareHMS (\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
-    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
-/**\r
-  To check if second date is later than first date within 24 hours.\r
-\r
-  @param  From   the first date\r
-  @param  To     the second date\r
-\r
-  @retval TRUE   From is previous to To within 24 hours.\r
-  @retval FALSE  From is later, or it is previous to To more than 24 hours.\r
-**/\r
-BOOLEAN\r
-IsWithinOneDay (\r
-  IN EFI_TIME  *From,\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
-\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
-  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 == DayOfMonth[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
diff --git a/MdeModulePkg/Universal/PcatRealTimeClockRuntimeDxe/PcRtc.h b/MdeModulePkg/Universal/PcatRealTimeClockRuntimeDxe/PcRtc.h
deleted file mode 100644 (file)
index 90cfa39..0000000
+++ /dev/null
@@ -1,364 +0,0 @@
-/** @file\r
-  Header file for real time clock driver.\r
-\r
-Copyright (c) 2006 - 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
-**/\r
-\r
-\r
-#ifndef _RTC_H_\r
-#define _RTC_H_\r
-\r
-\r
-#include <Uefi.h>\r
-\r
-#include <Protocol/RealTimeClock.h>\r
-\r
-#include <Library/BaseLib.h>\r
-#include <Library/DebugLib.h>\r
-#include <Library/UefiLib.h>\r
-#include <Library/BaseMemoryLib.h>\r
-#include <Library/IoLib.h>\r
-#include <Library/TimerLib.h>\r
-#include <Library/UefiDriverEntryPoint.h>\r
-#include <Library/UefiBootServicesTableLib.h>\r
-#include <Library/UefiRuntimeLib.h>\r
-#include <Library/UefiRuntimeServicesTableLib.h>\r
-#include <Library/PcdLib.h>\r
-\r
-\r
-typedef struct {\r
-  EFI_LOCK  RtcLock;\r
-  INT16     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
-/**\r
-  Initialize RTC.\r
-\r
-  @param  Global            For global use inside this module.\r
-\r
-  @retval EFI_DEVICE_ERROR  Initialization failed due to device error.\r
-  @retval EFI_SUCCESS       Initialization successful.\r
-\r
-**/\r
-EFI_STATUS\r
-PcRtcInit (\r
-  IN PC_RTC_MODULE_GLOBALS  *Global\r
-  );\r
-\r
-/**\r
-  Sets the current local time and date information.\r
-\r
-  @param  Time                  A pointer to the current time.\r
-  @param  Global                For global use inside this module.\r
-\r
-  @retval EFI_SUCCESS           The operation completed successfully.\r
-  @retval EFI_INVALID_PARAMETER A time field is out of range.\r
-  @retval EFI_DEVICE_ERROR      The time could not be set due due to hardware error.\r
-\r
-**/\r
-EFI_STATUS\r
-PcRtcSetTime (\r
-  IN EFI_TIME               *Time,\r
-  IN PC_RTC_MODULE_GLOBALS  *Global\r
-  );\r
-\r
-/**\r
-  Returns the current time and date information, and the time-keeping capabilities\r
-  of the hardware platform.\r
-\r
-  @param  Time          A pointer to storage to receive a snapshot of the current time.\r
-  @param  Capabilities  An optional pointer to a buffer to receive the real time clock\r
-                        device's capabilities.\r
-  @param  Global        For global use inside this module.\r
-\r
-  @retval EFI_SUCCESS            The operation completed successfully.\r
-  @retval EFI_INVALID_PARAMETER  Time is NULL.\r
-  @retval EFI_DEVICE_ERROR       The time could not be retrieved due to hardware error.\r
-\r
-**/\r
-EFI_STATUS\r
-PcRtcGetTime (\r
-  OUT EFI_TIME              *Time,\r
-  OUT EFI_TIME_CAPABILITIES *Capabilities, OPTIONAL\r
-  IN  PC_RTC_MODULE_GLOBALS *Global\r
-  );\r
-\r
-/**\r
-  Sets the system wakeup alarm clock time.\r
-\r
-  @param  Enabled  Enable or disable the wakeup alarm.\r
-  @param  Time     If Enable is TRUE, the time to set the wakeup alarm for.\r
-                   If Enable is FALSE, then this parameter is optional, and may be NULL.\r
-  @param  Global   For global use inside this module.\r
-\r
-  @retval EFI_SUCCESS           If Enable is TRUE, then the wakeup alarm was enabled.\r
-                                If Enable is FALSE, then the wakeup alarm was disabled.\r
-  @retval EFI_INVALID_PARAMETER A time field is out of range.\r
-  @retval EFI_DEVICE_ERROR      The wakeup time could not be set due to a hardware error.\r
-  @retval EFI_UNSUPPORTED       A wakeup timer is not supported on this platform.\r
-\r
-**/\r
-EFI_STATUS\r
-PcRtcSetWakeupTime (\r
-  IN BOOLEAN                Enable,\r
-  IN EFI_TIME               *Time,  OPTIONAL\r
-  IN PC_RTC_MODULE_GLOBALS  *Global\r
-  );\r
-\r
-/**\r
-  Returns the current wakeup alarm clock setting.\r
-\r
-  @param  Enabled  Indicates if the alarm is currently enabled or disabled.\r
-  @param  Pending  Indicates if the alarm signal is pending and requires acknowledgement.\r
-  @param  Time     The current alarm setting.\r
-  @param  Global   For global use inside this module.\r
-\r
-  @retval EFI_SUCCESS           The alarm settings were returned.\r
-  @retval EFI_INVALID_PARAMETER Enabled is NULL.\r
-  @retval EFI_INVALID_PARAMETER Pending is NULL.\r
-  @retval EFI_INVALID_PARAMETER Time is NULL.\r
-  @retval EFI_DEVICE_ERROR      The wakeup time could not be retrieved due to a hardware error.\r
-  @retval EFI_UNSUPPORTED       A wakeup timer is not supported on this platform.\r
-\r
-**/\r
-EFI_STATUS\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
-  The user Entry Point for PcRTC module.\r
-\r
-  This is the entrhy point for PcRTC module. It installs the UEFI runtime service\r
-  including GetTime(),SetTime(),GetWakeupTime(),and SetWakeupTime().\r
-\r
-  @param  ImageHandle    The firmware allocated handle for the EFI image.\r
-  @param  SystemTable    A pointer to the EFI System Table.\r
-\r
-  @retval EFI_SUCCESS    The entry point is executed successfully.\r
-  @retval Others         Some error occurs when executing this entry point.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-InitializePcRtc (\r
-  IN EFI_HANDLE                            ImageHandle,\r
-  IN EFI_SYSTEM_TABLE                      *SystemTable\r
-  );\r
-\r
-/**\r
-  See if all fields of a variable of EFI_TIME type is correct.\r
-\r
-  @param   Time   The time to be checked.\r
-\r
-  @retval  EFI_INVALID_PARAMETER  Some fields of Time are not correct.\r
-  @retval  EFI_SUCCESS            Time is a valid EFI_TIME variable.\r
-\r
-**/\r
-EFI_STATUS\r
-RtcTimeFieldsValid (\r
-  IN EFI_TIME *Time\r
-  );\r
-\r
-/**\r
-  Converts time from EFI_TIME format defined by UEFI spec to RTC's.\r
-\r
-  This function converts time from EFI_TIME format defined by UEFI spec to RTC's.\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
-  @param   Time       On input, the time data read from UEFI to convert\r
-                      On output, the time converted to RTC format\r
-  @param   RegisterB  Value of Register B of RTC, indicating data mode\r
-  @param   Century    It is set according to EFI_TIME Time.\r
-\r
-**/\r
-VOID\r
-ConvertEfiTimeToRtcTime (\r
-  IN OUT EFI_TIME        *Time,\r
-  IN     RTC_REGISTER_B  RegisterB,\r
-  OUT    UINT8           *Century\r
-  );\r
-\r
-\r
-/**\r
-  Converts time read from RTC to EFI_TIME format defined by UEFI spec.\r
-\r
-  This function converts raw time data read from RTC to the EFI_TIME format\r
-  defined by UEFI spec.\r
-  If data mode of RTC is BCD, then converts it to decimal,\r
-  If RTC is in 12-hour format, then converts it to 24-hour format.\r
-\r
-  @param   Time       On input, the time data read from RTC to convert\r
-                      On output, the time converted to UEFI format\r
-  @param   Century    Value of century read from RTC.\r
-  @param   RegisterB  Value of Register B of RTC, indicating data mode\r
-                      and hour format.\r
-\r
-  @retval  EFI_INVALID_PARAMETER  Parameters passed in are invalid.\r
-  @retval  EFI_SUCCESS            Convert RTC time to EFI time successfully.\r
-\r
-**/\r
-EFI_STATUS\r
-ConvertRtcTimeToEfiTime (\r
-  IN OUT EFI_TIME        *Time,\r
-  IN     UINT8           Century,\r
-  IN     RTC_REGISTER_B  RegisterB\r
-  );\r
-\r
-/**\r
-  Wait for a period for the RTC to be ready.\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
-**/\r
-EFI_STATUS\r
-RtcWaitToUpdate (\r
-  UINTN Timeout\r
-  );\r
-\r
-/**\r
-  See if field Day of an EFI_TIME is correct.\r
-\r
-  @param    Time   Its Day field is to be checked.\r
-\r
-  @retval   TRUE   Day field of Time is correct.\r
-  @retval   FALSE  Day field of Time is NOT correct.\r
-**/\r
-BOOLEAN\r
-DayValid (\r
-  IN  EFI_TIME  *Time\r
-  );\r
-\r
-/**\r
-  Check if it is a leapyear.\r
-\r
-  @param    Time   The time to be checked.\r
-\r
-  @retval   TRUE   It is a leapyear.\r
-  @retval   FALSE  It is NOT a leapyear.\r
-**/\r
-BOOLEAN\r
-IsLeapYear (\r
-  IN EFI_TIME   *Time\r
-  );\r
-\r
-#endif\r
diff --git a/MdeModulePkg/Universal/PcatRealTimeClockRuntimeDxe/PcRtcEntry.c b/MdeModulePkg/Universal/PcatRealTimeClockRuntimeDxe/PcRtcEntry.c
deleted file mode 100644 (file)
index ce3fa90..0000000
+++ /dev/null
@@ -1,158 +0,0 @@
-/** @file\r
-  Provides Set/Get time operations.\r
-\r
-Copyright (c) 2006 - 2008, 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
-**/\r
-\r
-#include "PcRtc.h"\r
-\r
-PC_RTC_MODULE_GLOBALS  mModuleGlobal;\r
-\r
-EFI_HANDLE             mHandle = NULL;\r
-\r
-\r
-/**\r
-  Returns the current time and date information, and the time-keeping capabilities\r
-  of the hardware platform.\r
-\r
-  @param  Time          A pointer to storage to receive a snapshot of the current time.\r
-  @param  Capabilities  An optional pointer to a buffer to receive the real time\r
-                        clock device's capabilities.\r
-\r
-  @retval EFI_SUCCESS            The operation completed successfully.\r
-  @retval EFI_INVALID_PARAMETER  Time is NULL.\r
-  @retval EFI_DEVICE_ERROR       The time could not be retrieved due to hardware error.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-PcRtcEfiGetTime (\r
-  OUT EFI_TIME                *Time,\r
-  OUT EFI_TIME_CAPABILITIES   *Capabilities  OPTIONAL\r
-  )\r
-{\r
-  return PcRtcGetTime (Time, Capabilities, &mModuleGlobal);\r
-}\r
-\r
-/**\r
-  Sets the current local time and date information.\r
-\r
-  @param  Time                   A pointer to the current time.\r
-\r
-  @retval EFI_SUCCESS            The operation completed successfully.\r
-  @retval EFI_INVALID_PARAMETER  A time field is out of range.\r
-  @retval EFI_DEVICE_ERROR       The time could not be set due due to hardware error.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-PcRtcEfiSetTime (\r
-  IN EFI_TIME                *Time\r
-  )\r
-{\r
-  return PcRtcSetTime (Time, &mModuleGlobal);\r
-}\r
-\r
-/**\r
-  Returns the current wakeup alarm clock setting.\r
-\r
-  @param  Enabled  Indicates if the alarm is currently enabled or disabled.\r
-  @param  Pending  Indicates if the alarm signal is pending and requires acknowledgement.\r
-  @param  Time     The current alarm setting.\r
-\r
-  @retval EFI_SUCCESS           The alarm settings were returned.\r
-  @retval EFI_INVALID_PARAMETER Enabled is NULL.\r
-  @retval EFI_INVALID_PARAMETER Pending is NULL.\r
-  @retval EFI_INVALID_PARAMETER Time is NULL.\r
-  @retval EFI_DEVICE_ERROR      The wakeup time could not be retrieved due to a hardware error.\r
-  @retval EFI_UNSUPPORTED       A wakeup timer is not supported on this platform.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-PcRtcEfiGetWakeupTime (\r
-  OUT BOOLEAN     *Enabled,\r
-  OUT BOOLEAN     *Pending,\r
-  OUT EFI_TIME    *Time\r
-  )\r
-{\r
-  return PcRtcGetWakeupTime (Enabled, Pending, Time, &mModuleGlobal);\r
-}\r
-\r
-\r
-/**\r
-  Sets the system wakeup alarm clock time.\r
-\r
-  @param  Enabled  Enable or disable the wakeup alarm.\r
-  @param  Time     If Enable is TRUE, the time to set the wakeup alarm for.\r
-                   If Enable is FALSE, then this parameter is optional, and may be NULL.\r
-\r
-  @retval EFI_SUCCESS            If Enable is TRUE, then the wakeup alarm was enabled.\r
-                                 If Enable is FALSE, then the wakeup alarm was disabled.\r
-  @retval EFI_INVALID_PARAMETER  A time field is out of range.\r
-  @retval EFI_DEVICE_ERROR       The wakeup time could not be set due to a hardware error.\r
-  @retval EFI_UNSUPPORTED        A wakeup timer is not supported on this platform.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-PcRtcEfiSetWakeupTime (\r
-  IN BOOLEAN      Enabled,\r
-  IN EFI_TIME    *Time       OPTIONAL\r
-  )\r
-{\r
-  return PcRtcSetWakeupTime (Enabled, Time, &mModuleGlobal);\r
-}\r
-\r
-/**\r
-  The user Entry Point for PcRTC module.\r
-\r
-  This is the entrhy point for PcRTC module. It installs the UEFI runtime service\r
-  including GetTime(),SetTime(),GetWakeupTime(),and SetWakeupTime().\r
-\r
-  @param  ImageHandle    The firmware allocated handle for the EFI image.\r
-  @param  SystemTable    A pointer to the EFI System Table.\r
-\r
-  @retval EFI_SUCCESS    The entry point is executed successfully.\r
-  @retval Others         Some error occurs when executing this entry point.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-InitializePcRtc (\r
-  IN EFI_HANDLE                            ImageHandle,\r
-  IN EFI_SYSTEM_TABLE                      *SystemTable\r
-  )\r
-{\r
-  EFI_STATUS  Status;\r
-\r
-  EfiInitializeLock (&mModuleGlobal.RtcLock, TPL_HIGH_LEVEL);\r
-\r
-  Status = PcRtcInit (&mModuleGlobal);\r
-  if (EFI_ERROR (Status)) {\r
-    return Status;\r
-  }\r
-\r
-  gRT->GetTime       = PcRtcEfiGetTime;\r
-  gRT->SetTime       = PcRtcEfiSetTime;\r
-  gRT->GetWakeupTime = PcRtcEfiGetWakeupTime;\r
-  gRT->SetWakeupTime = PcRtcEfiSetWakeupTime;\r
-\r
-  Status = gBS->InstallMultipleProtocolInterfaces (\r
-                  &mHandle,\r
-                  &gEfiRealTimeClockArchProtocolGuid,\r
-                  NULL,\r
-                  NULL\r
-                  );\r
-  ASSERT_EFI_ERROR (Status);\r
-\r
-  return Status;\r
-}\r
diff --git a/MdeModulePkg/Universal/PcatRealTimeClockRuntimeDxe/PcatRealTimeClockRuntimeDxe.inf b/MdeModulePkg/Universal/PcatRealTimeClockRuntimeDxe/PcatRealTimeClockRuntimeDxe.inf
deleted file mode 100644 (file)
index e9cdf48..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-#/** @file\r
-#\r
-#  PcRtc driver to install EFI_REAL_TIME_CLOCK_ARCH_PROTOCOL.\r
-#\r
-#  This driver provides GetTime, SetTime, GetWakeupTime, SetWakeupTime services to Runtime Service Table.\r
-#  It will install a tagging protocol with gEfiRealTimeClockArchProtocolGuid.\r
-#\r
-#  Copyright (c) 2006 - 2008 Intel Corporation. <BR>\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
-#**/\r
-\r
-[Defines]\r
-  INF_VERSION                    = 0x00010005\r
-  BASE_NAME                      = PcRtc\r
-  FILE_GUID                      = 378D7B65-8DA9-4773-B6E4-A47826A833E1\r
-  MODULE_TYPE                    = DXE_RUNTIME_DRIVER\r
-  VERSION_STRING                 = 1.0\r
-  ENTRY_POINT                    = InitializePcRtc\r
-\r
-#\r
-# The following information is for reference only and not required by the build tools.\r
-#\r
-#  VALID_ARCHITECTURES           = IA32 X64 EBC\r
-#\r
-\r
-[Sources.common]\r
-  PcRtcEntry.c\r
-  PcRtc.c\r
-  PcRtc.h\r
-\r
-[Packages]\r
-  MdePkg/MdePkg.dec\r
-  MdeModulePkg/MdeModulePkg.dec\r
-\r
-[LibraryClasses]\r
-  UefiRuntimeServicesTableLib\r
-  UefiRuntimeLib\r
-  UefiBootServicesTableLib\r
-  UefiDriverEntryPoint\r
-  TimerLib\r
-  IoLib\r
-  BaseMemoryLib\r
-  UefiLib\r
-  DebugLib\r
-  BaseLib\r
-  PcdLib\r
-\r
-[Protocols]\r
-  gEfiRealTimeClockArchProtocolGuid             ## PRODUCES\r
-\r
-[Depex]\r
-  gEfiVariableArchProtocolGuid AND gEfiVariableWriteArchProtocolGuid\r
-  \r
-[Pcd]\r
-  gEfiMdeModulePkgTokenSpaceGuid.PcdRealTimeClockUpdateTimeout         ## CONSUMES
\ No newline at end of file
diff --git a/PcAtChipsetPkg/PcatRealTimeClockRuntimeDxe/PcRtc.c b/PcAtChipsetPkg/PcatRealTimeClockRuntimeDxe/PcRtc.c
new file mode 100644 (file)
index 0000000..d26e923
--- /dev/null
@@ -0,0 +1,1059 @@
+/** @file\r
+  RTC Architectural Protocol GUID as defined in DxeCis 0.96.\r
+\r
+Copyright (c) 2006 - 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
+**/\r
+\r
+#include "PcRtc.h"\r
+\r
+/**\r
+  Compare the Hour, Minute and Second of the From time and the To time.\r
+  \r
+  Only compare H/M/S in EFI_TIME and ignore other fields here.\r
+\r
+  @param From   the first time\r
+  @param To     the second time\r
+\r
+  @return  >0   The H/M/S of the From time is later than those of To time\r
+  @return  ==0  The H/M/S of the From time is same as those of To time\r
+  @return  <0   The H/M/S of the From time is earlier than those of To time\r
+**/\r
+INTN\r
+CompareHMS (\r
+  IN EFI_TIME   *From,\r
+  IN EFI_TIME   *To\r
+  );\r
+\r
+/**\r
+  To check if second date is later than first date within 24 hours.\r
+\r
+  @param  From   the first date\r
+  @param  To     the second date\r
+\r
+  @retval TRUE   From is previous to To within 24 hours.\r
+  @retval FALSE  From is later, or it is previous to To more than 24 hours.\r
+**/\r
+BOOLEAN\r
+IsWithinOneDay (\r
+  IN EFI_TIME   *From,\r
+  IN EFI_TIME   *To\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
+\r
+  @return The data of UINT8 type read from RTC.\r
+**/\r
+UINT8\r
+RtcRead (\r
+  IN  UINT8 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
+}\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
+\r
+**/\r
+VOID\r
+RtcWrite (\r
+  IN  UINT8   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
+}\r
+\r
+/**\r
+  Initialize RTC.\r
+\r
+  @param  Global            For global use inside this module.\r
+\r
+  @retval EFI_DEVICE_ERROR  Initialization failed due to device error.\r
+  @retval EFI_SUCCESS       Initialization successful.\r
+\r
+**/\r
+EFI_STATUS\r
+PcRtcInit (\r
+  IN PC_RTC_MODULE_GLOBALS  *Global\r
+  )\r
+{\r
+  EFI_STATUS      Status;\r
+  RTC_REGISTER_A  RegisterA;\r
+  RTC_REGISTER_B  RegisterB;\r
+  RTC_REGISTER_D  RegisterD;\r
+  UINT8           Century;\r
+  EFI_TIME        Time;\r
+  UINTN           DataSize;\r
+  UINT32          TimerVar;\r
+\r
+  //\r
+  // Acquire RTC Lock to make access to RTC atomic\r
+  //\r
+  //Code here doesn't consider the runtime environment.\r
+  if (!EfiAtRuntime ()) {\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
+  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
+  Status = RtcWaitToUpdate (PcdGet32 (PcdRealTimeClockUpdateTimeout));\r
+  if (EFI_ERROR (Status)) {\r
+    //Code here doesn't consider the runtime environment.\r
+    if (!EfiAtRuntime ()) {\r
+      EfiReleaseLock (&Global->RtcLock);\r
+    }\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
+  Century = RtcRead (RTC_ADDRESS_CENTURY);\r
+  \r
+  //\r
+  // Set RTC configuration after get original time\r
+  // The value of bit AIE should be reserved.\r
+  //\r
+  RtcWrite (RTC_ADDRESS_REGISTER_B, (UINT8)(RTC_INIT_REGISTER_B | (RegisterB.Data & BIT5)));\r
+\r
+  //\r
+  // Release RTC Lock.\r
+  //\r
+  //Code here doesn't consider the runtime environment.\r
+  if (!EfiAtRuntime ()) {\r
+    EfiReleaseLock (&Global->RtcLock);\r
+  }\r
\r
+  //\r
+  // Validate time fields\r
+  //\r
+  Status = ConvertRtcTimeToEfiTime (&Time, Century, RegisterB);\r
+  if (!EFI_ERROR (Status)) {\r
+    Status = RtcTimeFieldsValid (&Time);\r
+  }\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
+  // 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
+  if (!EFI_ERROR (Status)) {\r
+    Global->SavedTimeZone = (INT16) TimerVar;\r
+    Global->Daylight      = (UINT8) (TimerVar >> 16);\r
+\r
+    Time.TimeZone = Global->SavedTimeZone;\r
+    Time.Daylight = Global->Daylight;\r
+  }\r
+  //\r
+  // Reset time value according to new RTC configuration\r
+  //\r
+  PcRtcSetTime (&Time, Global);\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Returns the current time and date information, and the time-keeping capabilities\r
+  of the hardware platform.\r
+\r
+  @param  Time          A pointer to storage to receive a snapshot of the current time.\r
+  @param  Capabilities  An optional pointer to a buffer to receive the real time clock\r
+                        device's capabilities.\r
+  @param  Global        For global use inside this module.\r
+\r
+  @retval EFI_SUCCESS            The operation completed successfully.\r
+  @retval EFI_INVALID_PARAMETER  Time is NULL.\r
+  @retval EFI_DEVICE_ERROR       The time could not be retrieved due to hardware error.\r
+\r
+**/\r
+EFI_STATUS\r
+PcRtcGetTime (\r
+  OUT  EFI_TIME               *Time,\r
+  OUT  EFI_TIME_CAPABILITIES  *Capabilities,  OPTIONAL\r
+  IN   PC_RTC_MODULE_GLOBALS  *Global\r
+  )\r
+{\r
+  EFI_STATUS      Status;\r
+  RTC_REGISTER_B  RegisterB;\r
+  UINT8           Century;\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
+  //Code here doesn't consider the runtime environment.\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
+      //Code here doesn't consider the runtime environment.\r
+      if (!EfiAtRuntime ()) {\r
+        EfiReleaseLock (&Global->RtcLock);\r
+      }\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
+  Century = RtcRead (RTC_ADDRESS_CENTURY);\r
+  \r
+  //\r
+  // Release RTC Lock.\r
+  //\r
+  //Code here doesn't consider the runtime environment.\r
+  if (!EfiAtRuntime ()) {\r
+    EfiReleaseLock (&Global->RtcLock);\r
+  }\r
+  //\r
+  // Get the variable that contains the TimeZone and Daylight fields\r
+  //\r
+  Time->TimeZone  = Global->SavedTimeZone;\r
+  Time->Daylight  = Global->Daylight;\r
+\r
+  //\r
+  // Make sure all field values are in correct range\r
+  //\r
+  Status = ConvertRtcTimeToEfiTime (Time, Century, RegisterB);\r
+  if (!EFI_ERROR (Status)) {\r
+    Status = RtcTimeFieldsValid (Time);\r
+  }\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 != NULL) {\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
+/**\r
+  Sets the current local time and date information.\r
+\r
+  @param  Time                  A pointer to the current time.\r
+  @param  Global                For global use inside this module.\r
+\r
+  @retval EFI_SUCCESS           The operation completed successfully.\r
+  @retval EFI_INVALID_PARAMETER A time field is out of range.\r
+  @retval EFI_DEVICE_ERROR      The time could not be set due due to hardware error.\r
+\r
+**/\r
+EFI_STATUS\r
+PcRtcSetTime (\r
+  IN EFI_TIME                *Time,\r
+  IN PC_RTC_MODULE_GLOBALS   *Global\r
+  )\r
+{\r
+  EFI_STATUS      Status;\r
+  EFI_TIME        RtcTime;\r
+  RTC_REGISTER_B  RegisterB;\r
+  UINT8           Century;\r
+  UINT32          TimerVar;\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
+  //Code here doesn't consider the runtime environment.\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
+     //Code here doesn't consider the runtime environment.\r
+     if (!EfiAtRuntime ()) {\r
+       EfiReleaseLock (&Global->RtcLock);\r
+     }\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
+  //Code here doesn't consider the runtime environment.\r
+  if (!EfiAtRuntime ()) {\r
+    EfiReleaseLock (&Global->RtcLock);\r
+  }\r
+  //\r
+  // Set the variable that contains the TimeZone and Daylight fields\r
+  //\r
+  Global->SavedTimeZone = Time->TimeZone;\r
+  Global->Daylight      = Time->Daylight;\r
+\r
+  TimerVar = Time->Daylight;\r
+  TimerVar = (UINT32) ((TimerVar << 16) | 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
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Returns the current wakeup alarm clock setting.\r
+\r
+  @param  Enabled  Indicates if the alarm is currently enabled or disabled.\r
+  @param  Pending  Indicates if the alarm signal is pending and requires acknowledgment.\r
+  @param  Time     The current alarm setting.\r
+  @param  Global   For global use inside this module.\r
+\r
+  @retval EFI_SUCCESS           The alarm settings were returned.\r
+  @retval EFI_INVALID_PARAMETER Enabled is NULL.\r
+  @retval EFI_INVALID_PARAMETER Pending is NULL.\r
+  @retval EFI_INVALID_PARAMETER Time is NULL.\r
+  @retval EFI_DEVICE_ERROR      The wakeup time could not be retrieved due to a hardware error.\r
+  @retval EFI_UNSUPPORTED       A wakeup timer is not supported on this platform.\r
+\r
+**/\r
+EFI_STATUS\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
+  EFI_STATUS      Status;\r
+  RTC_REGISTER_B  RegisterB;\r
+  RTC_REGISTER_C  RegisterC;\r
+  UINT8           Century;\r
+\r
+  //\r
+  // Check parameters 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
+  //Code here doesn't consider the runtime environment.\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
+    //Code here doesn't consider the runtime environment.\r
+    if (!EfiAtRuntime ()) {\r
+    EfiReleaseLock (&Global->RtcLock);\r
+    }\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
+  Century = RtcRead (RTC_ADDRESS_CENTURY);\r
+  \r
+  //\r
+  // Release RTC Lock.\r
+  //\r
+  //Code here doesn't consider the runtime environment.\r
+  if (!EfiAtRuntime ()) {\r
+    EfiReleaseLock (&Global->RtcLock);\r
+  }\r
+  //\r
+  // Make sure all field values are in correct range\r
+  //\r
+  Status = ConvertRtcTimeToEfiTime (Time, Century, RegisterB);\r
+  if (!EFI_ERROR (Status)) {\r
+    Status = RtcTimeFieldsValid (Time);\r
+  }\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
+/**\r
+  Sets the system wakeup alarm clock time.\r
+\r
+  @param  Enabled  Enable or disable the wakeup alarm.\r
+  @param  Time     If Enable is TRUE, the time to set the wakeup alarm for.\r
+                   If Enable is FALSE, then this parameter is optional, and may be NULL.\r
+  @param  Global   For global use inside this module.\r
+\r
+  @retval EFI_SUCCESS           If Enable is TRUE, then the wakeup alarm was enabled.\r
+                                If Enable is FALSE, then the wakeup alarm was disabled.\r
+  @retval EFI_INVALID_PARAMETER A time field is out of range.\r
+  @retval EFI_DEVICE_ERROR      The wakeup time could not be set due to a hardware error.\r
+  @retval EFI_UNSUPPORTED       A wakeup timer is not supported on this platform.\r
+\r
+**/\r
+EFI_STATUS\r
+PcRtcSetWakeupTime (\r
+  IN BOOLEAN                Enable,\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
+  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
+    Status = RtcTimeFieldsValid (&RtcTime);\r
+    if (EFI_ERROR (Status)) {\r
+      return EFI_DEVICE_ERROR;\r
+    }\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
+  //Code here doesn't consider the runtime environment.\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
+    //Code here doesn't consider the runtime environment.\r
+    if (!EfiAtRuntime ()) {\r
+    EfiReleaseLock (&Global->RtcLock);\r
+    }\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
+  //Code here doesn't consider the runtime environment.\r
+  if (!EfiAtRuntime ()) {\r
+    EfiReleaseLock (&Global->RtcLock);\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
+  This function checks the 8-bit BCD value specified by Value.\r
+  If valid, the function converts it to an 8-bit value and returns it.\r
+  Otherwise, return 0xff.\r
+\r
+  @param   Value The 8-bit BCD value to check and convert\r
+\r
+  @return  The 8-bit value converted. Or 0xff if Value is invalid.\r
+\r
+**/\r
+UINT8\r
+CheckAndConvertBcd8ToDecimal8 (\r
+  IN  UINT8  Value\r
+  )\r
+{\r
+  if ((Value < 0xa0) && ((Value & 0xf) < 0xa)) {\r
+    return BcdToDecimal8 (Value);\r
+  }\r
+\r
+  return 0xff;\r
+}\r
+\r
+/**\r
+  Converts time read from RTC to EFI_TIME format defined by UEFI spec.\r
+\r
+  This function converts raw time data read from RTC to the EFI_TIME format\r
+  defined by UEFI spec.\r
+  If data mode of RTC is BCD, then converts it to decimal,\r
+  If RTC is in 12-hour format, then converts it to 24-hour format.\r
+\r
+  @param   Time       On input, the time data read from RTC to convert\r
+                      On output, the time converted to UEFI format\r
+  @param   Century    Value of century read from RTC.\r
+  @param   RegisterB  Value of Register B of RTC, indicating data mode\r
+                      and hour format.\r
+\r
+  @retval  EFI_INVALID_PARAMETER  Parameters passed in are invalid.\r
+  @retval  EFI_SUCCESS            Convert RTC time to EFI time successfully.\r
+\r
+**/\r
+EFI_STATUS\r
+ConvertRtcTimeToEfiTime (\r
+  IN OUT EFI_TIME        *Time,\r
+  IN     UINT8           Century,\r
+  IN     RTC_REGISTER_B  RegisterB\r
+  )\r
+{\r
+  BOOLEAN IsPM;\r
+\r
+  if ((Time->Hour & 0x80) != 0) {\r
+    IsPM = TRUE;\r
+  } else {\r
+    IsPM = FALSE;\r
+  }\r
+\r
+  Time->Hour = (UINT8) (Time->Hour & 0x7f);\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
+  }\r
+  Century       = CheckAndConvertBcd8ToDecimal8 (Century);\r
+\r
+  if (Time->Year == 0xff || Time->Month == 0xff || Time->Day == 0xff ||\r
+      Time->Hour == 0xff || Time->Minute == 0xff || Time->Second == 0xff ||\r
+      Century == 0xff) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\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
+    }\r
+\r
+    if (!IsPM && 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
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Wait for a period for the RTC to be ready.\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
+**/\r
+EFI_STATUS\r
+RtcWaitToUpdate (\r
+  UINTN Timeout\r
+  )\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
+/**\r
+  See if all fields of a variable of EFI_TIME type is correct.\r
+\r
+  @param   Time   The time to be checked.\r
+\r
+  @retval  EFI_INVALID_PARAMETER  Some fields of Time are not correct.\r
+  @retval  EFI_SUCCESS            Time is a valid EFI_TIME variable.\r
+\r
+**/\r
+EFI_STATUS\r
+RtcTimeFieldsValid (\r
+  IN EFI_TIME *Time\r
+  )\r
+{\r
+  if (Time->Year < 1998 ||\r
+      Time->Year > 2099 ||\r
+      Time->Month < 1 ||\r
+      Time->Month > 12 ||\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
+    if (!DayValid (Time)) {\r
+      return EFI_INVALID_PARAMETER;\r
+    }\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  See if field Day of an EFI_TIME is correct.\r
+\r
+  @param    Time   Its Day field is to be checked.\r
+\r
+  @retval   TRUE   Day field of Time is correct.\r
+  @retval   FALSE  Day field of Time is NOT correct.\r
+**/\r
+BOOLEAN\r
+DayValid (\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
+    return FALSE;\r
+  }\r
+\r
+  return TRUE;\r
+}\r
+\r
+/**\r
+  Check if it is a leap year.\r
+\r
+  @param    Time   The time to be checked.\r
+\r
+  @retval   TRUE   It is a leap year.\r
+  @retval   FALSE  It is NOT a leap year.\r
+**/\r
+BOOLEAN\r
+IsLeapYear (\r
+  IN EFI_TIME   *Time\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
+/**\r
+  Converts time from EFI_TIME format defined by UEFI spec to RTC's.\r
+\r
+  This function converts time from EFI_TIME format defined by UEFI spec to RTC's.\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
+  @param   Time       On input, the time data read from UEFI to convert\r
+                      On output, the time converted to RTC format\r
+  @param   RegisterB  Value of Register B of RTC, indicating data mode\r
+  @param   Century    It is set according to EFI_TIME Time.\r
+\r
+**/\r
+VOID\r
+ConvertEfiTimeToRtcTime (\r
+  IN OUT EFI_TIME        *Time,\r
+  IN     RTC_REGISTER_B  RegisterB,\r
+     OUT UINT8           *Century\r
+  )\r
+{\r
+  BOOLEAN IsPM;\r
+\r
+  IsPM = TRUE;\r
+  //\r
+  // Adjust hour field if RTC is in 12 hour mode\r
+  //\r
+  if (RegisterB.Bits.MIL == 0) {\r
+    if (Time->Hour < 12) {\r
+      IsPM = 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    = DecimalToBcd8 ((UINT8) (Time->Year / 100));\r
+\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
+  }\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
+  }\r
+}\r
+\r
+/**\r
+  Compare the Hour, Minute and Second of the From time and the To time.\r
+  \r
+  Only compare H/M/S in EFI_TIME and ignore other fields here.\r
+\r
+  @param From   the first time\r
+  @param To     the second time\r
+\r
+  @return  >0   The H/M/S of the From time is later than those of To time\r
+  @return  ==0  The H/M/S of the From time is same as those of To time\r
+  @return  <0   The H/M/S of the From time is earlier than those of To time\r
+**/\r
+INTN\r
+CompareHMS (\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
+    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
+/**\r
+  To check if second date is later than first date within 24 hours.\r
+\r
+  @param  From   the first date\r
+  @param  To     the second date\r
+\r
+  @retval TRUE   From is previous to To within 24 hours.\r
+  @retval FALSE  From is later, or it is previous to To more than 24 hours.\r
+**/\r
+BOOLEAN\r
+IsWithinOneDay (\r
+  IN EFI_TIME  *From,\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
+\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
+  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 == DayOfMonth[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
diff --git a/PcAtChipsetPkg/PcatRealTimeClockRuntimeDxe/PcRtc.h b/PcAtChipsetPkg/PcatRealTimeClockRuntimeDxe/PcRtc.h
new file mode 100644 (file)
index 0000000..90cfa39
--- /dev/null
@@ -0,0 +1,364 @@
+/** @file\r
+  Header file for real time clock driver.\r
+\r
+Copyright (c) 2006 - 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
+**/\r
+\r
+\r
+#ifndef _RTC_H_\r
+#define _RTC_H_\r
+\r
+\r
+#include <Uefi.h>\r
+\r
+#include <Protocol/RealTimeClock.h>\r
+\r
+#include <Library/BaseLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/UefiLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/IoLib.h>\r
+#include <Library/TimerLib.h>\r
+#include <Library/UefiDriverEntryPoint.h>\r
+#include <Library/UefiBootServicesTableLib.h>\r
+#include <Library/UefiRuntimeLib.h>\r
+#include <Library/UefiRuntimeServicesTableLib.h>\r
+#include <Library/PcdLib.h>\r
+\r
+\r
+typedef struct {\r
+  EFI_LOCK  RtcLock;\r
+  INT16     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
+/**\r
+  Initialize RTC.\r
+\r
+  @param  Global            For global use inside this module.\r
+\r
+  @retval EFI_DEVICE_ERROR  Initialization failed due to device error.\r
+  @retval EFI_SUCCESS       Initialization successful.\r
+\r
+**/\r
+EFI_STATUS\r
+PcRtcInit (\r
+  IN PC_RTC_MODULE_GLOBALS  *Global\r
+  );\r
+\r
+/**\r
+  Sets the current local time and date information.\r
+\r
+  @param  Time                  A pointer to the current time.\r
+  @param  Global                For global use inside this module.\r
+\r
+  @retval EFI_SUCCESS           The operation completed successfully.\r
+  @retval EFI_INVALID_PARAMETER A time field is out of range.\r
+  @retval EFI_DEVICE_ERROR      The time could not be set due due to hardware error.\r
+\r
+**/\r
+EFI_STATUS\r
+PcRtcSetTime (\r
+  IN EFI_TIME               *Time,\r
+  IN PC_RTC_MODULE_GLOBALS  *Global\r
+  );\r
+\r
+/**\r
+  Returns the current time and date information, and the time-keeping capabilities\r
+  of the hardware platform.\r
+\r
+  @param  Time          A pointer to storage to receive a snapshot of the current time.\r
+  @param  Capabilities  An optional pointer to a buffer to receive the real time clock\r
+                        device's capabilities.\r
+  @param  Global        For global use inside this module.\r
+\r
+  @retval EFI_SUCCESS            The operation completed successfully.\r
+  @retval EFI_INVALID_PARAMETER  Time is NULL.\r
+  @retval EFI_DEVICE_ERROR       The time could not be retrieved due to hardware error.\r
+\r
+**/\r
+EFI_STATUS\r
+PcRtcGetTime (\r
+  OUT EFI_TIME              *Time,\r
+  OUT EFI_TIME_CAPABILITIES *Capabilities, OPTIONAL\r
+  IN  PC_RTC_MODULE_GLOBALS *Global\r
+  );\r
+\r
+/**\r
+  Sets the system wakeup alarm clock time.\r
+\r
+  @param  Enabled  Enable or disable the wakeup alarm.\r
+  @param  Time     If Enable is TRUE, the time to set the wakeup alarm for.\r
+                   If Enable is FALSE, then this parameter is optional, and may be NULL.\r
+  @param  Global   For global use inside this module.\r
+\r
+  @retval EFI_SUCCESS           If Enable is TRUE, then the wakeup alarm was enabled.\r
+                                If Enable is FALSE, then the wakeup alarm was disabled.\r
+  @retval EFI_INVALID_PARAMETER A time field is out of range.\r
+  @retval EFI_DEVICE_ERROR      The wakeup time could not be set due to a hardware error.\r
+  @retval EFI_UNSUPPORTED       A wakeup timer is not supported on this platform.\r
+\r
+**/\r
+EFI_STATUS\r
+PcRtcSetWakeupTime (\r
+  IN BOOLEAN                Enable,\r
+  IN EFI_TIME               *Time,  OPTIONAL\r
+  IN PC_RTC_MODULE_GLOBALS  *Global\r
+  );\r
+\r
+/**\r
+  Returns the current wakeup alarm clock setting.\r
+\r
+  @param  Enabled  Indicates if the alarm is currently enabled or disabled.\r
+  @param  Pending  Indicates if the alarm signal is pending and requires acknowledgement.\r
+  @param  Time     The current alarm setting.\r
+  @param  Global   For global use inside this module.\r
+\r
+  @retval EFI_SUCCESS           The alarm settings were returned.\r
+  @retval EFI_INVALID_PARAMETER Enabled is NULL.\r
+  @retval EFI_INVALID_PARAMETER Pending is NULL.\r
+  @retval EFI_INVALID_PARAMETER Time is NULL.\r
+  @retval EFI_DEVICE_ERROR      The wakeup time could not be retrieved due to a hardware error.\r
+  @retval EFI_UNSUPPORTED       A wakeup timer is not supported on this platform.\r
+\r
+**/\r
+EFI_STATUS\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
+  The user Entry Point for PcRTC module.\r
+\r
+  This is the entrhy point for PcRTC module. It installs the UEFI runtime service\r
+  including GetTime(),SetTime(),GetWakeupTime(),and SetWakeupTime().\r
+\r
+  @param  ImageHandle    The firmware allocated handle for the EFI image.\r
+  @param  SystemTable    A pointer to the EFI System Table.\r
+\r
+  @retval EFI_SUCCESS    The entry point is executed successfully.\r
+  @retval Others         Some error occurs when executing this entry point.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+InitializePcRtc (\r
+  IN EFI_HANDLE                            ImageHandle,\r
+  IN EFI_SYSTEM_TABLE                      *SystemTable\r
+  );\r
+\r
+/**\r
+  See if all fields of a variable of EFI_TIME type is correct.\r
+\r
+  @param   Time   The time to be checked.\r
+\r
+  @retval  EFI_INVALID_PARAMETER  Some fields of Time are not correct.\r
+  @retval  EFI_SUCCESS            Time is a valid EFI_TIME variable.\r
+\r
+**/\r
+EFI_STATUS\r
+RtcTimeFieldsValid (\r
+  IN EFI_TIME *Time\r
+  );\r
+\r
+/**\r
+  Converts time from EFI_TIME format defined by UEFI spec to RTC's.\r
+\r
+  This function converts time from EFI_TIME format defined by UEFI spec to RTC's.\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
+  @param   Time       On input, the time data read from UEFI to convert\r
+                      On output, the time converted to RTC format\r
+  @param   RegisterB  Value of Register B of RTC, indicating data mode\r
+  @param   Century    It is set according to EFI_TIME Time.\r
+\r
+**/\r
+VOID\r
+ConvertEfiTimeToRtcTime (\r
+  IN OUT EFI_TIME        *Time,\r
+  IN     RTC_REGISTER_B  RegisterB,\r
+  OUT    UINT8           *Century\r
+  );\r
+\r
+\r
+/**\r
+  Converts time read from RTC to EFI_TIME format defined by UEFI spec.\r
+\r
+  This function converts raw time data read from RTC to the EFI_TIME format\r
+  defined by UEFI spec.\r
+  If data mode of RTC is BCD, then converts it to decimal,\r
+  If RTC is in 12-hour format, then converts it to 24-hour format.\r
+\r
+  @param   Time       On input, the time data read from RTC to convert\r
+                      On output, the time converted to UEFI format\r
+  @param   Century    Value of century read from RTC.\r
+  @param   RegisterB  Value of Register B of RTC, indicating data mode\r
+                      and hour format.\r
+\r
+  @retval  EFI_INVALID_PARAMETER  Parameters passed in are invalid.\r
+  @retval  EFI_SUCCESS            Convert RTC time to EFI time successfully.\r
+\r
+**/\r
+EFI_STATUS\r
+ConvertRtcTimeToEfiTime (\r
+  IN OUT EFI_TIME        *Time,\r
+  IN     UINT8           Century,\r
+  IN     RTC_REGISTER_B  RegisterB\r
+  );\r
+\r
+/**\r
+  Wait for a period for the RTC to be ready.\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
+**/\r
+EFI_STATUS\r
+RtcWaitToUpdate (\r
+  UINTN Timeout\r
+  );\r
+\r
+/**\r
+  See if field Day of an EFI_TIME is correct.\r
+\r
+  @param    Time   Its Day field is to be checked.\r
+\r
+  @retval   TRUE   Day field of Time is correct.\r
+  @retval   FALSE  Day field of Time is NOT correct.\r
+**/\r
+BOOLEAN\r
+DayValid (\r
+  IN  EFI_TIME  *Time\r
+  );\r
+\r
+/**\r
+  Check if it is a leapyear.\r
+\r
+  @param    Time   The time to be checked.\r
+\r
+  @retval   TRUE   It is a leapyear.\r
+  @retval   FALSE  It is NOT a leapyear.\r
+**/\r
+BOOLEAN\r
+IsLeapYear (\r
+  IN EFI_TIME   *Time\r
+  );\r
+\r
+#endif\r
diff --git a/PcAtChipsetPkg/PcatRealTimeClockRuntimeDxe/PcRtcEntry.c b/PcAtChipsetPkg/PcatRealTimeClockRuntimeDxe/PcRtcEntry.c
new file mode 100644 (file)
index 0000000..ce3fa90
--- /dev/null
@@ -0,0 +1,158 @@
+/** @file\r
+  Provides Set/Get time operations.\r
+\r
+Copyright (c) 2006 - 2008, 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
+**/\r
+\r
+#include "PcRtc.h"\r
+\r
+PC_RTC_MODULE_GLOBALS  mModuleGlobal;\r
+\r
+EFI_HANDLE             mHandle = NULL;\r
+\r
+\r
+/**\r
+  Returns the current time and date information, and the time-keeping capabilities\r
+  of the hardware platform.\r
+\r
+  @param  Time          A pointer to storage to receive a snapshot of the current time.\r
+  @param  Capabilities  An optional pointer to a buffer to receive the real time\r
+                        clock device's capabilities.\r
+\r
+  @retval EFI_SUCCESS            The operation completed successfully.\r
+  @retval EFI_INVALID_PARAMETER  Time is NULL.\r
+  @retval EFI_DEVICE_ERROR       The time could not be retrieved due to hardware error.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+PcRtcEfiGetTime (\r
+  OUT EFI_TIME                *Time,\r
+  OUT EFI_TIME_CAPABILITIES   *Capabilities  OPTIONAL\r
+  )\r
+{\r
+  return PcRtcGetTime (Time, Capabilities, &mModuleGlobal);\r
+}\r
+\r
+/**\r
+  Sets the current local time and date information.\r
+\r
+  @param  Time                   A pointer to the current time.\r
+\r
+  @retval EFI_SUCCESS            The operation completed successfully.\r
+  @retval EFI_INVALID_PARAMETER  A time field is out of range.\r
+  @retval EFI_DEVICE_ERROR       The time could not be set due due to hardware error.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+PcRtcEfiSetTime (\r
+  IN EFI_TIME                *Time\r
+  )\r
+{\r
+  return PcRtcSetTime (Time, &mModuleGlobal);\r
+}\r
+\r
+/**\r
+  Returns the current wakeup alarm clock setting.\r
+\r
+  @param  Enabled  Indicates if the alarm is currently enabled or disabled.\r
+  @param  Pending  Indicates if the alarm signal is pending and requires acknowledgement.\r
+  @param  Time     The current alarm setting.\r
+\r
+  @retval EFI_SUCCESS           The alarm settings were returned.\r
+  @retval EFI_INVALID_PARAMETER Enabled is NULL.\r
+  @retval EFI_INVALID_PARAMETER Pending is NULL.\r
+  @retval EFI_INVALID_PARAMETER Time is NULL.\r
+  @retval EFI_DEVICE_ERROR      The wakeup time could not be retrieved due to a hardware error.\r
+  @retval EFI_UNSUPPORTED       A wakeup timer is not supported on this platform.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+PcRtcEfiGetWakeupTime (\r
+  OUT BOOLEAN     *Enabled,\r
+  OUT BOOLEAN     *Pending,\r
+  OUT EFI_TIME    *Time\r
+  )\r
+{\r
+  return PcRtcGetWakeupTime (Enabled, Pending, Time, &mModuleGlobal);\r
+}\r
+\r
+\r
+/**\r
+  Sets the system wakeup alarm clock time.\r
+\r
+  @param  Enabled  Enable or disable the wakeup alarm.\r
+  @param  Time     If Enable is TRUE, the time to set the wakeup alarm for.\r
+                   If Enable is FALSE, then this parameter is optional, and may be NULL.\r
+\r
+  @retval EFI_SUCCESS            If Enable is TRUE, then the wakeup alarm was enabled.\r
+                                 If Enable is FALSE, then the wakeup alarm was disabled.\r
+  @retval EFI_INVALID_PARAMETER  A time field is out of range.\r
+  @retval EFI_DEVICE_ERROR       The wakeup time could not be set due to a hardware error.\r
+  @retval EFI_UNSUPPORTED        A wakeup timer is not supported on this platform.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+PcRtcEfiSetWakeupTime (\r
+  IN BOOLEAN      Enabled,\r
+  IN EFI_TIME    *Time       OPTIONAL\r
+  )\r
+{\r
+  return PcRtcSetWakeupTime (Enabled, Time, &mModuleGlobal);\r
+}\r
+\r
+/**\r
+  The user Entry Point for PcRTC module.\r
+\r
+  This is the entrhy point for PcRTC module. It installs the UEFI runtime service\r
+  including GetTime(),SetTime(),GetWakeupTime(),and SetWakeupTime().\r
+\r
+  @param  ImageHandle    The firmware allocated handle for the EFI image.\r
+  @param  SystemTable    A pointer to the EFI System Table.\r
+\r
+  @retval EFI_SUCCESS    The entry point is executed successfully.\r
+  @retval Others         Some error occurs when executing this entry point.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+InitializePcRtc (\r
+  IN EFI_HANDLE                            ImageHandle,\r
+  IN EFI_SYSTEM_TABLE                      *SystemTable\r
+  )\r
+{\r
+  EFI_STATUS  Status;\r
+\r
+  EfiInitializeLock (&mModuleGlobal.RtcLock, TPL_HIGH_LEVEL);\r
+\r
+  Status = PcRtcInit (&mModuleGlobal);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  gRT->GetTime       = PcRtcEfiGetTime;\r
+  gRT->SetTime       = PcRtcEfiSetTime;\r
+  gRT->GetWakeupTime = PcRtcEfiGetWakeupTime;\r
+  gRT->SetWakeupTime = PcRtcEfiSetWakeupTime;\r
+\r
+  Status = gBS->InstallMultipleProtocolInterfaces (\r
+                  &mHandle,\r
+                  &gEfiRealTimeClockArchProtocolGuid,\r
+                  NULL,\r
+                  NULL\r
+                  );\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  return Status;\r
+}\r
diff --git a/PcAtChipsetPkg/PcatRealTimeClockRuntimeDxe/PcatRealTimeClockRuntimeDxe.inf b/PcAtChipsetPkg/PcatRealTimeClockRuntimeDxe/PcatRealTimeClockRuntimeDxe.inf
new file mode 100644 (file)
index 0000000..e9cdf48
--- /dev/null
@@ -0,0 +1,62 @@
+#/** @file\r
+#\r
+#  PcRtc driver to install EFI_REAL_TIME_CLOCK_ARCH_PROTOCOL.\r
+#\r
+#  This driver provides GetTime, SetTime, GetWakeupTime, SetWakeupTime services to Runtime Service Table.\r
+#  It will install a tagging protocol with gEfiRealTimeClockArchProtocolGuid.\r
+#\r
+#  Copyright (c) 2006 - 2008 Intel Corporation. <BR>\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
+#**/\r
+\r
+[Defines]\r
+  INF_VERSION                    = 0x00010005\r
+  BASE_NAME                      = PcRtc\r
+  FILE_GUID                      = 378D7B65-8DA9-4773-B6E4-A47826A833E1\r
+  MODULE_TYPE                    = DXE_RUNTIME_DRIVER\r
+  VERSION_STRING                 = 1.0\r
+  ENTRY_POINT                    = InitializePcRtc\r
+\r
+#\r
+# The following information is for reference only and not required by the build tools.\r
+#\r
+#  VALID_ARCHITECTURES           = IA32 X64 EBC\r
+#\r
+\r
+[Sources.common]\r
+  PcRtcEntry.c\r
+  PcRtc.c\r
+  PcRtc.h\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+  MdeModulePkg/MdeModulePkg.dec\r
+\r
+[LibraryClasses]\r
+  UefiRuntimeServicesTableLib\r
+  UefiRuntimeLib\r
+  UefiBootServicesTableLib\r
+  UefiDriverEntryPoint\r
+  TimerLib\r
+  IoLib\r
+  BaseMemoryLib\r
+  UefiLib\r
+  DebugLib\r
+  BaseLib\r
+  PcdLib\r
+\r
+[Protocols]\r
+  gEfiRealTimeClockArchProtocolGuid             ## PRODUCES\r
+\r
+[Depex]\r
+  gEfiVariableArchProtocolGuid AND gEfiVariableWriteArchProtocolGuid\r
+  \r
+[Pcd]\r
+  gEfiMdeModulePkgTokenSpaceGuid.PcdRealTimeClockUpdateTimeout         ## CONSUMES
\ No newline at end of file