14extern UINTN mRtcIndexRegister;
15extern UINTN mRtcTargetRegister;
16extern UINT16 mRtcDefaultYear;
17extern UINT16 mMinimalValidYear;
18extern UINT16 mMaximalValidYear;
22UINTN mDayOfMonth[] = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
27CHAR16 mTimeZoneVariableName[] = L
"RTC";
78 (UINT8)(Address | (UINT8)(
IoRead8 (mRtcIndexRegister) & 0x80))
80 return IoRead8 (mRtcTargetRegister);
100 (UINT8)(Address | (UINT8)(
IoRead8 (mRtcIndexRegister) & 0x80))
102 IoWrite8 (mRtcTargetRegister, Data);
121 (UINT8)(Address | (UINT8)(
MmioRead8 (mRtcIndexRegister) & 0x80))
143 (UINT8)(Address | (UINT8)(
MmioRead8 (mRtcIndexRegister) & 0x80))
213 ASSERT ((Daylight & (~(EFI_TIME_ADJUST_DAYLIGHT | EFI_TIME_IN_DAYLIGHT))) == 0);
220 mTimeZoneVariableName,
226 if (Status == EFI_NOT_FOUND) {
231 TimerVar = (UINT32)((TimerVar << 16) | (UINT16)(TimeZone));
233 mTimeZoneVariableName,
244 if (!EFI_ERROR (Status)) {
245 Global->SavedTimeZone = TimeZone;
246 Global->Daylight = Daylight;
275 BOOLEAN NeedRtcUpdate;
277 NeedRtcUpdate =
FALSE;
292 RegisterA.Data =
FixedPcdGet8 (PcdInitialValueRtcRegisterA);
293 RtcWrite (RTC_ADDRESS_REGISTER_A, RegisterA.Data);
298 RegisterB.Data =
RtcRead (RTC_ADDRESS_REGISTER_B);
303 RtcRead (RTC_ADDRESS_REGISTER_C);
308 RegisterD.Data =
FixedPcdGet8 (PcdInitialValueRtcRegisterD);
309 RtcWrite (RTC_ADDRESS_REGISTER_D, RegisterD.Data);
315 if (EFI_ERROR (Status)) {
320 Global->Daylight = 0;
325 return EFI_DEVICE_ERROR;
331 Time.Second =
RtcRead (RTC_ADDRESS_SECONDS);
332 Time.Minute =
RtcRead (RTC_ADDRESS_MINUTES);
333 Time.Hour =
RtcRead (RTC_ADDRESS_HOURS);
334 Time.Day =
RtcRead (RTC_ADDRESS_DAY_OF_THE_MONTH);
335 Time.Month =
RtcRead (RTC_ADDRESS_MONTH);
336 Time.Year =
RtcRead (RTC_ADDRESS_YEAR);
349 DataSize =
sizeof (UINT32);
351 mTimeZoneVariableName,
357 if (!EFI_ERROR (Status)) {
358 Time.TimeZone = (INT16)TimerVar;
359 Time.Daylight = (UINT8)(TimerVar >> 16);
369 if (!EFI_ERROR (Status)) {
373 if (EFI_ERROR (Status)) {
379 (EFI_SOFTWARE_DXE_RT_DRIVER | EFI_SW_EC_BAD_DATE_TIME)
381 Time.Second = RTC_INIT_SECOND;
382 Time.Minute = RTC_INIT_MINUTE;
383 Time.Hour = RTC_INIT_HOUR;
384 Time.Day = RTC_INIT_DAY;
385 Time.Month = RTC_INIT_MONTH;
386 Time.Year =
MAX (mRtcDefaultYear, mMinimalValidYear);
387 Time.Year =
MIN (Time.Year, mMaximalValidYear);
391 NeedRtcUpdate =
TRUE;
398 if ((RegisterB.Data | BIT5) != (
FixedPcdGet8 (PcdInitialValueRtcRegisterB) | BIT5)) {
399 RegisterB.Data =
FixedPcdGet8 (PcdInitialValueRtcRegisterB) | (RegisterB.Data & BIT5);
400 RtcWrite (RTC_ADDRESS_REGISTER_B, RegisterB.Data);
401 NeedRtcUpdate =
TRUE;
409 if (EFI_ERROR (Status)) {
410 return EFI_DEVICE_ERROR;
414 if (EFI_ERROR (Status)) {
415 return EFI_DEVICE_ERROR;
425 if ((!EFI_ERROR (Status)) || (Enabled)) {
433 Time.Second = RTC_INIT_SECOND;
434 Time.Minute = RTC_INIT_MINUTE;
435 Time.Hour = RTC_INIT_HOUR;
436 Time.Day = RTC_INIT_DAY;
437 Time.Month = RTC_INIT_MONTH;
438 Time.Year =
MAX (mRtcDefaultYear, mMinimalValidYear);
439 Time.Year =
MIN (Time.Year, mMaximalValidYear);
441 Time.TimeZone = Global->SavedTimeZone;
442 Time.Daylight = Global->Daylight;
455 if (EFI_ERROR (Status)) {
460 return EFI_DEVICE_ERROR;
475 if (EFI_ERROR (Status)) {
480 return EFI_DEVICE_ERROR;
486 RegisterB.Bits.Set = 1;
487 RtcWrite (RTC_ADDRESS_REGISTER_B, RegisterB.Data);
492 RtcWrite (RTC_ADDRESS_SECONDS_ALARM, Time.Second);
493 RtcWrite (RTC_ADDRESS_MINUTES_ALARM, Time.Minute);
494 RtcWrite (RTC_ADDRESS_HOURS_ALARM, Time.Hour);
499 RegisterB.Bits.Set = 0;
500 RtcWrite (RTC_ADDRESS_REGISTER_B, RegisterB.Data);
540 return EFI_INVALID_PARAMETER;
554 if (EFI_ERROR (Status)) {
565 RegisterB.Data =
RtcRead (RTC_ADDRESS_REGISTER_B);
570 Time->Second =
RtcRead (RTC_ADDRESS_SECONDS);
571 Time->Minute =
RtcRead (RTC_ADDRESS_MINUTES);
572 Time->Hour =
RtcRead (RTC_ADDRESS_HOURS);
573 Time->Day =
RtcRead (RTC_ADDRESS_DAY_OF_THE_MONTH);
574 Time->Month =
RtcRead (RTC_ADDRESS_MONTH);
575 Time->Year =
RtcRead (RTC_ADDRESS_YEAR);
587 Time->TimeZone = Global->SavedTimeZone;
588 Time->Daylight = Global->Daylight;
594 if (!EFI_ERROR (Status)) {
598 if (EFI_ERROR (Status)) {
599 return EFI_DEVICE_ERROR;
605 if (Capabilities !=
NULL) {
606 Capabilities->Resolution = 1;
610 Capabilities->Accuracy = 50000000;
614 Capabilities->SetsToZero =
FALSE;
643 return EFI_INVALID_PARAMETER;
650 if (EFI_ERROR (Status)) {
667 if (EFI_ERROR (Status)) {
677 if (EFI_ERROR (Status)) {
682 return EFI_DEVICE_ERROR;
688 RegisterB.Data =
RtcRead (RTC_ADDRESS_REGISTER_B);
689 RegisterB.Bits.Set = 1;
690 RtcWrite (RTC_ADDRESS_REGISTER_B, RegisterB.Data);
692 RegisterA.Data =
RtcRead (RTC_ADDRESS_REGISTER_A);
696 RtcWrite (RTC_ADDRESS_REGISTER_A, RegisterA.Data | RTC_DIV_RESET);
700 if (Global->CenturyRtcAddress != 0) {
706 RtcWrite (RTC_ADDRESS_SECONDS, RtcTime.Second);
707 RtcWrite (RTC_ADDRESS_MINUTES, RtcTime.Minute);
708 RtcWrite (RTC_ADDRESS_HOURS, RtcTime.Hour);
709 RtcWrite (RTC_ADDRESS_DAY_OF_THE_MONTH, RtcTime.Day);
710 RtcWrite (RTC_ADDRESS_MONTH, RtcTime.Month);
711 RtcWrite (RTC_ADDRESS_YEAR, (UINT8)RtcTime.Year);
716 RegisterB.Bits.Set = 0;
717 RtcWrite (RTC_ADDRESS_REGISTER_B, RegisterB.Data);
722 RtcWrite (RTC_ADDRESS_REGISTER_A, RegisterA.Data);
751 OUT BOOLEAN *Enabled,
752 OUT BOOLEAN *Pending,
766 if ((Enabled ==
NULL) || (Pending ==
NULL) || (Time ==
NULL)) {
767 return EFI_INVALID_PARAMETER;
781 if (EFI_ERROR (Status)) {
786 return EFI_DEVICE_ERROR;
792 RegisterB.Data =
RtcRead (RTC_ADDRESS_REGISTER_B);
793 RegisterC.Data =
RtcRead (RTC_ADDRESS_REGISTER_C);
798 *Enabled = RegisterB.Bits.Aie;
799 *Pending = RegisterC.Bits.Af;
801 Time->Second =
RtcRead (RTC_ADDRESS_SECONDS_ALARM);
802 Time->Minute =
RtcRead (RTC_ADDRESS_MINUTES_ALARM);
803 Time->Hour =
RtcRead (RTC_ADDRESS_HOURS_ALARM);
804 Time->Day =
RtcRead (RTC_ADDRESS_DAY_OF_THE_MONTH);
805 Time->Month =
RtcRead (RTC_ADDRESS_MONTH);
806 Time->Year =
RtcRead (RTC_ADDRESS_YEAR);
807 Time->TimeZone = Global->SavedTimeZone;
808 Time->Daylight = Global->Daylight;
821 if (!EFI_ERROR (Status)) {
825 Time->Day = RtcTime.Day;
826 Time->Month = RtcTime.Month;
827 Time->Year = RtcTime.Year;
841 if (!EFI_ERROR (Status)) {
845 if (EFI_ERROR (Status)) {
846 return EFI_DEVICE_ERROR;
879 ZeroMem (&RtcTime,
sizeof (RtcTime));
883 return EFI_INVALID_PARAMETER;
890 if (EFI_ERROR (Status)) {
891 return EFI_INVALID_PARAMETER;
897 Status =
PcRtcGetTime (&RtcTime, &Capabilities, Global);
898 if (!EFI_ERROR (Status)) {
902 if (EFI_ERROR (Status)) {
903 return EFI_DEVICE_ERROR;
907 return EFI_UNSUPPORTED;
927 if (EFI_ERROR (Status)) {
932 return EFI_DEVICE_ERROR;
938 RegisterB.Data =
RtcRead (RTC_ADDRESS_REGISTER_B);
946 RtcTime.Second =
RtcRead (RTC_ADDRESS_SECONDS_ALARM);
947 RtcTime.Minute =
RtcRead (RTC_ADDRESS_MINUTES_ALARM);
948 RtcTime.Hour =
RtcRead (RTC_ADDRESS_HOURS_ALARM);
949 RtcTime.Day =
RtcRead (RTC_ADDRESS_DAY_OF_THE_MONTH);
950 RtcTime.Month =
RtcRead (RTC_ADDRESS_MONTH);
951 RtcTime.Year =
RtcRead (RTC_ADDRESS_YEAR);
952 RtcTime.TimeZone = Global->SavedTimeZone;
953 RtcTime.Daylight = Global->Daylight;
966 if (EFI_ERROR (Status)) {
971 return EFI_DEVICE_ERROR;
977 RegisterB.Bits.Set = 1;
978 RtcWrite (RTC_ADDRESS_REGISTER_B, RegisterB.Data);
984 RtcWrite (RTC_ADDRESS_SECONDS_ALARM, RtcTime.Second);
985 RtcWrite (RTC_ADDRESS_MINUTES_ALARM, RtcTime.Minute);
986 RtcWrite (RTC_ADDRESS_HOURS_ALARM, RtcTime.Hour);
988 RegisterB.Bits.Aie = 1;
990 RegisterB.Bits.Aie = 0;
996 RegisterB.Bits.Set = 0;
997 RtcWrite (RTC_ADDRESS_REGISTER_B, RegisterB.Data);
1026 if ((Value < 0xa0) && ((Value & 0xf) < 0xa)) {
1060 if (RegisterB.Bits.Mil == 0) {
1061 if ((Time->Hour & 0x80) != 0) {
1067 Time->Hour = (UINT8)(Time->Hour & 0x7f);
1070 if (RegisterB.Bits.Dm == 0) {
1079 if ((Time->Year == 0xff) || (Time->Month == 0xff) || (Time->Day == 0xff) ||
1080 (Time->Hour == 0xff) || (Time->Minute == 0xff) || (Time->Second == 0xff))
1082 return EFI_INVALID_PARAMETER;
1090 Century = (UINT8)(mMinimalValidYear / 100);
1091 if (Time->Year < mMinimalValidYear % 100) {
1095 Time->Year = (UINT16)(Century * 100 + Time->Year);
1100 if (RegisterB.Bits.Mil == 0) {
1101 if (IsPM && (Time->Hour < 12)) {
1102 Time->Hour = (UINT8)(Time->Hour + 12);
1105 if (!IsPM && (Time->Hour == 12)) {
1110 Time->Nanosecond = 0;
1134 RegisterD.Data =
RtcRead (RTC_ADDRESS_REGISTER_D);
1136 if (RegisterD.Bits.Vrt == 0) {
1137 return EFI_DEVICE_ERROR;
1143 Timeout = (Timeout / 10) + 1;
1144 RegisterA.Data =
RtcRead (RTC_ADDRESS_REGISTER_A);
1145 while (RegisterA.Bits.Uip == 1 && Timeout > 0) {
1147 RegisterA.Data =
RtcRead (RTC_ADDRESS_REGISTER_A);
1151 RegisterD.Data =
RtcRead (RTC_ADDRESS_REGISTER_D);
1152 if ((Timeout == 0) || (RegisterD.Bits.Vrt == 0)) {
1153 return EFI_DEVICE_ERROR;
1173 if ((Time->Year < mMinimalValidYear) ||
1174 (Time->Year > mMaximalValidYear) ||
1175 (Time->Month < 1) ||
1176 (Time->Month > 12) ||
1178 (Time->Hour > 23) ||
1179 (Time->Minute > 59) ||
1180 (Time->Second > 59) ||
1181 (Time->Nanosecond > 999999999) ||
1183 ((Time->Daylight & (~(EFI_TIME_ADJUST_DAYLIGHT | EFI_TIME_IN_DAYLIGHT))) != 0))
1185 return EFI_INVALID_PARAMETER;
1207 ASSERT (Time->Month >= 1);
1208 ASSERT (Time->Month <= 12);
1209 if ((Time->Day < 1) ||
1210 (Time->Day > mDayOfMonth[Time->Month - 1]) ||
1211 ((Time->Month == 2) && (!
IsLeapYear (Time) && (Time->Day > 28)))
1233 if (Time->Year % 4 == 0) {
1234 if (Time->Year % 100 == 0) {
1235 if (Time->Year % 400 == 0) {
1271 if (RegisterB.Bits.Mil == 0) {
1272 if (Time->Hour < 12) {
1276 if (Time->Hour >= 13) {
1277 Time->Hour = (UINT8)(Time->Hour - 12);
1278 }
else if (Time->Hour == 0) {
1286 Time->Year = (UINT16)(Time->Year % 100);
1288 if (RegisterB.Bits.Dm == 0) {
1300 if ((RegisterB.Bits.Mil == 0) && IsPM) {
1301 Time->Hour = (UINT8)(Time->Hour | 0x80);
1323 if ((From->Hour > To->Hour) ||
1324 ((From->Hour == To->Hour) && (From->Minute > To->Minute)) ||
1325 ((From->Hour == To->Hour) && (From->Minute == To->Minute) && (From->Second > To->Second)))
1328 }
else if ((From->Hour == To->Hour) && (From->Minute == To->Minute) && (From->Second == To->Second)) {
1357 ASSERT (From->Month >= 1);
1358 ASSERT (From->Month <= 12);
1360 if (From->Year == To->Year) {
1361 if (From->Month == To->Month) {
1362 if ((From->Day + 1) == To->Day) {
1366 }
else if (From->Day == To->Day) {
1371 }
else if (((From->Month + 1) == To->Month) && (To->Day == 1)) {
1372 if ((From->Month == 2) && !
IsLeapYear (From)) {
1373 if (From->Day == 28) {
1378 }
else if (From->Day == mDayOfMonth[From->Month - 1]) {
1384 }
else if (((From->Year + 1) == To->Year) &&
1385 (From->Month == 12) &&
1386 (From->Day == 31) &&
1414 if ((Fadt !=
NULL) &&
1415 (Fadt->Century > RTC_ADDRESS_REGISTER_D) && (Fadt->Century < 0x80)
1418 return Fadt->Century;
1443 UINT8 CenturyRtcAddress;
1447 if ((CenturyRtcAddress != 0) && (mModuleGlobal.CenturyRtcAddress != CenturyRtcAddress)) {
1448 mModuleGlobal.CenturyRtcAddress = CenturyRtcAddress;
1450 if (!EFI_ERROR (Status)) {
1451 Century = (UINT8)(Time.Year / 100);
1453 DEBUG ((DEBUG_INFO,
"PcRtc: Write 0x%x to CMOS location 0x%x\n", Century, mModuleGlobal.CenturyRtcAddress));
1454 RtcWrite (mModuleGlobal.CenturyRtcAddress, Century);
#define EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE
UINTN EFIAPI MicroSecondDelay(IN UINTN MicroSeconds)
UINT8 EFIAPI BcdToDecimal8(IN UINT8 Value)
UINT8 EFIAPI DecimalToBcd8(IN UINT8 Value)
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
UINT8 EFIAPI IoWrite8(IN UINTN Port, IN UINT8 Value)
UINT8 EFIAPI MmioRead8(IN UINTN Address)
UINT8 EFIAPI MmioWrite8(IN UINTN Address, IN UINT8 Value)
UINT8 EFIAPI IoRead8(IN UINTN Port)
#define DEBUG(Expression)
#define REPORT_STATUS_CODE(Type, Value)
UINT8 GetCenturyRtcAddress(VOID)
STATIC UINT8 MmioRtcRead(IN UINTN Address)
BOOLEAN DayValid(IN EFI_TIME *Time)
EFI_STATUS PcRtcSetWakeupTime(IN BOOLEAN Enable, IN EFI_TIME *Time OPTIONAL, IN PC_RTC_MODULE_GLOBALS *Global)
EFI_STATUS RtcWaitToUpdate(UINTN Timeout)
EFI_STATUS PcRtcInit(IN PC_RTC_MODULE_GLOBALS *Global)
INTN CompareHMS(IN EFI_TIME *From, IN EFI_TIME *To)
STATIC UINT8 IoRtcRead(IN UINTN Address)
BOOLEAN IsLeapYear(IN EFI_TIME *Time)
EFI_STATUS ConvertRtcTimeToEfiTime(IN OUT EFI_TIME *Time, IN RTC_REGISTER_B RegisterB)
STATIC VOID RtcWrite(IN UINTN Address, IN UINT8 Data)
EFI_STATUS PcRtcGetWakeupTime(OUT BOOLEAN *Enabled, OUT BOOLEAN *Pending, OUT EFI_TIME *Time, IN PC_RTC_MODULE_GLOBALS *Global)
EFI_STATUS PcRtcGetTime(OUT EFI_TIME *Time, OUT EFI_TIME_CAPABILITIES *Capabilities OPTIONAL, IN PC_RTC_MODULE_GLOBALS *Global)
EFI_STATUS PcRtcSetTimeZone(IN INT16 TimeZone, IN UINT8 Daylight, IN PC_RTC_MODULE_GLOBALS *Global)
VOID ConvertEfiTimeToRtcTime(IN OUT EFI_TIME *Time, IN RTC_REGISTER_B RegisterB)
STATIC VOID IoRtcWrite(IN UINTN Address, IN UINT8 Data)
UINT8 CheckAndConvertBcd8ToDecimal8(IN UINT8 Value)
EFI_STATUS PcRtcSetTime(IN EFI_TIME *Time, IN PC_RTC_MODULE_GLOBALS *Global)
STATIC UINT8 RtcRead(IN UINTN Address)
EFI_STATUS RtcTimeFieldsValid(IN EFI_TIME *Time)
VOID EFIAPI PcRtcAcpiTableChangeCallback(IN EFI_EVENT Event, IN VOID *Context)
STATIC VOID MmioRtcWrite(IN UINTN Address, IN UINT8 Data)
BOOLEAN IsWithinOneDay(IN EFI_TIME *From, IN EFI_TIME *To)
#define PcdGet32(TokenName)
#define FixedPcdGet8(TokenName)
#define FeaturePcdGet(TokenName)
VOID EFIAPI EfiReleaseLock(IN EFI_LOCK *Lock)
VOID EFIAPI EfiAcquireLock(IN EFI_LOCK *Lock)
EFI_ACPI_COMMON_HEADER *EFIAPI EfiLocateFirstAcpiTable(IN UINT32 Signature)
#define EFI_VARIABLE_NON_VOLATILE
EFI_STATUS EFIAPI EfiGetVariable(IN CHAR16 *VariableName, IN EFI_GUID *VendorGuid, OUT UINT32 *Attributes OPTIONAL, IN OUT UINTN *DataSize, OUT VOID *Data)
BOOLEAN EFIAPI EfiAtRuntime(VOID)
EFI_STATUS EFIAPI EfiSetVariable(IN CHAR16 *VariableName, IN EFI_GUID *VendorGuid, IN UINT32 Attributes, IN UINTN DataSize, IN VOID *Data)
#define EFI_UNSPECIFIED_TIMEZONE