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