summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/arch/i386/prefix/romprefix.S151
1 files changed, 107 insertions, 44 deletions
diff --git a/src/arch/i386/prefix/romprefix.S b/src/arch/i386/prefix/romprefix.S
index f9b9e169..fbc8f00b 100644
--- a/src/arch/i386/prefix/romprefix.S
+++ b/src/arch/i386/prefix/romprefix.S
@@ -145,8 +145,6 @@ init:
cld
pushw %cs
popw %ds
- pushw $0x40
- popw %fs
/* Shuffle some registers around. We need %di available for
* the print_xxx functions, and in a register that's
@@ -317,46 +315,17 @@ no_pmm:
movw $init_message_prompt, %si
xorw %di, %di
call print_message
- /* Empty the keyboard buffer before waiting for input */
-empty_keyboard_buffer:
- movb $0x01, %ah
- int $0x16
- jz 1f
- xorw %ax, %ax
- int $0x16
- jmp empty_keyboard_buffer
-1: /* Wait for up to 3s for a key press */
- movw $(18 * 3), %cx /* Approx 3s worth of timer ticks */
-wait_for_key:
- decw %cx
- jz no_key_pressed
- /* Wait for timer tick to be updated */
- movl %fs:(0x6c), %eax
-1: pushf
- sti
- hlt
- popf
- cmpl %fs:(0x6c), %eax
- je 1b
- /* Check to see if a key was pressed */
- movb $0x01, %ah
- int $0x16
- jz wait_for_key
- /* Check to see if key was Ctrl-B */
- cmpb $0x02, %al
- je 1f
- /* Key was not Ctrl-B: remove from buffer and stop waiting */
- xorw %ax, %ax
- int $0x16
- jmp no_key_pressed
-1: /* Key was Ctrl-B: leave in keyboard buffer and invoke gPXE.
- * The keypress will be picked up by the initial shell
- * prompt, and we will drop into a shell.
+ /* Wait for Ctrl-B */
+ movw $0xff02, %bx
+ call wait_for_key
+ jnz 1f
+ /* Ctrl-B was pressed: invoke gPXE. The keypress will be
+ * picked up by the initial shell prompt, and we will drop
+ * into a shell.
*/
pushw %cs
call exec
-no_key_pressed:
-
+1:
/* Print blank lines to terminate messages */
movw $init_message_end, %si
xorw %di, %di
@@ -436,24 +405,54 @@ bev_entry:
/* INT19 entry point
*
* Called via the hooked INT 19 if we detected a non-PnP BIOS. We
- * attempt to return via the original INT 19 vector (if we were able to
- * store it).
+ * attempt to return via the original INT 19 vector (if we were able
+ * to store it).
*/
int19_entry:
pushw %cs
+ popw %ds
+ /* Prompt user to press B to boot */
+ movw $int19_message_prompt, %si
+ xorw %di, %di
+ call print_message
+ movw $prodstr, %si
+ call print_message
+ movw $int19_message_dots, %si
+ call print_message
+ movw $0xdf42, %bx
+ call wait_for_key
+ jnz 1f
+ /* Leave keypress in buffer and start gPXE. The keypress will
+ * cause the usual initial Ctrl-B prompt to be skipped.
+ */
+ pushw %cs
call exec
+1: /* Print blank lines to terminate messages */
+ movw $int19_message_end, %si
+ xorw %di, %di
+ call print_message
+ /* Try to call original INT 19 vector */
movl %cs:orig_int19, %eax
testl %eax, %eax
- je 1f
- /* Chain to original INT 19 vector */
+ je 2f
ljmp *%cs:orig_int19
-1: /* No chained vector: issue INT 18 as a last resort */
+2: /* No chained vector: issue INT 18 as a last resort */
int $0x18
.size int19_entry, . - int19_entry
orig_int19:
.long 0
.size orig_int19, . - orig_int19
+int19_message_prompt:
+ .asciz "Press B to boot from "
+ .size int19_message_prompt, . - int19_message_prompt
+int19_message_dots:
+ .asciz "..."
+ .size int19_message_dots, . - int19_message_dots
+int19_message_end:
+ .asciz "\n\n\n"
+ .size int19_message_end, . - int19_message_end
+
/* Execute as a boot device
*
*/
@@ -560,3 +559,67 @@ undiloader:
popl %esi
lret
.size undiloader, . - undiloader
+
+/* Wait for key press specified by %bl (masked by %bh)
+ *
+ * Used by init and INT19 code when prompting user. If the specified
+ * key is pressed, it is left in the keyboard buffer.
+ *
+ * Returns with ZF set iff specified key is pressed.
+ */
+wait_for_key:
+ /* Preserve registers */
+ pushw %cx
+ pushw %ax
+1: /* Empty the keyboard buffer before waiting for input */
+ movb $0x01, %ah
+ int $0x16
+ jz 2f
+ xorw %ax, %ax
+ int $0x16
+ jmp 1b
+2: /* Wait for up to 5s for a key press */
+ movw $(18 * 5), %cx /* Approx 5s worth of timer ticks */
+3: decw %cx
+ js 99f /* Exit with ZF clear */
+ /* Wait for timer tick to be updated */
+ call wait_for_tick
+ /* Check to see if a key was pressed */
+ movb $0x01, %ah
+ int $0x16
+ jz 3b
+ /* Check to see if key was the specified key */
+ andb %bh, %al
+ cmpb %al, %bl
+ je 99f /* Exit with ZF set */
+ /* Not the specified key: remove from buffer and stop waiting */
+ pushfw
+ xorw %ax, %ax
+ int $0x16
+ popfw /* Exit with ZF clear */
+99: /* Restore registers and return */
+ popw %ax
+ popw %cx
+ ret
+ .size wait_for_key, . - wait_for_key
+
+/* Wait for timer tick
+ *
+ * Used by wait_for_key
+ */
+wait_for_tick:
+ pushl %eax
+ pushw %fs
+ movw $0x40, %ax
+ movw %ax, %fs
+ movl %fs:(0x6c), %eax
+1: pushf
+ sti
+ hlt
+ popf
+ cmpl %fs:(0x6c), %eax
+ je 1b
+ popw %fs
+ popl %eax
+ ret
+ .size wait_for_tick, . - wait_for_tick