Home | History | Annotate | Download | only in PcatRealTimeClockRuntimeDxe
      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