From nobody Fri Apr 28 01:29:57 2023 X-Original-To: dev-commits-src-main@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4Q6w5K6N2fz47l2w; Fri, 28 Apr 2023 01:29:57 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4Q6w5K5BVzz3rr6; Fri, 28 Apr 2023 01:29:57 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1682645397; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=8bPZ0MM5pd5YdNuh3f0U9C89Y4QRFpNuiDQsop/HR6Y=; b=x/45bIa0rzqSXlDHIsdzFLW8OSqq3eXD4o0bgVEIr9zBxokvg+g2ZlEI+J/zz60n9O8QaI 3LoADYtuUcwt1r7o6Z9kyEPaN3Zh5XClu7zU36cMzYBaOSV/dyS0MMVMPqNpE8lV0JH7Vh XfsNgZjo8i5+FkqAaccTlFQZ24KdcQzgymgEKtFzvQarsXe/q9VzTaFxC4FCre1f3IVnL+ tBotJf1xrCdqucmXHEQwbPu7i8B4SiR0ICNZXbsm4o3qTqaeMFXDyi9S1J6EzNZrIZGrmB rjnwCPvKjMmi8pLDc7L7AnDHDgUGIgdTScCJys/SJlv0d9p5GfCUWkE7yljEgw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1682645397; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=8bPZ0MM5pd5YdNuh3f0U9C89Y4QRFpNuiDQsop/HR6Y=; b=Oi3euh3YakaPFVhic1bRvHP6RUbJoF9VDFcf+5jZwdkRooMRqjVwP2hpTvcywcYSWzxTav H+FXJSJFuG3Xt3Aw00L8kVDSKI3P5M8sb3zbkIi5RAjM110lMIY2bCevDc3cERo0WQNqyN f8GUx1SSRHCvfOQbv64lh4/kQofFqUjOaJcGaU8KZ+iJaGljAgfHUekoaPBUiRT84K1mdA B0ahzcjXSqsNHIsxq9LmqMRNa0zq5drzKlso0tSKxVgkmi6MlFBdkpQ6itY6qZVJtQaEih Hd+ARg/PzrMpDbiZn1elENKvmAywMS5D/KPrkuA/m5R/zxg7laS+R+2bHqPRcw== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1682645397; a=rsa-sha256; cv=none; b=cjt6CiejcH5AYyTTCPWKMW2F1lUiSt3LtAi/qam17urndSTwrRAurXOaNRSdYmRn01O3zL h2wPnfpIvAjY3y20B13Zruz6SyMLvfMw97+YXQA6eybOFPIi2bOgGIsFKJB4qzIfN1qH7d 4ivK3HS2LRholn1ARSYVfYK5einPNOjb/sUVqAdk3poee1jgMMq9ee2q/1an1AHpLPyAnt qMlxHPvgnr2ui4euAn+wPfHLURyIG9ee9zZaU+b4XieInMEFs/fI0ScgG8Aknz+AbgKap6 BncSzU64rR4Nxk3uMQvvMVa8jb6kG8Cdk//B29zrMjcztOiCFWFX8w2RVPZFxA== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4Q6w5K4C9nzgm9; Fri, 28 Apr 2023 01:29:57 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.16.1/8.16.1) with ESMTP id 33S1Tv1v075214; Fri, 28 Apr 2023 01:29:57 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 33S1Tv37075213; Fri, 28 Apr 2023 01:29:57 GMT (envelope-from git) Date: Fri, 28 Apr 2023 01:29:57 GMT Message-Id: <202304280129.33S1Tv37075213@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Konstantin Belousov Subject: git: 3f3ad56520ac - main - Expose EFI wake time API List-Id: Commit messages for the main branch of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-main List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-src-main@freebsd.org X-BeenThere: dev-commits-src-main@freebsd.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: kib X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: 3f3ad56520ac608a05a237c73adcb664f79de3fb Auto-Submitted: auto-generated X-ThisMailContainsUnwantedMimeParts: N The branch main has been updated by kib: URL: https://cgit.FreeBSD.org/src/commit/?id=3f3ad56520ac608a05a237c73adcb664f79de3fb commit 3f3ad56520ac608a05a237c73adcb664f79de3fb Author: Johannes Totz AuthorDate: 2023-04-26 16:15:31 +0000 Commit: Konstantin Belousov CommitDate: 2023-04-28 01:27:55 +0000 Expose EFI wake time API Reviewed by: kib MFC after: 1 week Differential revision: https://reviews.freebsd.org/D36714 --- sys/dev/efidev/efidev.c | 15 ++++++++++ sys/dev/efidev/efirt.c | 76 +++++++++++++++++++++++++++++++++++++++++++++++++ sys/sys/efi.h | 18 ++++++++++++ sys/sys/efiio.h | 9 ++++++ 4 files changed, 118 insertions(+) diff --git a/sys/dev/efidev/efidev.c b/sys/dev/efidev/efidev.c index 79d98956ed24..45e571828e51 100644 --- a/sys/dev/efidev/efidev.c +++ b/sys/dev/efidev/efidev.c @@ -90,6 +90,21 @@ efidev_ioctl(struct cdev *dev __unused, u_long cmd, caddr_t addr, 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 index e4c47fa68741..d577396de20c 100644 --- a/sys/dev/efidev/efirt.c +++ b/sys/dev/efidev/efirt.c @@ -32,6 +32,8 @@ #include __FBSDID("$FreeBSD$"); +#include "opt_acpi.h" + #include #include #include @@ -61,6 +63,10 @@ __FBSDID("$FreeBSD$"); #include #include +#ifdef DEV_ACPI +#include +#endif + #define EFI_TABLE_ALLOC_MAX 0x800000 static struct efi_systbl *efi_systbl; @@ -571,6 +577,74 @@ get_time(struct efi_tm *tm) 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 @@ const static struct efi_ops efi_ops = { .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 index 4714dd137551..8d2d932934da 100644 --- a/sys/sys/efi.h +++ b/sys/sys/efi.h @@ -254,6 +254,9 @@ struct efi_ops { 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 @@ static inline int efi_set_time(struct efi_tm *tm) 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 index 803aed6a965e..a5f0145127e3 100644 --- a/sys/sys/efiio.h +++ b/sys/sys/efiio.h @@ -50,11 +50,20 @@ struct efi_var_ioc 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_ */