diff options
| -rw-r--r-- | arch/x86/boot/video-bios.c | 27 | ||||
| -rw-r--r-- | arch/x86/boot/video-vesa.c | 137 | ||||
| -rw-r--r-- | arch/x86/boot/video-vga.c | 95 | ||||
| -rw-r--r-- | arch/x86/boot/video.c | 42 | ||||
| -rw-r--r-- | arch/x86/boot/video.h | 14 |
5 files changed, 151 insertions, 164 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; |
diff --git a/arch/x86/boot/video-vesa.c b/arch/x86/boot/video-vesa.c index 4a58c8ce3f69..c700147d6ffb 100644 --- a/arch/x86/boot/video-vesa.c +++ b/arch/x86/boot/video-vesa.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. |
| @@ -31,7 +32,7 @@ static inline void vesa_store_mode_params_graphics(void) {} | |||
| 31 | static int vesa_probe(void) | 32 | static int vesa_probe(void) |
| 32 | { | 33 | { |
| 33 | #if defined(CONFIG_VIDEO_VESA) || defined(CONFIG_FIRMWARE_EDID) | 34 | #if defined(CONFIG_VIDEO_VESA) || defined(CONFIG_FIRMWARE_EDID) |
| 34 | u16 ax, cx, di; | 35 | struct biosregs ireg, oreg; |
| 35 | u16 mode; | 36 | u16 mode; |
| 36 | addr_t mode_ptr; | 37 | addr_t mode_ptr; |
| 37 | struct mode_info *mi; | 38 | struct mode_info *mi; |
| @@ -39,13 +40,12 @@ static int vesa_probe(void) | |||
| 39 | 40 | ||
| 40 | video_vesa.modes = GET_HEAP(struct mode_info, 0); | 41 | video_vesa.modes = GET_HEAP(struct mode_info, 0); |
| 41 | 42 | ||
| 42 | ax = 0x4f00; | 43 | initregs(&ireg); |
| 43 | di = (size_t)&vginfo; | 44 | ireg.ax = 0x4f00; |
| 44 | asm(INT10 | 45 | ireg.di = (size_t)&vginfo; |
| 45 | : "+a" (ax), "+D" (di), "=m" (vginfo) | 46 | intcall(0x10, &ireg, &oreg); |
| 46 | : : "ebx", "ecx", "edx", "esi"); | ||
| 47 | 47 | ||
| 48 | if (ax != 0x004f || | 48 | if (ireg.ax != 0x004f || |
| 49 | vginfo.signature != VESA_MAGIC || | 49 | vginfo.signature != VESA_MAGIC || |
| 50 | vginfo.version < 0x0102) | 50 | vginfo.version < 0x0102) |
| 51 | return 0; /* Not present */ | 51 | return 0; /* Not present */ |
| @@ -65,14 +65,12 @@ static int vesa_probe(void) | |||
| 65 | 65 | ||
| 66 | memset(&vminfo, 0, sizeof vminfo); /* Just in case... */ | 66 | memset(&vminfo, 0, sizeof vminfo); /* Just in case... */ |
| 67 | 67 | ||
| 68 | ax = 0x4f01; | 68 | ireg.ax = 0x4f01; |
| 69 | cx = mode; | 69 | ireg.cx = mode; |
| 70 | di = (size_t)&vminfo; | 70 | ireg.di = (size_t)&vminfo; |
| 71 | asm(INT10 | 71 | intcall(0x10, &ireg, &oreg); |
| 72 | : "+a" (ax), "+c" (cx), "+D" (di), "=m" (vminfo) | ||
| 73 | : : "ebx", "edx", "esi"); | ||
| 74 | 72 | ||
| 75 | if (ax != 0x004f) | 73 | if (ireg.ax != 0x004f) |
| 76 | continue; | 74 | continue; |
| 77 | 75 | ||
| 78 | if ((vminfo.mode_attr & 0x15) == 0x05) { | 76 | if ((vminfo.mode_attr & 0x15) == 0x05) { |
| @@ -111,20 +109,19 @@ static int vesa_probe(void) | |||
| 111 | 109 | ||
| 112 | static int vesa_set_mode(struct mode_info *mode) | 110 | static int vesa_set_mode(struct mode_info *mode) |
| 113 | { | 111 | { |
| 114 | u16 ax, bx, cx, di; | 112 | struct biosregs ireg, oreg; |
| 115 | int is_graphic; | 113 | int is_graphic; |
| 116 | u16 vesa_mode = mode->mode - VIDEO_FIRST_VESA; | 114 | u16 vesa_mode = mode->mode - VIDEO_FIRST_VESA; |
| 117 | 115 | ||
| 118 | memset(&vminfo, 0, sizeof vminfo); /* Just in case... */ | 116 | memset(&vminfo, 0, sizeof vminfo); /* Just in case... */ |
| 119 | 117 | ||
| 120 | ax = 0x4f01; | 118 | initregs(&ireg); |
| 121 | cx = vesa_mode; | 119 | ireg.ax = 0x4f01; |
| 122 | di = (size_t)&vminfo; | 120 | ireg.cx = vesa_mode; |
| 123 | asm(INT10 | 121 | ireg.di = (size_t)&vminfo; |
| 124 | : "+a" (ax), "+c" (cx), "+D" (di), "=m" (vminfo) | 122 | intcall(0x10, &ireg, &oreg); |
| 125 | : : "ebx", "edx", "esi"); | ||
| 126 | 123 | ||
| 127 | if (ax != 0x004f) | 124 | if (oreg.ax != 0x004f) |
| 128 | return -1; | 125 | return -1; |
| 129 | 126 | ||
| 130 | if ((vminfo.mode_attr & 0x15) == 0x05) { | 127 | if ((vminfo.mode_attr & 0x15) == 0x05) { |
| @@ -141,14 +138,12 @@ static int vesa_set_mode(struct mode_info *mode) | |||
| 141 | } | 138 | } |
| 142 | 139 | ||
| 143 | 140 | ||
| 144 | ax = 0x4f02; | 141 | initregs(&ireg); |
| 145 | bx = vesa_mode; | 142 | ireg.ax = 0x4f02; |
| 146 | di = 0; | 143 | ireg.bx = vesa_mode; |
| 147 | asm volatile(INT10 | 144 | intcall(0x10, &ireg, &oreg); |
| 148 | : "+a" (ax), "+b" (bx), "+D" (di) | ||
| 149 | : : "ecx", "edx", "esi"); | ||
| 150 | 145 | ||
| 151 | if (ax != 0x004f) | 146 | if (oreg.ax != 0x004f) |
| 152 | return -1; | 147 | return -1; |
| 153 | 148 | ||
| 154 | graphic_mode = is_graphic; | 149 | graphic_mode = is_graphic; |
| @@ -171,50 +166,45 @@ static int vesa_set_mode(struct mode_info *mode) | |||
| 171 | /* Switch DAC to 8-bit mode */ | 166 | /* Switch DAC to 8-bit mode */ |
| 172 | static void vesa_dac_set_8bits(void) | 167 | static void vesa_dac_set_8bits(void) |
| 173 | { | 168 | { |
| 169 | struct biosregs ireg, oreg; | ||
| 174 | u8 dac_size = 6; | 170 | u8 dac_size = 6; |
| 175 | 171 | ||
| 176 | /* If possible, switch the DAC to 8-bit mode */ | 172 | /* If possible, switch the DAC to 8-bit mode */ |
| 177 | if (vginfo.capabilities & 1) { | 173 | if (vginfo.capabilities & 1) { |
| 178 | u16 ax, bx; | 174 | initregs(&ireg); |
| 179 | 175 | ireg.ax = 0x4f08; | |
| 180 | ax = 0x4f08; | 176 | ireg.bh = 0x08; |
| 181 | bx = 0x0800; | 177 | intcall(0x10, &ireg, &oreg); |
| 182 | asm volatile(INT10 | 178 | if (oreg.ax == 0x004f) |
| 183 | : "+a" (ax), "+b" (bx) | 179 | dac_size = oreg.bh; |
| 184 | : : "ecx", "edx", "esi", "edi"); | ||
| 185 | |||
| 186 | if (ax == 0x004f) | ||
| 187 | dac_size = bx >> 8; | ||
| 188 | } | 180 | } |
| 189 | 181 | ||
| 190 | /* Set the color sizes to the DAC size, and offsets to 0 */ | 182 | /* Set the color sizes to the DAC size, and offsets to 0 */ |
| 191 | boot_params.screen_info.red_size = dac_size; | 183 | boot_params.screen_info.red_size = dac_size; |
| 192 | boot_params.screen_info.green_size = dac_size; | 184 | boot_params.screen_info.green_size = dac_size; |
| 193 | boot_params.screen_info.blue_size = dac_size; | 185 | boot_params.screen_info.blue_size = dac_size; |
| 194 | boot_params.screen_info.rsvd_size = dac_size; | 186 | boot_params.screen_info.rsvd_size = dac_size; |
| 195 | 187 | ||
| 196 | boot_params.screen_info.red_pos = 0; | 188 | boot_params.screen_info.red_pos = 0; |
| 197 | boot_params.screen_info.green_pos = 0; | 189 | boot_params.screen_info.green_pos = 0; |
| 198 | boot_params.screen_info.blue_pos = 0; | 190 | boot_params.screen_info.blue_pos = 0; |
| 199 | boot_params.screen_info.rsvd_pos = 0; | 191 | boot_params.screen_info.rsvd_pos = 0; |
| 200 | } | 192 | } |
| 201 | 193 | ||
| 202 | /* Save the VESA protected mode info */ | 194 | /* Save the VESA protected mode info */ |
| 203 | static void vesa_store_pm_info(void) | 195 | static void vesa_store_pm_info(void) |
| 204 | { | 196 | { |
| 205 | u16 ax, bx, di, es; | 197 | struct biosregs ireg, oreg; |
| 206 | 198 | ||
| 207 | ax = 0x4f0a; | 199 | initregs(&ireg); |
| 208 | bx = di = 0; | 200 | ireg.ax = 0x4f0a; |
| 209 | asm("pushw %%es; "INT10"; movw %%es,%0; popw %%es" | 201 | intcall(0x10, &ireg, &oreg); |
| 210 | : "=d" (es), "+a" (ax), "+b" (bx), "+D" (di) | ||
| 211 | : : "ecx", "esi"); | ||
| 212 | 202 | ||
| 213 | if (ax != 0x004f) | 203 | if (oreg.ax != 0x004f) |
| 214 | return; | 204 | return; |
| 215 | 205 | ||
| 216 | boot_params.screen_info.vesapm_seg = es; | 206 | boot_params.screen_info.vesapm_seg = oreg.es; |
| 217 | boot_params.screen_info.vesapm_off = di; | 207 | boot_params.screen_info.vesapm_off = oreg.di; |
| 218 | } | 208 | } |
| 219 | 209 | ||
| 220 | /* | 210 | /* |
| @@ -252,7 +242,7 @@ static void vesa_store_mode_params_graphics(void) | |||
| 252 | void vesa_store_edid(void) | 242 | void vesa_store_edid(void) |
| 253 | { | 243 | { |
| 254 | #ifdef CONFIG_FIRMWARE_EDID | 244 | #ifdef CONFIG_FIRMWARE_EDID |
| 255 | u16 ax, bx, cx, dx, di; | 245 | struct biosregs ireg, oreg; |
| 256 | 246 | ||
| 257 | /* Apparently used as a nonsense token... */ | 247 | /* Apparently used as a nonsense token... */ |
| 258 | memset(&boot_params.edid_info, 0x13, sizeof boot_params.edid_info); | 248 | memset(&boot_params.edid_info, 0x13, sizeof boot_params.edid_info); |
| @@ -260,33 +250,26 @@ void vesa_store_edid(void) | |||
| 260 | if (vginfo.version < 0x0200) | 250 | if (vginfo.version < 0x0200) |
| 261 | return; /* EDID requires VBE 2.0+ */ | 251 | return; /* EDID requires VBE 2.0+ */ |
| 262 | 252 | ||
| 263 | ax = 0x4f15; /* VBE DDC */ | 253 | initregs(&ireg); |
| 264 | bx = 0x0000; /* Report DDC capabilities */ | 254 | ireg.ax = 0x4f15; /* VBE DDC */ |
| 265 | cx = 0; /* Controller 0 */ | 255 | /* ireg.bx = 0x0000; */ /* Report DDC capabilities */ |
| 266 | di = 0; /* ES:DI must be 0 by spec */ | 256 | /* ireg.cx = 0; */ /* Controller 0 */ |
| 267 | 257 | ireg.es = 0; /* ES:DI must be 0 by spec */ | |
| 268 | /* Note: The VBE DDC spec is different from the main VESA spec; | 258 | intcall(0x10, &ireg, &oreg); |
| 269 | we genuinely have to assume all registers are destroyed here. */ | ||
| 270 | |||
| 271 | asm("pushw %%es; movw %2,%%es; "INT10"; popw %%es" | ||
| 272 | : "+a" (ax), "+b" (bx), "+c" (cx), "+D" (di) | ||
| 273 | : : "esi", "edx"); | ||
| 274 | 259 | ||
| 275 | if (ax != 0x004f) | 260 | if (oreg.ax != 0x004f) |
| 276 | return; /* No EDID */ | 261 | return; /* No EDID */ |
| 277 | 262 | ||
| 278 | /* BH = time in seconds to transfer EDD information */ | 263 | /* BH = time in seconds to transfer EDD information */ |
| 279 | /* BL = DDC level supported */ | 264 | /* BL = DDC level supported */ |
| 280 | 265 | ||
| 281 | ax = 0x4f15; /* VBE DDC */ | 266 | ireg.ax = 0x4f15; /* VBE DDC */ |
| 282 | bx = 0x0001; /* Read EDID */ | 267 | ireg.bx = 0x0001; /* Read EDID */ |
| 283 | cx = 0; /* Controller 0 */ | 268 | /* ireg.cx = 0; */ /* Controller 0 */ |
| 284 | dx = 0; /* EDID block number */ | 269 | /* ireg.dx = 0; */ /* EDID block number */ |
| 285 | di =(size_t) &boot_params.edid_info; /* (ES:)Pointer to block */ | 270 | ireg.es = ds(); |
| 286 | asm(INT10 | 271 | ireg.di =(size_t)&boot_params.edid_info; /* (ES:)Pointer to block */ |
| 287 | : "+a" (ax), "+b" (bx), "+d" (dx), "=m" (boot_params.edid_info), | 272 | intcall(0x10, &ireg, &oreg); |
| 288 | "+c" (cx), "+D" (di) | ||
| 289 | : : "esi"); | ||
| 290 | #endif /* CONFIG_FIRMWARE_EDID */ | 273 | #endif /* CONFIG_FIRMWARE_EDID */ |
| 291 | } | 274 | } |
| 292 | 275 | ||
diff --git a/arch/x86/boot/video-vga.c b/arch/x86/boot/video-vga.c index 9e0587a37768..8f8d827e254d 100644 --- a/arch/x86/boot/video-vga.c +++ b/arch/x86/boot/video-vga.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. |
| @@ -39,30 +40,30 @@ static __videocard video_vga; | |||
| 39 | /* Set basic 80x25 mode */ | 40 | /* Set basic 80x25 mode */ |
| 40 | static u8 vga_set_basic_mode(void) | 41 | static u8 vga_set_basic_mode(void) |
| 41 | { | 42 | { |
| 43 | struct biosregs ireg, oreg; | ||
| 42 | u16 ax; | 44 | u16 ax; |
| 43 | u8 rows; | 45 | u8 rows; |
| 44 | u8 mode; | 46 | u8 mode; |
| 45 | 47 | ||
| 48 | initregs(&ireg); | ||
| 49 | |||
| 46 | #ifdef CONFIG_VIDEO_400_HACK | 50 | #ifdef CONFIG_VIDEO_400_HACK |
| 47 | if (adapter >= ADAPTER_VGA) { | 51 | if (adapter >= ADAPTER_VGA) { |
| 48 | asm volatile(INT10 | 52 | ireg.ax = 0x1202; |
| 49 | : : "a" (0x1202), "b" (0x0030) | 53 | ireg.bx = 0x0030; |
| 50 | : "ecx", "edx", "esi", "edi"); | 54 | intcall(0x10, &ireg, NULL); |
| 51 | } | 55 | } |
| 52 | #endif | 56 | #endif |
| 53 | 57 | ||
| 54 | ax = 0x0f00; | 58 | ax = 0x0f00; |
| 55 | asm volatile(INT10 | 59 | intcall(0x10, &ireg, &oreg); |
| 56 | : "+a" (ax) | 60 | mode = oreg.al; |
| 57 | : : "ebx", "ecx", "edx", "esi", "edi"); | ||
| 58 | |||
| 59 | mode = (u8)ax; | ||
| 60 | 61 | ||
| 61 | set_fs(0); | 62 | set_fs(0); |
| 62 | rows = rdfs8(0x484); /* rows minus one */ | 63 | rows = rdfs8(0x484); /* rows minus one */ |
| 63 | 64 | ||
| 64 | #ifndef CONFIG_VIDEO_400_HACK | 65 | #ifndef CONFIG_VIDEO_400_HACK |
| 65 | if ((ax == 0x5003 || ax == 0x5007) && | 66 | if ((oreg.ax == 0x5003 || oreg.ax == 0x5007) && |
| 66 | (rows == 0 || rows == 24)) | 67 | (rows == 0 || rows == 24)) |
| 67 | return mode; | 68 | return mode; |
| 68 | #endif | 69 | #endif |
| @@ -71,10 +72,8 @@ static u8 vga_set_basic_mode(void) | |||
| 71 | mode = 3; | 72 | mode = 3; |
| 72 | 73 | ||
| 73 | /* Set the mode */ | 74 | /* Set the mode */ |
| 74 | ax = mode; | 75 | ireg.ax = mode; /* AH=0: set mode */ |
| 75 | asm volatile(INT10 | 76 | intcall(0x10, &ireg, NULL); |
| 76 | : "+a" (ax) | ||
| 77 | : : "ebx", "ecx", "edx", "esi", "edi"); | ||
| 78 | do_restore = 1; | 77 | do_restore = 1; |
| 79 | return mode; | 78 | return mode; |
| 80 | } | 79 | } |
| @@ -82,43 +81,69 @@ static u8 vga_set_basic_mode(void) | |||
| 82 | static void vga_set_8font(void) | 81 | static void vga_set_8font(void) |
| 83 | { | 82 | { |
| 84 | /* Set 8x8 font - 80x43 on EGA, 80x50 on VGA */ | 83 | /* Set 8x8 font - 80x43 on EGA, 80x50 on VGA */ |
| 84 | struct biosregs ireg; | ||
| 85 | |||
| 86 | initregs(&ireg); | ||
| 85 | 87 | ||
| 86 | /* Set 8x8 font */ | 88 | /* Set 8x8 font */ |
| 87 | asm volatile(INT10 : : "a" (0x1112), "b" (0)); | 89 | ireg.ax = 0x1112; |
| 90 | /* ireg.bl = 0; */ | ||
| 91 | intcall(0x10, &ireg, NULL); | ||
| 88 | 92 | ||
| 89 | /* Use alternate print screen */ | 93 | /* Use alternate print screen */ |
| 90 | asm volatile(INT10 : : "a" (0x1200), "b" (0x20)); | 94 | ireg.ax = 0x1200; |
| 95 | ireg.bl = 0x20; | ||
| 96 | intcall(0x10, &ireg, NULL); | ||
| 91 | 97 | ||
| 92 | /* Turn off cursor emulation */ | 98 | /* Turn off cursor emulation */ |
| 93 | asm volatile(INT10 : : "a" (0x1201), "b" (0x34)); | 99 | ireg.ax = 0x1201; |
| 100 | ireg.bl = 0x34; | ||
| 101 | intcall(0x10, &ireg, NULL); | ||
| 94 | 102 | ||
| 95 | /* Cursor is scan lines 6-7 */ | 103 | /* Cursor is scan lines 6-7 */ |
| 96 | asm volatile(INT10 : : "a" (0x0100), "c" (0x0607)); | 104 | ireg.ax = 0x0100; |
| 105 | ireg.cx = 0x0607; | ||
| 106 | intcall(0x10, &ireg, NULL); | ||
| 97 | } | 107 | } |
| 98 | 108 | ||
| 99 | static void vga_set_14font(void) | 109 | static void vga_set_14font(void) |
| 100 | { | 110 | { |
| 101 | /* Set 9x14 font - 80x28 on VGA */ | 111 | /* Set 9x14 font - 80x28 on VGA */ |
| 112 | struct biosregs ireg; | ||
| 113 | |||
| 114 | initregs(&ireg); | ||
| 102 | 115 | ||
| 103 | /* Set 9x14 font */ | 116 | /* Set 9x14 font */ |
| 104 | asm volatile(INT10 : : "a" (0x1111), "b" (0)); | 117 | ireg.ax = 0x1111; |
| 118 | /* ireg.bl = 0; */ | ||
| 119 | intcall(0x10, &ireg, NULL); | ||
| 105 | 120 | ||
| 106 | /* Turn off cursor emulation */ | 121 | /* Turn off cursor emulation */ |
| 107 | asm volatile(INT10 : : "a" (0x1201), "b" (0x34)); | 122 | ireg.ax = 0x1201; |
| 123 | ireg.bl = 0x34; | ||
| 124 | intcall(0x10, &ireg, NULL); | ||
| 108 | 125 | ||
| 109 | /* Cursor is scan lines 11-12 */ | 126 | /* Cursor is scan lines 11-12 */ |
| 110 | asm volatile(INT10 : : "a" (0x0100), "c" (0x0b0c)); | 127 | ireg.ax = 0x0100; |
| 128 | ireg.cx = 0x0b0c; | ||
| 129 | intcall(0x10, &ireg, NULL); | ||
| 111 | } | 130 | } |
| 112 | 131 | ||
| 113 | static void vga_set_80x43(void) | 132 | static void vga_set_80x43(void) |
| 114 | { | 133 | { |
| 115 | /* Set 80x43 mode on VGA (not EGA) */ | 134 | /* Set 80x43 mode on VGA (not EGA) */ |
| 135 | struct biosregs ireg; | ||
| 136 | |||
| 137 | initregs(&ireg); | ||
| 116 | 138 | ||
| 117 | /* Set 350 scans */ | 139 | /* Set 350 scans */ |
| 118 | asm volatile(INT10 : : "a" (0x1201), "b" (0x30)); | 140 | ireg.ax = 0x1201; |
| 141 | ireg.bl = 0x30; | ||
| 142 | intcall(0x10, &ireg, NULL); | ||
| 119 | 143 | ||
| 120 | /* Reset video mode */ | 144 | /* Reset video mode */ |
| 121 | asm volatile(INT10 : : "a" (0x0003)); | 145 | ireg.ax = 0x0003; |
| 146 | intcall(0x10, &ireg, NULL); | ||
| 122 | 147 | ||
| 123 | vga_set_8font(); | 148 | vga_set_8font(); |
| 124 | } | 149 | } |
| @@ -225,8 +250,6 @@ static int vga_set_mode(struct mode_info *mode) | |||
| 225 | */ | 250 | */ |
| 226 | static int vga_probe(void) | 251 | static int vga_probe(void) |
| 227 | { | 252 | { |
| 228 | u16 ega_bx; | ||
| 229 | |||
| 230 | static const char *card_name[] = { | 253 | static const char *card_name[] = { |
| 231 | "CGA/MDA/HGC", "EGA", "VGA" | 254 | "CGA/MDA/HGC", "EGA", "VGA" |
| 232 | }; | 255 | }; |
| @@ -240,26 +263,26 @@ static int vga_probe(void) | |||
| 240 | sizeof(ega_modes)/sizeof(struct mode_info), | 263 | sizeof(ega_modes)/sizeof(struct mode_info), |
| 241 | sizeof(vga_modes)/sizeof(struct mode_info), | 264 | sizeof(vga_modes)/sizeof(struct mode_info), |
| 242 | }; | 265 | }; |
| 243 | u8 vga_flag; | ||
| 244 | 266 | ||
| 245 | asm(INT10 | 267 | struct biosregs ireg, oreg; |
| 246 | : "=b" (ega_bx) | 268 | |
| 247 | : "a" (0x1200), "b" (0x10) /* Check EGA/VGA */ | 269 | initregs(&ireg); |
| 248 | : "ecx", "edx", "esi", "edi"); | 270 | |
| 271 | ireg.ax = 0x1200; | ||
| 272 | ireg.bl = 0x10; /* Check EGA/VGA */ | ||
| 273 | intcall(0x10, &ireg, &oreg); | ||
| 249 | 274 | ||
| 250 | #ifndef _WAKEUP | 275 | #ifndef _WAKEUP |
| 251 | boot_params.screen_info.orig_video_ega_bx = ega_bx; | 276 | boot_params.screen_info.orig_video_ega_bx = oreg.bx; |
| 252 | #endif | 277 | #endif |
| 253 | 278 | ||
| 254 | /* If we have MDA/CGA/HGC then BL will be unchanged at 0x10 */ | 279 | /* If we have MDA/CGA/HGC then BL will be unchanged at 0x10 */ |
| 255 | if ((u8)ega_bx != 0x10) { | 280 | if (oreg.bl != 0x10) { |
| 256 | /* EGA/VGA */ | 281 | /* EGA/VGA */ |
| 257 | asm(INT10 | 282 | ireg.ax = 0x1a00; |
| 258 | : "=a" (vga_flag) | 283 | intcall(0x10, &ireg, &oreg); |
| 259 | : "a" (0x1a00) | ||
| 260 | : "ebx", "ecx", "edx", "esi", "edi"); | ||
| 261 | 284 | ||
| 262 | if (vga_flag == 0x1a) { | 285 | if (oreg.al == 0x1a) { |
| 263 | adapter = ADAPTER_VGA; | 286 | adapter = ADAPTER_VGA; |
| 264 | #ifndef _WAKEUP | 287 | #ifndef _WAKEUP |
| 265 | boot_params.screen_info.orig_video_isVGA = 1; | 288 | boot_params.screen_info.orig_video_isVGA = 1; |
diff --git a/arch/x86/boot/video.c b/arch/x86/boot/video.c index 3bef2c1febe9..bad728b76fc2 100644 --- a/arch/x86/boot/video.c +++ b/arch/x86/boot/video.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. |
| @@ -18,33 +19,29 @@ | |||
| 18 | 19 | ||
| 19 | static void store_cursor_position(void) | 20 | static void store_cursor_position(void) |
| 20 | { | 21 | { |
| 21 | u16 curpos; | 22 | struct biosregs ireg, oreg; |
| 22 | u16 ax, bx; | ||
| 23 | 23 | ||
| 24 | ax = 0x0300; | 24 | initregs(&ireg); |
| 25 | bx = 0; | 25 | ireg.ah = 0x03; |
| 26 | asm(INT10 | 26 | intcall(0x10, &ireg, &oreg); |
| 27 | : "=d" (curpos), "+a" (ax), "+b" (bx) | ||
| 28 | : : "ecx", "esi", "edi"); | ||
| 29 | 27 | ||
| 30 | boot_params.screen_info.orig_x = curpos; | 28 | boot_params.screen_info.orig_x = oreg.dl; |
| 31 | boot_params.screen_info.orig_y = curpos >> 8; | 29 | boot_params.screen_info.orig_y = oreg.dh; |
| 32 | } | 30 | } |
| 33 | 31 | ||
| 34 | static void store_video_mode(void) | 32 | static void store_video_mode(void) |
| 35 | { | 33 | { |
| 36 | u16 ax, page; | 34 | struct biosregs ireg, oreg; |
| 37 | 35 | ||
| 38 | /* N.B.: the saving of the video page here is a bit silly, | 36 | /* N.B.: the saving of the video page here is a bit silly, |
| 39 | since we pretty much assume page 0 everywhere. */ | 37 | since we pretty much assume page 0 everywhere. */ |
| 40 | ax = 0x0f00; | 38 | initregs(&ireg); |
| 41 | asm(INT10 | 39 | ireg.ah = 0x0f; |
| 42 | : "+a" (ax), "=b" (page) | 40 | intcall(0x10, &ireg, &oreg); |
| 43 | : : "ecx", "edx", "esi", "edi"); | ||
| 44 | 41 | ||
| 45 | /* Not all BIOSes are clean with respect to the top bit */ | 42 | /* Not all BIOSes are clean with respect to the top bit */ |
| 46 | boot_params.screen_info.orig_video_mode = ax & 0x7f; | 43 | boot_params.screen_info.orig_video_mode = oreg.al & 0x7f; |
| 47 | boot_params.screen_info.orig_video_page = page >> 8; | 44 | boot_params.screen_info.orig_video_page = oreg.bh; |
| 48 | } | 45 | } |
| 49 | 46 | ||
| 50 | /* | 47 | /* |
| @@ -257,7 +254,7 @@ static void restore_screen(void) | |||
| 257 | int y; | 254 | int y; |
| 258 | addr_t dst = 0; | 255 | addr_t dst = 0; |
| 259 | u16 *src = saved.data; | 256 | u16 *src = saved.data; |
| 260 | u16 ax, bx, dx; | 257 | struct biosregs ireg; |
| 261 | 258 | ||
| 262 | if (graphic_mode) | 259 | if (graphic_mode) |
| 263 | return; /* Can't restore onto a graphic mode */ | 260 | return; /* Can't restore onto a graphic mode */ |
| @@ -296,12 +293,11 @@ static void restore_screen(void) | |||
| 296 | } | 293 | } |
| 297 | 294 | ||
| 298 | /* Restore cursor position */ | 295 | /* Restore cursor position */ |
| 299 | ax = 0x0200; /* Set cursor position */ | 296 | initregs(&ireg); |
| 300 | bx = 0; /* Page number (<< 8) */ | 297 | ireg.ah = 0x02; /* Set cursor position */ |
| 301 | dx = (saved.cury << 8)+saved.curx; | 298 | ireg.dh = saved.cury; |
| 302 | asm volatile(INT10 | 299 | ireg.dl = saved.curx; |
| 303 | : "+a" (ax), "+b" (bx), "+d" (dx) | 300 | intcall(0x10, &ireg, NULL); |
| 304 | : : "ecx", "esi", "edi"); | ||
| 305 | } | 301 | } |
| 306 | #else | 302 | #else |
| 307 | #define save_screen() ((void)0) | 303 | #define save_screen() ((void)0) |
diff --git a/arch/x86/boot/video.h b/arch/x86/boot/video.h index ee63f5d14461..5bb174a997fc 100644 --- a/arch/x86/boot/video.h +++ b/arch/x86/boot/video.h | |||
| @@ -112,20 +112,6 @@ extern int force_x, force_y; /* Don't query the BIOS for cols/rows */ | |||
| 112 | extern int do_restore; /* Restore screen contents */ | 112 | extern int do_restore; /* Restore screen contents */ |
| 113 | extern int graphic_mode; /* Graphics mode with linear frame buffer */ | 113 | extern int graphic_mode; /* Graphics mode with linear frame buffer */ |
| 114 | 114 | ||
| 115 | /* | ||
| 116 | * int $0x10 is notorious for touching registers it shouldn't. | ||
| 117 | * gcc doesn't like %ebp being clobbered, so define it as a push/pop | ||
| 118 | * sequence here. | ||
| 119 | * | ||
| 120 | * A number of systems, including the original PC can clobber %bp in | ||
| 121 | * certain circumstances, like when scrolling. There exists at least | ||
| 122 | * one Trident video card which could clobber DS under a set of | ||
| 123 | * circumstances that we are unlikely to encounter (scrolling when | ||
| 124 | * using an extended graphics mode of more than 800x600 pixels), but | ||
| 125 | * it's cheap insurance to deal with that here. | ||
| 126 | */ | ||
| 127 | #define INT10 "pushl %%ebp; pushw %%ds; int $0x10; popw %%ds; popl %%ebp" | ||
| 128 | |||
| 129 | /* Accessing VGA indexed registers */ | 115 | /* Accessing VGA indexed registers */ |
| 130 | static inline u8 in_idx(u16 port, u8 index) | 116 | static inline u8 in_idx(u16 port, u8 index) |
| 131 | { | 117 | { |
