diff --git a/ArmPlatformPkg/PrePi/Exception.S b/ArmPlatformPkg/PrePi/Exception.S new file mode 100755 index 0000000000..628793e031 --- /dev/null +++ b/ArmPlatformPkg/PrePi/Exception.S @@ -0,0 +1,102 @@ +// +// Copyright (c) 2011, 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 <AsmMacroIoLib.h> +#include <Base.h> +#include <AutoGen.h> + +#start of the code section +.text +.align 5 + +# IMPORT +GCC_ASM_IMPORT(PrePiCommonExceptionEntry) + +# EXPORT +GCC_ASM_EXPORT(PrePiVectorTable) + +//============================================================ +//Default Exception Handlers +//============================================================ + + +ASM_PFX(PrePiVectorTable): + b _DefaultResetHandler + b _DefaultUndefined + b _DefaultSWI + b _DefaultPrefetchAbort + b _DefaultDataAbort + b _DefaultReserved + b _DefaultIrq + b _DefaultFiq + +// +// Default Exception handlers: There is no plan to return from any of these exceptions. +// No context saving at all. +// +_DefaultResetHandler: + mov r1, lr + # Switch to SVC for common stack + cps #0x13 + mov r0, #0 + blx ASM_PFX(PrePiCommonExceptionEntry) + +_DefaultUndefined: + sub r1, LR, #4 + # Switch to SVC for common stack + cps #0x13 + mov r0, #1 + blx ASM_PFX(PrePiCommonExceptionEntry) + +_DefaultSWI: + sub r1, LR, #4 + # Switch to SVC for common stack + cps #0x13 + mov r0, #2 + blx ASM_PFX(PrePiCommonExceptionEntry) + +_DefaultPrefetchAbort: + sub r1, LR, #4 + # Switch to SVC for common stack + cps #0x13 + mov r0, #3 + blx ASM_PFX(PrePiCommonExceptionEntry) + +_DefaultDataAbort: + sub r1, LR, #8 + # Switch to SVC for common stack + cps #0x13 + mov r0, #4 + blx ASM_PFX(PrePiCommonExceptionEntry) + +_DefaultReserved: + mov r1, lr + # Switch to SVC for common stack + cps #0x13 + mov r0, #5 + blx ASM_PFX(PrePiCommonExceptionEntry) + +_DefaultIrq: + sub r1, LR, #4 + # Switch to SVC for common stack + cps #0x13 + mov r0, #6 + blx ASM_PFX(PrePiCommonExceptionEntry) + +_DefaultFiq: + sub r1, LR, #4 + # Switch to SVC for common stack + cps #0x13 + mov r0, #7 + blx ASM_PFX(PrePiCommonExceptionEntry) + diff --git a/ArmPlatformPkg/PrePi/Exception.asm b/ArmPlatformPkg/PrePi/Exception.asm new file mode 100644 index 0000000000..26f41d19e0 --- /dev/null +++ b/ArmPlatformPkg/PrePi/Exception.asm @@ -0,0 +1,91 @@ +// +// Copyright (c) 2011, 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 <AsmMacroIoLib.h> +#include <Base.h> +#include <AutoGen.h> + + IMPORT PrePiCommonExceptionEntry + EXPORT PrePiVectorTable + + PRESERVE8 + AREA PrePeiCoreException, CODE, READONLY, CODEALIGN, ALIGN=5 + +//============================================================ +//Default Exception Handlers +//============================================================ +//TODO: there should be better way to handle the exceptions during the early stage. At the moment they are spinning in infinite loop + +PrePiVectorTable + b _DefaultResetHandler + b _DefaultUndefined + b _DefaultSWI + b _DefaultPrefetchAbort + b _DefaultDataAbort + b _DefaultReserved + b _DefaultIrq + b _DefaultFiq + +// +// Default Exception handlers: There is no plan to return from any of these exceptions. +// No context saving at all. +// +_DefaultResetHandler + mov r1, lr + cps #0x13 ; Switch to SVC for common stack + mov r0, #0 + blx PrePiCommonExceptionEntry + +_DefaultUndefined + sub r1, LR, #4 + cps #0x13 ; Switch to SVC for common stack + mov r0, #1 + blx PrePiCommonExceptionEntry + +_DefaultSWI + sub r1, LR, #4 + cps #0x13 ; Switch to SVC for common stack + mov r0, #2 + blx PrePiCommonExceptionEntry + +_DefaultPrefetchAbort + sub r1, LR, #4 + cps #0x13 ; Switch to SVC for common stack + mov r0, #3 + blx PrePiCommonExceptionEntry + +_DefaultDataAbort + sub r1, LR, #8 + cps #0x13 ; Switch to SVC for common stack + mov r0, #4 + blx PrePiCommonExceptionEntry + +_DefaultReserved + mov r1, lr + cps #0x13 ; Switch to SVC for common stack + mov r0, #5 + blx PrePiCommonExceptionEntry + +_DefaultIrq + sub r1, LR, #4 + cps #0x13 ; Switch to SVC for common stack + mov r0, #6 + blx PrePiCommonExceptionEntry + +_DefaultFiq + sub r1, LR, #4 + cps #0x13 ; Switch to SVC for common stack + mov r0, #7 + blx PrePiCommonExceptionEntry + + END diff --git a/ArmPlatformPkg/PrePi/LzmaDecompress.h b/ArmPlatformPkg/PrePi/LzmaDecompress.h new file mode 100644 index 0000000000..e4483b6823 --- /dev/null +++ b/ArmPlatformPkg/PrePi/LzmaDecompress.h @@ -0,0 +1,103 @@ +/** @file + LZMA Decompress Library header file + + Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR> + 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. + +**/ + +#ifndef __LZMA_DECOMPRESS_H___ +#define __LZMA_DECOMPRESS_H___ + +/** + Examines a GUIDed section and returns the size of the decoded buffer and the + size of an scratch buffer required to actually decode the data in a GUIDed section. + + Examines a GUIDed section specified by InputSection. + If GUID for InputSection does not match the GUID that this handler supports, + then RETURN_UNSUPPORTED is returned. + If the required information can not be retrieved from InputSection, + then RETURN_INVALID_PARAMETER is returned. + If the GUID of InputSection does match the GUID that this handler supports, + then the size required to hold the decoded buffer is returned in OututBufferSize, + the size of an optional scratch buffer is returned in ScratchSize, and the Attributes field + from EFI_GUID_DEFINED_SECTION header of InputSection is returned in SectionAttribute. + + If InputSection is NULL, then ASSERT(). + If OutputBufferSize is NULL, then ASSERT(). + If ScratchBufferSize is NULL, then ASSERT(). + If SectionAttribute is NULL, then ASSERT(). + + + @param[in] InputSection A pointer to a GUIDed section of an FFS formatted file. + @param[out] OutputBufferSize A pointer to the size, in bytes, of an output buffer required + if the buffer specified by InputSection were decoded. + @param[out] ScratchBufferSize A pointer to the size, in bytes, required as scratch space + if the buffer specified by InputSection were decoded. + @param[out] SectionAttribute A pointer to the attributes of the GUIDed section. See the Attributes + field of EFI_GUID_DEFINED_SECTION in the PI Specification. + + @retval RETURN_SUCCESS The information about InputSection was returned. + @retval RETURN_UNSUPPORTED The section specified by InputSection does not match the GUID this handler supports. + @retval RETURN_INVALID_PARAMETER The information can not be retrieved from the section specified by InputSection. + +**/ +RETURN_STATUS +EFIAPI +LzmaGuidedSectionGetInfo ( + IN CONST VOID *InputSection, + OUT UINT32 *OutputBufferSize, + OUT UINT32 *ScratchBufferSize, + OUT UINT16 *SectionAttribute + ); + +/** + Decompress a LZAM compressed GUIDed section into a caller allocated output buffer. + + Decodes the GUIDed section specified by InputSection. + If GUID for InputSection does not match the GUID that this handler supports, then RETURN_UNSUPPORTED is returned. + If the data in InputSection can not be decoded, then RETURN_INVALID_PARAMETER is returned. + If the GUID of InputSection does match the GUID that this handler supports, then InputSection + is decoded into the buffer specified by OutputBuffer and the authentication status of this + decode operation is returned in AuthenticationStatus. If the decoded buffer is identical to the + data in InputSection, then OutputBuffer is set to point at the data in InputSection. Otherwise, + the decoded data will be placed in caller allocated buffer specified by OutputBuffer. + + If InputSection is NULL, then ASSERT(). + If OutputBuffer is NULL, then ASSERT(). + If ScratchBuffer is NULL and this decode operation requires a scratch buffer, then ASSERT(). + If AuthenticationStatus is NULL, then ASSERT(). + + + @param[in] InputSection A pointer to a GUIDed section of an FFS formatted file. + @param[out] OutputBuffer A pointer to a buffer that contains the result of a decode operation. + @param[out] ScratchBuffer A caller allocated buffer that may be required by this function + as a scratch buffer to perform the decode operation. + @param[out] AuthenticationStatus + A pointer to the authentication status of the decoded output buffer. + See the definition of authentication status in the EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI + section of the PI Specification. EFI_AUTH_STATUS_PLATFORM_OVERRIDE must + never be set by this handler. + + @retval RETURN_SUCCESS The buffer specified by InputSection was decoded. + @retval RETURN_UNSUPPORTED The section specified by InputSection does not match the GUID this handler supports. + @retval RETURN_INVALID_PARAMETER The section specified by InputSection can not be decoded. + +**/ +RETURN_STATUS +EFIAPI +LzmaGuidedSectionExtraction ( + IN CONST VOID *InputSection, + OUT VOID **OutputBuffer, + OUT VOID *ScratchBuffer, OPTIONAL + OUT UINT32 *AuthenticationStatus + ); + +#endif // __LZMADECOMPRESS_H__ + diff --git a/ArmPlatformPkg/PrePi/MainMPCore.c b/ArmPlatformPkg/PrePi/MainMPCore.c new file mode 100644 index 0000000000..238b919e29 --- /dev/null +++ b/ArmPlatformPkg/PrePi/MainMPCore.c @@ -0,0 +1,68 @@ +/** @file +* +* Copyright (c) 2011, 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 <Library/ArmMPCoreMailBoxLib.h> +#include <Chipset/ArmV7.h> +#include <Drivers/PL390Gic.h> + +VOID +PrimaryMain ( + IN UINTN UefiMemoryBase, + IN UINTN StackBase, + IN UINT64 StartTimeStamp + ) +{ + //Enable the GIC Distributor + PL390GicEnableDistributor(PcdGet32(PcdGicDistributorBase)); + + // If ArmVe has not been built as Standalone then we need to wake up the secondary cores + if (!FixedPcdGet32(PcdStandalone)) { + // Sending SGI to all the Secondary CPU interfaces + PL390GicSendSgiTo (PcdGet32(PcdGicDistributorBase), GIC_ICDSGIR_FILTER_EVERYONEELSE, 0x0E); + } + + PrePiMain (UefiMemoryBase, StackBase, StartTimeStamp); + + // We must never return + ASSERT(FALSE); +} + +VOID +SecondaryMain ( + IN UINTN CoreId + ) +{ + // Function pointer to Secondary Core entry point + VOID (*secondary_start)(VOID); + UINTN secondary_entry_addr=0; + + // Clear Secondary cores MailBox + ArmClearMPCoreMailbox(); + + while (secondary_entry_addr = ArmGetMPCoreMailbox(), secondary_entry_addr == 0) { + ArmCallWFI(); + // Acknowledge the interrupt and send End of Interrupt signal. + PL390GicAcknowledgeSgiFrom(PcdGet32(PcdGicInterruptInterfaceBase),0/*CoreId*/); + } + + secondary_start = (VOID (*)())secondary_entry_addr; + + // Jump to secondary core entry point. + secondary_start(); + + // The secondaries shouldn't reach here + ASSERT(FALSE); +} diff --git a/ArmPlatformPkg/PrePi/MainUniCore.c b/ArmPlatformPkg/PrePi/MainUniCore.c new file mode 100644 index 0000000000..f8ce408f6d --- /dev/null +++ b/ArmPlatformPkg/PrePi/MainUniCore.c @@ -0,0 +1,38 @@ +/** @file +* +* Copyright (c) 2011, 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 +PrimaryMain ( + IN UINTN UefiMemoryBase, + IN UINTN StackBase, + IN UINT64 StartTimeStamp + ) +{ + PrePiMain (UefiMemoryBase, StackBase, StartTimeStamp); + + // We must never return + ASSERT(FALSE); +} + +VOID +SecondaryMain ( + IN UINTN CoreId + ) +{ + // We must never get into this function on UniCore system + ASSERT(FALSE); +} + diff --git a/ArmPlatformPkg/PrePi/ModuleEntryPoint.S b/ArmPlatformPkg/PrePi/ModuleEntryPoint.S new file mode 100755 index 0000000000..0857024a27 --- /dev/null +++ b/ArmPlatformPkg/PrePi/ModuleEntryPoint.S @@ -0,0 +1,84 @@ +// +// Copyright (c) 2011, 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 <AsmMacroIoLib.h> +#include <Base.h> +#include <Library/PcdLib.h> +#include <AutoGen.h> + +#start of the code section +.text +.align 3 + +#global symbols referenced by this module +GCC_ASM_IMPORT(CEntryPoint) + +StartupAddr: .word CEntryPoint + +#make _ModuleEntryPoint as global +GCC_ASM_EXPORT(_ModuleEntryPoint) + + +ASM_PFX(_ModuleEntryPoint): + // Identify CPU ID + mrc p15, 0, r0, c0, c0, 5 + and r0, #0xf + +_UefiMemoryBase: +#if FixedPcdGet32(PcdStandalone) + // Compute Top of System Memory + LoadConstantToReg (FixedPcdGet32(PcdSystemMemoryBase), r1) + LoadConstantToReg (FixedPcdGet32(PcdSystemMemorySize), r2) + add r1, r1, r2 // r1 = SystemMemoryTop = PcdSystemMemoryBase + PcdSystemMemorySize +#else + // If it is not a Standalone, we must compute the top of the UEFI memory with the base of the FD + LoadConstantToReg (FixedPcdGet32(PcdNormalFdBaseAddress), r1) +#endif + + // Compute Base of UEFI Memory + LoadConstantToReg (FixedPcdGet32(PcdSystemMemoryUefiRegionSize), r2) + sub r1, r1, r2 // r1 = SystemMemoryTop - PcdSystemMemoryUefiRegionSize = UefiMemoryBase + +_SetupStack: + // Compute Base of Normal stacks for CPU Cores + LoadConstantToReg (FixedPcdGet32(PcdCPUCoresNonSecStackSize), r2) + mul r3, r0, r2 // r3 = core_id * stack_size = offset from the stack base + sub sp, r1, r3 // r3 = UefiMemoryBase - StackOffset = TopOfStack + + // Only allocate memory in top of the primary core stack + cmp r0, #0 + bne _PrepareArguments + +_AllocateGlobalPeiVariables: + // Reserve top of the stack for Global PEI Variables (eg: PeiServicesTablePointer) + LoadConstantToReg (FixedPcdGet32(PcdPeiGlobalVariableSize), r4) + // The reserved place must be 8-bytes aligned for pushing 64-bit variable on the stack + and r5, r4, #7 + rsb r5, r5, #8 + add r4, r4, r5 + sub sp, sp, r4 + +_PrepareArguments: + // Pass the StackBase to the C Entrypoint (UefiMemoryBase - StackSize - StackOffset) + sub r2, r1, r2 + sub r2, r3 + // Move sec startup address into a data register + // Ensure we're jumping to FV version of the code (not boot remapped alias) + ldr r3, StartupAddr + + // jump to PrePiCore C code + // r0 = core_id + // r1 = UefiMemoryBase + // r2 = StackBase + blx r3 + diff --git a/ArmPlatformPkg/PrePi/ModuleEntryPoint.asm b/ArmPlatformPkg/PrePi/ModuleEntryPoint.asm new file mode 100644 index 0000000000..52690f8ecd --- /dev/null +++ b/ArmPlatformPkg/PrePi/ModuleEntryPoint.asm @@ -0,0 +1,82 @@ +// +// Copyright (c) 2011, 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 <AsmMacroIoLib.h> +#include <Base.h> +#include <Library/PcdLib.h> +#include <AutoGen.h> + + INCLUDE AsmMacroIoLib.inc + + IMPORT CEntryPoint + EXPORT _ModuleEntryPoint + + PRESERVE8 + AREA PrePiCoreEntryPoint, CODE, READONLY + +StartupAddr DCD CEntryPoint + +_ModuleEntryPoint + // Identify CPU ID + mrc p15, 0, r0, c0, c0, 5 + and r0, #0xf + +_UefiMemoryBase +#if FixedPcdGet32(PcdStandalone) + // Compute Top of System Memory + LoadConstantToReg (FixedPcdGet32(PcdSystemMemoryBase), r1) + LoadConstantToReg (FixedPcdGet32(PcdSystemMemorySize), r2) + add r1, r1, r2 // r1 = SystemMemoryTop = PcdSystemMemoryBase + PcdSystemMemorySize +#else + // If it is not a Standalone, we must compute the top of the UEFI memory with the base of the FD + LoadConstantToReg (FixedPcdGet32(PcdNormalFdBaseAddress), r1) +#endif + + // Compute Base of UEFI Memory + LoadConstantToReg (FixedPcdGet32(PcdSystemMemoryUefiRegionSize), r2) + sub r1, r1, r2 // r1 = SystemMemoryTop - PcdSystemMemoryUefiRegionSize = UefiMemoryBase + +_SetupStack + // Compute Base of Normal stacks for CPU Cores + LoadConstantToReg (FixedPcdGet32(PcdCPUCoresNonSecStackSize), r2) + mul r3, r0, r2 // r3 = core_id * stack_size = offset from the stack base + sub sp, r1, r3 // r3 = UefiMemoryBase - StackOffset = TopOfStack + + // Only allocate memory in top of the primary core stack + cmp r0, #0 + bne _PrepareArguments + +_AllocateGlobalPrePiVariables + // Reserve top of the stack for Global PEI Variables (eg: PeiServicesTablePointer) + LoadConstantToReg (FixedPcdGet32(PcdPeiGlobalVariableSize), r4) + // The reserved place must be 8-bytes aligned for pushing 64-bit variable on the stack + and r5, r4, #7 + rsb r5, r5, #8 + add r4, r4, r5 + sub sp, sp, r4 + +_PrepareArguments + // Pass the StackBase to the C Entrypoint (UefiMemoryBase - StackSize - StackOffset) + sub r2, r1, r2 + sub r2, r3 + // Move sec startup address into a data register + // Ensure we're jumping to FV version of the code (not boot remapped alias) + ldr r3, StartupAddr + + // jump to PrePiCore C code + // r0 = core_id + // r1 = UefiMemoryBase + // r2 = StackBase + blx r3 + + END diff --git a/ArmPlatformPkg/PrePi/PeiMPCore.inf b/ArmPlatformPkg/PrePi/PeiMPCore.inf new file mode 100755 index 0000000000..256fcafee9 --- /dev/null +++ b/ArmPlatformPkg/PrePi/PeiMPCore.inf @@ -0,0 +1,99 @@ +#/** @file +# +# Copyright (c) 2011, ARM Ltd. All rights reserved.<BR> +# 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. +# +#**/ + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = ArmPlatformPrePiMPCore + FILE_GUID = d959e387-7b91-452c-90e0-a1dbac90ddb8 + MODULE_TYPE = SEC + VERSION_STRING = 1.0 + +[Sources.ARM] + PrePi.c + ModuleEntryPoint.S | GCC + ModuleEntryPoint.asm | RVCT + Exception.S | GCC + Exception.asm | RVCT + MainMPCore.c + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + EmbeddedPkg/EmbeddedPkg.dec + ArmPkg/ArmPkg.dec + ArmPlatformPkg/ArmPlatformPkg.dec + IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec + +[LibraryClasses] + BaseLib + DebugLib + DebugAgentLib + ArmLib + ArmMPCoreMailBoxLib + PL390GicNonSecLib + IoLib + TimerLib + SerialPortLib + ExtractGuidedSectionLib + LzmaDecompressLib + PeCoffGetEntryPointLib + DebugAgentLib + PrePiLib + ArmPlatformLib + MemoryAllocationLib + HobLib + PrePiHobListPointerLib + PlatformPeiLib + MemoryInitPeiLib + +[FeaturePcd] + gEmbeddedTokenSpaceGuid.PcdCacheEnable + gEmbeddedTokenSpaceGuid.PcdPrePiProduceMemoryTypeInformationHob + +[FixedPcd] + gArmPlatformTokenSpaceGuid.PcdStandalone + gArmTokenSpaceGuid.PcdVFPEnabled + + gArmTokenSpaceGuid.PcdNormalFdBaseAddress + gArmTokenSpaceGuid.PcdNormalFdSize + + gArmTokenSpaceGuid.PcdNormalFvBaseAddress + gArmTokenSpaceGuid.PcdNormalFvSize + + gArmPlatformTokenSpaceGuid.PcdCPUCoresNonSecStackBase + gArmPlatformTokenSpaceGuid.PcdCPUCoresNonSecStackSize + + gArmPlatformTokenSpaceGuid.PcdPeiGlobalVariableSize + gArmPlatformTokenSpaceGuid.PcdHobListPtrGlobalOffset + + gArmTokenSpaceGuid.PcdGicDistributorBase + gArmTokenSpaceGuid.PcdGicInterruptInterfaceBase + + gArmTokenSpaceGuid.PcdSystemMemoryBase + gArmTokenSpaceGuid.PcdSystemMemorySize + gArmPlatformTokenSpaceGuid.PcdSystemMemoryFixRegionSize + gArmPlatformTokenSpaceGuid.PcdSystemMemoryUefiRegionSize + + gEmbeddedTokenSpaceGuid.PcdPrePiCpuMemorySize + gEmbeddedTokenSpaceGuid.PcdPrePiCpuIoSize + + gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiACPIReclaimMemory + gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiACPIMemoryNVS + gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiReservedMemoryType + gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiRuntimeServicesData + gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiRuntimeServicesCode + gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiBootServicesCode + gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiBootServicesData + gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiLoaderCode + gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiLoaderData + diff --git a/ArmPlatformPkg/PrePi/PeiUniCore.inf b/ArmPlatformPkg/PrePi/PeiUniCore.inf new file mode 100755 index 0000000000..c28fe3c6cb --- /dev/null +++ b/ArmPlatformPkg/PrePi/PeiUniCore.inf @@ -0,0 +1,93 @@ +#/** @file +# +# Copyright (c) 2011, ARM Ltd. All rights reserved.<BR> +# 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. +# +#**/ + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = ArmPlatformPrePiUniCore + FILE_GUID = d959e387-7b91-452c-90e0-a1dbac90ddb8 + MODULE_TYPE = SEC + VERSION_STRING = 1.0 + +[Sources.ARM] + PrePi.c + ModuleEntryPoint.S | GCC + ModuleEntryPoint.asm | RVCT + Exception.asm | RVCT + Exception.S | GCC + MainUniCore.c + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + EmbeddedPkg/EmbeddedPkg.dec + ArmPkg/ArmPkg.dec + ArmPlatformPkg/ArmPlatformPkg.dec + IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec + +[LibraryClasses] + BaseLib + DebugLib + DebugAgentLib + ArmLib + IoLib + TimerLib + SerialPortLib + ExtractGuidedSectionLib + LzmaDecompressLib + PeCoffGetEntryPointLib + DebugAgentLib + PrePiLib + ArmPlatformLib + MemoryAllocationLib + HobLib + PrePiHobListPointerLib + PlatformPeiLib + MemoryInitPeiLib + +[FeaturePcd] + gEmbeddedTokenSpaceGuid.PcdCacheEnable + gEmbeddedTokenSpaceGuid.PcdPrePiProduceMemoryTypeInformationHob + +[FixedPcd] + gArmPlatformTokenSpaceGuid.PcdStandalone + gArmTokenSpaceGuid.PcdVFPEnabled + + gArmTokenSpaceGuid.PcdNormalFdBaseAddress + gArmTokenSpaceGuid.PcdNormalFdSize + + gArmTokenSpaceGuid.PcdNormalFvBaseAddress + gArmTokenSpaceGuid.PcdNormalFvSize + + gArmPlatformTokenSpaceGuid.PcdCPUCoresNonSecStackBase + gArmPlatformTokenSpaceGuid.PcdCPUCoresNonSecStackSize + + gArmPlatformTokenSpaceGuid.PcdPeiGlobalVariableSize + gArmPlatformTokenSpaceGuid.PcdHobListPtrGlobalOffset + + gArmTokenSpaceGuid.PcdSystemMemoryBase + gArmTokenSpaceGuid.PcdSystemMemorySize + gArmPlatformTokenSpaceGuid.PcdSystemMemoryFixRegionSize + gArmPlatformTokenSpaceGuid.PcdSystemMemoryUefiRegionSize + + gEmbeddedTokenSpaceGuid.PcdPrePiCpuMemorySize + gEmbeddedTokenSpaceGuid.PcdPrePiCpuIoSize + + gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiACPIReclaimMemory + gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiACPIMemoryNVS + gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiReservedMemoryType + gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiRuntimeServicesData + gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiRuntimeServicesCode + gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiBootServicesCode + gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiBootServicesData + gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiLoaderCode + gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiLoaderData diff --git a/ArmPlatformPkg/PrePi/PrePi.c b/ArmPlatformPkg/PrePi/PrePi.c new file mode 100755 index 0000000000..501821465a --- /dev/null +++ b/ArmPlatformPkg/PrePi/PrePi.c @@ -0,0 +1,213 @@ +/** @file +* +* Copyright (c) 2011, 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 <PiPei.h> + +#include <Library/DebugAgentLib.h> +#include <Library/PrePiLib.h> +#include <Library/IoLib.h> +#include <Library/PrintLib.h> +#include <Library/PeCoffGetEntryPointLib.h> +#include <Library/TimerLib.h> +#include <Library/PerformanceLib.h> + +#include <Ppi/GuidedSectionExtraction.h> +#include <Guid/LzmaDecompress.h> + +#include "PrePi.h" +#include "LzmaDecompress.h" + +VOID +PrePiCommonExceptionEntry ( + IN UINT32 Entry, + IN UINT32 LR + ); + +EFI_STATUS +EFIAPI +ExtractGuidedSectionLibConstructor ( + VOID + ); + +EFI_STATUS +EFIAPI +LzmaDecompressLibConstructor ( + VOID + ); + +VOID +PrePiMain ( + IN UINTN UefiMemoryBase, + IN UINTN StackBase, + IN UINT64 StartTimeStamp + ) +{ + EFI_HOB_HANDOFF_INFO_TABLE** PrePiHobBase; + EFI_STATUS Status; + CHAR8 Buffer[100]; + UINTN CharCount; + + // Enable program flow prediction, if supported. + ArmEnableBranchPrediction (); + + if (FixedPcdGet32(PcdVFPEnabled)) { + ArmEnableVFP(); + } + + // Initialize the Serial Port + SerialPortInitialize (); + CharCount = AsciiSPrint (Buffer,sizeof (Buffer),"UEFI firmware built at %a on %a\n\r",__TIME__, __DATE__); + SerialPortWrite ((UINT8 *) Buffer, CharCount); + + // Initialize the Debug Agent for Source Level Debugging + InitializeDebugAgent (DEBUG_AGENT_INIT_POSTMEM_SEC, NULL, NULL); + SaveAndSetDebugTimerInterrupt (TRUE); + + PrePiHobBase = (EFI_HOB_HANDOFF_INFO_TABLE**)(PcdGet32 (PcdCPUCoresNonSecStackBase) + (PcdGet32 (PcdCPUCoresNonSecStackSize) / 2) - PcdGet32 (PcdHobListPtrGlobalOffset)); + + // We leave UINT32 at the top of UEFI memory for PcdPrePiHobBase + *PrePiHobBase = HobConstructor ( + (VOID*)UefiMemoryBase, + FixedPcdGet32 (PcdSystemMemoryUefiRegionSize), + (VOID*)UefiMemoryBase, + (VOID*)(UefiMemoryBase + FixedPcdGet32 (PcdSystemMemoryUefiRegionSize) - sizeof(UINT32))); + + // Initialize MMU and Memory HOBs (Resource Descriptor HOBs) + Status = MemoryPeim (UefiMemoryBase, FixedPcdGet32 (PcdSystemMemoryUefiRegionSize)); + ASSERT_EFI_ERROR (Status); + + // Create the Stack HOB + BuildStackHob (StackBase, FixedPcdGet32(PcdCPUCoresNonSecStackSize)); + + // Set the Boot Mode + SetBootMode (ArmPlatformGetBootMode ()); + + // Initialize Platform HOBs (CpuHob and FvHob) + Status = PlatformPeim (); + ASSERT_EFI_ERROR (Status); + + BuildMemoryTypeInformationHob (); + + //InitializeDebugAgent (DEBUG_AGENT_INIT_PREMEM_SEC, NULL, NULL); + //SaveAndSetDebugTimerInterrupt (TRUE); + + // Now, the HOB List has been initialized, we can register performance information + PERF_START (NULL, "PEI", NULL, StartTimeStamp); + + // SEC phase needs to run library constructors by hand. + ExtractGuidedSectionLibConstructor (); + LzmaDecompressLibConstructor (); + + // Build HOBs to pass up our version of stuff the DXE Core needs to save space + BuildPeCoffLoaderHob (); + BuildExtractSectionHob ( + &gLzmaCustomDecompressGuid, + LzmaGuidedSectionGetInfo, + LzmaGuidedSectionExtraction + ); + + // Assume the FV that contains the SEC (our code) also contains a compressed FV. + Status = DecompressFirstFv (); + ASSERT_EFI_ERROR (Status); + + // Load the DXE Core and transfer control to it + Status = LoadDxeCoreFromFv (NULL, 0); + ASSERT_EFI_ERROR (Status); +} + +VOID +CEntryPoint ( + IN UINTN CoreId, + IN UINTN UefiMemoryBase, + IN UINTN StackBase + ) +{ + UINT64 StartTimeStamp; + + if ((CoreId == 0) && PerformanceMeasurementEnabled ()) { + // Initialize the Timer Library to setup the Timer HW controller + TimerConstructor (); + // We cannot call yet the PerformanceLib because the HOB List has not been initialized + StartTimeStamp = GetPerformanceCounter (); + } + + //Clean Data cache + ArmCleanInvalidateDataCache(); + + //Invalidate instruction cache + ArmInvalidateInstructionCache(); + + //TODO:Drain Write Buffer + + // Enable Instruction & Data caches + ArmEnableDataCache(); + ArmEnableInstructionCache(); + + // Write VBAR - The Vector table must be 32-byte aligned + ASSERT(((UINT32)PrePiVectorTable & ((1 << 5)-1)) == 0); + ArmWriteVBar((UINT32)PrePiVectorTable); + + //If not primary Jump to Secondary Main + if(0 == CoreId) { + // Goto primary Main. + PrimaryMain (UefiMemoryBase, StackBase, StartTimeStamp); + } else { + SecondaryMain (CoreId); + } + + // DXE Core should always load and never return + ASSERT (FALSE); +} + +VOID +PrePiCommonExceptionEntry ( + IN UINT32 Entry, + IN UINT32 LR + ) +{ + CHAR8 Buffer[100]; + UINTN CharCount; + + switch (Entry) { + case 0: + CharCount = AsciiSPrint (Buffer,sizeof (Buffer),"Reset Exception at 0x%X\n\r",LR); + break; + case 1: + CharCount = AsciiSPrint (Buffer,sizeof (Buffer),"Undefined Exception at 0x%X\n\r",LR); + break; + case 2: + CharCount = AsciiSPrint (Buffer,sizeof (Buffer),"SWI Exception at 0x%X\n\r",LR); + break; + case 3: + CharCount = AsciiSPrint (Buffer,sizeof (Buffer),"PrefetchAbort Exception at 0x%X\n\r",LR); + break; + case 4: + CharCount = AsciiSPrint (Buffer,sizeof (Buffer),"DataAbort Exception at 0x%X\n\r",LR); + break; + case 5: + CharCount = AsciiSPrint (Buffer,sizeof (Buffer),"Reserved Exception at 0x%X\n\r",LR); + break; + case 6: + CharCount = AsciiSPrint (Buffer,sizeof (Buffer),"IRQ Exception at 0x%X\n\r",LR); + break; + case 7: + CharCount = AsciiSPrint (Buffer,sizeof (Buffer),"FIQ 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/PrePi/PrePi.h b/ArmPlatformPkg/PrePi/PrePi.h new file mode 100644 index 0000000000..b1d39c669a --- /dev/null +++ b/ArmPlatformPkg/PrePi/PrePi.h @@ -0,0 +1,82 @@ +/** @file +* +* Copyright (c) 2011, 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. +* +**/ + +#ifndef _PREPI_H_ +#define _PREPI_H_ + +#include <PiPei.h> + +#include <Library/PcdLib.h> +#include <Library/ArmLib.h> +#include <Library/DebugLib.h> +#include <Library/MemoryAllocationLib.h> +#include <Library/HobLib.h> +#include <Library/SerialPortLib.h> +#include <Library/ArmPlatformLib.h> + +#include <Chipset/ArmV7.h> + +#define SerialPrint(txt) SerialPortWrite (txt, AsciiStrLen(txt)+1); + +// Vector Table for PrePi Phase +VOID +PrePiVectorTable ( + VOID + ); + +RETURN_STATUS +EFIAPI +TimerConstructor ( + VOID + ); + +VOID +PrePiMain ( + IN UINTN UefiMemoryBase, + IN UINTN StackBase, + IN UINT64 StartTimeStamp + ); + +EFI_STATUS +EFIAPI +MemoryPeim ( + IN EFI_PHYSICAL_ADDRESS UefiMemoryBase, + IN UINT64 UefiMemorySize + ); + +EFI_STATUS +EFIAPI +PlatformPeim ( + VOID + ); + +VOID +PrimaryMain ( + IN UINTN UefiMemoryBase, + IN UINTN StackBase, + IN UINT64 StartTimeStamp + ); + +VOID +SecondaryMain ( + IN UINTN CoreId + ); + +// Either implemented by PrePiLib or by MemoryInitPei +VOID +BuildMemoryTypeInformationHob ( + VOID + ); + +#endif /* _PREPI_H_ */