diff options
author | Philip Guenther <guenther@cvs.openbsd.org> | 2015-06-07 06:25:00 +0000 |
---|---|---|
committer | Philip Guenther <guenther@cvs.openbsd.org> | 2015-06-07 06:25:00 +0000 |
commit | 879060768acca9d10c83640d78ed66f15d60833a (patch) | |
tree | 16b6b03cc91bf69b9ea51ffa50240d5665589061 | |
parent | daed99d989a2ec4b7b14c32c4fb525b494d5e50b (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.c | 39 | ||||
-rw-r--r-- | sys/arch/amd64/amd64/machdep.c | 4 | ||||
-rw-r--r-- | sys/arch/amd64/include/cpu.h | 10 | ||||
-rw-r--r-- | sys/arch/i386/i386/cpu.c | 39 | ||||
-rw-r--r-- | sys/arch/i386/i386/machdep.c | 4 | ||||
-rw-r--r-- | sys/arch/i386/include/cpu.h | 9 |
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; |