-/* $OpenBSD: cpu.c,v 1.81 2015/03/25 21:05:18 kettenis Exp $ */
+/* $OpenBSD: cpu.c,v 1.82 2015/04/18 22:16:21 kettenis Exp $ */
/* $NetBSD: cpu.c,v 1.1 2003/04/26 18:39:26 fvdl Exp $ */
/*-
cpu_idle_mwait_cycle(void)
{
struct cpu_info *ci = curcpu();
- volatile int *state = &ci->ci_mwait[0];
if ((read_rflags() & PSL_I) == 0)
panic("idle with interrupts blocked!");
* something to the queue and called cpu_unidle() between
* the check in sched_idle() and here.
*/
- atomic_setbits_int(state, MWAIT_IDLING);
+ atomic_setbits_int(&ci->ci_mwait, MWAIT_IDLING);
if (ci->ci_schedstate.spc_whichqs == 0) {
- monitor(state, 0, 0);
- if ((*state & MWAIT_IDLING) == MWAIT_IDLING)
+ monitor(&ci->ci_mwait, 0, 0);
+ if ((ci->ci_mwait & MWAIT_IDLING) == MWAIT_IDLING)
mwait(0, 0);
}
/* done idling; let cpu_kick() know that an IPI is required */
- atomic_clearbits_int(state, MWAIT_IDLING);
+ atomic_clearbits_int(&ci->ci_mwait, MWAIT_IDLING);
}
-unsigned int mwait_size;
+u_int cpu_mwait_size;
void
cpu_init_mwait(struct cpu_softc *sc)
(largest & (sizeof(int)-1)))
printf(" (bogus)");
else
- mwait_size = largest;
+ cpu_mwait_size = largest;
printf("\n");
- /* XXX disable mwait: ACPI says not to use it on too many systems */
- mwait_size = 0;
}
void
cpu_enable_mwait(void)
{
- unsigned long area;
- struct cpu_info *ci;
- CPU_INFO_ITERATOR cii;
-
- if (mwait_size == 0)
- return;
-
- /*
- * Allocate the area, with a bit extra so that we can align
- * to a multiple of mwait_size
- */
- area = (unsigned long)malloc((ncpus * mwait_size) + mwait_size
- - sizeof(int), M_DEVBUF, M_NOWAIT|M_ZERO);
- if (area == 0) {
- printf("cpu0: mwait failed\n");
- } else {
- /* round to a multiple of mwait_size */
- area = ((area + mwait_size - sizeof(int)) / mwait_size)
- * mwait_size;
- CPU_INFO_FOREACH(cii, ci) {
- ci->ci_mwait = (int *)area;
- area += mwait_size;
- }
+ if (cpu_mwait_size > 0)
cpu_idle_cycle_fcn = &cpu_idle_mwait_cycle;
- }
}
#endif /* MULTIPROCESSOR */
-/* $OpenBSD: machdep.c,v 1.208 2015/03/25 21:05:18 kettenis Exp $ */
+/* $OpenBSD: machdep.c,v 1.209 2015/04/18 22:16:21 kettenis Exp $ */
/* $NetBSD: machdep.c,v 1.3 2003/05/07 22:58:18 fvdl Exp $ */
/*-
{
/* only need to kick other CPUs */
if (ci != curcpu()) {
- if (ci->ci_mwait != NULL) {
+ if (cpu_mwait_size > 0) {
/*
* If not idling, then send an IPI, else
* just clear the "keep idling" bit.
*/
- if ((ci->ci_mwait[0] & MWAIT_IN_IDLE) == 0)
+ if ((ci->ci_mwait & MWAIT_IN_IDLE) == 0)
x86_send_ipi(ci, X86_IPI_NOP);
else
- atomic_clearbits_int(&ci->ci_mwait[0],
+ atomic_clearbits_int(&ci->ci_mwait,
MWAIT_KEEP_IDLING);
} else {
/* no mwait, so need an IPI */
void
cpu_unidle(struct cpu_info *ci)
{
- if (ci->ci_mwait != NULL) {
+ if (cpu_mwait_size > 0) {
/*
* Just clear the "keep idling" bit; if it wasn't
* idling then we didn't need to do anything anyway.
*/
- atomic_clearbits_int(&ci->ci_mwait[0], MWAIT_KEEP_IDLING);
+ atomic_clearbits_int(&ci->ci_mwait, MWAIT_KEEP_IDLING);
return;
}
-/* $OpenBSD: cpu.h,v 1.90 2015/01/15 15:30:17 sf Exp $ */
+/* $OpenBSD: cpu.h,v 1.91 2015/04/18 22:16:21 kettenis Exp $ */
/* $NetBSD: cpu.h,v 1.1 2003/04/26 18:39:39 fvdl Exp $ */
/*-
void (*cpu_setup)(struct cpu_info *);
void (*ci_info)(struct cpu_info *);
- u_int *ci_mwait;
-/* bits in ci_mwait[0] */
+ 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_IDLING (MWAIT_IN_IDLE | MWAIT_KEEP_IDLING)
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 *);
-/* $OpenBSD: cpu.c,v 1.61 2015/02/11 05:54:48 dlg Exp $ */
+/* $OpenBSD: cpu.c,v 1.62 2015/04/18 22:16:21 kettenis Exp $ */
/* $NetBSD: cpu.c,v 1.1.2.7 2000/06/26 02:04:05 sommerfeld Exp $ */
/*-
cpu_idle_mwait_cycle(void)
{
struct cpu_info *ci = curcpu();
- volatile int *state = &ci->ci_mwait[0];
if ((read_eflags() & PSL_I) == 0)
panic("idle with interrupts blocked!");
* something to the queue and called cpu_unidle() between
* the check in sched_idle() and here.
*/
- atomic_setbits_int(state, MWAIT_IDLING);
+ atomic_setbits_int(&ci->ci_mwait, MWAIT_IDLING);
if (ci->ci_schedstate.spc_whichqs == 0) {
- monitor(state, 0, 0);
- if ((*state & MWAIT_IDLING) == MWAIT_IDLING)
+ monitor(&ci->ci_mwait, 0, 0);
+ if ((ci->ci_mwait & MWAIT_IDLING) == MWAIT_IDLING)
mwait(0, 0);
}
/* done idling; let cpu_kick() know that an IPI is required */
- atomic_clearbits_int(state, MWAIT_IDLING);
+ atomic_clearbits_int(&ci->ci_mwait, MWAIT_IDLING);
}
-unsigned int mwait_size;
+u_int cpu_mwait_size;
void
cpu_init_mwait(struct device *dv)
(largest & (sizeof(int)-1)))
printf(" (bogus)");
else
- mwait_size = largest;
+ cpu_mwait_size = largest;
printf("\n");
- /* XXX disable mwait: ACPI says not to use it on too many systems */
- mwait_size = 0;
}
void
cpu_enable_mwait(void)
{
- unsigned long area;
- struct cpu_info *ci;
- CPU_INFO_ITERATOR cii;
-
- if (mwait_size == 0)
- return;
-
- /*
- * Allocate the area, with a bit extra so that we can align
- * to a multiple of mwait_size
- */
- area = (unsigned long)malloc((ncpus * mwait_size) + mwait_size
- - sizeof(int), M_DEVBUF, M_NOWAIT|M_ZERO);
- if (area == 0) {
- printf("cpu0: mwait failed\n");
- } else {
- /* round to a multiple of mwait_size */
- area = ((area + mwait_size - sizeof(int)) / mwait_size)
- * mwait_size;
- CPU_INFO_FOREACH(cii, ci) {
- ci->ci_mwait = (int *)area;
- area += mwait_size;
- }
+ if (cpu_mwait_size > 0)
cpu_idle_cycle_fcn = &cpu_idle_mwait_cycle;
- }
}
#endif /* MULTIPROCESSOR */
-/* $OpenBSD: machdep.c,v 1.568 2015/04/12 18:37:53 mlarkin Exp $ */
+/* $OpenBSD: machdep.c,v 1.569 2015/04/18 22:16:21 kettenis Exp $ */
/* $NetBSD: machdep.c,v 1.214 1996/11/10 03:16:17 thorpej Exp $ */
/*-
{
/* only need to kick other CPUs */
if (ci != curcpu()) {
- if (ci->ci_mwait != NULL) {
+ if (cpu_mwait_size > 0) {
/*
* If not idling, then send an IPI, else
* just clear the "keep idling" bit.
*/
- if ((ci->ci_mwait[0] & MWAIT_IN_IDLE) == 0)
+ if ((ci->ci_mwait & MWAIT_IN_IDLE) == 0)
i386_send_ipi(ci, I386_IPI_NOP);
else
- atomic_clearbits_int(&ci->ci_mwait[0],
+ atomic_clearbits_int(&ci->ci_mwait,
MWAIT_KEEP_IDLING);
} else {
/* no mwait, so need an IPI */
void
cpu_unidle(struct cpu_info *ci)
{
- if (ci->ci_mwait != NULL) {
+ if (cpu_mwait_size > 0) {
/*
* Just clear the "keep idling" bit; if it wasn't
* idling then we didn't need to do anything anyway.
*/
- atomic_clearbits_int(&ci->ci_mwait[0], MWAIT_KEEP_IDLING);
+ atomic_clearbits_int(&ci->ci_mwait, MWAIT_KEEP_IDLING);
return;
}
-/* $OpenBSD: cpu.h,v 1.138 2015/04/12 18:37:54 mlarkin Exp $ */
+/* $OpenBSD: cpu.h,v 1.139 2015/04/18 22:16:21 kettenis Exp $ */
/* $NetBSD: cpu.h,v 1.35 1996/05/05 19:29:26 christos Exp $ */
/*-
struct cpu_functions *ci_func; /* start/stop functions */
void (*cpu_setup)(struct cpu_info *); /* proc-dependant init */
- u_int *ci_mwait;
-/* bits in ci_mwait[0] */
+ 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_IDLING (MWAIT_IN_IDLE | MWAIT_KEEP_IDLING)
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 *);