]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Universal/PcatRealTimeClockRuntimeDxe/PcRtc.c
Fix date/time not work for the return value of RtcRead not need type convert.
[mirror_edk2.git] / MdeModulePkg / Universal / PcatRealTimeClockRuntimeDxe / PcRtc.c
index a58aee5f8a53d793fdaf72c6d391e78b6f032456..cf5ed0bf5a7d2870c64e551e59dec2b524508d97 100644 (file)
-/*++\r
+/** @file\r
+  RTC Architectural Protocol GUID as defined in DxeCis 0.96.\r
 \r
-Copyright (c) 2006 - 2007, Intel Corporation. All rights reserved. <BR>\r
-This software and associated documentation (if any) is furnished\r
-under a license and may only be used or copied in accordance\r
-with the terms of the license. Except as permitted by such\r
-license, no part of this software or documentation may be\r
-reproduced, stored in a retrieval system, or transmitted in any\r
-form or by any means without the express written consent of\r
-Intel Corporation.\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
-Module Name:\r
-\r
-  PcRtc.c\r
-\r
-Abstract:\r
-\r
-  RTC Architectural Protocol GUID as defined in DxeCis 0.96\r
+#include "PcRtc.h"\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
-#include "PcRtc.h"\r
+  @param From   the first time\r
+  @param To     the second time\r
 \r
-STATIC\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
-STATIC\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
-STATIC\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
-\r
-Routine Description:\r
-\r
-  GC_TODO: Add function description\r
-\r
-Arguments:\r
-\r
-  Address - GC_TODO: add argument description\r
-\r
-Returns:\r
-\r
-  GC_TODO: add return values\r
-\r
---*/\r
 {\r
   IoWrite8 (PCAT_RTC_ADDRESS_REGISTER, (UINT8) (Address | (UINT8) (IoRead8 (PCAT_RTC_ADDRESS_REGISTER) & 0x80)));\r
   return IoRead8 (PCAT_RTC_DATA_REGISTER);\r
 }\r
 \r
-STATIC\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
-\r
-Routine Description:\r
-\r
-  GC_TODO: Add function description\r
-\r
-Arguments:\r
-\r
-  Address - GC_TODO: add argument description\r
-  Data    - GC_TODO: add argument description\r
-\r
-Returns:\r
-\r
-  GC_TODO: add return values\r
-\r
---*/\r
 {\r
   IoWrite8 (PCAT_RTC_ADDRESS_REGISTER, (UINT8) (Address | (UINT8) (IoRead8 (PCAT_RTC_ADDRESS_REGISTER) & 0x80)));\r
   IoWrite8 (PCAT_RTC_DATA_REGISTER, Data);\r
 }\r
 \r
+/**\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
-Routine Description:\r
-\r
-  GC_TODO: Add function description\r
-\r
-Arguments:\r
-\r
-  Global  - GC_TODO: add argument description\r
-\r
-Returns:\r
-\r
-  EFI_DEVICE_ERROR - GC_TODO: Add description for return value\r
-  EFI_SUCCESS - GC_TODO: Add description for return value\r
-\r
---*/\r
 {\r
   EFI_STATUS      Status;\r
   RTC_REGISTER_A  RegisterA;\r
@@ -116,14 +102,15 @@ Returns:
   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
-  //BugBug: the EfiAtRuntime should be encapsulated in EfiAcquireLock or\r
-  //        provide a new instance for EfiAcquireLock, say, RtEfiAcquireLock\r
+  //Code here doesn't consider the runtime environment.\r
   if (!EfiAtRuntime ()) {\r
-  EfiAcquireLock (&Global->RtcLock);\r
+    EfiAcquireLock (&Global->RtcLock);\r
   }\r
   //\r
   // Initialize RTC Register\r
@@ -153,12 +140,11 @@ Returns:
   //\r
   // Wait for up to 0.1 seconds for the RTC to be updated\r
   //\r
-  Status = RtcWaitToUpdate (100000);\r
+  Status = RtcWaitToUpdate (PcdGet32 (PcdRealTimeClockUpdateTimeout));\r
   if (EFI_ERROR (Status)) {\r
-       //BugBug: the EfiAtRuntime should be encapsulated in EfiAcquireLock or\r
-    //        provide a new instance for EfiAcquireLock, say, RtEfiAcquireLock\r
+    //Code here doesn't consider the runtime environment.\r
     if (!EfiAtRuntime ()) {\r
-    EfiReleaseLock (&Global->RtcLock);\r
+      EfiReleaseLock (&Global->RtcLock);\r
     }\r
     return EFI_DEVICE_ERROR;\r
   }\r
@@ -172,33 +158,30 @@ Returns:
   Time.Month  = RtcRead (RTC_ADDRESS_MONTH);\r
   Time.Year   = RtcRead (RTC_ADDRESS_YEAR);\r
 \r
-  ConvertRtcTimeToEfiTime (&Time, RegisterB);\r
-\r
-  if (RtcTestCenturyRegister () == EFI_SUCCESS) {\r
-    Century = BcdToDecimal8 ((UINT8) (RtcRead (RTC_ADDRESS_CENTURY) & 0x7f));\r
-  } else {\r
-    Century = BcdToDecimal8 (RtcRead (RTC_ADDRESS_CENTURY));\r
-  }\r
-\r
+  Century = RtcRead (RTC_ADDRESS_CENTURY);\r
   Time.Year = (UINT16) (Century * 100 + Time.Year);\r
-\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, RTC_INIT_REGISTER_B);\r
+  RtcWrite (RTC_ADDRESS_REGISTER_B, (UINT8)(RTC_INIT_REGISTER_B | (RegisterB.Data & BIT5)));\r
 \r
   //\r
   // Release RTC Lock.\r
   //\r
