summaryrefslogtreecommitdiff
path: root/Board/EM/AmiGopPolicy/AmiGopPolicySetup.c
diff options
context:
space:
mode:
authorraywu <raywu0301@gmail.com>2018-06-15 00:00:50 +0800
committerraywu <raywu0301@gmail.com>2018-06-15 00:00:50 +0800
commitb7c51c9cf4864df6aabb99a1ae843becd577237c (patch)
treeeebe9b0d0ca03062955223097e57da84dd618b9a /Board/EM/AmiGopPolicy/AmiGopPolicySetup.c
downloadzprj-b7c51c9cf4864df6aabb99a1ae843becd577237c.tar.xz
init. 1AQQW051HEADmaster
Diffstat (limited to 'Board/EM/AmiGopPolicy/AmiGopPolicySetup.c')
-rw-r--r--Board/EM/AmiGopPolicy/AmiGopPolicySetup.c1402
1 files changed, 1402 insertions, 0 deletions
diff --git a/Board/EM/AmiGopPolicy/AmiGopPolicySetup.c b/Board/EM/AmiGopPolicy/AmiGopPolicySetup.c
new file mode 100644
index 0000000..cfcefc2
--- /dev/null
+++ b/Board/EM/AmiGopPolicy/AmiGopPolicySetup.c
@@ -0,0 +1,1402 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2014, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/AmiGopPolicy/AmiGopPolicySetup.c 9 7/17/14 5:36a Josephlin $
+//
+// $Revision: 9 $
+//
+// $Date: 7/17/14 5:36a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/AmiGopPolicy/AmiGopPolicySetup.c $
+//
+// 9 7/17/14 5:36a Josephlin
+// [TAG] EIP176969
+// [Category] Improvement
+// [Description] Change "#else if" to "#elif" to improve compiling
+// efficiency.
+// [Files] AmiGopPolicySetup.c
+//
+// 8 5/15/14 2:25a Jameswang
+// [TAG] EIP168961
+// [Category] Improvement
+// [Description] - Do not set EFI_VARIABLE_RUNTIME_ACCESS for all
+// variables: AmiGopPolicySetupData and AmiGopOutputDp.
+// - Do not change attribute of Setup variable.
+// - Fixed hanging at InitAmiGopPolicyStrings() if the length of GOP
+// driver name >= 0x40. GetDriverName() added a length argument.
+// - Change module specific variable's GUID not equal to
+// AMI_GLOBAL_VARIABLE_GUID.
+//
+// 7 11/07/12 5:00a Josephlin
+// [TAG] N/A
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] SCT Test Fail
+// [RootCause] EFI_GLOBAL_VARIABLE guid is used in non EFI defined
+// variable.
+// [Solution] New guid AMI_GLOBAL_VARIABLE_GUID is created and used.
+// [Files] AmiGopPolicySetup.c
+//
+// 6 10/28/12 11:59p Josephlin
+// [TAG] EIP103432
+// [Category] Improvement
+// [Description] Add nVidia GOP switch function support for AmiGopPolicy
+// module.
+// [Files] AmiGopPolicySetup.c
+//
+// 5 9/07/12 3:43a Josephlin
+// [TAG] EIP97375
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] If switch the output from HDMI to CRT then save and exit,
+// the setup value still keep in HDMI.
+// [RootCause] Incorrect input value (void **) for MemCmp().
+// [Solution] Change the input type to (void *) for MemCmp().
+// [Files] AmiGopPolicySetup.c
+//
+// 4 8/03/12 3:38a Josephlin
+// [TAG] EIP96705
+// [Category] Improvement
+// [Description] If ComponentName2 Protocol doesn't supports "en-us",
+// try to use first language of SupportedLanguages. This is able to avoid
+// Driver & Device name display "Unknow" always.
+// [Files] AmiGopPolicySetup.c
+//
+// 3 7/26/12 7:30a Josephlin
+// Update File Header.
+//
+// 2 7/23/12 3:32a Josephlin
+// 1. Added input argument SetupData for eLink OemGopSwitchHookList.
+// 2. Created token "AmiGopPolicySetupFile" and "AmiGopPolicySetupString"
+// for override sd and uni file.
+// 3. Rename AmiGopPolicyCallback to AmiGopSwitchCallback in case user
+// confuse.
+//
+// 1 6/29/12 3:45a Josephlin
+// [TAG] EIP91970
+// [Category] New Feature
+// [Description] Initial Release for Display Switch with UEFI GOP driver
+// support.
+// [Files] AmiGopPolicy.cif
+// AmiGopPolicy.c
+// AmiGopPolicy.h
+// AmiGopPolicy.mak
+// AmiGopPolicy.sd
+// AmiGopPolicy.sdl
+// AmiGopPolicy.uni
+// AmiGopPolicyLib.c
+// AmiGopPolicySetup.c
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: AmiGopPolicySetup.c
+//
+// Description: AmiGopPolicy Setup Routines.
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+
+//----------------------------------------------------------------------
+// Include(s)
+//----------------------------------------------------------------------
+
+#include <Efi.h>
+#include <AmiLib.h>
+#include <AmiDxeLib.h>
+#include "AmiCspLib.h"
+#include <Setup.h>
+#include <SetupStrTokens.h>
+#include <Token.h>
+#include "AmiGopPolicy.h"
+
+#include <Protocol\ComponentName.h>
+#include <Protocol\DevicePath.h>
+#include <Protocol\GraphicsOutput.h>
+#include <Protocol\DriverBinding.h>
+#include <Protocol\EdidDiscovered.h>
+
+//----------------------------------------------------------------------
+// Constant, Macro and Type Definition(s)
+//----------------------------------------------------------------------
+// Constant Definition(s)
+
+// Macro Definition(s)
+
+// Type Definition(s)
+
+// Function Prototype(s)
+
+BOOLEAN GetDriverName (
+ IN EFI_HANDLE DriverBindingHandle,
+ IN UINT16 Length,
+ OUT CHAR8 *String
+);
+
+BOOLEAN GetDeviceName (
+ IN EFI_HANDLE DriverBindingHandle,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_HANDLE ChildControllerHandle,
+ OUT CHAR8 *String
+);
+
+EFI_STATUS GetDriverBindingHandle (
+ IN EFI_HANDLE ControllerHandle,
+ OUT EFI_HANDLE *DriverBindingHandle
+);
+
+EFI_STATUS GetDriverHandleBuffer (
+ IN EFI_HANDLE Controller,
+ OUT UINTN *DriverHandleCount,
+ OUT EFI_HANDLE **DriverHandleBuffer
+);
+
+EFI_STATUS GetDeviceHandlesManagedByDriver (
+ IN EFI_HANDLE DriverBindingHandle,
+ OUT UINTN *ControllerHandleCount,
+ OUT EFI_HANDLE **ControllerHandleBuffer
+);
+
+EFI_STATUS GetChildDeviceHandlesManagedByDriver (
+ IN EFI_HANDLE DriverBindingHandle,
+ IN EFI_HANDLE ControllerHandle,
+ OUT UINTN *ChildControllerHandleCount,
+ OUT EFI_HANDLE **ChildControllerHandleBuffer
+);
+
+EFI_STATUS GetEdidDiscoveredHandlesManagedByDriver (
+ IN EFI_HANDLE DriverBindingHandle,
+ IN EFI_HANDLE ControllerHandle
+);
+
+EFI_STATUS GetOutputDeviceHandlesManagedByDriver (
+ IN EFI_HANDLE DriverBindingHandle,
+ IN EFI_HANDLE ControllerHandle,
+ OUT UINTN *OutputHandleCount,
+ OUT EFI_HANDLE **OutputHandleBuffer
+);
+
+EFI_STATUS AmiGopDeviceCheck (
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_HANDLE DriverBindingHandle,
+ IN EFI_PCI_IO_PROTOCOL *PciIo
+);
+
+EFI_STATUS AmiGopSwitchHook (
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_HANDLE DriverBindingHandle,
+ IN SETUP_DATA *SetupData,
+ IN EFI_DEVICE_PATH_PROTOCOL *DevicePath
+);
+
+//----------------------------------------------------------------------
+// Variable and External Declaration(s)
+//----------------------------------------------------------------------
+// Variable Declaration(s)
+
+T_ITEM_LIST OutputHndList = { 0, 0, NULL };
+
+UINT16 sDeviceName[] = {
+ STRING_TOKEN(STR_GOP_DEVICE_NAME_0),
+ STRING_TOKEN(STR_GOP_DEVICE_NAME_1),
+ STRING_TOKEN(STR_GOP_DEVICE_NAME_2),
+ STRING_TOKEN(STR_GOP_DEVICE_NAME_3),
+ };
+
+UINT16 sDriverName[] = {
+ STRING_TOKEN(STR_GOP_DRIVER_NAME_0),
+ STRING_TOKEN(STR_GOP_DRIVER_NAME_1),
+ STRING_TOKEN(STR_GOP_DRIVER_NAME_2),
+ STRING_TOKEN(STR_GOP_DRIVER_NAME_3),
+ };
+
+UINT16 sOutputName[] = {
+ STRING_TOKEN(STR_GOP_OUTPUT_NAME_0),
+ STRING_TOKEN(STR_GOP_OUTPUT_NAME_1),
+ STRING_TOKEN(STR_GOP_OUTPUT_NAME_2),
+ STRING_TOKEN(STR_GOP_OUTPUT_NAME_3),
+ STRING_TOKEN(STR_GOP_OUTPUT_NAME_4),
+ STRING_TOKEN(STR_GOP_OUTPUT_NAME_5),
+ STRING_TOKEN(STR_GOP_OUTPUT_NAME_6),
+ STRING_TOKEN(STR_GOP_OUTPUT_NAME_7)
+ };
+
+// GUID Definition(s)
+
+static EFI_GUID gAmiGopPolicyVariableGuid = AMI_GOP_POLICY_VARIABLE_GUID;
+static EFI_GUID gSetupGuid = SETUP_GUID;
+
+// Protocol Definition(s)
+
+// External Declaration(s)
+
+extern EFI_GUID gEfiComponentName2ProtocolGuid;
+
+// Function Definition(s)
+
+//----------------------------------------------------------------------
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: InitAmiGopPolicyStrings
+//
+// Description: Initializes AmiGopPolicy Setup String
+//
+// Parameters: HiiHandle - Handle to HII database
+// Class - Indicates the setup class
+//
+// Returns: None
+//
+// Notes:
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID InitAmiGopPolicyStrings (
+ IN EFI_HII_HANDLE HiiHandle,
+ IN UINT16 Class )
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+
+ UINTN VariableSize = 0;
+ AMI_GOP_POLICY_SETUP_DATA AmiGopPolicySetupData;
+
+ UINTN ControllerHandleCount = 0;
+ EFI_HANDLE *ControllerHandleBuffer = NULL;
+ EFI_HANDLE ControllerHandle;
+ UINTN ControllerHandleIndex;
+
+ EFI_HANDLE DriverBindingHandle;
+
+ EFI_PCI_IO_PROTOCOL *PciIo;
+
+ UINTN ChildHandleCount = 0;
+ EFI_HANDLE *ChildHandleBuffer = NULL;
+ EFI_HANDLE ChildHandle;
+ UINTN ChildHandleIndex = 0;
+ EFI_DEVICE_PATH_PROTOCOL *ChildHandleDp;
+ CHAR16 ChildHandleDpVar[0x40];
+ EFI_DEVICE_PATH_PROTOCOL *AmiGopOutputDp = NULL;
+
+ UINTN SetupSize;
+ SETUP_DATA SetupData;
+
+ CHAR8 String[0x40];
+
+ UINTN Index = 0;
+ UINTN SelectIndex = 0;
+
+ UINT32 VarAttr;
+
+ if (Class != ADVANCED_FORM_SET_CLASS) return;
+
+ // Save default AmiGopPolicySetupData on memory.
+ AmiGopPolicySetupData.GopDeviceCount = 0;
+ AmiGopPolicySetupData.GopOutputCount = 0;
+ VariableSize = sizeof(AMI_GOP_POLICY_SETUP_DATA);
+ Status = pRS->SetVariable (
+ L"AmiGopPolicySetupData",
+ &gAmiGopPolicyVariableGuid,
+ EFI_VARIABLE_BOOTSERVICE_ACCESS,
+ VariableSize,
+ &AmiGopPolicySetupData );
+
+ // Init String buffer
+ pBS->SetMem(String, sizeof(String), 0);
+
+ //
+ // Get all drivers handles which has PCI IO Protocol
+ //
+ Status = pBS->LocateHandleBuffer(
+ ByProtocol,
+ &gEfiPciIoProtocolGuid,
+ NULL,
+ &ControllerHandleCount,
+ &ControllerHandleBuffer);
+ if (EFI_ERROR(Status)) return;
+
+ for (ControllerHandleIndex = 0; ControllerHandleIndex < ControllerHandleCount; ControllerHandleIndex++) {
+ ControllerHandle = ControllerHandleBuffer[ControllerHandleIndex];
+ Status = pBS->HandleProtocol (ControllerHandle, &gEfiPciIoProtocolGuid, &PciIo);
+ if (EFI_ERROR(Status)) continue;
+
+ Status = GetDriverBindingHandle (ControllerHandle, &DriverBindingHandle);
+ if (EFI_ERROR(Status)) continue;
+
+ Status = AmiGopDeviceCheck (ControllerHandle, DriverBindingHandle, PciIo);
+ if (EFI_ERROR(Status)) continue;
+
+ if (GetDeviceName(DriverBindingHandle, ControllerHandle, NULL, String)) {
+ InitString(HiiHandle, sDeviceName[Index], L"%S", String);
+ pBS->SetMem(String, sizeof(String), 0);
+ }
+
+ if (GetDriverName(DriverBindingHandle, 0x40, String)) {
+ InitString(HiiHandle, sDriverName[Index], L"%S", String);
+ pBS->SetMem(String, sizeof(String), 0);
+ }
+
+ Status = GetOutputDeviceHandlesManagedByDriver (DriverBindingHandle, ControllerHandle, &ChildHandleCount, &ChildHandleBuffer);
+ if (!EFI_ERROR(Status)) {
+ VariableSize = 0;
+ Status = GetEfiVariable (
+ L"AmiGopOutputDp",
+ &gAmiGopPolicyVariableGuid,
+ NULL,
+ &VariableSize,
+ &AmiGopOutputDp);
+ for (ChildHandleIndex = 0; ChildHandleIndex < ChildHandleCount; ChildHandleIndex++) {
+ ChildHandle = ChildHandleBuffer[ChildHandleIndex];
+ if (GetDeviceName(DriverBindingHandle, ControllerHandle, ChildHandle, String)) {
+ Status = pBS->OpenProtocol (
+ ChildHandle,
+ &gEfiDevicePathProtocolGuid,
+ (VOID**)&ChildHandleDp,
+ NULL,
+ NULL,
+ EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL);
+ if (!EFI_ERROR(Status)) {
+ Swprintf (ChildHandleDpVar, L"ChildHandleDpVar%01x", ChildHandleIndex);
+ Status = pRS->SetVariable (
+ ChildHandleDpVar,
+ &gAmiGopPolicyVariableGuid,
+ EFI_VARIABLE_BOOTSERVICE_ACCESS,
+ DPLength (ChildHandleDp),
+ ChildHandleDp );
+ if (AmiGopOutputDp != NULL) {
+ if (MemCmp (AmiGopOutputDp, ChildHandleDp, DPLength(ChildHandleDp)) == 0) {
+ SelectIndex = ChildHandleIndex;
+ }
+ }
+ }
+ InitString(HiiHandle, sOutputName[ChildHandleIndex], L"%S", String);
+ pBS->SetMem(String, sizeof(String), 0);
+ }
+ }
+ }
+
+ Index ++;
+ }
+
+ pBS->FreePool(AmiGopOutputDp);
+ pBS->FreePool(ControllerHandleBuffer);
+
+ // Update Gop Output Device Count
+ SetupSize = sizeof(SETUP_DATA);
+ Status = pRS->GetVariable(L"Setup", &gSetupGuid, &VarAttr, &SetupSize, &SetupData);
+ if (!EFI_ERROR(Status)) {
+ SetupData.GopOutputSelect = (UINT8)SelectIndex;
+ Status = pRS->SetVariable(
+ L"Setup",
+ &gSetupGuid,
+ VarAttr,
+ sizeof(SETUP_DATA),
+ &SetupData);
+ }
+
+ // Save AmiGopPolicySetupData on memory.
+ AmiGopPolicySetupData.GopDeviceCount = (UINT8)Index;
+ AmiGopPolicySetupData.GopOutputCount = (UINT8)ChildHandleIndex;
+ VariableSize = sizeof(AMI_GOP_POLICY_SETUP_DATA);
+ Status = pRS->SetVariable (
+ L"AmiGopPolicySetupData",
+ &gAmiGopPolicyVariableGuid,
+ EFI_VARIABLE_BOOTSERVICE_ACCESS,
+ VariableSize,
+ &AmiGopPolicySetupData );
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: AmiGopSwitchCallback
+//
+// Description: None.
+//
+// Input: None.
+//
+// Output: None.
+//
+// Notes: None.
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS AmiGopSwitchCallback (
+ IN EFI_HII_HANDLE HiiHandle,
+ IN UINT16 Class,
+ IN UINT16 SubClass,
+ IN UINT16 Key )
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+ SETUP_DATA *SetupData = NULL;
+ UINTN SetupSize = sizeof(SETUP_DATA);
+ UINTN VariableSize = 0;
+ CALLBACK_PARAMETERS *CallbackParameters = NULL;
+
+ UINTN ControllerHandleCount = 0;
+ EFI_HANDLE *ControllerHandleBuffer = NULL;
+ EFI_HANDLE ControllerHandle;
+ UINTN ControllerHandleIndex;
+
+ EFI_PCI_IO_PROTOCOL *PciIo;
+
+ EFI_HANDLE DriverBindingHandle;
+ EFI_DRIVER_BINDING_PROTOCOL *DriverBinding = NULL;
+
+ UINTN DriverHandleCount = 0;
+ EFI_HANDLE *DriverHandleBuffer = NULL;
+
+ UINTN ChildHandleCount = 0;
+ EFI_HANDLE *ChildHandleBuffer = NULL;
+ UINTN ChildHandleIndex;
+ CHAR16 ChildHandleDpVar[0x40];
+
+ EFI_DEVICE_PATH_PROTOCOL *GopDevicePath = NULL;
+ UINTN GopDevicePathLength = 0;
+
+ EFI_GRAPHICS_OUTPUT_PROTOCOL *Gop = NULL;
+ UINTN HorizontalResolution = 0;
+ UINTN VerticalResolution = 0;
+ UINTN GopHandleCount = 0;
+ EFI_HANDLE *GopHandleBuffer = NULL;
+ UINTN GopHandleIndex;
+ UINTN SizeOfInfo = 0;
+ UINT32 Mode;
+ UINT32 MaxMode = 0;
+ EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Info = NULL;
+
+ //
+ // Get Setup Buffer
+ //
+ CallbackParameters = GetCallbackParameters();
+
+#if ((TSE_BUILD >= 0x1224) && (EFI_SPECIFICATION_VERSION >= 0x2000A))
+ if (CallbackParameters->Action != EFI_BROWSER_ACTION_CHANGED) return Status;
+#elif ((TSE_BUILD > 0x1208) && (EFI_SPECIFICATION_VERSION >= 0x2000A))
+ if (CallbackParameters->Action != EFI_BROWSER_ACTION_CHANGING) return Status;
+#endif
+
+ Status = pBS->AllocatePool (EfiBootServicesData, SetupSize, &SetupData);
+ if(EFI_ERROR(Status)) return Status;
+
+#if defined(EFI_SPECIFICATION_VERSION) && EFI_SPECIFICATION_VERSION > 0x20000
+ Status = HiiLibGetBrowserData (&SetupSize, SetupData, &gSetupGuid, L"Setup");
+ if(EFI_ERROR(Status)) return Status;
+#else
+ SetupData = (SETUP_DATA*)CallbackParameters->Data->NvRamMap;
+#endif
+
+ //
+ // Get all drivers handles which has PCI IO Protocol
+ //
+ Status = pBS->LocateHandleBuffer (
+ ByProtocol,
+ &gEfiPciIoProtocolGuid,
+ NULL,
+ &ControllerHandleCount,
+ &ControllerHandleBuffer);
+ if (EFI_ERROR(Status)) return Status;
+
+ for (ControllerHandleIndex = 0; ControllerHandleIndex < ControllerHandleCount; ControllerHandleIndex++) {
+ ControllerHandle = ControllerHandleBuffer[ControllerHandleIndex];
+ Status = pBS->HandleProtocol (ControllerHandle, &gEfiPciIoProtocolGuid, &PciIo);
+ if (EFI_ERROR(Status)) continue;
+
+ //
+ // Get Driver Binding Protocol for this VGA
+ //
+ Status = GetDriverBindingHandle (ControllerHandle, &DriverBindingHandle);
+ if (EFI_ERROR(Status)) continue;
+
+ Status = AmiGopDeviceCheck (ControllerHandle, DriverBindingHandle, PciIo);
+ if (EFI_ERROR(Status)) continue;
+
+ Status = pBS->OpenProtocol(
+ DriverBindingHandle,
+ &gEfiDriverBindingProtocolGuid,
+ (VOID**)&DriverBinding,
+ NULL,
+ NULL,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL);
+ if (EFI_ERROR(Status)) continue;
+
+ //
+ // Find out Current GOP Output Mode
+ //
+ if (!EFI_ERROR(GetOutputDeviceHandlesManagedByDriver (DriverBindingHandle, ControllerHandle, &ChildHandleCount, &ChildHandleBuffer))) {
+ for (ChildHandleIndex = 0; ChildHandleIndex < ChildHandleCount; ChildHandleIndex++) {
+ Status = pBS->OpenProtocol (
+ ChildHandleBuffer[ChildHandleIndex],
+ &gEfiGraphicsOutputProtocolGuid,
+ (VOID**)&Gop,
+ NULL,
+ NULL,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL);
+ if (!EFI_ERROR(Status)) {
+ HorizontalResolution = Gop->Mode->Info->HorizontalResolution;
+ VerticalResolution = Gop->Mode->Info->VerticalResolution;
+ break;
+ }
+ }
+ }
+
+ //
+ // Get User Selected Gop Output Handle.
+ //
+ Swprintf (ChildHandleDpVar, L"ChildHandleDpVar%01x", SetupData->GopOutputSelect);
+ GopDevicePathLength = 0;
+ Status = GetEfiVariable (
+ ChildHandleDpVar,
+ &gAmiGopPolicyVariableGuid,
+ NULL,
+ &GopDevicePathLength,
+ &GopDevicePath);
+ if (EFI_ERROR(Status)) continue;
+
+ Status = AmiGopSwitchHook (ControllerHandle, DriverBindingHandle, SetupData, GopDevicePath);
+ if (!EFI_ERROR(Status)) {
+ //
+ // Save AmiGop Outut Device path for next boot
+ //
+ Status = pRS->SetVariable (
+ L"AmiGopOutputDp",
+ &gAmiGopPolicyVariableGuid,
+ EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
+ DPLength(GopDevicePath),
+ GopDevicePath);
+ if (EFI_ERROR(Status)) continue;
+
+ //
+ // Set GOP Output Mode
+ //
+ Status = GetOutputDeviceHandlesManagedByDriver (DriverBindingHandle, ControllerHandle, &GopHandleCount, &GopHandleBuffer);
+ if (!EFI_ERROR(Status)) {
+ for (GopHandleIndex = 0; GopHandleIndex < GopHandleCount; GopHandleIndex++) {
+ Status = pBS->OpenProtocol (
+ GopHandleBuffer[GopHandleIndex],
+ &gEfiGraphicsOutputProtocolGuid,
+ (VOID**)&Gop,
+ NULL,
+ NULL,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL);
+ if (!EFI_ERROR(Status)) {
+ if ((HorizontalResolution == Gop->Mode->Info->HorizontalResolution) &&
+ (VerticalResolution == Gop->Mode->Info->VerticalResolution))
+ break;
+ MaxMode = Gop->Mode->MaxMode;
+ for (Mode = 0; Mode <= MaxMode; Mode++) {
+ if (!EFI_ERROR (Gop->QueryMode (Gop, Mode, &SizeOfInfo, &Info))) {
+ if ((HorizontalResolution == Info->HorizontalResolution) &&
+ (VerticalResolution == Info->VerticalResolution)) {
+ Status = Gop->SetMode (Gop, Mode);
+ if (!EFI_ERROR(Status)) break;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ pBS->FreePool(SetupData);
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: GetDriverName
+//
+// Description: Get driver's name from DriverBindingHandle first using
+// LANGUAGE_CODE_ENGLISH then "eng" codes.
+//
+// Input: DriverBindingHandle - handle with gEfiComponentName2ProtocolGuid
+// Length - Length of name to be copied to String including null
+//
+// Output: String - driver name got
+//
+// Notes: None.
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+BOOLEAN
+GetDriverName (
+ IN EFI_HANDLE DriverBindingHandle,
+ IN UINT16 Length,
+ OUT CHAR8 *String )
+{
+ EFI_STATUS Status;
+ CHAR16 *DriverName;
+ EFI_COMPONENT_NAME_PROTOCOL *ComponentName;
+ CHAR8 *Lang = NULL;
+ CHAR8 *TempChar;
+
+ //
+ // Get driver name from UEFI 2.0 Component Name 2 protocol interface.
+ //
+ Status = pBS->OpenProtocol(
+ DriverBindingHandle,
+ &gEfiComponentName2ProtocolGuid,
+ (VOID**)&ComponentName,
+ NULL,
+ NULL,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL);
+ if (!EFI_ERROR(Status)) {
+ Status = ComponentName->GetDriverName(ComponentName, LANGUAGE_CODE_ENGLISH, &DriverName);
+ if (EFI_ERROR(Status)) {
+ //
+ // Driver does not support "en-us", try to get SupportedLanguages
+ //
+ pBS->AllocatePool(EfiBootServicesData, Strlen(ComponentName->SupportedLanguages)+1, &Lang);
+ if (Lang != NULL) {
+ Strcpy(Lang, ComponentName->SupportedLanguages);
+ TempChar = Strstr(Lang, ";");
+ if (TempChar != NULL) *TempChar = 0x0000;
+ Status = ComponentName->GetDriverName(ComponentName, Lang, &DriverName);
+ pBS->FreePool(Lang);
+ Lang = NULL;
+ }
+ }
+ if (!EFI_ERROR(Status)) {
+ DriverName[Length-1]=0; // avoid overflowed, copy only length
+ Sprintf(String, "%S", DriverName);
+ return TRUE;
+ }
+ }
+
+ //
+ // If it fails to get the driver name from Component Name protocol interface, we should fall back on
+ // EFI 1.1 Component Name protocol interface.
+ //
+ Status = pBS->OpenProtocol(
+ DriverBindingHandle,
+ &gEfiComponentNameProtocolGuid,
+ (VOID**)&ComponentName,
+ NULL,
+ NULL,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL);
+ if (!EFI_ERROR(Status)) {
+ Status = ComponentName->GetDriverName(ComponentName, "eng", &DriverName);
+ if (!EFI_ERROR(Status)) {
+ DriverName[Length-1]=0; // avoid overflowed, copy only length
+ Sprintf(String, "%S", DriverName);
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Name: GetDriverBindingHandle
+//
+// Description: None.
+//
+// Input: None.
+//
+// Output: None.
+//
+// Notes: None.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+GetDriverBindingHandle (
+ IN EFI_HANDLE ControllerHandle,
+ OUT EFI_HANDLE *DriverBindingHandle )
+{
+ EFI_STATUS Status;
+ UINTN HandleCount;
+ EFI_HANDLE *HandleBuffer;
+ UINTN HandleIndex;
+ EFI_GUID **ProtocolGuidArray;
+ UINTN ArrayCount;
+ UINTN ProtocolIndex;
+ EFI_OPEN_PROTOCOL_INFORMATION_ENTRY *OpenInfo;
+ UINTN OpenInfoCount;
+ UINTN OpenInfoIndex;
+ UINTN Index;
+
+ Status = pBS->LocateHandleBuffer(
+ AllHandles,
+ NULL,
+ NULL,
+ &HandleCount,
+ &HandleBuffer);
+ if (EFI_ERROR(Status)) return EFI_NOT_FOUND;
+
+ for (HandleIndex = 0; HandleIndex < HandleCount; HandleIndex++) {
+ ProtocolGuidArray = NULL;
+ Status = pBS->ProtocolsPerHandle(
+ HandleBuffer[HandleIndex],
+ &ProtocolGuidArray,
+ &ArrayCount);
+ if (EFI_ERROR(Status)) continue;
+
+ for (ProtocolIndex = 0; ProtocolIndex < ArrayCount; ProtocolIndex++) {
+ Status = pBS->OpenProtocolInformation(
+ HandleBuffer[HandleIndex],
+ ProtocolGuidArray[ProtocolIndex],
+ &OpenInfo,
+ &OpenInfoCount);
+ if (EFI_ERROR(Status)) continue;
+
+ for (OpenInfoIndex = 0; OpenInfoIndex < OpenInfoCount; OpenInfoIndex++) {
+ if (OpenInfo[OpenInfoIndex].ControllerHandle == ControllerHandle) {
+ if ((OpenInfo[OpenInfoIndex].Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) == EFI_OPEN_PROTOCOL_BY_DRIVER) {
+ for(Index = 0; Index < HandleCount; Index++) {
+ if(HandleBuffer[Index] == OpenInfo[OpenInfoIndex].AgentHandle) {
+ *DriverBindingHandle=HandleBuffer[Index];
+ pBS->FreePool(OpenInfo);
+ pBS->FreePool(ProtocolGuidArray);
+ pBS->FreePool(HandleBuffer);
+ return EFI_SUCCESS;
+ }
+ }
+ }
+ }
+ }
+ if (OpenInfo != NULL) pBS->FreePool(OpenInfo);
+ }
+ if (ProtocolGuidArray != NULL) pBS->FreePool(ProtocolGuidArray);
+ }
+ if (HandleBuffer != NULL) pBS->FreePool(HandleBuffer);
+ return EFI_NOT_FOUND;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Name: GetDriverHandleBuffer
+//
+// Description: None.
+//
+// Input: None.
+//
+// Output: None.
+//
+// Notes: None.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+GetDriverHandleBuffer (
+ IN EFI_HANDLE Controller,
+ OUT UINTN *DriverHandleCount,
+ OUT EFI_HANDLE **DriverHandleBuffer )
+{
+ EFI_STATUS Status;
+ UINTN HandleCount;
+ BOOLEAN *HandleBufferMap;
+ EFI_HANDLE *HandleBuffer;
+ UINTN HandleIndex;
+ EFI_GUID **ProtocolGuidArray;
+ UINTN ArrayCount;
+ UINTN ProtocolIndex;
+ EFI_OPEN_PROTOCOL_INFORMATION_ENTRY *OpenInfo;
+ UINTN OpenInfoCount;
+ UINTN OpenInfoIndex;
+ UINTN Index;
+ UINTN AvailableIndex = 0;
+
+ Status = pBS->LocateHandleBuffer(
+ AllHandles,
+ NULL,
+ NULL,
+ &HandleCount,
+ &HandleBuffer);
+ if (EFI_ERROR(Status)) return EFI_NOT_FOUND;
+
+ HandleBufferMap = MallocZ (sizeof (BOOLEAN) * HandleCount);
+ for (HandleIndex = 0; HandleIndex < HandleCount; HandleIndex++) {
+ HandleBufferMap[HandleIndex] = FALSE;
+ }
+
+ for (HandleIndex = 0; HandleIndex < HandleCount; HandleIndex++) {
+ ProtocolGuidArray = NULL;
+ Status = pBS->ProtocolsPerHandle(
+ HandleBuffer[HandleIndex],
+ &ProtocolGuidArray,
+ &ArrayCount);
+ if (EFI_ERROR(Status)) continue;
+
+ for (ProtocolIndex = 0; ProtocolIndex < ArrayCount; ProtocolIndex++) {
+ Status = pBS->OpenProtocolInformation(
+ HandleBuffer[HandleIndex],
+ ProtocolGuidArray[ProtocolIndex],
+ &OpenInfo,
+ &OpenInfoCount);
+ if (EFI_ERROR(Status)) continue;
+
+ for (OpenInfoIndex = 0; OpenInfoIndex < OpenInfoCount; OpenInfoIndex++) {
+ if (OpenInfo[OpenInfoIndex].ControllerHandle == Controller) {
+ if ((OpenInfo[OpenInfoIndex].Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) == EFI_OPEN_PROTOCOL_BY_DRIVER) {
+ for (Index = 0; Index < HandleCount; Index++) {
+ if (HandleBuffer[Index] == OpenInfo[OpenInfoIndex].AgentHandle) {
+ HandleBufferMap[Index] = TRUE;
+ (*DriverHandleCount)++;
+ }
+ }
+ }
+ }
+ }
+ pBS->FreePool(OpenInfo);
+ }
+ pBS->FreePool(ProtocolGuidArray);
+ }
+
+ if (*DriverHandleCount > 0) {
+ //
+ // Copy the found device handle to returned buffer
+ //
+ *DriverHandleBuffer = MallocZ (sizeof (EFI_HANDLE) * (*DriverHandleCount));
+ for (HandleIndex = 0, AvailableIndex = 0; HandleIndex < HandleCount; HandleIndex++) {
+ if (HandleBufferMap[HandleIndex]) {
+ (*DriverHandleBuffer)[AvailableIndex] = HandleBuffer[HandleIndex];
+ AvailableIndex++;
+ }
+ }
+ }
+
+ pBS->FreePool(HandleBuffer);
+
+ if (*DriverHandleCount > 0)
+ return EFI_SUCCESS;
+ else
+ return EFI_NOT_FOUND;
+}
+
+// <AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: GetDeviceHandlesManagedByDriver
+//
+// Description:
+// Get all device handles which are being opened by a specific driver. The
+// rountine will allocate pool buffer for the found device handles, and it
+// is the caller's responsibility to safe free the buffer.
+//
+// Input:
+// IN EFI_HANDLE DriverBindingHandle - the handle of a driver which
+// contains the binding protocol
+// OUT UINTN ControllerHandleCount - the number of available device handles
+// returned in ControllerHandleBuffer
+// OUT EFI_HANDLE ControllerHandleBuffer - a pointer to the buffer to return
+// the array of device handles
+//
+// Output:
+// EFI_STATUS
+// If returned status is not succeful or find no available device,
+// the *ControllerHandleBuffer will be NULL
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//----------------------------------------------------------------------------
+// <AMI_PHDR_END>
+
+EFI_STATUS
+GetDeviceHandlesManagedByDriver (
+ IN EFI_HANDLE DriverBindingHandle,
+ OUT UINTN *ControllerHandleCount,
+ OUT EFI_HANDLE **ControllerHandleBuffer )
+{
+ UINTN HandleCount;
+ EFI_HANDLE *HandleBuffer;
+ BOOLEAN *HandleBufferMap;
+ EFI_STATUS Status;
+ UINTN HandleIndex;
+ UINTN AvailableIndex;
+ EFI_GUID **ProtocolGuidArray;
+ UINTN ArrayCount;
+ UINTN ProtocolIndex;
+ EFI_OPEN_PROTOCOL_INFORMATION_ENTRY *OpenInfo;
+ UINTN OpenInfoCount;
+ UINTN OpenInfoIndex;
+
+ *ControllerHandleCount = 0;
+ *ControllerHandleBuffer = NULL;
+ HandleCount = 0;
+ HandleBuffer = NULL;
+
+ if (DriverBindingHandle == NULL) {
+ Status = EFI_INVALID_PARAMETER;
+ goto Error;
+ }
+
+ //
+ // Retrieve the list of all handles from the handle database
+ //
+ Status = pBS->LocateHandleBuffer (
+ AllHandles,
+ NULL,
+ NULL,
+ &HandleCount,
+ &HandleBuffer
+ );
+ if (EFI_ERROR (Status)) goto Error;
+
+ //
+ //Create a map for HandleBuffer. If a handle in HandleBuffer is the wanted device handle, its map item is true.
+ //
+ HandleBufferMap = MallocZ (sizeof (BOOLEAN) * HandleCount);
+ for (HandleIndex = 0; HandleIndex < HandleCount; HandleIndex++) {
+ HandleBufferMap[HandleIndex] = FALSE;
+ }
+
+ for (HandleIndex = 0; HandleIndex < HandleCount; HandleIndex++) {
+ //
+ // Check if it is a device handle
+ //
+ Status = pBS->OpenProtocol (
+ HandleBuffer[HandleIndex],
+ &gEfiDevicePathProtocolGuid,
+ NULL,
+ NULL,
+ NULL,
+ EFI_OPEN_PROTOCOL_TEST_PROTOCOL);
+ if (EFI_ERROR(Status)) continue;
+
+ //
+ // Retrieve the list of all the protocols on each handle
+ //
+ Status = pBS->ProtocolsPerHandle (
+ HandleBuffer[HandleIndex],
+ &ProtocolGuidArray,
+ &ArrayCount);
+
+ if (!EFI_ERROR (Status)) {
+ for (ProtocolIndex = 0; ProtocolIndex < ArrayCount; ProtocolIndex++) {
+ //
+ // Retrieve the list of agents that have opened each protocol
+ //
+ Status = pBS->OpenProtocolInformation (
+ HandleBuffer[HandleIndex],
+ ProtocolGuidArray[ProtocolIndex],
+ &OpenInfo,
+ &OpenInfoCount);
+ if (!EFI_ERROR (Status)) {
+ for (OpenInfoIndex = 0; OpenInfoIndex < OpenInfoCount; OpenInfoIndex++) {
+ if (OpenInfo[OpenInfoIndex].AgentHandle == DriverBindingHandle) {
+ if ((OpenInfo[OpenInfoIndex].Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) == EFI_OPEN_PROTOCOL_BY_DRIVER) {
+ //
+ // HandleBufferMap[HandleIndex] is the wanted device handle, find it in the handlebuffer
+ // A bus driver maybe open a Controller with BY_DRIVER attribute for different protocol many times,
+ //
+ HandleBufferMap[HandleIndex] = TRUE;
+ }
+ }
+ }
+ pBS->FreePool (OpenInfo);
+ }
+ }
+ pBS->FreePool (ProtocolGuidArray);
+ }
+ }
+
+ //
+ // count how many device handles are found
+ //
+ for (HandleIndex = 0; HandleIndex < HandleCount; HandleIndex++) {
+ if (HandleBufferMap[HandleIndex]) {
+ (*ControllerHandleCount)++;
+ }
+ }
+
+ if (*ControllerHandleCount > 0) {
+ //
+ // Copy the found device handle to returned buffer
+ //
+ *ControllerHandleBuffer = MallocZ (sizeof (EFI_HANDLE) * (*ControllerHandleCount));
+ for (HandleIndex = 0, AvailableIndex = 0; HandleIndex < HandleCount; HandleIndex++) {
+ if (HandleBufferMap[HandleIndex]) {
+ (*ControllerHandleBuffer)[AvailableIndex] = HandleBuffer[HandleIndex];
+ AvailableIndex++;
+ }
+ }
+ }
+
+ if (HandleBuffer != NULL) pBS->FreePool (HandleBuffer);
+ return EFI_SUCCESS;
+
+Error:
+
+ if (HandleBuffer != NULL) pBS->FreePool (HandleBuffer);
+ return Status;
+}
+
+// <AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: GetChildDeviceHandlesManagedByDriver
+//
+// Description:
+// Get all child device handles which are being opened by a specific driver.
+// The rountine will allocate pool buffer for the found child device handles,
+// and it is the caller's responsibility to safe free the buffer.
+//
+// Input:
+// IN EFI_HANDLE DriverBindingHandle - the handle of a driver which
+// contains the binding protocol
+// IN EFI_HANDLE ControllerHandle - the device controller handle be opened
+// by its child device
+// OUT UINTN ChildControllerHandleCount - the number of available
+// device handles returned in
+// ControllerHandleBuffer
+// OUT EFI_HANDLE ChildControllerHandleBuffer - a pointer to the buffer to
+// return the array of child
+// device handles
+//
+// Output:
+// EFI_STATUS
+// If returned status is not succeful or find no available device,
+// the *ChildControllerHandleBuffer will be NULL
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//----------------------------------------------------------------------------
+// <AMI_PHDR_END>
+
+EFI_STATUS
+GetChildDeviceHandlesManagedByDriver (
+ IN EFI_HANDLE DriverBindingHandle,
+ IN EFI_HANDLE ControllerHandle,
+ OUT UINTN *ChildControllerHandleCount,
+ OUT EFI_HANDLE **ChildControllerHandleBuffer )
+{
+ UINTN HandleCount;
+ EFI_HANDLE *HandleBuffer;
+ BOOLEAN *HandleBufferMap;
+ EFI_STATUS Status;
+ UINTN HandleIndex;
+ UINTN AvailableIndex;
+ EFI_GUID **ProtocolGuidArray;
+ UINTN ArrayCount;
+ UINTN ProtocolIndex;
+ EFI_OPEN_PROTOCOL_INFORMATION_ENTRY *OpenInfo;
+ UINTN OpenInfoCount;
+ UINTN OpenInfoIndex;
+
+ *ChildControllerHandleCount = 0;
+ *ChildControllerHandleBuffer = NULL;
+ HandleCount = 0;
+ HandleBuffer = NULL;
+
+ if ((DriverBindingHandle == NULL) || (ControllerHandle == NULL)) {
+ Status = EFI_INVALID_PARAMETER;
+ goto Error;
+ }
+
+ //
+ // Retrieve the list of all handles from the handle database
+ //
+ Status = pBS->LocateHandleBuffer (
+ AllHandles,
+ NULL,
+ NULL,
+ &HandleCount,
+ &HandleBuffer);
+ if (EFI_ERROR(Status)) goto Error;
+
+ //
+ // Create a map for HandleBuffer. If a handle in HandleBuffer is the wanted device handle, its map item is true.
+ //
+ HandleBufferMap = MallocZ (sizeof (BOOLEAN) * HandleCount);
+ for (HandleIndex = 0; HandleIndex < HandleCount; HandleIndex++) {
+ HandleBufferMap[HandleIndex] = FALSE;
+ }
+
+ //
+ // Retrieve the list of all the protocols on each handle
+ //
+ Status = pBS->ProtocolsPerHandle (
+ ControllerHandle,
+ &ProtocolGuidArray,
+ &ArrayCount);
+ if (!EFI_ERROR (Status)) {
+ for (ProtocolIndex = 0; ProtocolIndex < ArrayCount; ProtocolIndex++) {
+ //
+ // Retrieve the list of agents that have opened each protocol
+ //
+ Status = pBS->OpenProtocolInformation (
+ ControllerHandle,
+ ProtocolGuidArray[ProtocolIndex],
+ &OpenInfo,
+ &OpenInfoCount);
+ if (!EFI_ERROR (Status)) {
+ for (OpenInfoIndex = 0; OpenInfoIndex < OpenInfoCount; OpenInfoIndex++) {
+ if (OpenInfo[OpenInfoIndex].AgentHandle == DriverBindingHandle) {
+ if ((OpenInfo[OpenInfoIndex].Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) == EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) {
+ //
+ // OpenInfo[OpenInfoIndex].ControllerHandle is the wanted child device handle, find it in the handlebuffer
+ // A bus driver maybe open a Controller with BY_CHILD_CONTROLLER attribute for different protocol many times,
+ //
+ for (HandleIndex = 0; HandleIndex < HandleCount; HandleIndex++) {
+ if (OpenInfo[OpenInfoIndex].ControllerHandle == HandleBuffer[HandleIndex]) {
+ HandleBufferMap[HandleIndex] = TRUE;
+ }
+ }
+ }
+ }
+ }
+ pBS->FreePool (OpenInfo);
+ }
+ }
+ pBS->FreePool (ProtocolGuidArray);
+ }
+
+ //
+ // count how many device handles are found
+ //
+ for (HandleIndex = 0; HandleIndex < HandleCount; HandleIndex++) {
+ if (HandleBufferMap[HandleIndex]) {
+ (*ChildControllerHandleCount)++;
+ }
+ }
+
+ if (*ChildControllerHandleCount > 0) {
+ //
+ // Copy the found device handle to returned buffer
+ //
+ *ChildControllerHandleBuffer = MallocZ (sizeof (EFI_HANDLE) * (*ChildControllerHandleCount));
+ for (HandleIndex = 0, AvailableIndex = 0; HandleIndex < HandleCount; HandleIndex++) {
+ if (HandleBufferMap[HandleIndex]) {
+ (*ChildControllerHandleBuffer)[AvailableIndex] = HandleBuffer[HandleIndex];
+ AvailableIndex++;
+ }
+ }
+ }
+
+ if (HandleBuffer != NULL) pBS->FreePool (HandleBuffer);
+ return EFI_SUCCESS;
+
+Error:
+ if (HandleBuffer != NULL) pBS->FreePool (HandleBuffer);
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: GetEdidDiscoveredHandlesManagedByDriver
+//
+// Description: None.
+//
+// Input: None.
+//
+// Output: None.
+//
+// Notes: None.
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+GetEdidDiscoveredHandlesManagedByDriver (
+ IN EFI_HANDLE DriverBindingHandle,
+ IN EFI_HANDLE ControllerHandle )
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+ UINTN ChildHandleCount = 0;
+ EFI_HANDLE *ChildHandleBuffer = NULL;
+ UINTN ChildHandleIndex = 0;
+
+ Status = GetChildDeviceHandlesManagedByDriver (DriverBindingHandle, ControllerHandle, &ChildHandleCount, &ChildHandleBuffer);
+ if (EFI_ERROR(Status)) return Status;
+
+ for (ChildHandleIndex = 0; ChildHandleIndex < ChildHandleCount; ChildHandleIndex++) {
+ Status = pBS->OpenProtocol(
+ ChildHandleBuffer[ChildHandleIndex],
+ &gEfiEdidDiscoveredProtocolGuid,
+ NULL, NULL, NULL,
+ EFI_OPEN_PROTOCOL_TEST_PROTOCOL);
+ if (EFI_ERROR(Status)) Status = GetEdidDiscoveredHandlesManagedByDriver (DriverBindingHandle, ChildHandleBuffer[ChildHandleIndex]);
+ else AppendItemLst(&OutputHndList, &ChildHandleBuffer[ChildHandleIndex]);
+ }
+
+ return EFI_SUCCESS;
+}
+
+// <AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: GetOutputDeviceHandlesManagedByDriver
+//
+// Description:
+// Get all output device handles which are produced by a specific driver.
+// The rountine will allocate pool buffer for the found output device handles,
+// and it is the caller's responsibility to safe free the buffer.
+//
+// Input:
+// IN EFI_HANDLE DriverBindingHandle - the handle of a driver which contains
+// the binding protocol
+// IN EFI_HANDLE ControllerHandle - the device controller handle be opened
+// by its child device
+// OUT UINTN OutputHandleCount - the number of available device handles
+// returned in OutputHandleBuffer.
+// OUT EFI_HANDLE OutputHandleBuffer - a pointer to the buffer to return
+// the array of Output device handles.
+//
+// Output:
+// EFI_STATUS
+// If returned status is not succeful or find no available device,
+// the *OutputHandleBuffer will be NULL
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//----------------------------------------------------------------------------
+// <AMI_PHDR_END>
+
+EFI_STATUS
+GetOutputDeviceHandlesManagedByDriver (
+ IN EFI_HANDLE DriverBindingHandle,
+ IN EFI_HANDLE ControllerHandle,
+ OUT UINTN *OutputHandleCount,
+ OUT EFI_HANDLE **OutputHandleBuffer )
+{
+ EFI_STATUS Status;
+ UINTN HandleIndex = 0;
+
+ *OutputHandleCount = 0;
+ *OutputHandleBuffer = NULL;
+
+ Status = GetEdidDiscoveredHandlesManagedByDriver (DriverBindingHandle, ControllerHandle);
+ if (OutputHndList.ItemCount) {
+ *OutputHandleCount = OutputHndList.ItemCount;
+ *OutputHandleBuffer = MallocZ(sizeof(EFI_HANDLE) * (*OutputHandleCount));
+ for (HandleIndex = 0; HandleIndex < *OutputHandleCount; HandleIndex++) {
+ (*OutputHandleBuffer)[HandleIndex] = *(EFI_HANDLE*)(OutputHndList.Items[HandleIndex]);
+ }
+ }
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: GetDeviceName
+//
+// Description: None.
+//
+// Input: None.
+//
+// Output: None.
+//
+// Notes: None.
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+BOOLEAN
+GetDeviceName (
+ IN EFI_HANDLE DriverBindingHandle,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_HANDLE ChildControllerHandle,
+ OUT CHAR8 *String )
+{
+ EFI_STATUS Status;
+ CHAR16 *DeviceName;
+ EFI_COMPONENT_NAME_PROTOCOL *ComponentName;
+ CHAR8 *Lang = NULL;
+ CHAR8 *TempChar;
+
+
+ //
+ // Get driver name from UEFI 2.0 Component Name 2 protocol interface.
+ //
+ Status = pBS->OpenProtocol(
+ DriverBindingHandle,
+ &gEfiComponentName2ProtocolGuid,
+ (VOID**)&ComponentName,
+ NULL,
+ NULL,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL);
+ if (!EFI_ERROR(Status)) {
+ Status = ComponentName->GetControllerName(ComponentName, ControllerHandle, ChildControllerHandle, LANGUAGE_CODE_ENGLISH, &DeviceName);
+ if (EFI_ERROR(Status)) {
+ //
+ // Driver does not support "en-us", try to get SupportedLanguages
+ //
+ pBS->AllocatePool(EfiBootServicesData, Strlen(ComponentName->SupportedLanguages)+1, &Lang);
+ if (Lang != NULL) {
+ Strcpy(Lang, ComponentName->SupportedLanguages);
+ TempChar = Strstr(Lang, ";");
+ if (TempChar != NULL) *TempChar = 0x0000;
+ Status = ComponentName->GetControllerName(ComponentName, ControllerHandle, ChildControllerHandle, Lang, &DeviceName);
+ pBS->FreePool(Lang);
+ Lang = NULL;
+ }
+ }
+ if (!EFI_ERROR(Status)) {
+ Sprintf(String, "%S", DeviceName);
+ return TRUE;
+ }
+ }
+
+ //
+ // If it fails to get the driver name from Component Name protocol interface, we should fall back on
+ // EFI 1.1 Component Name protocol interface.
+ //
+ Status = pBS->OpenProtocol(
+ DriverBindingHandle,
+ &gEfiComponentNameProtocolGuid,
+ (VOID**)&ComponentName,
+ NULL,
+ NULL,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL);
+ if (!EFI_ERROR(Status)) {
+ Status = ComponentName->GetControllerName(ComponentName, ControllerHandle, ChildControllerHandle, "eng", &DeviceName);
+ if (!EFI_ERROR(Status)) {
+ Sprintf(String, "%S", DeviceName);
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2014, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************