blob: 2581273f21237e647a68a1e114499204a804a66c [file] [log] [blame]
Travis Geiselbrecht1d0df692008-09-01 02:26:09 -07001/*
2 * Copyright (c) 2008 Travis Geiselbrecht
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining
5 * a copy of this software and associated documentation files
6 * (the "Software"), to deal in the Software without restriction,
7 * including without limitation the rights to use, copy, modify, merge,
8 * publish, distribute, sublicense, and/or sell copies of the Software,
9 * and to permit persons to whom the Software is furnished to do so,
10 * subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be
13 * included in all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
20 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
21 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 */
23#include <asm.h>
24
25.text
26
27/* void arch_enable_ints(void); */
28FUNCTION(arch_enable_ints)
29 mrs r0, cpsr
30 bic r0, r0, #(1<<7) /* clear the I bit */
31 msr cpsr_c, r0
32 bx lr
33
34/* void arch_disable_ints(void); */
35FUNCTION(arch_disable_ints)
36 mrs r0, cpsr
37 orr r0, r0, #(1<<7)
38 msr cpsr_c, r0
39 bx lr
40
41/* int atomic_swap(int *ptr, int val); */
42FUNCTION(atomic_swap)
43 swp r0, r2, [r1]
44 bx lr
45
46/* int atomic_add(int *ptr, int val); */
47FUNCTION(atomic_add)
Travis Geiselbrecht8d529ef2008-09-13 15:13:21 -070048#if ARM_ISA_ARMV6 || ARM_ISA_ARMV7
49 /* use load/store exclusive */
50.L_loop_add:
Deepa Dinamani1cc97642012-05-09 11:45:38 -070051 ldrex r12, [r0]
Travis Geiselbrecht8d529ef2008-09-13 15:13:21 -070052 add r2, r12, r1
Deepa Dinamani1cc97642012-05-09 11:45:38 -070053 strex r3, r2, [r0]
Travis Geiselbrecht8d529ef2008-09-13 15:13:21 -070054 cmp r3, #0
Deepa Dinamani1cc97642012-05-09 11:45:38 -070055 bne .L_loop_add
56
Travis Geiselbrecht8d529ef2008-09-13 15:13:21 -070057 /* save old value */
58 mov r0, r12
59 bx lr
60#else
Travis Geiselbrecht1d0df692008-09-01 02:26:09 -070061 /* disable interrupts, do the add, and reenable */
62 mrs r2, cpsr
63 mov r12, r2
64 orr r2, r2, #(3<<6)
65 msr cpsr_c, r2
66
67 /* ints disabled, old cpsr state in r12 */
Deepa Dinamani1cc97642012-05-09 11:45:38 -070068
Travis Geiselbrecht1d0df692008-09-01 02:26:09 -070069 /* do the add, leave the previous value in r0 */
70 mov r3, r0
71 ldr r0, [r3]
72 add r2, r0, r1
73 str r2, [r3]
74
75 /* restore interrupts and exit */
76 msr cpsr_c, r12
77 bx lr
Travis Geiselbrecht8d529ef2008-09-13 15:13:21 -070078#endif
Deepa Dinamani1cc97642012-05-09 11:45:38 -070079
Deepa Dinamanid642b802012-05-16 10:49:01 -070080/* uint64_t atomic_dw_read(uint32_t rd_addr,
81 * uint32_t st_addr_lo, uint32_t st_addr_hi);
82 */
83/* Reads a double word from memory atomically */
84FUNCTION(atomic_dw_read)
85#if ARM_ISA_ARMV6 || ARM_ISA_ARMV7
86 stmfd sp!, {r4-r5}
87 /* use load/store exclusive */
88 ldrexd r4, [r0]
89 str r4, [r1]
90 str r5, [r2]
91
92 /* Restore registers */
93 ldmfd sp!, {r4-r5}
94
95 bx lr
96#else
97 stmfd sp!, {r4-r5}
98 /* disable interrupts, do read, 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 memory read, return the double word read */
107 ldr r4, [r0]
108 ldr r5, [r0, #4]
109 str r4, [r1]
110 str r5, [r2]
111
112 /* restore interrupts */
113 msr cpsr_c, r12
114 /* restore registers */
115 ldmfd sp!, {r4-r5}
116
117 bx lr
118#endif
119
Travis Geiselbrecht1d0df692008-09-01 02:26:09 -0700120/* int atomic_and(int *ptr, int val); */
121FUNCTION(atomic_and)
Travis Geiselbrecht8d529ef2008-09-13 15:13:21 -0700122#if ARM_ISA_ARMV6 || ARM_ISA_ARMV7
123 /* use load/store exclusive */
124.L_loop_and:
Deepa Dinamani1cc97642012-05-09 11:45:38 -0700125 ldrex r12, [r0]
Travis Geiselbrecht8d529ef2008-09-13 15:13:21 -0700126 and r2, r12, r1
Deepa Dinamani1cc97642012-05-09 11:45:38 -0700127 strex r3, r2, [r0]
Travis Geiselbrecht8d529ef2008-09-13 15:13:21 -0700128 cmp r3, #0
Deepa Dinamani1cc97642012-05-09 11:45:38 -0700129 bne .L_loop_and
130
Travis Geiselbrecht8d529ef2008-09-13 15:13:21 -0700131 /* save old value */
132 mov r0, r12
133 bx lr
134#else
Travis Geiselbrecht1d0df692008-09-01 02:26:09 -0700135 /* disable interrupts, do the and, and reenable */
136 mrs r2, cpsr
137 mov r12, r2
138 orr r2, r2, #(3<<6)
139 msr cpsr_c, r2
140
141 /* ints disabled, old cpsr state in r12 */
Deepa Dinamani1cc97642012-05-09 11:45:38 -0700142
Travis Geiselbrecht1d0df692008-09-01 02:26:09 -0700143 /* do the and, leave the previous value in r0 */
144 mov r3, r0
145 ldr r0, [r3]
146 and r2, r0, r1
147 str r2, [r3]
148
149 /* restore interrupts and exit */
150 msr cpsr_c, r12
151 bx lr
Travis Geiselbrecht8d529ef2008-09-13 15:13:21 -0700152#endif
Deepa Dinamani1cc97642012-05-09 11:45:38 -0700153
Travis Geiselbrecht1d0df692008-09-01 02:26:09 -0700154/* int atomic_or(int *ptr, int val); */
155FUNCTION(atomic_or)
Travis Geiselbrecht8d529ef2008-09-13 15:13:21 -0700156#if ARM_ISA_ARMV6 || ARM_ISA_ARMV7
157 /* use load/store exclusive */
158.L_loop_or:
Deepa Dinamani1cc97642012-05-09 11:45:38 -0700159 ldrex r12, [r0]
Travis Geiselbrecht8d529ef2008-09-13 15:13:21 -0700160 orr r2, r12, r1
Deepa Dinamani1cc97642012-05-09 11:45:38 -0700161 strex r3, r2, [r0]
Travis Geiselbrecht8d529ef2008-09-13 15:13:21 -0700162 cmp r3, #0
Deepa Dinamani1cc97642012-05-09 11:45:38 -0700163 bne .L_loop_or
164
Travis Geiselbrecht8d529ef2008-09-13 15:13:21 -0700165 /* save old value */
166 mov r0, r12
167 bx lr
168#else
Travis Geiselbrecht1d0df692008-09-01 02:26:09 -0700169 /* disable interrupts, do the or, and reenable */
170 mrs r2, cpsr
171 mov r12, r2
172 orr r2, r2, #(3<<6)
173 msr cpsr_c, r2
174
175 /* ints disabled, old cpsr state in r12 */
Deepa Dinamani1cc97642012-05-09 11:45:38 -0700176
Travis Geiselbrecht1d0df692008-09-01 02:26:09 -0700177 /* do the or, leave the previous value in r0 */
178 mov r3, r0
179 ldr r0, [r3]
180 orr r2, r0, r1
181 str r2, [r3]
182
183 /* restore interrupts and exit */
184 msr cpsr_c, r12
185 bx lr
Travis Geiselbrecht8d529ef2008-09-13 15:13:21 -0700186#endif
Travis Geiselbrecht1d0df692008-09-01 02:26:09 -0700187
188/* void arch_idle(); */
189FUNCTION(arch_idle)
190#if ARM_CPU_CORTEX_A8
191 .word 0xe320f003 /* wfi */
Brian Swetlandaf7dab42008-09-07 02:49:51 -0700192#elif PLATFORM_MSM7K
193 /* TODO: safely handle 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
212 bx lr
213
214/* uint32_t arm_read_cr1_aux(void) */
215FUNCTION(arm_read_cr1_aux)
216 mrc p15, 0, r0, c1, c0, 1
217 bx lr
218
219/* void arm_write_cr1_aux(uint32_t val) */
220FUNCTION(arm_write_cr1_aux)
221 mcr p15, 0, r0, c1, c0, 1
222 bx lr
223
224/* void arm_write_ttbr(uint32_t val) */
225FUNCTION(arm_write_ttbr)
Deepa Dinamani1cc97642012-05-09 11:45:38 -0700226 mcr p15, 0, r0, c2, c0, 0
Travis Geiselbrecht1d0df692008-09-01 02:26:09 -0700227 bx lr
228
229/* void arm_write_dacr(uint32_t val) */
230FUNCTION(arm_write_dacr)
Deepa Dinamani1cc97642012-05-09 11:45:38 -0700231 mcr p15, 0, r0, c3, c0, 0
Travis Geiselbrecht1d0df692008-09-01 02:26:09 -0700232 bx lr
233
234/* void arm_invalidate_tlb(void) */
235FUNCTION(arm_invalidate_tlb)
236 mov r0, #0
Deepa Dinamani1cc97642012-05-09 11:45:38 -0700237 mcr p15, 0, r0, c8, c7, 0
Travis Geiselbrecht1d0df692008-09-01 02:26:09 -0700238 bx lr
239
240/* void arch_switch_stacks_and_call(addr_t call, addr_t stack) */
241FUNCTION(arch_switch_stacks_and_call)
242 mov sp, r1
Deepa Dinamani1cc97642012-05-09 11:45:38 -0700243 bx r0
Subbaraman Narayanamurthyc6472782010-09-30 12:39:14 -0700244
245/*void dmb(void) */
246FUNCTION(dmb)
247#if ARM_CPU_CORTEX_A8
248 dmb sy
249#elif ARM_CPU_ARM1136
250 mov r0, #0
251 mcr p15, 0, r0, c7, c10, 5
252#endif
253 bx lr
Shashank Mittal97d0f092011-07-25 13:30:19 -0700254
Deepa Dinamani1cc97642012-05-09 11:45:38 -0700255/*void isb(void) */
256FUNCTION(isb)
257#if ARM_CPU_CORTEX_A8
258 isb sy
259#elif ARM_CPU_ARM1136
260 mov r0, #0
261 mcr p15, 0, r0, c7, c5, 4
262#endif
263 bx lr
264
Shashank Mittal97d0f092011-07-25 13:30:19 -0700265/*void dsb(void) */
266FUNCTION(dsb)
267#if ARM_CPU_CORTEX_A8
268 dsb sy
269#elif ARM_CPU_ARM1136
270 mov r0, #0
271 mcr p15, 0, r0, c7, c10, 4
272#endif
273 bx lr
Ajay Dudanica0b6a22011-05-18 19:48:32 -0700274
275/* uint32_t arm_read_cycle_count(void); */
276FUNCTION(arm_read_cycle_count)
277
278/* uint32_t arch_cycle_count(void); */
279FUNCTION(arch_cycle_count)
280#if ARM_CPU_CORTEX_A8
281 mrc p15, 0, r0, c9, c13, 0
282#else
283 mov r0, #0
284#endif
285 bx lr