Finish moving the kernel from tsc_freq (32 bits) to tsc_frequency (64 bits).
authorMatthew Dillon <dillon@dragonflybsd.org>
Sat, 10 May 2008 17:24:12 +0000 (17:24 +0000)
committerMatthew Dillon <dillon@dragonflybsd.org>
Sat, 10 May 2008 17:24:12 +0000 (17:24 +0000)
Add sysctls to access hw.tsc_present and hw.tsc_frequency

Implement TSC support in the vkernel.

12 files changed:
sys/emulation/linux/i386/linprocfs/linprocfs_misc.c
sys/net/altq/altq_subr.c
sys/net/altq/altq_var.h
sys/platform/pc32/i386/identcpu.c
sys/platform/pc32/i386/perfmon.c
sys/platform/pc32/include/clock.h
sys/platform/pc32/isa/clock.c
sys/platform/pc32/isa/prof_machdep.c
sys/platform/pc64/include/clock.h
sys/platform/vkernel/include/clock.h
sys/platform/vkernel/platform/init.c
sys/platform/vkernel/platform/systimer.c

index 715c223..7b41dcd 100644 (file)
@@ -39,7 +39,7 @@
  *     @(#)procfs_status.c     8.4 (Berkeley) 6/15/94
  *
  * $FreeBSD: src/sys/i386/linux/linprocfs/linprocfs_misc.c,v 1.3.2.8 2001/06/25 19:46:47 pirzyk Exp $
- * $DragonFly: src/sys/emulation/linux/i386/linprocfs/linprocfs_misc.c,v 1.18 2007/02/18 16:15:23 corecode Exp $
+ * $DragonFly: src/sys/emulation/linux/i386/linprocfs/linprocfs_misc.c,v 1.19 2008/05/10 17:24:05 dillon Exp $
  */
 
 #include <sys/param.h>
@@ -233,10 +233,10 @@ linprocfs_docpuinfo(struct proc *curp, struct proc *p, struct pfsnode *pfs,
                ps += ksprintf(ps,
                        "cpu MHz\t\t: %d.%02d\n"
                        "bogomips\t: %d.%02d\n",
-                        (tsc_freq + 4999) / 1000000,
-                        ((tsc_freq + 4999) / 10000) % 100,
-                        (tsc_freq + 4999) / 1000000,
-                        ((tsc_freq + 4999) / 10000) % 100);
+                        (int)((tsc_frequency + 4999) / 1000000),
+                        (int)((tsc_frequency + 4999) / 10000) % 100,
+                        (int)((tsc_frequency + 4999) / 1000000),
+                        (int)((tsc_frequency + 4999) / 10000) % 100);
         }
         
        return (uiomove_frombuf(psbuf, ps - psbuf, uio));
index fd9a15e..7de22fb 100644 (file)
@@ -1,5 +1,5 @@
 /*     $KAME: altq_subr.c,v 1.23 2004/04/20 16:10:06 itojun Exp $      */
-/*     $DragonFly: src/sys/net/altq/altq_subr.c,v 1.10 2008/04/06 18:58:15 dillon Exp $ */
+/*     $DragonFly: src/sys/net/altq/altq_subr.c,v 1.11 2008/05/10 17:24:06 dillon Exp $ */
 
 /*
  * Copyright (C) 1997-2003
@@ -65,7 +65,7 @@
 
 /* machine dependent clock related includes */
 #if defined(__i386__)
-#include <machine/clock.h>             /* for tsc_freq */
+#include <machine/clock.h>             /* for tsc_frequency */
 #include <machine/md_var.h>            /* for cpu_feature */
 #include <machine/specialreg.h>                /* for CPUID_TSC */
 #endif /* __i386__ */
@@ -729,7 +729,7 @@ write_dsfield(struct mbuf *m, struct altq_pktattr *pktattr, uint8_t dsfield)
 #define        MACHCLK_SHIFT   8
 
 int machclk_usepcc;
