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 <maurice.ma@intel.com>
This commit is contained in:
Maurice Ma
2021-04-08 13:59:57 -07:00
parent a73d37fa91
commit ded75d8859
9 changed files with 149 additions and 13 deletions
@@ -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()
+2 -1
View File
@@ -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();
}
}
@@ -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.
+93
View File
@@ -0,0 +1,93 @@
/** @ Provide API to call extra modules
Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
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;
}
+3 -4
View File
@@ -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);
+3 -2
View File
@@ -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);
+24
View File
@@ -45,6 +45,7 @@
#include <Library/UsbKbLib.h>
#include <Library/ElfLib.h>
#include <Library/LinuxLib.h>
#include <Library/ThunkLib.h>
#include <Library/ContainerLib.h>
#include <Library/DebugLogBufferLib.h>
#include <Guid/SeedInfoHobGuid.h>
@@ -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
+1
View File
@@ -39,6 +39,7 @@
PreOsSupport.c
PreOsChecker.c
ModService.c
ExtraModSupport.c
[Packages]
MdePkg/MdePkg.dec
+5 -2
View File
@@ -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