]> git.proxmox.com Git - mirror_edk2.git/blob - MdePkg/Library/BaseLib/AArch64/SetJumpLongJump.S
MdePkg: Replace BSD License with BSD+Patent License
[mirror_edk2.git] / MdePkg / Library / BaseLib / AArch64 / SetJumpLongJump.S
1 #------------------------------------------------------------------------------
2 #
3 # Copyright (c) 2009-2013, ARM Ltd. All rights reserved.
4 # SPDX-License-Identifier: BSD-2-Clause-Patent
5 #
6 #------------------------------------------------------------------------------
7 .text
8 .p2align 3
9
10 GCC_ASM_EXPORT(SetJump)
11 GCC_ASM_EXPORT(InternalLongJump)
12
13 #define GPR_LAYOUT \
14 REG_PAIR (x19, x20, 0); \
15 REG_PAIR (x21, x22, 16); \
16 REG_PAIR (x23, x24, 32); \
17 REG_PAIR (x25, x26, 48); \
18 REG_PAIR (x27, x28, 64); \
19 REG_PAIR (x29, x30, 80);/*FP, LR*/ \
20 REG_ONE (x16, 96) /*IP0*/
21
22 #define FPR_LAYOUT \
23 REG_PAIR ( d8, d9, 112); \
24 REG_PAIR (d10, d11, 128); \
25 REG_PAIR (d12, d13, 144); \
26 REG_PAIR (d14, d15, 160);
27
28 #/**
29 # Saves the current CPU context that can be restored with a call to LongJump() and returns 0.#
30 #
31 # Saves the current CPU context in the buffer specified by JumpBuffer and returns 0. The initial
32 # call to SetJump() must always return 0. Subsequent calls to LongJump() cause a non-zero
33 # value to be returned by SetJump().
34 #
35 # If JumpBuffer is NULL, then ASSERT().
36 # For IPF CPUs, if JumpBuffer is not aligned on a 16-byte boundary, then ASSERT().
37 #
38 # @param JumpBuffer A pointer to CPU context buffer.
39 #
40 #**/
41 #
42 #UINTN
43 #EFIAPI
44 #SetJump (
45 # IN BASE_LIBRARY_JUMP_BUFFER *JumpBuffer // X0
46 # );
47 #
48 ASM_PFX(SetJump):
49 mov x16, sp // use IP0 so save SP
50 #define REG_PAIR(REG1, REG2, OFFS) stp REG1, REG2, [x0, OFFS]
51 #define REG_ONE(REG1, OFFS) str REG1, [x0, OFFS]
52 GPR_LAYOUT
53 FPR_LAYOUT
54 #undef REG_PAIR
55 #undef REG_ONE
56 mov w0, #0
57 ret
58
59 #/**
60 # Restores the CPU context that was saved with SetJump().#
61 #
62 # Restores the CPU context from the buffer specified by JumpBuffer.
63 # This function never returns to the caller.
64 # Instead is resumes execution based on the state of JumpBuffer.
65 #
66 # @param JumpBuffer A pointer to CPU context buffer.
67 # @param Value The value to return when the SetJump() context is restored.
68 #
69 #**/
70 #VOID
71 #EFIAPI
72 #InternalLongJump (
73 # IN BASE_LIBRARY_JUMP_BUFFER *JumpBuffer, // X0
74 # IN UINTN Value // X1
75 # );
76 #
77 ASM_PFX(InternalLongJump):
78 #define REG_PAIR(REG1, REG2, OFFS) ldp REG1, REG2, [x0, OFFS]
79 #define REG_ONE(REG1, OFFS) ldr REG1, [x0, OFFS]
80 GPR_LAYOUT
81 FPR_LAYOUT
82 #undef REG_PAIR
83 #undef REG_ONE
84 mov sp, x16
85 cmp w1, #0
86 mov w0, #1
87 csel w0, w1, w0, ne
88 // use br not ret, as ret is guaranteed to mispredict
89 br x30
90
91 ASM_FUNCTION_REMOVE_IF_UNREFERENCED