blob: c576320b0b898cd213261b27fcfb2c5a5f2248b1 [file] [log] [blame]
Kevin O'Connore0113c92008-04-05 15:51:12 -04001// Menu presented during final phase of "post".
2//
3// Copyright (C) 2008 Kevin O'Connor <kevin@koconnor.net>
4// Copyright (C) 2002 MandrakeSoft S.A.
5//
6// This file may be distributed under the terms of the GNU GPLv3 license.
7
8#include "biosvar.h" // GET_EBDA
Kevin O'Connorbc2aecd2008-11-28 16:40:06 -05009#include "util.h" // mdelay
Kevin O'Connor9521e262008-07-04 13:04:29 -040010#include "bregs.h" // struct bregs
Kevin O'Connore0113c92008-04-05 15:51:12 -040011
12static u8
13check_for_keystroke()
14{
15 struct bregs br;
16 memset(&br, 0, sizeof(br));
17 br.ah = 1;
18 call16_int(0x16, &br);
19 return !(br.flags & F_ZF);
20}
21
22static u8
23get_keystroke()
24{
25 struct bregs br;
26 memset(&br, 0, sizeof(br));
27 call16_int(0x16, &br);
28 return br.ah;
29}
30
31static void
Kevin O'Connorbc2aecd2008-11-28 16:40:06 -050032mdelay_and_check_for_keystroke(u32 msec, int count)
Kevin O'Connore0113c92008-04-05 15:51:12 -040033{
34 int i;
35 for (i = 1; i <= count; i++) {
Kevin O'Connorbc2aecd2008-11-28 16:40:06 -050036 mdelay(msec);
Kevin O'Connore0113c92008-04-05 15:51:12 -040037 if (check_for_keystroke())
38 break;
39 }
40}
41
42void
43interactive_bootmenu()
44{
Kevin O'Connor40967022008-07-21 22:23:05 -040045 if (! CONFIG_BOOTMENU)
46 return;
47
Kevin O'Connore0113c92008-04-05 15:51:12 -040048 while (check_for_keystroke())
49 get_keystroke();
50
51 printf("Press F12 for boot menu.\n\n");
52
Kevin O'Connorbc2aecd2008-11-28 16:40:06 -050053 mdelay_and_check_for_keystroke(500, 5);
Kevin O'Connore0113c92008-04-05 15:51:12 -040054 if (! check_for_keystroke())
55 return;
56 u8 scan_code = get_keystroke();
Kevin O'Connor7c774172008-10-25 14:38:31 -040057 if (scan_code != 0x86)
Kevin O'Connore0113c92008-04-05 15:51:12 -040058 /* not F12 */
59 return;
60
61 while (check_for_keystroke())
62 get_keystroke();
63
64 printf("Select boot device:\n\n");
65
66 int count = GET_EBDA(ipl.count);
67 int i;
68 for (i = 0; i < count; i++) {
69 printf("%d. ", i+1);
70 printf_bootdev(i);
71 printf("\n");
72 }
73
74 for (;;) {
75 scan_code = get_keystroke();
76 if (scan_code == 0x01 || scan_code == 0x58)
77 /* ESC or F12 */
78 break;
79 if (scan_code <= count + 1) {
Kevin O'Connorabc75972008-05-18 00:20:53 -040080 // Add user choice to the boot order.
81 u16 choice = scan_code - 1;
82 u32 bootorder = GET_EBDA(ipl.bootorder);
83 SET_EBDA(ipl.bootorder, (bootorder << 4) | choice);
Kevin O'Connore0113c92008-04-05 15:51:12 -040084 break;
85 }
86 }
87 printf("\n");
88}