Skip to content

Commit

Permalink
[x86 setup] Volatilize asm() statements
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
H. Peter Anvin committed Aug 23, 2007
1 parent b377fd3 commit b015124
Show file tree
Hide file tree
Showing 5 changed files with 30 additions and 29 deletions.
24 changes: 12 additions & 12 deletions arch/i386/boot/boot.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ static inline void set_fs(u16 seg)
static inline u16 fs(void)
{
u16 seg;
asm("movw %%fs,%0" : "=rm" (seg));
asm volatile("movw %%fs,%0" : "=rm" (seg));
return seg;
}

Expand All @@ -98,7 +98,7 @@ static inline void set_gs(u16 seg)
static inline u16 gs(void)
{
u16 seg;
asm("movw %%gs,%0" : "=rm" (seg));
asm volatile("movw %%gs,%0" : "=rm" (seg));
return seg;
}

Expand All @@ -107,19 +107,19 @@ typedef unsigned int addr_t;
static inline u8 rdfs8(addr_t addr)
{
u8 v;
asm("movb %%fs:%1,%0" : "=r" (v) : "m" (*(u8 *)addr));
asm volatile("movb %%fs:%1,%0" : "=r" (v) : "m" (*(u8 *)addr));
return v;
}
static inline u16 rdfs16(addr_t addr)
{
u16 v;
asm("movw %%fs:%1,%0" : "=r" (v) : "m" (*(u16 *)addr));
asm volatile("movw %%fs:%1,%0" : "=r" (v) : "m" (*(u16 *)addr));
return v;
}
static inline u32 rdfs32(addr_t addr)
{
u32 v;
asm("movl %%fs:%1,%0" : "=r" (v) : "m" (*(u32 *)addr));
asm volatile("movl %%fs:%1,%0" : "=r" (v) : "m" (*(u32 *)addr));
return v;
}

Expand All @@ -139,19 +139,19 @@ static inline void wrfs32(u32 v, addr_t addr)
static inline u8 rdgs8(addr_t addr)
{
u8 v;
asm("movb %%gs:%1,%0" : "=r" (v) : "m" (*(u8 *)addr));
asm volatile("movb %%gs:%1,%0" : "=r" (v) : "m" (*(u8 *)addr));
return v;
}
static inline u16 rdgs16(addr_t addr)
{
u16 v;
asm("movw %%gs:%1,%0" : "=r" (v) : "m" (*(u16 *)addr));
asm volatile("movw %%gs:%1,%0" : "=r" (v) : "m" (*(u16 *)addr));
return v;
}
static inline u32 rdgs32(addr_t addr)
{
u32 v;
asm("movl %%gs:%1,%0" : "=r" (v) : "m" (*(u32 *)addr));
asm volatile("movl %%gs:%1,%0" : "=r" (v) : "m" (*(u32 *)addr));
return v;
}

Expand Down Expand Up @@ -180,15 +180,15 @@ static inline int memcmp(const void *s1, const void *s2, size_t len)
static inline int memcmp_fs(const void *s1, addr_t s2, size_t len)
{
u8 diff;
asm("fs; repe; cmpsb; setnz %0"
: "=qm" (diff), "+D" (s1), "+S" (s2), "+c" (len));
asm volatile("fs; repe; cmpsb; setnz %0"
: "=qm" (diff), "+D" (s1), "+S" (s2), "+c" (len));
return diff;
}
static inline int memcmp_gs(const void *s1, addr_t s2, size_t len)
{
u8 diff;
asm("gs; repe; cmpsb; setnz %0"
: "=qm" (diff), "+D" (s1), "+S" (s2), "+c" (len));
asm volatile("gs; repe; cmpsb; setnz %0"
: "=qm" (diff), "+D" (s1), "+S" (s2), "+c" (len));
return diff;
}

Expand Down
3 changes: 2 additions & 1 deletion arch/i386/boot/cpucheck.c
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,8 @@ static int has_fpu(void)
asm volatile("movl %0,%%cr0" : : "r" (cr0));
}

asm("fninit ; fnstsw %0 ; fnstcw %1" : "+m" (fsw), "+m" (fcw));
asm volatile("fninit ; fnstsw %0 ; fnstcw %1"
: "+m" (fsw), "+m" (fcw));

return fsw == 0 && (fcw & 0x103f) == 0x003f;
}
Expand Down
6 changes: 3 additions & 3 deletions arch/i386/boot/edd.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,9 @@ static int read_mbr(u8 devno, void *buf)
cx = 0x0001; /* Sector 0-0-1 */
dx = devno;
bx = (size_t)buf;
asm("pushfl; stc; int $0x13; setc %%al; popfl"
: "+a" (ax), "+c" (cx), "+d" (dx), "+b" (bx)
: : "esi", "edi", "memory");
asm volatile("pushfl; stc; int $0x13; setc %%al; popfl"
: "+a" (ax), "+c" (cx), "+d" (dx), "+b" (bx)
: : "esi", "edi", "memory");

return -(u8)ax; /* 0 or -1 */
}
Expand Down
14 changes: 7 additions & 7 deletions arch/i386/boot/tty.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,9 @@ static u8 gettime(void)
u16 ax = 0x0200;
u16 cx, dx;

asm("int $0x1a"
: "+a" (ax), "=c" (cx), "=d" (dx)
: : "ebx", "esi", "edi");
asm volatile("int $0x1a"
: "+a" (ax), "=c" (cx), "=d" (dx)
: : "ebx", "esi", "edi");

return dx >> 8;
}
Expand All @@ -67,17 +67,17 @@ static u8 gettime(void)
int getchar(void)
{
u16 ax = 0;
asm("int $0x16" : "+a" (ax));
asm volatile("int $0x16" : "+a" (ax));

return ax & 0xff;
}

static int kbd_pending(void)
{
u8 pending;
asm("int $0x16; setnz %0"
: "=rm" (pending)
: "a" (0x0100));
asm volatile("int $0x16; setnz %0"
: "=rm" (pending)
: "a" (0x0100));
return pending;
}

Expand Down
12 changes: 6 additions & 6 deletions arch/i386/boot/video-vga.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,16 +47,16 @@ static u8 vga_set_basic_mode(void)

#ifdef CONFIG_VIDEO_400_HACK
if (adapter >= ADAPTER_VGA) {
asm(INT10
: : "a" (0x1202), "b" (0x0030)
: "ecx", "edx", "esi", "edi");
asm volatile(INT10
: : "a" (0x1202), "b" (0x0030)
: "ecx", "edx", "esi", "edi");
}
#endif

ax = 0x0f00;
asm(INT10
: "+a" (ax)
: : "ebx", "ecx", "edx", "esi", "edi");
asm volatile(INT10
: "+a" (ax)
: : "ebx", "ecx", "edx", "esi", "edi");

mode = (u8)ax;

Expand Down

0 comments on commit b015124

Please sign in to comment.