Skip to content

Commit

Permalink
[acpi] Correct the decoding of video mode numbers in wakeup.S
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
H. Peter Anvin committed Sep 20, 2007
1 parent 3f662b3 commit 91c4b8c
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 65 deletions.
41 changes: 10 additions & 31 deletions arch/i386/kernel/acpi/wakeup.S
Original file line number Diff line number Diff line change
Expand Up @@ -151,51 +151,30 @@ bogus_real_magic:
#define VIDEO_FIRST_V7 0x0900

# 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:
movw %ax, %bx
#if 0
cmpb $0xff, %ah
jz setalias

testb $VIDEO_RECALC>>8, %ah
jnz _setrec

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
subb $VIDEO_FIRST_VESA>>8, %bh
cmpb $2, %bh
jb check_vesa

setbad: clc
setbad:
clc
ret

check_vesa:
subb $VIDEO_FIRST_VESA>>8, %bh
orw $0x4000, %bx # Use linear frame buffer
movw $0x4f02, %ax # VESA BIOS mode set call
int $0x10
cmpw $0x004f, %ax # AL=4f if implemented
jnz _setbad # AH=0 if OK
jnz setbad # AH=0 if OK

stc
ret

_setbad: jmp setbad

.code32
ALIGN

Expand Down
47 changes: 13 additions & 34 deletions arch/x86_64/kernel/acpi/wakeup.S
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ wakeup_code:
testl $2, realmode_flags - wakeup_code
jz 1f
mov video_mode - wakeup_code, %ax
call mode_seta
call mode_set
1:

movw $0xb800, %ax
Expand Down Expand Up @@ -291,52 +291,31 @@ no_longmode:
#define VIDEO_FIRST_V7 0x0900

# 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
mode_seta:
mode_set:
movw %ax, %bx
#if 0
cmpb $0xff, %ah
jz setalias

testb $VIDEO_RECALC>>8, %ah
jnz _setrec

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
subb $VIDEO_FIRST_VESA>>8, %bh
cmpb $2, %bh
jb check_vesa

setbada: clc
setbad:
clc
ret

check_vesaa:
subb $VIDEO_FIRST_VESA>>8, %bh
check_vesa:
orw $0x4000, %bx # Use linear frame buffer
movw $0x4f02, %ax # VESA BIOS mode set call
int $0x10
cmpw $0x004f, %ax # AL=4f if implemented
jnz _setbada # AH=0 if OK
jnz setbad # AH=0 if OK

stc
ret

_setbada: jmp setbada

wakeup_stack_begin: # Stack grows down

.org 0xff0
Expand Down

0 comments on commit 91c4b8c

Please sign in to comment.