/** @file * * Copyright (c) 2011-2023, Arm Limited. All rights reserved. * * SPDX-License-Identifier: BSD-2-Clause-Patent * **/ #include #include #include #include #include #include #include #include #include #include #include #include "PrePi.h" VOID PrePiMain ( IN UINTN UefiMemoryBase, IN UINTN StacksBase, IN UINT64 StartTimeStamp ) { EFI_HOB_HANDOFF_INFO_TABLE *HobList; EFI_STATUS Status; CHAR8 Buffer[100]; UINTN CharCount; UINTN StacksSize; // Initialize the architecture specific bits ArchInitialize (); // Declare the PI/UEFI memory region HobList = HobConstructor ( (VOID *)UefiMemoryBase, FixedPcdGet32 (PcdSystemMemoryUefiRegionSize), (VOID *)UefiMemoryBase, (VOID *)StacksBase // The top of the UEFI Memory is reserved for the stacks ); PrePeiSetHobList (HobList); // // Ensure that the loaded image is invalidated in the caches, so that any // modifications we made with the caches and MMU off (such as the applied // relocations) don't become invisible once we turn them on. // InvalidateDataCacheRange ((VOID *)(UINTN)PcdGet64 (PcdFdBaseAddress), PcdGet32 (PcdFdSize)); // SEC phase needs to run library constructors by hand. ProcessLibraryConstructorList (); // Initialize MMU and Memory HOBs (Resource Descriptor HOBs) Status = MemoryPeim (UefiMemoryBase, FixedPcdGet32 (PcdSystemMemoryUefiRegionSize)); ASSERT_EFI_ERROR (Status); // Initialize the Serial Port SerialPortInitialize (); CharCount = AsciiSPrint ( Buffer, sizeof (Buffer), "UEFI firmware (version %s built at %a on %a)\n\r", (CHAR16 *)PcdGetPtr (PcdFirmwareVersionString), __TIME__, __DATE__ ); SerialPortWrite ((UINT8 *)Buffer, CharCount); // Create the Stacks HOB (reserve the memory for all stacks) StacksSize = PcdGet32 (PcdCPUCorePrimaryStackSize); BuildStackHob (StacksBase, StacksSize); // TODO: Call CpuPei as a library BuildCpuHob (ArmGetPhysicalAddressBits (), PcdGet8 (PcdPrePiCpuIoSize)); // Set the Boot Mode SetBootMode (BOOT_WITH_FULL_CONFIGURATION); // Initialize Platform HOBs (CpuHob and FvHob) Status = PlatformPeim (); ASSERT_EFI_ERROR (Status); // Now, the HOB List has been initialized, we can register performance information PERF_START (NULL, "PEI", NULL, StartTimeStamp); // 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, SIZE_128KB); ASSERT_EFI_ERROR (Status); } VOID CEntryPoint ( IN UINTN MpId, IN UINTN UefiMemoryBase, IN UINTN StacksBase ) { UINT64 StartTimeStamp; if (PerformanceMeasurementEnabled ()) { // We cannot call yet the PerformanceLib because the HOB List has not been initialized StartTimeStamp = GetPerformanceCounter (); } else { StartTimeStamp = 0; } // Data Cache enabled on Primary core when MMU is enabled. ArmDisableDataCache (); // Invalidate instruction cache ArmInvalidateInstructionCache (); // Enable Instruction Caches on all cores. ArmEnableInstructionCache (); PrePiMain (UefiMemoryBase, StacksBase, StartTimeStamp); // DXE Core should always load and never return ASSERT (FALSE); } VOID RelocatePeCoffImage ( IN EFI_PEI_FV_HANDLE FwVolHeader, IN PE_COFF_LOADER_READ_FILE ImageRead ) { EFI_PEI_FILE_HANDLE FileHandle; VOID *SectionData; PE_COFF_LOADER_IMAGE_CONTEXT ImageContext; EFI_STATUS Status; FileHandle = NULL; Status = FfsFindNextFile ( EFI_FV_FILETYPE_SECURITY_CORE, FwVolHeader, &FileHandle ); ASSERT_EFI_ERROR (Status); Status = FfsFindSectionData (EFI_SECTION_PE32, FileHandle, &SectionData); if (EFI_ERROR (Status)) { Status = FfsFindSectionData (EFI_SECTION_TE, FileHandle, &SectionData); } ASSERT_EFI_ERROR (Status); ZeroMem (&ImageContext, sizeof ImageContext); ImageContext.Handle = (EFI_HANDLE)SectionData; ImageContext.ImageRead = ImageRead; PeCoffLoaderGetImageInfo (&ImageContext); if (ImageContext.ImageAddress != (UINTN)SectionData) { ImageContext.ImageAddress = (UINTN)SectionData; PeCoffLoaderRelocateImage (&ImageContext); } }