/* * Copyright (c) 2008 Travis Geiselbrecht * * Copyright (c) 2014, The Linux Foundation. All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include /* context switch frame is as follows: * ulr * usp * lr * r11 * r10 * r9 * r8 * r7 * r6 * r5 * r4 */ /* arm_context_switch(addr_t *old_sp, addr_t new_sp) */ FUNCTION(arm_context_switch) /* save all the usual registers + user regs */ /* the spsr is saved and restored in the iframe by exceptions.S */ sub r3, sp, #(11*4) /* can't use sp in user mode stm */ mov r12, lr stmia r3, { r4-r11, r12, r13, r14 }^ /* save old sp */ str r3, [r0] /* clear any exlusive locks that the old thread holds */ #if ARM_ISA_ARMV7 clrex #elif ARM_ISA_ARMV6 /* have to do a fake strex to clear it */ ldr r0, =strex_spot strex r3, r2, [r0] #endif /* load new regs */ ldmia r1, { r4-r11, r12, r13, r14 }^ mov lr, r12 /* restore lr */ add sp, r1, #(11*4) /* restore sp */ bx lr .ltorg FUNCTION(arm_save_mode_regs) mrs r1, cpsr #if ARM_ISA_ARMv6 || ARM_ISA_ARMV7 cps #0x11 /* fiq */ str r13, [r0], #4 str r14, [r0], #4 cps #0x12 /* irq */ str r13, [r0], #4 str r14, [r0], #4 cps #0x13 /* svc */ str r13, [r0], #4 str r14, [r0], #4 cps #0x17 /* abt */ str r13, [r0], #4 str r14, [r0], #4 cps #0x1b /* und */ str r13, [r0], #4 str r14, [r0], #4 cps #0x1f /* sys */ str r13, [r0], #4 str r14, [r0], #4 #else // XXX implement b . #endif msr cpsr_c, r1 bx lr .data strex_spot: .word 0