diff options
author | H. Peter Anvin <hpa@zytor.com> | 2007-07-17 19:16:10 -0400 |
---|---|---|
committer | H. Peter Anvin <hpa@zytor.com> | 2007-07-18 14:36:17 -0400 |
commit | 7ad37df02c529525c4ad19035359af89d2d2a5bd (patch) | |
tree | d747f8fce857c6498c88cfb7608d2d3c6425fa34 /arch/i386 | |
parent | 5593eaa854d0b23c3b270933a93b9b82946df729 (diff) |
[x86 setup] VGA: Clear the Protect bit before setting the vertical height
If the user has asked for the vertical height registers to be recomputed
by setting bit 15 in the video mode number, we do so without clearing the
Protect bit in the Vertical Retrace Register before setting the Overflow
register. As a result, if the VGA BIOS had set the Protect bit, the
write to the Overflow register will be dropped, and bits [9:8] of the
vertical height will be left unchanged.
This is a bug imported from the assembly version of this code. It was
pointed out by Etienne Lorrain.
Cc: Etienne Lorrain <etienne_lorrain@yahoo.fr>
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
Diffstat (limited to 'arch/i386')
-rw-r--r-- | arch/i386/boot/video.c | 7 |
1 files changed, 6 insertions, 1 deletions
diff --git a/arch/i386/boot/video.c b/arch/i386/boot/video.c index 027a2c90300b..958130ef0042 100644 --- a/arch/i386/boot/video.c +++ b/arch/i386/boot/video.c | |||
@@ -195,7 +195,7 @@ static void vga_recalc_vertical(void) | |||
195 | { | 195 | { |
196 | unsigned int font_size, rows; | 196 | unsigned int font_size, rows; |
197 | u16 crtc; | 197 | u16 crtc; |
198 | u8 ov; | 198 | u8 pt, ov; |
199 | 199 | ||
200 | set_fs(0); | 200 | set_fs(0); |
201 | font_size = rdfs8(0x485); /* BIOS: font size (pixels) */ | 201 | font_size = rdfs8(0x485); /* BIOS: font size (pixels) */ |
@@ -206,7 +206,12 @@ static void vga_recalc_vertical(void) | |||
206 | 206 | ||
207 | crtc = vga_crtc(); | 207 | crtc = vga_crtc(); |
208 | 208 | ||
209 | pt = in_idx(crtc, 0x11); | ||
210 | pt &= ~0x80; /* Unlock CR0-7 */ | ||
211 | out_idx(pt, crtc, 0x11); | ||
212 | |||
209 | out_idx((u8)rows, crtc, 0x12); /* Lower height register */ | 213 | out_idx((u8)rows, crtc, 0x12); /* Lower height register */ |
214 | |||
210 | ov = in_idx(crtc, 0x07); /* Overflow register */ | 215 | ov = in_idx(crtc, 0x07); /* Overflow register */ |
211 | ov &= 0xbd; | 216 | ov &= 0xbd; |
212 | ov |= (rows >> (8-1)) & 0x02; | 217 | ov |= (rows >> (8-1)) & 0x02; |