From 807e2604ab2d1d52640253d13b7ec0191fb4b431 Mon Sep 17 00:00:00 2001 From: Harry Liebel Date: Mon, 29 Jul 2013 09:55:38 +0000 Subject: [PATCH] MdePkg/BaseLib: Added ARM Aarch64 architecture support Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Harry Liebel Signed-off-by: Olivier Martin Reviewed-by: Liming Gao git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@14515 6f19259b-4bc3-4df7-8a09-765794883524 --- MdePkg/Include/Library/BaseLib.h | 33 +++++++ .../Library/BaseLib/AArch64/CpuBreakpoint.S | 37 +++++++ .../BaseLib/AArch64/DisableInterrupts.S | 34 +++++++ .../BaseLib/AArch64/EnableInterrupts.S | 35 +++++++ .../BaseLib/AArch64/GetInterruptsState.S | 45 +++++++++ .../Library/BaseLib/AArch64/SetJumpLongJump.S | 97 +++++++++++++++++++ MdePkg/Library/BaseLib/AArch64/SwitchStack.S | 68 +++++++++++++ MdePkg/Library/BaseLib/BaseLib.inf | 15 ++- 8 files changed, 363 insertions(+), 1 deletion(-) create mode 100644 MdePkg/Library/BaseLib/AArch64/CpuBreakpoint.S create mode 100644 MdePkg/Library/BaseLib/AArch64/DisableInterrupts.S create mode 100644 MdePkg/Library/BaseLib/AArch64/EnableInterrupts.S create mode 100644 MdePkg/Library/BaseLib/AArch64/GetInterruptsState.S create mode 100644 MdePkg/Library/BaseLib/AArch64/SetJumpLongJump.S create mode 100644 MdePkg/Library/BaseLib/AArch64/SwitchStack.S diff --git a/MdePkg/Include/Library/BaseLib.h b/MdePkg/Include/Library/BaseLib.h index db07596399..cba5ab6b15 100644 --- a/MdePkg/Include/Library/BaseLib.h +++ b/MdePkg/Include/Library/BaseLib.h @@ -146,6 +146,39 @@ typedef struct { #endif // defined (MDE_CPU_ARM) +#if defined (MDE_CPU_AARCH64) +typedef struct { + // GP regs + UINT64 X19; + UINT64 X20; + UINT64 X21; + UINT64 X22; + UINT64 X23; + UINT64 X24; + UINT64 X25; + UINT64 X26; + UINT64 X27; + UINT64 X28; + UINT64 FP; + UINT64 LR; + UINT64 IP0; + + // FP regs + UINT64 D8; + UINT64 D9; + UINT64 D10; + UINT64 D11; + UINT64 D12; + UINT64 D13; + UINT64 D14; + UINT64 D15; +} BASE_LIBRARY_JUMP_BUFFER; + +#define BASE_LIBRARY_JUMP_BUFFER_ALIGNMENT 8 + +#endif // defined (MDE_CPU_AARCH64) + + // // String Services // diff --git a/MdePkg/Library/BaseLib/AArch64/CpuBreakpoint.S b/MdePkg/Library/BaseLib/AArch64/CpuBreakpoint.S new file mode 100644 index 0000000000..fe8c571720 --- /dev/null +++ b/MdePkg/Library/BaseLib/AArch64/CpuBreakpoint.S @@ -0,0 +1,37 @@ +#------------------------------------------------------------------------------ +# +# CpuBreakpoint() for AArch64 +# +# Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.
+# Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.
+# Portions copyright (c) 2011 - 2013, ARM Ltd. All rights reserved.
+# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php. +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +#------------------------------------------------------------------------------ + +.text +.p2align 2 +ASM_GLOBAL ASM_PFX(CpuBreakpoint) + +#/** +# Generates a breakpoint on the CPU. +# +# Generates a breakpoint on the CPU. The breakpoint must be implemented such +# that code can resume normal execution after the breakpoint. +# +#**/ +#VOID +#EFIAPI +#CpuBreakpoint ( +# VOID +# ); +# +ASM_PFX(CpuBreakpoint): + svc 0xdbdb // Superviser exception. Takes 16bit arg -> Armv7 had 'swi' here. + ret diff --git a/MdePkg/Library/BaseLib/AArch64/DisableInterrupts.S b/MdePkg/Library/BaseLib/AArch64/DisableInterrupts.S new file mode 100644 index 0000000000..b80a7b41d7 --- /dev/null +++ b/MdePkg/Library/BaseLib/AArch64/DisableInterrupts.S @@ -0,0 +1,34 @@ +#------------------------------------------------------------------------------ +# +# DisableInterrupts() for AArch64 +# +# Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.
+# Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.
+# Portions copyright (c) 2011 - 2013, ARM Ltd. All rights reserved.
+# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php. +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +#------------------------------------------------------------------------------ + +.text +.p2align 2 +ASM_GLOBAL ASM_PFX(DisableInterrupts) + +#/** +# Disables CPU interrupts. +# +#**/ +#VOID +#EFIAPI +#DisableInterrupts ( +# VOID +# ); +# +ASM_PFX(DisableInterrupts): + msr daifset, #2 + ret diff --git a/MdePkg/Library/BaseLib/AArch64/EnableInterrupts.S b/MdePkg/Library/BaseLib/AArch64/EnableInterrupts.S new file mode 100644 index 0000000000..289739cda6 --- /dev/null +++ b/MdePkg/Library/BaseLib/AArch64/EnableInterrupts.S @@ -0,0 +1,35 @@ +#------------------------------------------------------------------------------ +# +# EnableInterrupts() for AArch64 +# +# Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.
+# Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.
+# Portions copyright (c) 2011 - 2013, ARM Ltd. All rights reserved.
+# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php. +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +#------------------------------------------------------------------------------ + +.text +.p2align 2 +ASM_GLOBAL ASM_PFX(EnableInterrupts) + + +#/** +# Enables CPU interrupts. +# +#**/ +#VOID +#EFIAPI +#EnableInterrupts ( +# VOID +# ); +# +ASM_PFX(EnableInterrupts): + msr daifclr, #2 + ret diff --git a/MdePkg/Library/BaseLib/AArch64/GetInterruptsState.S b/MdePkg/Library/BaseLib/AArch64/GetInterruptsState.S new file mode 100644 index 0000000000..5a971f5612 --- /dev/null +++ b/MdePkg/Library/BaseLib/AArch64/GetInterruptsState.S @@ -0,0 +1,45 @@ +#------------------------------------------------------------------------------ +# +# GetInterruptState() function for AArch64 +# +# Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.
+# Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.
+# Portions copyright (c) 2011 - 2013, ARM Ltd. All rights reserved.
+# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php. +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +#------------------------------------------------------------------------------ + +.text +.p2align 2 +ASM_GLOBAL ASM_PFX(GetInterruptState) + +#/** +# Retrieves the current CPU interrupt state. +# +# Returns TRUE is interrupts are currently enabled. Otherwise +# returns FALSE. +# +# @retval TRUE CPU interrupts are enabled. +# @retval FALSE CPU interrupts are disabled. +# +#**/ +# +#BOOLEAN +#EFIAPI +#GetInterruptState ( +# VOID +# ); +# +ASM_PFX(GetInterruptState): + mrs x0, daif + tst x0, #2 // Check if IRQ is enabled. Enabled if 0. + mov w0, #0 + mov w1, #1 + csel w0, w1, w0, ne + ret diff --git a/MdePkg/Library/BaseLib/AArch64/SetJumpLongJump.S b/MdePkg/Library/BaseLib/AArch64/SetJumpLongJump.S new file mode 100644 index 0000000000..dbc5adbcac --- /dev/null +++ b/MdePkg/Library/BaseLib/AArch64/SetJumpLongJump.S @@ -0,0 +1,97 @@ +#------------------------------------------------------------------------------ +# +# Copyright (c) 2009-2013, ARM Ltd. All rights reserved. +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php. +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +#------------------------------------------------------------------------------ +.text +.p2align 3 + +ASM_GLOBAL ASM_PFX(SetJump) +ASM_GLOBAL ASM_PFX(InternalLongJump) + +#define GPR_LAYOUT \ + REG_PAIR (x19, x20, 0); \ + REG_PAIR (x21, x22, 16); \ + REG_PAIR (x23, x24, 32); \ + REG_PAIR (x25, x26, 48); \ + REG_PAIR (x27, x28, 64); \ + REG_PAIR (x29, x30, 80);/*FP, LR*/ \ + REG_ONE (x16, 96) /*IP0*/ + +#define FPR_LAYOUT \ + REG_PAIR ( d8, d9, 112); \ + REG_PAIR (d10, d11, 128); \ + REG_PAIR (d12, d13, 144); \ + REG_PAIR (d14, d15, 160); + +#/** +# Saves the current CPU context that can be restored with a call to LongJump() and returns 0.# +# +# Saves the current CPU context in the buffer specified by JumpBuffer and returns 0. The initial +# call to SetJump() must always return 0. Subsequent calls to LongJump() cause a non-zero +# value to be returned by SetJump(). +# +# If JumpBuffer is NULL, then ASSERT(). +# For IPF CPUs, if JumpBuffer is not aligned on a 16-byte boundary, then ASSERT(). +# +# @param JumpBuffer A pointer to CPU context buffer. +# +#**/ +# +#UINTN +#EFIAPI +#SetJump ( +# IN BASE_LIBRARY_JUMP_BUFFER *JumpBuffer // X0 +# ); +# +ASM_PFX(SetJump): + mov x16, sp // use IP0 so save SP +#define REG_PAIR(REG1, REG2, OFFS) stp REG1, REG2, [x0, OFFS] +#define REG_ONE(REG1, OFFS) str REG1, [x0, OFFS] + GPR_LAYOUT + FPR_LAYOUT +#undef REG_PAIR +#undef REG_ONE + mov w0, #0 + ret + +#/** +# Restores the CPU context that was saved with SetJump().# +# +# Restores the CPU context from the buffer specified by JumpBuffer. +# This function never returns to the caller. +# Instead is resumes execution based on the state of JumpBuffer. +# +# @param JumpBuffer A pointer to CPU context buffer. +# @param Value The value to return when the SetJump() context is restored. +# +#**/ +#VOID +#EFIAPI +#InternalLongJump ( +# IN BASE_LIBRARY_JUMP_BUFFER *JumpBuffer, // X0 +# IN UINTN Value // X1 +# ); +# +ASM_PFX(InternalLongJump): +#define REG_PAIR(REG1, REG2, OFFS) ldp REG1, REG2, [x0, OFFS] +#define REG_ONE(REG1, OFFS) ldr REG1, [x0, OFFS] + GPR_LAYOUT + FPR_LAYOUT +#undef REG_PAIR +#undef REG_ONE + mov sp, x16 + cmp w1, #0 + mov w0, #1 + csel w0, w1, w0, ne + // use br not ret, as ret is guaranteed to mispredict + br x30 + +ASM_FUNCTION_REMOVE_IF_UNREFERENCED diff --git a/MdePkg/Library/BaseLib/AArch64/SwitchStack.S b/MdePkg/Library/BaseLib/AArch64/SwitchStack.S new file mode 100644 index 0000000000..207a569b1b --- /dev/null +++ b/MdePkg/Library/BaseLib/AArch64/SwitchStack.S @@ -0,0 +1,68 @@ +//------------------------------------------------------------------------------ +// +// Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.
+// Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.
+// Portions copyright (c) 2011 - 2013, ARM Limited. All rights reserved.
+// This program and the accompanying materials +// are licensed and made available under the terms and conditions of the BSD License +// which accompanies this distribution. The full text of the license may be found at +// http://opensource.org/licenses/bsd-license.php. +// +// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +// +//------------------------------------------------------------------------------ + +.text +.align 5 + +ASM_GLOBAL ASM_PFX(InternalSwitchStackAsm) +ASM_GLOBAL ASM_PFX(CpuPause) + +/** +// +// This allows the caller to switch the stack and goes to the new entry point +// +// @param EntryPoint The pointer to the location to enter +// @param Context Parameter to pass in +// @param Context2 Parameter2 to pass in +// @param NewStack New Location of the stack +// +// @return Nothing. Goes to the Entry Point passing in the new parameters +// +VOID +EFIAPI +InternalSwitchStackAsm ( + SWITCH_STACK_ENTRY_POINT EntryPoint, + VOID *Context, + VOID *Context2, + VOID *NewStack + ); +**/ +ASM_PFX(InternalSwitchStackAsm): + mov x30, x0 + mov sp, x3 + mov x0, x1 + mov x1, x2 + ret + +/** +// +// Requests CPU to pause for a short period of time. +// +// Requests CPU to pause for a short period of time. Typically used in MP +// systems to prevent memory starvation while waiting for a spin lock. +// +VOID +EFIAPI +CpuPause ( + VOID + ) +**/ +ASM_PFX(CpuPause): + nop + nop + nop + nop + nop + ret diff --git a/MdePkg/Library/BaseLib/BaseLib.inf b/MdePkg/Library/BaseLib/BaseLib.inf index f54c3bc32b..3e47b55d19 100644 --- a/MdePkg/Library/BaseLib/BaseLib.inf +++ b/MdePkg/Library/BaseLib/BaseLib.inf @@ -3,6 +3,7 @@ # # Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.
# Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.
+# Portions copyright (c) 2011 - 2013, ARM Ltd. All rights reserved.
# # This program and the accompanying materials # are licensed and made available under the terms and conditions of the BSD License @@ -23,7 +24,7 @@ LIBRARY_CLASS = BaseLib # -# VALID_ARCHITECTURES = IA32 X64 IPF EBC ARM +# VALID_ARCHITECTURES = IA32 X64 IPF EBC ARM AARCH64 # [Sources] @@ -476,6 +477,18 @@ Arm/SetJumpLongJump.S | GCC Arm/CpuBreakpoint.S | GCC +[Sources.AARCH64] + Arm/InternalSwitchStack.c + Arm/Unaligned.c + Math64.c + + AArch64/SwitchStack.S | GCC + AArch64/EnableInterrupts.S | GCC + AArch64/DisableInterrupts.S | GCC + AArch64/GetInterruptsState.S | GCC + AArch64/SetJumpLongJump.S | GCC + AArch64/CpuBreakpoint.S | GCC + [Packages] MdePkg/MdePkg.dec -- 2.39.2