From ded75d885947f3542e29e12ce50dddce91da14f2 Mon Sep 17 00:00:00 2001 From: Maurice Ma Date: Thu, 8 Apr 2021 13:59:57 -0700 Subject: [PATCH] Enable SBL call into extra module in boot option SBL allows extra module to be called before tranfering into the main boot option. For example, RTCM module can be called for boot option with TCC feature support. This patch enabled this support. Since the extra module might have different ARCH mode from current SBL mode, thunk will be provided if mismatching is detected. Signed-off-by: Maurice Ma --- .../Include/Guid/MpCpuTaskInfoHob.h | 9 +- BootloaderCorePkg/Stage2/Stage2Support.c | 3 +- PayloadPkg/Include/Library/PayloadEntryLib.h | 13 +++ PayloadPkg/OsLoader/ExtraModSupport.c | 93 +++++++++++++++++++ PayloadPkg/OsLoader/LoadImage.c | 7 +- PayloadPkg/OsLoader/OsLoader.c | 5 +- PayloadPkg/OsLoader/OsLoader.h | 24 +++++ PayloadPkg/OsLoader/OsLoader.inf | 1 + PayloadPkg/PayloadPkg.dsc | 7 +- 9 files changed, 149 insertions(+), 13 deletions(-) create mode 100644 PayloadPkg/OsLoader/ExtraModSupport.c 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