diff options
author | H. Peter Anvin <hpa@zytor.com> | 2007-08-22 19:28:01 -0400 |
---|---|---|
committer | H. Peter Anvin <hpa@zytor.com> | 2007-08-23 16:03:25 -0400 |
commit | b015124e562a040f7faf361c72e8f5f457ac6cf5 (patch) | |
tree | 452f3fe6b9a7d2ef692e021a18f588490bc78441 /arch/i386 | |
parent | b377fd3982ad957c796758a90e2988401a884241 (diff) |
[x86 setup] Volatilize asm() statements
asm() statements need to be volatile when:
a. They have side effects (other than value returned).
b. When the value returned can vary over time.
c. When they have ordering constraints that cannot be expressed to gcc.
In particular, the keyboard and timer reads were violating constraint (b),
which resulted in the keyboard/timeout poll getting
loop-invariant-removed when compiling with gcc 4.2.0.
Thanks to an anonymous bug reporter for pointing this out.
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
Diffstat (limited to 'arch/i386')
-rw-r--r-- | arch/i386/boot/boot.h | 24 | ||||
-rw-r--r-- | arch/i386/boot/cpucheck.c | 3 | ||||
-rw-r--r-- | arch/i386/boot/edd.c | 6 | ||||
-rw-r--r-- | arch/i386/boot/tty.c | 14 | ||||
-rw-r--r-- | arch/i386/boot/video-vga.c | 12 |
5 files changed, 30 insertions, 29 deletions
diff --git a/arch/i386/boot/boot.h b/arch/i386/boot/boot.h index dec70c9b6050..20bab9431acb 100644 --- a/arch/i386/boot/boot.h +++ b/arch/i386/boot/boot.h | |||
@@ -87,7 +87,7 @@ static inline void set_fs(u16 seg) | |||
87 | static inline u16 fs(void) | 87 | static inline u16 fs(void) |
88 | { | 88 | { |
89 | u16 seg; | 89 | u16 seg; |
90 | asm("movw %%fs,%0" : "=rm" (seg)); | 90 | asm volatile("movw %%fs,%0" : "=rm" (seg)); |
91 | return seg; | 91 | return seg; |
92 | } | 92 | } |
93 | 93 | ||
@@ -98,7 +98,7 @@ static inline void set_gs(u16 seg) | |||
98 | static inline u16 gs(void) | 98 | static inline u16 gs(void) |
99 | { | 99 | { |
100 | u16 seg; | 100 | u16 seg; |
101 | asm("movw %%gs,%0" : "=rm" (seg)); | 101 | asm volatile("movw %%gs,%0" : "=rm" (seg)); |
102 | return seg; | 102 | return seg; |
103 | } | 103 | } |
104 | 104 | ||
@@ -107,19 +107,19 @@ typedef unsigned int addr_t; | |||
107 | static inline u8 rdfs8(addr_t addr) | 107 | static inline u8 rdfs8(addr_t addr) |
108 | { | 108 | { |
109 | u8 v; | 109 | u8 v; |
110 | asm("movb %%fs:%1,%0" : "=r" (v) : "m" (*(u8 *)addr)); | 110 | asm volatile("movb %%fs:%1,%0" : "=r" (v) : "m" (*(u8 *)addr)); |
111 | return v; | 111 | return v; |
112 | } | 112 | } |
113 | static inline u16 rdfs16(addr_t addr) | 113 | static inline u16 rdfs16(addr_t addr) |
114 | { | 114 | { |
115 | u16 v; | 115 | u16 v; |
116 | asm("movw %%fs:%1,%0" : "=r" (v) : "m" (*(u16 *)addr)); | 116 | asm volatile("movw %%fs:%1,%0" : "=r" (v) : "m" (*(u16 *)addr)); |
117 | return v; | 117 | return v; |
118 | } | 118 | } |
119 | static inline u32 rdfs32(addr_t addr) | 119 | static inline u32 rdfs32(addr_t addr) |
120 | { | 120 | { |
121 | u32 v; | 121 | u32 v; |
122 | asm("movl %%fs:%1,%0" : "=r" (v) : "m" (*(u32 *)addr)); | 122 | asm volatile("movl %%fs:%1,%0" : "=r" (v) : "m" (*(u32 *)addr)); |
123 | return v; | 123 | return v; |
124 | } | 124 | } |
125 | 125 | ||
@@ -139,19 +139,19 @@ static inline void wrfs32(u32 v, addr_t addr) | |||
139 | static inline u8 rdgs8(addr_t addr) | 139 | static inline u8 rdgs8(addr_t addr) |
140 | { | 140 | { |
141 | u8 v; | 141 | u8 v; |
142 | asm("movb %%gs:%1,%0" : "=r" (v) : "m" (*(u8 *)addr)); | 142 | asm volatile("movb %%gs:%1,%0" : "=r" (v) : "m" (*(u8 *)addr)); |
143 | return v; | 143 | return v; |
144 | } | 144 | } |
145 | static inline u16 rdgs16(addr_t addr) | 145 | static inline u16 rdgs16(addr_t addr) |
146 | { | 146 | { |
147 | u16 v; | 147 | u16 v; |
148 | asm("movw %%gs:%1,%0" : "=r" (v) : "m" (*(u16 *)addr)); | 148 | asm volatile("movw %%gs:%1,%0" : "=r" (v) : "m" (*(u16 *)addr)); |
149 | return v; | 149 | return v; |
150 | } | 150 | } |
151 | static inline u32 rdgs32(addr_t addr) | 151 | static inline u32 rdgs32(addr_t addr) |
152 | { | 152 | { |
153 | u32 v; | 153 | u32 v; |
154 | asm("movl %%gs:%1,%0" : "=r" (v) : "m" (*(u32 *)addr)); | 154 | asm volatile("movl %%gs:%1,%0" : "=r" (v) : "m" (*(u32 *)addr)); |
155 | return v; | 155 | return v; |
156 | } | 156 | } |
157 | 157 | ||
@@ -180,15 +180,15 @@ static inline int memcmp(const void *s1, const void *s2, size_t len) | |||
180 | static inline int memcmp_fs(const void *s1, addr_t s2, size_t len) | 180 | static inline int memcmp_fs(const void *s1, addr_t s2, size_t len) |
181 | { | 181 | { |
182 | u8 diff; | 182 | u8 diff; |
183 | asm("fs; repe; cmpsb; setnz %0" | 183 | asm volatile("fs; repe; cmpsb; setnz %0" |
184 | : "=qm" (diff), "+D" (s1), "+S" (s2), "+c" (len)); | 184 | : "=qm" (diff), "+D" (s1), "+S" (s2), "+c" (len)); |
185 | return diff; | 185 | return diff; |
186 | } | 186 | } |
187 | static inline int memcmp_gs(const void *s1, addr_t s2, size_t len) | 187 | static inline int memcmp_gs(const void *s1, addr_t s2, size_t len) |
188 | { | 188 | { |
189 | u8 diff; | 189 | u8 diff; |
190 | asm("gs; repe; cmpsb; setnz %0" | 190 | asm volatile("gs; repe; cmpsb; setnz %0" |
191 | : "=qm" (diff), "+D" (s1), "+S" (s2), "+c" (len)); | 191 | : "=qm" (diff), "+D" (s1), "+S" (s2), "+c" (len)); |
192 | return diff; | 192 | return diff; |
193 | } | 193 | } |
194 | 194 | ||
diff --git a/arch/i386/boot/cpucheck.c b/arch/i386/boot/cpucheck.c index 991e8ceae1de..e655a89c5510 100644 --- a/arch/i386/boot/cpucheck.c +++ b/arch/i386/boot/cpucheck.c | |||
@@ -96,7 +96,8 @@ static int has_fpu(void) | |||
96 | asm volatile("movl %0,%%cr0" : : "r" (cr0)); | 96 | asm volatile("movl %0,%%cr0" : : "r" (cr0)); |
97 | } | 97 | } |
98 | 98 | ||
99 | asm("fninit ; fnstsw %0 ; fnstcw %1" : "+m" (fsw), "+m" (fcw)); | 99 | asm volatile("fninit ; fnstsw %0 ; fnstcw %1" |
100 | : "+m" (fsw), "+m" (fcw)); | ||
100 | 101 | ||
101 | return fsw == 0 && (fcw & 0x103f) == 0x003f; | 102 | return fsw == 0 && (fcw & 0x103f) == 0x003f; |
102 | } | 103 | } |
diff --git a/arch/i386/boot/edd.c b/arch/i386/boot/edd.c index 82b5c846a194..bd138e442ec2 100644 --- a/arch/i386/boot/edd.c +++ b/arch/i386/boot/edd.c | |||
@@ -30,9 +30,9 @@ static int read_mbr(u8 devno, void *buf) | |||
30 | cx = 0x0001; /* Sector 0-0-1 */ | 30 | cx = 0x0001; /* Sector 0-0-1 */ |
31 | dx = devno; | 31 | dx = devno; |
32 | bx = (size_t)buf; | 32 | bx = (size_t)buf; |
33 | asm("pushfl; stc; int $0x13; setc %%al; popfl" | 33 | asm volatile("pushfl; stc; int $0x13; setc %%al; popfl" |
34 | : "+a" (ax), "+c" (cx), "+d" (dx), "+b" (bx) | 34 | : "+a" (ax), "+c" (cx), "+d" (dx), "+b" (bx) |
35 | : : "esi", "edi", "memory"); | 35 | : : "esi", "edi", "memory"); |
36 | 36 | ||
37 | return -(u8)ax; /* 0 or -1 */ | 37 | return -(u8)ax; /* 0 or -1 */ |
38 | } | 38 | } |
diff --git a/arch/i386/boot/tty.c b/arch/i386/boot/tty.c index 9c668aad3515..f3f14bd26371 100644 --- a/arch/i386/boot/tty.c +++ b/arch/i386/boot/tty.c | |||
@@ -54,9 +54,9 @@ static u8 gettime(void) | |||
54 | u16 ax = 0x0200; | 54 | u16 ax = 0x0200; |
55 | u16 cx, dx; | 55 | u16 cx, dx; |
56 | 56 | ||
57 | asm("int $0x1a" | 57 | asm volatile("int $0x1a" |
58 | : "+a" (ax), "=c" (cx), "=d" (dx) | 58 | : "+a" (ax), "=c" (cx), "=d" (dx) |
59 | : : "ebx", "esi", "edi"); | 59 | : : "ebx", "esi", "edi"); |
60 | 60 | ||
61 | return dx >> 8; | 61 | return dx >> 8; |
62 | } | 62 | } |
@@ -67,7 +67,7 @@ static u8 gettime(void) | |||
67 | int getchar(void) | 67 | int getchar(void) |
68 | { | 68 | { |
69 | u16 ax = 0; | 69 | u16 ax = 0; |
70 | asm("int $0x16" : "+a" (ax)); | 70 | asm volatile("int $0x16" : "+a" (ax)); |
71 | 71 | ||
72 | return ax & 0xff; | 72 | return ax & 0xff; |
73 | } | 73 | } |
@@ -75,9 +75,9 @@ int getchar(void) | |||
75 | static int kbd_pending(void) | 75 | static int kbd_pending(void) |
76 | { | 76 | { |
77 | u8 pending; | 77 | u8 pending; |
78 | asm("int $0x16; setnz %0" | 78 | asm volatile("int $0x16; setnz %0" |
79 | : "=rm" (pending) | 79 | : "=rm" (pending) |
80 | : "a" (0x0100)); | 80 | : "a" (0x0100)); |
81 | return pending; | 81 | return pending; |
82 | } | 82 | } |
83 | 83 | ||
diff --git a/arch/i386/boot/video-vga.c b/arch/i386/boot/video-vga.c index 700d09a9c9b3..d660e608cd58 100644 --- a/arch/i386/boot/video-vga.c +++ b/arch/i386/boot/video-vga.c | |||
@@ -47,16 +47,16 @@ static u8 vga_set_basic_mode(void) | |||
47 | 47 | ||
48 | #ifdef CONFIG_VIDEO_400_HACK | 48 | #ifdef CONFIG_VIDEO_400_HACK |
49 | if (adapter >= ADAPTER_VGA) { | 49 | if (adapter >= ADAPTER_VGA) { |
50 | asm(INT10 | 50 | asm volatile(INT10 |
51 | : : "a" (0x1202), "b" (0x0030) | 51 | : : "a" (0x1202), "b" (0x0030) |
52 | : "ecx", "edx", "esi", "edi"); | 52 | : "ecx", "edx", "esi", "edi"); |
53 | } | 53 | } |
54 | #endif | 54 | #endif |
55 | 55 | ||
56 | ax = 0x0f00; | 56 | ax = 0x0f00; |
57 | asm(INT10 | 57 | asm volatile(INT10 |
58 | : "+a" (ax) | 58 | : "+a" (ax) |
59 | : : "ebx", "ecx", "edx", "esi", "edi"); | 59 | : : "ebx", "ecx", "edx", "esi", "edi"); |
60 | 60 | ||
61 | mode = (u8)ax; | 61 | mode = (u8)ax; |
62 | 62 | ||