diff --git a/BootloaderCommonPkg/Include/Guid/MpCpuTaskInfoHob.h b/BootloaderCommonPkg/Include/Guid/MpCpuTaskInfoHob.h index 9f9a0ea1..0454fd37 100644 --- a/BootloaderCommonPkg/Include/Guid/MpCpuTaskInfoHob.h +++ b/BootloaderCommonPkg/Include/Guid/MpCpuTaskInfoHob.h @@ -20,9 +20,10 @@ typedef enum { EnumCpuReady, EnumCpuStart, EnumCpuEnd, + EnumCpuReturn, } CPU_STATE; -typedef UINT64 (*CPU_TASK_FUNC) (UINT64 Arg); +typedef UINT64 (EFIAPI *CPU_TASK_FUNC) (UINT64 Arg); #pragma pack(1) @@ -43,12 +44,12 @@ typedef struct { } CPU_TASK; typedef struct { - UINT32 CpuCount; - CPU_TASK CpuTask[0]; + UINT32 CpuCount; + CPU_TASK CpuTask[0]; } SYS_CPU_TASK; typedef struct { - SYS_CPU_TASK *SysCpuTask; + EFI_PHYSICAL_ADDRESS SysCpuTask; } SYS_CPU_TASK_HOB; #pragma pack() diff --git a/BootloaderCorePkg/Stage2/Stage2Support.c b/BootloaderCorePkg/Stage2/Stage2Support.c index 7a11af1a..144d4876 100644 --- a/BootloaderCorePkg/Stage2/Stage2Support.c +++ b/BootloaderCorePkg/Stage2/Stage2Support.c @@ -589,8 +589,9 @@ BuildExtraInfoHob ( if (GetPayloadId () == 0) { Length = sizeof (SYS_CPU_TASK_HOB); SysCpuTaskHob = BuildGuidHob (&gLoaderMpCpuTaskInfoGuid, Length); + if (SysCpuTaskHob != NULL) { - SysCpuTaskHob->SysCpuTask = MpGetTask (); + SysCpuTaskHob->SysCpuTask = (UINTN) MpGetTask(); } } diff --git a/PayloadPkg/Include/Library/PayloadEntryLib.h b/PayloadPkg/Include/Library/PayloadEntryLib.h index f3096479..f3429f48 100644 --- a/PayloadPkg/Include/Library/PayloadEntryLib.h +++ b/PayloadPkg/Include/Library/PayloadEntryLib.h @@ -8,6 +8,19 @@ #ifndef __PAYLOAD_ENTRY_LIB_H__ #define __PAYLOAD_ENTRY_LIB_H__ +typedef struct { + UINT32 Signature; + UINT32 HeapBase; + UINT32 HeapSize; + UINT32 RsvdBase; + UINT32 RsvdSize; + UINT32 Argc; + UINT32 Argv[4]; +} PLD_EXTRA_MOD_ARGS; + +typedef EFI_STATUS (EFIAPI *PLD_MODULE_ENTRY) \ + (VOID *HobList, PLD_EXTRA_MOD_ARGS *Params); + /** The payload common Entry Point for C code. diff --git a/PayloadPkg/OsLoader/ExtraModSupport.c b/PayloadPkg/OsLoader/ExtraModSupport.c new file mode 100644 index 00000000..c692e3df --- /dev/null +++ b/PayloadPkg/OsLoader/ExtraModSupport.c @@ -0,0 +1,93 @@ +/** @ Provide API to call extra modules + + Copyright (c) 2021, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "OsLoader.h" + +#define RTCM_HEAP_SIZE 0x10000 +#define RTCM_RSVD_SIZE 0xFF000 +#define MOD_DEF_HEAP_SIZE 0x10000 +#define MOD_DEF_RSVD_SIZE 0x04000 + +/** + Call into an extra image entrypoint. + + Detect and call into the image entrypoint. If required, handle thunk call + as well. + + @param[in] ModSignature Module signature. + @param[in] LoadedImage Loaded Image information, expected to be PE32 format. + + @retval EFI_SUCCESS Image returns successfully + @retval Others There is error during the module call. + +**/ +EFI_STATUS +CallExtraModule ( + IN UINT32 ModSignature, + IN LOADED_IMAGE *LoadedImage + ) +{ + EFI_STATUS Status; + UINT16 PldMachine; + PLD_MODULE_ENTRY PldEntry; + VOID *HobList; + PLD_EXTRA_MOD_ARGS ModArgs; + VOID *ExtraImageBase; + + ExtraImageBase = LoadedImage->ImageData.Addr; + + // Prepare memory for extra modules + ZeroMem (&ModArgs, sizeof(ModArgs)); + ModArgs.Signature = ModSignature; + if (ModSignature == PLD_EXTRA_MOD_RTCM) { + ModArgs.RsvdSize = RTCM_RSVD_SIZE; + ModArgs.HeapSize = RTCM_HEAP_SIZE; + } else { + ModArgs.RsvdSize = MOD_DEF_RSVD_SIZE; + ModArgs.HeapSize = MOD_DEF_HEAP_SIZE; + } + ModArgs.RsvdBase = (UINT32)(UINTN) AllocateReservedPages (EFI_SIZE_TO_PAGES (ModArgs.RsvdSize)); + ModArgs.HeapBase = (UINT32)(UINTN) AllocatePages (EFI_SIZE_TO_PAGES (ModArgs.HeapSize)); + ASSERT (ModArgs.HeapBase != 0); + ASSERT (ModArgs.RsvdBase != 0); + + // Get entrypoint and call into module with thunk support + Status = PeCoffLoaderGetMachine (ExtraImageBase, &PldMachine); + if (!EFI_ERROR(Status)) { + Status = PeCoffLoaderGetEntryPoint (ExtraImageBase, (VOID *)&PldEntry); + } + + if (!EFI_ERROR(Status)) { + if (IS_X64) { + if (PldMachine == IMAGE_FILE_MACHINE_I386) { + DEBUG ((DEBUG_INFO, "Switch to x86 Mode\n")); + } + } else { + if (PldMachine == IMAGE_FILE_MACHINE_X64) { + DEBUG ((DEBUG_INFO, "Switch to x64 Mode\n")); + } + } + DEBUG ((DEBUG_INIT, "Call Extra Module Entry @ 0x%p \n", PldEntry)); + HobList = (VOID *)(UINTN) PcdGet32 (PcdPayloadHobList); + if (PldMachine == IMAGE_FILE_MACHINE_X64) { + Status = Execute64BitCode ((UINT64)(UINTN)PldEntry, (UINT64)(UINTN)HobList, + (UINT64)(UINTN)&ModArgs, FALSE); + } else { + + Status = Execute32BitCode ((UINT64)(UINTN)PldEntry, (UINT64)(UINTN)HobList, + (UINT64)(UINTN)&ModArgs, FALSE); + } + DEBUG ((DEBUG_INFO, "Extra Module Returned: %r\n", Status)); + } + + // Deallocate heap memory, but keep reserved memory + if (ModArgs.HeapBase != 0) { + FreePages ((VOID *)(UINTN)ModArgs.HeapBase, EFI_SIZE_TO_PAGES (ModArgs.HeapSize)); + } + + return Status; +} diff --git a/PayloadPkg/OsLoader/LoadImage.c b/PayloadPkg/OsLoader/LoadImage.c index ffbf99aa..c7e8c49b 100644 --- a/PayloadPkg/OsLoader/LoadImage.c +++ b/PayloadPkg/OsLoader/LoadImage.c @@ -65,11 +65,10 @@ GetBootImageFromIfwiContainer ( if ((Image->ContainerSig == SIGNATURE_32 ('I', 'P', 'F', 'W')) && (Image->ComponentName == SIGNATURE_32 ('T', 'C', 'C', 'R'))) { // - // TCC RTCM image need runtime memory + // TCC RTCM image need reserved memory // - LoadedImage->ImageData.Addr = AllocateRuntimePages(EFI_SIZE_TO_PAGES(ImageSize)); - if (LoadedImage->ImageData.Addr == NULL) - { + LoadedImage->ImageData.Addr = AllocateReservedPages (EFI_SIZE_TO_PAGES(ImageSize)); + if (LoadedImage->ImageData.Addr == NULL) { return EFI_OUT_OF_RESOURCES; } CopyMem(LoadedImage->ImageData.Addr, Buffer, ImageSize); diff --git a/PayloadPkg/OsLoader/OsLoader.c b/PayloadPkg/OsLoader/OsLoader.c index a47cf5ba..c3dbff11 100644 --- a/PayloadPkg/OsLoader/OsLoader.c +++ b/PayloadPkg/OsLoader/OsLoader.c @@ -1038,7 +1038,8 @@ StartBootImages ( break; } if ((LoadedExtraImage != NULL) && ((LoadedExtraImage->Flags & LOADED_IMAGE_RUN_EXTRA) != 0)) { - Status = StartBooting (LoadedExtraImage); + // For now, only RTCM will be supported. + Status = CallExtraModule (PLD_EXTRA_MOD_RTCM, LoadedExtraImage); if (EFI_ERROR (Status)) { return Status; } @@ -1052,7 +1053,7 @@ StartBootImages ( Status = GetLoadedImageByType (LoadedImageHandle, LoadImageTypePreOs, &LoadedPreOsImage); if (EFI_ERROR (Status)) { - Status = StartBooting (LoadedImage); + Status = StartBooting (LoadedImage); } else { // PreOs found, need start PreOS Status = StartPreOsBooting (LoadedPreOsImage, LoadedImage); diff --git a/PayloadPkg/OsLoader/OsLoader.h b/PayloadPkg/OsLoader/OsLoader.h index 7f89dd07..6acebd48 100644 --- a/PayloadPkg/OsLoader/OsLoader.h +++ b/PayloadPkg/OsLoader/OsLoader.h @@ -45,6 +45,7 @@ #include #include #include +#include #include #include #include @@ -89,6 +90,8 @@ #define MAX_BOOT_MENU_ENTRY 8 #define MAX_STR_SLICE_LEN 16 +#define PLD_EXTRA_MOD_RTCM SIGNATURE_32('R', 'T', 'C', 'M') + typedef struct { UINT32 Pos; UINT32 Len; @@ -543,4 +546,25 @@ StartPreOsBooting ( IN LOADED_IMAGE *LoadedPreOsImage, IN LOADED_IMAGE *LoadedImage ); + + +/** + Call into an extra image entrypoint. + + Detect and call into the image entrypoint. If required, handle thunk call + as well. + + @param[in] ModSignature Module signature. + @param[in] LoadedImage Loaded Image information, expected to be PE32 format. + + @retval EFI_SUCCESS Image returns successfully + @retval Others There is error during the module call. + +**/ +EFI_STATUS +CallExtraModule ( + IN UINT32 ModSignature, + IN LOADED_IMAGE *LoadedImage + ); + #endif diff --git a/PayloadPkg/OsLoader/OsLoader.inf b/PayloadPkg/OsLoader/OsLoader.inf index 1c0f6384..c9e04195 100644 --- a/PayloadPkg/OsLoader/OsLoader.inf +++ b/PayloadPkg/OsLoader/OsLoader.inf @@ -39,6 +39,7 @@ PreOsSupport.c PreOsChecker.c ModService.c + ExtraModSupport.c [Packages] MdePkg/MdePkg.dec diff --git a/PayloadPkg/PayloadPkg.dsc b/PayloadPkg/PayloadPkg.dsc index 653516d0..9830edf2 100644 --- a/PayloadPkg/PayloadPkg.dsc +++ b/PayloadPkg/PayloadPkg.dsc @@ -39,6 +39,7 @@ BaseMemoryLib | MdePkg/Library/BaseMemoryLibSse2/BaseMemoryLibSse2.inf IoLib | MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf PrintLib | MdePkg/Library/BasePrintLib/BasePrintLib.inf + SynchronizationLib|MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf HobLib | BootloaderCommonPkg/Library/HobLib/HobLib.inf DebugLogBufferLib | BootloaderCommonPkg/Library/DebugLogBufferLib/DebugLogBufferLib.inf SerialPortLib | BootloaderCommonPkg/Library/SerialPortLib/SerialPortLib.inf @@ -59,6 +60,10 @@ PayloadEntryLib | PayloadPkg/Library/PayloadEntryLib/PayloadEntryLib.inf PlatformHookLib | PayloadPkg/Library/PlatformHookLib/PlatformHookLib.inf PagingLib|BootloaderCommonPkg/Library/PagingLib/PagingLib.inf + ThunkLib|BootloaderCommonPkg/Library/ThunkLib/ThunkLib.inf + LitePeCoffLib|BootloaderCommonPkg/Library/LitePeCoffLib/LitePeCoffLib.inf + DebugAgentLib|BootloaderCommonPkg/Library/DebugAgentLib/DebugAgentLibNull.inf + TimerLib|BootloaderCommonPkg/Library/AcpiTimerLib/AcpiTimerLib.inf [PcdsPatchableInModule] gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel | 0x8000004F @@ -85,11 +90,9 @@ gPayloadTokenSpaceGuid.PcdPayloadHeapSize | 0x02000000 gPayloadTokenSpaceGuid.PcdPayloadStackSize | 0x00010000 - [Components] PayloadPkg/HelloWorld/HelloWorld.inf - [BuildOptions.Common.EDKII] # Enable link-time optimization when building with GCC49 *_GCC49_IA32_CC_FLAGS = -flto