diff options
author | Thorsten Lockert <tholo@cvs.openbsd.org> | 1996-02-25 23:03:17 +0000 |
---|---|---|
committer | Thorsten Lockert <tholo@cvs.openbsd.org> | 1996-02-25 23:03:17 +0000 |
commit | 915abd18d665696c222321f6c34870ebed9a5457 (patch) | |
tree | 8879e4bd855cc89da55753b81fb094b329021735 | |
parent | d9458b4cd30074b84a2c9949cbbf2aaecd954409 (diff) |
Allow use of Pentium cycle counter for high-precision time keeping;
from FreeBSD
-rw-r--r-- | sys/arch/i386/i386/autoconf.c | 3 | ||||
-rw-r--r-- | sys/arch/i386/i386/machdep.c | 10 | ||||
-rw-r--r-- | sys/arch/i386/i386/microtime.s | 23 | ||||
-rw-r--r-- | sys/arch/i386/include/cpu.h | 31 | ||||
-rw-r--r-- | sys/arch/i386/isa/clock.c | 17 |
5 files changed, 78 insertions, 6 deletions
diff --git a/sys/arch/i386/i386/autoconf.c b/sys/arch/i386/i386/autoconf.c index a1ab9c17e31..b02546e3577 100644 --- a/sys/arch/i386/i386/autoconf.c +++ b/sys/arch/i386/i386/autoconf.c @@ -70,9 +70,6 @@ extern int cold; /* cold start flag initialized in locore.s */ */ configure() { - - startrtclock(); - config_rootfound("isa", NULL); config_rootfound("eisa", NULL); config_rootfound("pci", NULL); diff --git a/sys/arch/i386/i386/machdep.c b/sys/arch/i386/i386/machdep.c index 46a1e5bf534..9139f31dfd8 100644 --- a/sys/arch/i386/i386/machdep.c +++ b/sys/arch/i386/i386/machdep.c @@ -165,6 +165,7 @@ cpu_startup() msgbufmapped = 1; printf(version); + startrtclock(); identifycpu(); printf("real mem = %d\n", ctob(physmem)); @@ -390,7 +391,14 @@ identifycpu() break; } strcat(cpu_model, "-class CPU)"); - printf("%s\n", cpu_model); /* cpu speed would be nice, but how? */ + printf("%s", cpu_model); /* cpu speed would be nice, but how? */ +#if defined(I586_CPU) + if (cpu_class == CPUCLASS_586) { + calibrate_cyclecounter(); + printf(" %d MHz", pentium_mhz); + } +#endif + printf("\n"); /* * Now that we have told the user what they have, diff --git a/sys/arch/i386/i386/microtime.s b/sys/arch/i386/i386/microtime.s index 95ef8dc1a8a..fc2f33ab268 100644 --- a/sys/arch/i386/i386/microtime.s +++ b/sys/arch/i386/i386/microtime.s @@ -46,13 +46,21 @@ */ #ifndef HZ ENTRY(microtime) - cli # disable interrupts +#ifdef I586_CPU + movl _pentium_mhz, %ecx + testl %ecx, %ecx + jne pentium_microtime +#else + xorl %ecx,%ecx +#endif movb $(TIMER_SEL0|TIMER_LATCH),%al + + cli # disable interrupts + outb %al,$TIMER_MODE # latch timer 0's counter # Read counter value into ecx, LSB first - xorl %ecx,%ecx inb $TIMER_CNTR0,%al movb %al,%cl inb $TIMER_CNTR0,%al @@ -111,6 +119,7 @@ ENTRY(microtime) leal (%edx,%eax,8),%eax # a = 8a + d = 3433d shrl $12,%eax # a = a/4096 = 3433d/4096 +common_microtime: movl _time,%edx # get time.tv_sec addl _time+4,%eax # add time.tv_usec @@ -126,4 +135,14 @@ ENTRY(microtime) movl %eax,4(%ecx) # tvp->tv_usec = usec ret + +#ifdef I586_CPU + .align 2, 0x90 +pentium_microtime: + cli + .byte 0x0f, 0x31 # RDTSC + divl %ecx # convert to usec + jmp common_microtime +#endif + #endif diff --git a/sys/arch/i386/include/cpu.h b/sys/arch/i386/include/cpu.h index b8fcdd48720..6d6c439e6ac 100644 --- a/sys/arch/i386/include/cpu.h +++ b/sys/arch/i386/include/cpu.h @@ -94,6 +94,34 @@ int want_resched; /* resched() was called */ */ #define DELAY(x) delay(x) +#ifdef I586_CPU +/* + * High resolution clock support (Pentium only) + */ +#define CPU_CLOCKUPDATE(otime, ntime) \ + do { \ + if (pentium_mhz) { \ + __asm __volatile("cli\n" \ + "movl (%2), %%eax\n" \ + "movl %%eax, (%1)\n" \ + "movl 4(%2), %%eax\n" \ + "movl %%eax, 4(%1)\n" \ + "movl $0x10, %%ecx\n" \ + "xorl %%eax, %%eax\n" \ + "movl %%eax, %%edx\n" \ + ".byte 0xf, 0x30\n" \ + "sti\n" \ + "#%0%1%2" \ + : "=m" (*otime) \ + : "c" (otime), "b" (ntime) \ + : "ax", "cx", "dx"); \ + } \ + else { \ + *(otime) = *(ntime); \ + } \ + } while (0) +#endif + /* * pull in #defines for kinds of processors */ @@ -108,6 +136,9 @@ struct cpu_nameclass { extern int cpu; extern int cpu_class; extern struct cpu_nameclass i386_cpus[]; +#ifdef I586_CPU +extern int pentium_mhz; +#endif #endif /* diff --git a/sys/arch/i386/isa/clock.c b/sys/arch/i386/isa/clock.c index 5cacb8cc9fc..2833d2f2f10 100644 --- a/sys/arch/i386/isa/clock.c +++ b/sys/arch/i386/isa/clock.c @@ -107,6 +107,10 @@ WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. void spinwait __P((int)); +#ifdef I586_CPU +int pentium_mhz; +#endif + #define SECMIN ((unsigned)60) /* seconds per minute */ #define SECHOUR ((unsigned)(60*SECMIN)) /* seconds per hour */ #define SECDAY ((unsigned)(24*SECHOUR)) /* seconds per day */ @@ -303,6 +307,19 @@ findcpuspeed() delaycount = (FIRST_GUESS * TIMER_DIV(1000)) / (0xffff-remainder); } +#ifdef I586_CPU +void +calibrate_cyclecounter() +{ + unsigned long long count, last_count; + + __asm __volatile(".byte 0xf, 0x31" : "=A" (last_count)); + delay(1000000); + __asm __volatile(".byte 0xf, 0x31" : "=A" (count)); + pentium_mhz = ((count - last_count) + 500000) / 1000000; +} +#endif + void cpu_initclocks() { |