alder_lake_bios/Insyde/InsydeSetupPkg/Drivers/HiiLayoutPkgDxe/HiiLayoutPkg.c

345 lines
8.9 KiB
C

/** @file
;******************************************************************************
;* Copyright (c) 2013 - 2014, Insyde Software Corp. All Rights Reserved.
;*
;* You may not reproduce, distribute, publish, display, perform, modify, adapt,
;* transmit, broadcast, present, recite, release, license or otherwise exploit
;* any part of this publication in any form, by any means, without the prior
;* written permission of Insyde Software Corporation.
;*
;******************************************************************************
*/
#include "HiiLayoutPkg.h"
extern UINT8 HiiLayoutPkgDxeImages[];
extern UINT8 HiiLayoutPkgDxeStrings[];
extern UINT8 ProjectBin[];
EFI_GUID mLayoutPackageListGuid = {0xa7958683, 0x3242, 0x4963, {0xb6, 0x42, 0xa7, 0xc9, 0x77, 0x34, 0x3f, 0xd4}};
/**
HII Database Protocol notification event handler.
Register layout package when HII Database Protocol has been installed.
@param[in] Event Event whose notification function is being invoked.
@param[in] Context Pointer to the notification function's context.
**/
EFI_STATUS
GetLayoutPackageFromFv (
IN OUT UINT8 **LayoutPkg
)
{
EFI_STATUS Status;
UINTN FvProtocolCount;
EFI_HANDLE *FvHandles;
EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv;
UINTN Index;
UINT32 AuthenticationStatus;
UINTN ImageSize;
UINT8 *ImageData;
UINTN PackageLength;
UINT8 *Package;
Status = gBS->LocateHandleBuffer (
ByProtocol,
&gEfiFirmwareVolume2ProtocolGuid,
NULL,
&FvProtocolCount,
&FvHandles
);
if (EFI_ERROR (Status)) {
return Status;
}
ImageData = NULL;
ImageSize = 0;
for (Index = 0; Index < FvProtocolCount; Index++) {
Status = gBS->HandleProtocol (
FvHandles[Index],
&gEfiFirmwareVolume2ProtocolGuid,
(VOID **) &Fv
);
if (EFI_ERROR (Status)) {
continue;
}
Status = EFI_NOT_FOUND;
//
// gH2OHiiLayoutFileGuid = H2O_HII_LAYOUT_FILE_GUID
//
Status = Fv->ReadSection (
Fv,
&gH2OHiiLayoutFileGuid,
EFI_SECTION_RAW,
0,
(VOID **)&ImageData,
&ImageSize,
&AuthenticationStatus
);
if (!EFI_ERROR (Status)) {
break;
}
}
if (EFI_ERROR (Status)) {
return Status;
}
if (ImageSize <= sizeof (H2O_LAYOUT_PACKAGE_HDR)) {
return EFI_NOT_FOUND;
}
PackageLength = 4 + ImageSize;
Package = (UINT8 *)AllocateZeroPool (PackageLength);
if (Package == NULL) {
return EFI_OUT_OF_RESOURCES;
}
CopyMem (Package, &PackageLength, 4);
CopyMem (Package + 4, ImageData, ImageSize);
FreePool (ImageData);
*LayoutPkg = Package;
return EFI_SUCCESS;
}
/**
HII Database Protocol notification event handler.
Register layout package when HII Database Protocol has been installed.
@param[in] Event Event whose notification function is being invoked.
@param[in] Context Pointer to the notification function's context.
**/
VOID
RegisterLayoutPackage (
IN EFI_EVENT Event,
IN VOID *Context
)
{
EFI_STATUS Status;
UINT8 *LayoutPkg;
EFI_HII_HANDLE HiiHandle;
EFI_HII_DATABASE_PROTOCOL *HiiDatabase;
LAYOUT_DATABASE_PROTOCOL *LayoutDatabase;
//
// Layout pkg from FV.
//
LayoutPkg = NULL;
Status = GetLayoutPackageFromFv (&LayoutPkg);
if (EFI_ERROR (Status)) {
LayoutPkg = &ProjectBin[0];
}
//
// Locate HII Database Protocol
//
Status = gBS->LocateProtocol (&gEfiHiiDatabaseProtocolGuid, NULL, (VOID **) &HiiDatabase);
ASSERT (Status == EFI_SUCCESS);
//
// Add this layout package to a package list then install it.
// BUGBUG: HiiDatabase not support layout pkg yet
//
HiiHandle = NULL;
//HiiHandle = HiiAddPackages (&mLayoutPackageListGuid, NULL, LayoutPkg, NULL);
//ASSERT (HiiHandle != NULL);
//
// Restore HIIHandle
//
Status = gBS->LocateProtocol (&gLayoutDatabaseProtocolGuid, NULL, (VOID **) &LayoutDatabase);
ASSERT (Status == EFI_SUCCESS);
LayoutDatabase->LayoutPkgHiiHandle = HiiHandle;
LayoutDatabase->LayoutPkgAddr = (UINTN)(UINTN *)LayoutPkg;
LayoutDatabase->LayoutListHead = NULL;
}
/**
HII Database Protocol notification event handler.
Register layout package when HII Database Protocol has been installed.
@param[in] Event Event whose notification function is being invoked.
@param[in] Context Pointer to the notification function's context.
**/
VOID
RegisterImagePackage (
IN EFI_EVENT Event,
IN VOID *Context
)
{
EFI_STATUS Status;
UINT8 *ImagePkg;
EFI_HII_HANDLE HiiHandle;
EFI_HII_DATABASE_PROTOCOL *HiiDatabase;
LAYOUT_DATABASE_PROTOCOL *LayoutDatabase;
//
// Locate HII Database Protocol
//
Status = gBS->LocateProtocol (&gEfiHiiDatabaseProtocolGuid, NULL, (VOID **) &HiiDatabase);
ASSERT (Status == EFI_SUCCESS);
//
// Add this imgae package to a package list then install it.
//
HiiHandle = NULL;
ImagePkg = (UINT8 *)&HiiLayoutPkgDxeImages[0];
HiiHandle = HiiAddPackages (&mLayoutPackageListGuid, NULL, ImagePkg, HiiLayoutPkgDxeStrings, NULL);
ASSERT (HiiHandle != NULL);
//
// Restore HIIHandle
//
Status = gBS->LocateProtocol (&gLayoutDatabaseProtocolGuid, NULL, (VOID **) &LayoutDatabase);
ASSERT (Status == EFI_SUCCESS);
LayoutDatabase->ImagePkgHiiHandle = HiiHandle;
}
/**
Install HII Layout Package.
@retval EFI_SUCCESS Install HII Layout Package successfully.
@return other Failed to install HII Layout Package.
**/
EFI_STATUS
InstallHiiLayoutPkg (
VOID
)
{
EFI_EVENT HiiRegistration;
//
// Register notify function on HII Database Protocol to add layout package.
//
EfiCreateProtocolNotifyEvent (
&gEfiHiiDatabaseProtocolGuid,
TPL_CALLBACK,
RegisterLayoutPackage,
NULL,
&HiiRegistration
);
return EFI_SUCCESS;
}
/**
Install HII Image Package.
@retval EFI_SUCCESS Install HII Image Package successfully.
@return other Failed to install HII Image Package.
**/
EFI_STATUS
InstallHiiImagePkg (
VOID
)
{
EFI_EVENT HiiRegistration;
//
// Register notify function on HII Database Protocol to add image package.
//
EfiCreateProtocolNotifyEvent (
&gEfiHiiDatabaseProtocolGuid,
TPL_CALLBACK,
RegisterImagePackage,
NULL,
&HiiRegistration
);
return EFI_SUCCESS;
}
/**
Install HII Image Package.
@retval EFI_SUCCESS Install HII Image Package successfully.
@return other Failed to install HII Image Package.
**/
EFI_STATUS
InstalLayoutDatabaseProtocol (
VOID
)
{
EFI_STATUS Status;
EFI_HANDLE DriverHandle;
LAYOUT_DATABASE_PROTOCOL *LayoutDatabase;
//
// Get DriverHandle and install LAYOUT_DATABASE_PROTOCOL on it
//
LayoutDatabase = AllocateZeroPool (sizeof (LAYOUT_DATABASE_PROTOCOL));
if (LayoutDatabase == NULL) {
return EFI_OUT_OF_RESOURCES;
}
LayoutDatabase->Size = sizeof (LAYOUT_DATABASE_PROTOCOL);
//
// Init and Install
//
DriverHandle = NULL;
Status = gBS->InstallMultipleProtocolInterfaces (
&DriverHandle,
&gLayoutDatabaseProtocolGuid,
LayoutDatabase,
NULL
);
LayoutDatabase->DriverHandle = DriverHandle;
LayoutDatabase->LayoutPkgHiiHandle = 0;
LayoutDatabase->ImagePkgHiiHandle = 0;
LayoutDatabase->LayoutPkgAddr = 0;
ASSERT (Status == EFI_SUCCESS);
return EFI_SUCCESS;
}
/**
The user Entry Point for module HiiLayoutPkgDxe. The user code starts with this function.
@param[in] ImageHandle The firmware allocated handle for the EFI image.
@param[in] SystemTable A pointer to the EFI System Table.
@retval EFI_SUCCESS The entry point is executed successfully.
@return other Some error occurs when executing this entry point.
**/
EFI_STATUS
EFIAPI
HiiLayoutPkgDxeEntryPoint (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
EFI_STATUS Status;
//
// Install HII Layout Pkg.
//
Status = InstalLayoutDatabaseProtocol ();
Status = InstallHiiLayoutPkg ();
Status = InstallHiiImagePkg ();
ASSERT_EFI_ERROR (Status);
return Status;
}