From 1bc8326695a2181cb5934c3dfb01b0a26c4096a0 Mon Sep 17 00:00:00 2001 From: Harry Liebel Date: Thu, 18 Jul 2013 19:06:52 +0000 Subject: ArmPlatformPkg: Added Aarch64 support Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Harry Liebel Signed-off-by: Olivier Martin git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@14489 6f19259b-4bc3-4df7-8a09-765794883524 --- ArmPlatformPkg/PrePeiCore/AArch64/ArchPrePeiCore.c | 52 ++++++++++ ArmPlatformPkg/PrePeiCore/AArch64/Exception.S | 84 +++++++++++++++ ArmPlatformPkg/PrePeiCore/AArch64/Helper.S | 51 +++++++++ .../PrePeiCore/AArch64/PrePeiCoreEntryPoint.S | 114 +++++++++++++++++++++ ArmPlatformPkg/PrePeiCore/AArch64/SwitchStack.S | 43 ++++++++ ArmPlatformPkg/PrePeiCore/PrePeiCore.c | 3 +- ArmPlatformPkg/PrePeiCore/PrePeiCoreMPCore.inf | 7 ++ ArmPlatformPkg/PrePeiCore/PrePeiCoreUniCore.inf | 9 +- 8 files changed, 361 insertions(+), 2 deletions(-) create mode 100644 ArmPlatformPkg/PrePeiCore/AArch64/ArchPrePeiCore.c create mode 100644 ArmPlatformPkg/PrePeiCore/AArch64/Exception.S create mode 100644 ArmPlatformPkg/PrePeiCore/AArch64/Helper.S create mode 100644 ArmPlatformPkg/PrePeiCore/AArch64/PrePeiCoreEntryPoint.S create mode 100644 ArmPlatformPkg/PrePeiCore/AArch64/SwitchStack.S (limited to 'ArmPlatformPkg/PrePeiCore') diff --git a/ArmPlatformPkg/PrePeiCore/AArch64/ArchPrePeiCore.c b/ArmPlatformPkg/PrePeiCore/AArch64/ArchPrePeiCore.c new file mode 100644 index 000000000..e1842f2a0 --- /dev/null +++ b/ArmPlatformPkg/PrePeiCore/AArch64/ArchPrePeiCore.c @@ -0,0 +1,52 @@ +/** @file +* Main file supporting the transition to PEI Core in Normal World for Versatile Express +* +* Copyright (c) 2012-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. +* +**/ + +#include +#include + +#include "PrePeiCore.h" + +VOID +PeiCommonExceptionEntry ( + IN UINT32 Entry, + IN UINTN LR + ) +{ + CHAR8 Buffer[100]; + UINTN CharCount; + + switch (Entry) { + case EXCEPT_AARCH64_SYNCHRONOUS_EXCEPTIONS: + CharCount = AsciiSPrint (Buffer,sizeof (Buffer),"Synchronous Exception at 0x%X\n\r", LR); + break; + case EXCEPT_AARCH64_IRQ: + CharCount = AsciiSPrint (Buffer,sizeof (Buffer),"IRQ Exception at 0x%X\n\r", LR); + break; + case EXCEPT_AARCH64_FIQ: + CharCount = AsciiSPrint (Buffer,sizeof (Buffer),"FIQ Exception at 0x%X\n\r", LR); + break; + case EXCEPT_AARCH64_SERROR: + CharCount = AsciiSPrint (Buffer,sizeof (Buffer),"SError/Abort Exception at 0x%X\n\r", LR); + break; + default: + CharCount = AsciiSPrint (Buffer,sizeof (Buffer),"Unknown Exception at 0x%X\n\r", LR); + break; + } + + SerialPortWrite ((UINT8 *) Buffer, CharCount); + + while(1); +} + diff --git a/ArmPlatformPkg/PrePeiCore/AArch64/Exception.S b/ArmPlatformPkg/PrePeiCore/AArch64/Exception.S new file mode 100644 index 000000000..9ca422b2f --- /dev/null +++ b/ArmPlatformPkg/PrePeiCore/AArch64/Exception.S @@ -0,0 +1,84 @@ +# +# 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. +# +# + +#include +#include +#include + +.text +.align 11 + +ASM_GLOBAL ASM_PFX(PeiVectorTable) + +//============================================================ +//Default Exception Handlers +//============================================================ + +ASM_PFX(PeiVectorTable): + + +#define TO_HANDLER \ + EL1_OR_EL2(x1) \ +1: mrs x1, elr_el1 /* EL1 Exception Link Register */ ;\ + b 3f ;\ +2: mrs x1, elr_el2 /* EL2 Exception Link Register */ ;\ +3: bl ASM_PFX(PeiCommonExceptionEntry) ; + + +// +// Default Exception handlers: There is no plan to return from any of these exceptions. +// No context saving at all. +// + +.align 7 +_DefaultSyncExceptHandler_t: + mov x0, #EXCEPT_AARCH64_SYNCHRONOUS_EXCEPTIONS + TO_HANDLER + +.align 7 +_DefaultIrq_t: + mov x0, #EXCEPT_AARCH64_IRQ + TO_HANDLER + +.align 7 +_DefaultFiq_t: + mov x0, #EXCEPT_AARCH64_FIQ + TO_HANDLER + +.align 7 +_DefaultSError_t: + mov x0, #EXCEPT_AARCH64_SERROR + TO_HANDLER + +.align 7 +_DefaultSyncExceptHandler_h: + mov x0, #EXCEPT_AARCH64_SYNCHRONOUS_EXCEPTIONS + TO_HANDLER + +.align 7 +_DefaultIrq_h: + mov x0, #EXCEPT_AARCH64_IRQ + TO_HANDLER + +.align 7 +_DefaultFiq_h: + mov x0, #EXCEPT_AARCH64_FIQ + TO_HANDLER + +.align 7 +_DefaultSError_h: + mov x0, #EXCEPT_AARCH64_SERROR + TO_HANDLER + +dead: + b dead diff --git a/ArmPlatformPkg/PrePeiCore/AArch64/Helper.S b/ArmPlatformPkg/PrePeiCore/AArch64/Helper.S new file mode 100644 index 000000000..14e9cb8d8 --- /dev/null +++ b/ArmPlatformPkg/PrePeiCore/AArch64/Helper.S @@ -0,0 +1,51 @@ +#======================================================================================== +# 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. +# +#======================================================================================= + +#include +#include + +#start of the code section +.text +.align 3 + +ASM_GLOBAL ASM_PFX(SetupExceptionLevel1) +ASM_GLOBAL ASM_PFX(SetupExceptionLevel2) + +// Setup EL1 while in EL1 +ASM_PFX(SetupExceptionLevel1): + mov x5, x30 // Save LR + + mov x0, #CPACR_CP_FULL_ACCESS + bl ASM_PFX(ArmWriteCpacr) // Disable copro traps to EL1 + + ret x5 + +// Setup EL2 while in EL2 +ASM_PFX(SetupExceptionLevel2): + msr sctlr_el2, xzr + mrs x0, hcr_el2 // Read EL2 Hypervisor configuration Register + + // Send all interrupts to their respective Exception levels for EL2 + orr x0, x0, #(1 << 3) // Enable EL2 FIQ + orr x0, x0, #(1 << 4) // Enable EL2 IRQ + orr x0, x0, #(1 << 5) // Enable EL2 SError and Abort + msr hcr_el2, x0 // Write back our settings + + msr cptr_el2, xzr // Disable copro traps to EL2 + + ret + +dead: + b dead + +ASM_FUNCTION_REMOVE_IF_UNREFERENCED diff --git a/ArmPlatformPkg/PrePeiCore/AArch64/PrePeiCoreEntryPoint.S b/ArmPlatformPkg/PrePeiCore/AArch64/PrePeiCoreEntryPoint.S new file mode 100644 index 000000000..5bdbe4585 --- /dev/null +++ b/ArmPlatformPkg/PrePeiCore/AArch64/PrePeiCoreEntryPoint.S @@ -0,0 +1,114 @@ +// +// 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. +// +// + +#include +#include +#include +#include + +.text +.align 3 + +GCC_ASM_IMPORT(CEntryPoint) +GCC_ASM_IMPORT(ArmPlatformGetCorePosition) +GCC_ASM_IMPORT(ArmPlatformIsPrimaryCore) +GCC_ASM_IMPORT(ArmReadMpidr) +GCC_ASM_IMPORT(ArmPlatformPeiBootAction) +GCC_ASM_EXPORT(_ModuleEntryPoint) + +StartupAddr: .dword CEntryPoint + +ASM_PFX(_ModuleEntryPoint): + // Do early platform specific actions + bl ASM_PFX(ArmPlatformPeiBootAction) + +// NOTE: We could be booting from EL3, EL2 or EL1. Need to correctly detect +// and configure the system accordingly. EL2 is default if possible. +// If we started in EL3 we need to switch and run at EL2. +// If we are running at EL2 stay in EL2 +// If we are starting at EL1 stay in EL1. + +// If started at EL3 Sec is run and switches to EL2 before jumping to PEI. +// If started at EL1 or EL2 Sec jumps directly to PEI without making any +// changes. + +// Which EL are we running at? Every EL needs some level of setup... + EL1_OR_EL2_OR_EL3(x0) +1:bl ASM_PFX(SetupExceptionLevel1) + b ASM_PFX(MainEntryPoint) +2:bl ASM_PFX(SetupExceptionLevel2) + b ASM_PFX(MainEntryPoint) +3:// If we are at EL3 we die. + b dead + +ASM_PFX(MainEntryPoint): + // Identify CPU ID + bl ASM_PFX(ArmReadMpidr) + // Keep a copy of the MpId register value + mov x5, x0 + + // Is it the Primary Core ? + bl ASM_PFX(ArmPlatformIsPrimaryCore) + + // Get the top of the primary stacks (and the base of the secondary stacks) + LoadConstantToReg (FixedPcdGet32(PcdCPUCoresStackBase), x1) + LoadConstantToReg (FixedPcdGet32(PcdCPUCorePrimaryStackSize), x2) + add x1, x1, x2 + + // x0 is equal to 1 if I am the primary core + cmp x0, #1 + b.eq _SetupPrimaryCoreStack + +_SetupSecondaryCoreStack: + // x1 contains the base of the secondary stacks + + // Get the Core Position + mov x6, x1 // Save base of the secondary stacks + mov x0, x5 + bl ASM_PFX(ArmPlatformGetCorePosition) + // The stack starts at the top of the stack region. Add '1' to the Core Position to get the top of the stack + add x0, x0, #1 + + // StackOffset = CorePos * StackSize + LoadConstantToReg (FixedPcdGet32(PcdCPUCoreSecondaryStackSize), x2) + mul x0, x0, x2 + // SP = StackBase + StackOffset + add sp, x6, x0 + +_PrepareArguments: + // The PEI Core Entry Point has been computed by GenFV and stored in the second entry of the Reset Vector + LoadConstantToReg (FixedPcdGet64(PcdFvBaseAddress), x2) + add x2, x2, #8 + ldr x1, [x2] + + // Move sec startup address into a data register + // Ensure we're jumping to FV version of the code (not boot remapped alias) + ldr x3, StartupAddr + + // Jump to PrePeiCore C code + // x0 = mp_id + // x1 = pei_core_address + mov x0, x5 + blr x3 + +_SetupPrimaryCoreStack: + // x1 contains the top of the primary stack + LoadConstantToReg (FixedPcdGet32(PcdPeiGlobalVariableSize), x2) + + // The reserved space for global variable must be 16-bytes aligned for pushing + // 128-bit variable on the stack + SetPrimaryStack (x1, x2, x3, x4) + b _PrepareArguments + +dead: + b dead diff --git a/ArmPlatformPkg/PrePeiCore/AArch64/SwitchStack.S b/ArmPlatformPkg/PrePeiCore/AArch64/SwitchStack.S new file mode 100644 index 000000000..d3fcd0aa1 --- /dev/null +++ b/ArmPlatformPkg/PrePeiCore/AArch64/SwitchStack.S @@ -0,0 +1,43 @@ +#------------------------------------------------------------------------------ +# +# 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 +.align 3 + +ASM_GLOBAL ASM_PFX(SecSwitchStack) + + + +#/** +# This allows the caller to switch the stack and return +# +# @param StackDelta Signed amount by which to modify the stack pointer +# +# @return Nothing. Goes to the Entry Point passing in the new parameters +# +#**/ +#VOID +#EFIAPI +#SecSwitchStack ( +# VOID *StackDelta +# )# +# +ASM_PFX(SecSwitchStack): + mov x1, sp + add x1, x0, x1 + mov sp, x1 + ret + diff --git a/ArmPlatformPkg/PrePeiCore/PrePeiCore.c b/ArmPlatformPkg/PrePeiCore/PrePeiCore.c index ececd4c76..e165fd945 100644 --- a/ArmPlatformPkg/PrePeiCore/PrePeiCore.c +++ b/ArmPlatformPkg/PrePeiCore/PrePeiCore.c @@ -87,7 +87,8 @@ CEntryPoint ( // // Write VBAR - The Exception Vector table must be aligned to its requirement - ASSERT (((UINTN)PeiVectorTable & ARM_VECTOR_TABLE_ALIGNMENT) == 0); + //TODO: Fix baseTools to ensure the Exception Vector Table is correctly aligned in AArch64 + //ASSERT(((UINTN)PeiVectorTable & ARM_VECTOR_TABLE_ALIGNMENT) == 0); ArmWriteVBar ((UINTN)PeiVectorTable); //Note: The MMU will be enabled by MemoryPeim. Only the primary core will have the MMU on. diff --git a/ArmPlatformPkg/PrePeiCore/PrePeiCoreMPCore.inf b/ArmPlatformPkg/PrePeiCore/PrePeiCoreMPCore.inf index 351ac6780..d90481e75 100644 --- a/ArmPlatformPkg/PrePeiCore/PrePeiCoreMPCore.inf +++ b/ArmPlatformPkg/PrePeiCore/PrePeiCoreMPCore.inf @@ -33,6 +33,13 @@ Arm/Exception.asm | RVCT Arm/Exception.S | GCC +[Sources.AARCH64] + AArch64/ArchPrePeiCore.c + AArch64/PrePeiCoreEntryPoint.S | GCC + AArch64/SwitchStack.S | GCC + AArch64/Exception.S | GCC + AArch64/Helper.S | GCC + [Packages] MdePkg/MdePkg.dec MdeModulePkg/MdeModulePkg.dec diff --git a/ArmPlatformPkg/PrePeiCore/PrePeiCoreUniCore.inf b/ArmPlatformPkg/PrePeiCore/PrePeiCoreUniCore.inf index 13f86902b..94b7a6cf0 100644 --- a/ArmPlatformPkg/PrePeiCore/PrePeiCoreUniCore.inf +++ b/ArmPlatformPkg/PrePeiCore/PrePeiCoreUniCore.inf @@ -32,7 +32,14 @@ Arm/SwitchStack.S | GCC Arm/Exception.asm | RVCT Arm/Exception.S | GCC - + +[Sources.AARCH64] + AArch64/ArchPrePeiCore.c + AArch64/PrePeiCoreEntryPoint.S | GCC + AArch64/SwitchStack.S | GCC + AArch64/Exception.S | GCC + AArch64/Helper.S | GCC + [Packages] MdePkg/MdePkg.dec MdeModulePkg/MdeModulePkg.dec -- cgit v1.2.3