1 #------------------------------------------------------------------------------ 2 # 3 # Copyright (c) 2009-2013, ARM Ltd. All rights reserved. 4 # This program and the accompanying materials 5 # are licensed and made available under the terms and conditions of the BSD License 6 # which accompanies this distribution. The full text of the license may be found at 7 # http://opensource.org/licenses/bsd-license.php. 8 # 9 # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 10 # WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 11 # 12 #------------------------------------------------------------------------------ 13 .text 14 .p2align 3 15 16 GCC_ASM_EXPORT(SetJump) 17 GCC_ASM_EXPORT(InternalLongJump) 18 19 #define GPR_LAYOUT \ 20 REG_PAIR (x19, x20, 0); \ 21 REG_PAIR (x21, x22, 16); \ 22 REG_PAIR (x23, x24, 32); \ 23 REG_PAIR (x25, x26, 48); \ 24 REG_PAIR (x27, x28, 64); \ 25 REG_PAIR (x29, x30, 80);/*FP, LR*/ \ 26 REG_ONE (x16, 96) /*IP0*/ 27 28 #define FPR_LAYOUT \ 29 REG_PAIR ( d8, d9, 112); \ 30 REG_PAIR (d10, d11, 128); \ 31 REG_PAIR (d12, d13, 144); \ 32 REG_PAIR (d14, d15, 160); 33 34 #/** 35 # Saves the current CPU context that can be restored with a call to LongJump() and returns 0.# 36 # 37 # Saves the current CPU context in the buffer specified by JumpBuffer and returns 0. The initial 38 # call to SetJump() must always return 0. Subsequent calls to LongJump() cause a non-zero 39 # value to be returned by SetJump(). 40 # 41 # If JumpBuffer is NULL, then ASSERT(). 42 # For IPF CPUs, if JumpBuffer is not aligned on a 16-byte boundary, then ASSERT(). 43 # 44 # @param JumpBuffer A pointer to CPU context buffer. 45 # 46 #**/ 47 # 48 #UINTN 49 #EFIAPI 50 #SetJump ( 51 # IN BASE_LIBRARY_JUMP_BUFFER *JumpBuffer // X0 52 # ); 53 # 54 ASM_PFX(SetJump): 55 mov x16, sp // use IP0 so save SP 56 #define REG_PAIR(REG1, REG2, OFFS) stp REG1, REG2, [x0, OFFS] 57 #define REG_ONE(REG1, OFFS) str REG1, [x0, OFFS] 58 GPR_LAYOUT 59 FPR_LAYOUT 60 #undef REG_PAIR 61 #undef REG_ONE 62 mov w0, #0 63 ret 64 65 #/** 66 # Restores the CPU context that was saved with SetJump().# 67 # 68 # Restores the CPU context from the buffer specified by JumpBuffer. 69 # This function never returns to the caller. 70 # Instead is resumes execution based on the state of JumpBuffer. 71 # 72 # @param JumpBuffer A pointer to CPU context buffer. 73 # @param Value The value to return when the SetJump() context is restored. 74 # 75 #**/ 76 #VOID 77 #EFIAPI 78 #InternalLongJump ( 79 # IN BASE_LIBRARY_JUMP_BUFFER *JumpBuffer, // X0 80 # IN UINTN Value // X1 81 # ); 82 # 83 ASM_PFX(InternalLongJump): 84 #define REG_PAIR(REG1, REG2, OFFS) ldp REG1, REG2, [x0, OFFS] 85 #define REG_ONE(REG1, OFFS) ldr REG1, [x0, OFFS] 86 GPR_LAYOUT 87 FPR_LAYOUT 88 #undef REG_PAIR 89 #undef REG_ONE 90 mov sp, x16 91 cmp w1, #0 92 mov w0, #1 93 csel w0, w1, w0, ne 94 // use br not ret, as ret is guaranteed to mispredict 95 br x30 96 97 ASM_FUNCTION_REMOVE_IF_UNREFERENCED 98