diff --git a/ChangeLog b/ChangeLog index 6043b2694..52cb52ab5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,41 @@ +2000-08-26 OKUJI Yoshinori + + Don't save/restore fragile registers unnecessarily. + + * stage2/asm.S [!STAGE1_5] (track_int13): Don't save/restore + %ecx, %edx, or %eax. + [!STAGE1_5] (set_int13_handler): Likewise. + (biosdisk_int13_extensions): Likewise. + (biosdisk_standard): Likewise. + (check_int13_extensions): Likewise. + (get_diskinfo_int13_extensions): Likewise. + (get_diskinfo_standard): Likewise. + (get_diskinfo_floppy): Likewise. + [!STAGE1_5] (get_eisamemsize): Likewise. + [!STAGE1_5] (get_mmap_entry): Likewise. + [!STAGE1_5] (console_cls): Likewise. + [!STAGE1_5] (nocursor): Likewise. + [!STAGE1_5] (console_getxy): Likewise. + [!STAGE1_5] (console_gotoxy): Likewise. + [!STAGE1_5] (set_attrib): Likewise. + [!STAGE1_5] (getrtsecs): Likewise. + [!STAGE1_5] (currticks): Likewise, and don't zero %eax + explicitly, since prot_to_real does that. + +2000-08-25 OKUJI Yoshinori + + * stage2/char_io.c [!STAGE1_5] (translate_keycode): New + function. The serial part is stolen from the patch by Christoph + Plattner. + [!STAGE1_5] (get_cmdline): Call translate_keycode instead of + translating special key codes into ASCII characters by itself. + * stage2/stage2.c (run_menu): Wrap getkey with the macro + ASCII_CHAR, when checking if ESC is pressed. + Call translate_keycode as well as getkey, unless checkkey + returns -1. So don't check if C is KEY_DOWN or KEY_UP. And don't + use the macro ASCII_CHAR for C explicitly. + * stage2/shared.h (translate_keycode): Declared. + 2000-08-24 OKUJI Yoshinori * stage2/builtins.c [GRUB_UTIL]: Include stdio.h before diff --git a/grub/asmstub.c b/grub/asmstub.c index 79672fc3f..e5f8fa5d8 100644 --- a/grub/asmstub.c +++ b/grub/asmstub.c @@ -432,6 +432,31 @@ getrtsecs (void) return time (0); } +int +currticks (void) +{ + struct timeval tv; + long csecs; + int ticks_per_csec, ticks_per_usec; + + /* Note: 18.2 ticks/sec. */ + + /* Get current time. */ + gettimeofday (&tv, 0); + + /* Compute centiseconds. */ + csecs = tv.tv_sec / 10; + + /* Ticks per centisecond. */ + ticks_per_csec = csecs * 182; + + /* Ticks per microsecond. */ + ticks_per_usec = (((tv.tv_sec - csecs * 10) * 1000000 + tv.tv_usec) + * 182 / 10000000); + + /* Sum them. */ + return ticks_per_csec + ticks_per_usec; +} /* low-level character I/O */ void diff --git a/stage2/asm.S b/stage2/asm.S index 67767a561..c1321bb04 100644 --- a/stage2/asm.S +++ b/stage2/asm.S @@ -18,6 +18,23 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +/* + * Note: These functions defined in this file may be called from C. + * Be careful of that you must not modify some registers. Quote + * from gcc-2.95.2/gcc/config/i386/i386.h: + + 1 for registers not available across function calls. + These must include the FIXED_REGISTERS and also any + registers that can be used without being saved. + The latter must include the registers where values are returned + and the register where structure-value addresses are passed. + Aside from that, you can include as many other registers as you like. + + ax,dx,cx,bx,si,di,bp,sp,st,st1,st2,st3,st4,st5,st6,st7,arg +{ 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 } + */ + #define ASM_FILE #include "shared.h" @@ -258,7 +275,6 @@ ENTRY(track_int13) pushl %ebp movl %esp, %ebp - pushl %edx pushl %ebx pushl %edi @@ -310,7 +326,6 @@ ENTRY(track_int13) popl %edi popl %ebx - popl %edx popl %ebp ret @@ -605,7 +620,6 @@ ENTRY(set_int13_handler) pushl %ebp movl %esp, %ebp - pushl %ecx pushl %edi pushl %esi @@ -649,7 +663,6 @@ ENTRY(set_int13_handler) popl %esi popl %edi - popl %ecx popl %ebp ret @@ -938,8 +951,6 @@ ENTRY(biosdisk_int13_extensions) pushl %ebp movl %esp, %ebp - pushl %ecx - pushl %edx pushl %esi /* compute the address of disk_address_packet */ @@ -971,8 +982,6 @@ ENTRY(biosdisk_int13_extensions) movb %dl, %al /* return value in %eax */ popl %esi - popl %edx - popl %ecx popl %ebp ret @@ -991,8 +1000,6 @@ ENTRY(biosdisk_standard) movl %esp, %ebp pushl %ebx - pushl %ecx - pushl %edx pushl %edi pushl %esi @@ -1044,8 +1051,6 @@ ENTRY(biosdisk_standard) popl %esi popl %edi - popl %edx - popl %ecx popl %ebx popl %ebp @@ -1064,8 +1069,6 @@ ENTRY(check_int13_extensions) movl %esp, %ebp pushl %ebx - pushl %ecx - pushl %edx /* drive */ movb 0x8(%ebp), %dl @@ -1100,8 +1103,6 @@ ENTRY(check_int13_extensions) movb %bl, %al /* return value in %eax */ - popl %edx - popl %ecx popl %ebx popl %ebp @@ -1120,7 +1121,6 @@ ENTRY(get_diskinfo_int13_extensions) movl %esp, %ebp pushl %ebx - pushl %edx pushl %esi /* compute the address of drive parameters */ @@ -1149,7 +1149,6 @@ ENTRY(get_diskinfo_int13_extensions) movb %bl, %al /* return value in %eax */ popl %esi - popl %edx popl %ebx popl %ebp @@ -1169,8 +1168,6 @@ ENTRY(get_diskinfo_standard) movl %esp, %ebp pushl %ebx - pushl %ecx - pushl %edx pushl %edi /* drive */ @@ -1196,7 +1193,7 @@ ENTRY(get_diskinfo_standard) .code32 /* restore %ebp */ - leal 0x10(%esp), %ebp + leal 0x8(%esp), %ebp /* heads */ movb %dh, %al @@ -1224,8 +1221,6 @@ ENTRY(get_diskinfo_standard) movb %bl, %al /* return value in %eax */ popl %edi - popl %edx - popl %ecx popl %ebx popl %ebp @@ -1245,8 +1240,6 @@ ENTRY(get_diskinfo_floppy) movl %esp, %ebp pushl %ebx - pushl %ecx - pushl %edx pushl %esi /* drive */ @@ -1291,7 +1284,7 @@ probe_values: .code32 /* restore %ebp */ - leal 0x10(%esp), %ebp + leal 0x8(%esp), %ebp /* cylinders */ movl 0xc(%ebp), %eax @@ -1313,8 +1306,6 @@ probe_values: incl %eax /* %eax = 1 (non-zero) */ 3: popl %esi - popl %edx - popl %ecx popl %ebx popl %ebp @@ -1505,8 +1496,6 @@ xdone: ENTRY(get_eisamemsize) push %ebp push %ebx - push %ecx - push %edx call EXT_C(prot_to_real) /* enter real mode */ .code16 @@ -1527,8 +1516,6 @@ ENTRY(get_eisamemsize) movl %ebx, %eax xnoteisa: - pop %edx - pop %ecx pop %ebx pop %ebp ret @@ -1549,13 +1536,11 @@ xnoteisa: ENTRY(get_mmap_entry) push %ebp push %ebx - push %ecx - push %edx push %edi push %esi /* place address (+4) in ES:DI */ - movl 0x1c(%esp), %eax + movl 0x14(%esp), %eax addl $4, %eax movl %eax, %edi andl $0xf, %edi @@ -1563,7 +1548,7 @@ ENTRY(get_mmap_entry) movl %eax, %esi /* set continuation value */ - movl 0x20(%esp), %ebx + movl 0x18(%esp), %ebx /* set default maximum buffer size */ movl $0x14, %ecx @@ -1599,7 +1584,7 @@ xsmap: .code32 /* write length of buffer (zero if error) into "addr" */ - movl 0x1c(%esp), %eax + movl 0x14(%esp), %eax movl %ecx, (%eax) /* set return value to continuation */ @@ -1607,8 +1592,6 @@ xsmap: pop %esi pop %edi - pop %edx - pop %ecx pop %ebx pop %ebp ret @@ -1769,7 +1752,6 @@ ENTRY(multi_boot) ENTRY(console_cls) push %ebp - push %eax push %ebx /* save EBX */ call EXT_C(prot_to_real) @@ -1784,7 +1766,6 @@ ENTRY(console_cls) .code32 pop %ebx - pop %eax pop %ebp ret @@ -1799,9 +1780,7 @@ ENTRY(console_cls) ENTRY(nocursor) push %ebp - push %eax push %ebx /* save EBX */ - push %edx call EXT_C(prot_to_real) .code16 @@ -1813,9 +1792,7 @@ ENTRY(nocursor) DATA32 call EXT_C(real_to_prot) .code32 - pop %edx pop %ebx - pop %eax pop %ebp ret @@ -1835,8 +1812,6 @@ ENTRY(nocursor) ENTRY(console_getxy) push %ebp push %ebx /* save EBX */ - push %ecx /* save ECX */ - push %edx call EXT_C(prot_to_real) .code16 @@ -1851,8 +1826,6 @@ ENTRY(console_getxy) movb %dl, %ah movb %dh, %al - pop %edx - pop %ecx pop %ebx pop %ebp ret @@ -1870,12 +1843,10 @@ ENTRY(console_getxy) ENTRY(console_gotoxy) push %ebp - push %eax push %ebx /* save EBX */ - push %edx - movb 0x14(%esp), %dl /* %dl = x */ - movb 0x18(%esp), %dh /* %dh = y */ + movb 0xc(%esp), %dl /* %dl = x */ + movb 0x10(%esp), %dh /* %dh = y */ call EXT_C(prot_to_real) .code16 @@ -1887,9 +1858,7 @@ ENTRY(console_gotoxy) DATA32 call EXT_C(real_to_prot) .code32 - pop %edx pop %ebx - pop %eax pop %ebp ret @@ -1931,11 +1900,9 @@ ENTRY(console_gotoxy) ENTRY(set_attrib) push %ebp - push %eax push %ebx - push %ecx - movl 0x14(%esp), %ecx + movl 0xc(%esp), %ecx xorl %ebx, %ebx call EXT_C(prot_to_real) @@ -1951,9 +1918,7 @@ ENTRY(set_attrib) DATA32 call EXT_C(real_to_prot) .code32 - pop %ecx pop %ebx - pop %eax pop %ebp ret @@ -1978,8 +1943,6 @@ ENTRY(set_attrib) */ ENTRY(getrtsecs) push %ebp - push %ecx - push %edx call EXT_C(prot_to_real) /* enter real mode */ .code16 @@ -1996,8 +1959,6 @@ gottime: movb %dh, %al - pop %edx - pop %ecx pop %ebp ret @@ -2009,13 +1970,11 @@ gottime: */ ENTRY(currticks) pushl %ebp - pushl %ecx - pushl %edx call EXT_C(prot_to_real) /* enter real mode */ .code16 - xorl %eax, %eax + /* %ax is already zero */ int $0x1a DATA32 call EXT_C(real_to_prot) @@ -2025,8 +1984,6 @@ ENTRY(currticks) shll $16, %eax movw %dx, %ax - popl %edx - popl %ecx popl %ebp ret diff --git a/stage2/char_io.c b/stage2/char_io.c index c9e06a025..c239daf1d 100644 --- a/stage2/char_io.c +++ b/stage2/char_io.c @@ -337,36 +337,8 @@ get_cmdline (char *prompt, char *cmdline, int maxlen, while (ASCII_CHAR (c = getkey ()) != '\n' && ASCII_CHAR (c) != '\r') { - switch (c) - { - case KEY_LEFT: - c = 2; - break; - case KEY_RIGHT: - c = 6; - break; - case KEY_UP: - c = 16; - break; - case KEY_DOWN: - c = 14; - break; - case KEY_HOME: - c = 1; - break; - case KEY_END: - c = 5; - break; - case KEY_DC: - c = 4; - break; - case KEY_BACKSPACE: - c = 8; - break; - } - - c = ASCII_CHAR (c); - + c = translate_keycode (c); + /* If READLINE is non-zero, handle readline-like key bindings. */ if (readline) { @@ -618,6 +590,126 @@ get_cmdline (char *prompt, char *cmdline, int maxlen, return 0; } + +/* Translate a special key to a common ascii code. */ +int +translate_keycode (int c) +{ +# ifdef SUPPORT_SERIAL + if (terminal & TERMINAL_SERIAL) + { + /* In a serial terminal, things are complicated, because several + key codes start from the character ESC, while we want to accept + ESC itself. */ + if (c == '\e') + { + int start; + + /* Get current time. */ + start = currticks (); + + while (checkkey () == -1) + { + /* Wait for a next character, at least for 0.1 sec + (18.2 ticks/sec). */ + int now; + + now = currticks (); + if (now - start >= 2) + return c; + } + + c = getkey (); + if (c == '[') + { + int c1, c2; + + /* To filter illegal states. */ + c = 0; + c1 = getkey (); + switch (c1) + { + case 'A': /* KEY_UP */ + c = 16; + break; + case 'B': /* KEY_DOWN */ + c = 14; + break; + case 'C': /* KEY_RIGHT */ + c = 6; + break; + case 'D': /* KEY_LEFT */ + c = 2; + break; + case 'F': /* End */ + c = 5; + break; + case 'H': /* Home */ + c = 1; + break; + case '1': + c2 = getkey (); + if (c2 == '~') + { + /* One of control keys (pos1,....). */ + c = 1; + } + break; + case '3': + c2 = getkey (); + if (c2 == '~') + { + /* One of control keys (del,....). */ + c = 4; + } + break; + case '4': /* Del */ + c = 4; + break; + } + } + + /* Drain the input buffer, because so-called VT100-compatible + terminals could send key codes which aren't handled in the + code above. */ + while (checkkey () != -1) + (void) getkey (); + } + } + else +# endif /* SUPPORT_SERIAL */ + { + switch (c) + { + case KEY_LEFT: + c = 2; + break; + case KEY_RIGHT: + c = 6; + break; + case KEY_UP: + c = 16; + break; + case KEY_DOWN: + c = 14; + break; + case KEY_HOME: + c = 1; + break; + case KEY_END: + c = 5; + break; + case KEY_DC: + c = 4; + break; + case KEY_BACKSPACE: + c = 8; + break; + } + } + + return ASCII_CHAR (c); +} #endif /* STAGE1_5 */ int diff --git a/stage2/shared.h b/stage2/shared.h index 7e94178fe..c4596733a 100644 --- a/stage2/shared.h +++ b/stage2/shared.h @@ -798,6 +798,7 @@ int nul_terminate (char *str); int get_based_digit (int c, int base); int safe_parse_maxint (char **str_ptr, int *myint_ptr); int memcheck (int start, int len); +int translate_keycode (int c); #ifndef NO_DECOMPRESSION /* Compression support. */ diff --git a/stage2/stage2.c b/stage2/stage2.c index 79fd0a7ef..678f3e624 100644 --- a/stage2/stage2.c +++ b/stage2/stage2.c @@ -260,7 +260,7 @@ restart: while (1) { /* Check if ESC is pressed. */ - if (checkkey () != -1 && getkey () == 27) + if (checkkey () != -1 && ASCII_CHAR (getkey ()) == '\e') { grub_timeout = -1; show_menu = 1; @@ -358,7 +358,7 @@ restart: if (checkkey () != -1) { - c = getkey (); + c = translate_keycode (getkey ()); if (grub_timeout >= 0) { @@ -369,7 +369,7 @@ restart: gotoxy (74, 4 + entryno); } - if ((c == KEY_UP) || (ASCII_CHAR (c) == 16)) + if (c == 16) { if (entryno > 0) { @@ -386,8 +386,7 @@ restart: set_line_highlight (4, first_entry + entryno, menu_entries); } } - if (((c == KEY_DOWN) || (ASCII_CHAR (c) == 14)) - && (first_entry + entryno + 1) < num_entries) + if (c == 14 && (first_entry + entryno + 1) < num_entries) { if (entryno < 11) { @@ -405,8 +404,6 @@ restart: } } - c = ASCII_CHAR (c); - if (config_entries) { if ((c == '\n') || (c == '\r'))