1 /** @file 2 Header file for real time clock driver. 3 4 Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR> 5 Copyright (c) 2017, AMD Inc. All rights reserved.<BR> 6 7 SPDX-License-Identifier: BSD-2-Clause-Patent 8 9 **/ 10 11 12 #ifndef _RTC_H_ 13 #define _RTC_H_ 14 15 16 #include <Uefi.h> 17 18 #include <Guid/Acpi.h> 19 20 #include <Protocol/RealTimeClock.h> 21 22 #include <Library/BaseLib.h> 23 #include <Library/DebugLib.h> 24 #include <Library/UefiLib.h> 25 #include <Library/BaseMemoryLib.h> 26 #include <Library/IoLib.h> 27 #include <Library/TimerLib.h> 28 #include <Library/UefiDriverEntryPoint.h> 29 #include <Library/UefiBootServicesTableLib.h> 30 #include <Library/UefiRuntimeLib.h> 31 #include <Library/UefiRuntimeServicesTableLib.h> 32 #include <Library/PcdLib.h> 33 #include <Library/ReportStatusCodeLib.h> 34 35 typedef struct { 36 EFI_LOCK RtcLock; 37 INT16 SavedTimeZone; 38 UINT8 Daylight; 39 UINT8 CenturyRtcAddress; 40 } PC_RTC_MODULE_GLOBALS; 41 42 extern PC_RTC_MODULE_GLOBALS mModuleGlobal; 43 44 // 45 // Dallas DS12C887 Real Time Clock 46 // 47 #define RTC_ADDRESS_SECONDS 0 // R/W Range 0..59 48 #define RTC_ADDRESS_SECONDS_ALARM 1 // R/W Range 0..59 49 #define RTC_ADDRESS_MINUTES 2 // R/W Range 0..59 50 #define RTC_ADDRESS_MINUTES_ALARM 3 // R/W Range 0..59 51 #define RTC_ADDRESS_HOURS 4 // R/W Range 1..12 or 0..23 Bit 7 is AM/PM 52 #define RTC_ADDRESS_HOURS_ALARM 5 // R/W Range 1..12 or 0..23 Bit 7 is AM/PM 53 #define RTC_ADDRESS_DAY_OF_THE_WEEK 6 // R/W Range 1..7 54 #define RTC_ADDRESS_DAY_OF_THE_MONTH 7 // R/W Range 1..31 55 #define RTC_ADDRESS_MONTH 8 // R/W Range 1..12 56 #define RTC_ADDRESS_YEAR 9 // R/W Range 0..99 57 #define RTC_ADDRESS_REGISTER_A 10 // R/W[0..6] R0[7] 58 #define RTC_ADDRESS_REGISTER_B 11 // R/W 59 #define RTC_ADDRESS_REGISTER_C 12 // RO 60 #define RTC_ADDRESS_REGISTER_D 13 // RO 61 // 62 // Date and time initial values. 63 // They are used if the RTC values are invalid during driver initialization 64 // 65 #define RTC_INIT_SECOND 0 66 #define RTC_INIT_MINUTE 0 67 #define RTC_INIT_HOUR 0 68 #define RTC_INIT_DAY 1 69 #define RTC_INIT_MONTH 1 70 71 #pragma pack(1) 72 // 73 // Register A 74 // 75 typedef struct { 76 UINT8 Rs : 4; // Rate Selection Bits 77 UINT8 Dv : 3; // Divisor 78 UINT8 Uip : 1; // Update in progress 79 } RTC_REGISTER_A_BITS; 80 81 typedef union { 82 RTC_REGISTER_A_BITS Bits; 83 UINT8 Data; 84 } RTC_REGISTER_A; 85 86 // 87 // Register B 88 // 89 typedef struct { 90 UINT8 Dse : 1; // 0 - Daylight saving disabled 1 - Daylight savings enabled 91 UINT8 Mil : 1; // 0 - 12 hour mode 1 - 24 hour mode 92 UINT8 Dm : 1; // 0 - BCD Format 1 - Binary Format 93 UINT8 Sqwe : 1; // 0 - Disable SQWE output 1 - Enable SQWE output 94 UINT8 Uie : 1; // 0 - Update INT disabled 1 - Update INT enabled 95 UINT8 Aie : 1; // 0 - Alarm INT disabled 1 - Alarm INT Enabled 96 UINT8 Pie : 1; // 0 - Periodic INT disabled 1 - Periodic INT Enabled 97 UINT8 Set : 1; // 0 - Normal operation. 1 - Updates inhibited 98 } RTC_REGISTER_B_BITS; 99 100 typedef union { 101 RTC_REGISTER_B_BITS Bits; 102 UINT8 Data; 103 } RTC_REGISTER_B; 104 105 // 106 // Register C 107 // 108 typedef struct { 109 UINT8 Reserved : 4; // Read as zero. Can not be written. 110 UINT8 Uf : 1; // Update End Interrupt Flag 111 UINT8 Af : 1; // Alarm Interrupt Flag 112 UINT8 Pf : 1; // Periodic Interrupt Flag 113 UINT8 Irqf : 1; // Interrupt Request Flag = PF & PIE | AF & AIE | UF & UIE 114 } RTC_REGISTER_C_BITS; 115 116 typedef union { 117 RTC_REGISTER_C_BITS Bits; 118 UINT8 Data; 119 } RTC_REGISTER_C; 120 121 // 122 // Register D 123 // 124 typedef struct { 125 UINT8 Reserved : 7; // Read as zero. Can not be written. 126 UINT8 Vrt : 1; // Valid RAM and Time 127 } RTC_REGISTER_D_BITS; 128 129 typedef union { 130 RTC_REGISTER_D_BITS Bits; 131 UINT8 Data; 132 } RTC_REGISTER_D; 133 134 #pragma pack() 135 136 /** 137 Initialize RTC. 138 139 @param Global For global use inside this module. 140 141 @retval EFI_DEVICE_ERROR Initialization failed due to device error. 142 @retval EFI_SUCCESS Initialization successful. 143 144 **/ 145 EFI_STATUS 146 PcRtcInit ( 147 IN PC_RTC_MODULE_GLOBALS *Global 148 ); 149 150 /** 151 Sets the current local time and date information. 152 153 @param Time A pointer to the current time. 154 @param Global For global use inside this module. 155 156 @retval EFI_SUCCESS The operation completed successfully. 157 @retval EFI_INVALID_PARAMETER A time field is out of range. 158 @retval EFI_DEVICE_ERROR The time could not be set due due to hardware error. 159 160 **/ 161 EFI_STATUS 162 PcRtcSetTime ( 163 IN EFI_TIME *Time, 164 IN PC_RTC_MODULE_GLOBALS *Global 165 ); 166 167 /** 168 Returns the current time and date information, and the time-keeping capabilities 169 of the hardware platform. 170 171 @param Time A pointer to storage to receive a snapshot of the current time. 172 @param Capabilities An optional pointer to a buffer to receive the real time clock 173 device's capabilities. 174 @param Global For global use inside this module. 175 176 @retval EFI_SUCCESS The operation completed successfully. 177 @retval EFI_INVALID_PARAMETER Time is NULL. 178 @retval EFI_DEVICE_ERROR The time could not be retrieved due to hardware error. 179 180 **/ 181 EFI_STATUS 182 PcRtcGetTime ( 183 OUT EFI_TIME *Time, 184 OUT EFI_TIME_CAPABILITIES *Capabilities, OPTIONAL 185 IN PC_RTC_MODULE_GLOBALS *Global 186 ); 187 188 /** 189 Sets the system wakeup alarm clock time. 190 191 @param Enabled Enable or disable the wakeup alarm. 192 @param Time If Enable is TRUE, the time to set the wakeup alarm for. 193 If Enable is FALSE, then this parameter is optional, and may be NULL. 194 @param Global For global use inside this module. 195 196 @retval EFI_SUCCESS If Enable is TRUE, then the wakeup alarm was enabled. 197 If Enable is FALSE, then the wakeup alarm was disabled. 198 @retval EFI_INVALID_PARAMETER A time field is out of range. 199 @retval EFI_DEVICE_ERROR The wakeup time could not be set due to a hardware error. 200 @retval EFI_UNSUPPORTED A wakeup timer is not supported on this platform. 201 202 **/ 203 EFI_STATUS 204 PcRtcSetWakeupTime ( 205 IN BOOLEAN Enable, 206 IN EFI_TIME *Time, OPTIONAL 207 IN PC_RTC_MODULE_GLOBALS *Global 208 ); 209 210 /** 211 Returns the current wakeup alarm clock setting. 212 213 @param Enabled Indicates if the alarm is currently enabled or disabled. 214 @param Pending Indicates if the alarm signal is pending and requires acknowledgement. 215 @param Time The current alarm setting. 216 @param Global For global use inside this module. 217 218 @retval EFI_SUCCESS The alarm settings were returned. 219 @retval EFI_INVALID_PARAMETER Enabled is NULL. 220 @retval EFI_INVALID_PARAMETER Pending is NULL. 221 @retval EFI_INVALID_PARAMETER Time is NULL. 222 @retval EFI_DEVICE_ERROR The wakeup time could not be retrieved due to a hardware error. 223 @retval EFI_UNSUPPORTED A wakeup timer is not supported on this platform. 224 225 **/ 226 EFI_STATUS 227 PcRtcGetWakeupTime ( 228 OUT BOOLEAN *Enabled, 229 OUT BOOLEAN *Pending, 230 OUT EFI_TIME *Time, 231 IN PC_RTC_MODULE_GLOBALS *Global 232 ); 233 234 /** 235 The user Entry Point for PcRTC module. 236 237 This is the entry point for PcRTC module. It installs the UEFI runtime service 238 including GetTime(),SetTime(),GetWakeupTime(),and SetWakeupTime(). 239 240 @param ImageHandle The firmware allocated handle for the EFI image. 241 @param SystemTable A pointer to the EFI System Table. 242 243 @retval EFI_SUCCESS The entry point is executed successfully. 244 @retval Others Some error occurs when executing this entry point. 245 246 **/ 247 EFI_STATUS 248 EFIAPI 249 InitializePcRtc ( 250 IN EFI_HANDLE ImageHandle, 251 IN EFI_SYSTEM_TABLE *SystemTable 252 ); 253 254 /** 255 See if all fields of a variable of EFI_TIME type is correct. 256 257 @param Time The time to be checked. 258 259 @retval EFI_INVALID_PARAMETER Some fields of Time are not correct. 260 @retval EFI_SUCCESS Time is a valid EFI_TIME variable. 261 262 **/ 263 EFI_STATUS 264 RtcTimeFieldsValid ( 265 IN EFI_TIME *Time 266 ); 267 268 /** 269 Converts time from EFI_TIME format defined by UEFI spec to RTC format. 270 271 This function converts time from EFI_TIME format defined by UEFI spec to RTC format. 272 If data mode of RTC is BCD, then converts EFI_TIME to it. 273 If RTC is in 12-hour format, then converts EFI_TIME to it. 274 275 @param Time On input, the time data read from UEFI to convert 276 On output, the time converted to RTC format 277 @param RegisterB Value of Register B of RTC, indicating data mode 278 **/ 279 VOID 280 ConvertEfiTimeToRtcTime ( 281 IN OUT EFI_TIME *Time, 282 IN RTC_REGISTER_B RegisterB 283 ); 284 285 286 /** 287 Converts time read from RTC to EFI_TIME format defined by UEFI spec. 288 289 This function converts raw time data read from RTC to the EFI_TIME format 290 defined by UEFI spec. 291 If data mode of RTC is BCD, then converts it to decimal, 292 If RTC is in 12-hour format, then converts it to 24-hour format. 293 294 @param Time On input, the time data read from RTC to convert 295 On output, the time converted to UEFI format 296 @param RegisterB Value of Register B of RTC, indicating data mode 297 and hour format. 298 299 @retval EFI_INVALID_PARAMETER Parameters passed in are invalid. 300 @retval EFI_SUCCESS Convert RTC time to EFI time successfully. 301 302 **/ 303 EFI_STATUS 304 ConvertRtcTimeToEfiTime ( 305 IN OUT EFI_TIME *Time, 306 IN RTC_REGISTER_B RegisterB 307 ); 308 309 /** 310 Wait for a period for the RTC to be ready. 311 312 @param Timeout Tell how long it should take to wait. 313 314 @retval EFI_DEVICE_ERROR RTC device error. 315 @retval EFI_SUCCESS RTC is updated and ready. 316 **/ 317 EFI_STATUS 318 RtcWaitToUpdate ( 319 UINTN Timeout 320 ); 321 322 /** 323 See if field Day of an EFI_TIME is correct. 324 325 @param Time Its Day field is to be checked. 326 327 @retval TRUE Day field of Time is correct. 328 @retval FALSE Day field of Time is NOT correct. 329 **/ 330 BOOLEAN 331 DayValid ( 332 IN EFI_TIME *Time 333 ); 334 335 /** 336 Check if it is a leapyear. 337 338 @param Time The time to be checked. 339 340 @retval TRUE It is a leapyear. 341 @retval FALSE It is NOT a leapyear. 342 **/ 343 BOOLEAN 344 IsLeapYear ( 345 IN EFI_TIME *Time 346 ); 347 348 /** 349 Get the century RTC address from the ACPI FADT table. 350 351 @return The century RTC address or 0 if not found. 352 **/ 353 UINT8 354 GetCenturyRtcAddress ( 355 VOID 356 ); 357 358 /** 359 Notification function of ACPI Table change. 360 361 This is a notification function registered on ACPI Table change event. 362 It saves the Century address stored in ACPI FADT table. 363 364 @param Event Event whose notification function is being invoked. 365 @param Context Pointer to the notification function's context. 366 367 **/ 368 VOID 369 EFIAPI 370 PcRtcAcpiTableChangeCallback ( 371 IN EFI_EVENT Event, 372 IN VOID *Context 373 ); 374 #endif 375