/** @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 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; } }