First version
[3rdparty/ote_partner/tlk.git] / arch / arm / arm / ops.S
1 /*
2  * Copyright (c) 2008 Travis Geiselbrecht
3  * Copyright (c) 2012-2013, 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
25 #include <asm.h>
26
27 .text
28
29 /* void arch_enable_ints(void); */
30 FUNCTION(arch_enable_ints)
31         mrs     r0, cpsr
32         bic     r0, r0, #(1<<7)         /* clear the I bit */
33         msr     cpsr_c, r0
34         bx      lr
35
36 /* void arch_disable_ints(void); */
37 FUNCTION(arch_disable_ints)
38         mrs     r0, cpsr
39         orr     r0, r0, #(1<<7)
40         msr     cpsr_c, r0
41         bx      lr
42
43 /* int atomic_swap(int *ptr, int val); */
44 FUNCTION(atomic_swap)
45         swp     r2, r1, [r0]
46         mov     r0, r2
47         bx      lr
48
49 /* int atomic_add(int *ptr, int val); */
50 FUNCTION(atomic_add)
51 #if ARM_ISA_ARMV6 || ARM_ISA_ARMV7
52         /* use load/store exclusive */
53 .L_loop_add:
54         ldrex   r12, [r0]
55         add             r2, r12, r1
56         strex   r3, r2, [r0]
57         cmp             r3, #0
58         bne     .L_loop_add
59
60         /* save old value */
61         mov             r0, r12
62         bx              lr
63 #else
64         /* disable interrupts, do the add, and reenable */
65         mrs     r2, cpsr
66         mov     r12, r2
67         orr     r2, r2, #(3<<6)
68         msr     cpsr_c, r2
69
70         /* ints disabled, old cpsr state in r12 */
71
72         /* do the add, leave the previous value in r0 */
73         mov     r3, r0
74         ldr     r0, [r3]
75         add     r2, r0, r1
76         str     r2, [r3]
77
78         /* restore interrupts and exit */
79         msr     cpsr_c, r12
80         bx      lr
81 #endif
82
83 /* int atomic_and(int *ptr, int val); */
84 FUNCTION(atomic_and)
85 #if ARM_ISA_ARMV6 || ARM_ISA_ARMV7
86         /* use load/store exclusive */
87 .L_loop_and:
88         ldrex   r12, [r0]
89         and             r2, r12, r1
90         strex   r3, r2, [r0]
91         cmp             r3, #0
92         bne     .L_loop_and
93
94         /* save old value */
95         mov             r0, r12
96         bx              lr
97 #else
98         /* disable interrupts, do the and, and reenable */
99         mrs     r2, cpsr
100         mov     r12, r2
101         orr     r2, r2, #(3<<6)
102         msr     cpsr_c, r2
103
104         /* ints disabled, old cpsr state in r12 */
105
106         /* do the and, leave the previous value in r0 */
107         mov     r3, r0
108         ldr     r0, [r3]
109         and     r2, r0, r1
110         str     r2, [r3]
111
112         /* restore interrupts and exit */
113         msr     cpsr_c, r12
114         bx      lr
115 #endif
116
117 /* int atomic_or(int *ptr, int val); */
118 FUNCTION(atomic_or)
119 #if ARM_ISA_ARMV6 || ARM_ISA_ARMV7
120         /* use load/store exclusive */
121 .L_loop_or:
122         ldrex   r12, [r0]
123         orr             r2, r12, r1
124         strex   r3, r2, [r0]
125         cmp             r3, #0
126         bne     .L_loop_or
127
128         /* save old value */
129         mov             r0, r12
130         bx              lr
131 #else
132         /* disable interrupts, do the or, and reenable */
133         mrs     r2, cpsr
134         mov     r12, r2
135         orr     r2, r2, #(3<<6)
136         msr     cpsr_c, r2
137
138         /* ints disabled, old cpsr state in r12 */
139
140         /* do the or, leave the previous value in r0 */
141         mov     r3, r0
142         ldr     r0, [r3]
143         orr     r2, r0, r1
144         str     r2, [r3]
145
146         /* restore interrupts and exit */
147         msr     cpsr_c, r12
148         bx      lr
149 #endif
150
151 /* void arch_idle(); */
152 FUNCTION(arch_idle)
153 #if ARM_CPU_CORTEX_A8 || ARM_CPU_CORTEX_A9 || ARM_CPU_CORTEX_A15
154         wfi
155 #elif PLATFORM_MSM7K
156         /* TODO: safely handle wfi */
157 #elif ARM_CPU_ARM1136 || ARM_CPU_ARM926
158         mov     r0, #0
159         mcr     p15, 0, r0, c7, c0, #4
160 #elif ARM_CPU_ARM7
161         /* nothing to do here */
162 #else
163 #error unknown cpu
164 #endif
165         bx      lr
166
167 /* uint32_t arm_read_sctlr(void) */
168 FUNCTION(arm_read_sctlr)
169         mrc     p15, 0, r0, c1, c0, 0
170         bx      lr
171
172 /* void arm_write_sctlr(uint32_t val) */
173 FUNCTION(arm_write_sctlr)
174         mcr     p15, 0, r0, c1, c0, 0
175         bx      lr
176
177 /* uint32_t arm_read_actlr(void) */
178 FUNCTION(arm_read_actlr)
179         mrc     p15, 0, r0, c1, c0, 1
180         bx      lr
181
182 /* void arm_write_actlr(uint32_t val) */
183 FUNCTION(arm_write_actlr)
184         mcr     p15, 0, r0, c1, c0, 1
185         bx      lr
186
187 /* void arm_invalidate_tlb(void) */
188 FUNCTION(arm_invalidate_tlb)
189         mov     r0, #0
190         mcr     p15, 0, r0, c8, c7, 0
191         bx      lr
192
193 /* void arm_invalidate_tlb_byaddr(vaddr) */
194 FUNCTION(arm_invalidate_tlb_byaddr)
195         lsr     r0, r0, #12
196         lsl     r0, r0, #12             @ page align addr
197         dsb                             @ sync pgtbl writes
198         mcr     p15, 0, r0, c8, c7, 3   @ MVA and all ASIDs
199         bx      lr
200
201 /* void arm_invalidate_tlb_byaddr_asid(vaddr, asid) */
202 FUNCTION(arm_invalidate_tlb_byaddr_asid)
203         lsr     r0, r0, #12
204         lsl     r0, r0, #12             @ page align addr
205         and     r1, r1, #0xFF           @ asid is 8bits
206         orr     r0, r0, r1
207         dsb                             @ sync pgtbl writes
208         mcr     p15, 0, r0, c8, c7, 1   @ MVA and this ASID
209         bx      lr
210
211 /* void arm_write_v2p(uint32_t vaddr, uint32_t type) */
212 FUNCTION(arm_write_v2p)
213         cmp     r1, #0x0
214         mcreq   p15, 0, r0, c7, c8, 0   @ V2PCWPR
215         bxeq    lr
216         cmp     r1, #0x1
217         mcreq   p15, 0, r0, c7, c8, 1   @ V2PCWPW
218         bxeq    lr
219         cmp     r1, #0x2
220         mcreq   p15, 0, r0, c7, c8, 2   @ V2PCWUR
221         bxeq    lr
222         cmp     r1, #0x3
223         mcreq   p15, 0, r0, c7, c8, 3   @ V2PCWUW
224         bxeq    lr
225         cmp     r1, #0x4
226         mcreq   p15, 0, r0, c7, c8, 4   @ V2POWPR
227         bxeq    lr
228         cmp     r1, #0x5
229         mcreq   p15, 0, r0, c7, c8, 5   @ V2POWPW
230         bxeq    lr
231         cmp     r1, #0x6
232         mcreq   p15, 0, r0, c7, c8, 6   @ V2POWUR
233         bxeq    lr
234         cmp     r1, #0x7
235         mcreq   p15, 0, r0, c7, c8, 7   @ V2POWUW
236         bx      lr
237
238 /* uint64_t arm_read_par(void) */
239 FUNCTION(arm_read_par)
240         mrc     p15, 0, r0, c7, c4, 0
241         tst     r0, #(1 << 11)          @ LPAE / long desc format
242         moveq   r1, #0
243         mrrcne  p15, 0, r0, r1, c7
244         bx      lr
245
246 /* void arch_switch_stacks_and_call(addr_t call, addr_t stack) */
247 FUNCTION(arch_switch_stacks_and_call)
248         mov     sp, r1
249         bx      r0
250
251 /* uint32_t arch_cycle_count(void); */
252 FUNCTION(arch_cycle_count)
253 #if defined(ARM_CPU_CORTEX_A8) || defined(ARM_CPU_CORTEX_A9) || defined(ARM_CPU_CORTEX_A15)
254         mrc     p15, 0, r0, c9, c13, 0
255 #else
256         mov     r0, #0
257 #endif
258         bx      lr
259
260 /*void dsb(void) */
261 FUNCTION(dsb)
262 #if defined(ARM_CPU_CORTEX_A8) || defined(ARM_CPU_CORTEX_A9) || defined(ARM_CPU_CORTEX_A15)
263         dsb             sy
264 #elif ARM_CPU_ARM1136
265         mov     r0, #0
266         mcr     p15, 0, r0, c7, c10, 4
267 #endif
268         bx      lr
269
270 /* uint32_t arm_get_tls(void) */
271 FUNCTION(arm_get_tls)
272         mrc     p15, 0, r0, c13, c0, 3
273         bx      lr
274
275 /* void arm_set_tls(uint32_t) */
276 FUNCTION(arm_set_tls)
277         mcr     p15, 0, r0, c13, c0, 3
278         bx      lr
279
280 /* uint32_t arm_read_vbar(void) */
281 FUNCTION(arm_read_vbar)
282         mrc     p15, 0, r0, c12, c0, 0
283         bx      lr
284
285 /* void arm_write_vbar(uint32_t) */
286 FUNCTION(arm_write_vbar)
287         mcr     p15, 0, r0, c12, c0, 0
288         bx      lr