alder_lake_bios/EDK2/NtEmulatorPkg/VfrApp/VfrAppConOut.c

343 lines
10 KiB
C

/** @file
VFR application
;******************************************************************************
;* Copyright (c) 2017, 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 "VfrAppConOut.h"
EFI_HANDLE mConOutDevList[VFR_APP_MAX_CON_OUT_DEV_NUM] = {0};
UINTN mConOutDevCount = 0;
EFI_GUID *mConOutDevGuidList[] = {&gEfiGraphicsOutputProtocolGuid,
&gEfiSimpleTextOutProtocolGuid
};
STATIC
EFI_STATUS
AddConOutDevToList (
IN EFI_HANDLE Handle
)
{
UINTN Index;
if (mConOutDevCount >= VFR_APP_MAX_CON_OUT_DEV_NUM) {
return EFI_OUT_OF_RESOURCES;
}
for (Index = 0; Index < mConOutDevCount; Index++) {
if (mConOutDevList[Index] == Handle) {
return EFI_ALREADY_STARTED;
}
}
mConOutDevList[mConOutDevCount] = Handle;
mConOutDevCount++;
return EFI_SUCCESS;
}
STATIC
CHAR16 *
GetDeviceStr (
IN CONST EFI_HANDLE Handle
)
{
EFI_STATUS Status;
EFI_HANDLE *HandleBuffer;
UINTN NumberOfHandles;
UINTN Index;
EFI_COMPONENT_NAME2_PROTOCOL *ComponentName2;
CHAR16 *DeviceStr;
Status = gBS->LocateHandleBuffer (
ByProtocol,
&gEfiComponentName2ProtocolGuid,
NULL,
&NumberOfHandles,
&HandleBuffer
);
if (EFI_ERROR (Status)) {
return NULL;
}
for (Index = 0; Index < NumberOfHandles; Index++) {
Status = gBS->HandleProtocol (HandleBuffer[Index], &gEfiComponentName2ProtocolGuid, &ComponentName2);
if (EFI_ERROR (Status)) {
continue;
}
Status = ComponentName2->GetControllerName (ComponentName2, Handle, NULL, "en", &DeviceStr);
if (EFI_ERROR (Status)) {
continue;
}
FreePool (HandleBuffer);
return AllocateCopyPool (StrSize (DeviceStr), DeviceStr);
}
FreePool (HandleBuffer);
return NULL;
}
STATIC
CHAR16 *
GetDevicePathStr (
IN CONST EFI_HANDLE Handle
)
{
EFI_STATUS Status;
EFI_DEVICE_PATH_PROTOCOL *DevPath;
EFI_DEVICE_PATH_TO_TEXT_PROTOCOL *DevicePathToText;
Status = gBS->HandleProtocol (Handle, &gEfiDevicePathProtocolGuid, &DevPath);
if (EFI_ERROR (Status)) {
return NULL;
}
Status = gBS->LocateProtocol(&gEfiDevicePathToTextProtocolGuid, NULL, &DevicePathToText);
if (EFI_ERROR (Status)) {
return NULL;
}
return DevicePathToText->ConvertDevicePathToText (DevPath, FALSE, FALSE);
}
STATIC
EFI_STATUS
InstallDEProtocol (
IN EFI_HANDLE *Handle,
IN EFI_GUID *Protocol
)
{
EFI_STATUS Status;
VOID *Instance;
if (Handle == NULL) {
return EFI_INVALID_PARAMETER;
}
if (*Handle != NULL) {
Status = gBS->HandleProtocol (*Handle, Protocol, &Instance);
if (!EFI_ERROR (Status)) {
return Status;
}
}
return gBS->InstallProtocolInterface (Handle, Protocol, EFI_NATIVE_INTERFACE, NULL);
}
STATIC
EFI_STATUS
UninstallDEProtocol (
IN EFI_HANDLE Handle,
IN EFI_GUID *Protocol
)
{
EFI_STATUS Status;
VOID *Instance;
Status = gBS->HandleProtocol (Handle, Protocol, &Instance);
if (EFI_ERROR (Status)) {
return EFI_SUCCESS;
}
return gBS->UninstallProtocolInterface (Handle, Protocol, NULL);
}
VOID
EFIAPI
VfrAppConOutDevNotidyFunc (
IN EFI_EVENT Event,
IN VOID *Context
)
{
EFI_STATUS Status;
EFI_HANDLE *HandleBuffer;
UINTN NumberOfHandles;
UINTN Index;
VOID *Instance;
EFI_GUID *ConOutDevGuid;
if (Context == NULL) {
return;
}
ConOutDevGuid = (EFI_GUID *) Context;
Status = gBS->LocateHandleBuffer (
ByProtocol,
ConOutDevGuid,
NULL,
&NumberOfHandles,
&HandleBuffer
);
if (EFI_ERROR (Status)) {
return;
}
for (Index = 0; Index < NumberOfHandles; Index++) {
Status = gBS->HandleProtocol (HandleBuffer[Index], ConOutDevGuid, &Instance);
if (EFI_ERROR (Status)) {
continue;
}
Status = gBS->HandleProtocol (HandleBuffer[Index], &gEfiDevicePathProtocolGuid, &Instance);
if (EFI_ERROR (Status)) {
continue;
}
AddConOutDevToList (HandleBuffer[Index]);
}
FreePool (HandleBuffer);
}
EFI_STATUS
VfrAppConOutUpdateDESetting (
IN VFR_APP_PRIVATE_DATA *Private
)
{
UINTN Index;
EFI_HII_HANDLE Handle;
for (Index = 0; Index < mConOutDevCount; Index++) {
Handle = mConOutDevList[Index];
if (Handle == NULL) {
continue;
}
switch (Private->Configuration.ConOutDESetting[Index]) {
case VFR_APP_ACTIVE_DISPLAY_ENGINE_METRO:
InstallDEProtocol (&Handle, &gH2ODisplayEngineLocalMetroGuid);
UninstallDEProtocol (Handle, &gH2ODisplayEngineLocalTextGuid);
break;
case VFR_APP_ACTIVE_DISPLAY_ENGINE_TEXT:
InstallDEProtocol (&Handle, &gH2ODisplayEngineLocalTextGuid);
UninstallDEProtocol (Handle, &gH2ODisplayEngineLocalMetroGuid);
break;
}
}
return EFI_SUCCESS;
}
EFI_STATUS
VfrAppConOutUpdateDevLabel (
IN VFR_APP_PRIVATE_DATA *Private
)
{
UINTN Index;
EFI_STRING_ID Token;
EFI_STRING_ID TokenHelp;
EFI_HII_HANDLE HiiHandle;
CHAR16 *String;
VOID *StartOpCodeHandle;
VOID *EndOpCodeHandle;
VOID *OptionsOpCodeHandle;
EFI_IFR_GUID_LABEL *StartLabel;
EFI_IFR_GUID_LABEL *EndLabel;
UINT8 Type;
EFI_GUID FormSetGuid = VFR_APP_FORMSET_GUID;
StartOpCodeHandle = HiiAllocateOpCodeHandle ();
EndOpCodeHandle = HiiAllocateOpCodeHandle ();
OptionsOpCodeHandle = HiiAllocateOpCodeHandle ();
if (StartOpCodeHandle == NULL || EndOpCodeHandle == NULL || OptionsOpCodeHandle == NULL) {
return EFI_ABORTED;
}
StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (StartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));
StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
StartLabel->Number = LABEL_UPDATE_CON_OUT_LIST_START;
EndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (EndOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));
EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
EndLabel->Number = LABEL_UPDATE_CON_OUT_LIST_END;
Type = EFI_IFR_NUMERIC_SIZE_1;
HiiCreateOneOfOptionOpCode (OptionsOpCodeHandle, STRING_TOKEN(STR_ACTIVE_DISPLAY_ENGINE_METRO), EFI_IFR_OPTION_DEFAULT, Type, VFR_APP_ACTIVE_DISPLAY_ENGINE_METRO);
HiiCreateOneOfOptionOpCode (OptionsOpCodeHandle, STRING_TOKEN(STR_ACTIVE_DISPLAY_ENGINE_TEXT) , 0 , Type, VFR_APP_ACTIVE_DISPLAY_ENGINE_TEXT );
HiiHandle = Private->HiiHandle;
for (Index = 0; Index < mConOutDevCount; Index++) {
Token = STRING_TOKEN(STR_UNKNOWN_DEV);
String = GetDeviceStr (mConOutDevList[Index]);
if (String != NULL) {
Token = HiiSetString (HiiHandle, 0, String, NULL);
FreePool (String);
}
TokenHelp = STRING_TOKEN(STR_UNKNOWN_DEV);
String = GetDevicePathStr (mConOutDevList[Index]);
if (String != NULL) {
TokenHelp = HiiSetString (HiiHandle, 0, String, NULL);
FreePool (String);
}
HiiCreateOneOfOpCode (
StartOpCodeHandle,
(EFI_QUESTION_ID) (VFR_APP_KEY_CON_OUT_DEV_BASE + Index),
VFR_APP_CONFIGURATION_VARSTORE_ID,
(UINT16) ((UINTN) &Private->Configuration.ConOutDESetting[Index] - (UINTN) &Private->Configuration),
Token,
TokenHelp,
0,
Type,
OptionsOpCodeHandle,
NULL
);
}
HiiUpdateForm (
HiiHandle,
&FormSetGuid,
VFR_APP_FORM_ROOT,
StartOpCodeHandle,
EndOpCodeHandle
);
HiiFreeOpCodeHandle (StartOpCodeHandle);
HiiFreeOpCodeHandle (EndOpCodeHandle);
HiiFreeOpCodeHandle (OptionsOpCodeHandle);
return EFI_SUCCESS;
}
EFI_STATUS
VfrAppConOutDevInit (
VOID
)
{
EFI_STATUS Status;
UINTN Index;
EFI_EVENT Event;
VOID *Registration;
for (Index = 0; Index < sizeof (mConOutDevGuidList) / sizeof (EFI_GUID *); Index++) {
Status = gBS->CreateEvent (
EVT_NOTIFY_SIGNAL,
TPL_CALLBACK - 1, // Because DisplayType's level is TPL_CALLBACK, set lower level to override it.
VfrAppConOutDevNotidyFunc,
(VOID *) mConOutDevGuidList[Index],
&Event
);
if (!EFI_ERROR (Status)) {
gBS->RegisterProtocolNotify (
mConOutDevGuidList[Index],
Event,
&Registration
);
}
}
return EFI_SUCCESS;
}