\r
**/\r
\r
-#include <Base.h>\r
#include <Uefi.h>\r
#include <PiDxe.h>\r
#include <Library/BaseLib.h>\r
#include <Library/IoLib.h>\r
#include <Library/RealTimeClockLib.h>\r
#include <Library/MemoryAllocationLib.h>\r
+#include <Library/PcdLib.h>\r
#include <Library/ArmPlatformSysConfigLib.h>\r
#include <Library/UefiBootServicesTableLib.h>\r
#include <Library/UefiRuntimeServicesTableLib.h>\r
#include <Protocol/RealTimeClock.h>\r
#include <Guid/GlobalVariable.h>\r
-#include <ArmPlatform.h>\r
#include <Drivers/PL031RealTimeClock.h>\r
\r
+#include <ArmPlatform.h>\r
+\r
CHAR16 mTimeZoneVariableName[] = L"PL031_TimeZone";\r
CHAR16 mDaylightVariableName[] = L"PL031_Daylight";\r
BOOLEAN mPL031Initialized = FALSE;\r
EFI_STATUS Status;\r
\r
// Check if this is a PrimeCell Peripheral\r
- if( ( MmioRead8( PL031_RTC_PCELL_ID0 ) != 0x0D )\r
- || ( MmioRead8( PL031_RTC_PCELL_ID1 ) != 0xF0 )\r
- || ( MmioRead8( PL031_RTC_PCELL_ID2 ) != 0x05 )\r
- || ( MmioRead8( PL031_RTC_PCELL_ID3 ) != 0xB1 ) ) {\r
+ if ( (MmioRead8 (PL031_RTC_PCELL_ID0) != 0x0D)\r
+ || (MmioRead8 (PL031_RTC_PCELL_ID1) != 0xF0)\r
+ || (MmioRead8 (PL031_RTC_PCELL_ID2) != 0x05)\r
+ || (MmioRead8 (PL031_RTC_PCELL_ID3) != 0xB1)) {\r
Status = EFI_NOT_FOUND;\r
goto EXIT;\r
}\r
\r
// Check if this PrimeCell Peripheral is the SP805 Watchdog Timer\r
- if( ( MmioRead8( PL031_RTC_PERIPH_ID0 ) != 0x31 )\r
- || ( MmioRead8( PL031_RTC_PERIPH_ID1 ) != 0x10 )\r
- || (( MmioRead8( PL031_RTC_PERIPH_ID2 ) & 0xF) != 0x04 )\r
- || ( MmioRead8( PL031_RTC_PERIPH_ID3 ) != 0x00 ) ) {\r
+ if ( (MmioRead8 (PL031_RTC_PERIPH_ID0) != 0x31)\r
+ || (MmioRead8 (PL031_RTC_PERIPH_ID1) != 0x10)\r
+ || ((MmioRead8 (PL031_RTC_PERIPH_ID2) & 0xF) != 0x04)\r
+ || (MmioRead8 (PL031_RTC_PERIPH_ID3) != 0x00)) {\r
Status = EFI_NOT_FOUND;\r
goto EXIT;\r
}\r
}\r
\r
// Ensure interrupts are masked. We do not want RTC interrupts in UEFI\r
- if ( (MmioRead32( PL031_RTC_IMSC_IRQ_MASK_SET_CLEAR_REGISTER ) & PL031_SET_IRQ_MASK) != PL031_SET_IRQ_MASK ) {\r
- MmioOr32( PL031_RTC_IMSC_IRQ_MASK_SET_CLEAR_REGISTER, PL031_SET_IRQ_MASK);\r
+ if ((MmioRead32 (PL031_RTC_IMSC_IRQ_MASK_SET_CLEAR_REGISTER) & PL031_SET_IRQ_MASK) != PL031_SET_IRQ_MASK) {\r
+ MmioOr32 (PL031_RTC_IMSC_IRQ_MASK_SET_CLEAR_REGISTER, PL031_SET_IRQ_MASK);\r
}\r
\r
// Clear any existing interrupts\r
- if ( (MmioRead32( PL031_RTC_RIS_RAW_IRQ_STATUS_REGISTER ) & PL031_IRQ_TRIGGERED) == PL031_IRQ_TRIGGERED ) {\r
- MmioOr32( PL031_RTC_ICR_IRQ_CLEAR_REGISTER, PL031_CLEAR_IRQ);\r
+ if ((MmioRead32 (PL031_RTC_RIS_RAW_IRQ_STATUS_REGISTER) & PL031_IRQ_TRIGGERED) == PL031_IRQ_TRIGGERED) {\r
+ MmioOr32 (PL031_RTC_ICR_IRQ_CLEAR_REGISTER, PL031_CLEAR_IRQ);\r
}\r
\r
// Start the clock counter\r
- if ( (MmioRead32( PL031_RTC_CR_CONTROL_REGISTER ) & PL031_RTC_ENABLED) != PL031_RTC_ENABLED ) {\r
- MmioOr32( PL031_RTC_CR_CONTROL_REGISTER, PL031_RTC_ENABLED);\r
+ if ((MmioRead32 (PL031_RTC_CR_CONTROL_REGISTER) & PL031_RTC_ENABLED) != PL031_RTC_ENABLED) {\r
+ MmioOr32 (PL031_RTC_CR_CONTROL_REGISTER, PL031_RTC_ENABLED);\r
}\r
\r
mPL031Initialized = TRUE;\r
UINTN ss;\r
UINTN J;\r
\r
- if( Time->Daylight == TRUE) {\r
+ if (Time->Daylight == TRUE) {\r
\r
}\r
\r
\r
JulianDate = Time->Day + ((153*m + 2)/5) + (365*y) + (y/4) - (y/100) + (y/400) - 32045;\r
\r
- ASSERT( JulianDate > EPOCH_JULIAN_DATE );\r
+ ASSERT(JulianDate > EPOCH_JULIAN_DATE);\r
EpochDays = JulianDate - EPOCH_JULIAN_DATE;\r
\r
EpochSeconds = (EpochDays * SEC_PER_DAY) + ((UINTN)Time->Hour * SEC_PER_HOUR) + (Time->Minute * SEC_PER_MIN) + Time->Second;\r
if (Time->Day < 1 ||\r
Time->Day > DayOfMonth[Time->Month - 1] ||\r
(Time->Month == 2 && (!IsLeapYear (Time) && Time->Day > 28))\r
- ) {\r
+ ) {\r
return FALSE;\r
}\r
\r
UINTN *Daylight = 0;\r
\r
// Initialize the hardware if not already done\r
- if( !mPL031Initialized ) {\r
- Status = InitializePL031();\r
+ if (!mPL031Initialized) {\r
+ Status = InitializePL031 ();\r
if (EFI_ERROR (Status)) {\r
goto EXIT;\r
}\r
Status = ArmPlatformSysConfigGet (SYS_CFG_RTC, &EpochSeconds);\r
if (Status == EFI_UNSUPPORTED) {\r
// Battery backed up hardware RTC does not exist, revert to PL031\r
- EpochSeconds = MmioRead32( PL031_RTC_DR_DATA_REGISTER );\r
+ EpochSeconds = MmioRead32 (PL031_RTC_DR_DATA_REGISTER);\r
Status = EFI_SUCCESS;\r
} else if (EFI_ERROR (Status)) {\r
// Battery backed up hardware RTC exists but could not be read due to error. Abort.\r
} else {\r
// Battery backed up hardware RTC exists and we read the time correctly from it.\r
// Now sync the PL031 to the new time.\r
- MmioWrite32( PL031_RTC_LR_LOAD_REGISTER, EpochSeconds);\r
+ MmioWrite32 (PL031_RTC_LR_LOAD_REGISTER, EpochSeconds);\r
}\r
\r
// Ensure Time is a valid pointer\r
- if( Time == NULL ) {\r
+ if (Time == NULL) {\r
Status = EFI_INVALID_PARAMETER;\r
goto EXIT;\r
}\r
// Get the current time zone information from non-volatile storage\r
TimeZone = (INT16 *)GetVariable(mTimeZoneVariableName, &gEfiGlobalVariableGuid);\r
\r
- if( TimeZone == NULL ) {\r
+ if (TimeZone == NULL) {\r
// The time zone variable does not exist in non-volatile storage, so create it.\r
Time->TimeZone = EFI_UNSPECIFIED_TIMEZONE;\r
// Store it\r
EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,\r
sizeof(Time->TimeZone),\r
&(Time->TimeZone)\r
- );\r
+ );\r
if (EFI_ERROR (Status)) {\r
DEBUG((EFI_D_ERROR,"LibGetTime: ERROR: TimeZone\n"));\r
goto EXIT;\r
FreePool(TimeZone);\r
\r
// Check TimeZone bounds: -1440 to 1440 or 2047\r
- if( (( Time->TimeZone < -1440 ) || ( Time->TimeZone > 1440 ))\r
- && ( Time->TimeZone != EFI_UNSPECIFIED_TIMEZONE) ) {\r
+ if (((Time->TimeZone < -1440) || (Time->TimeZone > 1440))\r
+ && (Time->TimeZone != EFI_UNSPECIFIED_TIMEZONE)) {\r
Time->TimeZone = EFI_UNSPECIFIED_TIMEZONE;\r
}\r
\r
// Adjust for the correct time zone\r
- if( Time->TimeZone != EFI_UNSPECIFIED_TIMEZONE ) {\r
+ if (Time->TimeZone != EFI_UNSPECIFIED_TIMEZONE) {\r
EpochSeconds += Time->TimeZone * SEC_PER_MIN;\r
}\r
}\r
// Get the current daylight information from non-volatile storage\r
Daylight = (UINTN *)GetVariable(mDaylightVariableName, &gEfiGlobalVariableGuid);\r
\r
- if( Daylight == NULL ) {\r
+ if (Daylight == NULL) {\r
// The daylight variable does not exist in non-volatile storage, so create it.\r
Time->Daylight = 0;\r
// Store it\r
EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,\r
sizeof(Time->Daylight),\r
&(Time->Daylight)\r
- );\r
+ );\r
if (EFI_ERROR (Status)) {\r
DEBUG((EFI_D_ERROR,"LibGetTime: ERROR: Daylight\n"));\r
goto EXIT;\r
FreePool(Daylight);\r
\r
// Adjust for the correct period\r
- if( (Time->Daylight & EFI_TIME_IN_DAYLIGHT) == EFI_TIME_IN_DAYLIGHT ) {\r
+ if ((Time->Daylight & EFI_TIME_IN_DAYLIGHT) == EFI_TIME_IN_DAYLIGHT) {\r
// Convert to adjusted time, i.e. spring forwards one hour\r
EpochSeconds += SEC_PER_HOUR;\r
}\r
}\r
\r
// Convert from internal 32-bit time to UEFI time\r
- EpochToEfiTime( EpochSeconds, Time );\r
+ EpochToEfiTime (EpochSeconds, Time);\r
\r
// Update the Capabilities info\r
- if( Capabilities != NULL ) {\r
- Capabilities->Resolution = PL031_COUNTS_PER_SECOND; /* PL031 runs at frequency 1Hz */\r
- Capabilities->Accuracy = PL031_PPM_ACCURACY; /* Accuracy in ppm multiplied by 1,000,000, e.g. for 50ppm set 50,000,000 */\r
- Capabilities->SetsToZero = FALSE; /* FALSE: Setting the time does not clear the values below the resolution level */\r
+ if (Capabilities != NULL) {\r
+ // PL031 runs at frequency 1Hz\r
+ Capabilities->Resolution = PL031_COUNTS_PER_SECOND;\r
+ // Accuracy in ppm multiplied by 1,000,000, e.g. for 50ppm set 50,000,000\r
+ Capabilities->Accuracy = (UINT32)PcdGet32 (PcdPL031RtcPpmAccuracy);\r
+ // FALSE: Setting the time does not clear the values below the resolution level\r
+ Capabilities->SetsToZero = FALSE;\r
}\r
\r
EXIT:\r
// to the range 1998 .. 2011\r
\r
// Check the input parameters' range.\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
+ 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
Status = EFI_INVALID_PARAMETER;\r
goto EXIT;\r
}\r
\r
// Initialize the hardware if not already done\r
- if( !mPL031Initialized ) {\r
- Status = InitializePL031();\r
+ if (!mPL031Initialized) {\r
+ Status = InitializePL031 ();\r
if (EFI_ERROR (Status)) {\r
goto EXIT;\r
}\r
}\r
\r
- EpochSeconds = EfiTimeToEpoch( Time );\r
+ EpochSeconds = EfiTimeToEpoch (Time);\r
\r
// Adjust for the correct time zone, i.e. convert to UTC time zone\r
- if( Time->TimeZone != EFI_UNSPECIFIED_TIMEZONE ) {\r
+ if (Time->TimeZone != EFI_UNSPECIFIED_TIMEZONE) {\r
EpochSeconds -= Time->TimeZone * SEC_PER_MIN;\r
}\r
\r
// TODO: Automatic Daylight activation\r
\r
// Adjust for the correct period\r
- if( (Time->Daylight & EFI_TIME_IN_DAYLIGHT) == EFI_TIME_IN_DAYLIGHT ) {\r
+ if ((Time->Daylight & EFI_TIME_IN_DAYLIGHT) == EFI_TIME_IN_DAYLIGHT) {\r
// Convert to un-adjusted time, i.e. fall back one hour\r
EpochSeconds -= SEC_PER_HOUR;\r
}\r
\r
\r
// Set the PL031\r
- MmioWrite32( PL031_RTC_LR_LOAD_REGISTER, EpochSeconds);\r
+ MmioWrite32 (PL031_RTC_LR_LOAD_REGISTER, EpochSeconds);\r
\r
// The accesses to Variable Services can be very slow, because we may be writing to Flash.\r
// Do this after having set the RTC.\r
EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,\r
sizeof(Time->TimeZone),\r
&(Time->TimeZone)\r
- );\r
+ );\r
if (EFI_ERROR (Status)) {\r
DEBUG((EFI_D_ERROR,"LibSetTime: ERROR: TimeZone\n"));\r
goto EXIT;\r
EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,\r
sizeof(Time->Daylight),\r
&(Time->Daylight)\r
- );\r
+ );\r
if (EFI_ERROR (Status)) {\r
DEBUG((EFI_D_ERROR,"LibSetTime: ERROR: Daylight\n"));\r
goto EXIT;\r
&Handle,\r
&gEfiRealTimeClockArchProtocolGuid, NULL,\r
NULL\r
- );\r
+ );\r
\r
return Status;\r
}\r