145051539SThomas Gleixner/* SPDX-License-Identifier: GPL-2.0-only */ 22d81f1feSWill Deacon/* 32d81f1feSWill Deacon * arch/arm/lib/call_with_stack.S 42d81f1feSWill Deacon * 52d81f1feSWill Deacon * Copyright (C) 2011 ARM Ltd. 62d81f1feSWill Deacon * Written by Will Deacon <will.deacon@arm.com> 72d81f1feSWill Deacon */ 82d81f1feSWill Deacon 92d81f1feSWill Deacon#include <linux/linkage.h> 102d81f1feSWill Deacon#include <asm/assembler.h> 110b78f2e9SArd Biesheuvel#include <asm/unwind.h> 122d81f1feSWill Deacon 132d81f1feSWill Deacon/* 142d81f1feSWill Deacon * void call_with_stack(void (*fn)(void *), void *arg, void *sp) 152d81f1feSWill Deacon * 162d81f1feSWill Deacon * Change the stack to that pointed at by sp, then invoke fn(arg) with 172d81f1feSWill Deacon * the new stack. 180b78f2e9SArd Biesheuvel * 190b78f2e9SArd Biesheuvel * The sequence below follows the APCS frame convention for frame pointer 200b78f2e9SArd Biesheuvel * unwinding, and implements the unwinder annotations needed by the EABI 210b78f2e9SArd Biesheuvel * unwinder. 222d81f1feSWill Deacon */ 232d81f1feSWill Deacon 240b78f2e9SArd BiesheuvelENTRY(call_with_stack) 250b78f2e9SArd Biesheuvel#if defined(CONFIG_UNWINDER_FRAME_POINTER) && defined(CONFIG_CC_IS_GCC) 260b78f2e9SArd Biesheuvel mov ip, sp 270b78f2e9SArd Biesheuvel push {fp, ip, lr, pc} 280b78f2e9SArd Biesheuvel sub fp, ip, #4 290b78f2e9SArd Biesheuvel#else 300b78f2e9SArd BiesheuvelUNWIND( .fnstart ) 310b78f2e9SArd BiesheuvelUNWIND( .save {fpreg, lr} ) 320b78f2e9SArd Biesheuvel push {fpreg, lr} 330b78f2e9SArd BiesheuvelUNWIND( .setfp fpreg, sp ) 340b78f2e9SArd Biesheuvel mov fpreg, sp 350b78f2e9SArd Biesheuvel#endif 362d81f1feSWill Deacon mov sp, r2 372d81f1feSWill Deacon mov r2, r0 382d81f1feSWill Deacon mov r0, r1 392d81f1feSWill Deacon 400b78f2e9SArd Biesheuvel bl_r r2 412d81f1feSWill Deacon 420b78f2e9SArd Biesheuvel#if defined(CONFIG_UNWINDER_FRAME_POINTER) && defined(CONFIG_CC_IS_GCC) 430b78f2e9SArd Biesheuvel ldmdb fp, {fp, sp, pc} 440b78f2e9SArd Biesheuvel#else 450b78f2e9SArd Biesheuvel mov sp, fpreg 460b78f2e9SArd Biesheuvel pop {fpreg, pc} 470b78f2e9SArd BiesheuvelUNWIND( .fnend ) 480b78f2e9SArd Biesheuvel#endif 49*5854e4d8SLi Huafei .globl call_with_stack_end 50*5854e4d8SLi Huafeicall_with_stack_end: 512d81f1feSWill DeaconENDPROC(call_with_stack) 52