diff options
author | njl <njl@FreeBSD.org> | 2003-10-18 22:25:07 +0000 |
---|---|---|
committer | njl <njl@FreeBSD.org> | 2003-10-18 22:25:07 +0000 |
commit | 8689796a4b7db48eb94863f228f183d526c03134 (patch) | |
tree | d0d76931498b719475fa35837a3e8a739d9a033c /sys | |
parent | fb13ea0aa949c066e3a08be2fd0c4cde79a61d21 (diff) | |
download | FreeBSD-src-8689796a4b7db48eb94863f228f183d526c03134.zip FreeBSD-src-8689796a4b7db48eb94863f228f183d526c03134.tar.gz |
Add the cpu_idle_hook() function pointer so that other idlers can be
hooked at runtime. Make C1 sleep (e.g., HLT) be the default. This
prepares the way for further ACPI sleep states.
Diffstat (limited to 'sys')
-rw-r--r-- | sys/amd64/amd64/machdep.c | 26 | ||||
-rw-r--r-- | sys/i386/i386/machdep.c | 26 | ||||
-rw-r--r-- | sys/ia64/ia64/machdep.c | 13 | ||||
-rw-r--r-- | sys/sys/proc.h | 1 |
4 files changed, 46 insertions, 20 deletions
diff --git a/sys/amd64/amd64/machdep.c b/sys/amd64/amd64/machdep.c index 33687b7..65dd0eb 100644 --- a/sys/amd64/amd64/machdep.c +++ b/sys/amd64/amd64/machdep.c @@ -455,6 +455,17 @@ static int cpu_idle_hlt = 1; SYSCTL_INT(_machdep, OID_AUTO, cpu_idle_hlt, CTLFLAG_RW, &cpu_idle_hlt, 0, "Idle loop HLT enable"); +static void +cpu_idle_default(void) +{ + /* + * we must absolutely guarentee that hlt is the + * absolute next instruction after sti or we + * introduce a timing window. + */ + __asm __volatile("sti; hlt"); +} + /* * Note that we have to be careful here to avoid a race between checking * sched_runnable() and actually halting. If we don't do this, we may waste @@ -467,19 +478,16 @@ cpu_idle(void) if (cpu_idle_hlt) { disable_intr(); - if (sched_runnable()) { + if (sched_runnable()) enable_intr(); - } else { - /* - * we must absolutely guarentee that hlt is the - * absolute next instruction after sti or we - * introduce a timing window. - */ - __asm __volatile("sti; hlt"); - } + else + (*cpu_idle_hook)(); } } +/* Other subsystems (e.g., ACPI) can hook this later. */ +void (*cpu_idle_hook)(void) = cpu_idle_default; + /* * Clear registers on exec */ diff --git a/sys/i386/i386/machdep.c b/sys/i386/i386/machdep.c index a0ff4a2..e2ceead 100644 --- a/sys/i386/i386/machdep.c +++ b/sys/i386/i386/machdep.c @@ -1033,6 +1033,17 @@ static int cpu_idle_hlt = 1; SYSCTL_INT(_machdep, OID_AUTO, cpu_idle_hlt, CTLFLAG_RW, &cpu_idle_hlt, 0, "Idle loop HLT enable"); +static void +cpu_idle_default(void) +{ + /* + * we must absolutely guarentee that hlt is the + * absolute next instruction after sti or we + * introduce a timing window. + */ + __asm __volatile("sti; hlt"); +} + /* * Note that we have to be careful here to avoid a race between checking * sched_runnable() and actually halting. If we don't do this, we may waste @@ -1050,19 +1061,16 @@ cpu_idle(void) if (cpu_idle_hlt) { disable_intr(); - if (sched_runnable()) { + if (sched_runnable()) enable_intr(); - } else { - /* - * we must absolutely guarentee that hlt is the - * absolute next instruction after sti or we - * introduce a timing window. - */ - __asm __volatile("sti; hlt"); - } + else + (*cpu_idle_hook)(); } } +/* Other subsystems (e.g., ACPI) can hook this later. */ +void (*cpu_idle_hook)(void) = cpu_idle_default; + /* * Clear registers on exec */ diff --git a/sys/ia64/ia64/machdep.c b/sys/ia64/ia64/machdep.c index c533671..9d271c1 100644 --- a/sys/ia64/ia64/machdep.c +++ b/sys/ia64/ia64/machdep.c @@ -278,8 +278,8 @@ cpu_halt() ia64_efi_runtime->ResetSystem(EfiResetWarm, EFI_SUCCESS, 0, 0); } -void -cpu_idle() +static void +cpu_idle_default(void) { struct ia64_pal_result res; @@ -287,6 +287,15 @@ cpu_idle() } void +cpu_idle() +{ + (*cpu_idle_hook)(); +} + +/* Other subsystems (e.g., ACPI) can hook this later. */ +void (*cpu_idle_hook)(void) = cpu_idle_default; + +void cpu_reset() { diff --git a/sys/sys/proc.h b/sys/sys/proc.h index 8fc6b6f..2ff8a0b 100644 --- a/sys/sys/proc.h +++ b/sys/sys/proc.h @@ -865,6 +865,7 @@ int sigonstack(size_t sp); void sleepinit(void); void stopevent(struct proc *, u_int, u_int); void cpu_idle(void); +extern void (*cpu_idle_hook)(void); /* Hook to machdep CPU idler. */ void cpu_switch(struct thread *old, struct thread *new); void cpu_throw(struct thread *old, struct thread *new) __dead2; void unsleep(struct thread *); |