[acpi] Correct the decoding of video mode numbers in wakeup.S

wakeup.S looks at the video mode number from the setup header and
looks to see if it is a VESA mode.  Unfortunately, the decoding is
done incorrectly and it will attempt to frob the VESA BIOS for any
mode number 0x0200 or larger.  Correct this, and remove a bunch of #if
0'd code.

Massive thanks to Jeff Chua for reporting the bug, and suffering
though a large number of experiments in order to track this problem
down.

Cc: Pavel Machek <pavel@ucw.cz>
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
This commit is contained in:
H. Peter Anvin 2007-09-13 14:16:37 -07:00
parent 3f662b3f6e
commit 91c4b8cb5a
2 changed files with 23 additions and 65 deletions

View file

@ -151,51 +151,30 @@ bogus_real_magic:
#define VIDEO_FIRST_V7 0x0900 #define VIDEO_FIRST_V7 0x0900
# Setting of user mode (AX=mode ID) => CF=success # Setting of user mode (AX=mode ID) => CF=success
# For now, we only handle VESA modes (0x0200..0x03ff). To handle other
# modes, we should probably compile in the video code from the boot
# directory.
mode_set: mode_set:
movw %ax, %bx movw %ax, %bx
#if 0 subb $VIDEO_FIRST_VESA>>8, %bh
cmpb $0xff, %ah cmpb $2, %bh
jz setalias jb check_vesa
testb $VIDEO_RECALC>>8, %ah setbad:
jnz _setrec clc
cmpb $VIDEO_FIRST_RESOLUTION>>8, %ah
jnc setres
cmpb $VIDEO_FIRST_SPECIAL>>8, %ah
jz setspc
cmpb $VIDEO_FIRST_V7>>8, %ah
jz setv7
#endif
cmpb $VIDEO_FIRST_VESA>>8, %ah
jnc check_vesa
#if 0
orb %ah, %ah
jz setmenu
#endif
decb %ah
# jz setbios Add bios modes later
setbad: clc
ret ret
check_vesa: check_vesa:
subb $VIDEO_FIRST_VESA>>8, %bh
orw $0x4000, %bx # Use linear frame buffer orw $0x4000, %bx # Use linear frame buffer
movw $0x4f02, %ax # VESA BIOS mode set call movw $0x4f02, %ax # VESA BIOS mode set call
int $0x10 int $0x10
cmpw $0x004f, %ax # AL=4f if implemented cmpw $0x004f, %ax # AL=4f if implemented
jnz _setbad # AH=0 if OK jnz setbad # AH=0 if OK
stc stc
ret ret
_setbad: jmp setbad
.code32 .code32
ALIGN ALIGN

View file

@ -81,7 +81,7 @@ wakeup_code:
testl $2, realmode_flags - wakeup_code testl $2, realmode_flags - wakeup_code
jz 1f jz 1f
mov video_mode - wakeup_code, %ax mov video_mode - wakeup_code, %ax
call mode_seta call mode_set
1: 1:
movw $0xb800, %ax movw $0xb800, %ax
@ -291,52 +291,31 @@ no_longmode:
#define VIDEO_FIRST_V7 0x0900 #define VIDEO_FIRST_V7 0x0900
# Setting of user mode (AX=mode ID) => CF=success # Setting of user mode (AX=mode ID) => CF=success
# For now, we only handle VESA modes (0x0200..0x03ff). To handle other
# modes, we should probably compile in the video code from the boot
# directory.
.code16 .code16
mode_seta: mode_set:
movw %ax, %bx movw %ax, %bx
#if 0 subb $VIDEO_FIRST_VESA>>8, %bh
cmpb $0xff, %ah cmpb $2, %bh
jz setalias jb check_vesa
testb $VIDEO_RECALC>>8, %ah setbad:
jnz _setrec clc
cmpb $VIDEO_FIRST_RESOLUTION>>8, %ah
jnc setres
cmpb $VIDEO_FIRST_SPECIAL>>8, %ah
jz setspc
cmpb $VIDEO_FIRST_V7>>8, %ah
jz setv7
#endif
cmpb $VIDEO_FIRST_VESA>>8, %ah
jnc check_vesaa
#if 0
orb %ah, %ah
jz setmenu
#endif
decb %ah
# jz setbios Add bios modes later
setbada: clc
ret ret
check_vesaa: check_vesa:
subb $VIDEO_FIRST_VESA>>8, %bh
orw $0x4000, %bx # Use linear frame buffer orw $0x4000, %bx # Use linear frame buffer
movw $0x4f02, %ax # VESA BIOS mode set call movw $0x4f02, %ax # VESA BIOS mode set call
int $0x10 int $0x10
cmpw $0x004f, %ax # AL=4f if implemented cmpw $0x004f, %ax # AL=4f if implemented
jnz _setbada # AH=0 if OK jnz setbad # AH=0 if OK
stc stc
ret ret
_setbada: jmp setbada
wakeup_stack_begin: # Stack grows down wakeup_stack_begin: # Stack grows down
.org 0xff0 .org 0xff0