by using the <keycap>f</keycap> key.</para></listitem>
</varlistentry>
+ <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>
+ </varlistentry>
+
<varlistentry>
<term>reboot-for-bitlocker</term>
BOOLEAN force_menu;
BOOLEAN use_saved_entry;
BOOLEAN use_saved_entry_efivar;
+ BOOLEAN beep;
INT64 console_mode;
INT64 console_mode_efivar;
RandomSeedMode random_seed_mode;
ps_bool(L" editor: %s\n", config->editor);
ps_bool(L" auto-entries: %s\n", config->auto_entries);
ps_bool(L" auto-firmware: %s\n", config->auto_firmware);
+ ps_bool(L" beep: %s\n", config->beep);
ps_bool(L" reboot-for-bitlocker: %s\n", config->reboot_for_bitlocker);
ps_string(L" random-seed-mode: %s\n", random_seed_modes_table[config->random_seed_mode]);
_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;
+ BOOLEAN exit = FALSE, run = TRUE, firmware_setup = FALSE, do_beep = config->beep;
INT64 console_mode_initial = ST->ConOut->Mode->Mode, console_mode_efivar_saved = config->console_mode_efivar;
UINTN default_efivar_saved = config->idx_default_efivar;
ST->ConOut->OutputString(ST->ConOut, clearline + 1 + x + len);
}
+ if (do_beep) {
+ beep();
+ do_beep = FALSE;
+ }
+
err = console_key_read(&key, timeout_remain > 0 ? 1000 * 1000 : UINT64_MAX);
if (err == EFI_TIMEOUT) {
timeout_remain--;
continue;
}
+ if (strcmpa((CHAR8 *)"beep", key) == 0) {
+ err = parse_boolean(value, &config->beep);
+ if (EFI_ERROR(err))
+ log_error_stall(L"Error parsing 'beep' config option: %a", value);
+ }
+
if (strcmpa((CHAR8 *)"reboot-for-bitlocker", key) == 0) {
err = parse_boolean(value, &config->reboot_for_bitlocker);
if (EFI_ERROR(err))
#endif
}
#endif
+
+#if defined(__i386__) || defined(__x86_64__)
+static inline UINT8 inb(UINT16 port) {
+ UINT8 value;
+ asm volatile("inb %1, %0" : "=a"(value) : "Nd"(port));
+ return value;
+}
+
+static inline void outb(UINT16 port, UINT8 value) {
+ asm volatile("outb %0, %1" : : "a"(value), "Nd"(port));
+}
+
+void beep(void) {
+ enum {
+ PITCH = 500,
+ DURATION_USEC = 100 * 1000,
+
+ PIT_FREQUENCY = 0x1234dd,
+ SPEAKER_CONTROL_PORT = 0x61,
+ SPEAKER_ON_MASK = 0x03,
+ TIMER_PORT_MAGIC = 0xB6,
+ TIMER_CONTROL_PORT = 0x43,
+ TIMER_CONTROL2_PORT = 0x42,
+ };
+
+ /* Set frequency. */
+ UINT32 counter = PIT_FREQUENCY / PITCH;
+ outb(TIMER_CONTROL_PORT, TIMER_PORT_MAGIC);
+ 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);
+
+ /* Turn speaker off. */
+ value &= ~SPEAKER_ON_MASK;
+ outb(SPEAKER_CONTROL_PORT, value);
+}
+#endif
#else
# define debug_hook(identity)
#endif
+
+#if defined(__i386__) || defined(__x86_64__)
+void beep(void);
+#else
+static inline void beep(void) {}
+#endif