summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhilip Guenther <guenther@cvs.openbsd.org>2015-06-07 06:25:00 +0000
committerPhilip Guenther <guenther@cvs.openbsd.org>2015-06-07 06:25:00 +0000
commit879060768acca9d10c83640d78ed66f15d60833a (patch)
tree16b6b03cc91bf69b9ea51ffa50240d5665589061
parentdaed99d989a2ec4b7b14c32c4fb525b494d5e50b (diff)
Enable use of mwait in non-MP boxes and report # of C-substates up to C7,
truncating trailing zeros. Testing by many as part of a larger change to use ACPI _CST objects ok krw@
-rw-r--r--sys/arch/amd64/amd64/cpu.c39
-rw-r--r--sys/arch/amd64/amd64/machdep.c4
-rw-r--r--sys/arch/amd64/include/cpu.h10
-rw-r--r--sys/arch/i386/i386/cpu.c39
-rw-r--r--sys/arch/i386/i386/machdep.c4
-rw-r--r--sys/arch/i386/include/cpu.h9
6 files changed, 52 insertions, 53 deletions
diff --git a/sys/arch/amd64/amd64/cpu.c b/sys/arch/amd64/amd64/cpu.c
index 4337d0e2483..6dfeb13f00b 100644
--- a/sys/arch/amd64/amd64/cpu.c
+++ b/sys/arch/amd64/amd64/cpu.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: cpu.c,v 1.82 2015/04/18 22:16:21 kettenis Exp $ */
+/* $OpenBSD: cpu.c,v 1.83 2015/06/07 06:24:59 guenther Exp $ */
/* $NetBSD: cpu.c,v 1.1 2003/04/26 18:39:26 fvdl Exp $ */
/*-
@@ -234,10 +234,11 @@ cpu_vm_init(struct cpu_info *ci)
#endif
}
-#if defined(MULTIPROCESSOR)
+
void cpu_idle_mwait_cycle(void);
void cpu_init_mwait(struct cpu_softc *);
-void cpu_enable_mwait(void);
+
+u_int cpu_mwait_size, cpu_mwait_states;
void
cpu_idle_mwait_cycle(void)
@@ -261,7 +262,7 @@ cpu_idle_mwait_cycle(void)
* something to the queue and called cpu_unidle() between
* the check in sched_idle() and here.
*/
- atomic_setbits_int(&ci->ci_mwait, MWAIT_IDLING);
+ atomic_setbits_int(&ci->ci_mwait, MWAIT_IDLING | MWAIT_ONLY);
if (ci->ci_schedstate.spc_whichqs == 0) {
monitor(&ci->ci_mwait, 0, 0);
if ((ci->ci_mwait & MWAIT_IDLING) == MWAIT_IDLING)
@@ -272,8 +273,6 @@ cpu_idle_mwait_cycle(void)
atomic_clearbits_int(&ci->ci_mwait, MWAIT_IDLING);
}
-u_int cpu_mwait_size;
-
void
cpu_init_mwait(struct cpu_softc *sc)
{
@@ -283,21 +282,24 @@ cpu_init_mwait(struct cpu_softc *sc)
return;
/* get the monitor granularity */
- CPUID(0x5, smallest, largest, extensions, c_substates);
+ CPUID(0x5, smallest, largest, extensions, cpu_mwait_states);
smallest &= 0xffff;
largest &= 0xffff;
printf("%s: mwait min=%u, max=%u", sc->sc_dev.dv_xname,
smallest, largest);
if (extensions & 0x1) {
- printf(", C-substates=%u.%u.%u.%u.%u",
- 0xf & (c_substates),
- 0xf & (c_substates >> 4),
- 0xf & (c_substates >> 8),
- 0xf & (c_substates >> 12),
- 0xf & (c_substates >> 16));
+ if (cpu_mwait_states > 0) {
+ c_substates = cpu_mwait_states;
+ printf(", C-substates=%u", 0xf & c_substates);
+ while ((c_substates >>= 4) > 0)
+ printf(".%u", 0xf & c_substates);
+ }
if (extensions & 0x2)
printf(", IBE");
+ } else {
+ /* substates not supported, forge the default: just C1 */
+ cpu_mwait_states = 1 << 4;
}
/* paranoia: check the values */
@@ -307,15 +309,11 @@ cpu_init_mwait(struct cpu_softc *sc)
else
cpu_mwait_size = largest;
printf("\n");
-}
-void
-cpu_enable_mwait(void)
-{
+ /* enable use of mwait; may be overriden by acpicpu later */
if (cpu_mwait_size > 0)
cpu_idle_cycle_fcn = &cpu_idle_mwait_cycle;
}
-#endif /* MULTIPROCESSOR */
void
cpu_attach(struct device *parent, struct device *self, void *aux)
@@ -406,6 +404,7 @@ cpu_attach(struct device *parent, struct device *self, void *aux)
mem_range_attach();
#endif /* MTRR */
cpu_init(ci);
+ cpu_init_mwait(sc);
break;
case CPU_ROLE_BP:
@@ -428,9 +427,7 @@ cpu_attach(struct device *parent, struct device *self, void *aux)
#if NIOAPIC > 0
ioapic_bsp_id = caa->cpu_number;
#endif
-#if defined(MULTIPROCESSOR)
cpu_init_mwait(sc);
-#endif
break;
case CPU_ROLE_AP:
@@ -520,8 +517,6 @@ cpu_boot_secondary_processors(void)
struct cpu_info *ci;
u_long i;
- cpu_enable_mwait();
-
for (i=0; i < MAXCPUS; i++) {
ci = cpu_info[i];
if (ci == NULL)
diff --git a/sys/arch/amd64/amd64/machdep.c b/sys/arch/amd64/amd64/machdep.c
index 4d7be8a8466..e149b991a47 100644
--- a/sys/arch/amd64/amd64/machdep.c
+++ b/sys/arch/amd64/amd64/machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: machdep.c,v 1.212 2015/05/24 01:01:49 guenther Exp $ */
+/* $OpenBSD: machdep.c,v 1.213 2015/06/07 06:24:59 guenther Exp $ */
/* $NetBSD: machdep.c,v 1.3 2003/05/07 22:58:18 fvdl Exp $ */
/*-
@@ -698,7 +698,7 @@ signotify(struct proc *p)
void
cpu_unidle(struct cpu_info *ci)
{
- if (cpu_mwait_size > 0) {
+ if (cpu_mwait_size > 0 && (ci->ci_mwait & MWAIT_ONLY)) {
/*
* Just clear the "keep idling" bit; if it wasn't
* idling then we didn't need to do anything anyway.
diff --git a/sys/arch/amd64/include/cpu.h b/sys/arch/amd64/include/cpu.h
index a521fd6e773..a16fdb89b28 100644
--- a/sys/arch/amd64/include/cpu.h
+++ b/sys/arch/amd64/include/cpu.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: cpu.h,v 1.93 2015/05/28 20:10:58 guenther Exp $ */
+/* $OpenBSD: cpu.h,v 1.94 2015/06/07 06:24:59 guenther Exp $ */
/* $NetBSD: cpu.h,v 1.1 2003/04/26 18:39:39 fvdl Exp $ */
/*-
@@ -113,6 +113,7 @@ struct cpu_info {
volatile u_int ci_mwait;
#define MWAIT_IN_IDLE 0x1 /* don't need IPI to wake */
#define MWAIT_KEEP_IDLING 0x2 /* cleared by other cpus to wake me */
+#define MWAIT_ONLY 0x4 /* set if all idle states use mwait */
#define MWAIT_IDLING (MWAIT_IN_IDLE | MWAIT_KEEP_IDLING)
int ci_want_resched;
@@ -193,8 +194,6 @@ extern struct cpu_info *cpu_info[MAXCPUS];
void cpu_boot_secondary_processors(void);
void cpu_init_idle_pcbs(void);
-extern u_int cpu_mwait_size;
-
void cpu_kick(struct cpu_info *);
void cpu_unidle(struct cpu_info *);
@@ -273,6 +272,7 @@ struct timeval;
#ifdef _KERNEL
+/* locore.S */
extern int biosbasemem;
extern int biosextmem;
extern int cpu;
@@ -288,6 +288,10 @@ extern char cpu_vendor[];
extern int cpuid_level;
extern int cpuspeed;
+/* cpu.c */
+extern u_int cpu_mwait_size;
+extern u_int cpu_mwait_states;
+
/* identcpu.c */
void identifycpu(struct cpu_info *);
int cpu_amd64speed(int *);
diff --git a/sys/arch/i386/i386/cpu.c b/sys/arch/i386/i386/cpu.c
index a58e811cd31..123896286e7 100644
--- a/sys/arch/i386/i386/cpu.c
+++ b/sys/arch/i386/i386/cpu.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: cpu.c,v 1.63 2015/04/19 06:27:17 sf Exp $ */
+/* $OpenBSD: cpu.c,v 1.64 2015/06/07 06:24:59 guenther Exp $ */
/* $NetBSD: cpu.c,v 1.1.2.7 2000/06/26 02:04:05 sommerfeld Exp $ */
/*-
@@ -113,7 +113,8 @@ int cpu_activate(struct device *, int);
void patinit(struct cpu_info *ci);
void cpu_idle_mwait_cycle(void);
void cpu_init_mwait(struct device *);
-void cpu_enable_mwait(void);
+
+u_int cpu_mwait_size, cpu_mwait_states;
#ifdef MULTIPROCESSOR
int mp_cpu_start(struct cpu_info *);
@@ -289,6 +290,7 @@ cpu_attach(struct device *parent, struct device *self, void *aux)
mem_range_attach();
#endif
cpu_init(ci);
+ cpu_init_mwait(&ci->ci_dev);
break;
case CPU_ROLE_BP:
@@ -310,9 +312,7 @@ cpu_attach(struct device *parent, struct device *self, void *aux)
#if NIOAPIC > 0
ioapic_bsp_id = caa->cpu_number;
#endif
-#if defined(MULTIPROCESSOR)
cpu_init_mwait(&ci->ci_dev);
-#endif
break;
case CPU_ROLE_AP:
@@ -481,8 +481,6 @@ cpu_boot_secondary_processors()
struct cpu_info *ci;
u_long i;
- cpu_enable_mwait();
-
for (i = 0; i < MAXCPUS; i++) {
ci = cpu_info[i];
if (ci == NULL)
@@ -740,6 +738,8 @@ mp_cpu_start_cleanup(struct cpu_info *ci)
outb(IO_RTC+1, NVRAM_RESET_RST);
}
+#endif /* MULTIPROCESSOR */
+
void
cpu_idle_mwait_cycle(void)
{
@@ -762,7 +762,7 @@ cpu_idle_mwait_cycle(void)
* something to the queue and called cpu_unidle() between
* the check in sched_idle() and here.
*/
- atomic_setbits_int(&ci->ci_mwait, MWAIT_IDLING);
+ atomic_setbits_int(&ci->ci_mwait, MWAIT_IDLING | MWAIT_ONLY);
if (ci->ci_schedstate.spc_whichqs == 0) {
monitor(&ci->ci_mwait, 0, 0);
if ((ci->ci_mwait & MWAIT_IDLING) == MWAIT_IDLING)
@@ -773,8 +773,6 @@ cpu_idle_mwait_cycle(void)
atomic_clearbits_int(&ci->ci_mwait, MWAIT_IDLING);
}
-u_int cpu_mwait_size;
-
void
cpu_init_mwait(struct device *dv)
{
@@ -784,20 +782,23 @@ cpu_init_mwait(struct device *dv)
return;
/* get the monitor granularity */
- CPUID(0x5, smallest, largest, extensions, c_substates);
+ CPUID(0x5, smallest, largest, extensions, cpu_mwait_states);
smallest &= 0xffff;
largest &= 0xffff;
printf("%s: mwait min=%u, max=%u", dv->dv_xname, smallest, largest);
if (extensions & 0x1) {
- printf(", C-substates=%u.%u.%u.%u.%u",
- 0xf & (c_substates),
- 0xf & (c_substates >> 4),
- 0xf & (c_substates >> 8),
- 0xf & (c_substates >> 12),
- 0xf & (c_substates >> 16));
+ if (cpu_mwait_states > 0) {
+ c_substates = cpu_mwait_states;
+ printf(", C-substates=%u", 0xf & c_substates);
+ while ((c_substates >>= 4) > 0)
+ printf(".%u", 0xf & c_substates);
+ }
if (extensions & 0x2)
printf(", IBE");
+ } else {
+ /* substates not supported, forge the default: just C1 */
+ cpu_mwait_states = 1 << 4;
}
/* paranoia: check the values */
@@ -807,13 +808,9 @@ cpu_init_mwait(struct device *dv)
else
cpu_mwait_size = largest;
printf("\n");
-}
-void
-cpu_enable_mwait(void)
-{
+ /* enable use of mwait; may be overriden by acpicpu later */
if (cpu_mwait_size > 0)
cpu_idle_cycle_fcn = &cpu_idle_mwait_cycle;
}
-#endif /* MULTIPROCESSOR */
diff --git a/sys/arch/i386/i386/machdep.c b/sys/arch/i386/i386/machdep.c
index 1aa2ba82fbd..74ffa958595 100644
--- a/sys/arch/i386/i386/machdep.c
+++ b/sys/arch/i386/i386/machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: machdep.c,v 1.570 2015/05/28 20:10:58 guenther Exp $ */
+/* $OpenBSD: machdep.c,v 1.571 2015/06/07 06:24:59 guenther Exp $ */
/* $NetBSD: machdep.c,v 1.214 1996/11/10 03:16:17 thorpej Exp $ */
/*-
@@ -2577,7 +2577,7 @@ signotify(struct proc *p)
void
cpu_unidle(struct cpu_info *ci)
{
- if (cpu_mwait_size > 0) {
+ if (cpu_mwait_size > 0 && (ci->ci_mwait & MWAIT_ONLY)) {
/*
* Just clear the "keep idling" bit; if it wasn't
* idling then we didn't need to do anything anyway.
diff --git a/sys/arch/i386/include/cpu.h b/sys/arch/i386/include/cpu.h
index 623154e993d..0c52c8eb5e6 100644
--- a/sys/arch/i386/include/cpu.h
+++ b/sys/arch/i386/include/cpu.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: cpu.h,v 1.140 2015/05/28 20:10:58 guenther Exp $ */
+/* $OpenBSD: cpu.h,v 1.141 2015/06/07 06:24:59 guenther Exp $ */
/* $NetBSD: cpu.h,v 1.35 1996/05/05 19:29:26 christos Exp $ */
/*-
@@ -130,6 +130,7 @@ struct cpu_info {
volatile u_int ci_mwait;
#define MWAIT_IN_IDLE 0x1 /* don't need IPI to wake */
#define MWAIT_KEEP_IDLING 0x2 /* cleared by other cpus to wake me */
+#define MWAIT_ONLY 0x4 /* set if all idle states use mwait */
#define MWAIT_IDLING (MWAIT_IN_IDLE | MWAIT_KEEP_IDLING)
int ci_want_resched;
@@ -214,8 +215,6 @@ extern struct cpu_info *cpu_info[MAXCPUS];
extern void cpu_boot_secondary_processors(void);
extern void cpu_init_idle_pcbs(void);
-extern u_int cpu_mwait_size;
-
void cpu_kick(struct cpu_info *);
void cpu_unidle(struct cpu_info *);
@@ -336,6 +335,10 @@ extern int cpu_perf_ebx;
extern int cpu_perf_edx;
extern int cpu_apmi_edx;
+/* cpu.c */
+extern u_int cpu_mwait_size;
+extern u_int cpu_mwait_states;
+
/* machdep.c */
extern int cpu_apmhalt;
extern int cpu_class;