Add AMD C1E quirk. Tested by cegger@.

(a) This should be removed once C-states are supported.

  (b) As there seems to be no reliable way to detect whether C1E is present,
      the quirk blindly assumes that C1E is used on families 10h and 11h.
This commit is contained in:
jruoho 2010-11-30 04:31:00 +00:00
parent 0c1edef512
commit e1de74391b
3 changed files with 37 additions and 7 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: acpi_cpu_md.c,v 1.34 2010/08/25 05:07:43 jruoho Exp $ */
/* $NetBSD: acpi_cpu_md.c,v 1.35 2010/11/30 04:31:00 jruoho Exp $ */
/*-
* Copyright (c) 2010 Jukka Ruohonen <jruohonen@iki.fi>
@ -27,7 +27,7 @@
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: acpi_cpu_md.c,v 1.34 2010/08/25 05:07:43 jruoho Exp $");
__KERNEL_RCSID(0, "$NetBSD: acpi_cpu_md.c,v 1.35 2010/11/30 04:31:00 jruoho Exp $");
#include <sys/param.h>
#include <sys/bus.h>
@ -48,7 +48,14 @@ __KERNEL_RCSID(0, "$NetBSD: acpi_cpu_md.c,v 1.34 2010/08/25 05:07:43 jruoho Exp
#include <dev/pci/pcivar.h>
#include <dev/pci/pcidevs.h>
#define ACPICPU_P_STATE_STATUS 0
/*
* AMD C1E.
*/
#define MSR_CMPHALT 0xc0010055
#define MSR_CMPHALT_SMI __BIT(27)
#define MSR_CMPHALT_C1E __BIT(28)
#define MSR_CMPHALT_BMSTS __BIT(29)
/*
* AMD families 10h and 11h.
@ -105,6 +112,7 @@ static int acpicpu_md_pstate_sysctl_all(SYSCTLFN_PROTO);
extern uint32_t cpus_running;
extern struct acpicpu_softc **acpicpu_sc;
static bool acpicpu_pstate_status = false;
static struct sysctllog *acpicpu_log = NULL;
uint32_t
@ -256,6 +264,9 @@ acpicpu_md_quirks(void)
if ((regs[3] & CPUID_APM_CPB) != 0)
val |= ACPICPU_FLAG_P_TURBO;
val |= ACPICPU_FLAG_C_C1E;
break;
}
break;
@ -289,6 +300,18 @@ acpicpu_md_quirks_piix4(struct pci_attach_args *pa)
return 0;
}
void
acpicpu_md_quirks_c1e(void)
{
const uint64_t c1e = MSR_CMPHALT_SMI | MSR_CMPHALT_C1E;
uint64_t val;
val = rdmsr(MSR_CMPHALT);
if ((val & c1e) != 0)
wrmsr(MSR_CMPHALT, val & ~c1e);
}
uint32_t
acpicpu_md_cpus_running(void)
{
@ -580,7 +603,7 @@ acpicpu_md_pstate_set(struct acpicpu_pstate *ps)
xc = xc_broadcast(0, (xcfunc_t)x86_msr_xcall, &msr, NULL);
xc_wait(xc);
if (ACPICPU_P_STATE_STATUS == 0) {
if (acpicpu_pstate_status != false) {
DELAY(ps->ps_latency);
return 0;
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: acpi_cpu.h,v 1.25 2010/08/27 03:05:26 jruoho Exp $ */
/* $NetBSD: acpi_cpu.h,v 1.26 2010/11/30 04:31:00 jruoho Exp $ */
/*-
* Copyright (c) 2010 Jukka Ruohonen <jruohonen@iki.fi>
@ -236,6 +236,7 @@ int acpicpu_tstate_set(struct acpicpu_softc *, uint32_t);
uint32_t acpicpu_md_cap(void);
uint32_t acpicpu_md_quirks(void);
void acpicpu_md_quirks_c1e(void);
uint32_t acpicpu_md_cpus_running(void);
int acpicpu_md_idle_start(struct acpicpu_softc *);
int acpicpu_md_idle_stop(void);

View File

@ -1,4 +1,4 @@
/* $NetBSD: acpi_cpu_cstate.c,v 1.33 2010/08/23 16:20:45 jruoho Exp $ */
/* $NetBSD: acpi_cpu_cstate.c,v 1.34 2010/11/30 04:31:00 jruoho Exp $ */
/*-
* Copyright (c) 2010 Jukka Ruohonen <jruohonen@iki.fi>
@ -27,7 +27,7 @@
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: acpi_cpu_cstate.c,v 1.33 2010/08/23 16:20:45 jruoho Exp $");
__KERNEL_RCSID(0, "$NetBSD: acpi_cpu_cstate.c,v 1.34 2010/11/30 04:31:00 jruoho Exp $");
#include <sys/param.h>
#include <sys/cpu.h>
@ -683,6 +683,12 @@ acpicpu_cstate_idle(void)
mutex_exit(&sc->sc_mtx);
state = acpicpu_cstate_latency(sc);
/*
* Apply AMD C1E quirk.
*/
if ((sc->sc_flags & ACPICPU_FLAG_C_C1E) != 0)
acpicpu_md_quirks_c1e();
/*
* Check for bus master activity. Note that particularly usb(4)
* causes high activity, which may prevent the use of C3 states.