Move RealTimeClockRuntimeDxe to PcatRealTimeClockRuntimeDxe folder of MdeModulePkg.
authoryshang1 <yshang1@6f19259b-4bc3-4df7-8a09-765794883524>
Thu, 19 Jul 2007 10:26:16 +0000 (10:26 +0000)
committeryshang1 <yshang1@6f19259b-4bc3-4df7-8a09-765794883524>
Thu, 19 Jul 2007 10:26:16 +0000 (10:26 +0000)
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@3372 6f19259b-4bc3-4df7-8a09-765794883524

MdeModulePkg/MdeModulePkg.dsc
MdeModulePkg/Universal/PcatRealTimeClockRuntimeDxe/Ia32/Ia32PcRtc.c [new file with mode: 0644]
MdeModulePkg/Universal/PcatRealTimeClockRuntimeDxe/PcRtc.c [new file with mode: 0644]
MdeModulePkg/Universal/PcatRealTimeClockRuntimeDxe/PcRtc.h [new file with mode: 0644]
MdeModulePkg/Universal/PcatRealTimeClockRuntimeDxe/PcatRealTimeClockRuntimeDxe.inf [new file with mode: 0644]
MdeModulePkg/Universal/PcatRealTimeClockRuntimeDxe/RealTimeClockRuntimeDxe.msa [new file with mode: 0644]

index 46221b7..74f4322 100644 (file)
   $(WORKSPACE)/MdeModulePkg/Universal/MonotonicCounterRuntimeDxe/MonotonicCounterRuntimeDxe.inf\r
   $(WORKSPACE)/MdeModulePkg/Universal/EbcDxe/EbcDxe.inf\r
   $(WORKSPACE)/MdeModulePkg/Universal/DebugSupportDxe/DebugSupportDxe.inf\r
-  $(WORKSPACE)/MdeModulePkg/Universal/PcatCompatible/RealTimeClockRuntimeDxe/RealTimeClockRuntimeDxe.inf\r
+  $(WORKSPACE)/MdeModulePkg/Universal/PcatRealTimeClockRuntimeDxe/PcatRealTimeClockRuntimeDxe.inf\r
 \r
 [Components.X64]\r
   $(WORKSPACE)/MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf\r
