aboutsummaryrefslogtreecommitdiffstats
path: root/arch/tile
diff options
context:
space:
mode:
authorChris Metcalf <cmetcalf@tilera.com>2011-02-28 15:22:40 -0500
committerChris Metcalf <cmetcalf@tilera.com>2011-03-01 16:20:48 -0500
commit0b989cac90144565b8780ddde36e6a927f8ca7ba (patch)
tree5867cd253d019b8e23e9e581482c87551b32accb /arch/tile
parenta5c149c8a00b247749d0f18c13b130069dcc36e3 (diff)
arch/tile: use a cleaner technique to enable interrupt for cpu_idle()
Previously we used iret to atomically return to kernel PL with interrupts enabled. However, it turns out that we are architecturally guaranteed that we can just set and clear the "interrupt critical section" and only interrupt on the following instruction, so we now do that instead, since it's cleaner. Signed-off-by: Chris Metcalf <cmetcalf@tilera.com>
Diffstat (limited to 'arch/tile')
-rw-r--r--arch/tile/kernel/entry.S16
1 files changed, 5 insertions, 11 deletions
diff --git a/arch/tile/kernel/entry.S b/arch/tile/kernel/entry.S
index c3aa0676ed06..431e9ae60488 100644
--- a/arch/tile/kernel/entry.S
+++ b/arch/tile/kernel/entry.S
@@ -91,23 +91,17 @@ STD_ENTRY(smp_nap)
91 91
92/* 92/*
93 * Enable interrupts racelessly and then nap until interrupted. 93 * Enable interrupts racelessly and then nap until interrupted.
94 * Architecturally, we are guaranteed that enabling interrupts via
95 * mtspr to INTERRUPT_CRITICAL_SECTION only interrupts at the next PC.
94 * This function's _cpu_idle_nap address is special; see intvec.S. 96 * This function's _cpu_idle_nap address is special; see intvec.S.
95 * When interrupted at _cpu_idle_nap, we bump the PC forward 8, and 97 * When interrupted at _cpu_idle_nap, we bump the PC forward 8, and
96 * as a result return to the function that called _cpu_idle(). 98 * as a result return to the function that called _cpu_idle().
97 */ 99 */
98STD_ENTRY(_cpu_idle) 100STD_ENTRY(_cpu_idle)
99 { 101 movei r1, 1
100 lnk r0 102 mtspr INTERRUPT_CRITICAL_SECTION, r1
101 movei r1, KERNEL_PL
102 }
103 {
104 addli r0, r0, _cpu_idle_nap - .
105 mtspr INTERRUPT_CRITICAL_SECTION, r1
106 }
107 IRQ_ENABLE(r2, r3) /* unmask, but still with ICS set */ 103 IRQ_ENABLE(r2, r3) /* unmask, but still with ICS set */
108 mtspr SPR_EX_CONTEXT_K_1, r1 /* Kernel PL, ICS clear */ 104 mtspr INTERRUPT_CRITICAL_SECTION, zero
109 mtspr SPR_EX_CONTEXT_K_0, r0
110 iret
111 .global _cpu_idle_nap 105 .global _cpu_idle_nap
112_cpu_idle_nap: 106_cpu_idle_nap:
113 nap 107 nap