aboutsummaryrefslogtreecommitdiffstats
path: root/arch/i386
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2007-08-22 19:28:01 -0400
committerH. Peter Anvin <hpa@zytor.com>2007-08-23 16:03:25 -0400
commitb015124e562a040f7faf361c72e8f5f457ac6cf5 (patch)
tree452f3fe6b9a7d2ef692e021a18f588490bc78441 /arch/i386
parentb377fd3982ad957c796758a90e2988401a884241 (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.h24
-rw-r--r--arch/i386/boot/cpucheck.c3
-rw-r--r--arch/i386/boot/edd.c6
-rw-r--r--arch/i386/boot/tty.c14
-rw-r--r--arch/i386/boot/video-vga.c12
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)
87static inline u16 fs(void) 87static 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)
98static inline u16 gs(void) 98static 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;
107static inline u8 rdfs8(addr_t addr) 107static 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}
113static inline u16 rdfs16(addr_t addr) 113static 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}
119static inline u32 rdfs32(addr_t addr) 119static 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)
139static inline u8 rdgs8(addr_t addr) 139static 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}
145static inline u16 rdgs16(addr_t addr) 145static 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}
151static inline u32 rdgs32(addr_t addr) 151static 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)
180static inline int memcmp_fs(const void *s1, addr_t s2, size_t len) 180static 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}
187static inline int memcmp_gs(const void *s1, addr_t s2, size_t len) 187static 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)
67int getchar(void) 67int 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)
75static int kbd_pending(void) 75static 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