diff --git a/MdeModulePkg/Universal/PcatRealTimeClockRuntimeDxe/Ia32/Ia32PcRtc.c b/MdeModulePkg/Universal/PcatRealTimeClockRuntimeDxe/Ia32/Ia32PcRtc.c
new file mode 100644 (file)
index 0000000..f0b1640
--- /dev/null
@@ -0,0 +1,173 @@
+/*++\r
+\r
+Copyright (c) 2006, 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
+\r
+\r
+\r
+Module Name:\r
+\r
+ Ia32PcRtc.c\r
+\r
+Abstract:\r
+\r
+--*/\r
+\r
+#include "PcRtc.h"\r
+\r
+static PC_RTC_MODULE_GLOBALS  mModuleGlobal;\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PcRtcEfiGetTime (\r
+  OUT EFI_TIME                *Time,\r
+  OUT  EFI_TIME_CAPABILITIES  *Capabilities\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
+  Capabilities  - GC_TODO: add argument description\r
+\r
+Returns:\r
+\r
+  GC_TODO: add return values\r
+\r
+--*/\r
+{\r
+  return PcRtcGetTime (Time, Capabilities, &mModuleGlobal);\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PcRtcEfiSetTime (\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
+  return PcRtcSetTime (Time, &mModuleGlobal);\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
+\r
+Routine Description:\r
+\r
+  GC_TODO: Add function description\r
+\r
+Arguments:\r
+\r
+  Enabled - GC_TODO: add argument description\r
+  Pending - GC_TODO: add argument description\r
+  Time    - GC_TODO: add argument description\r
+\r
+Returns:\r
+\r
+  GC_TODO: add return values\r
+\r
+--*/\r
+{\r
+  return PcRtcGetWakeupTime (Enabled, Pending, Time, &mModuleGlobal);\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PcRtcEfiSetWakeupTime (\r
+  IN BOOLEAN      Enabled,\r
+  OUT EFI_TIME    *Time\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  GC_TODO: Add function description\r
+\r
+Arguments:\r
+\r
+  Enabled - GC_TODO: add argument description\r
+  Time    - GC_TODO: add argument description\r
+\r
+Returns:\r
+\r
+  GC_TODO: add return values\r
+\r
+--*/\r
+{\r
+  return PcRtcSetWakeupTime (Enabled, Time, &mModuleGlobal);\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+InitializePcRtc (\r
+  IN EFI_HANDLE                            ImageHandle,\r
+  IN EFI_SYSTEM_TABLE                      *SystemTable\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Arguments:\r
+\r
+  \r
+\r
+Returns: \r
+--*/\r
+// GC_TODO:    ImageHandle - add argument and description to function comment\r
+// GC_TODO:    SystemTable - add argument and description to function comment\r
+{\r
+  EFI_STATUS  Status;\r
+  EFI_HANDLE  NewHandle;\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
+  NewHandle = NULL;\r
+  Status = gBS->InstallMultipleProtocolInterfaces (\r
+                  &NewHandle,\r
+                  &gEfiRealTimeClockArchProtocolGuid,\r
+                  NULL,\r
+                  NULL\r
+                  );\r
+\r
+  return Status;\r
+}\r
diff --git a/MdeModulePkg/Universal/PcatRealTimeClockRuntimeDxe/PcRtc.c b/MdeModulePkg/Universal/PcatRealTimeClockRuntimeDxe/PcRtc.c
new file mode 100644 (file)
index 0000000..a58aee5
--- /dev/null
@@ -0,0 +1,1071 @@
+/*++\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
+\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
+\r
+--*/\r
+\r
+#include "PcRtc.h"\r
+\r
+STATIC\r
+INTN\r
+CompareHMS (\r
+  IN EFI_TIME   *From,\r
+  IN EFI_TIME   *To\r
+  );\r
+\r
+STATIC\r
+BOOLEAN\r
+IsWithinOneDay (\r
+  IN EFI_TIME   *From,\r
+  IN EFI_TIME   *To\r
+  );\r
+\r
+STATIC\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
+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
+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
+  RTC_REGISTER_B  RegisterB;\r
+  RTC_REGISTER_D  RegisterD;\r
+  UINT8           Century;\r
+  EFI_TIME        Time;\r
+\r
+  //\r
+  // Acquire RTC Lock to make access to RTC atomic\r
+  //\r
+  //BugBug: the EfiAtRuntime should be encapsulated in EfiAcquireLock or\r
+  //        provide a new instance for EfiAcquireLock, say, RtEfiAcquireLock\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 (100000);\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
+    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
+  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
+  Time.Year = (UINT16) (Century * 100 + Time.Year);\r
+\r
+  //\r
+  // Set RTC configuration after get original time\r
+  //\r
+  RtcWrite (RTC_ADDRESS_REGISTER_B, RTC_INIT_REGISTER_B);\r
+\r
+  //\r
+  // Release RTC Lock.\r
+  //\r
+  //BugBug: the EfiAtRuntime should be encapsulated in EfiAcquireLock or\r
+  //        provide a new instance for EfiAcquireLock, say, RtEfiAcquireLock\r
+  if (!EfiAtRuntime ()) {\r
+  EfiReleaseLock (&Global->RtcLock);\r
+  }\r
+  //\r
+  // Validate time fields\r
+  //\r
+  Status = RtcTimeFieldsValid (&Time);\r
+  if (EFI_ERROR (Status)) {\r
+    Time.Second = RTC_INIT_SECOND;\r
+    Time.Minute = RTC_INIT_MINUTE;\r
+    Time.Hour   = RTC_INIT_HOUR;\r
+    Time.Day    = RTC_INIT_DAY;\r
+    Time.Month  = RTC_INIT_MONTH;\r
+    Time.Year   = RTC_INIT_YEAR;\r
+  }\r
+  //\r
+  // Reset time value according to new RTC configuration\r
+  //\r
+  PcRtcSetTime (&Time, Global);\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+PcRtcGetTime (\r
+  OUT EFI_TIME              *Time,\r
+  IN  EFI_TIME_CAPABILITIES *Capabilities,\r
+  IN  PC_RTC_MODULE_GLOBALS *Global\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Arguments:\r
+\r
+  Returns:\r
+--*/\r
+// 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      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
+  //BugBug: the EfiAtRuntime should be encapsulated in EfiAcquireLock or\r
+  //        provide a new instance for EfiAcquireLock, say, RtEfiAcquireLock\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 (100000);\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
+      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
+  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
+  Time->Year = (UINT16) (Century * 100 + Time->Year);\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
+  if (!EfiAtRuntime ()) {\r
+  EfiReleaseLock (&Global->RtcLock);\r
+  }\r
+  //\r
+  // Get the variable that containts the TimeZone and Daylight fields\r
+  //\r
+  Time->TimeZone  = Global->SavedTimeZone;\r
+  Time->Daylight  = Global->Daylight;\r
+\r
+  //\r
+  // Make sure all field values are in correct range\r
+  //\r
+  Status = RtcTimeFieldsValid (Time);\r
+  if (EFI_ERROR (Status)) {\r
+    return EFI_DEVICE_ERROR;\r
+  }\r
+  //\r
+  //  Fill in Capabilities if it was passed in\r
+  //\r
+  if (Capabilities) {\r
+    Capabilities->Resolution = 1;\r
+    //\r
+    // 1 hertz\r
+    //\r
+    Capabilities->Accuracy = 50000000;\r
+    //\r
+    // 50 ppm\r
+    //\r
+    Capabilities->SetsToZero = FALSE;\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+PcRtcSetTime (\r
+  IN EFI_TIME                *Time,\r
+  IN PC_RTC_MODULE_GLOBALS   *Global\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Arguments:\r
+\r
+  Returns:\r
+--*/\r
+// 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
+\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
+  //BugBug: the EfiAtRuntime should be encapsulated in EfiAcquireLock or\r
+  //        provide a new instance for EfiAcquireLock, say, RtEfiAcquireLock\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 (100000);\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
+     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
+  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
+  // 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
+  //BugBug: the EfiAtRuntime should be encapsulated in EfiReleaseLock or\r
+  //        provide a new instance for EfiReleaseLock, say, RtEfiReleaseLock\r
+  if (!EfiAtRuntime ()) {\r
+  EfiReleaseLock (&Global->RtcLock);\r
+  }\r
+  //\r
+  // Set the variable that containts the TimeZone and Daylight fields\r
+  //\r
+  Global->SavedTimeZone = Time->TimeZone;\r
+  Global->Daylight      = Time->Daylight;\r
+  return Status;\r
+}\r
+\r
+EFI_STATUS\r
+PcRtcGetWakeupTime (\r
+  OUT BOOLEAN                *Enabled,\r
+  OUT BOOLEAN                *Pending,\r
+  OUT EFI_TIME               *Time,\r
+  IN PC_RTC_MODULE_GLOBALS   *Global\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Arguments:\r
+\r
+\r
+\r
+Returns:\r
+--*/\r
+// 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
+  RTC_REGISTER_C  RegisterC;\r
+  UINT8           Century;\r
+\r
+  //\r
+  // Check paramters for null pointers\r
+  //\r
+  if ((Enabled == NULL) || (Pending == NULL) || (Time == NULL)) {\r
+    return EFI_INVALID_PARAMETER;\r
+\r
+  }\r
+  //\r
+  // Acquire RTC Lock to make access to RTC atomic\r
+  //\r
+  //BugBug: the EfiAtRuntime should be encapsulated in EfiAcquireLock or\r
+  //        provide a new instance for EfiAcquireLock, say, RtEfiAcquireLock\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 (100000);\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
+    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
+  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
+  Time->Year = (UINT16) (Century * 100 + Time->Year);\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
+  if (!EfiAtRuntime ()) {\r
+  EfiReleaseLock (&Global->RtcLock);\r
+  }\r
+  //\r
+  // Make sure all field values are in correct range\r
+  //\r
+  Status = RtcTimeFieldsValid (Time);\r
+  if (EFI_ERROR (Status)) {\r
+    return EFI_DEVICE_ERROR;\r
+  }\r
+\r
+  *Pending = RegisterC.Bits.AF;\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+PcRtcSetWakeupTime (\r
+  IN BOOLEAN                Enable,\r
+  OUT EFI_TIME              *Time,\r
+  IN PC_RTC_MODULE_GLOBALS  *Global\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Arguments:\r
+\r
+\r
+\r
+Returns:\r
+--*/\r
+// 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
+  RTC_REGISTER_B        RegisterB;\r
+  UINT8                 Century;\r
+  EFI_TIME_CAPABILITIES Capabilities;\r
+\r
+  if (Enable) {\r
+\r
+    if (Time == NULL) {\r
+      return EFI_INVALID_PARAMETER;\r
+    }\r
+    //\r
+    // Make sure that the time fields are valid\r
+    //\r
+    Status = RtcTimeFieldsValid (Time);\r
+    if (EFI_ERROR (Status)) {\r
+      return EFI_INVALID_PARAMETER;\r
+    }\r
+    //\r
+    // Just support set alarm time within 24 hours\r
+    //\r
+    PcRtcGetTime (&RtcTime, &Capabilities, Global);\r
+    if (!IsWithinOneDay (&RtcTime, Time)) {\r
+      return EFI_UNSUPPORTED;\r
+    }\r
+    //\r
+    // Make a local copy of the time and date\r
+    //\r
+    CopyMem (&RtcTime, Time, sizeof (EFI_TIME));\r
+\r
+  }\r
+  //\r
+  // Acquire RTC Lock to make access to RTC atomic\r
+  //\r
+  //BugBug: the EfiAtRuntime should be encapsulated in EfiAcquireLock or\r
+  //        provide a new instance for EfiAcquireLock, say, RtEfiAcquireLock\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 (100000);\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
+    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
+  //BugBug: the EfiAtRuntime should be encapsulated in EfiReleaseLock or\r
+  //        provide a new instance for EfiReleaseLock, say, RtEfiReleaseLock\r
+  if (!EfiAtRuntime ()) {\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
+  Arguments:\r
+\r
+\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 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
+  }\r
+\r
+  return EFI_DEVICE_ERROR;\r
+}\r
+\r
+VOID\r
+ConvertRtcTimeToEfiTime (\r
+  IN EFI_TIME       *Time,\r
+  IN RTC_REGISTER_B RegisterB\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Arguments:\r
+\r
+\r
+\r
+Returns:\r
+--*/\r
+// GC_TODO:    Time - add argument and description to function comment\r
+// GC_TODO:    RegisterB - add argument and description to function comment\r
+{\r
+  BOOLEAN PM;\r
+\r
+  if ((Time->Hour) & 0x80) {\r
+    PM = TRUE;\r
+  } else {\r
+    PM = FALSE;\r
+  }\r
+\r
+  Time->Hour = (UINT8) (Time->Hour & 0x7f);\r
+\r
+  if (RegisterB.Bits.DM == 0) {\r
+    Time->Year    = BcdToDecimal8 ((UINT8) Time->Year);\r
+    Time->Month   = BcdToDecimal8 (Time->Month);\r
+    Time->Day     = BcdToDecimal8 (Time->Day);\r
+    Time->Hour    = BcdToDecimal8 (Time->Hour);\r
+    Time->Minute  = BcdToDecimal8 (Time->Minute);\r
+    Time->Second  = BcdToDecimal8 (Time->Second);\r
+  }\r
+  //\r
+  // If time is in 12 hour format, convert it to 24 hour format\r
+  //\r
+  if (RegisterB.Bits.MIL == 0) {\r
+    if (PM && Time->Hour < 12) {\r
+      Time->Hour = (UINT8) (Time->Hour + 12);\r
+    }\r
+\r
+    if (!PM && Time->Hour == 12) {\r
+      Time->Hour = 0;\r
+    }\r
+  }\r
+\r
+  Time->Nanosecond  = 0;\r
+  Time->TimeZone    = EFI_UNSPECIFIED_TIMEZONE;\r
+  Time->Daylight    = 0;\r
+}\r
+\r
+EFI_STATUS\r
+RtcWaitToUpdate (\r
+  UINTN Timeout\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Arguments:\r
+\r
+\r
+Returns:\r
+--*/\r
+// 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
+\r
+  //\r
+  // See if the RTC is functioning correctly\r
+  //\r
+  RegisterD.Data = RtcRead (RTC_ADDRESS_REGISTER_D);\r
+\r
+  if (RegisterD.Bits.VRT == 0) {\r
+    return EFI_DEVICE_ERROR;\r
+  }\r
+  //\r
+  // Wait for up to 0.1 seconds for the RTC to be ready.\r
+  //\r
+  Timeout         = (Timeout / 10) + 1;\r
+  RegisterA.Data  = RtcRead (RTC_ADDRESS_REGISTER_A);\r
+  while (RegisterA.Bits.UIP == 1 && Timeout > 0) {\r
+    MicroSecondDelay (10);\r
+    RegisterA.Data = RtcRead (RTC_ADDRESS_REGISTER_A);\r
+    Timeout--;\r
+  }\r
+\r
+  RegisterD.Data = RtcRead (RTC_ADDRESS_REGISTER_D);\r
+  if (Timeout == 0 || RegisterD.Bits.VRT == 0) {\r
+    return EFI_DEVICE_ERROR;\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+RtcTimeFieldsValid (\r
+  IN EFI_TIME *Time\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Arguments:\r
+\r
+  Returns:\r
+--*/\r
+// 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
+      ) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+BOOLEAN\r
+DayValid (\r
+  IN  EFI_TIME  *Time\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  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
+  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
+  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
+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
+      if (Time->Year % 400 == 0) {\r
+        return TRUE;\r
+      } else {\r
+        return FALSE;\r
+      }\r
+    } else {\r
+      return TRUE;\r
+    }\r
+  } else {\r
+    return FALSE;\r
+  }\r
+}\r
+\r
+VOID\r
+ConvertEfiTimeToRtcTime (\r
+  IN EFI_TIME       *Time,\r
+  IN RTC_REGISTER_B RegisterB,\r
+  IN UINT8          *Century\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Arguments:\r
+\r
+\r
+Returns:\r
+--*/\r
+// 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
+  BOOLEAN PM;\r
+\r
+  PM = TRUE;\r
+  //\r
+  // Adjust hour field if RTC in in 12 hour mode\r
+  //\r
+  if (RegisterB.Bits.MIL == 0) {\r
+    if (Time->Hour < 12) {\r
+      PM = FALSE;\r
+    }\r
+\r
+    if (Time->Hour >= 13) {\r
+      Time->Hour = (UINT8) (Time->Hour - 12);\r
+    } else if (Time->Hour == 0) {\r
+      Time->Hour = 12;\r
+    }\r
+  }\r
+  //\r
+  // Set the Time/Date/Daylight Savings values.\r
+  //\r
+  *Century    = 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 && PM) {\r
+    Time->Hour = (UINT8) (Time->Hour | 0x80);\r
+  }\r
+}\r
+\r
+STATIC\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
+     ((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
+STATIC\r
+BOOLEAN\r
+IsWithinOneDay (\r
+  IN EFI_TIME  *From,\r
+  IN EFI_TIME  *To\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Judge whether two days are adjacent.\r
+\r
+Arguments:\r
+\r
+  From  -   the first day\r
+  To    -   the second day\r
+\r
+Returns:\r
+\r
+  TRUE  -   The interval of two days are within one day.\r
+  FALSE -   The interval of two days exceed ony day or parameter error.\r
+\r
+--*/\r
+{\r
+  UINT8   DayOfMonth[12] = {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};\r
+  BOOLEAN Adjacent = FALSE;\r
+\r
+  if (From->Year == To->Year) {\r
+    if (From->Month == To->Month) {\r
+      if ((From->Day + 1) == To->Day) {\r
+        if ((CompareHMS(From, To) >= 0)) {\r
+          Adjacent = TRUE;\r
+        }\r
+      } else if (From->Day == To->Day) {\r
+        if ((CompareHMS(From, To) <= 0)) {\r
+          Adjacent = TRUE;\r
+        }\r
+      }\r
+    } else if (((From->Month + 1) == To->Month) && (To->Day == 1)) {\r
+      if ((From->Month == 2) && !IsLeapYear(From)) {\r
+        if (From->Day == 28) {\r
+          if ((CompareHMS(From, To) >= 0)) {\r
+            Adjacent = TRUE;\r
+          }\r
+        }\r
+      } else if (From->Day == 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
new file mode 100644 (file)
index 0000000..55ed7c3
--- /dev/null
@@ -0,0 +1,514 @@
+/*++\r
+\r
+Copyright (c) 2006, Intel Corporation. All rights reserved. \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
+\r
+\r
+Module Name:\r
+  \r
+    PcRtc.h\r
+\r
+Abstract:\r
+\r
+    Include for real time clock driver\r
+\r
+Revision History\r
+\r
+\r
+--*/\r
+\r
+#ifndef _RTC_H_\r
+#define _RTC_H_\r
+\r
+//\r
+// The package level header files this module uses\r
+//\r
+#include <PiDxe.h>\r
+//\r
+// The protocols, PPI and GUID defintions for this module\r
+//\r
+#include <Protocol/RealTimeClock.h>\r
+//\r
+// The Library classes this module consumes\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
+\r
+\r
+typedef struct {\r
+  EFI_LOCK  RtcLock;\r
+  UINT16    SavedTimeZone;\r
+  UINT8     Daylight;\r
+} PC_RTC_MODULE_GLOBALS;\r
+\r
+#define PCAT_RTC_ADDRESS_REGISTER 0x70\r
+#define PCAT_RTC_DATA_REGISTER    0x71\r
+\r
+//\r
+// Dallas DS12C887 Real Time Clock\r
+//\r
+#define RTC_ADDRESS_SECONDS           0   // R/W  Range 0..59\r
+#define RTC_ADDRESS_SECONDS_ALARM     1   // R/W  Range 0..59\r
+#define RTC_ADDRESS_MINUTES           2   // R/W  Range 0..59\r
+#define RTC_ADDRESS_MINUTES_ALARM     3   // R/W  Range 0..59\r
+#define RTC_ADDRESS_HOURS             4   // R/W  Range 1..12 or 0..23 Bit 7 is AM/PM\r
+#define RTC_ADDRESS_HOURS_ALARM       5   // R/W  Range 1..12 or 0..23 Bit 7 is AM/PM\r
+#define RTC_ADDRESS_DAY_OF_THE_WEEK   6   // R/W  Range 1..7\r
+#define RTC_ADDRESS_DAY_OF_THE_MONTH  7   // R/W  Range 1..31\r
+#define RTC_ADDRESS_MONTH             8   // R/W  Range 1..12\r
+#define RTC_ADDRESS_YEAR              9   // R/W  Range 0..99\r
+#define RTC_ADDRESS_REGISTER_A        10  // R/W[0..6]  R0[7]\r
+#define RTC_ADDRESS_REGISTER_B        11  // R/W\r
+#define RTC_ADDRESS_REGISTER_C        12  // RO\r
+#define RTC_ADDRESS_REGISTER_D        13  // RO\r
+#define RTC_ADDRESS_CENTURY           50  // R/W  Range 19..20 Bit 8 is R/W\r
+//\r
+// Date and time initial values.\r
+// They are used if the RTC values are invalid during driver initialization\r
+//\r
+#define RTC_INIT_SECOND 0\r
+#define RTC_INIT_MINUTE 0\r
+#define RTC_INIT_HOUR   0\r
+#define RTC_INIT_DAY    1\r
+#define RTC_INIT_MONTH  1\r
+#define RTC_INIT_YEAR   2001\r
+\r
+//\r
+// Register initial values\r
+//\r
+#define RTC_INIT_REGISTER_A 0x26\r
+#define RTC_INIT_REGISTER_B 0x02\r
+#define RTC_INIT_REGISTER_D 0x0\r
+\r
+#pragma pack(1)\r
+//\r
+// Register A\r
+//\r
+typedef struct {\r
+  UINT8 RS : 4;   // Rate Selection Bits\r
+  UINT8 DV : 3;   // Divisor\r
+  UINT8 UIP : 1;  // Update in progress\r
+} RTC_REGISTER_A_BITS;\r
+\r
+typedef union {\r
+  RTC_REGISTER_A_BITS Bits;\r
+  UINT8               Data;\r
+} RTC_REGISTER_A;\r
+\r
+//\r
+// Register B\r
+//\r
+typedef struct {\r
+  UINT8 DSE : 1;  // 0 - Daylight saving disabled  1 - Daylight savings enabled\r
+  UINT8 MIL : 1;  // 0 - 12 hour mode              1 - 24 hour mode\r
+  UINT8 DM : 1;   // 0 - BCD Format                1 - Binary Format\r
+  UINT8 SQWE : 1; // 0 - Disable SQWE output       1 - Enable SQWE output\r
+  UINT8 UIE : 1;  // 0 - Update INT disabled       1 - Update INT enabled\r
+  UINT8 AIE : 1;  // 0 - Alarm INT disabled        1 - Alarm INT Enabled\r
+  UINT8 PIE : 1;  // 0 - Periodic INT disabled     1 - Periodic INT Enabled\r
+  UINT8 SET : 1;  // 0 - Normal operation.         1 - Updates inhibited\r
+} RTC_REGISTER_B_BITS;\r
+\r
+typedef union {\r
+  RTC_REGISTER_B_BITS Bits;\r
+  UINT8               Data;\r
+} RTC_REGISTER_B;\r
+\r
+//\r
+// Register C\r
+//\r
+typedef struct {\r
+  UINT8 Reserved : 4; // Read as zero.  Can not be written.\r
+  UINT8 UF : 1;       // Update End Interrupt Flag\r
+  UINT8 AF : 1;       // Alarm Interrupt Flag\r
+  UINT8 PF : 1;       // Periodic Interrupt Flag\r
+  UINT8 IRQF : 1;     // Iterrupt Request Flag = PF & PIE | AF & AIE | UF & UIE\r
+} RTC_REGISTER_C_BITS;\r
+\r
+typedef union {\r
+  RTC_REGISTER_C_BITS Bits;\r
+  UINT8               Data;\r
+} RTC_REGISTER_C;\r
+\r
+//\r
+// Register D\r
+//\r
+typedef struct {\r
+  UINT8 Reserved : 7; // Read as zero.  Can not be written.\r
+  UINT8 VRT : 1;      // Valid RAM and Time\r
+} RTC_REGISTER_D_BITS;\r
+\r
+typedef union {\r
+  RTC_REGISTER_D_BITS Bits;\r
+  UINT8               Data;\r
+} RTC_REGISTER_D;\r
+\r
+#pragma pack()\r
+\r
+EFI_STATUS\r
+PcRtcInit (\r
+  IN PC_RTC_MODULE_GLOBALS  *Global\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  GC_TODO: Add function description\r
+\r
+Arguments:\r
+\r
+  Global  - GC_TODO: add argument description\r
+\r
+Returns:\r
+\r
+  GC_TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+PcRtcSetTime (\r
+  IN EFI_TIME               *Time,\r
+  IN PC_RTC_MODULE_GLOBALS  *Global\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  GC_TODO: Add function description\r
+\r
+Arguments:\r
+\r
+  Time    - GC_TODO: add argument description\r
+  Global  - GC_TODO: add argument description\r
+\r
+Returns:\r
+\r
+  GC_TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+PcRtcGetTime (\r
+  OUT EFI_TIME              *Time,\r
+  IN  EFI_TIME_CAPABILITIES *Capabilities,\r
+  IN  PC_RTC_MODULE_GLOBALS *Global\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  GC_TODO: Add function description\r
+\r
+Arguments:\r
+\r
+  Time          - GC_TODO: add argument description\r
+  Capabilities  - GC_TODO: add argument description\r
+  Global        - GC_TODO: add argument description\r
+\r
+Returns:\r
+\r
+  GC_TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+PcRtcSetWakeupTime (\r
+  IN BOOLEAN                Enable,\r
+  OUT EFI_TIME              *Time,\r
+  IN  PC_RTC_MODULE_GLOBALS *Global\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  GC_TODO: Add function description\r
+\r
+Arguments:\r
+\r
+  Enable  - GC_TODO: add argument description\r
+  Time    - GC_TODO: add argument description\r
+  Global  - GC_TODO: add argument description\r
+\r
+Returns:\r
+\r
+  GC_TODO: add return values\r
+\r
+--*/\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
+Routine Description:\r
+\r
+  GC_TODO: Add function description\r
+\r
+Arguments:\r
+\r
+  Enabled - GC_TODO: add argument description\r
+  Pending - GC_TODO: add argument description\r
+  Time    - GC_TODO: add argument description\r
+  Global  - GC_TODO: add argument description\r
+\r
+Returns:\r
+\r
+  GC_TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+InitializePcRtc (\r
+  IN EFI_HANDLE                            ImageHandle,\r
+  IN EFI_SYSTEM_TABLE                      *SystemTable\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  GC_TODO: Add function description\r
+\r
+Arguments:\r
+\r
+  ImageHandle - GC_TODO: add argument description\r
+  SystemTable - GC_TODO: add argument description\r
+\r
+Returns:\r
+\r
+  GC_TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+UINT8\r
+BcdToDecimal (\r
+  IN  UINT8 BcdValue\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  GC_TODO: Add function description\r
+\r
+Arguments:\r
+\r
+  BcdValue  - GC_TODO: add argument description\r
+\r
+Returns:\r
+\r
+  GC_TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+RtcTimeFieldsValid (\r
+  IN EFI_TIME *Time\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  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
+\r
+UINT8\r
+DecimaltoBcd (\r
+  IN  UINT8 DecValue\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  GC_TODO: Add function description\r
+\r
+Arguments:\r
+\r
+  DecValue  - GC_TODO: add argument description\r
+\r
+Returns:\r
+\r
+  GC_TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+VOID\r
+ConvertEfiTimeToRtcTime (\r
+  IN EFI_TIME       *Time,\r
+  IN RTC_REGISTER_B RegisterB,\r
+  IN UINT8          *Century\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  GC_TODO: Add function description\r
+\r
+Arguments:\r
+\r
+  Time      - GC_TODO: add argument description\r
+  RegisterB - GC_TODO: add argument description\r
+  Century   - GC_TODO: add argument description\r
+\r
+Returns:\r
+\r
+  GC_TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+RtcTestCenturyRegister (\r
+  VOID\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  GC_TODO: Add function description\r
+\r
+Arguments:\r
+\r
+  None\r
+\r
+Returns:\r
+\r
+  GC_TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+VOID\r
+ConvertRtcTimeToEfiTime (\r
+  IN EFI_TIME       *Time,\r
+  IN RTC_REGISTER_B RegisterB\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  GC_TODO: Add function description\r
+\r
+Arguments:\r
+\r
+  Time      - GC_TODO: add argument description\r
+  RegisterB - GC_TODO: add argument description\r
+\r
+Returns:\r
+\r
+  GC_TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+RtcWaitToUpdate (\r
+  UINTN Timeout\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  GC_TODO: Add function description\r
+\r
+Arguments:\r
+\r
+  Timeout - GC_TODO: add argument description\r
+\r
+Returns:\r
+\r
+  GC_TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+UINT8\r
+RtcSaveContext (\r
+  IN  PC_RTC_MODULE_GLOBALS  *Global\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  GC_TODO: Add function description\r
+\r
+Arguments:\r
+\r
+  Global  - GC_TODO: add argument description\r
+\r
+Returns:\r
+\r
+  GC_TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+VOID\r
+RtcRestoreContext (\r
+  IN  UINT8                 SavedAddressRegister,\r
+  IN  PC_RTC_MODULE_GLOBALS *Global\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  GC_TODO: Add function description\r
+\r
+Arguments:\r
+\r
+  SavedAddressRegister  - GC_TODO: add argument description\r
+  Global                - GC_TODO: add argument description\r
+\r
+Returns:\r
+\r
+  GC_TODO: add return values\r
+\r
+--*/\r
+;\r
+\r
+BOOLEAN\r
+DayValid (\r
+  IN  EFI_TIME  *Time\r
+  );\r
+\r
+BOOLEAN\r
+IsLeapYear (\r
+  IN EFI_TIME   *Time\r
+  );\r
+\r
+#endif\r
diff --git a/MdeModulePkg/Universal/PcatRealTimeClockRuntimeDxe/PcatRealTimeClockRuntimeDxe.inf b/MdeModulePkg/Universal/PcatRealTimeClockRuntimeDxe/PcatRealTimeClockRuntimeDxe.inf
new file mode 100644 (file)
index 0000000..e9c0649
--- /dev/null
@@ -0,0 +1,105 @@
+#/** @file\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
+# Copyright (c) 2006 - 2007, Intel Corporation.\r
+#\r
+#  All rights reserved.\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
+#\r
+#\r
+#**/\r
+\r
+################################################################################\r
+#\r
+# Defines Section - statements that will be processed to create a Makefile.\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
+  EDK_RELEASE_VERSION            = 0x00020000\r
+  EFI_SPECIFICATION_VERSION      = 0x00020000\r
+\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
+################################################################################\r
+#\r
+# Sources Section - list of files that are required for the build to succeed.\r
+#\r
+################################################################################\r
+\r
+[Sources.common]\r
+  Ia32/Ia32PcRtc.c\r
+  PcRtc.c\r
+  PcRtc.h\r
+\r
+\r
+################################################################################\r
+#\r
+# Package Dependency Section - list of Package files that are required for\r
+#                              this module.\r
+#\r
+################################################################################\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+  IntelFrameworkPkg/IntelFrameworkPkg.dec\r
+\r
+\r
+################################################################################\r
+#\r
+# Library Class Section - list of Library Classes that are required for\r
+#                         this module.\r
+#\r
+################################################################################\r
+\r
+[LibraryClasses]\r
+  UefiRuntimeServicesTableLib\r
+  UefiRuntimeLib\r
+  UefiBootServicesTableLib\r
+  UefiDriverEntryPoint\r
+  TimerLib\r
+  IoLib\r
+  BaseMemoryLib\r
+  UefiLib\r
+  DebugLib\r
+  BaseLib\r
+\r
+\r
+################################################################################\r
+#\r
+# Protocol C Name Section - list of Protocol and Protocol Notify C Names\r
+#                           that this module uses or produces.\r
+#\r
+################################################################################\r
+\r
+[Protocols]\r
+  gEfiRealTimeClockArchProtocolGuid             # PROTOCOL ALWAYS_PRODUCED\r
+\r
+\r
+################################################################################\r
+#\r
+# Dependency Expression Section - list of Dependency expressions that are required for\r
+#                              this module.\r
+#\r
+################################################################################\r
+\r
+[Depex]\r
+  gEfiCpuArchProtocolGuid AND gEfiMetronomeArchProtocolGuid\r
+\r
diff --git a/MdeModulePkg/Universal/PcatRealTimeClockRuntimeDxe/RealTimeClockRuntimeDxe.msa b/MdeModulePkg/Universal/PcatRealTimeClockRuntimeDxe/RealTimeClockRuntimeDxe.msa
new file mode 100644 (file)
index 0000000..9e911b8
--- /dev/null
@@ -0,0 +1,79 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<ModuleSurfaceArea xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0  http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd" xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">\r
+  <MsaHeader>\r
+    <ModuleName>PcRtc</ModuleName>\r
+    <ModuleType>DXE_RUNTIME_DRIVER</ModuleType>\r
+    <GuidValue>378D7B65-8DA9-4773-B6E4-A47826A833E1</GuidValue>\r
+    <Version>1.0</Version>\r
+    <Abstract>PcRtc driver to install EFI_REAL_TIME_CLOCK_ARCH_PROTOCOL.</Abstract>\r
+    <Description>This driver provides GetTime, SetTime, GetWakeupTime, SetWakeupTime services to Runtime Service Table.</Description>\r
+    <Copyright>Copyright (c) 2006 - 2007, Intel Corporation.</Copyright>\r
+    <License>All rights reserved.\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.</License>\r
+    <Specification>FRAMEWORK_BUILD_PACKAGING_SPECIFICATION   0x00000052</Specification>\r
+  </MsaHeader>\r
+  <ModuleDefinitions>\r
+    <SupportedArchitectures>IA32 X64 EBC</SupportedArchitectures>\r
+    <BinaryModule>false</BinaryModule>\r
+    <OutputFileBasename>PcRtc</OutputFileBasename>\r
+  </ModuleDefinitions>\r
+  <LibraryClassDefinitions>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>BaseLib</Keyword>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>DebugLib</Keyword>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>UefiLib</Keyword>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>BaseMemoryLib</Keyword>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>IoLib</Keyword>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>TimerLib</Keyword>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>UefiDriverEntryPoint</Keyword>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>UefiBootServicesTableLib</Keyword>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>UefiRuntimeLib</Keyword>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>UefiRuntimeServicesTableLib</Keyword>\r
+    </LibraryClass>\r
+  </LibraryClassDefinitions>\r
+  <SourceFiles>\r
+    <Filename>PcRtc.h</Filename>\r
+    <Filename>PcRtc.c</Filename>\r
+    <Filename>Ia32PcRtc.dxs</Filename>\r
+    <Filename>Ia32/Ia32PcRtc.c</Filename>\r
+  </SourceFiles>\r
+  <PackageDependencies>\r
+    <Package PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>\r
+  </PackageDependencies>\r
+  <Protocols>\r
+    <Protocol Usage="ALWAYS_PRODUCED">\r
+      <ProtocolCName>gEfiRealTimeClockArchProtocolGuid</ProtocolCName>\r
+    </Protocol>\r
+  </Protocols>\r
+  <Externs>\r
+    <Specification>EFI_SPECIFICATION_VERSION 0x00020000</Specification>\r
+    <Specification>EDK_RELEASE_VERSION 0x00020000</Specification>\r
+    <Extern>\r
+      <ModuleEntryPoint>InitializePcRtc</ModuleEntryPoint>\r
+    </Extern>\r
+  </Externs>\r
+</ModuleSurfaceArea>\r