Move container initialization earlier

Current container library cannot be used before memory is initialized
because the structure will only be initialized after memory. This
patch moved the initialization into Stage1A so that the library can be
used much earlier. The containers registered before memory will be
migrated into memory automatically post memory initialization. In this
way it avoids duplicated header authentication.

Signed-off-by: Maurice Ma <maurice.ma@intel.com>
This commit is contained in:
Maurice Ma 2020-04-23 14:02:05 -07:00
parent 83eab7e046
commit 86566d4196
8 changed files with 73 additions and 44 deletions

View File

@ -51,8 +51,8 @@ typedef VOID (*LOAD_COMPONENT_CALLBACK) (UINT32 ProgressId, COMPONENT_CALLBACK_I
typedef struct {
UINT32 Signature;
UINT32 HeaderCache;
UINT32 HeaderSize;
UINT32 Base;
UINT32 Reserved;
} CONTAINER_ENTRY;
typedef struct {

View File

@ -55,6 +55,40 @@ GetContainerBySignature (
return NULL;
}
/**
This function returns the container header size.
@param[in] ContainerEntry Container entry pointer.
@retval Container header size.
**/
STATIC
UINT32
GetContainerHeaderSize (
IN CONTAINER_HDR *ContainerHdr
)
{
INTN Offset;
UINT32 Index;
COMPONENT_ENTRY *CompEntry;
Offset = 0;
if (ContainerHdr != NULL) {
CompEntry = (COMPONENT_ENTRY *)&ContainerHdr[1];
for (Index = 0; Index < ContainerHdr->Count; Index++) {
CompEntry = (COMPONENT_ENTRY *)((UINT8 *)(CompEntry + 1) + CompEntry->HashSize);
Offset = (UINT8 *)CompEntry - (UINT8 *)ContainerHdr;
if ((Offset < 0) || (Offset >= ContainerHdr->DataOffset)) {
Offset = 0;
break;
}
}
}
return (UINT32)Offset;
}
/**
This function registers a container.
@ -78,6 +112,7 @@ RegisterContainerInternal (
CONTAINER_ENTRY *ContainerEntry;
UINT32 Index;
VOID *Buffer;
UINT32 MaxHdrSize;
ContainerList = (CONTAINER_LIST *)GetContainerListPtr ();
if (ContainerList == NULL) {
@ -95,15 +130,21 @@ RegisterContainerInternal (
return EFI_BUFFER_TOO_SMALL;
}
Buffer = AllocatePool (ContainerHdr->DataOffset);
MaxHdrSize = GetContainerHeaderSize (ContainerHdr) + SIGNATURE_AND_KEY_SIZE_MAX;
if (MaxHdrSize > ContainerHdr->DataOffset) {
MaxHdrSize = ContainerHdr->DataOffset;
}
Buffer = AllocatePool (MaxHdrSize);
if (Buffer == NULL) {
return EFI_OUT_OF_RESOURCES;
}
ContainerList->Entry[Index].Signature = ContainerHdr->Signature;
ContainerList->Entry[Index].HeaderCache = (UINT32)(UINTN)Buffer;
ContainerList->Entry[Index].HeaderSize = MaxHdrSize ;
ContainerList->Entry[Index].Base = ContainerBase;
CopyMem (Buffer, (VOID *)(UINTN)ContainerBase, ContainerHdr->DataOffset);
CopyMem (Buffer, (VOID *)(UINTN)ContainerBase, MaxHdrSize);
ContainerList->Count++;
return EFI_SUCCESS;
@ -163,40 +204,6 @@ UnregisterContainer (
return Status;
}
/**
This function returns the container header size.
@param[in] ContainerEntry Container entry pointer.
@retval Container header size.
**/
STATIC
UINT32
GetContainerHeaderSize (
IN CONTAINER_HDR *ContainerHdr
)
{
INTN Offset;
UINT32 Index;
COMPONENT_ENTRY *CompEntry;
Offset = 0;
if (ContainerHdr != NULL) {
CompEntry = (COMPONENT_ENTRY *)&ContainerHdr[1];
for (Index = 0; Index < ContainerHdr->Count; Index++) {
CompEntry = (COMPONENT_ENTRY *)((UINT8 *)(CompEntry + 1) + CompEntry->HashSize);
Offset = (UINT8 *)CompEntry - (UINT8 *)ContainerHdr;
if ((Offset < 0) || (Offset >= ContainerHdr->DataOffset)) {
Offset = 0;
break;
}
}
}
return (UINT32)Offset;
}
/**
This function returns the component entry info.

View File

@ -43,6 +43,7 @@ typedef enum {
EnumBufPcdData,
EnumBufPlatData,
EnumBufCfgData,
EnumBufCtnList,
EnumBufLogBuf,
EnumBufMax
} BUF_INFO_ID;

View File

@ -264,6 +264,7 @@ SecStartup2 (
HASH_STORE_TABLE *HashStoreTable;
SERVICES_LIST *ServiceList;
BUF_INFO *BufInfo;
CONTAINER_LIST *ContainerList;
Stage1aFvBase = PcdGet32 (PcdStage1AFdBase) + PcdGet32 (PcdFSPTSize);
PeCoffFindAndReportImageInfo ((UINT32) (UINTN) GET_STAGE_MODULE_BASE (Stage1aFvBase));
@ -325,6 +326,11 @@ SecStartup2 (
BufInfo->CopyLen = sizeof(CDATA_BLOB);
BufInfo->DstBase = &LdrGlobal->CfgDataPtr;
// Container list
BufInfo = &Stage1aParam.BufInfo[EnumBufCtnList];
BufInfo->AllocLen = PcdGet32 (PcdContainerMaxNumber) * sizeof (CONTAINER_ENTRY) + sizeof (CONTAINER_LIST);
BufInfo->DstBase = &LdrGlobal->ContainerList;
// Log Buffer
BufInfo = &Stage1aParam.BufInfo[EnumBufLogBuf];
BufInfo->SrcBase = (VOID *)&mLogBufHdrTmpl;
@ -343,13 +349,19 @@ SecStartup2 (
if (HashStoreTable != NULL) {
HashStoreTable->TotalLength = PcdGet32 (PcdHashStoreSize);
}
ContainerList = (CONTAINER_LIST *) LdrGlobal->ContainerList;
if (ContainerList != NULL) {
BufInfo = &Stage1aParam.BufInfo[EnumBufCtnList];
ContainerList->Signature = CONTAINER_LIST_SIGNATURE;
ContainerList->TotalLength = BufInfo->AllocLen;
}
BufInfo = &Stage1aParam.BufInfo[EnumBufPcdData];
SetLibraryData (PcdGet8 (PcdPcdLibId), LdrGlobal->PcdDataPtr, BufInfo->AllocLen);
}
// Extra initialization
if (FlashMap != NULL) {
SetCurrentBootPartition((FlashMap->Attributes & FLASH_MAP_ATTRIBUTES_BACKUP_REGION)? 1 : 0);
SetCurrentBootPartition ((FlashMap->Attributes & FLASH_MAP_ATTRIBUTES_BACKUP_REGION) ? 1 : 0);
}
// Call board hook to enable debug

View File

@ -27,6 +27,7 @@
#include <Library/CpuExceptionLib.h>
#include <Library/DebugLogBufferLib.h>
#include <Library/DebugAgentLib.h>
#include <Library/ContainerLib.h>
#include <Library/StageLib.h>
#include <Guid/FspHeaderFile.h>
#include <Guid/FlashMapInfoGuid.h>

View File

@ -62,6 +62,7 @@
gPlatformCommonLibTokenSpaceGuid.PcdMaxLibraryDataEntry
gPlatformCommonLibTokenSpaceGuid.PcdVerifiedBootEnabled
gPlatformCommonLibTokenSpaceGuid.PcdDebugOutputDeviceMask
gPlatformCommonLibTokenSpaceGuid.PcdContainerMaxNumber
gPlatformModuleTokenSpaceGuid.PcdStage1StackSize
gPlatformModuleTokenSpaceGuid.PcdStage1BFdBase
gPlatformModuleTokenSpaceGuid.PcdStage1BLoadBase

View File

@ -368,6 +368,7 @@ SecStartup2 (
BOOLEAN OldStatus;
PLT_DEVICE_TABLE *DeviceTable;
CONTAINER_LIST *ContainerList;
CONTAINER_ENTRY *ContainerEntry;
VOID **FieldPtr;
LdrGlobal = (LOADER_GLOBAL_DATA *)GetLoaderGlobalDataPointer ();
@ -563,13 +564,20 @@ SecStartup2 (
CopyMem (LdrGlobal->DeviceTable, DeviceTable, AllocateLen);
}
// Allocate container list
AllocateLen = PcdGet32 (PcdContainerMaxNumber) * sizeof (CONTAINER_ENTRY) + sizeof (CONTAINER_LIST);
LdrGlobal->ContainerList = AllocateZeroPool (AllocateLen);
// Migrate container header cache into memory
ContainerList = (CONTAINER_LIST *) LdrGlobal->ContainerList;
if (ContainerList != NULL) {
ContainerList->Signature = CONTAINER_LIST_SIGNATURE;
ContainerList->TotalLength = AllocateLen;
for (Idx = 0; Idx < ContainerList->Count; Idx++) {
ContainerEntry = (CONTAINER_ENTRY *)&ContainerList->Entry[Idx];
if (ContainerEntry->HeaderSize == 0) {
continue;
}
BufPtr = AllocatePool (ContainerEntry->HeaderSize);
if (BufPtr != NULL) {
CopyMem (BufPtr, (VOID *)(UINTN)ContainerEntry->HeaderCache, ContainerEntry->HeaderSize);
ContainerEntry->HeaderCache = (UINT32)(UINTN)BufPtr;
}
}
}
// Call back into board hooks post memory

View File

@ -63,7 +63,6 @@
[Pcd]
gPlatformCommonLibTokenSpaceGuid.PcdMaxLibraryDataEntry
gPlatformCommonLibTokenSpaceGuid.PcdVerifiedBootEnabled
gPlatformCommonLibTokenSpaceGuid.PcdContainerMaxNumber
gPlatformModuleTokenSpaceGuid.PcdStage1StackSize
gPlatformModuleTokenSpaceGuid.PcdStage1DataSize
gPlatformModuleTokenSpaceGuid.PcdFSPTBase