Something went wrong. Try again.
Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
Something went wrong. Try again.
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152/* SPDX-License-Identifier: GPL-2.0-only *//* * arch/arm/lib/call_with_stack.S * * Copyright (C) 2011 ARM Ltd. * Written by Will Deacon <will.deacon@arm.com> */
#include <linux/linkage.h>#include <asm/assembler.h>#include <asm/unwind.h>
/* * void call_with_stack(void (*fn)(void *), void *arg, void *sp) * * Change the stack to that pointed at by sp, then invoke fn(arg) with * the new stack. * * The sequence below follows the APCS frame convention for frame pointer * unwinding, and implements the unwinder annotations needed by the EABI * unwinder. */
ENTRY(call_with_stack)#if defined(CONFIG_UNWINDER_FRAME_POINTER) && defined(CONFIG_CC_IS_GCC) mov ip, sp push {fp, ip, lr, pc} sub fp, ip, #4#elseUNWIND( .fnstart )UNWIND( .save {fpreg, lr} ) push {fpreg, lr}UNWIND( .setfp fpreg, sp ) mov fpreg, sp#endif mov sp, r2 mov r2, r0 mov r0, r1
bl_r r2
#if defined(CONFIG_UNWINDER_FRAME_POINTER) && defined(CONFIG_CC_IS_GCC) ldmdb fp, {fp, sp, pc}#else mov sp, fpreg pop {fpreg, pc}UNWIND( .fnend )#endif .globl call_with_stack_endcall_with_stack_end:ENDPROC(call_with_stack)