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 16GCC_ASM_EXPORT(SetJump) 17GCC_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# 54ASM_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# 83ASM_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 97ASM_FUNCTION_REMOVE_IF_UNREFERENCED 98