ARC: Low level IRQ/Trap/Exception Handling
[deliverable/linux.git] / arch / arc / kernel / entry.S
CommitLineData
9d42c84f
VG
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 **********************
84VECTOR res_service ; 0x0, Restart Vector (0x0)
85VECTOR mem_service ; 0x8, Mem exception (0x1)
86VECTOR instr_service ; 0x10, Instrn Error (0x2)
87
88; ******************** Device ISRs **********************
89VECTOR handle_interrupt_level1
90
91VECTOR handle_interrupt_level1
92
93VECTOR handle_interrupt_level1
94
95VECTOR handle_interrupt_level1
96
97.rept 25
98VECTOR handle_interrupt_level1 ; Other devices
99.endr
100
101/* FOR ARC600: timer = 0x3, uart = 0x8, emac = 0x10 */
102
103; ******************** Exceptions **********************
104VECTOR EV_MachineCheck ; 0x100, Fatal Machine check (0x20)
105VECTOR EV_TLBMissI ; 0x108, Intruction TLB miss (0x21)
106VECTOR EV_TLBMissD ; 0x110, Data TLB miss (0x22)
107VECTOR EV_TLBProtV ; 0x118, Protection Violation (0x23)
108 ; or Misaligned Access
109VECTOR EV_PrivilegeV ; 0x120, Privilege Violation (0x24)
110VECTOR EV_Trap ; 0x128, Trap exception (0x25)
111VECTOR EV_Extension ; 0x130, Extn Intruction Excp (0x26)
112
113.rept 24
114VECTOR 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
129int1_saved_reg:
130 .zero 4
131
132; ---------------------------------------------
133 .section .text, "ax",@progbits
134
135res_service: ; processor restart
136 flag 0x1 ; not implemented
137 nop
138 nop
139
140reserved: ; processor restart
141 rtie ; jump to processor initializations
142
143;##################### Interrupt Handling ##############################
144
145; ---------------------------------------------
146; Level 1 ISR
147; ---------------------------------------------
148ARC_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
169ARC_EXIT handle_interrupt_level1
170
171;################### Non TLB Exception Handling #############################
172
173; ---------------------------------------------
174; Instruction Error Exception Handler
175; ---------------------------------------------
176
177ARC_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
195ARC_EXIT instr_service
196
197; ---------------------------------------------
198; Memory Error Exception Handler
199; ---------------------------------------------
200
201ARC_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
215ARC_EXIT mem_service
216
217; ---------------------------------------------
218; Machine Check Exception Handler
219; ---------------------------------------------
220
221ARC_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
2371:
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
246ARC_EXIT EV_MachineCheck
247
248; ---------------------------------------------
249; Protection Violation Exception Handler
250; ---------------------------------------------
251
252ARC_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 ============
2974:
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
305ARC_EXIT EV_TLBProtV
306
307; ---------------------------------------------
308; Privilege Violation Exception Handler
309; ---------------------------------------------
310ARC_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
327ARC_EXIT EV_PrivilegeV
328
329; ---------------------------------------------
330; Extension Instruction Exception Handler
331; ---------------------------------------------
332ARC_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
345ARC_EXIT EV_Extension
346
347;################### Break Point TRAP ##########################
348
349 ; ======= (5b) Trap is due to Break-Point =========
350
351trap_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
391ARC_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
423ARC_EXIT EV_Trap
424
425ARC_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
435ARC_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.
448resume_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 ; save CALLEE Regs.
474 ; (i) If this signal causes coredump - full regfile needed
475 ; (ii) If signal is SIGTRAP/SIGSTOP, task is being traced thus
476 ; tracer might call PEEKUSR(CALLEE reg)
477 ;
478 ; NOTE: SP will grow up by size of CALLEE Reg-File
479 SAVE_CALLEE_SAVED_USER ; clobbers r12
480
481 ; save location of saved Callee Regs @ thread_struct->callee
482 GET_CURR_TASK_FIELD_PTR TASK_THREAD, r10
483 st sp, [r10, THREAD_CALLEE_REG]
484
485 bl @do_signal
486
487 ; unwind SP for cheap discard of Callee saved Regs
488 DISCARD_CALLEE_SAVED_USER
489
490 b resume_user_mode_begin ; loop back to start of U mode ret
491
492 ; --- (Slow Path #3) notify_resume ---
493.Lchk_notify_resume:
494 btst r9, TIF_NOTIFY_RESUME
495 blnz @do_notify_resume
496 b resume_user_mode_begin ; unconditionally back to U mode ret chks
497 ; for single exit point from this block
498
499#ifdef CONFIG_PREEMPT
500
501resume_kernel_mode:
502
503 ; Can't preempt if preemption disabled
504 GET_CURR_THR_INFO_FROM_SP r10
505 ld r8, [r10, THREAD_INFO_PREEMPT_COUNT]
506 brne r8, 0, restore_regs
507
508 ; check if this task's NEED_RESCHED flag set
509 ld r9, [r10, THREAD_INFO_FLAGS]
510 bbit0 r9, TIF_NEED_RESCHED, restore_regs
511
512 IRQ_DISABLE r9
513
514 ; Invoke PREEMPTION
515 bl preempt_schedule_irq
516
517 ; preempt_schedule_irq() always returns with IRQ disabled
518#endif
519
520 ; fall through
521
522;############# Return from Intr/Excp/Trap (ARC Specifics) ##############
523;
524; Restore the saved sys context (common exit-path for EXCPN/IRQ/Trap)
525; IRQ shd definitely not happen between now and rtie
526
527restore_regs :
528
529 ; Disable Interrupts while restoring reg-file back
530 ; XXX can this be optimised out
531 IRQ_DISABLE_SAVE r9, r10 ;@r10 has prisitine (pre-disable) copy
532
533 ; Restore REG File. In case multiple Events outstanding,
534 ; use the same priorty as rtie: EXCPN, L2 IRQ, L1 IRQ, None
535 ; Note that we use realtime STATUS32 (not pt_regs->status32) to
536 ; decide that.
537
538 ; if Returning from Exception
539 bbit0 r10, STATUS_AE_BIT, not_exception
540 RESTORE_ALL_SYS
541 rtie
542
543 ; Not Exception so maybe Interrupts (Level 1 or 2)
544
545not_exception:
546
547 bbit0 r10, STATUS_A1_BIT, not_level1_interrupt
548
549 ;return from level 1
550
551 RESTORE_ALL_INT1
552debug_marker_l1:
553 rtie
554
555not_level1_interrupt:
556
557 ;this case is for syscalls or Exceptions (with fake rtie)
558
559 RESTORE_ALL_SYS
560debug_marker_syscall:
561 rtie
562
563ARC_EXIT ret_from_exception
564
565ARC_ENTRY ret_from_fork
566 ; when the forked child comes here from the __switch_to function
567 ; r0 has the last task pointer.
568 ; put last task in scheduler queue
569 bl @schedule_tail
570 b @ret_from_exception
571ARC_EXIT ret_from_fork
This page took 0.051041 seconds and 5 git commands to generate.