blob: 6b9d966ca3ce8dd36c640fc3ce9790863a8d48db [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
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