-uint32_t machclk_freq = 0;
+uint64_t machclk_freq = 0;
 uint32_t machclk_per_tick = 0;
 
 void
@@ -751,10 +751,10 @@ init_machclk(void)
 
        if (machclk_usepcc == 0) {
                /* emulate 256MHz using microtime() */
-               machclk_freq = 1000000 << MACHCLK_SHIFT;
+               machclk_freq = 1000000LLU << MACHCLK_SHIFT;
                machclk_per_tick = machclk_freq / hz;
 #ifdef ALTQ_DEBUG
-               kprintf("altq: emulate %uHz cpu clock\n", machclk_freq);
+               kprintf("altq: emulate %lluHz cpu clock\n", machclk_freq);
 #endif
                return;
        }
@@ -763,10 +763,9 @@ init_machclk(void)
         * if the clock frequency (of Pentium TSC or Alpha PCC) is
         * accessible, just use it.
         */
-#ifdef __i386__
-       machclk_freq = tsc_freq;
-#else
-#error "machclk_freq interface not implemented"
+#if _RDTSC_SUPPORTED
+       if (cpu_feature & CPUID_TSC)
+               machclk_freq = (uint64_t)tsc_frequency;
 #endif
 
        /*
@@ -787,13 +786,13 @@ init_machclk(void)
                diff = (uint64_t)(tv_end.tv_sec - tv_start.tv_sec) * 1000000
                    + tv_end.tv_usec - tv_start.tv_usec;
                if (diff != 0)
-                       machclk_freq = (u_int)((end - start) * 1000000 / diff);
+                       machclk_freq = (end - start) * 1000000 / diff;
        }
 
        machclk_per_tick = machclk_freq / hz;
 
 #ifdef ALTQ_DEBUG
-       kprintf("altq: CPU clock: %uHz\n", machclk_freq);
+       kprintf("altq: CPU clock: %lluHz\n", machclk_freq);
 #endif
 }
 
@@ -803,7 +802,7 @@ read_machclk(void)
        uint64_t val;
 
        if (machclk_usepcc) {
-#if defined(__i386__)
+#ifdef _RDTSC_SUPPORTED_
                val = rdtsc();
 #else
                panic("read_machclk");
index 6ffebc7..d39e16f 100644 (file)
@@ -1,5 +1,5 @@
 /*     $KAME: altq_var.h,v 1.17 2004/04/20 05:09:08 kjc Exp $  */
-/*     $DragonFly: src/sys/net/altq/altq_var.h,v 1.3 2008/04/06 18:58:15 dillon Exp $ */
+/*     $DragonFly: src/sys/net/altq/altq_var.h,v 1.4 2008/05/10 17:24:06 dillon Exp $ */
 
 /*
  * Copyright (C) 1998-2003
@@ -51,7 +51,7 @@ MALLOC_DECLARE(M_ALTQ);
  * a 64bit high resolution time counter.
  */
 extern int     machclk_usepcc;
-extern uint32_t        machclk_freq;
+extern uint64_t        machclk_freq;
 extern uint32_t        machclk_per_tick;
 
 void           init_machclk(void);
index 70120c2..4f7f4a2 100644 (file)
@@ -39,7 +39,7 @@
  *
  *     from: Id: machdep.c,v 1.193 1996/06/18 01:22:04 bde Exp
  * $FreeBSD: src/sys/i386/i386/identcpu.c,v 1.80.2.15 2003/04/11 17:06:41 jhb Exp $
- * $DragonFly: src/sys/platform/pc32/i386/identcpu.c,v 1.20 2008/05/06 10:05:02 sephe Exp $
+ * $DragonFly: src/sys/platform/pc32/i386/identcpu.c,v 1.21 2008/05/10 17:24:07 dillon Exp $
  */
 
 #include "opt_cpu.h"
