diff options
author | Michael Shalayeff <mickey@cvs.openbsd.org> | 1998-05-13 19:49:26 +0000 |
---|---|---|
committer | Michael Shalayeff <mickey@cvs.openbsd.org> | 1998-05-13 19:49:26 +0000 |
commit | 4004b43497a804047215084c5ccd26a0c08ec0ce (patch) | |
tree | 071750dd260c1e664b110c84a9b4234e1e351921 /sys/arch | |
parent | ac2c89bf61167c1418043fdb45c252c1e3e62077 (diff) |
making kernel, drinking LI tea and writing an opus magnum enspired
by the freebsd commit logs:
first of all i should state that we are the only os that uses pentium
counters in their microtime (freebsd, netbsd, etc checked).
the bug fixed derives from the fact that #UD (divide by zero)
is generated in two cases:
a) divide by zero;
b) divide overflow.
so, the later case was the one causing panics on reboot.
due to the divl insn design in the intel processors, the possible
sizes of operands and results are: 16/8=8,8; 32/16=16,16; 64/32=32,32.
the division will generate an #UD exception when the quotient
won't fit into result, that is 32bit in our case (64bit is divided on 32bit).
problem solved by normalizing the dividend by the divisor, so the quotient
would not result a divide overflow.
tested by: mickey, gene, mickey.
talked over: mickey, gene, marc, maillists, mickey.
Diffstat (limited to 'sys/arch')
-rw-r--r-- | sys/arch/i386/i386/microtime.s | 21 |
1 files changed, 15 insertions, 6 deletions
diff --git a/sys/arch/i386/i386/microtime.s b/sys/arch/i386/i386/microtime.s index 27b417abe52..6234c91f9ae 100644 --- a/sys/arch/i386/i386/microtime.s +++ b/sys/arch/i386/i386/microtime.s @@ -1,4 +1,4 @@ -/* $OpenBSD: microtime.s,v 1.10 1997/12/30 23:35:19 mickey Exp $ */ +/* $OpenBSD: microtime.s,v 1.11 1998/05/13 19:49:25 mickey Exp $ */ /* $NetBSD: microtime.s,v 1.16 1995/04/17 12:06:47 cgd Exp $ */ /*- @@ -57,6 +57,7 @@ ENTRY(microtime) #endif movb $(TIMER_SEL0|TIMER_LATCH),%al + pushfl cli # disable interrupts outb %al,$TIMER_MODE # latch timer 0's counter @@ -125,7 +126,7 @@ common_microtime: movl _time,%edx # get time.tv_sec addl _time+4,%eax # add time.tv_usec - sti # enable interrupts + popfl # enable interrupts cmpl $1000000,%eax # carry in timeval? jb 3f @@ -147,14 +148,22 @@ common_microtime: #if defined (NTP) .align 2, 0x90 pentium_microtime: + pushfl cli .byte 0x0f, 0x31 # RDTSC subl _pentium_base_tsc,%eax sbbl _pentium_base_tsc+4,%edx - orl %ecx, %ecx - jnz 1f - incl %ecx -1: divl %ecx # convert to usec + /* + * correct the high word first so we won't + * receive a result overflow aka div/0 fault + */ + pushl %eax + movl %edx, %eax + shll $16, %edx + divw %cx + movzwl %dx, %edx + popl %eax + divl %ecx jmp common_microtime #endif #endif |