-/** @file
-
- Copyright (c) 2008 - 2009, Apple Inc. 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.
-
-**/
-
-#include <PrePi.h>
-
-//
-// Hack to work in NT32
-//
-EFI_STATUS
-
-EFIAPI
-
-SecWinNtPeiLoadFile (
- IN VOID *Pe32Data,
- IN EFI_PHYSICAL_ADDRESS *ImageAddress,
- IN UINT64 *ImageSize,
- IN EFI_PHYSICAL_ADDRESS *EntryPoint
- );
-
-
-EFI_STATUS
-EFIAPI
-LoadPeCoffImage (
- IN VOID *PeCoffImage,
- OUT EFI_PHYSICAL_ADDRESS *ImageAddress,
- OUT UINT64 *ImageSize,
- OUT EFI_PHYSICAL_ADDRESS *EntryPoint
- )
-{
- RETURN_STATUS Status;
- PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;
- VOID *Buffer;
-
- ZeroMem (&ImageContext, sizeof (ImageContext));
-
- ImageContext.Handle = PeCoffImage;
- ImageContext.ImageRead = PeCoffLoaderImageReadFromMemory;
-
- Status = PeCoffLoaderGetImageInfo (&ImageContext);
- ASSERT_EFI_ERROR (Status);
-
-
- //
- // Allocate Memory for the image
- //
- Buffer = AllocatePages (EFI_SIZE_TO_PAGES((UINT32)ImageContext.ImageSize));
- ASSERT (Buffer != 0);
-
-
- ImageContext.ImageAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)Buffer;
-
- //
- // Load the image to our new buffer
- //
- Status = PeCoffLoaderLoadImage (&ImageContext);
- ASSERT_EFI_ERROR (Status);
-
- //
- // Relocate the image in our new buffer
- //
- Status = PeCoffLoaderRelocateImage (&ImageContext);
- ASSERT_EFI_ERROR (Status);
-
-
- *ImageAddress = ImageContext.ImageAddress;
- *ImageSize = ImageContext.ImageSize;
- *EntryPoint = ImageContext.EntryPoint;
-
- //
- // Flush not needed for all architectures. We could have a processor specific
- // function in this library that does the no-op if needed.
- //
- InvalidateInstructionCacheRange ((VOID *)(UINTN)*ImageAddress, (UINTN)*ImageSize);
-
- return Status;
-}
-
-
-
-typedef
-VOID
-(EFIAPI *DXE_CORE_ENTRY_POINT) (
- IN VOID *HobStart
- );
-
-EFI_STATUS
-EFIAPI
-LoadDxeCoreFromFfsFile (
- IN EFI_PEI_FILE_HANDLE FileHandle,
- IN UINTN StackSize
- )
-{
- EFI_STATUS Status;
- VOID *PeCoffImage;
- EFI_PHYSICAL_ADDRESS ImageAddress;
- UINT64 ImageSize;
- EFI_PHYSICAL_ADDRESS EntryPoint;
- VOID *BaseOfStack;
- VOID *TopOfStack;
- VOID *Hob;
- EFI_FV_FILE_INFO FvFileInfo;
-
- Status = FfsFindSectionData (EFI_SECTION_PE32, FileHandle, &PeCoffImage);
- if (EFI_ERROR (Status)) {
- return Status;
- }
-
-
- Status = LoadPeCoffImage (PeCoffImage, &ImageAddress, &ImageSize, &EntryPoint);
-// For NT32 Debug Status = SecWinNtPeiLoadFile (PeCoffImage, &ImageAddress, &ImageSize, &EntryPoint);
- ASSERT_EFI_ERROR (Status);
-
- //
- // Extract the DxeCore GUID file name.
- //
- Status = FfsGetFileInfo (FileHandle, &FvFileInfo);
- ASSERT_EFI_ERROR (Status);
-
- BuildModuleHob (&FvFileInfo.FileName, (EFI_PHYSICAL_ADDRESS)(UINTN)ImageAddress, EFI_SIZE_TO_PAGES ((UINT32) ImageSize) * EFI_PAGE_SIZE, EntryPoint);
-
- DEBUG ((EFI_D_INFO | EFI_D_LOAD, "Loading DxeCore at 0x%10p EntryPoint=0x%10p\n", (VOID *)(UINTN)ImageAddress, (VOID *)(UINTN)EntryPoint));
-
- Hob = GetHobList ();
- if (StackSize == 0) {
- // User the current stack
-
- ((DXE_CORE_ENTRY_POINT)(UINTN)EntryPoint) (Hob);
- } else {
-
- //
- // Allocate 128KB for the Stack
- //
- BaseOfStack = AllocatePages (EFI_SIZE_TO_PAGES (StackSize));
- ASSERT (BaseOfStack != NULL);
-
- //
- // Compute the top of the stack we were allocated. Pre-allocate a UINTN
- // for safety.
- //
- TopOfStack = (VOID *) ((UINTN) BaseOfStack + EFI_SIZE_TO_PAGES (StackSize) * EFI_PAGE_SIZE - CPU_STACK_ALIGNMENT);
- TopOfStack = ALIGN_POINTER (TopOfStack, CPU_STACK_ALIGNMENT);
-
- //
- // Update the contents of BSP stack HOB to reflect the real stack info passed to DxeCore.
- //
- UpdateStackHob ((EFI_PHYSICAL_ADDRESS)(UINTN) BaseOfStack, StackSize);
-
- SwitchStack (
- (SWITCH_STACK_ENTRY_POINT)(UINTN)EntryPoint,
- Hob,
- NULL,
- TopOfStack
- );
-
- }
-
- // Should never get here as DXE Core does not return
- DEBUG ((EFI_D_ERROR, "DxeCore returned\n"));
- ASSERT (FALSE);
-
- return EFI_DEVICE_ERROR;
-}
-
-
-
-EFI_STATUS
-EFIAPI
-LoadDxeCoreFromFv (
- IN UINTN *FvInstance, OPTIONAL
- IN UINTN StackSize
- )
-{
- EFI_STATUS Status;
- EFI_PEI_FV_HANDLE VolumeHandle;
- EFI_PEI_FILE_HANDLE FileHandle = NULL;
-
- if (FvInstance != NULL) {
- //
- // Caller passed in a specific FV to try, so only try that one
- //
- Status = FfsFindNextVolume (*FvInstance, &VolumeHandle);
- if (!EFI_ERROR (Status)) {
- Status = FfsFindNextFile (EFI_FV_FILETYPE_DXE_CORE, VolumeHandle, &FileHandle);
- }
- } else {
- Status = FfsAnyFvFindFirstFile (EFI_FV_FILETYPE_DXE_CORE, &VolumeHandle, &FileHandle);
- }
-
- if (!EFI_ERROR (Status)) {
- return LoadDxeCoreFromFfsFile (FileHandle, StackSize);
- }
-
- return Status;
-}
-
-
-EFI_STATUS
-EFIAPI
-DecompressFirstFv (
- VOID
- )
-{
- EFI_STATUS Status;
- EFI_PEI_FV_HANDLE VolumeHandle;
- EFI_PEI_FILE_HANDLE FileHandle;
-
- Status = FfsAnyFvFindFirstFile (EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE, &VolumeHandle, &FileHandle);
- if (!EFI_ERROR (Status)) {
- Status = FfsProcessFvFile (FileHandle);
- }
-
- return Status;
-}
-
-
+/** @file\r
+\r
+ Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>\r
+\r
+ SPDX-License-Identifier: BSD-2-Clause-Patent\r
+\r
+**/\r
+\r
+#include <PrePi.h>\r
+\r
+//\r
+// Hack to work in NT32\r
+//\r
+EFI_STATUS\r
+\r
+EFIAPI\r
+\r
+SecWinNtPeiLoadFile (\r
+ IN VOID *Pe32Data,\r
+ IN EFI_PHYSICAL_ADDRESS *ImageAddress,\r
+ IN UINT64 *ImageSize,\r
+ IN EFI_PHYSICAL_ADDRESS *EntryPoint\r
+ );\r
+\r
+STATIC\r
+VOID*\r
+EFIAPI\r
+AllocateCodePages (\r
+ IN UINTN Pages\r
+ )\r
+{\r
+ VOID *Alloc;\r
+ EFI_PEI_HOB_POINTERS Hob;\r
+\r
+ Alloc = AllocatePages (Pages);\r
+ if (Alloc == NULL) {\r
+ return NULL;\r
+ }\r
+\r
+ // find the HOB we just created, and change the type to EfiBootServicesCode\r
+ Hob.Raw = GetFirstHob (EFI_HOB_TYPE_MEMORY_ALLOCATION);\r
+ while (Hob.Raw != NULL) {\r
+ if (Hob.MemoryAllocation->AllocDescriptor.MemoryBaseAddress == (UINTN)Alloc) {\r
+ Hob.MemoryAllocation->AllocDescriptor.MemoryType = EfiBootServicesCode;\r
+ return Alloc;\r
+ }\r
+ Hob.Raw = GetNextHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, GET_NEXT_HOB (Hob));\r
+ }\r
+\r
+ ASSERT (FALSE);\r
+\r
+ FreePages (Alloc, Pages);\r
+ return NULL;\r
+}\r
+\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+LoadPeCoffImage (\r
+ IN VOID *PeCoffImage,\r
+ OUT EFI_PHYSICAL_ADDRESS *ImageAddress,\r
+ OUT UINT64 *ImageSize,\r
+ OUT EFI_PHYSICAL_ADDRESS *EntryPoint\r
+ )\r
+{\r
+ RETURN_STATUS Status;\r
+ PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;\r
+ VOID *Buffer;\r
+\r
+ ZeroMem (&ImageContext, sizeof (ImageContext));\r
+\r
+ ImageContext.Handle = PeCoffImage;\r
+ ImageContext.ImageRead = PeCoffLoaderImageReadFromMemory;\r
+\r
+ Status = PeCoffLoaderGetImageInfo (&ImageContext);\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
+\r
+ //\r
+ // Allocate Memory for the image\r
+ //\r
+ Buffer = AllocateCodePages (EFI_SIZE_TO_PAGES((UINT32)ImageContext.ImageSize));\r
+ ASSERT (Buffer != 0);\r
+\r
+\r
+ ImageContext.ImageAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)Buffer;\r
+\r
+ //\r
+ // Load the image to our new buffer\r
+ //\r
+ Status = PeCoffLoaderLoadImage (&ImageContext);\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
+ //\r
+ // Relocate the image in our new buffer\r
+ //\r
+ Status = PeCoffLoaderRelocateImage (&ImageContext);\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
+\r
+ *ImageAddress = ImageContext.ImageAddress;\r
+ *ImageSize = ImageContext.ImageSize;\r
+ *EntryPoint = ImageContext.EntryPoint;\r
+\r
+ //\r
+ // Flush not needed for all architectures. We could have a processor specific\r
+ // function in this library that does the no-op if needed.\r
+ //\r
+ InvalidateInstructionCacheRange ((VOID *)(UINTN)*ImageAddress, (UINTN)*ImageSize);\r
+\r
+ return Status;\r
+}\r
+\r
+\r
+\r
+typedef\r
+VOID\r
+(EFIAPI *DXE_CORE_ENTRY_POINT) (\r
+ IN VOID *HobStart\r
+ );\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+LoadDxeCoreFromFfsFile (\r
+ IN EFI_PEI_FILE_HANDLE FileHandle,\r
+ IN UINTN StackSize\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ VOID *PeCoffImage;\r
+ EFI_PHYSICAL_ADDRESS ImageAddress;\r
+ UINT64 ImageSize;\r
+ EFI_PHYSICAL_ADDRESS EntryPoint;\r
+ VOID *BaseOfStack;\r
+ VOID *TopOfStack;\r
+ VOID *Hob;\r
+ EFI_FV_FILE_INFO FvFileInfo;\r
+\r
+ Status = FfsFindSectionData (EFI_SECTION_PE32, FileHandle, &PeCoffImage);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+\r
+ Status = LoadPeCoffImage (PeCoffImage, &ImageAddress, &ImageSize, &EntryPoint);\r
+// For NT32 Debug Status = SecWinNtPeiLoadFile (PeCoffImage, &ImageAddress, &ImageSize, &EntryPoint);\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
+ //\r
+ // Extract the DxeCore GUID file name.\r
+ //\r
+ Status = FfsGetFileInfo (FileHandle, &FvFileInfo);\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
+ BuildModuleHob (&FvFileInfo.FileName, (EFI_PHYSICAL_ADDRESS)(UINTN)ImageAddress, EFI_SIZE_TO_PAGES ((UINT32) ImageSize) * EFI_PAGE_SIZE, EntryPoint);\r
+\r
+ DEBUG ((DEBUG_INFO | DEBUG_LOAD, "Loading DxeCore at 0x%10p EntryPoint=0x%10p\n", (VOID *)(UINTN)ImageAddress, (VOID *)(UINTN)EntryPoint));\r
+\r
+ Hob = GetHobList ();\r
+ if (StackSize == 0) {\r
+ // User the current stack\r
+\r
+ ((DXE_CORE_ENTRY_POINT)(UINTN)EntryPoint) (Hob);\r
+ } else {\r
+\r
+ //\r
+ // Allocate 128KB for the Stack\r
+ //\r
+ BaseOfStack = AllocatePages (EFI_SIZE_TO_PAGES (StackSize));\r
+ ASSERT (BaseOfStack != NULL);\r
+\r
+ //\r
+ // Compute the top of the stack we were allocated. Pre-allocate a UINTN\r
+ // for safety.\r
+ //\r
+ TopOfStack = (VOID *) ((UINTN) BaseOfStack + EFI_SIZE_TO_PAGES (StackSize) * EFI_PAGE_SIZE - CPU_STACK_ALIGNMENT);\r
+ TopOfStack = ALIGN_POINTER (TopOfStack, CPU_STACK_ALIGNMENT);\r
+\r
+ //\r
+ // Update the contents of BSP stack HOB to reflect the real stack info passed to DxeCore.\r
+ //\r
+ UpdateStackHob ((EFI_PHYSICAL_ADDRESS)(UINTN) BaseOfStack, StackSize);\r
+\r
+ SwitchStack (\r
+ (SWITCH_STACK_ENTRY_POINT)(UINTN)EntryPoint,\r
+ Hob,\r
+ NULL,\r
+ TopOfStack\r
+ );\r
+\r
+ }\r
+\r
+ // Should never get here as DXE Core does not return\r
+ DEBUG ((DEBUG_ERROR, "DxeCore returned\n"));\r
+ ASSERT (FALSE);\r
+\r
+ return EFI_DEVICE_ERROR;\r
+}\r
+\r
+\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+LoadDxeCoreFromFv (\r
+ IN UINTN *FvInstance OPTIONAL,\r
+ IN UINTN StackSize\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_PEI_FV_HANDLE VolumeHandle;\r
+ EFI_PEI_FILE_HANDLE FileHandle = NULL;\r
+\r
+ if (FvInstance != NULL) {\r
+ //\r
+ // Caller passed in a specific FV to try, so only try that one\r
+ //\r
+ Status = FfsFindNextVolume (*FvInstance, &VolumeHandle);\r
+ if (!EFI_ERROR (Status)) {\r
+ Status = FfsFindNextFile (EFI_FV_FILETYPE_DXE_CORE, VolumeHandle, &FileHandle);\r
+ }\r
+ } else {\r
+ Status = FfsAnyFvFindFirstFile (EFI_FV_FILETYPE_DXE_CORE, &VolumeHandle, &FileHandle);\r
+ }\r
+\r
+ if (!EFI_ERROR (Status)) {\r
+ return LoadDxeCoreFromFfsFile (FileHandle, StackSize);\r
+ }\r
+\r
+ return Status;\r
+}\r
+\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+DecompressFirstFv (\r
+ VOID\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_PEI_FV_HANDLE VolumeHandle;\r
+ EFI_PEI_FILE_HANDLE FileHandle;\r
+\r
+ Status = FfsAnyFvFindFirstFile (EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE, &VolumeHandle, &FileHandle);\r
+ if (!EFI_ERROR (Status)) {\r
+ Status = FfsProcessFvFile (FileHandle);\r
+ }\r
+\r
+ return Status;\r
+}\r