diff options
author | Chris Metcalf <cmetcalf@tilera.com> | 2011-02-28 15:22:40 -0500 |
---|---|---|
committer | Chris Metcalf <cmetcalf@tilera.com> | 2011-03-01 16:20:48 -0500 |
commit | 0b989cac90144565b8780ddde36e6a927f8ca7ba (patch) | |
tree | 5867cd253d019b8e23e9e581482c87551b32accb /arch/tile | |
parent | a5c149c8a00b247749d0f18c13b130069dcc36e3 (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.S | 16 |
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 | */ |
98 | STD_ENTRY(_cpu_idle) | 100 | STD_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 |