2024-09-09 08:52:07 +00:00
|
|
|
/*
|
|
|
|
* Copyright (c) 2008 Travis Geiselbrecht
|
|
|
|
*
|
2024-09-09 08:57:42 +00:00
|
|
|
* Copyright (c) 2014, The Linux Foundation. All rights reserved.
|
|
|
|
*
|
2024-09-09 08:52:07 +00:00
|
|
|
* 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 <asm.h>
|
|
|
|
|
|
|
|
|
|
|
|
/* 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
|
2024-09-09 08:57:42 +00:00
|
|
|
clrex
|
2024-09-09 08:52:07 +00:00
|
|
|
#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
|
|
|
|
|
2024-09-09 08:57:42 +00:00
|
|
|
#if ARM_ISA_ARMv6 || ARM_ISA_ARMV7
|
2024-09-09 08:52:07 +00:00
|
|
|
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
|
|
|
|
|
|
|
|
|