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