Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src Add native support for AMD family 0Fh processors. This is th...
details: https://anonhg.NetBSD.org/src/rev/911a1fa28e7c
branches: trunk
changeset: 757293:911a1fa28e7c
user: jruoho <jruoho%NetBSD.org@localhost>
date: Tue Aug 24 07:27:59 2010 +0000
description:
Add native support for AMD family 0Fh processors. This is the furthest we
will go backwards; K7 will not be supported already due doubts about
availability and reliability of ACPI during that era. Some unfortunate code
duplication is present (but not overly much). Thanks to cegger@ and jakllsch@
for patiently testing this.
diffstat:
share/man/man4/acpicpu.4 | 36 ++--
sys/arch/x86/acpi/acpi_cpu_md.c | 275 +++++++++++++++++++++++++++++++++++++--
sys/dev/acpi/acpi_cpu.h | 7 +-
3 files changed, 282 insertions(+), 36 deletions(-)
diffs (truncated from 513 to 300 lines):
diff -r 28151101529a -r 911a1fa28e7c share/man/man4/acpicpu.4
--- a/share/man/man4/acpicpu.4 Tue Aug 24 05:34:15 2010 +0000
+++ b/share/man/man4/acpicpu.4 Tue Aug 24 07:27:59 2010 +0000
@@ -1,4 +1,4 @@
-.\" $NetBSD: acpicpu.4,v 1.14 2010/08/20 06:35:55 jruoho Exp $
+.\" $NetBSD: acpicpu.4,v 1.15 2010/08/24 07:27:59 jruoho Exp $
.\"
.\" Coyright (c) 2010 Jukka Ruohonen <jruohonen%iki.fi@localhost>
.\" All rights reserved.
@@ -24,7 +24,7 @@
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
.\" POSSIBILITY OF SUCH DAMAGE.
.\"
-.Dd August 20, 2010
+.Dd August 24, 2010
.Dt ACPICPU 4
.Os
.Sh NAME
@@ -161,12 +161,17 @@
.Dq PowerSaver
.Pq VIA .
.Pp
-The
-.Dv P0
-state is always the highest operating frequency supported by the processor.
+The P0-state is always the highest operating
+frequency supported by the processor.
The number of additional P-states may vary across processors and vendors.
Each higher numbered P-state represents lower
clock frequencies and hence lower power consumption.
+Note that while
+.Nm
+always uses the exact frequencies internally,
+the user-visible values reported by
+.Tn ACPI
+may be rounded or approximated by the vendor.
.Pp
Unlike conventional
.Tn CPU
@@ -174,8 +179,9 @@
.Tn ACPI
provides support for Dynamic Voltage and Frequency Scaling
.Pq Tn DVFS .
-This means that the firmware may request the implementation to
-dynamically scale the presently supported maximum clock frequency.
+Among other things,
+this means that the firmware may request the implementation to
+dynamically scale the presently supported maximum or minimum clock frequency.
For example, if
.Xr acpiacad 4
is disconnected, the maximum available frequency may be lowered.
@@ -191,7 +197,7 @@
time a processor is allowed to execute.
Outside the
.Tn ACPI
-nomenclature, throttling may be known as
+nomenclature, throttling and T-states may be known as
.Dq on-demand clock modulation
.Pq Tn ODCM .
.Pp
@@ -205,8 +211,7 @@
and thus, comparable to the C0-state, the processor is fully active.
Each additional higher-numbered T-state indicates lower duty cycles.
At most eight T-states may be available, although also T-states use
-.Tn DVFS ;
-both the maximum and the minimum available T-state may change dynamically.
+.Tn DVFS .
.Pp
The duty cycle does not refer to the actual clock signal,
but to the time period in which the clock signal is allowed
@@ -218,7 +223,7 @@
.Tn CPU
is forced to idle.
Because of this, the use of T-states may
-severely reduce system performance.
+severely affect system performance.
.Pp
There are two typical situations for throttling:
power management and thermal control.
@@ -266,7 +271,7 @@
.Dv ENHANCED_SPEEDSTEP
and
.Dv POWERNOW_K8 .
-Depending on the processor vendor, the second-level node is either
+Depending on the processor, the second-level node is either
.Ic machdep.est
or
.Ic machdep.powernow .
@@ -299,9 +304,6 @@
.An Jukka Ruohonen
.Aq jruohonen%iki.fi@localhost
.Sh CAVEATS
-The
-.Nm
-driver should be considered experimental.
At least the following caveats can be mentioned.
.Bl -bullet
.It
@@ -320,10 +322,6 @@
it is recommended to turn it off, with or without
.Nm .
.It
-While P-states are supported on all Intel
-.Tn CPUs ,
-not all AMD processors are yet supported.
-.It
Processor thermal control (see
.Xr acpitz 4 )
is not yet supported.
diff -r 28151101529a -r 911a1fa28e7c sys/arch/x86/acpi/acpi_cpu_md.c
--- a/sys/arch/x86/acpi/acpi_cpu_md.c Tue Aug 24 05:34:15 2010 +0000
+++ b/sys/arch/x86/acpi/acpi_cpu_md.c Tue Aug 24 07:27:59 2010 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: acpi_cpu_md.c,v 1.31 2010/08/23 16:20:44 jruoho Exp $ */
+/* $NetBSD: acpi_cpu_md.c,v 1.32 2010/08/24 07:28:00 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.31 2010/08/23 16:20:44 jruoho Exp $");
+__KERNEL_RCSID(0, "$NetBSD: acpi_cpu_md.c,v 1.32 2010/08/24 07:28:00 jruoho Exp $");
#include <sys/param.h>
#include <sys/bus.h>
@@ -48,21 +48,53 @@
#include <dev/pci/pcivar.h>
#include <dev/pci/pcidevs.h>
-#define CPUID_INTEL_TSC __BIT(8)
-
-#define MSR_0FH_CONTROL 0xc0010041 /* Family 0Fh (and K7). */
-#define MSR_0FH_STATUS 0xc0010042
-
-#define MSR_10H_LIMIT 0xc0010061 /* Families 10h and 11h. */
+/*
+ * AMD families 10h and 11h.
+ */
+#define MSR_10H_LIMIT 0xc0010061
#define MSR_10H_CONTROL 0xc0010062
#define MSR_10H_STATUS 0xc0010063
#define MSR_10H_CONFIG 0xc0010064
+/*
+ * AMD family 0Fh.
+ */
+#define MSR_0FH_CONTROL 0xc0010041
+#define MSR_0FH_STATUS 0xc0010042
+
+#define MSR_0FH_STATUS_CFID __BITS( 0, 5)
+#define MSR_0FH_STATUS_CVID __BITS(32, 36)
+#define MSR_0FH_STATUS_PENDING __BITS(31, 31)
+
+#define MSR_0FH_CONTROL_FID __BITS( 0, 5)
+#define MSR_0FH_CONTROL_VID __BITS( 8, 12)
+#define MSR_0FH_CONTROL_CHG __BITS(16, 16)
+#define MSR_0FH_CONTROL_CNT __BITS(32, 51)
+
+#define ACPI_0FH_STATUS_FID __BITS( 0, 5)
+#define ACPI_0FH_STATUS_VID __BITS( 6, 10)
+
+#define ACPI_0FH_CONTROL_FID __BITS( 0, 5)
+#define ACPI_0FH_CONTROL_VID __BITS( 6, 10)
+#define ACPI_0FH_CONTROL_VST __BITS(11, 17)
+#define ACPI_0FH_CONTROL_MVS __BITS(18, 19)
+#define ACPI_0FH_CONTROL_PLL __BITS(20, 26)
+#define ACPI_0FH_CONTROL_RVO __BITS(28, 29)
+#define ACPI_0FH_CONTROL_IRT __BITS(30, 31)
+
+#define FID_TO_VCO_FID(fidd) (((fid) < 8) ? (8 + ((fid) << 1)) : (fid))
+
static char native_idle_text[16];
void (*native_idle)(void) = NULL;
static int acpicpu_md_quirks_piix4(struct pci_attach_args *);
static void acpicpu_md_pstate_status(void *, void *);
+static int acpicpu_md_pstate_fidvid_get(struct acpicpu_softc *,
+ uint32_t *);
+static int acpicpu_md_pstate_fidvid_set(struct acpicpu_pstate *);
+static int acpicpu_md_pstate_fidvid_read(uint32_t *, uint32_t *);
+static void acpicpu_md_pstate_fidvid_write(uint32_t, uint32_t,
+ uint32_t, uint32_t);
static void acpicpu_md_tstate_status(void *, void *);
static int acpicpu_md_pstate_sysctl_init(void);
static int acpicpu_md_pstate_sysctl_get(SYSCTLFN_PROTO);
@@ -178,7 +210,7 @@
x86_cpuid(0x80000007, regs);
- if ((regs[3] & CPUID_INTEL_TSC) != 0)
+ if ((regs[3] & __BIT(8)) != 0)
val &= ~ACPICPU_FLAG_C_TSC;
}
@@ -186,19 +218,34 @@
case CPUVENDOR_AMD:
+ x86_cpuid(0x80000000, regs);
+
+ if (regs[0] < 0x80000007)
+ break;
+
+ x86_cpuid(0x80000007, regs);
+
family = CPUID2FAMILY(ci->ci_signature);
if (family == 0xf)
family += CPUID2EXTFAMILY(ci->ci_signature);
- switch (family) {
+ switch (family) {
case 0x0f:
+
+ if ((regs[3] & CPUID_APM_FID) == 0)
+ break;
+
+ if ((regs[3] & CPUID_APM_VID) == 0)
+ break;
+
+ val |= ACPICPU_FLAG_P_FFH | ACPICPU_FLAG_P_FIDVID;
+ break;
+
case 0x10:
case 0x11:
- x86_cpuid(0x80000007, regs);
-
if ((regs[3] & CPUID_APM_TSC) != 0)
val &= ~ACPICPU_FLAG_C_TSC;
@@ -370,6 +417,9 @@
(void)memset(&msr, 0, sizeof(struct acpicpu_pstate));
+ if ((sc->sc_flags & ACPICPU_FLAG_P_FIDVID) != 0)
+ msr.ps_flags = ACPICPU_FLAG_P_FIDVID;
+
switch (cpu_vendor) {
case CPUVENDOR_IDT:
@@ -390,6 +440,11 @@
switch (family) {
+ case 0x0f:
+ msr.ps_control_addr = MSR_0FH_CONTROL;
+ msr.ps_status_addr = MSR_0FH_STATUS;
+ break;
+
case 0x10:
case 0x11:
msr.ps_control_addr = MSR_10H_CONTROL;
@@ -421,6 +476,9 @@
ps = &sc->sc_pstate[i];
+ if (msr.ps_flags != 0)
+ ps->ps_flags |= msr.ps_flags;
+
if (msr.ps_status_addr != 0)
ps->ps_status_addr = msr.ps_status_addr;
@@ -466,11 +524,14 @@
uint64_t val;
uint32_t i;
+ if ((sc->sc_flags & ACPICPU_FLAG_P_FIDVID) != 0)
+ return acpicpu_md_pstate_fidvid_get(sc, freq);
+
for (i = 0; i < sc->sc_pstate_count; i++) {
ps = &sc->sc_pstate[i];
- if (ps->ps_freq != 0)
+ if (__predict_true(ps->ps_freq != 0))
break;
}
@@ -489,7 +550,7 @@
ps = &sc->sc_pstate[i];
- if (ps->ps_freq == 0)
+ if (__predict_false(ps->ps_freq == 0))
continue;
if (val == ps->ps_status) {
@@ -508,6 +569,9 @@
uint64_t xc;
int rv = 0;
+ if ((ps->ps_flags & ACPICPU_FLAG_P_FIDVID) != 0)
+ return acpicpu_md_pstate_fidvid_set(ps);
+
msr.msr_read = false;
msr.msr_type = ps->ps_control_addr;
Home |
Main Index |
Thread Index |
Old Index