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 @@ -67,6 +67,20 @@ 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 @@ -439,6 +439,51 @@ return (error); } +int +efi_get_waketime(uint8_t* enabled, uint8_t* pending, 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_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(); + + return (error); +} + +int +efi_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(); + + return (error); +} + int efi_get_time_capabilities(struct efi_tmcap *tmcap) { diff --git a/sys/sys/efi.h b/sys/sys/efi.h --- a/sys/sys/efi.h +++ b/sys/sys/efi.h @@ -184,6 +184,8 @@ int efi_rt_ok(void); int efi_get_table(struct uuid *uuid, void **ptr); int efi_get_time(struct efi_tm *tm); +int efi_get_waketime(uint8_t* enabled, uint8_t* pending, struct efi_tm *tm); +int efi_set_waketime(uint8_t enable, struct efi_tm *tm); int efi_get_time_capabilities(struct efi_tmcap *tmcap); int efi_reset_system(enum efi_reset type); int efi_set_time(struct efi_tm *tm); diff --git a/sys/sys/efiio.h b/sys/sys/efiio.h --- a/sys/sys/efiio.h +++ b/sys/sys/efiio.h @@ -42,10 +42,19 @@ 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_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_ */