summaryrefslogtreecommitdiff
path: root/sys/arch/amd64/stand
diff options
context:
space:
mode:
authorKlemens Nanni <kn@cvs.openbsd.org>2024-04-25 18:31:50 +0000
committerKlemens Nanni <kn@cvs.openbsd.org>2024-04-25 18:31:50 +0000
commit2664480f5c625d6ebfbd5cc09cf0dcc1a4c0c784 (patch)
tree60076840a12a6d8893fd6fbbc42ab96a3f11c19f /sys/arch/amd64/stand
parent18e2247e7b21ba046404816a5e7ec4fed7f701d2 (diff)
Add boot.conf(8) 'mach idle [secs]' to halt at idle passphrase prompts
Enable users to power down their machines if there was no input after N seconds during disk descryption. Motivation is to save battery and prevent pocket heaters when notebooks unhibernate (e.g. lid accidentially opened) and sit at "Passphrase: ". Only available on efi(4) systems as the timeout is saved as EFI variable; mostly because that's trivial to do, but also because we lack a better mechanism to configure that and persist such data without the root disk. Discussed with many, starting at h2k23 OK Tests gnezdo
Diffstat (limited to 'sys/arch/amd64/stand')
-rw-r--r--sys/arch/amd64/stand/boot/boot.818
-rw-r--r--sys/arch/amd64/stand/efiboot/Makefile.common3
-rw-r--r--sys/arch/amd64/stand/efiboot/cmd_i386.c5
-rw-r--r--sys/arch/amd64/stand/efiboot/conf.c4
-rw-r--r--sys/arch/amd64/stand/efiboot/efiboot.c74
-rw-r--r--sys/arch/amd64/stand/efiboot/efiboot.h5
6 files changed, 100 insertions, 9 deletions
diff --git a/sys/arch/amd64/stand/boot/boot.8 b/sys/arch/amd64/stand/boot/boot.8
index 6b3eee8ffcb..cdeb55a3cc1 100644
--- a/sys/arch/amd64/stand/boot/boot.8
+++ b/sys/arch/amd64/stand/boot/boot.8
@@ -1,4 +1,4 @@
-.\" $OpenBSD: boot.8,v 1.34 2023/02/23 19:48:21 miod Exp $
+.\" $OpenBSD: boot.8,v 1.35 2024/04/25 18:31:49 kn Exp $
.\"
.\" Copyright (c) 1997-2001 Michael Shalayeff
.\" All rights reserved.
@@ -25,7 +25,7 @@
.\" THE POSSIBILITY OF SUCH DAMAGE.
.\"
.\"
-.Dd $Mdocdate: February 23 2023 $
+.Dd $Mdocdate: April 25 2024 $
.Dt BOOT 8 amd64
.Os
.Sh NAME
@@ -245,6 +245,19 @@ If
.Ar mode
is not given,
a list of available modes is shown.
+.It Ic idle Op Ar secs
+On
+.Xr efi 4
+systems,
+sets the timeout in seconds to power down the machine,
+if no input has been given at the
+.Xr softraid 4
+passphrase prompt.
+A value of 0 unsets the timeout.
+If
+.Ar secs
+is not given,
+the current timeout is shown.
.It Ic memory
If used without any arguments, this command will print out
the memory configuration as determined through BIOS routines.
@@ -426,6 +439,7 @@ option.
.Xr gzip 1 ,
.Xr autoconf 4 ,
.Xr ddb 4 ,
+.Xr efi 4 ,
.Xr softraid 4 ,
.Xr biosboot 8 ,
.Xr boot_amd64 8 ,
diff --git a/sys/arch/amd64/stand/efiboot/Makefile.common b/sys/arch/amd64/stand/efiboot/Makefile.common
index 80b36b71a68..8421a2b4332 100644
--- a/sys/arch/amd64/stand/efiboot/Makefile.common
+++ b/sys/arch/amd64/stand/efiboot/Makefile.common
@@ -1,4 +1,4 @@
-# $OpenBSD: Makefile.common,v 1.22 2021/11/14 21:51:48 guenther Exp $
+# $OpenBSD: Makefile.common,v 1.23 2024/04/25 18:31:49 kn Exp $
S= ${.CURDIR}/../../../../..
SADIR= ${.CURDIR}/../..
@@ -18,6 +18,7 @@ COPTS+= -ffreestanding -std=gnu99
COPTS+= -fshort-wchar -fPIC -mno-red-zone
.if ${SOFTRAID:L} == "yes"
COPTS+= -DSOFTRAID
+COPTS+= -DIDLE_POWEROFF
.endif
COPTS+= -D_STANDALONE -nostdinc -fno-builtin
diff --git a/sys/arch/amd64/stand/efiboot/cmd_i386.c b/sys/arch/amd64/stand/efiboot/cmd_i386.c
index f79e2b1e090..8f6cd67f0c3 100644
--- a/sys/arch/amd64/stand/efiboot/cmd_i386.c
+++ b/sys/arch/amd64/stand/efiboot/cmd_i386.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: cmd_i386.c,v 1.1 2019/05/10 21:20:42 mlarkin Exp $ */
+/* $OpenBSD: cmd_i386.c,v 1.2 2024/04/25 18:31:49 kn Exp $ */
/*
* Copyright (c) 1997-1999 Michael Shalayeff
@@ -62,6 +62,9 @@ const struct cmd_table cmd_machine[] = {
#ifdef DEBUG
{ "regs", CMDT_CMD, Xregs },
#endif
+#ifdef IDLE_POWEROFF
+ { "idle", CMDT_CMD, Xidle_efi },
+#endif
{ NULL, 0 }
};
diff --git a/sys/arch/amd64/stand/efiboot/conf.c b/sys/arch/amd64/stand/efiboot/conf.c
index a7d10203bf3..1204987c8ea 100644
--- a/sys/arch/amd64/stand/efiboot/conf.c
+++ b/sys/arch/amd64/stand/efiboot/conf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: conf.c,v 1.42 2023/07/22 10:11:19 jsg Exp $ */
+/* $OpenBSD: conf.c,v 1.43 2024/04/25 18:31:49 kn Exp $ */
/*
* Copyright (c) 1996 Michael Shalayeff
@@ -40,7 +40,7 @@
#include "efidev.h"
#include "efipxe.h"
-const char version[] = "3.65";
+const char version[] = "3.66";
#ifdef EFI_DEBUG
int debug = 0;
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 */
diff --git a/sys/arch/amd64/stand/efiboot/efiboot.h b/sys/arch/amd64/stand/efiboot/efiboot.h
index 725aebcccbd..8fdc5beb08d 100644
--- a/sys/arch/amd64/stand/efiboot/efiboot.h
+++ b/sys/arch/amd64/stand/efiboot/efiboot.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: efiboot.h,v 1.5 2022/07/11 19:45:02 kettenis Exp $ */
+/* $OpenBSD: efiboot.h,v 1.6 2024/04/25 18:31:49 kn Exp $ */
/*
* Copyright (c) 2015 YASUOKA Masahiko <yasuoka@yasuoka.net>
@@ -37,6 +37,9 @@ void efi_makebootargs(void);
void efi_setconsdev(void);
int Xpoweroff_efi(void);
+#ifdef IDLE_POWEROFF
+int Xidle_efi(void);
+#endif
extern void (*run_i386)(u_long, u_long, int, int, int, int, int, int, int, int)
__attribute__ ((noreturn));