summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authormarcel <marcel@FreeBSD.org>2011-06-06 19:06:15 +0000
committermarcel <marcel@FreeBSD.org>2011-06-06 19:06:15 +0000
commitb85f2958405471837cf29da0149697935f47e464 (patch)
treeaa44b9eae54b3faaf88b0f579422ade75d862e10 /sys
parent2157ebafe521d9b08c3b5fc99e5f19eac4530377 (diff)
downloadFreeBSD-src-b85f2958405471837cf29da0149697935f47e464.zip
FreeBSD-src-b85f2958405471837cf29da0149697935f47e464.tar.gz
Improve cpu_idle():
o cpu_idle_hook is expected to be called with interrupts disabled and re-enables interrupts on return. o sync with x86: don't idle when the CPU has runnable tasks o have callers of ia64_call_pal_static() disable interrupts and re-enable interrupts. o add, but compile-out, support for idle mode. This will be enabled at some later time, after proper testing.
Diffstat (limited to 'sys')
-rw-r--r--sys/ia64/acpica/acpi_machdep.c7
-rw-r--r--sys/ia64/ia64/machdep.c33
-rw-r--r--sys/ia64/ia64/pal.S25
3 files changed, 47 insertions, 18 deletions
diff --git a/sys/ia64/acpica/acpi_machdep.c b/sys/ia64/acpica/acpi_machdep.c
index b7b612f..1466cfe 100644
--- a/sys/ia64/acpica/acpi_machdep.c
+++ b/sys/ia64/acpica/acpi_machdep.c
@@ -56,7 +56,14 @@ acpi_machdep_quirks(int *quirks)
void
acpi_cpu_c1()
{
+#ifdef INVARIANTS
+ register_t ie;
+
+ ie = intr_disable();
+ KASSERT(ie == 0, ("%s called with interrupts enabled\n", __func__));
+#endif
ia64_call_pal_static(PAL_HALT_LIGHT, 0, 0, 0);
+ ia64_enable_intr();
}
void *
diff --git a/sys/ia64/ia64/machdep.c b/sys/ia64/ia64/machdep.c
index 7252865..fc7df7a 100644
--- a/sys/ia64/ia64/machdep.c
+++ b/sys/ia64/ia64/machdep.c
@@ -411,12 +411,34 @@ cpu_halt()
void
cpu_idle(int busy)
{
- struct ia64_pal_result res;
+ register_t ie;
- if (cpu_idle_hook != NULL)
+#if 0
+ if (!busy) {
+ critical_enter();
+ cpu_idleclock();
+ }
+#endif
+
+ ie = intr_disable();
+ KASSERT(ie != 0, ("%s called with interrupts disabled\n", __func__));
+
+ if (sched_runnable())
+ ia64_enable_intr();
+ else if (cpu_idle_hook != NULL) {
(*cpu_idle_hook)();
- else
- res = ia64_call_pal_static(PAL_HALT_LIGHT, 0, 0, 0);
+ /* The hook must enable interrupts! */
+ } else {
+ ia64_call_pal_static(PAL_HALT_LIGHT, 0, 0, 0);
+ ia64_enable_intr();
+ }
+
+#if 0
+ if (!busy) {
+ cpu_activeclock();
+ critical_exit();
+ }
+#endif
}
int
@@ -644,9 +666,12 @@ calculate_frequencies(void)
{
struct ia64_sal_result sal;
struct ia64_pal_result pal;
+ register_t ie;
+ ie = intr_disable();
sal = ia64_sal_entry(SAL_FREQ_BASE, 0, 0, 0, 0, 0, 0, 0);
pal = ia64_call_pal_static(PAL_FREQ_RATIOS, 0, 0, 0);
+ intr_restore(ie);
if (sal.sal_status == 0 && pal.pal_status == 0) {
if (bootverbose) {
diff --git a/sys/ia64/ia64/pal.S b/sys/ia64/ia64/pal.S
index 2f0d0da..2e3f4cd 100644
--- a/sys/ia64/ia64/pal.S
+++ b/sys/ia64/ia64/pal.S
@@ -38,43 +38,40 @@ ia64_pal_entry: .quad 0
* u_int64_t arg1, u_int64_t arg2, u_int64_t arg3)
*/
ENTRY(ia64_call_pal_static, 4)
-
- .regstk 4,5,0,0
+
+ .regstk 4,4,0,0
palret = loc0
entry = loc1
rpsave = loc2
pfssave = loc3
-psrsave = loc4
- alloc pfssave=ar.pfs,4,5,0,0
+ alloc pfssave=ar.pfs,4,4,0,0
;;
mov rpsave=rp
-
movl entry=@gprel(ia64_pal_entry)
+
1: mov palret=ip // for return address
;;
add entry=entry,gp
- mov psrsave=psr
+ add palret=2f-1b,palret // calculate return address
mov r28=in0 // procedure number
- ;;
- ld8 entry=[entry] // read entry point
mov r29=in1 // copy arguments
mov r30=in2
mov r31=in3
;;
- mov b6=entry
- add palret=2f-1b,palret // calculate return address
- ;;
+ ld8 entry=[entry] // read entry point
mov b0=palret
- rsm psr.i // disable interrupts
+ ;;
+ mov b6=entry
;;
br.cond.sptk b6 // call into firmware
-2: mov psr.l=psrsave
+ ;;
+2:
mov rp=rpsave
mov ar.pfs=pfssave
;;
- srlz.d
br.ret.sptk rp
+ ;;
END(ia64_call_pal_static)
/*
OpenPOWER on IntegriCloud