2 * Copyright (C) 2008 Google, Inc.
4 * This software is licensed under the terms of the GNU General Public
5 * License version 2, as published by the Free Software Foundation, and
6 * may be copied, distributed, and modified under those terms.
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
15 #include <linux/linkage.h>
16 #include <asm/assembler.h>
22 /* fiq stack: r0-r15,cpsr,spsr of interrupted mode */
25 /* store pc, cpsr from previous mode */
31 stmfd sp!, {r11-r12, lr}
33 /* store r8-r14 from previous mode */
38 /* store r0-r7 from previous mode */
41 /* setup func(data,regs) arguments */
48 /* Get sp and lr from non-user modes */
49 and r4, r12, #MODE_MASK
54 orr r4, r4, #(PSR_I_BIT | PSR_F_BIT)
56 str sp, [r7, #(4 * 13)]
57 str lr, [r7, #(4 * 14)]
59 str r5, [r7, #(4 * 17)]
61 cmp r4, #(SVC_MODE | PSR_I_BIT | PSR_F_BIT)
62 /* use fiq stack if we reenter this mode */
63 subne sp, r7, #(4 * 3)
66 msr cpsr_c, #(SVC_MODE | PSR_I_BIT | PSR_F_BIT)
69 stmfd sp!, {r2, ip, lr}
70 /* call func(data,regs) */
72 ldmfd sp, {r2, ip, lr}
75 /* restore/discard saved state */
77 beq fiq_from_usr_mode_exit
80 ldr sp, [r7, #(4 * 13)]
81 ldr lr, [r7, #(4 * 14)]
84 fiq_from_usr_mode_exit:
85 msr cpsr_c, #(FIQ_MODE | PSR_I_BIT | PSR_F_BIT)
89 ldmfd sp!, {r11-r12, lr}
96 orr r12, r12, #(PSR_F_BIT)
101 ENTRY(fiq_glue_setup) /* func, data, sp */
103 msr cpsr_c, #(FIQ_MODE | PSR_I_BIT | PSR_F_BIT)