-  //BugBug: the EfiAtRuntime should be encapsulated in EfiAcquireLock or\r
-  //        provide a new instance for EfiAcquireLock, say, RtEfiAcquireLock\r
+  //Code here doesn't consider the runtime environment.\r
   if (!EfiAtRuntime ()) {\r
-  EfiReleaseLock (&Global->RtcLock);\r
+    EfiReleaseLock (&Global->RtcLock);\r
   }\r
\r
   //\r
   // Validate time fields\r
   //\r
-  Status = RtcTimeFieldsValid (&Time);\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
@@ -208,6 +191,25 @@ Returns:
     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
@@ -215,26 +217,26 @@ Returns:
   return EFI_SUCCESS;\r
 }\r
 \r
-EFI_STATUS\r
-PcRtcGetTime (\r
-  OUT EFI_TIME              *Time,\r
-  IN  EFI_TIME_CAPABILITIES *Capabilities,\r
-  IN  PC_RTC_MODULE_GLOBALS *Global\r
-  )\r
-/*++\r
+/**\r
+  Returns the current time and date information, and the time-keeping capabilities\r
+  of the hardware platform.\r
 \r
-Routine Description:\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
-  Arguments:\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
-  Returns:\r
---*/\r
-// GC_TODO:    Time - add argument and description to function comment\r
-// GC_TODO:    Capabilities - add argument and description to function comment\r
-// GC_TODO:    Global - add argument and description to function comment\r
-// GC_TODO:    EFI_INVALID_PARAMETER - add return value to function comment\r
-// GC_TODO:    EFI_DEVICE_ERROR - add return value to function comment\r
-// GC_TODO:    EFI_SUCCESS - add return value to function comment\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
@@ -250,20 +252,18 @@ Routine Description:
   //\r
   // Acquire RTC Lock to make access to RTC atomic\r
   //\r
-  //BugBug: the EfiAtRuntime should be encapsulated in EfiAcquireLock or\r
-  //        provide a new instance for EfiAcquireLock, say, RtEfiAcquireLock\r
+  //Code here doesn't consider the runtime environment.\r
   if (!EfiAtRuntime ()) {\r
-  EfiAcquireLock (&Global->RtcLock);\r
+    EfiAcquireLock (&Global->RtcLock);\r
   }\r
   //\r
   // Wait for up to 0.1 seconds for the RTC to be updated\r
   //\r
-  Status = RtcWaitToUpdate (100000);\r
+  Status = RtcWaitToUpdate (PcdGet32 (PcdRealTimeClockUpdateTimeout));\r
   if (EFI_ERROR (Status)) {\r
-         //BugBug: the EfiAtRuntime should be encapsulated in EfiReleaseLock or\r
-      //        provide a new instance for EfiReleaseLock, say, RtEfiReleaseLock\r
+      //Code here doesn't consider the runtime environment.\r
       if (!EfiAtRuntime ()) {\r
-    EfiReleaseLock (&Global->RtcLock);\r
+        EfiReleaseLock (&Global->RtcLock);\r
       }\r
     return Status;\r
   }\r
