Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F109907976
D36714.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
4 KB
Referenced Files
None
Subscribers
None
D36714.diff
View Options
diff --git a/sys/dev/efidev/efidev.c b/sys/dev/efidev/efidev.c
--- a/sys/dev/efidev/efidev.c
+++ b/sys/dev/efidev/efidev.c
@@ -90,6 +90,21 @@
error = efi_set_time(tm);
break;
}
+ case EFIIOC_GET_WAKETIME:
+ {
+ struct efi_waketime_ioc *wt = (struct efi_waketime_ioc *)addr;
+
+ error = efi_get_waketime(&wt->enabled, &wt->pending,
+ &wt->waketime);
+ break;
+ }
+ case EFIIOC_SET_WAKETIME:
+ {
+ struct efi_waketime_ioc *wt = (struct efi_waketime_ioc *)addr;
+
+ error = efi_set_waketime(wt->enabled, &wt->waketime);
+ break;
+ }
case EFIIOC_VAR_GET:
{
struct efi_var_ioc *ev = (struct efi_var_ioc *)addr;
diff --git a/sys/dev/efidev/efirt.c b/sys/dev/efidev/efirt.c
--- a/sys/dev/efidev/efirt.c
+++ b/sys/dev/efidev/efirt.c
@@ -32,6 +32,8 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
+#include "opt_acpi.h"
+
#include <sys/param.h>
#include <sys/efi.h>
#include <sys/eventhandler.h>
@@ -61,6 +63,10 @@
#include <vm/pmap.h>
#include <vm/vm_map.h>
+#ifdef DEV_ACPI
+#include <contrib/dev/acpica/include/acpi.h>
+#endif
+
#define EFI_TABLE_ALLOC_MAX 0x800000
static struct efi_systbl *efi_systbl;
@@ -571,6 +577,74 @@
return (error);
}
+static int
+get_waketime(uint8_t *enabled, uint8_t *pending, struct efi_tm *tm)
+{
+ struct efirt_callinfo ec;
+ int error;
+#ifdef DEV_ACPI
+ UINT32 acpiRtcEnabled;
+#endif
+
+ if (efi_runtime == NULL)
+ return (ENXIO);
+
+ EFI_TIME_LOCK();
+ bzero(&ec, sizeof(ec));
+ ec.ec_name = "rt_getwaketime";
+ ec.ec_argcnt = 3;
+ ec.ec_arg1 = (uintptr_t)enabled;
+ ec.ec_arg2 = (uintptr_t)pending;
+ ec.ec_arg3 = (uintptr_t)tm;
+ ec.ec_fptr = EFI_RT_METHOD_PA(rt_getwaketime);
+ error = efi_call(&ec);
+ EFI_TIME_UNLOCK();
+
+#ifdef DEV_ACPI
+ if (error == 0) {
+ error = AcpiReadBitRegister(ACPI_BITREG_RT_CLOCK_ENABLE,
+ &acpiRtcEnabled);
+ if (ACPI_SUCCESS(error)) {
+ *enabled = *enabled && acpiRtcEnabled;
+ } else
+ error = EIO;
+ }
+#endif
+
+ return (error);
+}
+
+static int
+set_waketime(uint8_t enable, struct efi_tm *tm)
+{
+ struct efirt_callinfo ec;
+ int error;
+
+ if (efi_runtime == NULL)
+ return (ENXIO);
+
+ EFI_TIME_LOCK();
+ bzero(&ec, sizeof(ec));
+ ec.ec_name = "rt_setwaketime";
+ ec.ec_argcnt = 2;
+ ec.ec_arg1 = (uintptr_t)enable;
+ ec.ec_arg2 = (uintptr_t)tm;
+ ec.ec_fptr = EFI_RT_METHOD_PA(rt_setwaketime);
+ error = efi_call(&ec);
+ EFI_TIME_UNLOCK();
+
+#ifdef DEV_ACPI
+ if (error == 0) {
+ error = AcpiWriteBitRegister(ACPI_BITREG_RT_CLOCK_ENABLE,
+ (enable != 0) ? 1 : 0);
+ if (ACPI_FAILURE(error))
+ error = EIO;
+ }
+#endif
+
+ return (error);
+}
+
static int
get_time_capabilities(struct efi_tmcap *tmcap)
{
@@ -713,6 +787,8 @@
.get_time_capabilities = get_time_capabilities,
.reset_system = reset_system,
.set_time = set_time,
+ .get_waketime = get_waketime,
+ .set_waketime = set_waketime,
.var_get = var_get,
.var_nextname = var_nextname,
.var_set = var_set,
diff --git a/sys/sys/efi.h b/sys/sys/efi.h
--- a/sys/sys/efi.h
+++ b/sys/sys/efi.h
@@ -254,6 +254,9 @@
int (*get_time_capabilities)(struct efi_tmcap *);
int (*reset_system)(enum efi_reset);
int (*set_time)(struct efi_tm *);
+ int (*get_waketime)(uint8_t *enabled, uint8_t *pending,
+ struct efi_tm *tm);
+ int (*set_waketime)(uint8_t enable, struct efi_tm *tm);
int (*var_get)(uint16_t *, struct uuid *, uint32_t *, size_t *,
void *);
int (*var_nextname)(size_t *, uint16_t *, struct uuid *);
@@ -319,6 +322,21 @@
return (active_efi_ops->set_time(tm));
}
+static inline int efi_get_waketime(uint8_t *enabled, uint8_t *pending,
+ struct efi_tm *tm)
+{
+ if (active_efi_ops->get_waketime == NULL)
+ return (ENXIO);
+ return (active_efi_ops->get_waketime(enabled, pending, tm));
+}
+
+static inline int efi_set_waketime(uint8_t enable, struct efi_tm *tm)
+{
+ if (active_efi_ops->set_waketime == NULL)
+ return (ENXIO);
+ return (active_efi_ops->set_waketime(enable, tm));
+}
+
static inline int efi_var_get(uint16_t *name, struct uuid *vendor,
uint32_t *attrib, size_t *datasize, void *data)
{
diff --git a/sys/sys/efiio.h b/sys/sys/efiio.h
--- a/sys/sys/efiio.h
+++ b/sys/sys/efiio.h
@@ -50,11 +50,20 @@
size_t datasize; /* Number of *bytes* in the data */
};
+struct efi_waketime_ioc
+{
+ struct efi_tm waketime;
+ uint8_t enabled;
+ uint8_t pending;
+};
+
#define EFIIOC_GET_TABLE _IOWR('E', 1, struct efi_get_table_ioc)
#define EFIIOC_GET_TIME _IOR('E', 2, struct efi_tm)
#define EFIIOC_SET_TIME _IOW('E', 3, struct efi_tm)
#define EFIIOC_VAR_GET _IOWR('E', 4, struct efi_var_ioc)
#define EFIIOC_VAR_NEXT _IOWR('E', 5, struct efi_var_ioc)
#define EFIIOC_VAR_SET _IOWR('E', 6, struct efi_var_ioc)
+#define EFIIOC_GET_WAKETIME _IOR('E', 7, struct efi_waketime_ioc)
+#define EFIIOC_SET_WAKETIME _IOW('E', 8, struct efi_waketime_ioc)
#endif /* _SYS_EFIIO_H_ */
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Wed, Feb 12, 1:34 AM (17 h, 16 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
16604116
Default Alt Text
D36714.diff (4 KB)
Attached To
Mode
D36714: EFI wake time
Attached
Detach File
Event Timeline
Log In to Comment