Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/arch/x86/acpi Add MD support for the vendor-independent ...
details: https://anonhg.NetBSD.org/src/rev/8ae37458da73
branches: trunk
changeset: 757184:8ae37458da73
user: jruoho <jruoho%NetBSD.org@localhost>
date: Wed Aug 18 04:12:29 2010 +0000
description:
Add MD support for the vendor-independent extended PSS. Some conforming AMD
systems are known to work. Alas, not all of them. We still need to deal with
the variety of different PowerNow! revisions.
diffstat:
sys/arch/x86/acpi/acpi_cpu_md.c | 144 +++++++++++++++++++++++++--------------
1 files changed, 92 insertions(+), 52 deletions(-)
diffs (253 lines):
diff -r 0ada09abbf7a -r 8ae37458da73 sys/arch/x86/acpi/acpi_cpu_md.c
--- a/sys/arch/x86/acpi/acpi_cpu_md.c Wed Aug 18 02:53:54 2010 +0000
+++ b/sys/arch/x86/acpi/acpi_cpu_md.c Wed Aug 18 04:12:29 2010 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: acpi_cpu_md.c,v 1.12 2010/08/14 05:13:20 jruoho Exp $ */
+/* $NetBSD: acpi_cpu_md.c,v 1.13 2010/08/18 04:12:29 jruoho Exp $ */
/*-
* Copyright (c) 2010 Jukka Ruohonen <jruohonen%iki.fi@localhost>
@@ -27,7 +27,7 @@
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: acpi_cpu_md.c,v 1.12 2010/08/14 05:13:20 jruoho Exp $");
+__KERNEL_RCSID(0, "$NetBSD: acpi_cpu_md.c,v 1.13 2010/08/18 04:12:29 jruoho Exp $");
#include <sys/param.h>
#include <sys/bus.h>
@@ -56,7 +56,6 @@
static int acpicpu_md_pstate_sysctl_get(SYSCTLFN_PROTO);
static int acpicpu_md_pstate_sysctl_set(SYSCTLFN_PROTO);
static int acpicpu_md_pstate_sysctl_all(SYSCTLFN_PROTO);
-static int acpicpu_md_tstate_get_status(uint64_t *);
extern uint32_t cpus_running;
extern struct acpicpu_softc **acpicpu_sc;
@@ -135,7 +134,7 @@
case CPUVENDOR_AMD:
/*
- * XXX: Deal with PowerNow! and C1E here.
+ * XXX: Deal with (non-XPSS) PowerNow! and C1E.
*/
break;
}
@@ -253,6 +252,10 @@
str = "est";
break;
+ case CPUVENDOR_AMD:
+ str = "powernow";
+ break;
+
default:
return ENODEV;
}
@@ -449,37 +452,61 @@
int
acpicpu_md_pstate_get(struct acpicpu_softc *sc, uint32_t *freq)
{
- struct acpicpu_pstate *ps;
+ struct acpicpu_pstate *ps = NULL;
uint64_t val;
uint32_t i;
+ for (i = 0; i < sc->sc_pstate_count; i++) {
+
+ ps = &sc->sc_pstate[i];
+
+ if (ps->ps_freq != 0)
+ break;
+ }
+
+ if (__predict_false(ps == NULL))
+ return EINVAL;
+
switch (cpu_vendor) {
case CPUVENDOR_INTEL:
-
- val = rdmsr(MSR_PERF_STATUS);
- val = val & 0xffff;
-
- for (i = 0; i < sc->sc_pstate_count; i++) {
-
- ps = &sc->sc_pstate[i];
+ ps->ps_status_addr = MSR_PERF_STATUS;
+ ps->ps_status_mask = __BITS(0, 15);
+ break;
- if (ps->ps_freq == 0)
- continue;
+ case CPUVENDOR_AMD:
- if (val == ps->ps_status) {
- *freq = ps->ps_freq;
- return 0;
- }
- }
+ if ((ps->ps_flags & ACPICPU_FLAG_P_XPSS) == 0)
+ return EOPNOTSUPP;
- return EIO;
+ break;
default:
return ENODEV;
}
- return 0;
+ if (ps->ps_status_addr == 0)
+ return EINVAL;
+
+ val = rdmsr(ps->ps_status_addr);
+
+ if (ps->ps_status_mask != 0)
+ val = val & ps->ps_status_mask;
+
+ for (i = 0; i < sc->sc_pstate_count; i++) {
+
+ ps = &sc->sc_pstate[i];
+
+ if (ps->ps_freq == 0)
+ continue;
+
+ if (val == ps->ps_status) {
+ *freq = ps->ps_freq;
+ return 0;
+ }
+ }
+
+ return EIO;
}
int
@@ -492,23 +519,45 @@
switch (cpu_vendor) {
case CPUVENDOR_INTEL:
- msr.msr_read = true;
- msr.msr_type = MSR_PERF_CTL;
- msr.msr_value = ps->ps_control;
- msr.msr_mask = 0xffffULL;
+ ps->ps_control_addr = MSR_PERF_CTL;
+ ps->ps_control_mask = __BITS(0, 15);
+
+ ps->ps_status_addr = MSR_PERF_STATUS;
+ ps->ps_status_mask = __BITS(0, 15);
+ break;
+
+ case CPUVENDOR_AMD:
+
+ if ((ps->ps_flags & ACPICPU_FLAG_P_XPSS) == 0)
+ return EOPNOTSUPP;
+
break;
default:
return ENODEV;
}
+ msr.msr_read = false;
+ msr.msr_type = ps->ps_control_addr;
+ msr.msr_value = ps->ps_control;
+
+ if (ps->ps_control_mask != 0) {
+ msr.msr_mask = ps->ps_control_mask;
+ msr.msr_read = true;
+ }
+
xc = xc_broadcast(0, (xcfunc_t)x86_msr_xcall, &msr, NULL);
xc_wait(xc);
+ if (ps->ps_status_addr == 0)
+ return 0;
+
for (i = val = 0; i < ACPICPU_P_STATE_RETRY; i++) {
- val = rdmsr(MSR_PERF_STATUS);
- val = val & 0xffff;
+ val = rdmsr(ps->ps_status_addr);
+
+ if (ps->ps_status_mask != 0)
+ val = val & ps->ps_status_mask;
if (val == ps->ps_status)
return 0;
@@ -523,14 +572,20 @@
acpicpu_md_tstate_get(struct acpicpu_softc *sc, uint32_t *percent)
{
struct acpicpu_tstate *ts;
- uint64_t val;
+ uint64_t val, sta;
uint32_t i;
- int rv;
+
+ switch (cpu_vendor) {
- rv = acpicpu_md_tstate_get_status(&val);
+ case CPUVENDOR_INTEL:
+ sta = MSR_THERM_CONTROL;
+ break;
- if (rv != 0)
- return rv;
+ default:
+ return ENODEV;
+ }
+
+ val = rdmsr(sta);
for (i = 0; i < sc->sc_tstate_count; i++) {
@@ -548,29 +603,12 @@
return EIO;
}
-static int
-acpicpu_md_tstate_get_status(uint64_t *val)
-{
-
- switch (cpu_vendor) {
-
- case CPUVENDOR_INTEL:
- *val = rdmsr(MSR_THERM_CONTROL);
- break;
-
- default:
- return ENODEV;
- }
-
- return 0;
-}
-
int
acpicpu_md_tstate_set(struct acpicpu_tstate *ts)
{
struct msr_rw_info msr;
- uint64_t xc, val;
- int i;
+ uint64_t xc, val, sta;
+ uint32_t i;
switch (cpu_vendor) {
@@ -579,6 +617,8 @@
msr.msr_type = MSR_THERM_CONTROL;
msr.msr_value = ts->ts_control;
msr.msr_mask = __BITS(1, 4);
+
+ sta = MSR_THERM_CONTROL;
break;
default:
@@ -593,7 +633,7 @@
for (i = val = 0; i < ACPICPU_T_STATE_RETRY; i++) {
- (void)acpicpu_md_tstate_get_status(&val);
+ val = rdmsr(sta);
if (val == ts->ts_status)
return 0;
Home |
Main Index |
Thread Index |
Old Index