Back to home page

OSCL-LXR

 
 

    


0001 ==========================
0002 EFI Real Time Clock driver
0003 ==========================
0004 
0005 S. Eranian <eranian@hpl.hp.com>
0006 
0007 March 2000
0008 
0009 1. Introduction
0010 ===============
0011 
0012 This document describes the efirtc.c driver has provided for
0013 the IA-64 platform.
0014 
0015 The purpose of this driver is to supply an API for kernel and user applications
0016 to get access to the Time Service offered by EFI version 0.92.
0017 
0018 EFI provides 4 calls one can make once the OS is booted: GetTime(),
0019 SetTime(), GetWakeupTime(), SetWakeupTime() which are all supported by this
0020 driver. We describe those calls as well the design of the driver in the
0021 following sections.
0022 
0023 2. Design Decisions
0024 ===================
0025 
0026 The original ideas was to provide a very simple driver to get access to,
0027 at first, the time of day service. This is required in order to access, in a
0028 portable way, the CMOS clock. A program like /sbin/hwclock uses such a clock
0029 to initialize the system view of the time during boot.
0030 
0031 Because we wanted to minimize the impact on existing user-level apps using
0032 the CMOS clock, we decided to expose an API that was very similar to the one
0033 used today with the legacy RTC driver (driver/char/rtc.c). However, because
0034 EFI provides a simpler services, not all ioctl() are available. Also
0035 new ioctl()s have been introduced for things that EFI provides but not the
0036 legacy.
0037 
0038 EFI uses a slightly different way of representing the time, noticeably
0039 the reference date is different. Year is the using the full 4-digit format.
0040 The Epoch is January 1st 1998. For backward compatibility reasons we don't
0041 expose this new way of representing time. Instead we use something very
0042 similar to the struct tm, i.e. struct rtc_time, as used by hwclock.
0043 One of the reasons for doing it this way is to allow for EFI to still evolve
0044 without necessarily impacting any of the user applications. The decoupling
0045 enables flexibility and permits writing wrapper code is ncase things change.
0046 
0047 The driver exposes two interfaces, one via the device file and a set of
0048 ioctl()s. The other is read-only via the /proc filesystem.
0049 
0050 As of today we don't offer a /proc/sys interface.
0051 
0052 To allow for a uniform interface between the legacy RTC and EFI time service,
0053 we have created the include/linux/rtc.h header file to contain only the
0054 "public" API of the two drivers.  The specifics of the legacy RTC are still
0055 in include/linux/mc146818rtc.h.
0056 
0057 
0058 3. Time of day service
0059 ======================
0060 
0061 The part of the driver gives access to the time of day service of EFI.
0062 Two ioctl()s, compatible with the legacy RTC calls:
0063 
0064         Read the CMOS clock::
0065 
0066                 ioctl(d, RTC_RD_TIME, &rtc);
0067 
0068         Write the CMOS clock::
0069 
0070                 ioctl(d, RTC_SET_TIME, &rtc);
0071 
0072 The rtc is a pointer to a data structure defined in rtc.h which is close
0073 to a struct tm::
0074 
0075   struct rtc_time {
0076           int tm_sec;
0077           int tm_min;
0078           int tm_hour;
0079           int tm_mday;
0080           int tm_mon;
0081           int tm_year;
0082           int tm_wday;
0083           int tm_yday;
0084           int tm_isdst;
0085   };
0086 
0087 The driver takes care of converting back an forth between the EFI time and
0088 this format.
0089 
0090 Those two ioctl()s can be exercised with the hwclock command:
0091 
0092 For reading::
0093 
0094         # /sbin/hwclock --show
0095         Mon Mar  6 15:32:32 2000  -0.910248 seconds
0096 
0097 For setting::
0098 
0099         # /sbin/hwclock --systohc
0100 
0101 Root privileges are required to be able to set the time of day.
0102 
0103 4. Wakeup Alarm service
0104 =======================
0105 
0106 EFI provides an API by which one can program when a machine should wakeup,
0107 i.e. reboot. This is very different from the alarm provided by the legacy
0108 RTC which is some kind of interval timer alarm. For this reason we don't use
0109 the same ioctl()s to get access to the service. Instead we have
0110 introduced 2 news ioctl()s to the interface of an RTC.
0111 
0112 We have added 2 new ioctl()s that are specific to the EFI driver:
0113 
0114         Read the current state of the alarm::
0115 
0116                 ioctl(d, RTC_WKALM_RD, &wkt)
0117 
0118         Set the alarm or change its status::
0119 
0120                 ioctl(d, RTC_WKALM_SET, &wkt)
0121 
0122 The wkt structure encapsulates a struct rtc_time + 2 extra fields to get
0123 status information::
0124 
0125   struct rtc_wkalrm {
0126 
0127           unsigned char enabled; /* =1 if alarm is enabled */
0128           unsigned char pending; /* =1 if alarm is pending  */
0129 
0130           struct rtc_time time;
0131   }
0132 
0133 As of today, none of the existing user-level apps supports this feature.
0134 However writing such a program should be hard by simply using those two
0135 ioctl().
0136 
0137 Root privileges are required to be able to set the alarm.
0138 
0139 5. References
0140 =============
0141 
0142 Checkout the following Web site for more information on EFI:
0143 
0144 http://developer.intel.com/technology/efi/