345 lines
8.9 KiB
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;
|
|
}
|
|
|