2 * Copyright 2009, Wischert, johanneswi@gmail.com.
3 * All rights reserved. Distributed under the terms of the MIT License.
5 * Copyright 2003, Travis Geiselbrecht. All rights reserved.
6 * Distributed under the terms of the NewOS License.
9 #include <arch/arm/arch_cpu.h>
13 #include "asm_offsets.h"
18 /* int mmu_read_c1(void); */
19 FUNCTION(mmu_read_c1):
20 mrc p15, 0, r0, c1, c0, 0
22 FUNCTION_END(mmu_read_c1)
25 /* void mmu_write_c1(int val); */
26 FUNCTION(mmu_write_c1):
27 mcr p15, 0, r0, c1, c0, 0
29 FUNCTION_END(mmu_write_c1)
32 /* NOTE: the I bit in cpsr (bit 7) is *set* to disable... */
35 /* void arch_int_enable_interrupts(void) */
36 FUNCTION(arch_int_enable_interrupts):
41 FUNCTION_END(arch_int_enable_interrupts)
44 /* int arch_int_disable_interrupts(void) */
45 FUNCTION(arch_int_disable_interrupts):
50 FUNCTION_END(arch_int_disable_interrupts)
53 /* void arch_int_restore_interrupts(int oldState) */
54 FUNCTION(arch_int_restore_interrupts):
61 FUNCTION_END(arch_int_restore_interrupts)
64 /* bool arch_int_are_interrupts_enabled(void) */
65 FUNCTION(arch_int_are_interrupts_enabled):
67 and r0, r0, #(1<<7) /*read the I bit*/
72 FUNCTION_END(arch_int_are_interrupts_enabled)
75 /* void arm_context_switch(struct arch_thread* oldState,
76 struct arch_thread* newState); */
77 FUNCTION(arm_context_switch):
78 stmfd sp!, { r0-r12, lr }
81 ldmfd sp!, { r0-r12, lr }
83 FUNCTION_END(arm_context_switch)
86 /* addr_t arm_get_fsr(void); */
87 FUNCTION(arm_get_fsr):
88 mrc p15, 0, r0, c5, c0, 0 @ get FSR
90 FUNCTION_END(arm_get_fsr)
93 /* addr_t arm_get_far(void); */
94 FUNCTION(arm_get_far):
95 mrc p15, 0, r0, c6, c0, 0 @ get FAR
97 FUNCTION_END(arm_get_far)
100 /* addr_t arm_get_fp(void); */
101 FUNCTION(arm_get_fp):
102 mov r0, fp @ get framepointer
104 FUNCTION_END(arm_get_fp);
107 /* status_t arch_cpu_user_memcpy(void *to, const void *from, size_t size, addr_t *faultHandler) */
108 FUNCTION(_arch_cpu_user_memcpy):
109 stmfd sp!, { r4-r6, lr }
112 ldr r4, =.L_user_memcpy_error
113 str r4, [r3] /* set fault handler */
114 mov r4, r2, lsr #2 /* size / 4 */
123 ands r4, r2, #3 /* size % 4 */
134 str r6, [r3] /* restore fault handler */
136 ldmfd sp!, { r4-r6, pc }
138 .L_user_memcpy_error:
139 str r6, [r3] /* restore fault handler */
142 ldmfd sp!, { r4-r6, pc }
143 FUNCTION_END(_arch_cpu_user_memcpy)
145 /* status_t arch_cpu_user_memset(void *to, char c, size_t count, addr_t *faultHandler) */
146 FUNCTION(_arch_cpu_user_memset):
147 stmfd sp!, { r4-r5, lr }
150 ldr r4, =.L_user_memset_error
158 mov r4, r2, lsr #2 /* count / 4 */
165 and r4, r2, #3 /* count % 4 */
175 ldmfd sp!, { r4-r5, pc }
177 .L_user_memset_error:
181 ldmfd sp!, { r4-r5, pc }
182 FUNCTION_END(_arch_cpu_user_memset)
184 /* ssize_t arch_cpu_user_strlcpy(void *to, const void *from, size_t size, addr_t *faultHandler) */
185 FUNCTION(_arch_cpu_user_strlcpy):
186 stmfd sp!, { r4-r6, lr }
188 ldr r4, =.L_user_strlcpy_error
197 cmp r6, r2 /* reached max length? */
203 mov r0, r6 /* return length */
204 str r5, [r3] /* restore fault handler */
206 ldmfd sp!, { r4-r6, pc }
208 .L_user_strlcpy_error:
212 ldmfd sp!, { r4-r6, pc }
213 FUNCTION_END(_arch_cpu_user_strlcpy)
216 /*! \fn void arch_debug_call_with_fault_handler(cpu_ent* cpu,
217 jmp_buf jumpBuffer, void (*function)(void*), void* parameter)
219 Called by debug_call_with_fault_handler() to do the dirty work of setting
220 the fault handler and calling the function. If the function causes a page
221 fault, the arch_debug_call_with_fault_handler() calls longjmp() with the
222 given \a jumpBuffer. Otherwise it returns normally.
224 debug_call_with_fault_handler() has already saved the CPU's fault_handler
225 and fault_handler_stack_pointer and will reset them later, so
226 arch_debug_call_with_fault_handler() doesn't need to care about it.
228 \param cpu The \c cpu_ent for the current CPU.
229 \param jumpBuffer Buffer to be used for longjmp().
230 \param function The function to be called.
231 \param parameter The parameter to be passed to the function to be called.
233 FUNCTION(arch_debug_call_with_fault_handler):
234 stmfd sp!, { r1, r4, lr }
236 // Set fault handler address, and fault handler stack pointer address. We
237 // don't need to save the previous values, since that's done by the caller.
239 str r4, [r0, #CPU_ENT_fault_handler]
240 str sp, [r0, #CPU_ENT_fault_handler_stack_pointer]
248 ldmfd sp!, { r1, r4, pc }
250 // fault -- return via longjmp(jumpBuffer, 1)
252 ldmfd sp!, { r0, r4, lr } // restore jumpBuffer in r0 (was r1)
255 FUNCTION_END(arch_debug_call_with_fault_handler)