blob: 6daea960f9483c3c599514a053be4205e590e219 [file] [log] [blame]
Travis Geiselbrecht1d0df692008-09-01 02:26:09 -07001/*
2 * Copyright (c) 2008 Travis Geiselbrecht
3 *
Channagoud Kadabibca52542014-01-30 14:35:39 -08004 * Copyright (c) 2014, The Linux Foundation. All rights reserved.
5 *
Travis Geiselbrecht1d0df692008-09-01 02:26:09 -07006 * Permission is hereby granted, free of charge, to any person obtaining
7 * a copy of this software and associated documentation files
8 * (the "Software"), to deal in the Software without restriction,
9 * including without limitation the rights to use, copy, modify, merge,
10 * publish, distribute, sublicense, and/or sell copies of the Software,
11 * and to permit persons to whom the Software is furnished to do so,
12 * subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be
15 * included in all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
21 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
22 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
23 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 */
25#include <asm.h>
26
27.text
28
29/* void arch_enable_ints(void); */
30FUNCTION(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); */
37FUNCTION(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); */
44FUNCTION(atomic_swap)
45 swp r0, r2, [r1]
46 bx lr
47
48/* int atomic_add(int *ptr, int val); */
49FUNCTION(atomic_add)
Travis Geiselbrecht8d529ef2008-09-13 15:13:21 -070050#if ARM_ISA_ARMV6 || ARM_ISA_ARMV7
51 /* use load/store exclusive */
52.L_loop_add:
Deepa Dinamani1cc97642012-05-09 11:45:38 -070053 ldrex r12, [r0]
Travis Geiselbrecht8d529ef2008-09-13 15:13:21 -070054 add r2, r12, r1
Deepa Dinamani1cc97642012-05-09 11:45:38 -070055 strex r3, r2, [r0]
Travis Geiselbrecht8d529ef2008-09-13 15:13:21 -070056 cmp r3, #0
Deepa Dinamani1cc97642012-05-09 11:45:38 -070057 bne .L_loop_add
58
Travis Geiselbrecht8d529ef2008-09-13 15:13:21 -070059 /* save old value */
60 mov r0, r12
61 bx lr
62#else
Travis Geiselbrecht1d0df692008-09-01 02:26:09 -070063 /* disable interrupts, do the add, and reenable */
64 mrs r2, cpsr
65 mov r12, r2
66 orr r2, r2, #(3<<6)
67 msr cpsr_c, r2
68
69 /* ints disabled, old cpsr state in r12 */
Deepa Dinamani1cc97642012-05-09 11:45:38 -070070
Travis Geiselbrecht1d0df692008-09-01 02:26:09 -070071 /* do the add, leave the previous value in r0 */
72 mov r3, r0
73 ldr r0, [r3]
74 add r2, r0, r1
75 str r2, [r3]
76
77 /* restore interrupts and exit */
78 msr cpsr_c, r12
79 bx lr
Travis Geiselbrecht8d529ef2008-09-13 15:13:21 -070080#endif
Deepa Dinamani1cc97642012-05-09 11:45:38 -070081
Deepa Dinamanid642b802012-05-16 10:49:01 -070082/* uint64_t atomic_dw_read(uint32_t rd_addr,
83 * uint32_t st_addr_lo, uint32_t st_addr_hi);
84 */
85/* Reads a double word from memory atomically */
86FUNCTION(atomic_dw_read)
87#if ARM_ISA_ARMV6 || ARM_ISA_ARMV7
88 stmfd sp!, {r4-r5}
89 /* use load/store exclusive */
90 ldrexd r4, [r0]
91 str r4, [r1]
92 str r5, [r2]
93
94 /* Restore registers */
95 ldmfd sp!, {r4-r5}
96
97 bx lr
98#else
99 stmfd sp!, {r4-r5}
100 /* disable interrupts, do read, and reenable */
101 mrs r2, cpsr
102 mov r12, r2
103 orr r2, r2, #(3<<6)
104 msr cpsr_c, r2
105
106 /* ints disabled, old cpsr state in r12 */
107
108 /* do memory read, return the double word read */
109 ldr r4, [r0]
110 ldr r5, [r0, #4]
111 str r4, [r1]
112 str r5, [r2]
113
114 /* restore interrupts */
115 msr cpsr_c, r12
116 /* restore registers */
117 ldmfd sp!, {r4-r5}
118
119 bx lr
120#endif
121
Travis Geiselbrecht1d0df692008-09-01 02:26:09 -0700122/* int atomic_and(int *ptr, int val); */
123FUNCTION(atomic_and)
Travis Geiselbrecht8d529ef2008-09-13 15:13:21 -0700124#if ARM_ISA_ARMV6 || ARM_ISA_ARMV7
125 /* use load/store exclusive */
126.L_loop_and:
Deepa Dinamani1cc97642012-05-09 11:45:38 -0700127 ldrex r12, [r0]
Travis Geiselbrecht8d529ef2008-09-13 15:13:21 -0700128 and r2, r12, r1
Deepa Dinamani1cc97642012-05-09 11:45:38 -0700129 strex r3, r2, [r0]
Travis Geiselbrecht8d529ef2008-09-13 15:13:21 -0700130 cmp r3, #0
Deepa Dinamani1cc97642012-05-09 11:45:38 -0700131 bne .L_loop_and
132
Travis Geiselbrecht8d529ef2008-09-13 15:13:21 -0700133 /* save old value */
134 mov r0, r12
135 bx lr
136#else
Travis Geiselbrecht1d0df692008-09-01 02:26:09 -0700137 /* disable interrupts, do the and, and reenable */
138 mrs r2, cpsr
139 mov r12, r2
140 orr r2, r2, #(3<<6)
141 msr cpsr_c, r2
142
143 /* ints disabled, old cpsr state in r12 */
Deepa Dinamani1cc97642012-05-09 11:45:38 -0700144
Travis Geiselbrecht1d0df692008-09-01 02:26:09 -0700145 /* do the and, leave the previous value in r0 */
146 mov r3, r0
147 ldr r0, [r3]
148 and r2, r0, r1
149 str r2, [r3]
150
151 /* restore interrupts and exit */
152 msr cpsr_c, r12
153 bx lr
Travis Geiselbrecht8d529ef2008-09-13 15:13:21 -0700154#endif
Deepa Dinamani1cc97642012-05-09 11:45:38 -0700155
Travis Geiselbrecht1d0df692008-09-01 02:26:09 -0700156/* int atomic_or(int *ptr, int val); */
157FUNCTION(atomic_or)
Travis Geiselbrecht8d529ef2008-09-13 15:13:21 -0700158#if ARM_ISA_ARMV6 || ARM_ISA_ARMV7
159 /* use load/store exclusive */
160.L_loop_or:
Deepa Dinamani1cc97642012-05-09 11:45:38 -0700161 ldrex r12, [r0]
Travis Geiselbrecht8d529ef2008-09-13 15:13:21 -0700162 orr r2, r12, r1
Deepa Dinamani1cc97642012-05-09 11:45:38 -0700163 strex r3, r2, [r0]
Travis Geiselbrecht8d529ef2008-09-13 15:13:21 -0700164 cmp r3, #0
Deepa Dinamani1cc97642012-05-09 11:45:38 -0700165 bne .L_loop_or
166
Travis Geiselbrecht8d529ef2008-09-13 15:13:21 -0700167 /* save old value */
168 mov r0, r12
169 bx lr
170#else
Travis Geiselbrecht1d0df692008-09-01 02:26:09 -0700171 /* disable interrupts, do the or, and reenable */
172 mrs r2, cpsr
173 mov r12, r2
174 orr r2, r2, #(3<<6)
175 msr cpsr_c, r2
176
177 /* ints disabled, old cpsr state in r12 */
Deepa Dinamani1cc97642012-05-09 11:45:38 -0700178
Travis Geiselbrecht1d0df692008-09-01 02:26:09 -0700179 /* do the or, leave the previous value in r0 */
180 mov r3, r0
181 ldr r0, [r3]
182 orr r2, r0, r1
183 str r2, [r3]
184
185 /* restore interrupts and exit */
186 msr cpsr_c, r12
187 bx lr
Travis Geiselbrecht8d529ef2008-09-13 15:13:21 -0700188#endif
Travis Geiselbrecht1d0df692008-09-01 02:26:09 -0700189
190/* void arch_idle(); */
191FUNCTION(arch_idle)
192#if ARM_CPU_CORTEX_A8
Channagoud Kadabibca52542014-01-30 14:35:39 -0800193 wfi
Travis Geiselbrecht1d0df692008-09-01 02:26:09 -0700194#elif ARM_CPU_ARM1136 || ARM_CPU_ARM926
195 mov r0, #0
196 mcr p15, 0, r0, c7, c0, #4
197#elif ARM_CPU_ARM7
198 /* nothing to do here */
199#else
200#error unknown cpu
201#endif
202 bx lr
203
204/* uint32_t arm_read_cr1(void) */
205FUNCTION(arm_read_cr1)
206 mrc p15, 0, r0, c1, c0, 0
207 bx lr
208
209/* void arm_write_cr1(uint32_t val) */
210FUNCTION(arm_write_cr1)
211 mcr p15, 0, r0, c1, c0, 0
Channagoud Kadabic9f8da62013-08-05 15:27:13 -0700212#if ARM_CPU_CORTEX_A8
213 isb sy
214#elif ARM_CPU_ARM1136
215 mov r0, #0
216 mcr p15, 0, r0, c7, c5, 4
217#endif
Travis Geiselbrecht1d0df692008-09-01 02:26:09 -0700218 bx lr
219
220/* uint32_t arm_read_cr1_aux(void) */
221FUNCTION(arm_read_cr1_aux)
222 mrc p15, 0, r0, c1, c0, 1
223 bx lr
224
225/* void arm_write_cr1_aux(uint32_t val) */
226FUNCTION(arm_write_cr1_aux)
227 mcr p15, 0, r0, c1, c0, 1
228 bx lr
229
230/* void arm_write_ttbr(uint32_t val) */
231FUNCTION(arm_write_ttbr)
Deepa Dinamani1cc97642012-05-09 11:45:38 -0700232 mcr p15, 0, r0, c2, c0, 0
Travis Geiselbrecht1d0df692008-09-01 02:26:09 -0700233 bx lr
234
235/* void arm_write_dacr(uint32_t val) */
236FUNCTION(arm_write_dacr)
Deepa Dinamani1cc97642012-05-09 11:45:38 -0700237 mcr p15, 0, r0, c3, c0, 0
Travis Geiselbrecht1d0df692008-09-01 02:26:09 -0700238 bx lr
239
240/* void arm_invalidate_tlb(void) */
241FUNCTION(arm_invalidate_tlb)
242 mov r0, #0
Deepa Dinamani1cc97642012-05-09 11:45:38 -0700243 mcr p15, 0, r0, c8, c7, 0
Channagoud Kadabic9f8da62013-08-05 15:27:13 -0700244#if ARM_CPU_CORTEX_A8
245 dsb sy
246#elif ARM_CPU_ARM1136
247 mov r0, #0
248 mcr p15, 0, r0, c7, c10, 4
249#endif
250#if ARM_CPU_CORTEX_A8
251 isb sy
252#elif ARM_CPU_ARM1136
253 mov r0, #0
254 mcr p15, 0, r0, c7, c5, 4
255#endif
Travis Geiselbrecht1d0df692008-09-01 02:26:09 -0700256 bx lr
257
258/* void arch_switch_stacks_and_call(addr_t call, addr_t stack) */
259FUNCTION(arch_switch_stacks_and_call)
260 mov sp, r1
Deepa Dinamani1cc97642012-05-09 11:45:38 -0700261 bx r0
Subbaraman Narayanamurthyc6472782010-09-30 12:39:14 -0700262
263/*void dmb(void) */
264FUNCTION(dmb)
265#if ARM_CPU_CORTEX_A8
266 dmb sy
267#elif ARM_CPU_ARM1136
268 mov r0, #0
269 mcr p15, 0, r0, c7, c10, 5
270#endif
271 bx lr
Shashank Mittal97d0f092011-07-25 13:30:19 -0700272
Ajay Dudanica0b6a22011-05-18 19:48:32 -0700273/* uint32_t arm_read_cycle_count(void); */
274FUNCTION(arm_read_cycle_count)
275
276/* uint32_t arch_cycle_count(void); */
277FUNCTION(arch_cycle_count)
278#if ARM_CPU_CORTEX_A8
279 mrc p15, 0, r0, c9, c13, 0
280#else
281 mov r0, #0
282#endif
283 bx lr