summaryrefslogtreecommitdiff
path: root/sys/arch/amd64/stand/efiboot/efiboot.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/arch/amd64/stand/efiboot/efiboot.c')
-rw-r--r--sys/arch/amd64/stand/efiboot/efiboot.c74
1 files changed, 72 insertions, 2 deletions
diff --git a/sys/arch/amd64/stand/efiboot/efiboot.c b/sys/arch/amd64/stand/efiboot/efiboot.c
index 95cf92d298d..b4ff8576201 100644
--- a/sys/arch/amd64/stand/efiboot/efiboot.c
+++ b/sys/arch/amd64/stand/efiboot/efiboot.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: efiboot.c,v 1.41 2023/01/02 22:41:17 kettenis Exp $ */
+/* $OpenBSD: efiboot.c,v 1.42 2024/04/25 18:31:49 kn Exp $ */
/*
* Copyright (c) 2015 YASUOKA Masahiko <yasuoka@yasuoka.net>
@@ -1078,17 +1078,69 @@ u_int
sleep(u_int i)
{
time_t t;
+ u_int intr = 0;
/*
* Loop for the requested number of seconds, polling,
* so that it may handle interrupts.
*/
- for (t = getsecs() + i; getsecs() < t; cnischar())
+ for (t = getsecs() + i; intr == 0 && getsecs() < t; intr = cnischar())
;
+ return intr;
+}
+
+#ifdef IDLE_POWEROFF
+CHAR16 *idle_name = L"IdlePoweroff";
+EFI_STATUS idle_status;
+/* randomly generated f948e8a9-0570-4338-ad10-29f4cf12849d */
+EFI_GUID openbsd_guid = { 0xf948e8a9, 0x0570, 0x4338,
+ { 0xad, 0x10, 0x29, 0xf4, 0xcf, 0x12, 0x84, 0x9d } };
+/* Non-Volatile, Boot Service Access, Runtime Service Access */
+UINT32 idle_attrs = 0x1 | 0x2 | 0x4;
+UINT16 idle_secs;
+UINTN idle_sz = sizeof(idle_secs);
+
+int
+get_idle_timeout(void)
+{
+ idle_status = RS->GetVariable(idle_name, &openbsd_guid, NULL,
+ &idle_sz, &idle_secs);
+ if (idle_status != EFI_SUCCESS) {
+ if (idle_status != EFI_NOT_FOUND) {
+ printf("%s: %d\n", __func__, idle_status);
+ return 1;
+ }
+ return -1;
+ }
+ return 0;
+}
+
+int
+set_idle_timeout(int secs)
+{
+ idle_secs = secs;
+ idle_sz = idle_secs > 0 ? sizeof(idle_secs) : 0;
+ idle_status = RS->SetVariable(idle_name, &openbsd_guid, idle_attrs,
+ idle_sz, &idle_secs);
+ if (idle_status != EFI_SUCCESS) {
+ printf("%s: %d\n", __func__, idle_status);
+ return -1;
+ }
return 0;
}
+/* see lib/libsa/softraid.c sr_crypto_passphrase_decrypt() */
+void
+idle_poweroff(void)
+{
+ if (get_idle_timeout() == 0 && sleep(idle_secs) == 0) {
+ printf("\nno input after %us, powering off...\n", idle_secs);
+ Xpoweroff_efi();
+ }
+}
+#endif /* IDLE_POWEROFF */
+
/***********************************************************************
* Commands
***********************************************************************/
@@ -1173,3 +1225,21 @@ Xgop_efi(void)
return (0);
}
+
+#ifdef IDLE_POWEROFF
+int
+Xidle_efi(void)
+{
+ if (cmd.argc >= 2) {
+ int secs;
+
+ secs = strtol(cmd.argv[1], NULL, 10);
+ if (0 <= secs && secs < UINT16_MAX)
+ set_idle_timeout(secs);
+ } else {
+ if (get_idle_timeout() == 0)
+ printf("Timeout = %us\n", idle_secs);
+ }
+ return 0;
+}
+#endif /* IDLE_POWEROFF */