904 lines
29 KiB
C
904 lines
29 KiB
C
/** @file
|
|
|
|
;******************************************************************************
|
|
;* Copyright (c) 2014 - 2020, Insyde Software Corporation. 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 <DisplaySelection.h>
|
|
|
|
UINT8 *mPtrToVbtTable = NULL;
|
|
PLUG_IN_ACTIVE_VIDEO_CONTROLLER_INFO *mPlugInVgaInfo = NULL;
|
|
|
|
EFI_DEVICE_PATH_PROTOCOL *
|
|
PartMatchInstance (
|
|
IN EFI_DEVICE_PATH_PROTOCOL *Multi,
|
|
IN EFI_DEVICE_PATH_PROTOCOL *Single
|
|
)
|
|
{
|
|
EFI_DEVICE_PATH_PROTOCOL *Instance;
|
|
UINTN InstanceSize;
|
|
UINTN SingleDpSize;
|
|
UINTN Size;
|
|
EFI_DEVICE_PATH_PROTOCOL *NewDevicePath;
|
|
EFI_DEVICE_PATH_PROTOCOL *OldDevicePath;
|
|
|
|
NewDevicePath = NULL;
|
|
|
|
if (Multi == NULL || Single == NULL) {
|
|
return FALSE;
|
|
}
|
|
|
|
Instance = GetNextDevicePathInstance (&Multi, &InstanceSize);
|
|
SingleDpSize = GetDevicePathSize (Single) - END_DEVICE_PATH_LENGTH;
|
|
InstanceSize -= END_DEVICE_PATH_LENGTH;
|
|
|
|
while (Instance != NULL) {
|
|
|
|
Size = (SingleDpSize < InstanceSize) ? SingleDpSize : InstanceSize;
|
|
|
|
if ((CompareMem (Instance, Single, Size) == 0)) {
|
|
OldDevicePath = NewDevicePath;
|
|
NewDevicePath = AppendDevicePathInstance (OldDevicePath, Instance);
|
|
|
|
if (OldDevicePath != NULL) {
|
|
gBS->FreePool (OldDevicePath);
|
|
}
|
|
}
|
|
|
|
gBS->FreePool (Instance);
|
|
Instance = GetNextDevicePathInstance (&Multi, &InstanceSize);
|
|
InstanceSize -= END_DEVICE_PATH_LENGTH;
|
|
}
|
|
|
|
return NewDevicePath;
|
|
}
|
|
|
|
EFI_STATUS
|
|
RemainingDevicePathFromConOutVar (
|
|
IN EFI_HANDLE VgaControllerHandle,
|
|
OUT EFI_DEVICE_PATH_PROTOCOL **RemainingDevicePath
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
EFI_DEVICE_PATH_PROTOCOL *ConOutVar;
|
|
UINTN ConOutSize;
|
|
EFI_DEVICE_PATH_PROTOCOL *VideoOutputDevicePath;
|
|
EFI_DEVICE_PATH_PROTOCOL *ControllerDevicePath;
|
|
|
|
ConOutVar = NULL;
|
|
*RemainingDevicePath = NULL;
|
|
VideoOutputDevicePath = NULL;
|
|
//
|
|
// Get last run Acpi_ADR Value from ConOut.
|
|
//
|
|
ConOutVar = GetVariableAndSize (
|
|
L"ConOut",
|
|
&gEfiGlobalVariableGuid,
|
|
&ConOutSize
|
|
);
|
|
if (ConOutVar != NULL) {
|
|
Status = gBS->HandleProtocol (
|
|
VgaControllerHandle,
|
|
&gEfiDevicePathProtocolGuid,
|
|
(VOID**)&ControllerDevicePath
|
|
);
|
|
|
|
VideoOutputDevicePath = PartMatchInstance (ConOutVar, ControllerDevicePath);
|
|
gBS->FreePool (ConOutVar);
|
|
|
|
if (VideoOutputDevicePath != NULL) {
|
|
while (!IsDevicePathEnd (VideoOutputDevicePath)) {
|
|
if ((DevicePathType (VideoOutputDevicePath) == ACPI_DEVICE_PATH) &&
|
|
(DevicePathSubType (VideoOutputDevicePath) == ACPI_ADR_DP)) {
|
|
if (DevicePathNodeLength(VideoOutputDevicePath) != sizeof (ACPI_ADR_DEVICE_PATH)) {
|
|
return EFI_SUCCESS;
|
|
} else {
|
|
*RemainingDevicePath = VideoOutputDevicePath;
|
|
}
|
|
}
|
|
VideoOutputDevicePath = NextDevicePathNode (VideoOutputDevicePath);
|
|
}
|
|
}
|
|
}
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
ACPI_ADR_DEVICE_PATH *
|
|
GetAcpiADRFromDevicePath (
|
|
IN EFI_DEVICE_PATH_PROTOCOL *DevicePath
|
|
)
|
|
{
|
|
ACPI_ADR_DEVICE_PATH *AcpiADR;
|
|
|
|
while (!IsDevicePathEnd (DevicePath)) {
|
|
if ((DevicePathType (DevicePath) == ACPI_DEVICE_PATH) &&
|
|
(DevicePathSubType (DevicePath) == ACPI_ADR_DP)) {
|
|
AcpiADR = (ACPI_ADR_DEVICE_PATH*)DuplicateDevicePath(DevicePath);
|
|
return AcpiADR;
|
|
}
|
|
DevicePath = NextDevicePathNode (DevicePath);
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
EFI_STATUS
|
|
UpdateDisplayPortInfo (
|
|
IN PLUG_IN_ACTIVE_VIDEO_CONTROLLER_INFO *VgaControllerInfo
|
|
)
|
|
{
|
|
UINTN DriverBindingHandleCount;
|
|
EFI_HANDLE *DriverBindingHandleBuffer;
|
|
EFI_STATUS Status;
|
|
UINTN DrvierBindingIndex;
|
|
UINTN ChildHandleIndex;
|
|
CHAR16 *TempControllerName;
|
|
CHAR16 *TempVideoOutputName;
|
|
CHAR16 *ControllerName;
|
|
CHAR16 *VideoOutputName;
|
|
EFI_COMPONENT_NAME2_PROTOCOL *ComponentNameInterface;
|
|
UINTN ChildhandleCount;
|
|
EFI_HANDLE *ChildhandleBuffer;
|
|
EFI_DEVICE_PATH_PROTOCOL *ChildHandleDevicePath;
|
|
EFI_DEVICE_PATH_PROTOCOL *ControllerDevicePath;
|
|
VIDEO_OUTPUT_PORT_INFO *TempDisplayPortInfo;
|
|
UINTN Index;
|
|
UINTN StringSize;
|
|
|
|
|
|
TempVideoOutputName = NULL;
|
|
TempControllerName = NULL;
|
|
VgaControllerInfo->NumOfConnectedPort = 0;
|
|
ComponentNameInterface = NULL;
|
|
DriverBindingHandleCount = 0;
|
|
ChildhandleCount = 0;
|
|
|
|
Status = gBS->HandleProtocol (
|
|
VgaControllerInfo->ControllerHandle,
|
|
&gEfiDevicePathProtocolGuid,
|
|
(VOID**)&ControllerDevicePath
|
|
);
|
|
if (EFI_ERROR(Status)) {
|
|
return EFI_NOT_FOUND;
|
|
}
|
|
|
|
//
|
|
// Get Controller Name by DriverBinding Protocol.
|
|
//
|
|
Status = gBS->LocateHandleBuffer (
|
|
ByProtocol,
|
|
&gEfiDriverBindingProtocolGuid,
|
|
NULL,
|
|
&DriverBindingHandleCount,
|
|
&DriverBindingHandleBuffer
|
|
);
|
|
if (EFI_ERROR(Status) || (DriverBindingHandleCount == 0)) {
|
|
return Status;
|
|
}
|
|
|
|
for (DrvierBindingIndex = 0; DrvierBindingIndex < DriverBindingHandleCount; DrvierBindingIndex++) {
|
|
Status = gBS->HandleProtocol (
|
|
DriverBindingHandleBuffer[DrvierBindingIndex],
|
|
&gEfiComponentName2ProtocolGuid,
|
|
(VOID**)&ComponentNameInterface
|
|
);
|
|
if (!EFI_ERROR(Status)) {
|
|
TempControllerName = NULL;
|
|
Status = ComponentNameInterface->GetControllerName (
|
|
ComponentNameInterface,
|
|
VgaControllerInfo->ControllerHandle,
|
|
NULL,
|
|
LANGUAGE_CODE_ENGLISH,
|
|
&TempControllerName
|
|
);
|
|
if (!EFI_ERROR(Status)) {
|
|
//
|
|
// Update Controller Name.
|
|
//
|
|
StringSize = StrSize (TempControllerName);
|
|
ControllerName = AllocateZeroPool (StringSize);
|
|
ASSERT (ControllerName != NULL);
|
|
if (ControllerName == NULL) {
|
|
return EFI_OUT_OF_RESOURCES;
|
|
}
|
|
StrCpyS (ControllerName, StringSize / sizeof (CHAR16), TempControllerName);
|
|
VgaControllerInfo->ControllerName = ControllerName;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (DriverBindingHandleCount != 0) {
|
|
gBS->FreePool (DriverBindingHandleBuffer);
|
|
}
|
|
|
|
if (EFI_ERROR(Status)) {
|
|
return Status;
|
|
}
|
|
//
|
|
// Get connected display port name.
|
|
//
|
|
Status = gBS->LocateHandleBuffer (
|
|
ByProtocol,
|
|
&gEfiEdidDiscoveredProtocolGuid,
|
|
NULL,
|
|
&ChildhandleCount,
|
|
&ChildhandleBuffer
|
|
);
|
|
if (EFI_ERROR(Status)) {
|
|
return Status;
|
|
}
|
|
|
|
TempDisplayPortInfo = AllocateZeroPool (sizeof(VIDEO_OUTPUT_PORT_INFO) * ChildhandleCount);
|
|
ASSERT (TempDisplayPortInfo != NULL);
|
|
if (TempDisplayPortInfo == NULL) {
|
|
return EFI_OUT_OF_RESOURCES;
|
|
}
|
|
|
|
for (ChildHandleIndex = 0; ChildHandleIndex < ChildhandleCount; ChildHandleIndex++) {
|
|
Status = gBS->HandleProtocol (
|
|
ChildhandleBuffer[ChildHandleIndex],
|
|
&gEfiDevicePathProtocolGuid,
|
|
(VOID*)&ChildHandleDevicePath
|
|
);
|
|
if (!EFI_ERROR(Status)) {
|
|
if (CompareMem (
|
|
ControllerDevicePath,
|
|
ChildHandleDevicePath,
|
|
GetDevicePathSize (ControllerDevicePath) - END_DEVICE_PATH_LENGTH
|
|
) == 0) {
|
|
Status = ComponentNameInterface->GetControllerName (
|
|
ComponentNameInterface,
|
|
VgaControllerInfo->ControllerHandle,
|
|
ChildhandleBuffer[ChildHandleIndex],
|
|
LANGUAGE_CODE_ENGLISH,
|
|
&TempVideoOutputName
|
|
);
|
|
if (!EFI_ERROR(Status)) {
|
|
StringSize = StrSize (TempVideoOutputName);
|
|
VideoOutputName = AllocateZeroPool (StringSize);
|
|
ASSERT (VideoOutputName != NULL);
|
|
if (VideoOutputName == NULL) {
|
|
return EFI_OUT_OF_RESOURCES;
|
|
}
|
|
StrCpyS (VideoOutputName, StringSize / sizeof (CHAR16), TempVideoOutputName);
|
|
TempDisplayPortInfo[ChildHandleIndex].PortName = VideoOutputName;
|
|
} else {
|
|
TempDisplayPortInfo[ChildHandleIndex].PortName = L"\0";
|
|
}
|
|
TempDisplayPortInfo[ChildHandleIndex].PortAcpiADR = GetAcpiADRFromDevicePath (ChildHandleDevicePath);
|
|
VgaControllerInfo->NumOfConnectedPort++;
|
|
}
|
|
}
|
|
}
|
|
|
|
Index = 0;
|
|
VgaControllerInfo->ConnectedPortInfo = AllocateZeroPool (sizeof(PLUG_IN_ACTIVE_VIDEO_CONTROLLER_INFO) * VgaControllerInfo->NumOfConnectedPort);
|
|
ASSERT (VgaControllerInfo->ConnectedPortInfo != NULL);
|
|
if (VgaControllerInfo->ConnectedPortInfo == NULL) {
|
|
return EFI_OUT_OF_RESOURCES;
|
|
}
|
|
for (ChildHandleIndex = 0; ChildHandleIndex < ChildhandleCount; ChildHandleIndex++) {
|
|
if (TempDisplayPortInfo[ChildHandleIndex].PortAcpiADR != NULL) {
|
|
VgaControllerInfo->ConnectedPortInfo[Index].PortName = TempDisplayPortInfo[ChildHandleIndex].PortName;
|
|
VgaControllerInfo->ConnectedPortInfo[Index].PortAcpiADR = TempDisplayPortInfo[ChildHandleIndex].PortAcpiADR;
|
|
Index++;
|
|
}
|
|
}
|
|
gBS->FreePool (TempDisplayPortInfo);
|
|
if (ChildhandleCount != 0) {
|
|
gBS->FreePool (ChildhandleBuffer);
|
|
}
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
EFI_STATUS
|
|
GetAcpiADRFromGopHandle (
|
|
IN EFI_HANDLE VgaControllerHandle,
|
|
OUT ACPI_ADR_DEVICE_PATH **AcpiADR
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
EFI_HANDLE *GopHandleBuffer;
|
|
UINTN GopHandleCount;
|
|
UINTN Index;
|
|
EFI_DEVICE_PATH_PROTOCOL *ControllerDevicePath;
|
|
EFI_DEVICE_PATH_PROTOCOL *GopDevicePath;
|
|
|
|
Status = gBS->HandleProtocol (
|
|
VgaControllerHandle,
|
|
&gEfiDevicePathProtocolGuid,
|
|
(VOID**)&ControllerDevicePath
|
|
);
|
|
if (EFI_ERROR(Status)) {
|
|
return Status;
|
|
}
|
|
|
|
GopHandleCount = 0;
|
|
Status = gBS->LocateHandleBuffer (
|
|
ByProtocol,
|
|
&gEfiGraphicsOutputProtocolGuid,
|
|
NULL,
|
|
&GopHandleCount,
|
|
&GopHandleBuffer
|
|
);
|
|
if (!EFI_ERROR (Status)) {
|
|
//
|
|
// Add all the child handles as possible Console Device
|
|
//
|
|
for (Index = 0; Index < GopHandleCount; Index++) {
|
|
Status = gBS->HandleProtocol (
|
|
GopHandleBuffer[Index],
|
|
&gEfiDevicePathProtocolGuid,
|
|
(VOID*)&GopDevicePath
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
continue;
|
|
}
|
|
|
|
if (CompareMem (ControllerDevicePath, GopDevicePath, GetDevicePathSize (ControllerDevicePath) - END_DEVICE_PATH_LENGTH) == 0) {
|
|
*AcpiADR = GetAcpiADRFromDevicePath (GopDevicePath);
|
|
gBS->FreePool (GopHandleBuffer);
|
|
return EFI_SUCCESS;
|
|
}
|
|
}
|
|
|
|
if (GopHandleCount != 0) {
|
|
gBS->FreePool (GopHandleBuffer);
|
|
}
|
|
}
|
|
|
|
return EFI_NOT_FOUND;
|
|
}
|
|
|
|
EFI_STATUS
|
|
PlugInVgaUpdateInfo (
|
|
VOID
|
|
)
|
|
{
|
|
EFI_HANDLE *HandleList;
|
|
EFI_HANDLE *PtrToHandle;
|
|
UINTN NumOfHandles;
|
|
UINTN Index;
|
|
PLUG_IN_ACTIVE_VIDEO_CONTROLLER_INFO *PtrToList;
|
|
UINTN VarSize;
|
|
EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath;
|
|
EFI_STATUS Status;
|
|
EFI_CONSOLE_CONTROL_PROTOCOL *ConsoleControl;
|
|
|
|
if (mPlugInVgaInfo != NULL) {
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
HandleList = NULL;
|
|
HandleList = GetVariableAndSize (
|
|
PLUG_IN_VIDEO_DISPLAY_INFO_VAR_NAME,
|
|
&gEfiGenericVariableGuid,
|
|
&VarSize
|
|
);
|
|
if (HandleList == NULL) {
|
|
return EFI_NOT_FOUND;
|
|
}
|
|
|
|
PtrToHandle = HandleList;
|
|
NumOfHandles = 0;
|
|
while (*PtrToHandle != NULL_HANDLE) {
|
|
NumOfHandles++;
|
|
PtrToHandle++;
|
|
}
|
|
if (NumOfHandles == 0) {
|
|
return EFI_NOT_FOUND;
|
|
}
|
|
//
|
|
// Add the NULL PLUG_IN_ACTIVE_VIDEO_CONTROLLER_INFO as the end of list.
|
|
//
|
|
mPlugInVgaInfo = AllocateZeroPool ((NumOfHandles + 1) * sizeof(PLUG_IN_ACTIVE_VIDEO_CONTROLLER_INFO));
|
|
ASSERT (mPlugInVgaInfo != NULL);
|
|
if (mPlugInVgaInfo == NULL) {
|
|
return EFI_OUT_OF_RESOURCES;
|
|
}
|
|
//
|
|
// Set Mode to the TextMode before re-ConnectController.
|
|
//
|
|
Status = gBS->LocateProtocol (&gEfiConsoleControlProtocolGuid, NULL, (VOID**)&ConsoleControl);
|
|
if (EFI_ERROR (Status)) {
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
Status = ConsoleControl->SetMode (ConsoleControl, EfiConsoleControlScreenText);
|
|
|
|
PtrToList = mPlugInVgaInfo;
|
|
|
|
for (Index = 0; Index < NumOfHandles; Index++) {
|
|
|
|
PtrToList->ControllerHandle = HandleList[Index];
|
|
//
|
|
// Get Original RemainingDevicePath.
|
|
//
|
|
RemainingDevicePathFromConOutVar (PtrToList->ControllerHandle, &RemainingDevicePath);
|
|
|
|
Status = gBS->DisconnectController (PtrToList->ControllerHandle, NULL, NULL);
|
|
//
|
|
// Parsing RemainingDeivePath == NULL to get all display prot info.
|
|
//
|
|
gBS->ConnectController (PtrToList->ControllerHandle, NULL, NULL, FALSE);
|
|
UpdateDisplayPortInfo (PtrToList);
|
|
GetAcpiADRFromGopHandle (PtrToList->ControllerHandle, &PtrToList->DefaultAcpiADR);
|
|
gBS->DisconnectController (PtrToList->ControllerHandle, NULL, NULL);
|
|
//
|
|
// Restore original display selection.
|
|
//
|
|
gBS->ConnectController (PtrToList->ControllerHandle, NULL, RemainingDevicePath, TRUE);
|
|
|
|
PtrToList++;
|
|
}
|
|
|
|
gBS->FreePool (HandleList);
|
|
|
|
return Status;
|
|
}
|
|
|
|
VOID
|
|
FindDefaultOption (
|
|
IN OUT PLUG_IN_ACTIVE_VIDEO_CONTROLLER_INFO *VgaControllerInfo,
|
|
IN EFI_DEVICE_PATH_PROTOCOL *ConOutDevicePath,
|
|
IN UINTN NumOfOptions,
|
|
OUT EFI_IFR_ONE_OF_OPTION *OptionList,
|
|
IN VOID *OptionsOpCodeHandle
|
|
)
|
|
{
|
|
ACPI_ADR_DEVICE_PATH *AcpiADR;
|
|
UINTN Index;
|
|
|
|
AcpiADR = NULL;
|
|
|
|
while (!IsDevicePathEnd (ConOutDevicePath)) {
|
|
if ((DevicePathType (ConOutDevicePath) == ACPI_DEVICE_PATH) &&
|
|
(DevicePathSubType (ConOutDevicePath) == ACPI_ADR_DP)) {
|
|
if (DevicePathNodeLength(ConOutDevicePath) != sizeof (ACPI_ADR_DEVICE_PATH)){
|
|
VgaControllerInfo->SelectedAcpiADR = VgaControllerInfo->DefaultAcpiADR;
|
|
HiiCreateOneOfOptionOpCode (
|
|
OptionsOpCodeHandle,
|
|
OptionList[NumOfOptions - 1].Option,
|
|
EFI_IFR_OPTION_DEFAULT,
|
|
EFI_IFR_NUMERIC_SIZE_4,
|
|
(UINT32)OptionList[NumOfOptions - 1].Value.u32
|
|
);
|
|
return;
|
|
}
|
|
AcpiADR = (ACPI_ADR_DEVICE_PATH*)ConOutDevicePath;
|
|
}
|
|
ConOutDevicePath = NextDevicePathNode (ConOutDevicePath);
|
|
}
|
|
|
|
if (AcpiADR == NULL) {
|
|
return;
|
|
}
|
|
|
|
for (Index = 0; Index < NumOfOptions; Index++) {
|
|
if (AcpiADR->ADR == OptionList[Index].Value.u32) {
|
|
VgaControllerInfo->SelectedAcpiADR = VgaControllerInfo->ConnectedPortInfo[Index].PortAcpiADR;
|
|
HiiCreateOneOfOptionOpCode (
|
|
OptionsOpCodeHandle,
|
|
OptionList[Index].Option,
|
|
EFI_IFR_OPTION_DEFAULT,
|
|
EFI_IFR_NUMERIC_SIZE_4,
|
|
(UINT32)OptionList[Index].Value.u32
|
|
);
|
|
return;
|
|
}
|
|
}
|
|
|
|
OptionList[NumOfOptions - 1].Flags = EFI_IFR_OPTION_DEFAULT;
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
EFI_DEVICE_PATH_PROTOCOL *
|
|
UpdateDevicePath (
|
|
IN EFI_DEVICE_PATH_PROTOCOL *Source,
|
|
IN EFI_DEVICE_PATH_PROTOCOL *ControllerDevicePath,
|
|
IN EFI_DEVICE_PATH_PROTOCOL *CustomizedConDevicePath
|
|
)
|
|
{
|
|
EFI_DEVICE_PATH_PROTOCOL *NewDevicePath;
|
|
EFI_DEVICE_PATH_PROTOCOL *OldDevicePath;
|
|
EFI_DEVICE_PATH_PROTOCOL *Instance;
|
|
EFI_DEVICE_PATH_PROTOCOL *PtrToSrc;
|
|
UINTN Size;
|
|
EFI_DEVICE_PATH_PROTOCOL *BufferPtr;
|
|
|
|
|
|
NewDevicePath = NULL;
|
|
Instance = NULL;
|
|
|
|
PtrToSrc = Source;
|
|
while (PtrToSrc != NULL) {
|
|
Instance = GetNextDevicePathInstance (&PtrToSrc, &Size);
|
|
BufferPtr = Instance;
|
|
|
|
if (CompareMem (Instance, ControllerDevicePath, GetDevicePathSize (ControllerDevicePath) - END_DEVICE_PATH_LENGTH) == 0) {
|
|
Instance = CustomizedConDevicePath;
|
|
}
|
|
|
|
OldDevicePath = NewDevicePath;
|
|
NewDevicePath = AppendDevicePathInstance (NewDevicePath, Instance);
|
|
|
|
if (OldDevicePath != NULL) {
|
|
gBS->FreePool (OldDevicePath);
|
|
}
|
|
gBS->FreePool (BufferPtr);
|
|
}
|
|
|
|
return NewDevicePath;
|
|
}
|
|
|
|
EFI_STATUS
|
|
PlugInVgaDisplaySelectionSave (
|
|
VOID
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
EFI_DEVICE_PATH_PROTOCOL *ControllerDevicePath;
|
|
EFI_DEVICE_PATH_PROTOCOL *NewDevicePath;
|
|
EFI_DEVICE_PATH_PROTOCOL *NewConOutVar;
|
|
EFI_DEVICE_PATH_PROTOCOL *OldConOutVar;
|
|
UINTN ConOutSize;
|
|
PLUG_IN_ACTIVE_VIDEO_CONTROLLER_INFO *PtrToList;
|
|
BOOLEAN UpdateConOutVar;
|
|
|
|
|
|
if (mPlugInVgaInfo == NULL) {
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
|
|
PtrToList = mPlugInVgaInfo;
|
|
NewDevicePath = NULL;
|
|
UpdateConOutVar = FALSE;
|
|
Status = EFI_UNSUPPORTED;
|
|
|
|
NewConOutVar = GetVariableAndSize (
|
|
L"ConOut",
|
|
&gEfiGlobalVariableGuid,
|
|
&ConOutSize
|
|
);
|
|
|
|
while (PtrToList->ControllerHandle != NULL_HANDLE) {
|
|
Status = gBS->HandleProtocol (
|
|
PtrToList->ControllerHandle,
|
|
&gEfiDevicePathProtocolGuid,
|
|
(VOID**)&ControllerDevicePath
|
|
);
|
|
|
|
if (!EFI_ERROR(Status)&& (PtrToList->SelectedAcpiADR != NULL)) {
|
|
NewDevicePath = AppendDevicePathNode (ControllerDevicePath, (EFI_DEVICE_PATH_PROTOCOL*)PtrToList->SelectedAcpiADR);
|
|
OldConOutVar = NewConOutVar;
|
|
NewConOutVar = UpdateDevicePath (OldConOutVar, ControllerDevicePath, NewDevicePath);
|
|
UpdateConOutVar =TRUE;
|
|
gBS->FreePool (OldConOutVar);
|
|
}
|
|
|
|
PtrToList++;
|
|
}
|
|
|
|
if (UpdateConOutVar) {
|
|
ConOutSize = GetDevicePathSize (NewConOutVar);
|
|
Status = gRT->SetVariable (
|
|
L"ConOut",
|
|
&gEfiGlobalVariableGuid,
|
|
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
|
|
ConOutSize,
|
|
NewConOutVar
|
|
);
|
|
}
|
|
|
|
return Status;
|
|
}
|
|
|
|
EFI_STATUS
|
|
PlugInVideoDisplaySelectionOption (
|
|
IN EFI_QUESTION_ID QuestionId,
|
|
IN EFI_IFR_TYPE_VALUE *Value
|
|
)
|
|
{
|
|
PLUG_IN_ACTIVE_VIDEO_CONTROLLER_INFO *PtrToList;
|
|
UINTN Index;
|
|
|
|
if (mPlugInVgaInfo == NULL) {
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
|
|
PtrToList = mPlugInVgaInfo + (QuestionId - KEY_PLUG_IN_DISPLAY_SELECTION1);
|
|
|
|
if (Value->u32 == 0) {
|
|
PtrToList->SelectedAcpiADR = PtrToList->DefaultAcpiADR;
|
|
} else {
|
|
for (Index = 0; Index < PtrToList->NumOfConnectedPort; Index++) {
|
|
if (PtrToList->ConnectedPortInfo[Index].PortAcpiADR->ADR == Value->u32)
|
|
PtrToList->SelectedAcpiADR = PtrToList->ConnectedPortInfo[Index].PortAcpiADR;
|
|
}
|
|
}
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
EFI_STATUS
|
|
PlugInVideoDisplaySelectionLabel (
|
|
IN EFI_HII_HANDLE HiiHandle
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
EFI_IFR_ONE_OF_OPTION *OptionList;
|
|
UINTN OptionsConut;
|
|
PLUG_IN_ACTIVE_VIDEO_CONTROLLER_INFO *PtrToList;
|
|
UINTN ControllerIndex;
|
|
UINTN ChildHandleIndex;
|
|
EFI_STRING_ID ControllerStringId;
|
|
EFI_STRING_ID ChildStringId;
|
|
EFI_QUESTION_ID QuestionId;
|
|
EFI_DEVICE_PATH_PROTOCOL *ConOutVar;
|
|
UINTN ConOutSize;
|
|
EFI_DEVICE_PATH_PROTOCOL *MatchConOutDevice;
|
|
EFI_DEVICE_PATH_PROTOCOL *ControllerDevicePath;
|
|
EFI_STRING_ID HelpStringId;
|
|
CHAR16 *PluginHelpString = \
|
|
L"Display Selection for Plug-in Vga Controller, Only supported Uefi Boot mode";
|
|
|
|
VOID *StartOpCodeHandle;
|
|
EFI_IFR_GUID_LABEL *StartLabel;
|
|
VOID *OptionsOpCodeHandle;
|
|
|
|
if (mPlugInVgaInfo == NULL) {
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
|
|
ConOutVar = NULL;
|
|
ConOutVar = GetVariableAndSize (
|
|
L"ConOut",
|
|
&gEfiGlobalVariableGuid,
|
|
&ConOutSize
|
|
);
|
|
if (ConOutVar == NULL) {
|
|
return EFI_NOT_FOUND;
|
|
}
|
|
|
|
PtrToList = mPlugInVgaInfo;
|
|
ControllerIndex = 0;
|
|
while (PtrToList->ControllerHandle != NULL_HANDLE) {
|
|
StartOpCodeHandle = HiiAllocateOpCodeHandle ();
|
|
ASSERT (StartOpCodeHandle != NULL);
|
|
|
|
OptionsOpCodeHandle= HiiAllocateOpCodeHandle ();
|
|
ASSERT ( OptionsOpCodeHandle != NULL);
|
|
|
|
StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (StartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));
|
|
StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
|
|
StartLabel->Number = PLUG_IN_DISPLAY_SELECTION_START_LABEL;
|
|
|
|
Status = gBS->HandleProtocol (
|
|
PtrToList->ControllerHandle,
|
|
&gEfiDevicePathProtocolGuid,
|
|
(VOID**)&ControllerDevicePath
|
|
);
|
|
|
|
MatchConOutDevice = PartMatchInstance (ConOutVar, ControllerDevicePath);
|
|
if (MatchConOutDevice == NULL) {
|
|
PtrToList++;
|
|
ControllerIndex++;
|
|
continue;
|
|
}
|
|
//
|
|
// Add the Controller Name.
|
|
//
|
|
ControllerStringId=HiiSetString (HiiHandle, 0, PtrToList->ControllerName, NULL);
|
|
HelpStringId=HiiSetString (HiiHandle, 0, PluginHelpString, NULL);
|
|
//
|
|
// Add the Video Output Ports.
|
|
//
|
|
OptionsConut = (PtrToList->NumOfConnectedPort + 1);
|
|
OptionList = AllocateZeroPool (sizeof(EFI_IFR_ONE_OF_OPTION) * OptionsConut);
|
|
if (OptionList == NULL) {
|
|
Status = EFI_OUT_OF_RESOURCES;
|
|
ASSERT_EFI_ERROR (Status);
|
|
gBS->FreePool (MatchConOutDevice);
|
|
gBS->FreePool (ConOutVar);
|
|
return Status;
|
|
}
|
|
|
|
for (ChildHandleIndex = 0; ChildHandleIndex < PtrToList->NumOfConnectedPort; ChildHandleIndex++) {
|
|
ChildStringId=HiiSetString (HiiHandle, 0, PtrToList->ConnectedPortInfo[ChildHandleIndex].PortName, NULL);
|
|
OptionList[ChildHandleIndex].Option = ChildStringId;
|
|
OptionList[ChildHandleIndex].Value.u32 = PtrToList->ConnectedPortInfo[ChildHandleIndex].PortAcpiADR->ADR;
|
|
HiiCreateOneOfOptionOpCode (
|
|
OptionsOpCodeHandle,
|
|
ChildStringId,
|
|
EFI_IFR_TYPE_NUM_SIZE_32,
|
|
EFI_IFR_NUMERIC_SIZE_4,
|
|
(UINT32)PtrToList->ConnectedPortInfo[ChildHandleIndex].PortAcpiADR->ADR
|
|
);
|
|
}
|
|
|
|
ChildStringId=HiiSetString (HiiHandle, 0, L"Default", NULL);
|
|
OptionList[OptionsConut - 1].Option = ChildStringId;
|
|
OptionList[OptionsConut - 1].Value.u32 = 0;
|
|
HiiCreateOneOfOptionOpCode (
|
|
OptionsOpCodeHandle,
|
|
ChildStringId,
|
|
EFI_IFR_TYPE_NUM_SIZE_32,
|
|
EFI_IFR_NUMERIC_SIZE_4,
|
|
(UINT32)0
|
|
);
|
|
|
|
FindDefaultOption (PtrToList, MatchConOutDevice, OptionsConut, OptionList, OptionsOpCodeHandle);
|
|
|
|
|
|
QuestionId = (EFI_QUESTION_ID)(KEY_PLUG_IN_DISPLAY_SELECTION1 + ControllerIndex);
|
|
|
|
HiiCreateOneOfOpCode (
|
|
StartOpCodeHandle,
|
|
QuestionId,
|
|
INVALID_VARSTORE_ID,
|
|
0,
|
|
ControllerStringId,
|
|
HelpStringId,
|
|
0x04,
|
|
EFI_IFR_NUMERIC_SIZE_4,
|
|
OptionsOpCodeHandle,
|
|
NULL
|
|
);
|
|
|
|
HiiUpdateForm (
|
|
HiiHandle,
|
|
NULL,
|
|
(EFI_FORM_ID)IGFX_FORM_ID,
|
|
StartOpCodeHandle,
|
|
NULL
|
|
);
|
|
HiiFreeOpCodeHandle (StartOpCodeHandle);
|
|
HiiFreeOpCodeHandle (OptionsOpCodeHandle);
|
|
gBS->FreePool (MatchConOutDevice);
|
|
|
|
PtrToList++;
|
|
ControllerIndex++;
|
|
}
|
|
|
|
gBS->FreePool (ConOutVar);
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
EFI_STATUS
|
|
ClearFormDataFromLabel (
|
|
IN EFI_HII_HANDLE HiiHandle,
|
|
IN EFI_FORM_ID FormID,
|
|
IN UINT16 Label
|
|
)
|
|
{
|
|
VOID *StartOpCodeHandle;
|
|
EFI_IFR_GUID_LABEL *StartLabel;
|
|
VOID *OptionsOpCodeHandle;
|
|
StartOpCodeHandle = HiiAllocateOpCodeHandle ();
|
|
ASSERT (StartOpCodeHandle != NULL);
|
|
|
|
OptionsOpCodeHandle= HiiAllocateOpCodeHandle ();
|
|
ASSERT ( OptionsOpCodeHandle != NULL);
|
|
|
|
StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (StartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));
|
|
StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
|
|
StartLabel->Number = Label;
|
|
|
|
HiiUpdateForm (
|
|
HiiHandle,
|
|
NULL,
|
|
(EFI_FORM_ID)FormID,
|
|
StartOpCodeHandle,
|
|
NULL
|
|
);
|
|
HiiFreeOpCodeHandle (StartOpCodeHandle);
|
|
HiiFreeOpCodeHandle (OptionsOpCodeHandle);
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
EFI_STATUS
|
|
InitialDualVgaControllersLabel (
|
|
IN EFI_HII_HANDLE HiiHandle
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
EFI_LEGACY_BIOS_PROTOCOL *LegacyBios;
|
|
UINTN OptionsConut;
|
|
CHIPSET_CONFIGURATION *SetupVariable;
|
|
CHIPSET_CONFIGURATION SetupNvData;
|
|
UINT16 VarOffset;
|
|
VOID *StartOpCodeHandle;
|
|
EFI_IFR_GUID_LABEL *StartLabel;
|
|
VOID *OptionsOpCodeHandle;
|
|
UINT8 Flags;
|
|
|
|
SetupVariable = (CHIPSET_CONFIGURATION *)(gSUBrowser->SCBuffer);
|
|
|
|
Status = gBS->LocateProtocol (
|
|
&gEfiLegacyBiosProtocolGuid,
|
|
NULL,
|
|
(VOID **)&LegacyBios
|
|
);
|
|
|
|
StartOpCodeHandle = HiiAllocateOpCodeHandle ();
|
|
ASSERT (StartOpCodeHandle != NULL);
|
|
|
|
OptionsOpCodeHandle= HiiAllocateOpCodeHandle ();
|
|
ASSERT ( OptionsOpCodeHandle != NULL);
|
|
|
|
StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (StartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));
|
|
StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
|
|
StartLabel->Number = DUAL_VGA_SUPPORT_START_LABEL;
|
|
|
|
//
|
|
// Only supported in the non-CSM mode.
|
|
//
|
|
if (EFI_ERROR(Status)) {
|
|
OptionsConut = 2; // Enable and disable.
|
|
Flags = EFI_IFR_TYPE_NUM_SIZE_8;
|
|
if (SetupVariable->UefiDualVgaControllers == DUAL_VGA_CONTROLLER_ENABLE) {
|
|
Flags = EFI_IFR_OPTION_DEFAULT;
|
|
}
|
|
HiiCreateOneOfOptionOpCode (
|
|
OptionsOpCodeHandle,
|
|
STRING_TOKEN(STR_ENABLED_TEXT),
|
|
Flags,
|
|
EFI_IFR_NUMERIC_SIZE_1,
|
|
DUAL_VGA_CONTROLLER_ENABLE
|
|
);
|
|
Flags = EFI_IFR_TYPE_NUM_SIZE_8;
|
|
if (DUAL_VGA_CONTROLLER_DISABLE == SetupVariable->UefiDualVgaControllers) {
|
|
Flags = EFI_IFR_OPTION_DEFAULT;
|
|
}
|
|
HiiCreateOneOfOptionOpCode (
|
|
OptionsOpCodeHandle,
|
|
STRING_TOKEN(STR_DISABLED_TEXT),
|
|
Flags,
|
|
EFI_IFR_NUMERIC_SIZE_1,
|
|
DUAL_VGA_CONTROLLER_DISABLE
|
|
);
|
|
|
|
|
|
VarOffset = (UINT16)((UINTN)(&SetupNvData.UefiDualVgaControllers)-(UINTN)(&SetupNvData));
|
|
|
|
HiiCreateOneOfOpCode (
|
|
StartOpCodeHandle,
|
|
KEY_DUAL_VGA_SUPPORT,
|
|
CONFIGURATION_VARSTORE_ID,
|
|
VarOffset,
|
|
(EFI_STRING_ID)STRING_TOKEN(STR_UEFI_DUAL_VGA_SUPPORT_PROMPT),
|
|
(EFI_STRING_ID)STRING_TOKEN(STR_UEFI_DUAL_VGA_SUPPORT_HELP),
|
|
0x04,
|
|
EFI_IFR_NUMERIC_SIZE_1,
|
|
OptionsOpCodeHandle,
|
|
NULL
|
|
);
|
|
|
|
Status= HiiUpdateForm (
|
|
HiiHandle,
|
|
NULL,
|
|
(EFI_FORM_ID)IGFX_FORM_ID,
|
|
StartOpCodeHandle,
|
|
NULL
|
|
);
|
|
|
|
HiiFreeOpCodeHandle (StartOpCodeHandle);
|
|
HiiFreeOpCodeHandle (OptionsOpCodeHandle);
|
|
return Status;
|
|
} else {
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
}
|