@@ -609,16 +609,16 @@ printcpuinfo(void)
 #if defined(I586_CPU)
        case CPUCLASS_586:
                kprintf("%d.%02d-MHz ",
-                      (tsc_freq + 4999) / 1000000,
-                      ((tsc_freq + 4999) / 10000) % 100);
+                      (int)((tsc_frequency + 4999) / 1000000),
+                      (int)((tsc_frequency + 4999) / 10000) % 100);
                kprintf("586");
                break;
 #endif
 #if defined(I686_CPU)
        case CPUCLASS_686:
                kprintf("%d.%02d-MHz ",
-                      (tsc_freq + 4999) / 1000000,
-                      ((tsc_freq + 4999) / 10000) % 100);
+                      ((int)(tsc_frequency + 4999) / 1000000),
+                      (int)((tsc_frequency + 4999) / 10000) % 100);
                kprintf("686");
                break;
 #endif
index f7093d4..04a1474 100644 (file)
@@ -27,7 +27,7 @@
  * SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/i386/i386/perfmon.c,v 1.21 1999/09/25 18:24:04 phk Exp $
- * $DragonFly: src/sys/platform/pc32/i386/perfmon.c,v 1.10 2007/07/02 02:14:32 dillon Exp $
+ * $DragonFly: src/sys/platform/pc32/i386/perfmon.c,v 1.11 2008/05/10 17:24:07 dillon Exp $
  */
 
 #include <sys/param.h>
@@ -380,13 +380,13 @@ perfmon_ioctl(struct dev_ioctl_args *ap)
                break;
 
        case PMIOTSTAMP:
