summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Janssen <medhefgo@web.de>2022-01-16 15:57:38 +0100
committerLuca Boccassi <luca.boccassi@gmail.com>2022-01-17 00:05:35 +0000
commitcc25bedb2964e81cab7f02c87b70554dc0d3b24e (patch)
tree5f455714609a853422097f3935b28958797589f0
parent6eed65d455e9e76b020acbd858c20eafa43cebf8 (diff)
downloadsystemd-cc25bedb2964e81cab7f02c87b70554dc0d3b24e.tar.gz
boot: Beep n times for n-th entry
-rw-r--r--man/loader.conf.xml4
-rw-r--r--src/boot/efi/boot.c9
-rw-r--r--src/boot/efi/util.c26
-rw-r--r--src/boot/efi/util.h4
4 files changed, 25 insertions, 18 deletions
diff --git a/man/loader.conf.xml b/man/loader.conf.xml
index 844bd631fc..caff44aa1e 100644
--- a/man/loader.conf.xml
+++ b/man/loader.conf.xml
@@ -199,8 +199,8 @@
<varlistentry>
<term>beep</term>
- <listitem><para>Beep once as soon as the boot menu is shown (default disabled). Currently,
- only x86 is supported, where it uses the PC speaker.</para></listitem>
+ <listitem><para>Beep n times when the n-th entry in the boot menu is shown (default disabled).
+ Currently, only x86 is supported, where it uses the PC speaker.</para></listitem>
</varlistentry>
<varlistentry>
diff --git a/src/boot/efi/boot.c b/src/boot/efi/boot.c
index a128b38b9c..f49bd9e5f8 100644
--- a/src/boot/efi/boot.c
+++ b/src/boot/efi/boot.c
@@ -590,7 +590,7 @@ static BOOLEAN menu_run(
_cleanup_freepool_ CHAR16 *clearline = NULL, *status = NULL;
UINT32 timeout_efivar_saved = config->timeout_sec_efivar;
UINT32 timeout_remain = config->timeout_sec == TIMEOUT_MENU_FORCE ? 0 : config->timeout_sec;
- BOOLEAN exit = FALSE, run = TRUE, firmware_setup = FALSE, do_beep = config->beep;
+ BOOLEAN exit = FALSE, run = TRUE, firmware_setup = FALSE;
INT64 console_mode_initial = ST->ConOut->Mode->Mode, console_mode_efivar_saved = config->console_mode_efivar;
UINTN default_efivar_saved = config->idx_default_efivar;
@@ -727,10 +727,9 @@ static BOOLEAN menu_run(
ST->ConOut->OutputString(ST->ConOut, clearline + 1 + x + len);
}
- if (do_beep) {
- beep();
- do_beep = FALSE;
- }
+ /* Beep several times so that the selected entry can be distinguished. */
+ if (config->beep)
+ beep(idx_highlight + 1);
err = console_key_read(&key, timeout_remain > 0 ? 1000 * 1000 : UINT64_MAX);
if (err == EFI_TIMEOUT) {
diff --git a/src/boot/efi/util.c b/src/boot/efi/util.c
index 42c28badbf..e023b97d2f 100644
--- a/src/boot/efi/util.c
+++ b/src/boot/efi/util.c
@@ -769,10 +769,11 @@ static inline void outb(UINT16 port, UINT8 value) {
asm volatile("outb %0, %1" : : "a"(value), "Nd"(port));
}
-void beep(void) {
+void beep(UINTN beep_count) {
enum {
PITCH = 500,
- DURATION_USEC = 100 * 1000,
+ BEEP_DURATION_USEC = 100 * 1000,
+ WAIT_DURATION_USEC = 400 * 1000,
PIT_FREQUENCY = 0x1234dd,
SPEAKER_CONTROL_PORT = 0x61,
@@ -788,15 +789,22 @@ void beep(void) {
outb(TIMER_CONTROL2_PORT, counter & 0xFF);
outb(TIMER_CONTROL2_PORT, (counter >> 8) & 0xFF);
- /* Turn speaker on. */
UINT8 value = inb(SPEAKER_CONTROL_PORT);
- value |= SPEAKER_ON_MASK;
- outb(SPEAKER_CONTROL_PORT, value);
- BS->Stall(DURATION_USEC);
+ while (beep_count > 0) {
+ /* Turn speaker on. */
+ value |= SPEAKER_ON_MASK;
+ outb(SPEAKER_CONTROL_PORT, value);
- /* Turn speaker off. */
- value &= ~SPEAKER_ON_MASK;
- outb(SPEAKER_CONTROL_PORT, value);
+ BS->Stall(BEEP_DURATION_USEC);
+
+ /* Turn speaker off. */
+ value &= ~SPEAKER_ON_MASK;
+ outb(SPEAKER_CONTROL_PORT, value);
+
+ beep_count--;
+ if (beep_count > 0)
+ BS->Stall(WAIT_DURATION_USEC);
+ }
}
#endif
diff --git a/src/boot/efi/util.h b/src/boot/efi/util.h
index 8cee20885e..b60814b491 100644
--- a/src/boot/efi/util.h
+++ b/src/boot/efi/util.h
@@ -171,7 +171,7 @@ extern UINT8 _text, _data;
#endif
#if defined(__i386__) || defined(__x86_64__)
-void beep(void);
+void beep(UINTN beep_count);
#else
-static inline void beep(void) {}
+static inline void beep(UINTN beep_count) {}
#endif