Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys Add preliminary support for the IA32_APERF and IA32_MPER...



details:   https://anonhg.NetBSD.org/src/rev/7bddc5002f54
branches:  trunk
changeset: 762661:7bddc5002f54
user:      jruoho <jruoho%NetBSD.org@localhost>
date:      Fri Feb 25 09:16:00 2011 +0000

description:
Add preliminary support for the IA32_APERF and IA32_MPERF frequency counters.
These are not yet used for anything and only Intel is supported at the moment.

diffstat:

 sys/arch/x86/acpi/acpi_cpu_md.c |  96 +++++++++++++++++++++++++++++++++++++++-
 sys/dev/acpi/acpi_cpu.h         |   9 ++-
 sys/dev/acpi/acpi_cpu_pstate.c  |   8 +-
 3 files changed, 102 insertions(+), 11 deletions(-)

diffs (214 lines):

diff -r ba670cff8816 -r 7bddc5002f54 sys/arch/x86/acpi/acpi_cpu_md.c
--- a/sys/arch/x86/acpi/acpi_cpu_md.c   Fri Feb 25 08:04:18 2011 +0000
+++ b/sys/arch/x86/acpi/acpi_cpu_md.c   Fri Feb 25 09:16:00 2011 +0000
@@ -1,7 +1,7 @@
-/* $NetBSD: acpi_cpu_md.c,v 1.40 2011/02/24 13:19:36 jmcneill Exp $ */
+/* $NetBSD: acpi_cpu_md.c,v 1.41 2011/02/25 09:16:00 jruoho Exp $ */
 
 /*-
- * Copyright (c) 2010 Jukka Ruohonen <jruohonen%iki.fi@localhost>
+ * Copyright (c) 2010, 2011 Jukka Ruohonen <jruohonen%iki.fi@localhost>
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -27,7 +27,7 @@
  * SUCH DAMAGE.
  */
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: acpi_cpu_md.c,v 1.40 2011/02/24 13:19:36 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: acpi_cpu_md.c,v 1.41 2011/02/25 09:16:00 jruoho Exp $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -99,6 +99,8 @@
 void           (*native_idle)(void) = NULL;
 
 static int      acpicpu_md_quirks_piix4(struct pci_attach_args *);
+static void     acpicpu_md_pstate_percent_reset(struct acpicpu_softc *);
+static void     acpicpu_md_pstate_percent_status(void *, void *);
 static void     acpicpu_md_pstate_status(void *, void *);
 static int      acpicpu_md_pstate_fidvid_get(struct acpicpu_softc *,
                                               uint32_t *);
@@ -408,16 +410,22 @@
 }
 
 int
-acpicpu_md_pstate_start(void)
+acpicpu_md_pstate_start(struct acpicpu_softc *sc)
 {
        const uint64_t est = __BIT(16);
        uint64_t val;
 
+       if ((sc->sc_flags & ACPICPU_FLAG_P) == 0)
+               return ENODEV;
+
        switch (cpu_vendor) {
 
        case CPUVENDOR_IDT:
        case CPUVENDOR_INTEL:
 
+               /*
+                * Make sure EST is enabled.
+                */
                val = rdmsr(MSR_MISC_ENABLE);
 
                if ((val & est) == 0) {
@@ -430,6 +438,12 @@
                        if ((val & est) == 0)
                                return ENOTTY;
                }
+
+               /*
+                * Reset the APERF and MPERF counters.
+                */
+               if ((sc->sc_flags & ACPICPU_FLAG_P_HW) != 0)
+                       acpicpu_md_pstate_percent_reset(sc);
        }
 
        return acpicpu_md_pstate_sysctl_init();
@@ -549,6 +563,80 @@
        return 0;
 }
 
