M7350/kernel/arch/arm/common/fiq_glue.S

119 lines
2.5 KiB
ArmAsm
Raw Normal View History

2024-09-09 08:52:07 +00:00
/*
* Copyright (C) 2008 Google, Inc.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#include <linux/linkage.h>
#include <asm/assembler.h>
.text
.global fiq_glue_end
/* fiq stack: r0-r15,cpsr,spsr of interrupted mode */
ENTRY(fiq_glue)
2024-09-09 08:57:42 +00:00
/* store pc, cpsr from previous mode, reserve space for spsr */
2024-09-09 08:52:07 +00:00
mrs r12, spsr
2024-09-09 08:57:42 +00:00
sub lr, lr, #4
2024-09-09 08:52:07 +00:00
subs r10, #1
bne nested_fiq
2024-09-09 08:57:42 +00:00
str r12, [sp, #-8]!
str lr, [sp, #-4]!
2024-09-09 08:52:07 +00:00
/* store r8-r14 from previous mode */
sub sp, sp, #(7 * 4)
stmia sp, {r8-r14}^
nop
/* store r0-r7 from previous mode */
stmfd sp!, {r0-r7}
/* setup func(data,regs) arguments */
mov r0, r9
mov r1, sp
mov r3, r8
mov r7, sp
/* Get sp and lr from non-user modes */
and r4, r12, #MODE_MASK
cmp r4, #USR_MODE
beq fiq_from_usr_mode
mov r7, sp
orr r4, r4, #(PSR_I_BIT | PSR_F_BIT)
msr cpsr_c, r4
str sp, [r7, #(4 * 13)]
str lr, [r7, #(4 * 14)]
mrs r5, spsr
str r5, [r7, #(4 * 17)]
cmp r4, #(SVC_MODE | PSR_I_BIT | PSR_F_BIT)
/* use fiq stack if we reenter this mode */
subne sp, r7, #(4 * 3)
fiq_from_usr_mode:
msr cpsr_c, #(SVC_MODE | PSR_I_BIT | PSR_F_BIT)
mov r2, sp
sub sp, r7, #12
stmfd sp!, {r2, ip, lr}
/* call func(data,regs) */
blx r3
ldmfd sp, {r2, ip, lr}
mov sp, r2
/* restore/discard saved state */
cmp r4, #USR_MODE
beq fiq_from_usr_mode_exit
msr cpsr_c, r4
ldr sp, [r7, #(4 * 13)]
ldr lr, [r7, #(4 * 14)]
msr spsr_cxsf, r5
fiq_from_usr_mode_exit:
msr cpsr_c, #(FIQ_MODE | PSR_I_BIT | PSR_F_BIT)
ldmfd sp!, {r0-r7}
2024-09-09 08:57:42 +00:00
ldr lr, [sp, #(4 * 7)]
ldr r12, [sp, #(4 * 8)]
add sp, sp, #(10 * 4)
2024-09-09 08:52:07 +00:00
exit_fiq:
msr spsr_cxsf, r12
add r10, #1
2024-09-09 08:57:42 +00:00
cmp r11, #0
moveqs pc, lr
bx r11 /* jump to custom fiq return function */
2024-09-09 08:52:07 +00:00
nested_fiq:
orr r12, r12, #(PSR_F_BIT)
b exit_fiq
fiq_glue_end:
2024-09-09 08:57:42 +00:00
ENTRY(fiq_glue_setup) /* func, data, sp, smc call number */
stmfd sp!, {r4}
mrs r4, cpsr
2024-09-09 08:52:07 +00:00
msr cpsr_c, #(FIQ_MODE | PSR_I_BIT | PSR_F_BIT)
movs r8, r0
mov r9, r1
mov sp, r2
2024-09-09 08:57:42 +00:00
mov r11, r3
2024-09-09 08:52:07 +00:00
moveq r10, #0
movne r10, #1
2024-09-09 08:57:42 +00:00
msr cpsr_c, r4
ldmfd sp!, {r4}
2024-09-09 08:52:07 +00:00
bx lr