diff options
author | H. Peter Anvin <hpa@zytor.com> | 2007-07-16 14:58:24 -0400 |
---|---|---|
committer | H. Peter Anvin <hpa@zytor.com> | 2007-07-18 14:36:17 -0400 |
commit | 8c027ae2dcfa7b9130941a2a743c735c1fee04ee (patch) | |
tree | cf0f803ee6f3dcaa323f171b58da0bf0b70c9899 | |
parent | 7ad37df02c529525c4ad19035359af89d2d2a5bd (diff) |
[x86 setup] Save/restore DS around invocations of INT 10h
There exists at least one card, Trident TVGA8900CL (BIOS dated 1992/9/8)
which clobbers DS when "scrolling in an SVGA text mode of more than
800x600 pixels." Although we are extremely unlikely to run into that
situation, it is cheap insurance to save and restore DS, and it only adds
a grand total of 50 bytes to the total output.
Pointed out by Etienne Lorrain.
Cc: Etienne Lorrain <etienne_lorrain@yahoo.fr>
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-rw-r--r-- | arch/i386/boot/tty.c | 2 | ||||
-rw-r--r-- | arch/i386/boot/video.h | 9 |
2 files changed, 9 insertions, 2 deletions
diff --git a/arch/i386/boot/tty.c b/arch/i386/boot/tty.c index a8db78736b02..9c668aad3515 100644 --- a/arch/i386/boot/tty.c +++ b/arch/i386/boot/tty.c | |||
@@ -31,7 +31,7 @@ void __attribute__((section(".inittext"))) putchar(int ch) | |||
31 | 31 | ||
32 | /* int $0x10 is known to have bugs involving touching registers | 32 | /* int $0x10 is known to have bugs involving touching registers |
33 | it shouldn't. Be extra conservative... */ | 33 | it shouldn't. Be extra conservative... */ |
34 | asm volatile("pushal; int $0x10; popal" | 34 | asm volatile("pushal; pushw %%ds; int $0x10; popw %%ds; popal" |
35 | : : "b" (0x0007), "c" (0x0001), "a" (0x0e00|ch)); | 35 | : : "b" (0x0007), "c" (0x0001), "a" (0x0e00|ch)); |
36 | } | 36 | } |
37 | 37 | ||
diff --git a/arch/i386/boot/video.h b/arch/i386/boot/video.h index 29eca1710b2c..b92447d51213 100644 --- a/arch/i386/boot/video.h +++ b/arch/i386/boot/video.h | |||
@@ -117,8 +117,15 @@ extern int graphic_mode; /* Graphics mode with linear frame buffer */ | |||
117 | * int $0x10 is notorious for touching registers it shouldn't. | 117 | * int $0x10 is notorious for touching registers it shouldn't. |
118 | * gcc doesn't like %ebp being clobbered, so define it as a push/pop | 118 | * gcc doesn't like %ebp being clobbered, so define it as a push/pop |
119 | * sequence here. | 119 | * sequence here. |
120 | * | ||
121 | * A number of systems, including the original PC can clobber %bp in | ||
122 | * certain circumstances, like when scrolling. There exists at least | ||
123 | * one Trident video card which could clobber DS under a set of | ||
124 | * circumstances that we are unlikely to encounter (scrolling when | ||
125 | * using an extended graphics mode of more than 800x600 pixels), but | ||
126 | * it's cheap insurance to deal with that here. | ||
120 | */ | 127 | */ |
121 | #define INT10 "pushl %%ebp; int $0x10; popl %%ebp" | 128 | #define INT10 "pushl %%ebp; pushw %%ds; int $0x10; popw %%ds; popl %%ebp" |
122 | 129 | ||
123 | /* Accessing VGA indexed registers */ | 130 | /* Accessing VGA indexed registers */ |
124 | static inline u8 in_idx(u16 port, u8 index) | 131 | static inline u8 in_idx(u16 port, u8 index) |