-               if (!tsc_freq) {
+               if (tsc_frequency == 0) {
                        rv = ENOTTY;
                        break;
                }
                pmct = (struct pmc_tstamp *)param;
                /* XXX interface loses precision. */
-               pmct->pmct_rate = tsc_freq / 1000000;
+               pmct->pmct_rate = (int)(tsc_frequency / 1000000);
                pmct->pmct_value = rdtsc();
                rv = 0;
                break;
index d8dc0c9..5142717 100644 (file)
@@ -4,7 +4,7 @@
  * This file is in the public domain.
  *
  * $FreeBSD: src/sys/i386/include/clock.h,v 1.38.2.1 2002/11/02 04:41:50 iwasaki Exp $
- * $DragonFly: src/sys/platform/pc32/include/clock.h,v 1.8 2006/05/20 02:42:06 dillon Exp $
+ * $DragonFly: src/sys/platform/pc32/include/clock.h,v 1.9 2008/05/10 17:24:08 dillon Exp $
  */
 
 #ifndef _MACHINE_CLOCK_H_
@@ -26,7 +26,7 @@ extern int    statclock_disable;
 extern u_int   timer_freq;
 extern int     timer0_max_count;
 extern int     tsc_present;
-extern u_int   tsc_freq;
+extern int64_t tsc_frequency;
 extern int     tsc_is_broken;
 extern int     wall_cmos_clock;
 #ifdef APIC_IO
index 6360cf6..80bb841 100644 (file)
@@ -35,7 +35,7 @@
  *
  *     from: @(#)clock.c       7.2 (Berkeley) 5/12/91
  * $FreeBSD: src/sys/i386/isa/clock.c,v 1.149.2.6 2002/11/02 04:41:50 iwasaki Exp $
- * $DragonFly: src/sys/platform/pc32/isa/clock.c,v 1.53 2007/06/04 17:22:02 dillon Exp $
+ * $DragonFly: src/sys/platform/pc32/isa/clock.c,v 1.54 2008/05/10 17:24:09 dillon Exp $
  */
 
 /*
@@ -115,7 +115,6 @@ int adjkerntz;              /* local offset from GMT in seconds */
 int    disable_rtc_set;        /* disable resettodr() if != 0 */
 int    statclock_disable = 1;  /* we don't use the statclock right now */
 int    tsc_present;
-u_int  tsc_freq;               /* XXX obsolete, convert users */
 int64_t        tsc_frequency;
 int    tsc_is_broken;
 int    wall_cmos_clock;        /* wall CMOS clock assumed if != 0 */
@@ -585,11 +584,10 @@ calibrate_clocks(void)
         */
        if (tsc_present) {
                tsc_frequency = rdtsc() - old_tsc;
-               tsc_freq = (u_int)tsc_frequency;        /* XXX */
        }
 
        if (tsc_present)
-               kprintf("TSC clock: %u Hz, ", tsc_freq);
+               kprintf("TSC clock: %llu Hz, ", tsc_frequency);
        kprintf("i8254 clock: %u Hz\n", tot_count);
        return (tot_count);
 
@@ -767,16 +765,14 @@ startrtclock(void)
                        kprintf(
                    "%d Hz differs from default of %d Hz by more than 1%%\n",
                               freq, i8254_cputimer.freq);
-               tsc_freq = 0;
                tsc_frequency = 0;
        }
 
 #ifndef CLK_USE_TSC_CALIBRATION
-       if (tsc_freq != 0) {
+       if (tsc_frequency != 0) {
                if (bootverbose)
                        kprintf(
 "CLK_USE_TSC_CALIBRATION not specified - using old calibration method\n");
-               tsc_freq = 0;
                tsc_frequency = 0;
        }
 #endif
@@ -790,10 +786,11 @@ startrtclock(void)
 
                DELAY(1000000);
                tsc_frequency = rdtsc() - old_tsc;
-               tsc_freq = (u_int)tsc_frequency;
 #ifdef CLK_USE_TSC_CALIBRATION
-               if (bootverbose)
-                       kprintf("TSC clock: %u Hz (Method B)\n", tsc_freq);
+               if (bootverbose) {
+                       kprintf("TSC clock: %llu Hz (Method B)\n",
+                               tsc_frequency);
+               }
 #endif
        }
 
@@ -1216,3 +1213,8 @@ SYSCTL_UINT(_hw_i8254, OID_AUTO, freq, CTLFLAG_RD, &i8254_cputimer.freq, 0,
 SYSCTL_PROC(_hw_i8254, OID_AUTO, timestamp, CTLTYPE_STRING|CTLFLAG_RD,
            0, 0, hw_i8254_timestamp, "A", "");
 
+SYSCTL_INT(_hw, OID_AUTO, tsc_present, CTLFLAG_RD,
+           &tsc_present, 0, "TSC Available");
+SYSCTL_QUAD(_hw, OID_AUTO, tsc_frequency, CTLFLAG_RD,
+           &tsc_frequency, 0, "TSC Frequency");
+
index f0694c4..e1aa8e1 100644 (file)
@@ -24,7 +24,7 @@
  * SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/i386/isa/prof_machdep.c,v 1.14.2.1 2000/08/03 00:09:30 ps Exp $
- * $DragonFly: src/sys/platform/pc32/isa/prof_machdep.c,v 1.8 2006/11/07 06:43:25 dillon Exp $
+ * $DragonFly: src/sys/platform/pc32/isa/prof_machdep.c,v 1.9 2008/05/10 17:24:09 dillon Exp $
  */
 
 #ifdef GUPROF
@@ -295,14 +295,14 @@ startguprof(struct gmonparam *gp)
        if (cputime_clock == CPUTIME_CLOCK_UNINITIALIZED) {
                cputime_clock = CPUTIME_CLOCK_I8254;
 #if (defined(I586_CPU) || defined(I686_CPU)) && !defined(SMP)
-               if (tsc_freq != 0)
+               if (tsc_frequency != 0)
                        cputime_clock = CPUTIME_CLOCK_TSC;
 #endif
        }
        gp->profrate = timer_freq << CPUTIME_CLOCK_I8254_SHIFT;
 #if (defined(I586_CPU) || defined(I686_CPU)) && !defined(SMP)
        if (cputime_clock == CPUTIME_CLOCK_TSC)
-               gp->profrate = tsc_freq;
+               gp->profrate = (u_int)tsc_frequency;    /* XXX */
 #if defined(PERFMON) && defined(I586_PMC_GUPROF)
        else if (cputime_clock == CPUTIME_CLOCK_I586_PMC) {
                if (perfmon_avail() &&
index 502320a..c72ea92 100644 (file)
@@ -4,7 +4,7 @@
  * This file is in the public domain.
  *
  * $FreeBSD: src/sys/amd64/include/clock.h,v 1.54 2007/01/23 08:01:19 bde Exp $
- * $DragonFly: src/sys/platform/pc64/include/clock.h,v 1.1 2007/09/23 04:42:07 yanyh Exp $ 
+ * $DragonFly: src/sys/platform/pc64/include/clock.h,v 1.2 2008/05/10 17:24:10 dillon Exp $ 
  */
 
 #ifndef _MACHINE_CLOCK_H_
@@ -23,7 +23,6 @@ extern int    statclock_disable;
 extern u_int   timer_freq;
 extern int     timer0_max_count;
 extern int     tsc_present;
-extern uint64_t        tsc_freq;
 extern int     tsc_is_broken;
 extern int     wall_cmos_clock;
 
index 7e596ec..6465b61 100644 (file)
@@ -4,7 +4,7 @@
  * This file is in the public domain.
  *
  * $FreeBSD: src/sys/i386/include/clock.h,v 1.38.2.1 2002/11/02 04:41:50 iwasaki Exp $
- * $DragonFly: src/sys/platform/vkernel/include/clock.h,v 1.1 2006/11/08 16:40:00 dillon Exp $
+ * $DragonFly: src/sys/platform/vkernel/include/clock.h,v 1.2 2008/05/10 17:24:11 dillon Exp $
  */
 
 #ifndef _MACHINE_CLOCK_H_
@@ -26,7 +26,7 @@ extern int    statclock_disable;
 extern u_int   timer_freq;
 extern int     timer0_max_count;
 extern int     tsc_present;
-extern u_int   tsc_freq;
+extern int64_t tsc_frequency;
 extern int     tsc_is_broken;
 extern int     wall_cmos_clock;
 #ifdef APIC_IO
index a15da0c..7c37c10 100644 (file)
@@ -31,7 +31,7 @@
  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  * 
- * $DragonFly: src/sys/platform/vkernel/platform/init.c,v 1.51 2008/05/07 17:19:47 dillon Exp $
+ * $DragonFly: src/sys/platform/vkernel/platform/init.c,v 1.52 2008/05/10 17:24:12 dillon Exp $
  */
 
 #include <sys/types.h>
@@ -57,6 +57,7 @@
 #include <machine/tls.h>
 #include <machine/md_var.h>
 #include <machine/vmparam.h>
+#include <cpu/specialreg.h>
 
 #include <net/if.h>
 #include <net/if_arp.h>
@@ -98,7 +99,8 @@ caddr_t ptvmmap;
 vpte_t *KernelPTD;
 vpte_t *KernelPTA;     /* Warning: Offset for direct VA translation */
 u_int cpu_feature;     /* XXX */
-int tsc_present;       /* XXX */
+int tsc_present;
+int64_t tsc_frequency;
 int optcpus;           /* number of cpus - see mp_start() */
 int lwp_cpu_lock;      /* if/how to lock virtual CPUs to real CPUs */
 int real_ncpus;                /* number of real CPUs */
@@ -134,7 +136,6 @@ main(int ac, char **av)
        char *cdFile[VKDISK_MAX];
        char *suffix;
        char *endp;
-       size_t real_ncpus_size;
        int netifFileNum = 0;
        int diskFileNum = 0;
        int cdFileNum = 0;
@@ -143,9 +144,8 @@ main(int ac, char **av)
        int i;
        int n;
        int real_vkernel_enable;
-       size_t real_vkernel_enable_size;
        int supports_sse;
-       int supports_sse_size;
+       size_t vsize;
        
        save_ac = ac;
        save_av = av;
@@ -160,17 +160,17 @@ main(int ac, char **av)
        lwp_cpu_lock = LCL_NONE;
 
        real_vkernel_enable = 0;
-       real_vkernel_enable_size = sizeof(real_vkernel_enable);
-       sysctlbyname("vm.vkernel_enable", &real_vkernel_enable, &real_vkernel_enable_size, NULL, 0);
+       vsize = sizeof(real_vkernel_enable);
+       sysctlbyname("vm.vkernel_enable", &real_vkernel_enable, &vsize, NULL,0);
        
        if (real_vkernel_enable == 0) {
                errx(1, "vm.vkernel_enable is 0, must be set "
                        "to 1 to execute a vkernel!");
        }
 
-       real_ncpus_size = sizeof(real_ncpus);
        real_ncpus = 1;
-       sysctlbyname("hw.ncpu", &real_ncpus, &real_ncpus_size, NULL, 0);
+       vsize = sizeof(real_ncpus);
+       sysctlbyname("hw.ncpu", &real_ncpus, &vsize, NULL, 0);
 
        while ((c = getopt(ac, av, "c:svl:m:n:r:e:i:p:I:U")) != -1) {
                switch(c) {
@@ -296,11 +296,25 @@ main(int ac, char **av)
        setrealcpu();
        init_kqueue();
 
-       supports_sse_size = sizeof(supports_sse);
+       /*
+        * Check TSC
+        */
+       vsize = sizeof(tsc_present);
+       sysctlbyname("hw.tsc_present", &tsc_present, &vsize, NULL, 0);
+       vsize = sizeof(tsc_frequency);
+       sysctlbyname("hw.tsc_frequency", &tsc_frequency, &vsize, NULL, 0);
+       if (tsc_present)
+               cpu_feature |= CPUID_TSC;
+
+       /*
+        * Check SSE
+        */
+       vsize = sizeof(supports_sse);
        supports_sse = 0;
-       sysctlbyname("hw.instruction_sse", &supports_sse, &supports_sse_size,
-                    NULL, 0);
+       sysctlbyname("hw.instruction_sse", &supports_sse, &vsize, NULL, 0);
        init_fpu(supports_sse);
+       if (supports_sse)
+               cpu_feature |= CPUID_SSE | CPUID_FXSR;
 
        /*
         * We boot from the first installed disk.
index 3a0cb90..8e30e07 100644 (file)
@@ -31,7 +31,7 @@
  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  * 
- * $DragonFly: src/sys/platform/vkernel/platform/systimer.c,v 1.15 2007/07/02 15:18:51 dillon Exp $
+ * $DragonFly: src/sys/platform/vkernel/platform/systimer.c,v 1.16 2008/05/10 17:24:12 dillon Exp $
  */
 
 #include <sys/types.h>
@@ -44,6 +44,7 @@
 #include <sys/bus.h>
 #include <sys/time.h>
 #include <machine/cpu.h>
+#include <machine/clock.h>
 #include <machine/globaldata.h>
 #include <machine/md_var.h>
 
@@ -57,6 +58,10 @@ static void cputimer_intr(void *dummy, struct intrframe *frame);
 int disable_rtc_set;
 SYSCTL_INT(_machdep, CPU_DISRTCSET, disable_rtc_set,
           CTLFLAG_RW, &disable_rtc_set, 0, "");
+SYSCTL_INT(_hw, OID_AUTO, tsc_present, CTLFLAG_RD,
+            &tsc_present, 0, "TSC Available");
+SYSCTL_QUAD(_hw, OID_AUTO, tsc_frequency, CTLFLAG_RD,
+           &tsc_frequency, 0, "TSC Frequency");
 
 int adjkerntz;
 int wall_cmos_clock = 0;