@@ -282,26 +282,18 @@ Routine Description:
   Time->Month   = RtcRead (RTC_ADDRESS_MONTH);\r
   Time->Year    = RtcRead (RTC_ADDRESS_YEAR);\r
 \r
-  ConvertRtcTimeToEfiTime (Time, RegisterB);\r
-\r
-  if (RtcTestCenturyRegister () == EFI_SUCCESS) {\r
-    Century = BcdToDecimal8 ((UINT8) (RtcRead (RTC_ADDRESS_CENTURY) & 0x7f));\r
-  } else {\r
-    Century = BcdToDecimal8 (RtcRead (RTC_ADDRESS_CENTURY));\r
-  }\r
-\r
+  Century = RtcRead (RTC_ADDRESS_CENTURY);\r
   Time->Year = (UINT16) (Century * 100 + Time->Year);\r
-\r
+  \r
   //\r
   // Release RTC Lock.\r
   //\r
-  //BugBug: the EfiAtRuntime should be encapsulated in EfiReleaseLock or\r
-  //        provide a new instance for EfiReleaseLock, say, RtEfiReleaseLock\r
+  //Code here doesn't consider the runtime environment.\r
   if (!EfiAtRuntime ()) {\r
-  EfiReleaseLock (&Global->RtcLock);\r
+    EfiReleaseLock (&Global->RtcLock);\r
   }\r
   //\r
-  // Get the variable that containts the TimeZone and Daylight fields\r
+  // Get the variable that contains the TimeZone and Daylight fields\r
   //\r
   Time->TimeZone  = Global->SavedTimeZone;\r
   Time->Daylight  = Global->Daylight;\r
@@ -309,14 +301,17 @@ Routine Description:
   //\r
   // Make sure all field values are in correct range\r
   //\r
