First version
[3rdparty/ote_partner/tlk.git] / arch / arm / arm / exceptions.S
1 /*
2  * Copyright (c) 2008 Travis Geiselbrecht
3  * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining
6  * a copy of this software and associated documentation files
7  * (the "Software"), to deal in the Software without restriction,
8  * including without limitation the rights to use, copy, modify, merge,
9  * publish, distribute, sublicense, and/or sell copies of the Software,
10  * and to permit persons to whom the Software is furnished to do so,
11  * subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be
14  * included in all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
20  * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
21  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
22  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23  */
24 #include <asm.h>
25 #include <arch/arch_thread.h>
26
27 FUNCTION(arm_undefined)
28         stmfd   sp!, { r0-r12, r14 }
29         sub     sp, sp, #12
30         mrs     r1, spsr
31         stmia   sp, { r1, r13-r14 }^
32
33         mov     r0, sp
34         bl      arm_undefined_handler
35
36         ldmia   sp, { r1, r13-r14 }^
37         msr     spsr_fsxc, r1
38         add     sp, sp, #12
39         ldmia   sp!, { r0-r12, r14 }
40         movs    pc, r14
41
42 FUNCTION(arm_syscall)
43         stmfd   sp!, { r0-r12, r14 }
44         sub     sp, sp, #12
45         mrs     r1, spsr
46         stmia   sp, { r1, r13-r14 }^
47
48         mov     r0, sp
49         bl      arm_syscall_handler
50
51         ldmia   sp, { r1, r13-r14 }^
52
53         /* make USR cpsr I/F bits agree with SVC */
54         mrs     r0, cpsr
55         cpsid   aif             @ don't let IRQ intr change spsr
56         bic     r1, r1, #(3 << 6)
57         and     r0, r0, #(3 << 6)
58         orr     r1, r1, r0
59         msr     spsr_fsxc, r1
60
61         add     sp, sp, #12
62         ldmia   sp!, { r0-r12, r14 }
63         movs    pc, r14
64
65 FUNCTION(arm_prefetch_abort)
66         stmfd   sp!, { r0-r12, r14 }
67         sub     sp, sp, #12
68         mov     r0, sp
69         mrs     r1, spsr
70         stmia   r0, { r1, r13-r14 }^
71         b       arm_prefetch_abort_handler
72         b       .
73
74 FUNCTION(arm_data_abort)
75         stmfd   sp!, { r0-r12, r14 }
76         sub     sp, sp, #12
77         mov     r0, sp
78         mrs     r1, spsr
79         stmia   r0, { r1, r13-r14 }^
80         b       arm_data_abort_handler
81         b       .
82
83 FUNCTION(arm_reserved)
84         b       .
85
86 FUNCTION(arm_irq)
87         /* save spsr, exception pc on sp_svc */
88         sub     lr, lr, #4      @ both ARM/Thumb latch (PC + 4)
89         srsdb   sp!, #0x13
90
91         /* move into supervisor mode. irq/fiq disabled */
92         cpsid   if, #0x13
93
94         /* save core register state */
95         stmfd   sp, { r13-r14 }^
96         sub     sp, sp, #8
97         stmfd   sp!, { r0-r12, r14 }
98
99         /* increment the global critical section count */
100         ldr     r1, =critical_section_count
101         ldr     r0, [r1]
102         add     r0, r0, #1
103         str     r0, [r1]
104
105         /* call into higher level code */
106         mov     r0, sp /* iframe */
107         bl      platform_irq
108
109         /* reschedule if the handler returns nonzero */
110         cmp     r0, #0
111         bne     thread_preempt
112
113         /* decrement the global critical section count */
114         ldr     r1, =critical_section_count
115         ldr     r0, [r1]
116         sub     r0, r0, #1
117         str     r0, [r1]
118
119         /* restore core register state */
120         ldmia   sp!, { r0-r12, r14 }
121         ldmia   sp, { r13-r14 }^
122         add     sp, sp, #8
123
124         /* restore to cpsr, pc */
125         rfeia   sp!
126
127         /* should never reach here */
128         b       .
129
130 .bss
131 .align 2
132         .global irq_save_spot
133 irq_save_spot:
134         .word   0       /* r4 */
135         .word   0       /* r5 */
136         .word   0       /* r6 */
137
138 .text
139 FUNCTION(arm_fiq)
140         sub     lr, lr, #4
141         stmfd   sp!, { r0-r3, r12, lr }
142
143         bl      platform_fiq
144
145         ldmfd   sp!, { r0-r3, r12, pc }^
146
147 .ltorg