diff --git a/ArmPlatformPkg/ArmPlatformPkg-2ndstage.dsc b/ArmPlatformPkg/ArmPlatformPkg-2ndstage.dsc index 126fb3648e..b8b439555b 100644 --- a/ArmPlatformPkg/ArmPlatformPkg-2ndstage.dsc +++ b/ArmPlatformPkg/ArmPlatformPkg-2ndstage.dsc @@ -21,14 +21,12 @@ PLATFORM_VERSION = 0.1 DSC_SPECIFICATION = 0x00010005 OUTPUT_DIRECTORY = Build/$(PLATFORM_NAME) - SUPPORTED_ARCHITECTURES = ARM + SUPPORTED_ARCHITECTURES = ARM|AARCH64 BUILD_TARGETS = DEBUG|RELEASE SKUID_IDENTIFIER = DEFAULT FLASH_DEFINITION = ArmPlatformPkg/ArmPlatformPkg-2ndstage.fdf [LibraryClasses.common] - ArmLib|ArmPkg/Library/ArmLib/ArmV7/ArmV7Lib.inf - ArmCpuLib|ArmPkg/Drivers/ArmCpuLib/ArmCortexA9Lib/ArmCortexA9Lib.inf ArmPlatformLib|ArmPlatformPkg/Library/ArmPlatformLibNull/ArmPlatformLibNull.inf !if $(TARGET) == RELEASE @@ -113,6 +111,14 @@ BdsLib|ArmPkg/Library/BdsLib/BdsLib.inf FdtLib|EmbeddedPkg/Library/FdtLib/FdtLib.inf +[LibraryClasses.ARM] + ArmLib|ArmPkg/Library/ArmLib/ArmV7/ArmV7Lib.inf + ArmCpuLib|ArmPkg/Drivers/ArmCpuLib/ArmCortexA9Lib/ArmCortexA9Lib.inf + +[LibraryClasses.AARCH64] + ArmLib|ArmPkg/Library/ArmLib/AArch64/AArch64Lib.inf + ArmCpuLib|ArmPkg/Drivers/ArmCpuLib/ArmCortexAEMv8Lib/ArmCortexAEMv8Lib.inf + [LibraryClasses.common.SEC] ArmPlatformGlobalVariableLib|ArmPlatformPkg/Library/ArmPlatformGlobalVariableLib/PrePi/PrePiArmPlatformGlobalVariableLib.inf diff --git a/ArmPlatformPkg/ArmPlatformPkg.dec b/ArmPlatformPkg/ArmPlatformPkg.dec index 3e2900ba31..3358225aee 100644 --- a/ArmPlatformPkg/ArmPlatformPkg.dec +++ b/ArmPlatformPkg/ArmPlatformPkg.dec @@ -1,6 +1,6 @@ #/** @file # -# Copyright (c) 2011-2012, ARM Limited. All rights reserved. +# 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 @@ -63,10 +63,6 @@ gArmPlatformTokenSpaceGuid.PcdCPUCoreSecPrimaryStackSize|0x10000|UINT32|0x00000036 gArmPlatformTokenSpaceGuid.PcdCPUCoreSecSecondaryStackSize|0x1000|UINT32|0x00000006 - # Stack for CPU Cores in Secure Monitor Mode - gArmPlatformTokenSpaceGuid.PcdCPUCoresSecMonStackBase|0|UINT32|0x00000007 - gArmPlatformTokenSpaceGuid.PcdCPUCoreSecMonStackSize|0x1000|UINT32|0x00000008 - # Stack for CPU Cores in Non Secure Mode gArmPlatformTokenSpaceGuid.PcdCPUCoresStackBase|0|UINT32|0x00000009 gArmPlatformTokenSpaceGuid.PcdCPUCorePrimaryStackSize|0x10000|UINT32|0x00000037 @@ -142,4 +138,16 @@ gArmPlatformTokenSpaceGuid.PcdDefaultConInPaths|L""|VOID*|0x0000001B gArmPlatformTokenSpaceGuid.PcdDefaultConOutPaths|L""|VOID*|0x0000001C - + +[PcdsFixedAtBuild.ARM] + # Stack for CPU Cores in Secure Monitor Mode + gArmPlatformTokenSpaceGuid.PcdCPUCoresSecMonStackBase|0|UINT32|0x00000007 + gArmPlatformTokenSpaceGuid.PcdCPUCoreSecMonStackSize|0x1000|UINT32|0x00000008 + +[PcdsFixedAtBuild.AARCH64] + # The Secure World is only running in EL3. Only one set of stacks is needed for AArch64. + # The Secure stacks are described by PcdCPUCoresSecStackBase, PcdCPUCoreSecPrimaryStackSize + # and PcdCPUCoreSecSecondaryStackSize + gArmPlatformTokenSpaceGuid.PcdCPUCoresSecMonStackBase|0|UINT32|0x00000007 + gArmPlatformTokenSpaceGuid.PcdCPUCoreSecMonStackSize|0x0|UINT32|0x00000008 + diff --git a/ArmPlatformPkg/ArmPlatformPkg.dsc b/ArmPlatformPkg/ArmPlatformPkg.dsc index 495896c886..c353e6f902 100644 --- a/ArmPlatformPkg/ArmPlatformPkg.dsc +++ b/ArmPlatformPkg/ArmPlatformPkg.dsc @@ -21,14 +21,12 @@ PLATFORM_VERSION = 0.1 DSC_SPECIFICATION = 0x00010005 OUTPUT_DIRECTORY = Build/$(PLATFORM_NAME) - SUPPORTED_ARCHITECTURES = ARM + SUPPORTED_ARCHITECTURES = ARM|AARCH64 BUILD_TARGETS = DEBUG|RELEASE SKUID_IDENTIFIER = DEFAULT FLASH_DEFINITION = ArmPlatformPkg/ArmPlatformPkg.fdf [LibraryClasses.common] - ArmLib|ArmPkg/Library/ArmLib/ArmV7/ArmV7Lib.inf - ArmCpuLib|ArmPkg/Drivers/ArmCpuLib/ArmCortexA9Lib/ArmCortexA9Lib.inf ArmPlatformLib|ArmPlatformPkg/Library/ArmPlatformLibNull/ArmPlatformLibNull.inf !if $(TARGET) == RELEASE @@ -112,8 +110,15 @@ BdsLib|ArmPkg/Library/BdsLib/BdsLib.inf FdtLib|EmbeddedPkg/Library/FdtLib/FdtLib.inf +[LibraryClasses.ARM] + ArmLib|ArmPkg/Library/ArmLib/ArmV7/ArmV7Lib.inf + ArmCpuLib|ArmPkg/Drivers/ArmCpuLib/ArmCortexA9Lib/ArmCortexA9Lib.inf + +[LibraryClasses.AARCH64] + ArmLib|ArmPkg/Library/ArmLib/AArch64/AArch64Lib.inf + ArmCpuLib|ArmPkg/Drivers/ArmCpuLib/ArmCortexAEMv8Lib/ArmCortexAEMv8Lib.inf + [LibraryClasses.common.SEC] - ArmLib|ArmPkg/Library/ArmLib/ArmV7/ArmV7LibSec.inf ArmPlatformSecLib|ArmPlatformPkg/Library/ArmPlatformSecLibNull/ArmPlatformLibNullSec.inf ArmPlatformLib|ArmPlatformPkg/Library/ArmPlatformLibNull/ArmPlatformLibNullSec.inf ArmTrustedMonitorLib|ArmPlatformPkg/Library/ArmTrustedMonitorLibNull/ArmTrustedMonitorLibNull.inf @@ -124,6 +129,12 @@ DebugAgentLib|ArmPkg/Library/DebugAgentSymbolsBaseLib/DebugAgentSymbolsBaseLib.inf DefaultExceptionHandlerLib|ArmPkg/Library/DefaultExceptionHandlerLib/DefaultExceptionHandlerLibBase.inf +[LibraryClasses.ARM.SEC] + ArmLib|ArmPkg/Library/ArmLib/ArmV7/ArmV7LibSec.inf + +[LibraryClasses.AARCH64.SEC] + ArmLib|ArmPkg/Library/ArmLib/AArch64/AArch64LibSec.inf + [LibraryClasses.common.PEI_CORE] HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf PeiServicesLib|MdePkg/Library/PeiServicesLib/PeiServicesLib.inf @@ -200,6 +211,9 @@ # NULL|ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf +[LibraryClasses.AARCH64] + NULL|ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf + [BuildOptions] XCODE:*_*_ARM_PLATFORM_FLAGS == -arch armv7 diff --git a/ArmPlatformPkg/Library/ArmPlatformLibNull/AArch64/ArmPlatformHelper.S b/ArmPlatformPkg/Library/ArmPlatformLibNull/AArch64/ArmPlatformHelper.S new file mode 100644 index 0000000000..8c099b469e --- /dev/null +++ b/ArmPlatformPkg/Library/ArmPlatformLibNull/AArch64/ArmPlatformHelper.S @@ -0,0 +1,65 @@ +// +// 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 + +.text +.align 2 + +GCC_ASM_EXPORT(ArmPlatformPeiBootAction) +GCC_ASM_EXPORT(ArmPlatformGetCorePosition) +GCC_ASM_EXPORT(ArmPlatformGetPrimaryCoreMpId) +GCC_ASM_EXPORT(ArmPlatformIsPrimaryCore) + +GCC_ASM_IMPORT(_gPcd_FixedAtBuild_PcdArmPrimaryCore) +GCC_ASM_IMPORT(_gPcd_FixedAtBuild_PcdArmPrimaryCoreMask) + +ASM_PFX(ArmPlatformPeiBootAction): + ret + +//UINTN +//ArmPlatformGetCorePosition ( +// IN UINTN MpId +// ); +// With this function: CorePos = (ClusterId * 4) + CoreId +ASM_PFX(ArmPlatformGetCorePosition): + and x1, x0, #ARM_CORE_MASK + and x0, x0, #ARM_CLUSTER_MASK + add x0, x1, x0, LSR #6 + ret + +//UINTN +//ArmPlatformGetPrimaryCoreMpId ( +// VOID +// ); +ASM_PFX(ArmPlatformGetPrimaryCoreMpId): + LoadConstantToReg (_gPcd_FixedAtBuild_PcdArmPrimaryCore, x0) + ldrh w0, [x0] + ret + +//UINTN +//ArmPlatformIsPrimaryCore ( +// IN UINTN MpId +// ); +ASM_PFX(ArmPlatformIsPrimaryCore): + LoadConstantToReg (_gPcd_FixedAtBuild_PcdArmPrimaryCoreMask, x1) + ldrh w1, [x1] + and x0, x0, x1 + LoadConstantToReg (_gPcd_FixedAtBuild_PcdArmPrimaryCore, x1) + ldrh w1, [x1] + cmp w0, w1 + mov x0, #1 + mov x1, #0 + csel x0, x0, x1, eq + ret diff --git a/ArmPlatformPkg/Library/ArmPlatformLibNull/ArmPlatformLibNull.inf b/ArmPlatformPkg/Library/ArmPlatformLibNull/ArmPlatformLibNull.inf index a6c2e8f48e..18a506af18 100644 --- a/ArmPlatformPkg/Library/ArmPlatformLibNull/ArmPlatformLibNull.inf +++ b/ArmPlatformPkg/Library/ArmPlatformLibNull/ArmPlatformLibNull.inf @@ -37,6 +37,9 @@ Arm/ArmPlatformHelper.S | GCC Arm/ArmPlatformHelper.asm | RVCT +[Sources.AArch64] + AArch64/ArmPlatformHelper.S | GCC + [FixedPcd] gArmTokenSpaceGuid.PcdSystemMemoryBase gArmTokenSpaceGuid.PcdSystemMemorySize diff --git a/ArmPlatformPkg/Library/ArmPlatformLibNull/ArmPlatformLibNullSec.inf b/ArmPlatformPkg/Library/ArmPlatformLibNull/ArmPlatformLibNullSec.inf index 128b0b59e2..bdd0a4833c 100644 --- a/ArmPlatformPkg/Library/ArmPlatformLibNull/ArmPlatformLibNullSec.inf +++ b/ArmPlatformPkg/Library/ArmPlatformLibNull/ArmPlatformLibNullSec.inf @@ -36,6 +36,9 @@ Arm/ArmPlatformHelper.S | GCC Arm/ArmPlatformHelper.asm | RVCT +[Sources.AArch64] + AArch64/ArmPlatformHelper.S | GCC + [FixedPcd] gArmTokenSpaceGuid.PcdSystemMemoryBase gArmTokenSpaceGuid.PcdSystemMemorySize diff --git a/ArmPlatformPkg/Library/ArmPlatformSecLibNull/AArch64/ArmPlatformLibNullBoot.S b/ArmPlatformPkg/Library/ArmPlatformSecLibNull/AArch64/ArmPlatformLibNullBoot.S new file mode 100644 index 0000000000..0bfb947d1c --- /dev/null +++ b/ArmPlatformPkg/Library/ArmPlatformSecLibNull/AArch64/ArmPlatformLibNullBoot.S @@ -0,0 +1,61 @@ +// +// 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 + +.text +.align 3 + +GCC_ASM_EXPORT(ArmPlatformSecBootAction) +GCC_ASM_EXPORT(ArmPlatformSecBootMemoryInit) +GCC_ASM_EXPORT(ArmSecMpCoreSecondariesWrite) +GCC_ASM_EXPORT(ArmSecMpCoreSecondariesRead) + +/** + Call at the beginning of the platform boot up + + This function allows the firmware platform to do extra actions at the early + stage of the platform power up. + + Note: This function must be implemented in assembler as there is no stack set up yet + +**/ +ASM_PFX(ArmPlatformSecBootAction): + ret + +/** + Initialize the memory where the initial stacks will reside + + This memory can contain the initial stacks (Secure and Secure Monitor stacks). + In some platform, this region is already initialized and the implementation of this function can + do nothing. This memory can also represent the Secure RAM. + This function is called before the satck has been set up. Its implementation must ensure the stack + pointer is not used (probably required to use assembly language) + +**/ +ASM_PFX(ArmPlatformSecBootMemoryInit): + // The SMC does not need to be initialized for RTSM + ret + +/* Write the flag register used to start Secondary cores */ +ASM_PFX(ArmSecMpCoreSecondariesWrite): + // Write to the CPU Mailbox + ret + + +/* Read the flag register used to start Secondary cores */ +ASM_PFX(ArmSecMpCoreSecondariesRead): + // Return the value from the CPU Mailbox + mov x0, #0 + ret diff --git a/ArmPlatformPkg/Library/ArmPlatformSecLibNull/ArmPlatformLibNullSec.inf b/ArmPlatformPkg/Library/ArmPlatformSecLibNull/ArmPlatformLibNullSec.inf index f399547574..8fe933af26 100644 --- a/ArmPlatformPkg/Library/ArmPlatformSecLibNull/ArmPlatformLibNullSec.inf +++ b/ArmPlatformPkg/Library/ArmPlatformSecLibNull/ArmPlatformLibNullSec.inf @@ -36,6 +36,10 @@ Arm/ArmPlatformLibNullBoot.asm | RVCT Arm/ArmPlatformLibNullBoot.S | GCC +[Sources.AARCH64] + AArch64/ArmPlatformLibNullBoot.S | GCC + + [FixedPcd] gArmTokenSpaceGuid.PcdFvBaseAddress diff --git a/ArmPlatformPkg/Library/ArmPlatformStackLib/AArch64/ArmPlatformStackLib.S b/ArmPlatformPkg/Library/ArmPlatformStackLib/AArch64/ArmPlatformStackLib.S new file mode 100644 index 0000000000..337af9c6a9 --- /dev/null +++ b/ArmPlatformPkg/Library/ArmPlatformStackLib/AArch64/ArmPlatformStackLib.S @@ -0,0 +1,129 @@ +// +// 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 + +.text +.align 3 + +GCC_ASM_EXPORT(ArmPlatformStackSet) +GCC_ASM_EXPORT(ArmPlatformStackSetPrimary) +GCC_ASM_EXPORT(ArmPlatformStackSetSecondary) + +GCC_ASM_IMPORT(ArmPlatformIsPrimaryCore) +GCC_ASM_IMPORT(ArmPlatformGetCorePosition) +GCC_ASM_IMPORT(ArmPlatformGetPrimaryCoreMpId) + +GCC_ASM_IMPORT(gPcd_FixedAtBuild_PcdCoreCount) + +//VOID +//ArmPlatformStackSet ( +// IN UINTN StackBase, +// IN UINTN MpId, +// IN UINTN PrimaryStackSize, +// IN UINTN SecondaryStackSize +// ); +ASM_PFX(ArmPlatformStackSet): + // Save parameters + mov x6, x3 + mov x5, x2 + mov x4, x1 + mov x3, x0 + + // Save the Link register + mov x7, x30 + + // Identify Stack + mov x0, x1 + bl ASM_PFX(ArmPlatformIsPrimaryCore) + cmp x0, #1 + + // Restore parameters + mov x0, x3 + mov x1, x4 + mov x2, x5 + mov x3, x6 + + // Restore the Link register + mov x30, x7 + + // Should be ASM_PFX(ArmPlatformStackSetPrimary) but generate linker error 'unsupported ELF EM_AARCH64' + b.eq ArmPlatformStackSetPrimaryL + // Should be ASM_PFX(ArmPlatformStackSetSecondary) but generate linker error 'unsupported ELF EM_AARCH64' + b.ne ArmPlatformStackSetSecondaryL + +//VOID +//ArmPlatformStackSetPrimary ( +// IN UINTN StackBase, +// IN UINTN MpId, +// IN UINTN PrimaryStackSize, +// IN UINTN SecondaryStackSize +// ); +ArmPlatformStackSetPrimaryL: +ASM_PFX(ArmPlatformStackSetPrimary): + // Save the Link register + mov x4, x30 + + // Add stack of primary stack to StackBase + add x0, x0, x2 + + // Compute SecondaryCoresCount * SecondaryCoreStackSize + LoadConstantToReg (_gPcd_FixedAtBuild_PcdCoreCount, x1) + ldr w1, [x1] + sub x1, x1, #1 + mul x3, x3, x1 + + // Set Primary Stack ((StackBase + PrimaryStackSize) + (SecondaryCoresCount * SecondaryCoreStackSize)) + add sp, x0, x3 + + br x4 + +//VOID +//ArmPlatformStackSetSecondary ( +// IN UINTN StackBase, +// IN UINTN MpId, +// IN UINTN PrimaryStackSize, +// IN UINTN SecondaryStackSize +// ); +ArmPlatformStackSetSecondaryL: +ASM_PFX(ArmPlatformStackSetSecondary): + // Save the Link register + mov x4, x30 + mov sp, x0 + + // Get Core Position + mov x0, x1 + bl ASM_PFX(ArmPlatformGetCorePosition) + mov x5, x0 + + // Get Primary Core Position + bl ASM_PFX(ArmPlatformGetPrimaryCoreMpId) + bl ASM_PFX(ArmPlatformGetCorePosition) + + // Get Secondary Core Position. We should get consecutive secondary stack number from 1...(CoreCount-1) + cmp x5, x0 + b.ls 1f + // Decrement the position if after the primary core + sub x5, x5, #1 +1: + add x5, x5, #1 + + // Compute top of the secondary stack + mul x3, x3, x5 + + // Set stack + add sp, sp, x3 + + br x4 diff --git a/ArmPlatformPkg/Library/ArmPlatformStackLib/Arm/ArmPlatformStackLib.S b/ArmPlatformPkg/Library/ArmPlatformStackLib/Arm/ArmPlatformStackLib.S index 94660c97fe..34fab31dd4 100644 --- a/ArmPlatformPkg/Library/ArmPlatformStackLib/Arm/ArmPlatformStackLib.S +++ b/ArmPlatformPkg/Library/ArmPlatformStackLib/Arm/ArmPlatformStackLib.S @@ -1,5 +1,5 @@ // -// Copyright (c) 2012, ARM Limited. All rights reserved. +// 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 @@ -38,12 +38,12 @@ ASM_PFX(ArmPlatformStackSet): // Identify Stack // Mask for ClusterId|CoreId LoadConstantToReg (0xFFFF, r4) - and r1, r1, r4 + and r1, r1, r4 // Is it the Primary Core ? LoadConstantToReg (_gPcd_FixedAtBuild_PcdArmPrimaryCore, r4) - ldr r4, [r4] + ldr r4, [r4] cmp r1, r4 - beq ASM_PFX(ArmPlatformStackSetPrimary) + beq ASM_PFX(ArmPlatformStackSetPrimary) bne ASM_PFX(ArmPlatformStackSetSecondary) //VOID @@ -54,19 +54,19 @@ ASM_PFX(ArmPlatformStackSet): // IN UINTN SecondaryStackSize // ); ASM_PFX(ArmPlatformStackSetPrimary): - mov r4, lr + mov r4, lr // Add stack of primary stack to StackBase - add r0, r0, r2 + add r0, r0, r2 // Compute SecondaryCoresCount * SecondaryCoreStackSize LoadConstantToReg (_gPcd_FixedAtBuild_PcdCoreCount, r1) - ldr r1, [r1] - sub r1, #1 - mul r3, r3, r1 + ldr r1, [r1] + sub r1, #1 + mul r3, r3, r1 // Set Primary Stack ((StackBase + PrimaryStackSize) + (SecondaryCoresCount * SecondaryCoreStackSize)) - add sp, r0, r3 + add sp, r0, r3 bx r4 @@ -78,29 +78,29 @@ ASM_PFX(ArmPlatformStackSetPrimary): // IN UINTN SecondaryStackSize // ); ASM_PFX(ArmPlatformStackSetSecondary): - mov r4, lr + mov r4, lr mov sp, r0 // Get Core Position - mov r0, r1 + mov r0, r1 bl ASM_PFX(ArmPlatformGetCorePosition) - mov r5, r0 + mov r5, r0 // Get Primary Core Position LoadConstantToReg (_gPcd_FixedAtBuild_PcdArmPrimaryCore, r0) - ldr r0, [r0] + ldr r0, [r0] bl ASM_PFX(ArmPlatformGetCorePosition) // Get Secondary Core Position. We should get consecutive secondary stack number from 1...(CoreCount-1) - cmp r5, r0 + cmp r5, r0 subhi r5, r5, #1 - add r5, r5, #1 + add r5, r5, #1 // Compute top of the secondary stack - mul r3, r3, r5 + mul r3, r3, r5 // Set stack - add sp, sp, r3 + add sp, sp, r3 bx r4 diff --git a/ArmPlatformPkg/Library/ArmPlatformStackLib/ArmPlatformStackLib.inf b/ArmPlatformPkg/Library/ArmPlatformStackLib/ArmPlatformStackLib.inf index e48a65801d..700bc89eac 100644 --- a/ArmPlatformPkg/Library/ArmPlatformStackLib/ArmPlatformStackLib.inf +++ b/ArmPlatformPkg/Library/ArmPlatformStackLib/ArmPlatformStackLib.inf @@ -30,6 +30,9 @@ Arm/ArmPlatformStackLib.asm | RVCT Arm/ArmPlatformStackLib.S | GCC +[Sources.AARCH64] + AArch64/ArmPlatformStackLib.S | GCC + [FixedPcd] gArmPlatformTokenSpaceGuid.PcdCoreCount diff --git a/ArmPlatformPkg/Library/ArmTrustedMonitorLibNull/AArch64/ArmTrustedMonitorLibNull.c b/ArmPlatformPkg/Library/ArmTrustedMonitorLibNull/AArch64/ArmTrustedMonitorLibNull.c new file mode 100644 index 0000000000..72c62d7f10 --- /dev/null +++ b/ArmPlatformPkg/Library/ArmTrustedMonitorLibNull/AArch64/ArmTrustedMonitorLibNull.c @@ -0,0 +1,24 @@ +/** @file +* Main file supporting the Monitor World on ARM PLatforms +* +* 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. +* +**/ + +VOID +ArmSecureMonitorWorldInitialize ( + VOID + ) +{ + // Do not touch the EL3 Exception Vector Table Register. + // The default default DebugAgentLib could have already set its own vector + // into EL3 to catch abort exceptions. +} diff --git a/ArmPlatformPkg/Library/ArmTrustedMonitorLibNull/ArmTrustedMonitorLibNull.c b/ArmPlatformPkg/Library/ArmTrustedMonitorLibNull/Arm/ArmTrustedMonitorLibNull.c similarity index 100% rename from ArmPlatformPkg/Library/ArmTrustedMonitorLibNull/ArmTrustedMonitorLibNull.c rename to ArmPlatformPkg/Library/ArmTrustedMonitorLibNull/Arm/ArmTrustedMonitorLibNull.c diff --git a/ArmPlatformPkg/Library/ArmTrustedMonitorLibNull/ArmTrustedMonitorLibNull.inf b/ArmPlatformPkg/Library/ArmTrustedMonitorLibNull/ArmTrustedMonitorLibNull.inf index 2a9c54babe..da867e1fe9 100644 --- a/ArmPlatformPkg/Library/ArmTrustedMonitorLibNull/ArmTrustedMonitorLibNull.inf +++ b/ArmPlatformPkg/Library/ArmTrustedMonitorLibNull/ArmTrustedMonitorLibNull.inf @@ -19,13 +19,14 @@ VERSION_STRING = 1.0 LIBRARY_CLASS = ArmTrustedMonitorLib -[Sources.common] - ArmTrustedMonitorLibNull.c - [Sources.ARM] + Arm/ArmTrustedMonitorLibNull.c Arm/MonitorTable.asm | RVCT Arm/MonitorTable.S | GCC +[Sources.AARCH64] + AArch64/ArmTrustedMonitorLibNull.c + [Packages] ArmPkg/ArmPkg.dec ArmPlatformPkg/ArmPlatformPkg.dec diff --git a/ArmPlatformPkg/Library/EblCmdLib/AArch64/EblCmdMmu.c b/ArmPlatformPkg/Library/EblCmdLib/AArch64/EblCmdMmu.c new file mode 100644 index 0000000000..169267576b --- /dev/null +++ b/ArmPlatformPkg/Library/EblCmdLib/AArch64/EblCmdMmu.c @@ -0,0 +1,33 @@ +/** @file +* +* 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 +#include +#include +#include +#include + +EFI_STATUS +EblDumpMmu ( + IN UINTN Argc, + IN CHAR8 **Argv + ) +{ + AsciiPrint ("\nNot supported on this platform.\n"); + + return EFI_SUCCESS; +} diff --git a/ArmPlatformPkg/Library/EblCmdLib/EblCmdLib.inf b/ArmPlatformPkg/Library/EblCmdLib/EblCmdLib.inf index 33508c26ea..4de0d9d9de 100644 --- a/ArmPlatformPkg/Library/EblCmdLib/EblCmdLib.inf +++ b/ArmPlatformPkg/Library/EblCmdLib/EblCmdLib.inf @@ -34,6 +34,9 @@ [Sources.ARM] Arm/EblCmdMmu.c +[Sources.AARCH64] + AArch64/EblCmdMmu.c + [Packages] MdePkg/MdePkg.dec MdeModulePkg/MdeModulePkg.dec diff --git a/ArmPlatformPkg/PrePeiCore/AArch64/ArchPrePeiCore.c b/ArmPlatformPkg/PrePeiCore/AArch64/ArchPrePeiCore.c new file mode 100644 index 0000000000..e1842f2a02 --- /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 0000000000..9ca422b2f5 --- /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 0000000000..14e9cb8d8b --- /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 0000000000..5bdbe4585f --- /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 0000000000..d3fcd0aa13 --- /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 ececd4c763..e165fd9456 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 351ac67807..d90481e750 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 13f86902b6..94b7a6cf09 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 diff --git a/ArmPlatformPkg/PrePi/AArch64/ArchPrePi.c b/ArmPlatformPkg/PrePi/AArch64/ArchPrePi.c new file mode 100644 index 0000000000..217986107e --- /dev/null +++ b/ArmPlatformPkg/PrePi/AArch64/ArchPrePi.c @@ -0,0 +1,33 @@ +/** @file +* +* 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 "PrePi.h" + +#include + +VOID +ArchInitialize ( + VOID + ) +{ + // Enable Floating Point + if (FixedPcdGet32 (PcdVFPEnabled)) { + ArmEnableVFP (); + } + + if (ArmReadCurrentEL () == AARCH64_EL2) { + // Trap General Exceptions. All exceptions that would be routed to EL1 are routed to EL2 + ArmWriteHcr (ARM_HCR_TGE); + } +} diff --git a/ArmPlatformPkg/PrePi/AArch64/ModuleEntryPoint.S b/ArmPlatformPkg/PrePi/AArch64/ModuleEntryPoint.S new file mode 100644 index 0000000000..e442819539 --- /dev/null +++ b/ArmPlatformPkg/PrePi/AArch64/ModuleEntryPoint.S @@ -0,0 +1,148 @@ +// +// 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 + +#include + +.text +.align 3 + +GCC_ASM_IMPORT(ArmPlatformIsPrimaryCore) +GCC_ASM_IMPORT(ArmReadMpidr) +GCC_ASM_IMPORT(ArmPlatformPeiBootAction) +GCC_ASM_IMPORT(ArmPlatformStackSet) +GCC_ASM_EXPORT(_ModuleEntryPoint) + +StartupAddr: .dword ASM_PFX(CEntryPoint) + +ASM_PFX(_ModuleEntryPoint): + // Do early platform specific actions + bl ASM_PFX(ArmPlatformPeiBootAction) + + // Get ID of this CPU in Multicore system + bl ASM_PFX(ArmReadMpidr) + // Keep a copy of the MpId register value + mov x10, x0 + +_SetSVCMode: +// Check if we can install the stack at the top of the System Memory or if we need +// to install the stacks at the bottom of the Firmware Device (case the FD is located +// at the top of the DRAM) +_SetupStackPosition: + // Compute Top of System Memory + LoadConstantToReg (FixedPcdGet32(PcdSystemMemoryBase), x1) + LoadConstantToReg (FixedPcdGet32(PcdSystemMemorySize), x2) + sub x2, x2, #1 + add x1, x1, x2 // x1 = SystemMemoryTop = PcdSystemMemoryBase + PcdSystemMemorySize + + // Calculate Top of the Firmware Device + LoadConstantToReg (FixedPcdGet32(PcdFdBaseAddress), x2) + LoadConstantToReg (FixedPcdGet32(PcdFdSize), x3) + sub x3, x3, #1 + add x3, x3, x2 // x3 = FdTop = PcdFdBaseAddress + PcdFdSize + + // UEFI Memory Size (stacks are allocated in this region) + LoadConstantToReg (FixedPcdGet32(PcdSystemMemoryUefiRegionSize), x4) + + // + // Reserve the memory for the UEFI region (contain stacks on its top) + // + + // Calculate how much space there is between the top of the Firmware and the Top of the System Memory + subs x0, x1, x3 // x0 = SystemMemoryTop - FdTop + b.mi _SetupStack // Jump if negative (FdTop > SystemMemoryTop). Case when the PrePi is in XIP memory outside of the DRAM + cmp x0, x4 + b.ge _SetupStack + + // Case the top of stacks is the FdBaseAddress + mov x1, x2 + +_SetupStack: + // x1 contains the top of the stack (and the UEFI Memory) + + // Because the 'push' instruction is equivalent to 'stmdb' (decrement before), we need to increment + // one to the top of the stack. We check if incrementing one does not overflow (case of DRAM at the + // top of the memory space) + adds x11, x1, #1 + b.cs _SetupOverflowStack + +_SetupAlignedStack: + mov x1, x11 + b _GetBaseUefiMemory + +_SetupOverflowStack: + // Case memory at the top of the address space. Ensure the top of the stack is EFI_PAGE_SIZE + // aligned (4KB) + LoadConstantToReg (EFI_PAGE_MASK, x11) + and x11, x11, x1 + sub x1, x1, x11 + +_GetBaseUefiMemory: + // Calculate the Base of the UEFI Memory + sub x11, x1, x4 + +_GetStackBase: + // r1 = The top of the Mpcore Stacks + // Stack for the primary core = PrimaryCoreStack + LoadConstantToReg (FixedPcdGet32(PcdCPUCorePrimaryStackSize), x2) + sub x12, x1, x2 + + // Stack for the secondary core = Number of Cores - 1 + LoadConstantToReg (FixedPcdGet32(PcdCoreCount), x0) + sub x0, x0, #1 + LoadConstantToReg (FixedPcdGet32(PcdCPUCoreSecondaryStackSize), x1) + mul x1, x1, x0 + sub x12, x12, x1 + + // x12 = The base of the MpCore Stacks (primary stack & secondary stacks) + mov x0, x12 + mov x1, x10 + //ArmPlatformStackSet(StackBase, MpId, PrimaryStackSize, SecondaryStackSize) + LoadConstantToReg (FixedPcdGet32(PcdCPUCorePrimaryStackSize), x2) + LoadConstantToReg (FixedPcdGet32(PcdCPUCoreSecondaryStackSize), x3) + bl ASM_PFX(ArmPlatformStackSet) + + // Is it the Primary Core ? + mov x0, x10 + bl ASM_PFX(ArmPlatformIsPrimaryCore) + cmp x0, #1 + bne _PrepareArguments + +_ReserveGlobalVariable: + LoadConstantToReg (FixedPcdGet32(PcdPeiGlobalVariableSize), x0) + // InitializePrimaryStack($GlobalVariableSize, $Tmp1, $Tmp2) + InitializePrimaryStack(x0, x1, x2) + +_PrepareArguments: + mov x0, x10 + mov x1, x11 + mov x2, x12 + mov x3, sp + + // Move sec startup address into a data register + // Ensure we're jumping to FV version of the code (not boot remapped alias) + ldr x4, StartupAddr + + // Jump to PrePiCore C code + // x0 = MpId + // x1 = UefiMemoryBase + // x2 = StacksBase + // x3 = GlobalVariableBase + blr x4 + +_NeverReturn: + b _NeverReturn diff --git a/ArmPlatformPkg/PrePi/Arm/ArchPrePi.c b/ArmPlatformPkg/PrePi/Arm/ArchPrePi.c new file mode 100644 index 0000000000..075eb89e1b --- /dev/null +++ b/ArmPlatformPkg/PrePi/Arm/ArchPrePi.c @@ -0,0 +1,29 @@ +/** @file +* +* 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 "PrePi.h" + +VOID +ArchInitialize ( + VOID + ) +{ + // Enable program flow prediction, if supported. + ArmEnableBranchPrediction (); + + if (FixedPcdGet32 (PcdVFPEnabled)) { + ArmEnableVFP (); + } +} + diff --git a/ArmPlatformPkg/PrePi/PeiMPCore.inf b/ArmPlatformPkg/PrePi/PeiMPCore.inf index a2814b6710..ee89c04ae1 100755 --- a/ArmPlatformPkg/PrePi/PeiMPCore.inf +++ b/ArmPlatformPkg/PrePi/PeiMPCore.inf @@ -24,8 +24,13 @@ MainMPCore.c [Sources.ARM] + Arm/ArchPrePi.c Arm/ModuleEntryPoint.S | GCC Arm/ModuleEntryPoint.asm | RVCT + +[Sources.AArch64] + AArch64/ArchPrePi.c + AArch64/ModuleEntryPoint.S | GCC [Packages] MdePkg/MdePkg.dec diff --git a/ArmPlatformPkg/PrePi/PeiUniCore.inf b/ArmPlatformPkg/PrePi/PeiUniCore.inf index dd6b82ed38..6cb94cbd77 100755 --- a/ArmPlatformPkg/PrePi/PeiUniCore.inf +++ b/ArmPlatformPkg/PrePi/PeiUniCore.inf @@ -24,8 +24,13 @@ MainUniCore.c [Sources.ARM] + Arm/ArchPrePi.c Arm/ModuleEntryPoint.S | GCC Arm/ModuleEntryPoint.asm | RVCT + +[Sources.AArch64] + AArch64/ArchPrePi.c + AArch64/ModuleEntryPoint.S | GCC [Packages] MdePkg/MdePkg.dec diff --git a/ArmPlatformPkg/PrePi/PrePi.c b/ArmPlatformPkg/PrePi/PrePi.c index 238b0989ab..e8b1ff7ed7 100755 --- a/ArmPlatformPkg/PrePi/PrePi.c +++ b/ArmPlatformPkg/PrePi/PrePi.c @@ -111,12 +111,8 @@ PrePiMain ( ((FixedPcdGet32 (PcdFdBaseAddress) >= FixedPcdGet32 (PcdSystemMemoryBase)) && ((UINT32)(FixedPcdGet32 (PcdFdBaseAddress) + FixedPcdGet32 (PcdFdSize)) <= (UINT32)(FixedPcdGet32 (PcdSystemMemoryBase) + FixedPcdGet32 (PcdSystemMemorySize))))); - // Enable program flow prediction, if supported. - ArmEnableBranchPrediction (); - - if (FixedPcdGet32(PcdVFPEnabled)) { - ArmEnableVFP(); - } + // Initialize the architecture specific bits + ArchInitialize (); // Initialize the Serial Port SerialPortInitialize (); diff --git a/ArmPlatformPkg/PrePi/PrePi.h b/ArmPlatformPkg/PrePi/PrePi.h index deb8851688..e67795f449 100644 --- a/ArmPlatformPkg/PrePi/PrePi.h +++ b/ArmPlatformPkg/PrePi/PrePi.h @@ -81,4 +81,10 @@ GetPlatformPpi ( OUT VOID **Ppi ); +// Initialize the Architecture specific controllers +VOID +ArchInitialize ( + VOID + ); + #endif /* _PREPI_H_ */ diff --git a/ArmPlatformPkg/Sec/AArch64/Helper.S b/ArmPlatformPkg/Sec/AArch64/Helper.S new file mode 100644 index 0000000000..ff46255763 --- /dev/null +++ b/ArmPlatformPkg/Sec/AArch64/Helper.S @@ -0,0 +1,156 @@ +#======================================================================================== +# 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(SetupExceptionLevel3) +ASM_GLOBAL ASM_PFX(SwitchToNSExceptionLevel1) +ASM_GLOBAL ASM_PFX(enter_monitor_mode) +ASM_GLOBAL ASM_PFX(return_from_exception) +ASM_GLOBAL ASM_PFX(copy_cpsr_into_spsr) +ASM_GLOBAL ASM_PFX(set_non_secure_mode) + +ASM_PFX(SetupExceptionLevel3): + mrs x0, scr_el3 // Read EL3 Secure Configuration Register + orr x0, x0, #1 // EL0 an EL1 cannot access secure memory + + // Send all interrupts to their respective Exception levels for EL3 + bic x0, x0, #(1 << 1) // IRQ + bic x0, x0, #(1 << 2) // FIQ + bic x0, x0, #(1 << 3) // Serror and Abort + orr x0, x0, #(1 << 8) // Enable HVC + orr x0, x0, #(1 << 10) // Make next level down 64Bit. This is EL2 in the case of the Model. + // We need a nice way to detect this. + msr scr_el3, x0 // Write back our settings + + msr cptr_el3, xzr // Disable copro traps to EL3 + + // Check for the primary CPU to avoid a race on the distributor registers. + mrs x0, mpidr_el1 + tst x0, #15 + b.ne 1f // secondary CPU + + LoadConstantToReg (FixedPcdGet32(PcdGicInterruptInterfaceBase), x1) + mov w0, #3 // EnableGrp0 | EnableGrp1 + str w0, [x1] + +1: LoadConstantToReg (FixedPcdGet32(PcdGicDistributorBase), x1) + add x1, x1, #0x80 + mov w0, #~0 // Grp1 interrupts + str w0, [x1], #4 + b.ne 2f // Only local interrupts for secondary CPUs + str w0, [x1], #4 + str w0, [x1], #4 + +2: LoadConstantToReg (FixedPcdGet32(PcdGicInterruptInterfaceBase), x1) + ldr w0, [x1] + mov w0, #3 // EnableGrp0 | EnableGrp1 + str w0, [x1] + + mov w0, #1 << 7 // allow NS access to GICC_PMR + str w0, [x1, #4] // GICC_PMR + + ret + +// Switch from EL3 to NS-EL1 +ASM_PFX(SwitchToNSExceptionLevel1): + // Now setup our EL1. Controlled by EL2 config on Model + mrs x0, hcr_el2 // Read EL2 Hypervisor configuration Register + orr x0, x0, #(1 << 31) // Set EL1 to be 64bit + + // Send all interrupts to their respective Exception levels for EL2 + bic x0, x0, #(1 << 3) // Disable virtual FIQ + bic x0, x0, #(1 << 4) // Disable virtual IRQ + bic x0, x0, #(1 << 5) // Disable virtual SError and Abort + msr hcr_el2, x0 // Write back our settings + + msr cptr_el2, xzr // Disable copro traps to EL2 + + msr sctlr_el2, xzr + + // Enable architected timer access + mrs x0, cnthctl_el2 + orr x0, x0, #3 // Enable EL1 access to timers + msr cnthctl_el2, x0 + + mrs x0, cntkctl_el1 + orr x0, x0, #3 // EL0 access to counters + msr cntkctl_el1, x0 + + // Set ID regs + mrs x0, midr_el1 + mrs x1, mpidr_el1 + msr vpidr_el2, x0 + msr vmpidr_el2, x1 + + ret + + +// EL3 on AArch64 is Secure/monitor so this funtion is reduced vs ARMv7 +// we don't need a mode switch, just setup the Arguments and jump. +// x0: Monitor World EntryPoint +// x1: MpId +// x2: SecBootMode +// x3: Secure Monitor mode stack +ASM_PFX(enter_monitor_mode): + mov x4, x0 // Swap EntryPoint and MpId registers + mov x0, x1 + mov x1, x2 + mov x2, x3 + br x4 + +// Put the address in correct ELR_ELx and do a eret. +// We may need to do some config before we change to another Mode. +ASM_PFX(return_from_exception): + msr elr_el3, x0 + + mrs x7, spsr_el3 + ands w7, w7, #0xC + cmp w7, #0xC // EL3? + b.eq 3f + bl ASM_PFX(SetupExceptionLevel3) + cmp w7, #0x8 // EL2? + b.eq 2f + cmp w7, #0x4 // EL1? + b.eq 1f + b dead // We should never get here. + +1: bl ASM_PFX(SwitchToNSExceptionLevel1) +2: // EL2: No more setup required. +3: // EL3: Not sure why we would do this. + eret + +// For AArch64 we need to construct the spsr we want from individual bits and pieces. +ASM_PFX(copy_cpsr_into_spsr): + mrs x0, CurrentEl // Get the current exception level we are running at. + mrs x1, SPSel // Which Stack are we using + orr x0, x0, x1 + mrs x1, daif // Which interrupts are enabled + orr x0, x0, x1 + msr spsr_el3, x0 // Write to spsr + ret + +// Get this from platform file. +ASM_PFX(set_non_secure_mode): + msr spsr_el3, x0 + ret + +dead: + b dead + +ASM_FUNCTION_REMOVE_IF_UNREFERENCED diff --git a/ArmPlatformPkg/Sec/AArch64/SecEntryPoint.S b/ArmPlatformPkg/Sec/AArch64/SecEntryPoint.S new file mode 100644 index 0000000000..e678f4c18c --- /dev/null +++ b/ArmPlatformPkg/Sec/AArch64/SecEntryPoint.S @@ -0,0 +1,146 @@ +// +// 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 "SecInternal.h" + +.text +.align 3 + +GCC_ASM_IMPORT(CEntryPoint) +GCC_ASM_IMPORT(ArmPlatformIsPrimaryCore) +GCC_ASM_IMPORT(ArmPlatformGetCorePosition) +GCC_ASM_IMPORT(ArmPlatformSecBootAction) +GCC_ASM_IMPORT(ArmPlatformSecBootMemoryInit) +GCC_ASM_IMPORT(ArmDisableInterrupts) +GCC_ASM_IMPORT(ArmDisableCachesAndMmu) +GCC_ASM_IMPORT(ArmReadMpidr) +GCC_ASM_IMPORT(ArmCallWFE) +GCC_ASM_EXPORT(_ModuleEntryPoint) + +StartupAddr: .dword ASM_PFX(CEntryPoint) + +ASM_PFX(_ModuleEntryPoint): + +// 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. + +// Sec only runs in EL3. Othewise we jump to PEI without changing anything. +// If Sec runs we change to EL2 before switching to PEI. + +// Which EL are we running at? Every EL needs some level of setup... + EL1_OR_EL2_OR_EL3(x0) +1:// If we are at EL1 or EL2 leave SEC for PEI. +2:b ASM_PFX(JumpToPEI) + // If we are at EL3 we need to configure it and switch to EL2 +3:b ASM_PFX(MainEntryPoint) + +ASM_PFX(MainEntryPoint): + // First ensure all interrupts are disabled + bl ASM_PFX(ArmDisableInterrupts) + + // Ensure that the MMU and caches are off + bl ASM_PFX(ArmDisableCachesAndMmu) + + // By default, we are doing a cold boot + mov x10, #ARM_SEC_COLD_BOOT + + // Jump to Platform Specific Boot Action function + bl ASM_PFX(ArmPlatformSecBootAction) + +_IdentifyCpu: + // 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) + cmp x0, #1 + // Only the primary core initialize the memory (SMC) + b.eq _InitMem + +_WaitInitMem: + // If we are not doing a cold boot in this case we should assume the Initial Memory to be already initialized + // Otherwise we have to wait the Primary Core to finish the initialization + cmp x10, #ARM_SEC_COLD_BOOT + b.ne _SetupSecondaryCoreStack + + // Wait for the primary core to initialize the initial memory (event: BOOT_MEM_INIT) + bl ASM_PFX(ArmCallWFE) + // Now the Init Mem is initialized, we setup the secondary core stacks + b _SetupSecondaryCoreStack + +_InitMem: + // If we are not doing a cold boot in this case we should assume the Initial Memory to be already initialized + cmp x10, #ARM_SEC_COLD_BOOT + b.ne _SetupPrimaryCoreStack + + // Initialize Init Boot Memory + bl ASM_PFX(ArmPlatformSecBootMemoryInit) + +_SetupPrimaryCoreStack: + // Get the top of the primary stacks (and the base of the secondary stacks) + LoadConstantToReg (FixedPcdGet32(PcdCPUCoresSecStackBase), x1) + LoadConstantToReg (FixedPcdGet32(PcdCPUCoreSecPrimaryStackSize), x2) + add x1, x1, x2 + + LoadConstantToReg (FixedPcdGet32(PcdSecGlobalVariableSize), x2) + + // The reserved space for global variable must be 8-bytes aligned for pushing + // 64-bit variable on the stack + SetPrimaryStack (x1, x2, x3, x4) + b _PrepareArguments + +_SetupSecondaryCoreStack: + // Get the top of the primary stacks (and the base of the secondary stacks) + LoadConstantToReg (FixedPcdGet32(PcdCPUCoresSecStackBase), x1) + LoadConstantToReg (FixedPcdGet32(PcdCPUCoreSecPrimaryStackSize), x2) + add x6, x1, x2 + + // Get the Core Position + 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(PcdCPUCoreSecSecondaryStackSize), x2) + mul x0, x0, x2 + // SP = StackBase + StackOffset + add sp, x6, x0 + +_PrepareArguments: + // 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 SEC C code + // r0 = mp_id + // r1 = Boot Mode + mov x0, x5 + mov x1, x10 + blr x3 + + ret + +ASM_PFX(JumpToPEI): + LoadConstantToReg (FixedPcdGet32(PcdFvBaseAddress), x0) + blr x0 + +dead: + b dead diff --git a/ArmPlatformPkg/Sec/Sec.inf b/ArmPlatformPkg/Sec/Sec.inf index 8e64a73142..dc1c4f2bee 100644 --- a/ArmPlatformPkg/Sec/Sec.inf +++ b/ArmPlatformPkg/Sec/Sec.inf @@ -1,7 +1,7 @@ #/** @file -# SEC - Reset vector code that jumps to C and loads DXE core +# SEC - Reset vector code that jumps to C and starts the PEI phase # -# Copyright (c) 2011-2012, ARM Limited. All rights reserved. +# 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 @@ -29,6 +29,10 @@ Arm/SecEntryPoint.S | GCC Arm/SecEntryPoint.asm | RVCT +[Sources.AARCH64] + AArch64/Helper.S | GCC + AArch64/SecEntryPoint.S | GCC + [Packages] MdePkg/MdePkg.dec MdeModulePkg/MdeModulePkg.dec