mirror of https://github.com/Qortal/Brooklyn
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
51 lines
1.1 KiB
51 lines
1.1 KiB
/* 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 |
|
#else |
|
UNWIND( .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_end |
|
call_with_stack_end: |
|
ENDPROC(call_with_stack)
|
|
|