~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/arch/arc/kernel/entry-compact.S

Version: ~ [ linux-6.12-rc7 ] ~ [ linux-6.11.7 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.60 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.116 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.171 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.229 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.285 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.323 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.12 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /* SPDX-License-Identifier: GPL-2.0-only */
  2 /*
  3  * Low Level Interrupts/Traps/Exceptions(non-TLB) Handling for ARCompact ISA
  4  *
  5  * Copyright (C) 2014-15 Synopsys, Inc. (www.synopsys.com)
  6  * Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com)
  7  *
  8  * vineetg: May 2011
  9  *  -Userspace unaligned access emulation
 10  *
 11  * vineetg: Feb 2011 (ptrace low level code fixes)
 12  *  -traced syscall return code (r0) was not saved into pt_regs for restoring
 13  *   into user reg-file when traded task rets to user space.
 14  *  -syscalls needing arch-wrappers (mainly for passing sp as pt_regs)
 15  *   were not invoking post-syscall trace hook (jumping directly into
 16  *   ret_from_system_call)
 17  *
 18  * vineetg: Nov 2010:
 19  *  -Vector table jumps (@8 bytes) converted into branches (@4 bytes)
 20  *  -To maintain the slot size of 8 bytes/vector, added nop, which is
 21  *   not executed at runtime.
 22  *
 23  * vineetg: Nov 2009 (Everything needed for TIF_RESTORE_SIGMASK)
 24  *  -do_signal()invoked upon TIF_RESTORE_SIGMASK as well
 25  *  -Wrappers for sys_{,rt_}sigsuspend() no longer needed as they don't
 26  *   need ptregs anymore
 27  *
 28  * Vineetg: Oct 2009
 29  *  -In a rare scenario, Process gets a Priv-V exception and gets scheduled
 30  *   out. Since we don't do FAKE RTIE for Priv-V, CPU exception state remains
 31  *   active (AE bit enabled).  This causes a double fault for a subseq valid
 32  *   exception. Thus FAKE RTIE needed in low level Priv-Violation handler.
 33  *   Instr Error could also cause similar scenario, so same there as well.
 34  *
 35  * Vineetg: March 2009 (Supporting 2 levels of Interrupts)
 36  *
 37  * Vineetg: Aug 28th 2008: Bug #94984
 38  *  -Zero Overhead Loop Context shd be cleared when entering IRQ/EXcp/Trap
 39  *   Normally CPU does this automatically, however when doing FAKE rtie,
 40  *   we need to explicitly do this. The problem in macros
 41  *   FAKE_RET_FROM_EXCPN and FAKE_RET_FROM_EXCPN_LOCK_IRQ was that this bit
 42  *   was being "CLEARED" rather then "SET". Since it is Loop INHIBIT Bit,
 43  *   setting it and not clearing it clears ZOL context
 44  *
 45  * Vineetg: May 16th, 2008
 46  *  - r25 now contains the Current Task when in kernel
 47  *
 48  * Vineetg: Dec 22, 2007
 49  *    Minor Surgery of Low Level ISR to make it SMP safe
 50  *    - MMU_SCRATCH0 Reg used for freeing up r9 in Level 1 ISR
 51  *    - _current_task is made an array of NR_CPUS
 52  *    - Access of _current_task wrapped inside a macro so that if hardware
 53  *       team agrees for a dedicated reg, no other code is touched
 54  *
 55  * Amit Bhor, Rahul Trivedi, Kanika Nema, Sameer Dhavale : Codito Tech 2004
 56  */
 57 
 58 #include <linux/errno.h>
 59 #include <linux/linkage.h>      /* {ENTRY,EXIT} */
 60 #include <asm/entry.h>
 61 #include <asm/irqflags.h>
 62 
 63         .cpu A7
 64 
 65 ;############################ Vector Table #################################
 66 
 67 .macro VECTOR  lbl
 68 #if 1   /* Just in case, build breaks */
 69         j   \lbl
 70 #else
 71         b   \lbl
 72         nop
 73 #endif
 74 .endm
 75 
 76         .section .vector, "ax",@progbits
 77         .align 4
 78 
 79 /* Each entry in the vector table must occupy 2 words. Since it is a jump
 80  * across sections (.vector to .text) we are guaranteed that 'j somewhere'
 81  * will use the 'j limm' form of the instruction as long as somewhere is in
 82  * a section other than .vector.
 83  */
 84 
 85 ; ********* Critical System Events **********************
 86 VECTOR   res_service             ; 0x0, Reset Vector    (0x0)
 87 VECTOR   mem_service             ; 0x8, Mem exception   (0x1)
 88 VECTOR   instr_service           ; 0x10, Instrn Error   (0x2)
 89 
 90 ; ******************** Device ISRs **********************
 91 #ifdef CONFIG_ARC_COMPACT_IRQ_LEVELS
 92 VECTOR   handle_interrupt_level2
 93 #else
 94 VECTOR   handle_interrupt_level1
 95 #endif
 96 
 97 .rept   28
 98 VECTOR   handle_interrupt_level1 ; Other devices
 99 .endr
100 
101 /* FOR ARC600: timer = 0x3, uart = 0x8, emac = 0x10 */
102 
103 ; ******************** Exceptions **********************
104 VECTOR   EV_MachineCheck         ; 0x100, Fatal Machine check   (0x20)
105 VECTOR   EV_TLBMissI             ; 0x108, Instruction TLB miss  (0x21)
106 VECTOR   EV_TLBMissD             ; 0x110, Data TLB miss         (0x22)
107 VECTOR   EV_TLBProtV             ; 0x118, Protection Violation  (0x23)
108                                  ;         or Misaligned Access
109 VECTOR   EV_PrivilegeV           ; 0x120, Privilege Violation   (0x24)
110 VECTOR   EV_Trap                 ; 0x128, Trap exception        (0x25)
111 VECTOR   EV_Extension            ; 0x130, Extn Instruction Excp (0x26)
112 
113 .rept   24
114 VECTOR   reserved                ; Reserved Exceptions
115 .endr
116 
117 
118 ;##################### Scratch Mem for IRQ stack switching #############
119 
120 ARCFP_DATA int1_saved_reg
121         .align 32
122         .type   int1_saved_reg, @object
123         .size   int1_saved_reg, 4
124 int1_saved_reg:
125         .zero 4
126 
127 /* Each Interrupt level needs its own scratch */
128 ARCFP_DATA int2_saved_reg
129         .type   int2_saved_reg, @object
130         .size   int2_saved_reg, 4
131 int2_saved_reg:
132         .zero 4
133 
134 ; ---------------------------------------------
135         .section .text, "ax",@progbits
136 
137 
138 reserved:
139         flag 1          ; Unexpected event, halt
140 
141 ;##################### Interrupt Handling ##############################
142 
143 #ifdef CONFIG_ARC_COMPACT_IRQ_LEVELS
144 ; ---------------------------------------------
145 ;  Level 2 ISR: Can interrupt a Level 1 ISR
146 ; ---------------------------------------------
147 ENTRY(handle_interrupt_level2)
148 
149         INTERRUPT_PROLOGUE 2
150 
151         ;------------------------------------------------------
152         ; if L2 IRQ interrupted a L1 ISR, disable preemption
153         ;
154         ; This is to avoid a potential L1-L2-L1 scenario
155         ;  -L1 IRQ taken
156         ;  -L2 interrupts L1 (before L1 ISR could run)
157         ;  -preemption off IRQ, user task in syscall picked to run
158         ;  -RTIE to userspace
159         ;       Returns from L2 context fine
160         ;       But both L1 and L2 re-enabled, so another L1 can be taken
161         ;       while prev L1 is still unserviced
162         ;
163         ;------------------------------------------------------
164 
165         ; L2 interrupting L1 implies both L2 and L1 active
166         ; However both A2 and A1 are NOT set in STATUS32, thus
167         ; need to check STATUS32_L2 to determine if L1 was active
168 
169         ld r9, [sp, PT_status32]        ; get statu32_l2 (saved in pt_regs)
170         bbit0 r9, STATUS_A1_BIT, 1f     ; L1 not active when L2 IRQ, so normal
171 
172         ; bump thread_info->preempt_count (Disable preemption)
173         GET_CURR_THR_INFO_FROM_SP   r10
174         ld      r9, [r10, THREAD_INFO_PREEMPT_COUNT]
175         add     r9, r9, 1
176         st      r9, [r10, THREAD_INFO_PREEMPT_COUNT]
177 
178 1:
179         ;------------------------------------------------------
180         ; setup params for Linux common ISR and invoke it
181         ;------------------------------------------------------
182         lr  r0, [icause2]
183         and r0, r0, 0x1f
184 
185         bl.d  @arch_do_IRQ
186         mov r1, sp
187 
188         mov r8,0x2
189         sr r8, [AUX_IRQ_LV12]       ; clear bit in Sticky Status Reg
190 
191         b   ret_from_exception
192 
193 END(handle_interrupt_level2)
194 
195 #endif
196 
197 ; ---------------------------------------------
198 ; User Mode Memory Bus Error Interrupt Handler
199 ; (Kernel mode memory errors handled via separate exception vectors)
200 ; ---------------------------------------------
201 ENTRY(mem_service)
202 
203         INTERRUPT_PROLOGUE 2
204 
205         mov r0, ilink2
206         mov r1, sp
207 
208         ; User process needs to be killed with SIGBUS, but first need to get
209         ; out of the L2 interrupt context (drop to pure kernel mode) and jump
210         ; off to "C" code where SIGBUS in enqueued
211         lr  r3, [status32]
212         bclr r3, r3, STATUS_A2_BIT
213         or  r3, r3, (STATUS_E1_MASK|STATUS_E2_MASK)
214         sr  r3, [status32_l2]
215         mov ilink2, 1f
216         rtie
217 1:
218         bl  do_memory_error
219         b   ret_from_exception
220 END(mem_service)
221 
222 ; ---------------------------------------------
223 ;  Level 1 ISR
224 ; ---------------------------------------------
225 ENTRY(handle_interrupt_level1)
226 
227         INTERRUPT_PROLOGUE 1
228 
229         lr  r0, [icause1]
230         and r0, r0, 0x1f
231 
232 #ifdef CONFIG_TRACE_IRQFLAGS
233         ; icause1 needs to be read early, before calling tracing, which
234         ; can clobber scratch regs, hence use of stack to stash it
235         push r0
236         TRACE_ASM_IRQ_DISABLE
237         pop  r0
238 #endif
239 
240         bl.d  @arch_do_IRQ
241         mov r1, sp
242 
243         mov r8,0x1
244         sr r8, [AUX_IRQ_LV12]       ; clear bit in Sticky Status Reg
245 
246         b   ret_from_exception
247 END(handle_interrupt_level1)
248 
249 ;################### Non TLB Exception Handling #############################
250 
251 ; ---------------------------------------------
252 ; Protection Violation Exception Handler
253 ; ---------------------------------------------
254 
255 ENTRY(EV_TLBProtV)
256 
257         EXCEPTION_PROLOGUE      ; ECR returned in r10
258 
259         ;------ (5) Type of Protection Violation? ----------
260         ;
261         ; ProtV Hardware Exception is triggered for Access Faults of 2 types
262         ;   -Access Violation   : 00_23_(00|01|02|03)_00
263         ;                                x  r  w  r+w
264         ;   -Unaligned Access   : 00_23_04_00
265         bbit1 r10, ECR_C_BIT_PROTV_MISALIG_DATA, 4f
266 
267         ;========= (6a) Access Violation Processing ========
268         bl  do_page_fault
269         b   ret_from_exception
270 
271         ;========== (6b) Non aligned access ============
272 4:
273 
274         SAVE_CALLEE_SAVED_USER
275         mov r2, sp              ; callee_regs
276 
277         bl  do_misaligned_access
278 
279         ; TBD: optimize - do this only if a callee reg was involved
280         ; either a dst of emulated LD/ST or src with address-writeback
281         RESTORE_CALLEE_SAVED_USER
282 
283         b   ret_from_exception
284 
285 END(EV_TLBProtV)
286 
287 ; Wrapper for Linux page fault handler called from EV_TLBMiss*
288 ; Very similar to ProtV handler case (6a) above, but avoids the extra checks
289 ; for Misaligned access
290 ;
291 ENTRY(call_do_page_fault)
292 
293         EXCEPTION_PROLOGUE
294 
295         mov blink, ret_from_exception
296         b  do_page_fault
297 
298 END(call_do_page_fault)
299 
300 ;############# Common Handlers for ARCompact and ARCv2 ##############
301 
302 #include "entry.S"
303 
304 ;############# Return from Intr/Excp/Trap (ARC Specifics) ##############
305 ;
306 ; Restore the saved sys context (common exit-path for EXCPN/IRQ/Trap)
307 ; IRQ shd definitely not happen between now and rtie
308 ; All 2 entry points to here already disable interrupts
309 
310 .Lrestore_regs:
311 
312         # Interrupts are actually disabled from this point on, but will get
313         # reenabled after we return from interrupt/exception.
314         # But irq tracer needs to be told now...
315         TRACE_ASM_IRQ_ENABLE
316 
317         lr      r10, [status32]
318 
319         ; Restore REG File. In case multiple Events outstanding,
320         ; use the same priority as rtie: EXCPN, L2 IRQ, L1 IRQ, None
321         ; Note that we use realtime STATUS32 (not pt_regs->status32) to
322         ; decide that.
323 
324         and.f   0, r10, (STATUS_A1_MASK|STATUS_A2_MASK)
325         bz      .Lexcep_or_pure_K_ret
326 
327         ; Returning from Interrupts (Level 1 or 2)
328 
329 #ifdef CONFIG_ARC_COMPACT_IRQ_LEVELS
330 
331         ; Level 2 interrupt return Path - from hardware standpoint
332         bbit0  r10, STATUS_A2_BIT, not_level2_interrupt
333 
334         ;------------------------------------------------------------------
335         ; However the context returning might not have taken L2 intr itself
336         ; e.g. Task'A' user-code -> L2 intr -> schedule -> 'B' user-code ret
337         ; Special considerations needed for the context which took L2 intr
338 
339         ld   r9, [sp, PT_event]        ; Ensure this is L2 intr context
340         brne r9, event_IRQ2, 149f
341 
342         ;------------------------------------------------------------------
343         ; if L2 IRQ interrupted an L1 ISR,  we'd disabled preemption earlier
344         ; so that sched doesn't move to new task, causing L1 to be delayed
345         ; undeterministically. Now that we've achieved that, let's reset
346         ; things to what they were, before returning from L2 context
347         ;----------------------------------------------------------------
348 
349         ld r9, [sp, PT_status32]       ; get statu32_l2 (saved in pt_regs)
350         bbit0 r9, STATUS_A1_BIT, 149f  ; L1 not active when L2 IRQ, so normal
351 
352         ; decrement thread_info->preempt_count (re-enable preemption)
353         GET_CURR_THR_INFO_FROM_SP   r10
354         ld      r9, [r10, THREAD_INFO_PREEMPT_COUNT]
355 
356         ; paranoid check, given A1 was active when A2 happened, preempt count
357         ; must not be 0 because we would have incremented it.
358         ; If this does happen we simply HALT as it means a BUG !!!
359         cmp     r9, 0
360         bnz     2f
361         flag 1
362 
363 2:
364         sub     r9, r9, 1
365         st      r9, [r10, THREAD_INFO_PREEMPT_COUNT]
366 
367 149:
368         INTERRUPT_EPILOGUE 2    ; return from level 2 interrupt
369 debug_marker_l2:
370         rtie
371 
372 not_level2_interrupt:
373 
374 #endif
375 
376         INTERRUPT_EPILOGUE 1    ; return from level 1 interrupt
377 debug_marker_l1:
378         rtie
379 
380 .Lexcep_or_pure_K_ret:
381 
382         ;this case is for syscalls or Exceptions or pure kernel mode
383 
384         EXCEPTION_EPILOGUE
385 debug_marker_syscall:
386         rtie
387 
388 END(ret_from_exception)

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php