diff options
author | H. Peter Anvin <hpa@linux.intel.com> | 2009-04-01 21:20:11 -0400 |
---|---|---|
committer | H. Peter Anvin <hpa@zytor.com> | 2009-04-09 19:08:12 -0400 |
commit | cf06de7b9cdd3efee7a59dced1977b3c21d43732 (patch) | |
tree | 22a4fd8675461fc35756573a3964e07a236cb71b /arch/x86/boot/video-bios.c | |
parent | 0a706db320768f8f6e43bbf73b58d2aabdc93354 (diff) |
x86, setup: "glove box" BIOS interrupts in the video code
Impact: BIOS proofing
"Glove box" off BIOS interrupts in the video code.
LKML-Reference: <49DE7F79.4030106@zytor.com>
Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
Cc: Pavel Machek <pavel@ucw.cz>
Cc: Rafael J. Wysocki <rjw@sisk.pl>
Diffstat (limited to 'arch/x86/boot/video-bios.c')
-rw-r--r-- | arch/x86/boot/video-bios.c | 27 |
1 files changed, 13 insertions, 14 deletions
diff --git a/arch/x86/boot/video-bios.c b/arch/x86/boot/video-bios.c index 3fa979c9c363..d660be492363 100644 --- a/arch/x86/boot/video-bios.c +++ b/arch/x86/boot/video-bios.c | |||
@@ -2,6 +2,7 @@ | |||
2 | * | 2 | * |
3 | * Copyright (C) 1991, 1992 Linus Torvalds | 3 | * Copyright (C) 1991, 1992 Linus Torvalds |
4 | * Copyright 2007 rPath, Inc. - All Rights Reserved | 4 | * Copyright 2007 rPath, Inc. - All Rights Reserved |
5 | * Copyright 2009 Intel Corporation; author H. Peter Anvin | ||
5 | * | 6 | * |
6 | * This file is part of the Linux kernel, and is made available under | 7 | * This file is part of the Linux kernel, and is made available under |
7 | * the terms of the GNU General Public License version 2. | 8 | * the terms of the GNU General Public License version 2. |
@@ -29,21 +30,21 @@ static int bios_set_mode(struct mode_info *mi) | |||
29 | 30 | ||
30 | static int set_bios_mode(u8 mode) | 31 | static int set_bios_mode(u8 mode) |
31 | { | 32 | { |
32 | u16 ax; | 33 | struct biosregs ireg, oreg; |
33 | u8 new_mode; | 34 | u8 new_mode; |
34 | 35 | ||
35 | ax = mode; /* AH=0x00 Set Video Mode */ | 36 | initregs(&ireg); |
36 | asm volatile(INT10 | 37 | ireg.al = mode; /* AH=0x00 Set Video Mode */ |
37 | : "+a" (ax) | 38 | intcall(0x10, &ireg, NULL); |
38 | : : "ebx", "ecx", "edx", "esi", "edi"); | ||
39 | 39 | ||
40 | ax = 0x0f00; /* Get Current Video Mode */ | 40 | |
41 | asm volatile(INT10 | 41 | ireg.ah = 0x0f; /* Get Current Video Mode */ |
42 | : "+a" (ax) | 42 | intcall(0x10, &ireg, &oreg); |
43 | : : "ebx", "ecx", "edx", "esi", "edi"); | ||
44 | 43 | ||
45 | do_restore = 1; /* Assume video contents were lost */ | 44 | do_restore = 1; /* Assume video contents were lost */ |
46 | new_mode = ax & 0x7f; /* Not all BIOSes are clean with the top bit */ | 45 | |
46 | /* Not all BIOSes are clean with the top bit */ | ||
47 | new_mode = ireg.al & 0x7f; | ||
47 | 48 | ||
48 | if (new_mode == mode) | 49 | if (new_mode == mode) |
49 | return 0; /* Mode change OK */ | 50 | return 0; /* Mode change OK */ |
@@ -53,10 +54,8 @@ static int set_bios_mode(u8 mode) | |||
53 | /* Mode setting failed, but we didn't end up where we | 54 | /* Mode setting failed, but we didn't end up where we |
54 | started. That's bad. Try to revert to the original | 55 | started. That's bad. Try to revert to the original |
55 | video mode. */ | 56 | video mode. */ |
56 | ax = boot_params.screen_info.orig_video_mode; | 57 | ireg.ax = boot_params.screen_info.orig_video_mode; |
57 | asm volatile(INT10 | 58 | intcall(0x10, &ireg, NULL); |
58 | : "+a" (ax) | ||
59 | : : "ebx", "ecx", "edx", "esi", "edi"); | ||
60 | } | 59 | } |
61 | #endif | 60 | #endif |
62 | return -1; | 61 | return -1; |