From d6a2825ae408609301329df4abbdb22fb324ecc1 Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Fri, 10 Jul 1998 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1998-07-10 --- ip/devip.c | 2 +- pc/archgeneric.c | 38 ++++++++++++++++++++++++++++++++++++++ pc/clock.c | 1 + pc/dat.h | 1 + pc/fns.h | 1 + pc/i8253.c | 14 ++++++++++++++ port/devcons.c | 31 +++++++++++++++++++++++++++++++ port/portfns.h | 1 + 8 files changed, 88 insertions(+), 1 deletion(-) diff --git a/ip/devip.c b/ip/devip.c index 7814d43eab2f0597f133d8e3699e597b826d9a0e..bfbc364f06864db29d91d4e18d8569a58d11624b 100644 --- a/ip/devip.c +++ b/ip/devip.c @@ -520,7 +520,7 @@ ipread(Chan *ch, void *a, long n, vlong off) Conv *c; Proto *x; char *buf, *p; - long m, rv; + long rv; Fs *f; ulong offset = off; diff --git a/pc/archgeneric.c b/pc/archgeneric.c index d2945c0cd4e557be9eb17a9b43ffea61a44d517e..561b33b13e17505b3734354bd5a3f63d33002a4b 100644 --- a/pc/archgeneric.c +++ b/pc/archgeneric.c @@ -17,6 +17,8 @@ nop(void) } void (*coherence)(void) = nop; +void cycletimerinit(void); +uvlong cycletimer(uvlong*); PCArch* arch; extern PCArch* knownarch[]; @@ -32,6 +34,8 @@ PCArch archgeneric = { i8259enable, /* intrenable */ i8253enable, /* clockenable */ + + i8253read, /* read the standard timer */ }; typedef struct { @@ -185,6 +189,12 @@ archinit(void) arch->intrenable = archgeneric.intrenable; } + /* pick the better timer */ + if(X86FAMILY(m->cpuidax) >= 5){ + cycletimerinit(); + arch->fastclock = cycletimer; + } + /* * Decide whether to use copy-on-reference (386 and mp). */ @@ -194,3 +204,31 @@ archinit(void) if(X86FAMILY(m->cpuidax) == 6 /*&& conf.nmach > 1*/) coherence = wbflush; } + +static uvlong fasthz; + +void +cycletimerinit(void) +{ + fasthz = 1000000LL*m->cpumhz; +} + +/* + * return the most precice clock we have + */ +uvlong +cycletimer(uvlong *hz) +{ + uvlong tsc; + + rdmsr(0x10, (vlong*)&tsc); + if(hz != nil) + *hz = fasthz; + return tsc; +} + +uvlong +fastticks(uvlong *hz) +{ + return (*arch->fastclock)(hz); +} diff --git a/pc/clock.c b/pc/clock.c index 0e21e510bc328df03af8e492ead8d432ba5d9847..3954a5bec32f4a8df34a225f291b2d580205966a 100644 --- a/pc/clock.c +++ b/pc/clock.c @@ -88,3 +88,4 @@ microdelay(int microsecs) microsecs = 1; aamloop(microsecs); } + diff --git a/pc/dat.h b/pc/dat.h index b4d22fed551cc980806dcef5588a46ea9d7fd1c1..957c2325564254d62c437a7a139e1d431f624d50 100644 --- a/pc/dat.h +++ b/pc/dat.h @@ -221,6 +221,7 @@ struct PCArch int (*intrenable)(int, int, Irqctl*); void (*clockenable)(void); + uvlong (*fastclock)(uvlong*); }; /* diff --git a/pc/fns.h b/pc/fns.h index 4a47e89f539ddbf1f5b22b3e760db5b36e692c53..bd3ec3c5f0ad9c9ffbb1e093f424baaf1a1bbd5b 100644 --- a/pc/fns.h +++ b/pc/fns.h @@ -36,6 +36,7 @@ void i8042auxenable(void (*)(int, int)); void i8042reset(void); void i8253init(int); void i8253enable(void); +uvlong i8253read(uvlong*); void i8259init(void); int i8259enable(int, int, Irqctl*); void idle(void); diff --git a/pc/i8253.c b/pc/i8253.c index 0326a6551d002f90f8676db6d91a05b09ab826e7..0ce67e8064d3dc371175e5c96cf6e880a1d50049 100644 --- a/pc/i8253.c +++ b/pc/i8253.c @@ -98,3 +98,17 @@ i8253enable(void) { intrenable(VectorCLOCK, clockintr, 0, BUSUNKNOWN); } + +Lock i8253lock; + +/* + * return time elapsed since clock start in + * 10ths of nanoseconds + */ +uvlong +i8253read(uvlong *hz) +{ + if(hz) + *hz = HZ; + return m->ticks; +} diff --git a/port/devcons.c b/port/devcons.c index de7c8f920573db5a65627031145060f752049349..5fa0c598fe6914e9aedcbf80692ebf9fe0e43e60 100644 --- a/port/devcons.c +++ b/port/devcons.c @@ -345,6 +345,7 @@ enum{ Qconsctl, Qcputime, Qdrivers, + Qfastclock, Qhz, Qkey, Qhostdomain, @@ -373,6 +374,7 @@ static Dirtab consdir[]={ "consctl", {Qconsctl}, 0, 0220, "cputime", {Qcputime}, 6*NUMSIZE, 0444, "drivers", {Qdrivers}, 0, 0644, + "fastclock", {Qfastclock}, 4*NUMSIZE, 0444, "hostdomain", {Qhostdomain}, DOMLEN, 0664, "hostowner", {Qhostowner}, NAMELEN, 0664, "hz", {Qhz}, NUMSIZE, 0666, @@ -400,6 +402,21 @@ seconds(void) return boottime + TK2SEC(MACHP(0)->ticks); } +int +readvlnum(ulong off, char *buf, ulong n, uvlong val, int size) +{ + char tmp[64]; + + snprint(tmp, sizeof(tmp), "%*.0ulld", size-1, val); + tmp[size-1] = ' '; + if(off >= size) + return 0; + if(off+n > size) + n = size-off; + memmove(buf, tmp+off, n); + return n; +} + int readnum(ulong off, char *buf, ulong n, ulong val, int size) { @@ -515,6 +532,7 @@ consread(Chan *c, void *buf, long n, vlong off) char *cbuf = buf; int ch, i, k, id, eol; vlong offset = off; + uvlong ticks, fasthz; if(n <= 0) return n; @@ -623,6 +641,19 @@ consread(Chan *c, void *buf, long n, vlong off) memmove(buf, tmp+k, n); return n; + case Qfastclock: + ticks = fastticks(&fasthz); + + k = offset; + if(k >= 4*NUMSIZE) + return 0; + if(k+n > 4*NUMSIZE) + n = 4*NUMSIZE - k; + readvlnum(0, tmp, 2*NUMSIZE, ticks, 2*NUMSIZE); + readvlnum(0, tmp+2*NUMSIZE, 2*NUMSIZE, fasthz, 2*NUMSIZE); + memmove(buf, tmp+k, n); + return n; + case Qkey: return keyread(buf, n, offset); diff --git a/port/portfns.h b/port/portfns.h index 4b442324d11e0d60af37e550631eb2439af36658..7a1a033e8cbb02e9b4b052cda42ae786cfe82d48 100644 --- a/port/portfns.h +++ b/port/portfns.h @@ -91,6 +91,7 @@ void error(char*); long execregs(ulong, ulong, ulong); void exhausted(char*); void exit(int); +uvlong fastticks(uvlong*); int fault(ulong, int); void fdclose(int, int); Chan* fdtochan(int, int, int, int);