@@ -104,48 +104,59 @@ handle_vcei:
104104
105105 __FINIT
106106
107- .align 5 /* 32 byte rollback region */
108- LEAF(__r4k_wait)
109- .set push
110- .set noreorder
111- /* start of rollback region */
112- LONG_L t0, TI_FLAGS($28 )
113- nop
114- andi t0, _TIF_NEED_RESCHED
115- bnez t0, 1f
116- nop
117- nop
118- nop
119- #ifdef CONFIG_CPU_MICROMIPS
120- nop
121- nop
122- nop
123- nop
124- #endif
107+ .section .cpuidle.text,"ax"
108+ /* Align to 32 bytes for the maximum idle interrupt region size. */
109+ .align 5
110+ LEAF(r4k_wait)
111+ /* Keep the ISA bit clear for calculations on local labels here. */
112+ 0: .fill 0
113+ /* Start of idle interrupt region. */
114+ local_irq_enable
115+ /*
116+ * If an interrupt lands here, before going idle on the next
117+ * instruction, we must *NOT* go idle since the interrupt could
118+ * have set TIF_NEED_RESCHED or caused a timer to need resched.
119+ * Fall through -- see skipover_handler below -- and have the
120+ * idle loop take care of things.
121+ */
122+ 1: .fill 0
123+ /* The R2 EI/EHB sequence takes 8 bytes, otherwise pad up. */
124+ .if 1b - 0b > 32
125+ .error "overlong idle interrupt region"
126+ .elseif 1b - 0b > 8
127+ .align 4
128+ .endif
129+ 2: .fill 0
130+ .equ r4k_wait_idle_size, 2b - 0b
131+ /* End of idle interrupt region; size has to be a power of 2. */
125132 .set MIPS_ISA_ARCH_LEVEL_RAW
133+ r4k_wait_insn:
126134 wait
127- /* end of rollback region (the region size must be power of two) */
128- 1:
135+ r4k_wait_exit:
136+ .set mips0
137+ local_irq_disable
129138 jr ra
130- nop
131- .set pop
132- END(__r4k_wait)
139+ END(r4k_wait)
140+ .previous
133141
134- .macro BUILD_ROLLBACK_PROLOGUE handler
135- FEXPORT(rollback_ \handler)
142+ .macro BUILD_SKIPOVER_PROLOGUE handler
143+ FEXPORT(skipover_ \handler)
136144 .set push
137145 .set noat
138146 MFC0 k0, CP0_EPC
139- PTR_LA k1, __r4k_wait
140- ori k0, 0x1f /* 32 byte rollback region */
141- xori k0, 0x1f
147+ /* Subtract/add 2 to let the ISA bit propagate through the mask. */
148+ PTR_LA k1, r4k_wait_insn - 2
149+ ori k0, r4k_wait_idle_size - 2
150+ .set noreorder
142151 bne k0, k1, \handler
152+ PTR_ADDIU k0, r4k_wait_exit - r4k_wait_insn + 2
153+ .set reorder
143154 MTC0 k0, CP0_EPC
144155 .set pop
145156 .endm
146157
147158 .align 5
148- BUILD_ROLLBACK_PROLOGUE handle_int
159+ BUILD_SKIPOVER_PROLOGUE handle_int
149160NESTED(handle_int, PT_SIZE, sp)
150161 .cfi_signal_frame
151162#ifdef CONFIG_TRACE_IRQFLAGS
@@ -265,7 +276,7 @@ NESTED(except_vec_ejtag_debug, 0, sp)
265276 * This prototype is copied to ebase + n*IntCtl.VS and patched
266277 * to invoke the handler
267278 */
268- BUILD_ROLLBACK_PROLOGUE except_vec_vi
279+ BUILD_SKIPOVER_PROLOGUE except_vec_vi
269280NESTED(except_vec_vi, 0 , sp)
270281 SAVE_SOME docfi =1
271282 SAVE_AT docfi =1
0 commit comments