+/*
+ * Returns the percentage of the actual frequency in
+ * terms of the maximum frequency of the calling CPU
+ * since the last call. A value zero implies an error.
+ */
+uint8_t
+acpicpu_md_pstate_percent(struct acpicpu_softc *sc)
+{
+       struct cpu_info *ci = sc->sc_ci;
+       uint64_t aperf, mperf;
+       uint64_t xc, rv = 0;
+
+       if (__predict_false((sc->sc_flags & ACPICPU_FLAG_P) == 0))
+               return 0;
+
+       if (__predict_false((sc->sc_flags & ACPICPU_FLAG_P_HW) == 0))
+               return 0;
+
+       /*
+        * Read the IA32_APERF and IA32_MPERF counters. The first
+        * increments at the rate of the fixed maximum frequency
+        * configured during the boot, whereas APERF counts at the
+        * rate of the actual frequency. Note that the MSRs must be
+        * read without delay, and that only the ratio between
+        * IA32_APERF and IA32_MPERF is architecturally defined.
+        *
+        * For further details, refer to:
+        *
+        *      Intel Corporation: Intel 64 and IA-32 Architectures
+        *      Software Developer's Manual. Section 13.2, Volume 3A:
+        *      System Programming Guide, Part 1. July, 2008.
+        */
+       x86_disable_intr();
+
+       aperf = sc->sc_pstate_aperf;
+       mperf = sc->sc_pstate_mperf;
+
+       xc = xc_unicast(0, acpicpu_md_pstate_percent_status, sc, NULL, ci);
+       xc_wait(xc);
+
+       x86_enable_intr();
+
+       aperf = sc->sc_pstate_aperf - aperf;
+       mperf = sc->sc_pstate_mperf - mperf;
+
+       if (__predict_true(mperf != 0))
+               rv = (aperf * 100) / mperf;
+
+       return rv;
+}
+
+static void
+acpicpu_md_pstate_percent_status(void *arg1, void *arg2)
+{
+       struct acpicpu_softc *sc = arg1;
+
+       sc->sc_pstate_aperf = rdmsr(MSR_APERF);
+       sc->sc_pstate_mperf = rdmsr(MSR_MPERF);
+}
+
+static void
+acpicpu_md_pstate_percent_reset(struct acpicpu_softc *sc)
+{
+
+       KASSERT((sc->sc_flags & ACPICPU_FLAG_P) != 0);
+       KASSERT((sc->sc_flags & ACPICPU_FLAG_P_HW) != 0);
+
+       wrmsr(MSR_APERF, 0);
+       wrmsr(MSR_MPERF, 0);
+
+       sc->sc_pstate_aperf = 0;
+       sc->sc_pstate_mperf = 0;
+}
+
 int
 acpicpu_md_pstate_get(struct acpicpu_softc *sc, uint32_t *freq)
 {
diff -r ba670cff8816 -r 7bddc5002f54 sys/dev/acpi/acpi_cpu.h
--- a/sys/dev/acpi/acpi_cpu.h   Fri Feb 25 08:04:18 2011 +0000
+++ b/sys/dev/acpi/acpi_cpu.h   Fri Feb 25 09:16:00 2011 +0000
@@ -1,7 +1,7 @@
-/* $NetBSD: acpi_cpu.h,v 1.29 2011/02/25 06:18:02 jruoho Exp $ */
+/* $NetBSD: acpi_cpu.h,v 1.30 2011/02/25 09:16:00 jruoho Exp $ */
 
 /*-
- * Copyright (c) 2010 Jukka Ruohonen <jruohonen%iki.fi@localhost>
+ * Copyright (c) 2010, 2011 Jukka Ruohonen <jruohonen%iki.fi@localhost>
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -188,6 +188,8 @@
        struct acpicpu_pstate   *sc_pstate;
        struct acpicpu_reg       sc_pstate_control;
        struct acpicpu_reg       sc_pstate_status;
+       uint64_t                 sc_pstate_aperf;       /* ACPICPU_FLAG_P_HW */
+       uint64_t                 sc_pstate_mperf;       /* ACPICPU_FLAG_P_HW*/
        uint32_t                 sc_pstate_current;
        uint32_t                 sc_pstate_count;
        uint32_t                 sc_pstate_max;
@@ -239,9 +241,10 @@
 int            acpicpu_md_idle_start(struct acpicpu_softc *);
 int            acpicpu_md_idle_stop(void);
 void           acpicpu_md_idle_enter(int, int);
-int            acpicpu_md_pstate_start(void);
+int            acpicpu_md_pstate_start(struct acpicpu_softc *);
 int            acpicpu_md_pstate_stop(void);
 int            acpicpu_md_pstate_pss(struct acpicpu_softc *);
+uint8_t                acpicpu_md_pstate_percent(struct acpicpu_softc *);
 int            acpicpu_md_pstate_get(struct acpicpu_softc *, uint32_t *);
 int            acpicpu_md_pstate_set(struct acpicpu_pstate *);
 int            acpicpu_md_tstate_get(struct acpicpu_softc *, uint32_t *);
diff -r ba670cff8816 -r 7bddc5002f54 sys/dev/acpi/acpi_cpu_pstate.c
--- a/sys/dev/acpi/acpi_cpu_pstate.c    Fri Feb 25 08:04:18 2011 +0000
+++ b/sys/dev/acpi/acpi_cpu_pstate.c    Fri Feb 25 09:16:00 2011 +0000
@@ -1,7 +1,7 @@
-/* $NetBSD: acpi_cpu_pstate.c,v 1.38 2011/02/23 06:17:55 jruoho Exp $ */
+/* $NetBSD: acpi_cpu_pstate.c,v 1.39 2011/02/25 09:16:00 jruoho Exp $ */
 
 /*-
- * Copyright (c) 2010 Jukka Ruohonen <jruohonen%iki.fi@localhost>
+ * Copyright (c) 2010, 2011 Jukka Ruohonen <jruohonen%iki.fi@localhost>
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -27,7 +27,7 @@
  * SUCH DAMAGE.
  */
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: acpi_cpu_pstate.c,v 1.38 2011/02/23 06:17:55 jruoho Exp $");
+__KERNEL_RCSID(0, "$NetBSD: acpi_cpu_pstate.c,v 1.39 2011/02/25 09:16:00 jruoho Exp $");
 
 #include <sys/param.h>
 #include <sys/evcnt.h>
@@ -249,7 +249,7 @@
        uint32_t i;
        int rv;
 
-       rv = acpicpu_md_pstate_start();
+       rv = acpicpu_md_pstate_start(sc);
 
        if (rv != 0)
                goto fail;



Home | Main Index | Thread Index | Old Index