aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2007-08-31 14:30:31 -0400
committerH. Peter Anvin <hpa@zytor.com>2007-08-31 14:52:35 -0400
commit4221d014ea04d439e6d1e65951c3b406e7c1b7ab (patch)
tree68457ec6ff8fbaeefa0a3b9e5565d8c10a20643f
parent3b42d28b2a04b3c9830eb865288239d45eccc402 (diff)
[x86 setup] Don't rely on the VESA BIOS being register-clean
The VESA BIOS is specified to be register-clean. However, we have now found at least one system which violates that. Thus, be as paranoid about VESA calls as about everything else. Huge thanks to Will Simoneau for reporting, diagnosing, and testing this out on Dell Inspiron 5150. Cc: Will Simoneau <simoneau@ele.uri.edu> Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-rw-r--r--arch/i386/boot/video-vesa.c34
1 files changed, 21 insertions, 13 deletions
diff --git a/arch/i386/boot/video-vesa.c b/arch/i386/boot/video-vesa.c
index f1bc71e948cf..192190710710 100644
--- a/arch/i386/boot/video-vesa.c
+++ b/arch/i386/boot/video-vesa.c
@@ -29,7 +29,7 @@ static void vesa_store_mode_params_graphics(void);
29static int vesa_probe(void) 29static int vesa_probe(void)
30{ 30{
31#if defined(CONFIG_VIDEO_VESA) || defined(CONFIG_FIRMWARE_EDID) 31#if defined(CONFIG_VIDEO_VESA) || defined(CONFIG_FIRMWARE_EDID)
32 u16 ax; 32 u16 ax, cx, di;
33 u16 mode; 33 u16 mode;
34 addr_t mode_ptr; 34 addr_t mode_ptr;
35 struct mode_info *mi; 35 struct mode_info *mi;
@@ -39,9 +39,11 @@ static int vesa_probe(void)
39 39
40 vginfo.signature = VBE2_MAGIC; 40 vginfo.signature = VBE2_MAGIC;
41 41
42 /* Optimistically assume a VESA BIOS is register-clean... */
43 ax = 0x4f00; 42 ax = 0x4f00;
44 asm("int $0x10" : "+a" (ax), "=m" (vginfo) : "D" (&vginfo)); 43 di = (size_t)&vginfo;
44 asm(INT10
45 : "+a" (ax), "+D" (di), "=m" (vginfo)
46 : : "ebx", "ecx", "edx", "esi");
45 47
46 if (ax != 0x004f || 48 if (ax != 0x004f ||
47 vginfo.signature != VESA_MAGIC || 49 vginfo.signature != VESA_MAGIC ||
@@ -64,9 +66,11 @@ static int vesa_probe(void)
64 memset(&vminfo, 0, sizeof vminfo); /* Just in case... */ 66 memset(&vminfo, 0, sizeof vminfo); /* Just in case... */
65 67
66 ax = 0x4f01; 68 ax = 0x4f01;
67 asm("int $0x10" 69 cx = mode;
68 : "+a" (ax), "=m" (vminfo) 70 di = (size_t)&vminfo;
69 : "c" (mode), "D" (&vminfo)); 71 asm(INT10
72 : "+a" (ax), "+c" (cx), "+D" (di), "=m" (vminfo)
73 : : "ebx", "edx", "esi");
70 74
71 if (ax != 0x004f) 75 if (ax != 0x004f)
72 continue; 76 continue;
@@ -102,16 +106,18 @@ static int vesa_probe(void)
102 106
103static int vesa_set_mode(struct mode_info *mode) 107static int vesa_set_mode(struct mode_info *mode)
104{ 108{
105 u16 ax; 109 u16 ax, bx, cx, di;
106 int is_graphic; 110 int is_graphic;
107 u16 vesa_mode = mode->mode - VIDEO_FIRST_VESA; 111 u16 vesa_mode = mode->mode - VIDEO_FIRST_VESA;
108 112
109 memset(&vminfo, 0, sizeof vminfo); /* Just in case... */ 113 memset(&vminfo, 0, sizeof vminfo); /* Just in case... */
110 114
111 ax = 0x4f01; 115 ax = 0x4f01;
112 asm("int $0x10" 116 cx = vesa_mode;
113 : "+a" (ax), "=m" (vminfo) 117 di = (size_t)&vminfo;
114 : "c" (vesa_mode), "D" (&vminfo)); 118 asm(INT10
119 : "+a" (ax), "+c" (cx), "+D" (di), "=m" (vminfo)
120 : : "ebx", "edx", "esi");
115 121
116 if (ax != 0x004f) 122 if (ax != 0x004f)
117 return -1; 123 return -1;
@@ -129,9 +135,11 @@ static int vesa_set_mode(struct mode_info *mode)
129 135
130 136
131 ax = 0x4f02; 137 ax = 0x4f02;
132 asm volatile("int $0x10" 138 bx = vesa_mode;
133 : "+a" (ax) 139 di = 0;
134 : "b" (vesa_mode), "D" (0)); 140 asm volatile(INT10
141 : "+a" (ax), "+b" (bx), "+D" (di)
142 : : "ecx", "edx", "esi");
135 143
136 if (ax != 0x004f) 144 if (ax != 0x004f)
137 return -1; 145 return -1;