]> git.kernelconcepts.de Git - karo-tx-linux.git/blob - arch/arc/kernel/entry.S
ARC: Signal handling
[karo-tx-linux.git] / arch / arc / kernel / entry.S
1 /*
2  * Low Level Interrupts/Traps/Exceptions(non-TLB) Handling for ARC
3  *
4  * Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com)
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 as
8  * published by the Free Software Foundation.
9  *
10  * vineetg: Nov 2010:
11  *  -Vector table jumps (@8 bytes) converted into branches (@4 bytes)
12  *  -To maintain the slot size of 8 bytes/vector, added nop, which is
13  *   not executed at runtime.
14  *
15  * vineetg: Nov 2009 (Everything needed for TIF_RESTORE_SIGMASK)
16  *  -do_signal()invoked upon TIF_RESTORE_SIGMASK as well
17  *  -Wrappers for sys_{,rt_}sigsuspend() nolonger needed as they don't
18  *   need ptregs anymore
19  *
20  * Vineetg: Oct 2009
21  *  -In a rare scenario, Process gets a Priv-V exception and gets scheduled
22  *   out. Since we don't do FAKE RTIE for Priv-V, CPU excpetion state remains
23  *   active (AE bit enabled).  This causes a double fault for a subseq valid
24  *   exception. Thus FAKE RTIE needed in low level Priv-Violation handler.
25  *   Instr Error could also cause similar scenario, so same there as well.
26  *
27  * Vineetg: Aug 28th 2008: Bug #94984
28  *  -Zero Overhead Loop Context shd be cleared when entering IRQ/EXcp/Trap
29  *   Normally CPU does this automatically, however when doing FAKE rtie,
30  *   we need to explicitly do this. The problem in macros
31  *   FAKE_RET_FROM_EXCPN and FAKE_RET_FROM_EXCPN_LOCK_IRQ was that this bit
32  *   was being "CLEARED" rather then "SET". Since it is Loop INHIBIT Bit,
33  *   setting it and not clearing it clears ZOL context
34  *
35  * Vineetg: Dec 22, 2007
36  *    Minor Surgery of Low Level ISR to make it SMP safe
37  *    - MMU_SCRATCH0 Reg used for freeing up r9 in Level 1 ISR
38  *    - _current_task is made an array of NR_CPUS
39  *    - Access of _current_task wrapped inside a macro so that if hardware
40  *       team agrees for a dedicated reg, no other code is touched
41  *
42  * Amit Bhor, Rahul Trivedi, Kanika Nema, Sameer Dhavale : Codito Tech 2004
43  */
44
45 /*------------------------------------------------------------------
46  *    Function                            ABI
47  *------------------------------------------------------------------
48  *
49  *  Arguments                           r0 - r7
50  *  Caller Saved Registers              r0 - r12
51  *  Callee Saved Registers              r13- r25
52  *  Global Pointer (gp)                 r26
53  *  Frame Pointer (fp)                  r27
54  *  Stack Pointer (sp)                  r28
55  *  Interrupt link register (ilink1)    r29
56  *  Interrupt link register (ilink2)    r30
57  *  Branch link register (blink)        r31
58  *------------------------------------------------------------------
59  */
60
61         .cpu A7
62
63 ;############################ Vector Table #################################
64
65 .macro VECTOR  lbl
66 #if 1   /* Just in case, build breaks */
67         j   \lbl
68 #else
69         b   \lbl
70         nop
71 #endif
72 .endm
73
74         .section .vector, "ax",@progbits
75         .align 4
76
77 /* Each entry in the vector table must occupy 2 words. Since it is a jump
78  * across sections (.vector to .text) we are gauranteed that 'j somewhere'
79  * will use the 'j limm' form of the intrsuction as long as somewhere is in
80  * a section other than .vector.
81  */
82
83 ; ********* Critical System Events **********************
84 VECTOR   res_service             ; 0x0, Restart Vector  (0x0)
85 VECTOR   mem_service             ; 0x8, Mem exception   (0x1)
86 VECTOR   instr_service           ; 0x10, Instrn Error   (0x2)
87
88 ; ******************** Device ISRs **********************
89 VECTOR   handle_interrupt_level1
90
91 VECTOR   handle_interrupt_level1
92
93 VECTOR   handle_interrupt_level1
94
95 VECTOR   handle_interrupt_level1
96
97 .rept   25
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, Intruction 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 Intruction Excp  (0x26)
112
113 .rept   24
114 VECTOR   reserved                ; Reserved Exceptions
115 .endr
116
117 #include <linux/linkage.h>   /* ARC_{EXTRY,EXIT} */
118 #include <asm/entry.h>       /* SAVE_ALL_{INT1,INT2,TRAP...} */
119 #include <asm/errno.h>
120 #include <asm/arcregs.h>
121 #include <asm/irqflags.h>
122
123 ;##################### Scratch Mem for IRQ stack switching #############
124
125         .section .data          ; NOT .global
126         .align 32
127         .type   int1_saved_reg, @object
128         .size   int1_saved_reg, 4
129 int1_saved_reg:
130         .zero 4
131
132 ; ---------------------------------------------
133         .section .text, "ax",@progbits
134
135 res_service:            ; processor restart
136         flag    0x1     ; not implemented
137         nop
138         nop
139
140 reserved:               ; processor restart
141         rtie            ; jump to processor initializations
142
143 ;##################### Interrupt Handling ##############################
144
145 ; ---------------------------------------------
146 ;  Level 1 ISR
147 ; ---------------------------------------------
148 ARC_ENTRY handle_interrupt_level1
149
150         /* free up r9 as scratchpad */
151         st   r9, [@int1_saved_reg]
152
153         ;Which mode (user/kernel) was the system in when intr occured
154         lr  r9, [status32_l1]
155
156         SWITCH_TO_KERNEL_STK
157         SAVE_ALL_INT1
158
159         lr  r0, [icause1]
160         and r0, r0, 0x1f
161
162         bl.d  @arch_do_IRQ
163         mov r1, sp
164
165         mov r8,0x1
166         sr r8, [AUX_IRQ_LV12]       ; clear bit in Sticky Status Reg
167
168         b   ret_from_exception
169 ARC_EXIT handle_interrupt_level1
170
171 ;################### Non TLB Exception Handling #############################
172
173 ; ---------------------------------------------
174 ; Instruction Error Exception Handler
175 ; ---------------------------------------------
176
177 ARC_ENTRY instr_service
178
179         EXCPN_PROLOG_FREEUP_REG r9
180
181         lr  r9, [erstatus]
182
183         SWITCH_TO_KERNEL_STK
184         SAVE_ALL_SYS
185
186         lr  r0, [ecr]
187         lr  r1, [efa]
188
189         mov r2, sp
190
191         FAKE_RET_FROM_EXCPN r9
192
193         bl  do_insterror_or_kprobe
194         b   ret_from_exception
195 ARC_EXIT instr_service
196
197 ; ---------------------------------------------
198 ; Memory Error Exception Handler
199 ; ---------------------------------------------
200
201 ARC_ENTRY mem_service
202
203         EXCPN_PROLOG_FREEUP_REG r9
204
205         lr  r9, [erstatus]
206
207         SWITCH_TO_KERNEL_STK
208         SAVE_ALL_SYS
209
210         lr  r0, [ecr]
211         lr  r1, [efa]
212         mov r2, sp
213         bl  do_memory_error
214         b   ret_from_exception
215 ARC_EXIT mem_service
216
217 ; ---------------------------------------------
218 ; Machine Check Exception Handler
219 ; ---------------------------------------------
220
221 ARC_ENTRY EV_MachineCheck
222
223         EXCPN_PROLOG_FREEUP_REG r9
224         lr  r9, [erstatus]
225
226         SWITCH_TO_KERNEL_STK
227         SAVE_ALL_SYS
228
229         lr  r0, [ecr]
230         lr  r1, [efa]
231         mov r2, sp
232
233         brne    r0, 0x200100, 1f
234         bl      do_tlb_overlap_fault
235         b       ret_from_exception
236
237 1:
238         ; DEAD END: can't do much, display Regs and HALT
239         SAVE_CALLEE_SAVED_USER
240
241         GET_CURR_TASK_FIELD_PTR   TASK_THREAD, r10
242         st  sp, [r10, THREAD_CALLEE_REG]
243
244         j  do_machine_check_fault
245
246 ARC_EXIT EV_MachineCheck
247
248 ; ---------------------------------------------
249 ; Protection Violation Exception Handler
250 ; ---------------------------------------------
251
252 ARC_ENTRY EV_TLBProtV
253
254         EXCPN_PROLOG_FREEUP_REG r9
255
256         ;Which mode (user/kernel) was the system in when Exception occured
257         lr  r9, [erstatus]
258
259         SWITCH_TO_KERNEL_STK
260         SAVE_ALL_SYS
261
262         ;---------(3) Save some more regs-----------------
263         ;  vineetg: Mar 6th: Random Seg Fault issue #1
264         ;  ecr and efa were not saved in case an Intr sneaks in
265         ;  after fake rtie
266         ;
267         lr  r3, [ecr]
268         lr  r4, [efa]
269
270         ; --------(4) Return from CPU Exception Mode ---------
271         ;  Fake a rtie, but rtie to next label
272         ;  That way, subsequently, do_page_fault ( ) executes in pure kernel
273         ;  mode with further Exceptions enabled
274
275         FAKE_RET_FROM_EXCPN r9
276
277         ;------ (5) Type of Protection Violation? ----------
278         ;
279         ; ProtV Hardware Exception is triggered for Access Faults of 2 types
280         ;   -Access Violaton (WRITE to READ ONLY Page) - for linux COW
281         ;   -Unaligned Access (READ/WRITE on odd boundary)
282         ;
283         cmp r3, 0x230400    ; Misaligned data access ?
284         beq 4f
285
286         ;========= (6a) Access Violation Processing ========
287         cmp r3, 0x230100
288         mov r1, 0x0              ; if LD exception ? write = 0
289         mov.ne r1, 0x1           ; else write = 1
290
291         mov r2, r4              ; faulting address
292         mov r0, sp              ; pt_regs
293         bl  do_page_fault
294         b   ret_from_exception
295
296         ;========== (6b) Non aligned access ============
297 4:
298         mov r0, r3              ; cause code
299         mov r1, r4              ; faulting address
300         mov r2, sp              ; pt_regs
301
302         bl  do_misaligned_access
303         b   ret_from_exception
304
305 ARC_EXIT EV_TLBProtV
306
307 ; ---------------------------------------------
308 ; Privilege Violation Exception Handler
309 ; ---------------------------------------------
310 ARC_ENTRY EV_PrivilegeV
311
312         EXCPN_PROLOG_FREEUP_REG r9
313
314         lr  r9, [erstatus]
315
316         SWITCH_TO_KERNEL_STK
317         SAVE_ALL_SYS
318
319         lr  r0, [ecr]
320         lr  r1, [efa]
321         mov r2, sp
322
323         FAKE_RET_FROM_EXCPN r9
324
325         bl  do_privilege_fault
326         b   ret_from_exception
327 ARC_EXIT EV_PrivilegeV
328
329 ; ---------------------------------------------
330 ; Extension Instruction Exception Handler
331 ; ---------------------------------------------
332 ARC_ENTRY EV_Extension
333
334         EXCPN_PROLOG_FREEUP_REG r9
335         lr  r9, [erstatus]
336
337         SWITCH_TO_KERNEL_STK
338         SAVE_ALL_SYS
339
340         lr  r0, [ecr]
341         lr  r1, [efa]
342         mov r2, sp
343         bl  do_extension_fault
344         b   ret_from_exception
345 ARC_EXIT EV_Extension
346
347 ;################### Break Point TRAP ##########################
348
349         ; ======= (5b) Trap is due to Break-Point =========
350
351 trap_with_param:
352
353         ;make sure orig_r8 is a positive value
354         st  NR_syscalls + 2, [sp, PT_orig_r8]
355
356         mov r0, r12
357         lr  r1, [efa]
358         mov r2, sp
359
360         ; Now that we have read EFA, its safe to do "fake" rtie
361         ;   and get out of CPU exception mode
362         FAKE_RET_FROM_EXCPN r11
363
364         ; Save callee regs in case gdb wants to have a look
365         ; SP will grow up by size of CALLEE Reg-File
366         ; NOTE: clobbers r12
367         SAVE_CALLEE_SAVED_USER
368
369         ; save location of saved Callee Regs @ thread_struct->pc
370         GET_CURR_TASK_FIELD_PTR   TASK_THREAD, r10
371         st  sp, [r10, THREAD_CALLEE_REG]
372
373         ; Call the trap handler
374         bl  do_non_swi_trap
375
376         ; unwind stack to discard Callee saved Regs
377         DISCARD_CALLEE_SAVED_USER
378
379         b   ret_from_exception
380
381 ;##################### Trap Handling ##############################
382 ;
383 ; EV_Trap caused by TRAP_S and TRAP0 instructions.
384 ;------------------------------------------------------------------
385 ;   (1) System Calls
386 ;       :parameters in r0-r7.
387 ;       :r8 has the system call number
388 ;   (2) Break Points
389 ;------------------------------------------------------------------
390
391 ARC_ENTRY EV_Trap
392
393         ; Need at least 1 reg to code the early exception prolog
394         EXCPN_PROLOG_FREEUP_REG r9
395
396         ;Which mode (user/kernel) was the system in when intr occured
397         lr  r9, [erstatus]
398
399         SWITCH_TO_KERNEL_STK
400         SAVE_ALL_TRAP
401
402         ;------- (4) What caused the Trap --------------
403         lr     r12, [ecr]
404         and.f  0, r12, ECR_PARAM_MASK
405         bnz    trap_with_param
406
407         ; ======= (5a) Trap is due to System Call ========
408
409         ; Before doing anything, return from CPU Exception Mode
410         FAKE_RET_FROM_EXCPN r11
411
412         ;============ This is normal System Call case ==========
413         ; Sys-call num shd not exceed the total system calls avail
414         cmp     r8,  NR_syscalls
415         mov.hi  r0, -ENOSYS
416         bhi     ret_from_system_call
417
418         ; Offset into the syscall_table and call handler
419         ld.as   r9,[sys_call_table, r8]
420         jl      [r9]        ; Entry into Sys Call Handler
421
422         ; fall through to ret_from_system_call
423 ARC_EXIT EV_Trap
424
425 ARC_ENTRY ret_from_system_call
426
427         st  r0, [sp, PT_r0]     ; sys call return value in pt_regs
428
429         ; fall through yet again to ret_from_exception
430
431 ;############# Return from Intr/Excp/Trap (Linux Specifics) ##############
432 ;
433 ; If ret to user mode do we need to handle signals, schedule() et al.
434
435 ARC_ENTRY ret_from_exception
436
437         ; Pre-{IRQ,Trap,Exception} K/U mode from pt_regs->status32
438         ld  r8, [sp, PT_status32]   ; returning to User/Kernel Mode
439
440 #ifdef CONFIG_PREEMPT
441         bbit0  r8, STATUS_U_BIT, resume_kernel_mode
442 #else
443         bbit0  r8, STATUS_U_BIT, restore_regs
444 #endif
445
446         ; Before returning to User mode check-for-and-complete any pending work
447         ; such as rescheduling/signal-delivery etc.
448 resume_user_mode_begin:
449
450         ; Disable IRQs to ensures that chk for pending work itself is atomic
451         ; (and we don't end up missing a NEED_RESCHED/SIGPENDING due to an
452         ; interim IRQ).
453         IRQ_DISABLE     r10
454
455         ; Fast Path return to user mode if no pending work
456         GET_CURR_THR_INFO_FLAGS   r9
457         and.f  0,  r9, _TIF_WORK_MASK
458         bz     restore_regs
459
460         ; --- (Slow Path #1) task preemption ---
461         bbit0  r9, TIF_NEED_RESCHED, .Lchk_pend_signals
462         mov    blink, resume_user_mode_begin  ; tail-call to U mode ret chks
463         b      @schedule        ; BTST+Bnz causes relo error in link
464
465 .Lchk_pend_signals:
466         IRQ_ENABLE      r10
467
468         ; --- (Slow Path #2) pending signal  ---
469         mov r0, sp      ; pt_regs for arg to do_signal()/do_notify_resume()
470
471         bbit0  r9, TIF_SIGPENDING, .Lchk_notify_resume
472
473         ; Normal Trap/IRQ entry only saves Scratch (caller-saved) regs
474         ; in pt_reg since the "C" ABI (kernel code) will automatically
475         ; save/restore callee-saved regs.
476         ;
477         ; However, here we need to explicitly save callee regs because
478         ; (i)  If this signal causes coredump - full regfile needed
479         ; (ii) If signal is SIGTRAP/SIGSTOP, task is being traced thus
480         ;      tracer might call PEEKUSR(CALLEE reg)
481         ;
482         ; NOTE: SP will grow up by size of CALLEE Reg-File
483         SAVE_CALLEE_SAVED_USER          ; clobbers r12
484
485         ; save location of saved Callee Regs @ thread_struct->callee
486         GET_CURR_TASK_FIELD_PTR   TASK_THREAD, r10
487         st  sp, [r10, THREAD_CALLEE_REG]
488
489         bl  @do_signal
490
491         ; Ideally we want to discard the Callee reg above, however if this was
492         ; a tracing signal, tracer could have done a POKEUSR(CALLEE reg)
493         RESTORE_CALLEE_SAVED_USER
494
495         b      resume_user_mode_begin   ; loop back to start of U mode ret
496
497         ; --- (Slow Path #3) notify_resume ---
498 .Lchk_notify_resume:
499         btst   r9, TIF_NOTIFY_RESUME
500         blnz   @do_notify_resume
501         b      resume_user_mode_begin   ; unconditionally back to U mode ret chks
502                                         ; for single exit point from this block
503
504 #ifdef CONFIG_PREEMPT
505
506 resume_kernel_mode:
507
508         ; Can't preempt if preemption disabled
509         GET_CURR_THR_INFO_FROM_SP   r10
510         ld  r8, [r10, THREAD_INFO_PREEMPT_COUNT]
511         brne  r8, 0, restore_regs
512
513         ; check if this task's NEED_RESCHED flag set
514         ld  r9, [r10, THREAD_INFO_FLAGS]
515         bbit0  r9, TIF_NEED_RESCHED, restore_regs
516
517         IRQ_DISABLE     r9
518
519         ; Invoke PREEMPTION
520         bl      preempt_schedule_irq
521
522         ; preempt_schedule_irq() always returns with IRQ disabled
523 #endif
524
525         ; fall through
526
527 ;############# Return from Intr/Excp/Trap (ARC Specifics) ##############
528 ;
529 ; Restore the saved sys context (common exit-path for EXCPN/IRQ/Trap)
530 ; IRQ shd definitely not happen between now and rtie
531
532 restore_regs :
533
534         ; Disable Interrupts while restoring reg-file back
535         ; XXX can this be optimised out
536         IRQ_DISABLE_SAVE    r9, r10     ;@r10 has prisitine (pre-disable) copy
537
538         ; Restore REG File. In case multiple Events outstanding,
539         ; use the same priorty as rtie: EXCPN, L2 IRQ, L1 IRQ, None
540         ; Note that we use realtime STATUS32 (not pt_regs->status32) to
541         ; decide that.
542
543         ; if Returning from Exception
544         bbit0  r10, STATUS_AE_BIT, not_exception
545         RESTORE_ALL_SYS
546         rtie
547
548         ; Not Exception so maybe Interrupts (Level 1 or 2)
549
550 not_exception:
551
552         bbit0  r10, STATUS_A1_BIT, not_level1_interrupt
553
554         ;return from level 1
555
556         RESTORE_ALL_INT1
557 debug_marker_l1:
558         rtie
559
560 not_level1_interrupt:
561
562         ;this case is for syscalls or Exceptions (with fake rtie)
563
564         RESTORE_ALL_SYS
565 debug_marker_syscall:
566         rtie
567
568 ARC_EXIT ret_from_exception
569
570 ARC_ENTRY ret_from_fork
571         ; when the forked child comes here from the __switch_to function
572         ; r0 has the last task pointer.
573         ; put last task in scheduler queue
574         bl   @schedule_tail
575
576         ; If kernel thread, jump to it's entry-point
577         ld   r9, [sp, PT_status32]
578         brne r9, 0, 1f
579
580         jl.d [r14]
581         mov  r0, r13            ; arg to payload
582
583 1:
584         ; special case of kernel_thread entry point returning back due to
585         ; kernel_execve() - pretend return from syscall to ret to userland
586         b    ret_from_exception
587 ARC_EXIT ret_from_fork
588
589 ;################### Special Sys Call Wrappers ##########################
590
591 ; TBD: call do_fork directly from here
592 ARC_ENTRY sys_fork_wrapper
593         SAVE_CALLEE_SAVED_USER
594         bl  @sys_fork
595         DISCARD_CALLEE_SAVED_USER
596
597         b ret_from_system_call
598 ARC_EXIT sys_fork_wrapper
599
600 ARC_ENTRY sys_vfork_wrapper
601         SAVE_CALLEE_SAVED_USER
602         bl  @sys_vfork
603         DISCARD_CALLEE_SAVED_USER
604
605         b ret_from_system_call
606 ARC_EXIT sys_vfork_wrapper
607
608 ARC_ENTRY sys_clone_wrapper
609         SAVE_CALLEE_SAVED_USER
610         bl  @sys_clone
611         DISCARD_CALLEE_SAVED_USER
612
613         b ret_from_system_call
614 ARC_EXIT sys_clone_wrapper