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