summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThorsten Lockert <tholo@cvs.openbsd.org>1996-02-25 23:03:17 +0000
committerThorsten Lockert <tholo@cvs.openbsd.org>1996-02-25 23:03:17 +0000
commit915abd18d665696c222321f6c34870ebed9a5457 (patch)
tree8879e4bd855cc89da55753b81fb094b329021735
parentd9458b4cd30074b84a2c9949cbbf2aaecd954409 (diff)
Allow use of Pentium cycle counter for high-precision time keeping;
from FreeBSD
-rw-r--r--sys/arch/i386/i386/autoconf.c3
-rw-r--r--sys/arch/i386/i386/machdep.c10
-rw-r--r--sys/arch/i386/i386/microtime.s23
-rw-r--r--sys/arch/i386/include/cpu.h31
-rw-r--r--sys/arch/i386/isa/clock.c17
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()
{