blob: c97a4d62043cd1d6dec50016eaddbbc1c7f3d799 [file] [log] [blame]
Travis Geiselbrecht1d0df692008-09-01 02:26:09 -07001/*
2 * Copyright (c) 2008 Travis Geiselbrecht
3 *
Channagoud Kadabi4db45f82015-07-02 14:54:48 -07004 * Copyright (c) 2014-2015 The Linux Foundation. All rights reserved.
Channagoud Kadabibca52542014-01-30 14:35:39 -08005 *
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)
Channagoud Kadabif2bceda2014-12-19 13:35:45 -080045.L_loop_swap:
46 ldrex r12, [r0]
47 strex r2, r1, [r0]
48 cmp r2 , #0
49 bne .L_loop_swap
50
51 mov r0, r12
Travis Geiselbrecht1d0df692008-09-01 02:26:09 -070052 bx lr
53
54/* int atomic_add(int *ptr, int val); */
55FUNCTION(atomic_add)
Travis Geiselbrecht8d529ef2008-09-13 15:13:21 -070056#if ARM_ISA_ARMV6 || ARM_ISA_ARMV7
57 /* use load/store exclusive */
58.L_loop_add:
Deepa Dinamani1cc97642012-05-09 11:45:38 -070059 ldrex r12, [r0]
Travis Geiselbrecht8d529ef2008-09-13 15:13:21 -070060 add r2, r12, r1
Deepa Dinamani1cc97642012-05-09 11:45:38 -070061 strex r3, r2, [r0]
Travis Geiselbrecht8d529ef2008-09-13 15:13:21 -070062 cmp r3, #0
Deepa Dinamani1cc97642012-05-09 11:45:38 -070063 bne .L_loop_add
64
Travis Geiselbrecht8d529ef2008-09-13 15:13:21 -070065 /* save old value */
66 mov r0, r12
67 bx lr
68#else
Travis Geiselbrecht1d0df692008-09-01 02:26:09 -070069 /* disable interrupts, do the add, and reenable */
70 mrs r2, cpsr
71 mov r12, r2
72 orr r2, r2, #(3<<6)
73 msr cpsr_c, r2
74
75 /* ints disabled, old cpsr state in r12 */
Deepa Dinamani1cc97642012-05-09 11:45:38 -070076
Travis Geiselbrecht1d0df692008-09-01 02:26:09 -070077 /* do the add, leave the previous value in r0 */
78 mov r3, r0
79 ldr r0, [r3]
80 add r2, r0, r1
81 str r2, [r3]
82
83 /* restore interrupts and exit */
84 msr cpsr_c, r12
85 bx lr
Travis Geiselbrecht8d529ef2008-09-13 15:13:21 -070086#endif
Deepa Dinamani1cc97642012-05-09 11:45:38 -070087
Deepa Dinamanid642b802012-05-16 10:49:01 -070088/* uint64_t atomic_dw_read(uint32_t rd_addr,
89 * uint32_t st_addr_lo, uint32_t st_addr_hi);
90 */
91/* Reads a double word from memory atomically */
92FUNCTION(atomic_dw_read)
93#if ARM_ISA_ARMV6 || ARM_ISA_ARMV7
94 stmfd sp!, {r4-r5}
95 /* use load/store exclusive */
96 ldrexd r4, [r0]
97 str r4, [r1]
98 str r5, [r2]
99
100 /* Restore registers */
101 ldmfd sp!, {r4-r5}
102
103 bx lr
104#else
105 stmfd sp!, {r4-r5}
106 /* disable interrupts, do read, and reenable */
107 mrs r2, cpsr
108 mov r12, r2
109 orr r2, r2, #(3<<6)
110 msr cpsr_c, r2
111
112 /* ints disabled, old cpsr state in r12 */
113
114 /* do memory read, return the double word read */
115 ldr r4, [r0]
116 ldr r5, [r0, #4]
117 str r4, [r1]
118 str r5, [r2]
119
120 /* restore interrupts */
121 msr cpsr_c, r12
122 /* restore registers */
123 ldmfd sp!, {r4-r5}
124
125 bx lr
126#endif
127
Travis Geiselbrecht1d0df692008-09-01 02:26:09 -0700128/* int atomic_and(int *ptr, int val); */
129FUNCTION(atomic_and)
Travis Geiselbrecht8d529ef2008-09-13 15:13:21 -0700130#if ARM_ISA_ARMV6 || ARM_ISA_ARMV7
131 /* use load/store exclusive */
132.L_loop_and:
Deepa Dinamani1cc97642012-05-09 11:45:38 -0700133 ldrex r12, [r0]
Travis Geiselbrecht8d529ef2008-09-13 15:13:21 -0700134 and r2, r12, r1
Deepa Dinamani1cc97642012-05-09 11:45:38 -0700135 strex r3, r2, [r0]
Travis Geiselbrecht8d529ef2008-09-13 15:13:21 -0700136 cmp r3, #0
Deepa Dinamani1cc97642012-05-09 11:45:38 -0700137 bne .L_loop_and
138
Travis Geiselbrecht8d529ef2008-09-13 15:13:21 -0700139 /* save old value */
140 mov r0, r12
141 bx lr
142#else
Travis Geiselbrecht1d0df692008-09-01 02:26:09 -0700143 /* disable interrupts, do the and, and reenable */
144 mrs r2, cpsr
145 mov r12, r2
146 orr r2, r2, #(3<<6)
147 msr cpsr_c, r2
148
149 /* ints disabled, old cpsr state in r12 */
Deepa Dinamani1cc97642012-05-09 11:45:38 -0700150
Travis Geiselbrecht1d0df692008-09-01 02:26:09 -0700151 /* do the and, leave the previous value in r0 */
152 mov r3, r0
153 ldr r0, [r3]
154 and r2, r0, r1
155 str r2, [r3]
156
157 /* restore interrupts and exit */
158 msr cpsr_c, r12
159 bx lr
Travis Geiselbrecht8d529ef2008-09-13 15:13:21 -0700160#endif
Deepa Dinamani1cc97642012-05-09 11:45:38 -0700161
Travis Geiselbrecht1d0df692008-09-01 02:26:09 -0700162/* int atomic_or(int *ptr, int val); */
163FUNCTION(atomic_or)
Travis Geiselbrecht8d529ef2008-09-13 15:13:21 -0700164#if ARM_ISA_ARMV6 || ARM_ISA_ARMV7
165 /* use load/store exclusive */
166.L_loop_or:
Deepa Dinamani1cc97642012-05-09 11:45:38 -0700167 ldrex r12, [r0]
Travis Geiselbrecht8d529ef2008-09-13 15:13:21 -0700168 orr r2, r12, r1
Deepa Dinamani1cc97642012-05-09 11:45:38 -0700169 strex r3, r2, [r0]
Travis Geiselbrecht8d529ef2008-09-13 15:13:21 -0700170 cmp r3, #0
Deepa Dinamani1cc97642012-05-09 11:45:38 -0700171 bne .L_loop_or
172
Travis Geiselbrecht8d529ef2008-09-13 15:13:21 -0700173 /* save old value */
174 mov r0, r12
175 bx lr
176#else
Travis Geiselbrecht1d0df692008-09-01 02:26:09 -0700177 /* disable interrupts, do the or, and reenable */
178 mrs r2, cpsr
179 mov r12, r2
180 orr r2, r2, #(3<<6)
181 msr cpsr_c, r2
182
183 /* ints disabled, old cpsr state in r12 */
Deepa Dinamani1cc97642012-05-09 11:45:38 -0700184
Travis Geiselbrecht1d0df692008-09-01 02:26:09 -0700185 /* do the or, leave the previous value in r0 */
186 mov r3, r0
187 ldr r0, [r3]
188 orr r2, r0, r1
189 str r2, [r3]
190
191 /* restore interrupts and exit */
192 msr cpsr_c, r12
193 bx lr
Travis Geiselbrecht8d529ef2008-09-13 15:13:21 -0700194#endif
Travis Geiselbrecht1d0df692008-09-01 02:26:09 -0700195
196/* void arch_idle(); */
197FUNCTION(arch_idle)
198#if ARM_CPU_CORTEX_A8
Channagoud Kadabibca52542014-01-30 14:35:39 -0800199 wfi
Travis Geiselbrecht1d0df692008-09-01 02:26:09 -0700200#elif ARM_CPU_ARM1136 || ARM_CPU_ARM926
201 mov r0, #0
202 mcr p15, 0, r0, c7, c0, #4
203#elif ARM_CPU_ARM7
204 /* nothing to do here */
205#else
206#error unknown cpu
207#endif
208 bx lr
209
210/* uint32_t arm_read_cr1(void) */
211FUNCTION(arm_read_cr1)
212 mrc p15, 0, r0, c1, c0, 0
213 bx lr
214
215/* void arm_write_cr1(uint32_t val) */
216FUNCTION(arm_write_cr1)
217 mcr p15, 0, r0, c1, c0, 0
Channagoud Kadabic9f8da62013-08-05 15:27:13 -0700218#if ARM_CPU_CORTEX_A8
219 isb sy
220#elif ARM_CPU_ARM1136
221 mov r0, #0
222 mcr p15, 0, r0, c7, c5, 4
223#endif
Travis Geiselbrecht1d0df692008-09-01 02:26:09 -0700224 bx lr
225
226/* uint32_t arm_read_cr1_aux(void) */
227FUNCTION(arm_read_cr1_aux)
228 mrc p15, 0, r0, c1, c0, 1
229 bx lr
230
231/* void arm_write_cr1_aux(uint32_t val) */
232FUNCTION(arm_write_cr1_aux)
233 mcr p15, 0, r0, c1, c0, 1
234 bx lr
235
236/* void arm_write_ttbr(uint32_t val) */
237FUNCTION(arm_write_ttbr)
Deepa Dinamani1cc97642012-05-09 11:45:38 -0700238 mcr p15, 0, r0, c2, c0, 0
Travis Geiselbrecht1d0df692008-09-01 02:26:09 -0700239 bx lr
240
241/* void arm_write_dacr(uint32_t val) */
242FUNCTION(arm_write_dacr)
Deepa Dinamani1cc97642012-05-09 11:45:38 -0700243 mcr p15, 0, r0, c3, c0, 0
Travis Geiselbrecht1d0df692008-09-01 02:26:09 -0700244 bx lr
245
246/* void arm_invalidate_tlb(void) */
247FUNCTION(arm_invalidate_tlb)
Channagoud Kadabi4db45f82015-07-02 14:54:48 -0700248 dsb
249 isb
Travis Geiselbrecht1d0df692008-09-01 02:26:09 -0700250 mov r0, #0
Deepa Dinamani1cc97642012-05-09 11:45:38 -0700251 mcr p15, 0, r0, c8, c7, 0
Channagoud Kadabic9f8da62013-08-05 15:27:13 -0700252#if ARM_CPU_CORTEX_A8
253 dsb sy
254#elif ARM_CPU_ARM1136
255 mov r0, #0
256 mcr p15, 0, r0, c7, c10, 4
257#endif
258#if ARM_CPU_CORTEX_A8
259 isb sy
260#elif ARM_CPU_ARM1136
261 mov r0, #0
262 mcr p15, 0, r0, c7, c5, 4
263#endif
Travis Geiselbrecht1d0df692008-09-01 02:26:09 -0700264 bx lr
265
266/* void arch_switch_stacks_and_call(addr_t call, addr_t stack) */
267FUNCTION(arch_switch_stacks_and_call)
268 mov sp, r1
Deepa Dinamani1cc97642012-05-09 11:45:38 -0700269 bx r0
Subbaraman Narayanamurthyc6472782010-09-30 12:39:14 -0700270
271/*void dmb(void) */
272FUNCTION(dmb)
273#if ARM_CPU_CORTEX_A8
274 dmb sy
275#elif ARM_CPU_ARM1136
276 mov r0, #0
277 mcr p15, 0, r0, c7, c10, 5
278#endif
279 bx lr
Shashank Mittal97d0f092011-07-25 13:30:19 -0700280
Ajay Dudanica0b6a22011-05-18 19:48:32 -0700281/* uint32_t arm_read_cycle_count(void); */
282FUNCTION(arm_read_cycle_count)
283
284/* uint32_t arch_cycle_count(void); */
285FUNCTION(arch_cycle_count)
286#if ARM_CPU_CORTEX_A8
287 mrc p15, 0, r0, c9, c13, 0
288#else
289 mov r0, #0
290#endif
291 bx lr
Channagoud Kadabi70f9c4e2015-06-17 17:29:10 -0700292
293FUNCTION(arm_write_mair0)
294 mcr p15, 0, r0, c10, c2, 0
295 bx lr
296
297FUNCTION(arm_write_mair1)
298 mcr p15, 0, r0, c10, c2, 1
299 bx lr
300
301FUNCTION(arm_write_ttbcr)
302 mcr p15, 0, r0, c2, c0, 2
303 bx lr