2 * SPDX-License-Identifier: BSD-2-Clause
4 * Copyright (c) 2023 Johannes Totz
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 #include <sys/efiio.h>
42 fprintf(stderr, "Usage:\n"
43 " efiwake -- print out current "
44 "EFI time and wake time\n"
45 " efiwake -d -- disable wake time\n"
46 " efiwake -e yyyy-mm-ddThh:mm:ss -- enable wake time\n"
52 main(int argc, char **argv)
55 struct efi_waketime_ioc waketime;
56 int ch, error, efi_fd;
57 bool disable = false, enable = false;
59 memset(&waketime, 0, sizeof(waketime));
61 while ((ch = getopt(argc, argv, "de:")) != -1) {
68 "%hu-%02hhu-%02hhuT%02hhu:%02hhu:%02hhu",
69 &waketime.waketime.tm_year,
70 &waketime.waketime.tm_mon,
71 &waketime.waketime.tm_mday,
72 &waketime.waketime.tm_hour,
73 &waketime.waketime.tm_min,
74 &waketime.waketime.tm_sec) != 6) {
89 if (disable && enable)
92 efi_fd = open("/dev/efi", O_RDWR);
94 err(EX_OSERR, "cannot open /dev/efi");
96 error = ioctl(efi_fd, EFIIOC_GET_TIME, &now);
98 err(EX_OSERR, "cannot get EFI time");
100 /* EFI's time can be different from kernel's time. */
101 printf("Current EFI time: %u-%02u-%02uT%02u:%02u:%02u\n",
102 now.tm_year, now.tm_mon, now.tm_mday, now.tm_hour, now.tm_min,
107 * It's tempting to preserve the current timer value.
108 * However, wonky EFI implementations sometimes return bogus
109 * dates for the wake timer and would then fail disabling it
111 * A safe timer value is the current EFI time.
113 waketime.waketime = now;
114 waketime.enabled = 0;
115 error = ioctl(efi_fd, EFIIOC_SET_WAKETIME, &waketime);
117 err(EX_OSERR, "cannot disable EFI wake time");
120 waketime.enabled = 1;
121 error = ioctl(efi_fd, EFIIOC_SET_WAKETIME, &waketime);
123 err(EX_OSERR, "cannot enable EFI wake time");
126 /* Confirm to user what the wake time has been set to. */
127 error = ioctl(efi_fd, EFIIOC_GET_WAKETIME, &waketime);
129 err(EX_OSERR, "cannot get EFI wake time");
131 printf("EFI wake time: %u-%02u-%02uT%02u:%02u:%02u; "
132 "enabled=%i, pending=%i\n",
133 waketime.waketime.tm_year, waketime.waketime.tm_mon,
134 waketime.waketime.tm_mday, waketime.waketime.tm_hour,
135 waketime.waketime.tm_min, waketime.waketime.tm_sec,
136 waketime.enabled, waketime.pending);