|
@@ -46,62 +46,47 @@
|
|
#include <asm/cpudata.h>
|
|
#include <asm/cpudata.h>
|
|
#include <asm/mmu_context.h>
|
|
#include <asm/mmu_context.h>
|
|
#include <asm/unistd.h>
|
|
#include <asm/unistd.h>
|
|
|
|
+#include <asm/hypervisor.h>
|
|
|
|
|
|
/* #define VERBOSE_SHOWREGS */
|
|
/* #define VERBOSE_SHOWREGS */
|
|
|
|
|
|
-/*
|
|
|
|
- * Nothing special yet...
|
|
|
|
- */
|
|
|
|
-void default_idle(void)
|
|
|
|
-{
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-#ifndef CONFIG_SMP
|
|
|
|
-
|
|
|
|
-/*
|
|
|
|
- * the idle loop on a Sparc... ;)
|
|
|
|
- */
|
|
|
|
-void cpu_idle(void)
|
|
|
|
|
|
+static void sparc64_yield(void)
|
|
{
|
|
{
|
|
- /* endless idle loop with no priority at all */
|
|
|
|
- for (;;) {
|
|
|
|
- /* If current->work.need_resched is zero we should really
|
|
|
|
- * setup for a system wakup event and execute a shutdown
|
|
|
|
- * instruction.
|
|
|
|
- *
|
|
|
|
- * But this requires writing back the contents of the
|
|
|
|
- * L2 cache etc. so implement this later. -DaveM
|
|
|
|
- */
|
|
|
|
- while (!need_resched())
|
|
|
|
- barrier();
|
|
|
|
|
|
+ if (tlb_type != hypervisor)
|
|
|
|
+ return;
|
|
|
|
|
|
- preempt_enable_no_resched();
|
|
|
|
- schedule();
|
|
|
|
- preempt_disable();
|
|
|
|
- check_pgt_cache();
|
|
|
|
|
|
+ clear_thread_flag(TIF_POLLING_NRFLAG);
|
|
|
|
+ smp_mb__after_clear_bit();
|
|
|
|
+
|
|
|
|
+ while (!need_resched()) {
|
|
|
|
+ unsigned long pstate;
|
|
|
|
+
|
|
|
|
+ /* Disable interrupts. */
|
|
|
|
+ __asm__ __volatile__(
|
|
|
|
+ "rdpr %%pstate, %0\n\t"
|
|
|
|
+ "andn %0, %1, %0\n\t"
|
|
|
|
+ "wrpr %0, %%g0, %%pstate"
|
|
|
|
+ : "=&r" (pstate)
|
|
|
|
+ : "i" (PSTATE_IE));
|
|
|
|
+
|
|
|
|
+ if (!need_resched())
|
|
|
|
+ sun4v_cpu_yield();
|
|
|
|
+
|
|
|
|
+ /* Re-enable interrupts. */
|
|
|
|
+ __asm__ __volatile__(
|
|
|
|
+ "rdpr %%pstate, %0\n\t"
|
|
|
|
+ "or %0, %1, %0\n\t"
|
|
|
|
+ "wrpr %0, %%g0, %%pstate"
|
|
|
|
+ : "=&r" (pstate)
|
|
|
|
+ : "i" (PSTATE_IE));
|
|
}
|
|
}
|
|
-}
|
|
|
|
|
|
|
|
-#else
|
|
|
|
|
|
+ set_thread_flag(TIF_POLLING_NRFLAG);
|
|
|
|
+}
|
|
|
|
|
|
-/*
|
|
|
|
- * the idle loop on a UltraMultiPenguin...
|
|
|
|
- *
|
|
|
|
- * TIF_POLLING_NRFLAG is set because we do not sleep the cpu
|
|
|
|
- * inside of the idler task, so an interrupt is not needed
|
|
|
|
- * to get a clean fast response.
|
|
|
|
- *
|
|
|
|
- * XXX Reverify this assumption... -DaveM
|
|
|
|
- *
|
|
|
|
- * Addendum: We do want it to do something for the signal
|
|
|
|
- * delivery case, we detect that by just seeing
|
|
|
|
- * if we are trying to send this to an idler or not.
|
|
|
|
- */
|
|
|
|
|
|
+/* The idle loop on sparc64. */
|
|
void cpu_idle(void)
|
|
void cpu_idle(void)
|
|
{
|
|
{
|
|
- cpuinfo_sparc *cpuinfo = &local_cpu_data();
|
|
|
|
set_thread_flag(TIF_POLLING_NRFLAG);
|
|
set_thread_flag(TIF_POLLING_NRFLAG);
|
|
|
|
|
|
while(1) {
|
|
while(1) {
|
|
@@ -109,13 +94,11 @@ void cpu_idle(void)
|
|
preempt_enable_no_resched();
|
|
preempt_enable_no_resched();
|
|
schedule();
|
|
schedule();
|
|
preempt_disable();
|
|
preempt_disable();
|
|
- check_pgt_cache();
|
|
|
|
}
|
|
}
|
|
|
|
+ sparc64_yield();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
-#endif
|
|
|
|
-
|
|
|
|
extern char reboot_command [];
|
|
extern char reboot_command [];
|
|
|
|
|
|
extern void (*prom_palette)(int);
|
|
extern void (*prom_palette)(int);
|