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