^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) ==========================
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) EFI Real Time Clock driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) ==========================
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) S. Eranian <eranian@hpl.hp.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) March 2000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) 1. Introduction
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) ===============
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) This document describes the efirtc.c driver has provided for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) the IA-64 platform.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) The purpose of this driver is to supply an API for kernel and user applications
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) to get access to the Time Service offered by EFI version 0.92.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) EFI provides 4 calls one can make once the OS is booted: GetTime(),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) SetTime(), GetWakeupTime(), SetWakeupTime() which are all supported by this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) driver. We describe those calls as well the design of the driver in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) following sections.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) 2. Design Decisions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) ===================
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) The original ideas was to provide a very simple driver to get access to,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) at first, the time of day service. This is required in order to access, in a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) portable way, the CMOS clock. A program like /sbin/hwclock uses such a clock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) to initialize the system view of the time during boot.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) Because we wanted to minimize the impact on existing user-level apps using
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) the CMOS clock, we decided to expose an API that was very similar to the one
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) used today with the legacy RTC driver (driver/char/rtc.c). However, because
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) EFI provides a simpler services, not all ioctl() are available. Also
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) new ioctl()s have been introduced for things that EFI provides but not the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) legacy.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) EFI uses a slightly different way of representing the time, noticeably
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) the reference date is different. Year is the using the full 4-digit format.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) The Epoch is January 1st 1998. For backward compatibility reasons we don't
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) expose this new way of representing time. Instead we use something very
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) similar to the struct tm, i.e. struct rtc_time, as used by hwclock.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) One of the reasons for doing it this way is to allow for EFI to still evolve
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) without necessarily impacting any of the user applications. The decoupling
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) enables flexibility and permits writing wrapper code is ncase things change.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) The driver exposes two interfaces, one via the device file and a set of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) ioctl()s. The other is read-only via the /proc filesystem.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) As of today we don't offer a /proc/sys interface.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) To allow for a uniform interface between the legacy RTC and EFI time service,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) we have created the include/linux/rtc.h header file to contain only the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) "public" API of the two drivers. The specifics of the legacy RTC are still
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) in include/linux/mc146818rtc.h.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) 3. Time of day service
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) ======================
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) The part of the driver gives access to the time of day service of EFI.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) Two ioctl()s, compatible with the legacy RTC calls:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) Read the CMOS clock::
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) ioctl(d, RTC_RD_TIME, &rtc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) Write the CMOS clock::
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) ioctl(d, RTC_SET_TIME, &rtc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) The rtc is a pointer to a data structure defined in rtc.h which is close
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) to a struct tm::
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) struct rtc_time {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) int tm_sec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) int tm_min;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) int tm_hour;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) int tm_mday;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) int tm_mon;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) int tm_year;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) int tm_wday;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) int tm_yday;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) int tm_isdst;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) The driver takes care of converting back an forth between the EFI time and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) this format.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) Those two ioctl()s can be exercised with the hwclock command:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) For reading::
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) # /sbin/hwclock --show
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) Mon Mar 6 15:32:32 2000 -0.910248 seconds
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) For setting::
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) # /sbin/hwclock --systohc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) Root privileges are required to be able to set the time of day.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 4. Wakeup Alarm service
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) =======================
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) EFI provides an API by which one can program when a machine should wakeup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) i.e. reboot. This is very different from the alarm provided by the legacy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) RTC which is some kind of interval timer alarm. For this reason we don't use
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) the same ioctl()s to get access to the service. Instead we have
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) introduced 2 news ioctl()s to the interface of an RTC.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) We have added 2 new ioctl()s that are specific to the EFI driver:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) Read the current state of the alarm::
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) ioctl(d, RTC_WKALM_RD, &wkt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) Set the alarm or change its status::
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) ioctl(d, RTC_WKALM_SET, &wkt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) The wkt structure encapsulates a struct rtc_time + 2 extra fields to get
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) status information::
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) struct rtc_wkalrm {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) unsigned char enabled; /* =1 if alarm is enabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) unsigned char pending; /* =1 if alarm is pending */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) struct rtc_time time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) As of today, none of the existing user-level apps supports this feature.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) However writing such a program should be hard by simply using those two
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) ioctl().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) Root privileges are required to be able to set the alarm.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 5. References
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) =============
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) Checkout the following Web site for more information on EFI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) http://developer.intel.com/technology/efi/