-  Status = RtcTimeFieldsValid (Time);\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) {\r
+  if (Capabilities != NULL) {\r
     Capabilities->Resolution = 1;\r
     //\r
     // 1 hertz\r
@@ -331,27 +326,28 @@ Routine Description:
   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
-\r
-Routine Description:\r
-\r
-  Arguments:\r
-\r
-  Returns:\r
---*/\r
-// GC_TODO:    Time - add argument and description to function comment\r
-// GC_TODO:    Global - add argument and description to function comment\r
-// GC_TODO:    EFI_INVALID_PARAMETER - add return value to function comment\r
 {\r
   EFI_STATUS      Status;\r
   EFI_TIME        RtcTime;\r
   RTC_REGISTER_B  RegisterB;\r
   UINT8           Century;\r
+  UINT32          TimerVar;\r
 \r
   if (Time == NULL) {\r
     return EFI_INVALID_PARAMETER;\r
@@ -369,20 +365,18 @@ Routine Description:
   //\r
   // Acquire RTC Lock to make access to RTC atomic\r
   //\r
-  //BugBug: the EfiAtRuntime should be encapsulated in EfiAcquireLock or\r
-  //        provide a new instance for EfiAcquireLock, say, RtEfiAcquireLock\r
+  //Code here doesn't consider the runtime environment.\r
   if (!EfiAtRuntime ()) {\r
-  EfiAcquireLock (&Global->RtcLock);\r
+    EfiAcquireLock (&Global->RtcLock);\r
   }\r
   //\r
   // Wait for up to 0.1 seconds for the RTC to be updated\r
   //\r
-  Status = RtcWaitToUpdate (100000);\r
+  Status = RtcWaitToUpdate (PcdGet32 (PcdRealTimeClockUpdateTimeout));\r
   if (EFI_ERROR (Status)) {\r
-        //BugBug: the EfiAtRuntime should be encapsulated in EfiReleaseLock or\r
-     //        provide a new instance for EfiReleaseLock, say, RtEfiReleaseLock\r
+     //Code here doesn't consider the runtime environment.\r
      if (!EfiAtRuntime ()) {\r
-    EfiReleaseLock (&Global->RtcLock);\r
+       EfiReleaseLock (&Global->RtcLock);\r
      }\r
     return Status;\r
   }\r
@@ -401,10 +395,6 @@ Routine Description:
   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
-  if (RtcTestCenturyRegister () == EFI_SUCCESS) {\r
-    Century = (UINT8) ((Century & 0x7f) | (RtcRead (RTC_ADDRESS_CENTURY) & 0x80));\r
-  }\r
-\r
   RtcWrite (RTC_ADDRESS_CENTURY, Century);\r
 \r
   //\r
@@ -416,44 +406,53 @@ Routine Description:
   //\r
   // Release RTC Lock.\r
   //\r
-  //BugBug: the EfiAtRuntime should be encapsulated in EfiReleaseLock or\r
-  //        provide a new instance for EfiReleaseLock, say, RtEfiReleaseLock\r
+  //Code here doesn't consider the runtime environment.\r
   if (!EfiAtRuntime ()) {\r
-  EfiReleaseLock (&Global->RtcLock);\r
+    EfiReleaseLock (&Global->RtcLock);\r
   }\r
   //\r
-  // Set the variable that containts the TimeZone and Daylight fields\r
+  // Set the variable that contains the TimeZone and Daylight fields\r
   //\r
   Global->SavedTimeZone = Time->TimeZone;\r
   Global->Daylight      = Time->Daylight;\r
-  return Status;\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
+  IN  PC_RTC_MODULE_GLOBALS  *Global\r
   )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  Arguments:\r
-\r
-\r
-\r
-Returns:\r
---*/\r
-// GC_TODO:    Enabled - add argument and description to function comment\r
-// GC_TODO:    Pending - add argument and description to function comment\r
-// GC_TODO:    Time - add argument and description to function comment\r
-// GC_TODO:    Global - add argument and description to function comment\r
-// GC_TODO:    EFI_INVALID_PARAMETER - add return value to function comment\r
-// GC_TODO:    EFI_DEVICE_ERROR - add return value to function comment\r
-// GC_TODO:    EFI_DEVICE_ERROR - add return value to function comment\r
-// GC_TODO:    EFI_SUCCESS - add return value to function comment\r
 {\r
   EFI_STATUS      Status;\r
   RTC_REGISTER_B  RegisterB;\r
@@ -461,7 +460,7 @@ Returns:
   UINT8           Century;\r
 \r
   //\r
-  // Check paramters for null pointers\r
+  // Check parameters for null pointers\r
   //\r
   if ((Enabled == NULL) || (Pending == NULL) || (Time == NULL)) {\r
     return EFI_INVALID_PARAMETER;\r
@@ -470,18 +469,16 @@ Returns:
   //\r
   // Acquire RTC Lock to make access to RTC atomic\r
   //\r
-  //BugBug: the EfiAtRuntime should be encapsulated in EfiAcquireLock or\r
-  //        provide a new instance for EfiAcquireLock, say, RtEfiAcquireLock\r
+  //Code here doesn't consider the runtime environment.\r
   if (!EfiAtRuntime ()) {\r
-  EfiAcquireLock (&Global->RtcLock);\r
+    EfiAcquireLock (&Global->RtcLock);\r
   }\r
   //\r
   // Wait for up to 0.1 seconds for the RTC to be updated\r
   //\r
-  Status = RtcWaitToUpdate (100000);\r
+  Status = RtcWaitToUpdate (PcdGet32 (PcdRealTimeClockUpdateTimeout));\r
   if (EFI_ERROR (Status)) {\r
-       //BugBug: the EfiAtRuntime should be encapsulated in EfiReleaseLock or\r
-    //        provide a new instance for EfiReleaseLock, say, RtEfiReleaseLock\r
+    //Code here doesn't consider the runtime environment.\r
     if (!EfiAtRuntime ()) {\r
     EfiReleaseLock (&Global->RtcLock);\r
     }\r
@@ -513,28 +510,23 @@ Returns:
     Time->Year    = RtcRead (RTC_ADDRESS_YEAR);\r
   }\r
 \r
-  ConvertRtcTimeToEfiTime (Time, RegisterB);\r
-\r
-  if (RtcTestCenturyRegister () == EFI_SUCCESS) {\r
-    Century = BcdToDecimal8 ((UINT8) (RtcRead (RTC_ADDRESS_CENTURY) & 0x7f));\r
-  } else {\r
-    Century = BcdToDecimal8 (RtcRead (RTC_ADDRESS_CENTURY));\r
-  }\r
-\r
+  Century = RtcRead (RTC_ADDRESS_CENTURY);\r
   Time->Year = (UINT16) (Century * 100 + Time->Year);\r
-\r
+  \r
   //\r
   // Release RTC Lock.\r
   //\r
-  //BugBug: the EfiAtRuntime should be encapsulated in EfiReleaseLock or\r
-  //        provide a new instance for EfiReleaseLock, say, RtEfiReleaseLock\r
+  //Code here doesn't consider the runtime environment.\r
   if (!EfiAtRuntime ()) {\r
-  EfiReleaseLock (&Global->RtcLock);\r
+    EfiReleaseLock (&Global->RtcLock);\r
   }\r
   //\r
   // Make sure all field values are in correct range\r
   //\r
-  Status = RtcTimeFieldsValid (Time);\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
@@ -544,30 +536,27 @@ Returns:
   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
-  OUT EFI_TIME              *Time,\r
+  IN EFI_TIME               *Time,   OPTIONAL\r
   IN PC_RTC_MODULE_GLOBALS  *Global\r
   )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  Arguments:\r
-\r
-\r
-\r
-Returns:\r
---*/\r
-// GC_TODO:    Enable - add argument and description to function comment\r
-// GC_TODO:    Time - add argument and description to function comment\r
-// GC_TODO:    Global - add argument and description to function comment\r
-// GC_TODO:    EFI_INVALID_PARAMETER - add return value to function comment\r
-// GC_TODO:    EFI_INVALID_PARAMETER - add return value to function comment\r
-// GC_TODO:    EFI_UNSUPPORTED - add return value to function comment\r
-// GC_TODO:    EFI_DEVICE_ERROR - add return value to function comment\r
-// GC_TODO:    EFI_SUCCESS - add return value to function comment\r
 {\r
   EFI_STATUS            Status;\r
   EFI_TIME              RtcTime;\r
@@ -591,6 +580,10 @@ Returns:
     // 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
@@ -603,18 +596,16 @@ Returns:
   //\r
   // Acquire RTC Lock to make access to RTC atomic\r
   //\r
-  //BugBug: the EfiAtRuntime should be encapsulated in EfiAcquireLock or\r
-  //        provide a new instance for EfiAcquireLock, say, RtEfiAcquireLock\r
+  //Code here doesn't consider the runtime environment.\r
   if (!EfiAtRuntime ()) {\r
-  EfiAcquireLock (&Global->RtcLock);\r
+    EfiAcquireLock (&Global->RtcLock);\r
   }\r
   //\r
   // Wait for up to 0.1 seconds for the RTC to be updated\r
   //\r
-  Status = RtcWaitToUpdate (100000);\r
+  Status = RtcWaitToUpdate (PcdGet32 (PcdRealTimeClockUpdateTimeout));\r
   if (EFI_ERROR (Status)) {\r
-    //BugBug: the EfiAtRuntime should be encapsulated in EfiReleaseLock or\r
-    //        provide a new instance for EfiReleaseLock, say, RtEfiReleaseLock\r
+    //Code here doesn't consider the runtime environment.\r
     if (!EfiAtRuntime ()) {\r
     EfiReleaseLock (&Global->RtcLock);\r
     }\r
@@ -652,92 +643,100 @@ Returns:
   //\r
   // Release RTC Lock.\r
   //\r
-  //BugBug: the EfiAtRuntime should be encapsulated in EfiReleaseLock or\r
-  //        provide a new instance for EfiReleaseLock, say, RtEfiReleaseLock\r
+  //Code here doesn't consider the runtime environment.\r
   if (!EfiAtRuntime ()) {\r
-  EfiReleaseLock (&Global->RtcLock);\r
+    EfiReleaseLock (&Global->RtcLock);\r
   }\r
   return EFI_SUCCESS;\r
 }\r
 \r
-EFI_STATUS\r
-RtcTestCenturyRegister (\r
-  VOID\r
-  )\r
-/*++\r
 \r
-Routine Description:\r
+/**\r
+  Checks an 8-bit BCD value, and converts to an 8-bit value if valid.\r
 \r
-  Arguments:\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
-Returns:\r
---*/\r
-// GC_TODO:    EFI_SUCCESS - add return value to function comment\r
-// GC_TODO:    EFI_DEVICE_ERROR - add return value to function comment\r
+**/\r
+UINT8\r
+CheckAndConvertBcd8ToDecimal8 (\r
+  IN  UINT8  Value\r
+  )\r
 {\r
-  UINT8 Century;\r
-  UINT8 Temp;\r
-\r
-  Century = RtcRead (RTC_ADDRESS_CENTURY);\r
-  //\r
-  //  RtcWrite (RTC_ADDRESS_CENTURY, 0x00);\r
-  //\r
-  Temp = (UINT8) (RtcRead (RTC_ADDRESS_CENTURY) & 0x7f);\r
-  RtcWrite (RTC_ADDRESS_CENTURY, Century);\r
-  if (Temp == 0x19 || Temp == 0x20) {\r
-    return EFI_SUCCESS;\r
+  if ((Value < 0xa0) && ((Value & 0xf) < 0xa)) {\r
+    return BcdToDecimal8 (Value);\r
   }\r
 \r
-  return EFI_DEVICE_ERROR;\r
+  return 0xff;\r
 }\r
 \r
-VOID\r
-ConvertRtcTimeToEfiTime (\r
-  IN EFI_TIME       *Time,\r
-  IN RTC_REGISTER_B RegisterB\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
+/**\r
+  Converts time read from RTC to EFI_TIME format defined by UEFI spec.\r
 \r
-  Arguments:\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
-Returns:\r
---*/\r
-// GC_TODO:    Time - add argument and description to function comment\r
-// GC_TODO:    RegisterB - add argument and description to function comment\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 PM;\r
+  BOOLEAN IsPM;\r
 \r
-  if ((Time->Hour) & 0x80) {\r
-    PM = TRUE;\r
+  if ((Time->Hour & 0x80) != 0) {\r
+    IsPM = TRUE;\r
   } else {\r
-    PM = FALSE;\r
+    IsPM = FALSE;\r
   }\r
 \r
   Time->Hour = (UINT8) (Time->Hour & 0x7f);\r
 \r
   if (RegisterB.Bits.DM == 0) {\r
-    Time->Year    = BcdToDecimal8 ((UINT8) Time->Year);\r
-    Time->Month   = BcdToDecimal8 (Time->Month);\r
-    Time->Day     = BcdToDecimal8 (Time->Day);\r
-    Time->Hour    = BcdToDecimal8 (Time->Hour);\r
-    Time->Minute  = BcdToDecimal8 (Time->Minute);\r
-    Time->Second  = BcdToDecimal8 (Time->Second);\r
+    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
+    Century       = CheckAndConvertBcd8ToDecimal8 (Century);\r
   }\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 (PM && Time->Hour < 12) {\r
+    if (IsPM && Time->Hour < 12) {\r
       Time->Hour = (UINT8) (Time->Hour + 12);\r
     }\r
 \r
-    if (!PM && Time->Hour == 12) {\r
+    if (!IsPM && Time->Hour == 12) {\r
       Time->Hour = 0;\r
     }\r
   }\r
@@ -745,25 +744,22 @@ Returns:
   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
-\r
-Routine Description:\r
-\r
-  Arguments:\r
-\r
-\r
-Returns:\r
---*/\r
-// GC_TODO:    Timeout - add argument and description to function comment\r
-// GC_TODO:    EFI_DEVICE_ERROR - add return value to function comment\r
-// GC_TODO:    EFI_DEVICE_ERROR - add return value to function comment\r
-// GC_TODO:    EFI_SUCCESS - add return value to function comment\r
 {\r
   RTC_REGISTER_A  RegisterA;\r
   RTC_REGISTER_D  RegisterD;\r
@@ -795,59 +791,51 @@ Returns:
   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
-\r
-Routine Description:\r
-\r
-  Arguments:\r
-\r
-  Returns:\r
---*/\r
-// GC_TODO:    Time - add argument and description to function comment\r
-// GC_TODO:    EFI_INVALID_PARAMETER - add return value to function comment\r
-// GC_TODO:    EFI_SUCCESS - add return value to function comment\r
 {\r
   if (Time->Year < 1998 ||\r
       Time->Year > 2099 ||\r
       Time->Month < 1 ||\r
       Time->Month > 12 ||\r
-      (!DayValid (Time)) ||\r
       Time->Hour > 23 ||\r
       Time->Minute > 59 ||\r
       Time->Second > 59 ||\r
       Time->Nanosecond > 999999999 ||\r
       (!(Time->TimeZone == EFI_UNSPECIFIED_TIMEZONE || (Time->TimeZone >= -1440 && Time->TimeZone <= 1440))) ||\r
-      (Time->Daylight & (~(EFI_TIME_ADJUST_DAYLIGHT | EFI_TIME_IN_DAYLIGHT)))\r
+      ((Time->Daylight & (~(EFI_TIME_ADJUST_DAYLIGHT | EFI_TIME_IN_DAYLIGHT))) != 0)\r
       ) {\r
-    return EFI_INVALID_PARAMETER;\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
-\r
-Routine Description:\r
-\r
-  GC_TODO: Add function description\r
-\r
-Arguments:\r
-\r
-  Time  - GC_TODO: add argument description\r
-\r
-Returns:\r
-\r
-  GC_TODO: add return values\r
-\r
---*/\r
 {\r
   INTN  DayOfMonth[12];\r
 \r
@@ -864,6 +852,11 @@ Returns:
   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
@@ -874,25 +867,18 @@ Returns:
   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
-\r
-Routine Description:\r
-\r
-  GC_TODO: Add function description\r
-\r
-Arguments:\r
-\r
-  Time  - GC_TODO: add argument description\r
-\r
-Returns:\r
-\r
-  GC_TODO: add return values\r
-\r
---*/\r
 {\r
   if (Time->Year % 4 == 0) {\r
     if (Time->Year % 100 == 0) {\r
@@ -909,34 +895,35 @@ Returns:
   }\r
 }\r
 \r
-VOID\r
-ConvertEfiTimeToRtcTime (\r
-  IN EFI_TIME       *Time,\r
-  IN RTC_REGISTER_B RegisterB,\r
-  IN UINT8          *Century\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
+/**\r
+  Converts time from EFI_TIME format defined by UEFI spec to RTC's.\r
 \r
-  Arguments:\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
-Returns:\r
---*/\r
-// GC_TODO:    Time - add argument and description to function comment\r
-// GC_TODO:    RegisterB - add argument and description to function comment\r
-// GC_TODO:    Century - add argument and description to function comment\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 PM;\r
+  BOOLEAN IsPM;\r
 \r
-  PM = TRUE;\r
+  IsPM = TRUE;\r
   //\r
-  // Adjust hour field if RTC in in 12 hour mode\r
+  // Adjust hour field if RTC is in 12 hour mode\r
   //\r
   if (RegisterB.Bits.MIL == 0) {\r
     if (Time->Hour < 12) {\r
-      PM = FALSE;\r
+      IsPM = FALSE;\r
     }\r
 \r
     if (Time->Hour >= 13) {\r
@@ -963,36 +950,28 @@ Returns:
   //\r
   // If we are in 12 hour mode and PM is set, then set bit 7 of the Hour field.\r
   //\r
-  if (RegisterB.Bits.MIL == 0 && PM) {\r
+  if (RegisterB.Bits.MIL == 0 && IsPM) {\r
     Time->Hour = (UINT8) (Time->Hour | 0x80);\r
   }\r
 }\r
 \r
-STATIC\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
-Routine Description:\r
-\r
-  Compare the Hour, Minute and Second of the 'From' time and the 'To' time.\r
-  Only compare H/M/S in EFI_TIME and ignore other fields here.\r
-\r
-Arguments:\r
-\r
-  From  -   the first time\r
-  To    -   the second time\r
-\r
-Returns:\r
-\r
-  >0   : The H/M/S of the 'From' time is later than those of 'To' time\r
-  ==0  : The H/M/S of the 'From' time is same as those of 'To' time\r
-  <0   : The H/M/S of the 'From' time is earlier than those of 'To' time\r
-\r
---*/\r
 {\r
   if ((From->Hour > To->Hour) ||\r
      ((From->Hour == To->Hour) && (From->Minute > To->Minute)) ||\r
@@ -1005,33 +984,45 @@ Returns:
   }\r
 }\r
 \r
-STATIC\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
-Routine Description:\r
-\r
-  Judge whether two days are adjacent.\r
-\r
-Arguments:\r
-\r
-  From  -   the first day\r
-  To    -   the second day\r
-\r
-Returns:\r
+{\r
+  UINT8   DayOfMonth[12];\r
+  BOOLEAN Adjacent;\r
 \r
-  TRUE  -   The interval of two days are within one day.\r
-  FALSE -   The interval of two days exceed ony day or parameter error.\r
+  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
-{\r
-  UINT8   DayOfMonth[12] = {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};\r
-  BOOLEAN Adjacent = FALSE;\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