Signed-off-by: Gerd Hoffmann kraxel@redhat.com --- src/util.h | 2 +- src/boot.c | 16 +++++++++------- src/tcgbios.c | 8 ++++---- 3 files changed, 14 insertions(+), 12 deletions(-)
diff --git a/src/util.h b/src/util.h index 9c06850353a4..fdb542c42964 100644 --- a/src/util.h +++ b/src/util.h @@ -36,7 +36,7 @@ int bootprio_find_pci_rom(struct pci_device *pci, int instance); int bootprio_find_named_rom(const char *name, int instance); struct usbdevice_s; int bootprio_find_usb(struct usbdevice_s *usbdev, int lun); -int get_keystroke(int msec); +int get_keystroke(int msec, u8 *ascii);
// bootsplash.c void enable_vga_console(void); diff --git a/src/boot.c b/src/boot.c index 9f82f3ca0c3e..47b039fbad09 100644 --- a/src/boot.c +++ b/src/boot.c @@ -435,23 +435,25 @@ check_for_keystroke(void)
// Return a keystroke - waiting forever if necessary. static int -get_raw_keystroke(void) +get_raw_keystroke(u8 *ascii) { struct bregs br; memset(&br, 0, sizeof(br)); br.flags = F_IF; call16_int(0x16, &br); + if (ascii) + *ascii = br.al; return br.ah; }
// Read a keystroke - waiting up to 'msec' milliseconds. int -get_keystroke(int msec) +get_keystroke(int msec, u8 *ascii) { u32 end = irqtimer_calc(msec); for (;;) { if (check_for_keystroke()) - return get_raw_keystroke(); + return get_raw_keystroke(ascii); if (irqtimer_check(end)) return -1; yield_toirq(); @@ -474,7 +476,7 @@ interactive_bootmenu(void) if (! CONFIG_BOOTMENU || !romfile_loadint("etc/show-boot-menu", 1)) return;
- while (get_keystroke(0) >= 0) + while (get_keystroke(0, NULL) >= 0) ;
char *bootmsg = romfile_loadfile("etc/boot-menu-message", NULL); @@ -484,12 +486,12 @@ interactive_bootmenu(void)
u32 menutime = romfile_loadint("etc/boot-menu-wait", DEFAULT_BOOTMENU_WAIT); enable_bootsplash(); - int scan_code = get_keystroke(menutime); + int scan_code = get_keystroke(menutime, NULL); disable_bootsplash(); if (scan_code != menukey) return;
- while (get_keystroke(0) >= 0) + while (get_keystroke(0, NULL) >= 0) ;
printf("Select boot device:\n\n"); @@ -514,7 +516,7 @@ interactive_bootmenu(void) // multiple times and immediately booting the primary boot device. int esc_accepted_time = irqtimer_calc(menukey == 1 ? 1500 : 0); for (;;) { - scan_code = get_keystroke(1000); + scan_code = get_keystroke(1000, NULL); if (scan_code == 1 && !irqtimer_check(esc_accepted_time)) continue; if (tpm_can_show_menu() && scan_code == 20 /* t */) { diff --git a/src/tcgbios.c b/src/tcgbios.c index 2e503f933524..a17239db21c9 100644 --- a/src/tcgbios.c +++ b/src/tcgbios.c @@ -2068,7 +2068,7 @@ tpm12_menu(void) waitkey = 1;
while (waitkey) { - while ((scancode = get_keystroke(1000)) == ~0) + while ((scancode = get_keystroke(1000, NULL)) == ~0) ;
switch (scancode) { @@ -2156,7 +2156,7 @@ tpm20_menu_change_active_pcrbanks(void) u8 flagnum; int show = 0; while (!show) { - int scancode = get_keystroke(1000); + int scancode = get_keystroke(1000, NULL);
switch (scancode) { case ~0: @@ -2197,7 +2197,7 @@ tpm20_menu(void)
msgCode = TPM_PPI_OP_NOOP;
- while ((scan_code = get_keystroke(1000)) == ~0) + while ((scan_code = get_keystroke(1000, NULL)) == ~0) ;
switch (scan_code) { @@ -2225,7 +2225,7 @@ tpm_menu(void) if (!CONFIG_TCGBIOS) return;
- while (get_keystroke(0) >= 0) + while (get_keystroke(0, NULL) >= 0) ; wait_threads();
10th and following entries can be selected using letters.
Signed-off-by: Gerd Hoffmann kraxel@redhat.com --- src/boot.c | 56 +++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 39 insertions(+), 17 deletions(-)
diff --git a/src/boot.c b/src/boot.c index 47b039fbad09..e87a0fe6351b 100644 --- a/src/boot.c +++ b/src/boot.c @@ -467,6 +467,14 @@ get_keystroke(int msec, u8 *ascii)
#define DEFAULT_BOOTMENU_WAIT 2500
+static const char menuchars[] = { + '1', '2', '3', '4', '5', '6', '7', '8', '9', + 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', + 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', + 's', /* skip t (tpm menu) */ + 'u', 'v', 'w', 'x', 'y', 'z' +}; + // Show IPL option menu. void interactive_bootmenu(void) @@ -499,12 +507,15 @@ interactive_bootmenu(void)
// Show menu items int maxmenu = 0; - struct bootentry_s *pos; + struct bootentry_s *pos, *boot = NULL; hlist_for_each_entry(pos, &BootList, node) { char desc[77]; - maxmenu++; - printf("%d. %s\n", maxmenu + if (maxmenu >= ARRAY_SIZE(menuchars)) { + break; + } + printf("%c. %s\n", menuchars[maxmenu] , strtcpy(desc, pos->description, ARRAY_SIZE(desc))); + maxmenu++; } if (tpm_can_show_menu()) { printf("\nt. TPM Configuration\n"); @@ -514,32 +525,43 @@ interactive_bootmenu(void) // 1.5 seconds have passed. Otherwise users (trained by years of // repeatedly hitting keys to enter the BIOS) will end up hitting ESC // multiple times and immediately booting the primary boot device. + u8 key_ascii; int esc_accepted_time = irqtimer_calc(menukey == 1 ? 1500 : 0); for (;;) { - scan_code = get_keystroke(1000, NULL); + scan_code = get_keystroke(1000, &key_ascii); if (scan_code == 1 && !irqtimer_check(esc_accepted_time)) continue; - if (tpm_can_show_menu() && scan_code == 20 /* t */) { + if (scan_code < 0) // timeout + continue; + if (tpm_can_show_menu() && key_ascii == 't') { printf("\n"); tpm_menu(); } - if (scan_code >= 1 && scan_code <= maxmenu+1) + if (scan_code == 1) { + // ESC + printf("\n"); + return; + } + + maxmenu = 0; + hlist_for_each_entry(pos, &BootList, node) { + if (maxmenu >= ARRAY_SIZE(menuchars)) + break; + if (key_ascii == menuchars[maxmenu]) { + boot = pos; + break; + } + maxmenu++; + } + if (boot) break; } printf("\n"); - if (scan_code == 0x01) - // ESC - return;
// Find entry and make top priority. - int choice = scan_code - 1; - hlist_for_each_entry(pos, &BootList, node) { - if (! --choice) - break; - } - hlist_del(&pos->node); - pos->priority = 0; - hlist_add_head(&pos->node, &BootList); + hlist_del(&boot->node); + boot->priority = 0; + hlist_add_head(&boot->node, &BootList); }
// BEV (Boot Execution Vector) list
On Fri, Apr 12, 2019 at 08:30:09AM +0200, Gerd Hoffmann wrote:
Signed-off-by: Gerd Hoffmann kraxel@redhat.com
src/util.h | 2 +- src/boot.c | 16 +++++++++------- src/tcgbios.c | 8 ++++---- 3 files changed, 14 insertions(+), 12 deletions(-)
diff --git a/src/util.h b/src/util.h index 9c06850353a4..fdb542c42964 100644 --- a/src/util.h +++ b/src/util.h @@ -36,7 +36,7 @@ int bootprio_find_pci_rom(struct pci_device *pci, int instance); int bootprio_find_named_rom(const char *name, int instance); struct usbdevice_s; int bootprio_find_usb(struct usbdevice_s *usbdev, int lun); -int get_keystroke(int msec); +int get_keystroke(int msec, u8 *ascii);
// bootsplash.c void enable_vga_console(void); diff --git a/src/boot.c b/src/boot.c index 9f82f3ca0c3e..47b039fbad09 100644 --- a/src/boot.c +++ b/src/boot.c @@ -435,23 +435,25 @@ check_for_keystroke(void)
// Return a keystroke - waiting forever if necessary. static int -get_raw_keystroke(void) +get_raw_keystroke(u8 *ascii) { struct bregs br; memset(&br, 0, sizeof(br)); br.flags = F_IF; call16_int(0x16, &br);
- if (ascii)
return br.ah;*ascii = br.al;
}
FYI, it may be simpler to return br.ax which is the "keycode". Callers could then convert the "keycode" to either a "scancode" or an ascii code.
-Kevin
// Read a keystroke - waiting up to 'msec' milliseconds. int -get_keystroke(int msec) +get_keystroke(int msec, u8 *ascii) { u32 end = irqtimer_calc(msec); for (;;) { if (check_for_keystroke())
return get_raw_keystroke();
return get_raw_keystroke(ascii); if (irqtimer_check(end)) return -1; yield_toirq();
@@ -474,7 +476,7 @@ interactive_bootmenu(void) if (! CONFIG_BOOTMENU || !romfile_loadint("etc/show-boot-menu", 1)) return;
- while (get_keystroke(0) >= 0)
while (get_keystroke(0, NULL) >= 0) ;
char *bootmsg = romfile_loadfile("etc/boot-menu-message", NULL);
@@ -484,12 +486,12 @@ interactive_bootmenu(void)
u32 menutime = romfile_loadint("etc/boot-menu-wait", DEFAULT_BOOTMENU_WAIT); enable_bootsplash();
- int scan_code = get_keystroke(menutime);
- int scan_code = get_keystroke(menutime, NULL); disable_bootsplash(); if (scan_code != menukey) return;
- while (get_keystroke(0) >= 0)
while (get_keystroke(0, NULL) >= 0) ;
printf("Select boot device:\n\n");
@@ -514,7 +516,7 @@ interactive_bootmenu(void) // multiple times and immediately booting the primary boot device. int esc_accepted_time = irqtimer_calc(menukey == 1 ? 1500 : 0); for (;;) {
scan_code = get_keystroke(1000);
scan_code = get_keystroke(1000, NULL); if (scan_code == 1 && !irqtimer_check(esc_accepted_time)) continue; if (tpm_can_show_menu() && scan_code == 20 /* t */) {
diff --git a/src/tcgbios.c b/src/tcgbios.c index 2e503f933524..a17239db21c9 100644 --- a/src/tcgbios.c +++ b/src/tcgbios.c @@ -2068,7 +2068,7 @@ tpm12_menu(void) waitkey = 1;
while (waitkey) {
while ((scancode = get_keystroke(1000)) == ~0)
while ((scancode = get_keystroke(1000, NULL)) == ~0) ; switch (scancode) {
@@ -2156,7 +2156,7 @@ tpm20_menu_change_active_pcrbanks(void) u8 flagnum; int show = 0; while (!show) {
int scancode = get_keystroke(1000);
int scancode = get_keystroke(1000, NULL); switch (scancode) { case ~0:
@@ -2197,7 +2197,7 @@ tpm20_menu(void)
msgCode = TPM_PPI_OP_NOOP;
while ((scan_code = get_keystroke(1000)) == ~0)
while ((scan_code = get_keystroke(1000, NULL)) == ~0) ; switch (scan_code) {
@@ -2225,7 +2225,7 @@ tpm_menu(void) if (!CONFIG_TCGBIOS) return;
- while (get_keystroke(0) >= 0)
- while (get_keystroke(0, NULL) >= 0) ; wait_threads();
-- 2.18.1 _______________________________________________ SeaBIOS mailing list -- seabios@seabios.org To unsubscribe send an email to seabios-leave@seabios.org