From b7c51c9cf4864df6aabb99a1ae843becd577237c Mon Sep 17 00:00:00 2001 From: raywu Date: Fri, 15 Jun 2018 00:00:50 +0800 Subject: init. 1AQQW051 --- Board/EM/AmiGopPolicy/AmiGopPolicy.c | 238 +++++ Board/EM/AmiGopPolicy/AmiGopPolicy.chm | Bin 0 -> 25685 bytes Board/EM/AmiGopPolicy/AmiGopPolicy.cif | 16 + Board/EM/AmiGopPolicy/AmiGopPolicy.h | 96 ++ Board/EM/AmiGopPolicy/AmiGopPolicy.mak | 124 +++ Board/EM/AmiGopPolicy/AmiGopPolicy.sd | 254 ++++++ Board/EM/AmiGopPolicy/AmiGopPolicy.sdl | 268 ++++++ Board/EM/AmiGopPolicy/AmiGopPolicy.uni | Bin 0 -> 8128 bytes Board/EM/AmiGopPolicy/AmiGopPolicyLib.c | 461 ++++++++++ Board/EM/AmiGopPolicy/AmiGopPolicySetup.c | 1402 +++++++++++++++++++++++++++++ 10 files changed, 2859 insertions(+) create mode 100644 Board/EM/AmiGopPolicy/AmiGopPolicy.c create mode 100644 Board/EM/AmiGopPolicy/AmiGopPolicy.chm create mode 100644 Board/EM/AmiGopPolicy/AmiGopPolicy.cif create mode 100644 Board/EM/AmiGopPolicy/AmiGopPolicy.h create mode 100644 Board/EM/AmiGopPolicy/AmiGopPolicy.mak create mode 100644 Board/EM/AmiGopPolicy/AmiGopPolicy.sd create mode 100644 Board/EM/AmiGopPolicy/AmiGopPolicy.sdl create mode 100644 Board/EM/AmiGopPolicy/AmiGopPolicy.uni create mode 100644 Board/EM/AmiGopPolicy/AmiGopPolicyLib.c create mode 100644 Board/EM/AmiGopPolicy/AmiGopPolicySetup.c (limited to 'Board/EM/AmiGopPolicy') diff --git a/Board/EM/AmiGopPolicy/AmiGopPolicy.c b/Board/EM/AmiGopPolicy/AmiGopPolicy.c new file mode 100644 index 0000000..745a381 --- /dev/null +++ b/Board/EM/AmiGopPolicy/AmiGopPolicy.c @@ -0,0 +1,238 @@ +//********************************************************************** +//********************************************************************** +//** ** +//** (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/AmiGopPolicy.c 6 5/15/14 2:22a Jameswang $ +// +// $Revision: 6 $ +// +// $Date: 5/15/14 2:22a $ +//********************************************************************** +// Revision History +// ---------------- +// $Log: /Alaska/SOURCE/Modules/AmiGopPolicy/AmiGopPolicy.c $ +// +// 6 5/15/14 2:22a Jameswang +// [TAG] EIP168961 +// [Category] Improvement +// [Description] Changed AmiGopOutputDp from AMI_GLOBAL_VARIABLE_GUID to +// AMI_GOP_POLICY_VARIABLE_GUID +// +// 5 4/03/13 4:16a Josephlin +// Fixed CPU Exception Erro if EdidOverrideProtoco got call. +// +// 4 12/18/12 11:03p Josephlin +// [TAG] EIP108311 +// [Category] Improvement +// [Description] Create eLINK "OemGopEdidOverrideGetEdidList" for easy +// to implement EdidOverrideProtocol in project. +// [Files] AmiGopPolicy.c +// AmiGopPolicy.sdl +// AmiGopPolicy.mak +// AmiGopPolicyLib.c +// +// 3 11/08/12 12:58a 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] AmiGopPolicy.c +// +// 2 7/26/12 7:30a Josephlin +// Update File Header. +// +// 1 6/29/12 3:43a 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 +// +//********************************************************************** +// +// +// Name: AmiGopPolicy.c +// +// Description: AmiGopPolicy output initialization in the DXE stage. +// +// +//********************************************************************** + +//---------------------------------------------------------------------- +// Include(s) +//---------------------------------------------------------------------- + +#include +#include +#include +#include +#include +#include + +#include +#if OEM_EDID_OVERRIDE_PROTOCOL_SUPPORT +#include +#endif +#include "AmiGopPolicy.h" + +//---------------------------------------------------------------------- +// Constant, Macro and Type Definition(s) +//---------------------------------------------------------------------- +// Constant Definition(s) + +// Macro Definition(s) + +// Type Definition(s) + +// Function Prototype(s) + +#if OEM_EDID_OVERRIDE_PROTOCOL_SUPPORT +EFI_STATUS AmiGopEdidOverrideGetEdid ( + IN EFI_EDID_OVERRIDE_PROTOCOL *This, + IN EFI_HANDLE *ChildHandle, + OUT UINT32 *Attributes, + IN OUT UINTN *EdidSize, + IN OUT UINT8 **Edid +); +#endif + +//---------------------------------------------------------------------- +// Variable and External Declaration(s) +//---------------------------------------------------------------------- +// Variable Declaration(s) + +// GUID Definition(s) + +static EFI_GUID gAmiGopPolicyVariableGuid = AMI_GOP_POLICY_VARIABLE_GUID; + +// Protocol Definition(s) + +#if OEM_EDID_OVERRIDE_PROTOCOL_SUPPORT +EFI_EDID_OVERRIDE_PROTOCOL EfiEdidOverrideProtocol = { + AmiGopEdidOverrideGetEdid +}; +#endif + +// External Declaration(s) + +// Function Definition(s) + +VOID ConnectDevicePath(IN EFI_DEVICE_PATH_PROTOCOL *pPath); + +//---------------------------------------------------------------------- + +// +//---------------------------------------------------------------------- +// Name: ConnectAmiGopPolicyConOut +// +// Description: None. +// +// Input: None. +// +// Output: None. +// +// Notes: None. +// +//---------------------------------------------------------------------- +// + +VOID ConnectAmiGopPolicyConOut (VOID) +{ + EFI_STATUS Status; + EFI_DEVICE_PATH_PROTOCOL *GopDevicePath = NULL; + UINTN VariableSize = 0; + + Status = GetEfiVariable ( + L"AmiGopOutputDp", + &gAmiGopPolicyVariableGuid, + NULL, + &VariableSize, + &GopDevicePath); + if ((EFI_ERROR(Status)) || (GopDevicePath == NULL)) return ; + + ConnectDevicePath(GopDevicePath); + + return; +} + +// +//---------------------------------------------------------------------- +// +// Procedure: AmiGopPolicyEntryPoint +// +// Description: Installs GOP related protocols +// +// Input: +// IN EFI_HANDLE ImageHandle, +// IN EFI_SYSTEM_TABLE *SystemTable +// +// Output: +// EFI_STATUS +// +// Modified: +// None +// +// Referrals: InitAmiLib InstallMultipleProtocolInterfaces +// +// Notes: +// Here is the control flow of this function: +// 1. Initialize Ami Lib. +// 2. Install Driver Binding Protocol +// 3. Return EFI_SUCCESS. +//---------------------------------------------------------------------- +// + +EFI_STATUS AmiGopPolicyEntryPoint ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable ) +{ + EFI_STATUS Status = EFI_SUCCESS; +#if OEM_EDID_OVERRIDE_PROTOCOL_SUPPORT + EFI_HANDLE Handle = NULL; + + InitAmiLib( ImageHandle, SystemTable ); + + Status = pBS->InstallMultipleProtocolInterfaces( + &Handle, + &gEfiEdidOverrideProtocolGuid, + &EfiEdidOverrideProtocol, + NULL ); +#endif + return Status; +} + +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2012, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** diff --git a/Board/EM/AmiGopPolicy/AmiGopPolicy.chm b/Board/EM/AmiGopPolicy/AmiGopPolicy.chm new file mode 100644 index 0000000..3d9e8d3 Binary files /dev/null and b/Board/EM/AmiGopPolicy/AmiGopPolicy.chm differ diff --git a/Board/EM/AmiGopPolicy/AmiGopPolicy.cif b/Board/EM/AmiGopPolicy/AmiGopPolicy.cif new file mode 100644 index 0000000..b5fe2f1 --- /dev/null +++ b/Board/EM/AmiGopPolicy/AmiGopPolicy.cif @@ -0,0 +1,16 @@ + + name = "AmiGopPolicy" + category = eModule + LocalRoot = "Board\eM\AmiGopPolicy" + RefName = "AmiGopPolicy" +[files] +"AmiGopPolicy.c" +"AmiGopPolicy.h" +"AmiGopPolicy.chm" +"AmiGopPolicy.mak" +"AmiGopPolicy.sd" +"AmiGopPolicy.sdl" +"AmiGopPolicy.uni" +"AmiGopPolicyLib.c" +"AmiGopPolicySetup.c" + diff --git a/Board/EM/AmiGopPolicy/AmiGopPolicy.h b/Board/EM/AmiGopPolicy/AmiGopPolicy.h new file mode 100644 index 0000000..db3910f --- /dev/null +++ b/Board/EM/AmiGopPolicy/AmiGopPolicy.h @@ -0,0 +1,96 @@ +//********************************************************************** +//********************************************************************** +//** ** +//** (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/AmiGopPolicy.h 3 5/15/14 2:39a Jameswang $ +// +// $Revision: 3 $ +// +// $Date: 5/15/14 2:39a $ +//********************************************************************** +// Revision History +// ---------------- +// $Log: /Alaska/SOURCE/Modules/AmiGopPolicy/AmiGopPolicy.h $ +// +// 3 5/15/14 2:39a Jameswang +// [TAG] EIP168961 +// [Category] New Feature +// [Description] Added AMI_GOP_POLICY_VARIABLE_GUID. +// +// 2 7/26/12 7:30a Josephlin +// Update File Header. +// +// 1 6/29/12 3:43a 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 +// +//********************************************************************** +// +// +// Name: AmiGopPolicy.h +// +// Description: AmiGopPolicy Header File. +// +// +//********************************************************************** + +#ifndef _AMI_GOP_POLICY_H_ +#define _AMI_GOP_POLICY_H_ +#ifdef __cplusplus +extern "C" { +#endif + +#define AMI_GOP_POLICY_VARIABLE_GUID \ + {0xc143929c, 0xbf5d, 0x423b, 0x99, 0x9b, 0xf, 0x2d, 0xd2, 0xb6, 0x1f, 0xf7} + +#pragma pack(1) + +typedef struct _AMI_GOP_POLICY_SETUP_DATA +{ + UINT8 GopDeviceCount; + UINT8 GopOutputCount; +} AMI_GOP_POLICY_SETUP_DATA; + +#pragma pack() + +/****** DO NOT WRITE BELOW THIS LINE *******/ +#ifdef __cplusplus +} +#endif +#endif + +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2014, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** diff --git a/Board/EM/AmiGopPolicy/AmiGopPolicy.mak b/Board/EM/AmiGopPolicy/AmiGopPolicy.mak new file mode 100644 index 0000000..ea48a5d --- /dev/null +++ b/Board/EM/AmiGopPolicy/AmiGopPolicy.mak @@ -0,0 +1,124 @@ +#********************************************************************** +#********************************************************************** +#** ** +#** (C)Copyright 1985-2012, American Megatrends, Inc. ** +#** ** +#** All Rights Reserved. ** +#** ** +#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +#** ** +#** Phone: (770)-246-8600 ** +#** ** +#********************************************************************** +#********************************************************************** + +#********************************************************************** +# $Header: /Alaska/SOURCE/Modules/AmiGopPolicy/AmiGopPolicy.mak 5 12/18/12 11:03p Josephlin $ +# +# $Revision: 5 $ +# +# $Date: 12/18/12 11:03p $ +#********************************************************************** +# Revision History +# ---------------- +# $Log: /Alaska/SOURCE/Modules/AmiGopPolicy/AmiGopPolicy.mak $ +# +# 5 12/18/12 11:03p Josephlin +# [TAG] EIP108311 +# [Category] Improvement +# [Description] Create eLINK "OemGopEdidOverrideGetEdidList" for easy +# to implement EdidOverrideProtocol in project. +# [Files] AmiGopPolicy.c +# AmiGopPolicy.sdl +# AmiGopPolicy.mak +# AmiGopPolicyLib.c +# +# 4 7/26/12 7:30a Josephlin +# Update File Header. +# +# 3 7/23/12 5:20a Josephlin +# Fixed build error occured in VIA platform issue. +# +# 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:44a 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 +# +#********************************************************************** +# +# +# Name: AmiGopPolicy.mak +# +# Description: Make file that builds AmiGopPolicy components and link +# them to respective binary. +# +# +#********************************************************************** + +all : AmiGopPolicy + +AmiGopPolicy : $(BUILD_DIR)\AmiGopPolicy.mak + +#---------------------------------------------------------------------- +# Generic eModule dependencies +#---------------------------------------------------------------------- +$(BUILD_DIR)\AmiGopPolicy.mak : $(AMIGOPPOLICY_DIR)\AmiGopPolicy.cif $(AMIGOPPOLICY_DIR)\$(@B).mak $(BUILD_RULES) + $(CIF2MAK) $(AMIGOPPOLICY_DIR)\AmiGopPolicy.cif $(CIF2MAK_DEFAULTS) + +AMI_CSP_LIB_OBJS = $(AMI_CSP_LIB_OBJS) \ +$(BUILD_DIR)\AmiGopPolicy.obj \ +$(BUILD_DIR)\AmiGopPolicyLib.obj + +{$(AMIGOPPOLICY_DIR)}.c{$(BUILD_DIR)}.obj:: + $(CC) $(CFLAGS) \ + /D\"OEM_GOP_DEVICE_CHECK_LIST=$(OemGopDeviceCheckList)\"\ + /D\"OEM_GOP_SWITCH_HOOK_LIST=$(OemGopSwitchHookList)\"\ + /D\"OEM_GOP_EDID_OVERRIDE_GET_EDID_LIST=$(OemGopEdidOverrideGetEdidList)\"\ + /Fo$(BUILD_DIR)\ $< + +$(BUILD_DIR)\AmiGopPolicy.obj : $(AMIGOPPOLICY_DIR)\AmiGopPolicy.c +$(BUILD_DIR)\AmiGopPolicyLib.obj : $(AMIGOPPOLICY_DIR)\AmiGopPolicyLib.c + +#---------------------------------------------------------------------- +# Create eModule Setup Screens +#---------------------------------------------------------------------- +SetupSdbs : $(BUILD_DIR)\AmiGopPolicy.sdb +SetupBin : $(BUILD_DIR)\AmiGopPolicySetup.obj $(AMICSPLib) + +$(BUILD_DIR)\AmiGopPolicy.sdb : $(AmiGopPolicySetupData) $(AmiGopPolicySetupString) + $(STRGATHER) -i INCLUDE -parse -newdb -db $(BUILD_DIR)\AmiGopPolicy.sdb $(AmiGopPolicySetupString) + $(STRGATHER) -scan -db $(BUILD_DIR)\AmiGopPolicy.sdb -od $(BUILD_DIR)\AmiGopPolicy.sdb $(AmiGopPolicySetupData) + +$(BUILD_DIR)\AmiGopPolicySetup.obj : $(AMIGOPPOLICY_DIR)\AmiGopPolicySetup.c $(BUILD_DIR)\SetupStrTokens.h + $(CC) $(CFLAGS) /Fo$(BUILD_DIR)\ $(AMIGOPPOLICY_DIR)\AmiGopPolicySetup.c + +#********************************************************************** +#********************************************************************** +#** ** +#** (C)Copyright 1985-2012, American Megatrends, Inc. ** +#** ** +#** All Rights Reserved. ** +#** ** +#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +#** ** +#** Phone: (770)-246-8600 ** +#** ** +#********************************************************************** +#********************************************************************** \ No newline at end of file diff --git a/Board/EM/AmiGopPolicy/AmiGopPolicy.sd b/Board/EM/AmiGopPolicy/AmiGopPolicy.sd new file mode 100644 index 0000000..4bdc910 --- /dev/null +++ b/Board/EM/AmiGopPolicy/AmiGopPolicy.sd @@ -0,0 +1,254 @@ +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2012, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** + +//********************************************************************** +// $Header: /Alaska/SOURCE/Modules/AmiGopPolicy/AmiGopPolicy.sd 3 6/26/14 3:19a Josephlin $ +// +// $Revision: 3 $ +// +// $Date: 6/26/14 3:19a $ +//********************************************************************** +// Revision History +// ---------------- +// $Log: /Alaska/SOURCE/Modules/AmiGopPolicy/AmiGopPolicy.sd $ +// +// 3 6/26/14 3:19a Josephlin +// [TAG] EIP168961 +// [Category] Bug Fix +// [Severity] Important +// [Symptom] All output device are displayed to "Unknow" if CSM has not +// disabled. +// [RootCause] In EIP168961, this module had changed module specific +// variable's GUID not equal to AMI_GLOBAL_VARIABLE_GUID but without +// changed AmiGopPolicy.sd. +// [Solution] Change guid from SETUP_GUID to +// AMI_GOP_POLICY_VARIABLE_GUID. +// [Files] AmiGopPolicy.sd +// +// 2 7/26/12 7:30a Josephlin +// Update File Header. +// +// 1 6/29/12 3:44a 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 +// +//********************************************************************** +// +// +// Name: AmiGopPolicy.sd +// +// Description: AmiGopPolicy Setup Form. +// +// +//********************************************************************** + +#ifdef SETUP_DATA_DEFINITION +// Put NVRAM data definitions here. +// For example: UINT8 Data1; +// These definitions will be converted by the build process +// to a definitions of SETUP_DATA fields. + UINT8 GopOutputSelect; +#endif //SETUP_DATA_DEFINITION + +#ifdef FORM_SET_TYPEDEF + #include "AmiGopPolicy.h" +#endif + +//Select Top level menu itmem (forset) for you pages +#ifdef ADVANCED_FORM_SET + #ifndef SUPPRESS_GRAYOUT_ENDIF //old Core + #define SUPPRESS_GRAYOUT_ENDIF endif; + #endif + + #ifdef FORM_SET_VARSTORE + varstore AMI_GOP_POLICY_SETUP_DATA, + key = AUTO_ID(AMI_GOP_POLICY_SETUP_DATA_ID), + name = AmiGopPolicySetupData, + guid = AMI_GOP_POLICY_VARIABLE_GUID; + #endif + +#ifdef FORM_SET_GOTO +// Define goto commands for the forms defined in this file +// goto ID_OF_MY_FORM, +// prompt = STRING_TOKEN(STR_FORM_TITLE), +// help = STRING_TOKEN(STR_FORM_HELP); + suppressif ideqval AMI_GOP_POLICY_SETUP_DATA.GopDeviceCount == 0x0; + goto AGP_FORM_ID, + prompt = STRING_TOKEN(STR_TITLE), + help = STRING_TOKEN(STR_TITLE_HELP); + endif; //suppressif GopDeviceCount < 1 +#endif //FORM_SET_GOTO + +#ifdef FORM_SET_FORM +// Define forms +// form formid = AUTO_ID(ID_OF_MY_FORM), +// title = STRING_TOKEN(STR_FORM_TITLE); +// endform; + form formid = AUTO_ID(AGP_FORM_ID), + title = STRING_TOKEN(STR_TITLE); + + //suppressif ideqval AMI_GOP_POLICY_SETUP_DATA.GopDeviceCount == 0x0; + SUBTITLE(STRING_TOKEN(STR_GOP_DEVICE_NAME_0)) + SUBTITLE(STRING_TOKEN(STR_GOP_DRIVER_NAME_0)) + + suppressif NOT ideqval AMI_GOP_POLICY_SETUP_DATA.GopOutputCount == 0x1; + oneof varid = SETUP_DATA.GopOutputSelect, + prompt = STRING_TOKEN(STR_GOP_OUTPUT_SELECT), + help = STRING_TOKEN(STR_GOP_OUTPUT_HELP), + option text = STRING_TOKEN(STR_GOP_OUTPUT_NAME_0), value = 0, flags = DEFAULT | MANUFACTURING | INTERACTIVE, key = AUTO_ID(AGP_KEY_0); + endoneof; + endif; //suppressif GopOutputCount != 1 + + suppressif NOT ideqval AMI_GOP_POLICY_SETUP_DATA.GopOutputCount == 0x2; + oneof varid = SETUP_DATA.GopOutputSelect, + prompt = STRING_TOKEN(STR_GOP_OUTPUT_SELECT), + help = STRING_TOKEN(STR_GOP_OUTPUT_HELP), + option text = STRING_TOKEN(STR_GOP_OUTPUT_NAME_0), value = 0, flags = DEFAULT | MANUFACTURING | INTERACTIVE, key = AUTO_ID(AGP_KEY_1); + option text = STRING_TOKEN(STR_GOP_OUTPUT_NAME_1), value = 1, flags = 0; + endoneof; + endif; //suppressif GopOutputCount != 2 + + suppressif NOT ideqval AMI_GOP_POLICY_SETUP_DATA.GopOutputCount == 0x3; + oneof varid = SETUP_DATA.GopOutputSelect, + prompt = STRING_TOKEN(STR_GOP_OUTPUT_SELECT), + help = STRING_TOKEN(STR_GOP_OUTPUT_HELP), + option text = STRING_TOKEN(STR_GOP_OUTPUT_NAME_0), value = 0, flags = DEFAULT | MANUFACTURING | INTERACTIVE, key = AUTO_ID(AGP_KEY_2); + option text = STRING_TOKEN(STR_GOP_OUTPUT_NAME_1), value = 1, flags = 0; + option text = STRING_TOKEN(STR_GOP_OUTPUT_NAME_2), value = 2, flags = 0; + endoneof; + endif; //suppressif GopOutputCount != 3 + + suppressif NOT ideqval AMI_GOP_POLICY_SETUP_DATA.GopOutputCount == 0x4; + oneof varid = SETUP_DATA.GopOutputSelect, + prompt = STRING_TOKEN(STR_GOP_OUTPUT_SELECT), + help = STRING_TOKEN(STR_GOP_OUTPUT_HELP), + option text = STRING_TOKEN(STR_GOP_OUTPUT_NAME_0), value = 0, flags = DEFAULT | MANUFACTURING | INTERACTIVE, key = AUTO_ID(AGP_KEY_3); + option text = STRING_TOKEN(STR_GOP_OUTPUT_NAME_1), value = 1, flags = 0; + option text = STRING_TOKEN(STR_GOP_OUTPUT_NAME_2), value = 2, flags = 0; + option text = STRING_TOKEN(STR_GOP_OUTPUT_NAME_3), value = 3, flags = 0; + endoneof; + endif; //suppressif GopOutputCount != 4 + + suppressif NOT ideqval AMI_GOP_POLICY_SETUP_DATA.GopOutputCount == 0x5; + oneof varid = SETUP_DATA.GopOutputSelect, + prompt = STRING_TOKEN(STR_GOP_OUTPUT_SELECT), + help = STRING_TOKEN(STR_GOP_OUTPUT_HELP), + option text = STRING_TOKEN(STR_GOP_OUTPUT_NAME_0), value = 0, flags = DEFAULT | MANUFACTURING | INTERACTIVE, key = AUTO_ID(AGP_KEY_4); + option text = STRING_TOKEN(STR_GOP_OUTPUT_NAME_1), value = 1, flags = 0; + option text = STRING_TOKEN(STR_GOP_OUTPUT_NAME_2), value = 2, flags = 0; + option text = STRING_TOKEN(STR_GOP_OUTPUT_NAME_3), value = 3, flags = 0; + option text = STRING_TOKEN(STR_GOP_OUTPUT_NAME_4), value = 4, flags = 0; + endoneof; + endif; //suppressif GopOutputCount != 5 + + suppressif NOT ideqval AMI_GOP_POLICY_SETUP_DATA.GopOutputCount == 0x6; + oneof varid = SETUP_DATA.GopOutputSelect, + prompt = STRING_TOKEN(STR_GOP_OUTPUT_SELECT), + help = STRING_TOKEN(STR_GOP_OUTPUT_HELP), + option text = STRING_TOKEN(STR_GOP_OUTPUT_NAME_0), value = 0, flags = DEFAULT | MANUFACTURING | INTERACTIVE, key = AUTO_ID(AGP_KEY_5); + option text = STRING_TOKEN(STR_GOP_OUTPUT_NAME_1), value = 1, flags = 0; + option text = STRING_TOKEN(STR_GOP_OUTPUT_NAME_2), value = 2, flags = 0; + option text = STRING_TOKEN(STR_GOP_OUTPUT_NAME_3), value = 3, flags = 0; + option text = STRING_TOKEN(STR_GOP_OUTPUT_NAME_4), value = 4, flags = 0; + option text = STRING_TOKEN(STR_GOP_OUTPUT_NAME_5), value = 5, flags = 0; + endoneof; + endif; //suppressif GopOutputCount != 6 + + suppressif NOT ideqval AMI_GOP_POLICY_SETUP_DATA.GopOutputCount == 0x7; + oneof varid = SETUP_DATA.GopOutputSelect, + prompt = STRING_TOKEN(STR_GOP_OUTPUT_SELECT), + help = STRING_TOKEN(STR_GOP_OUTPUT_HELP), + option text = STRING_TOKEN(STR_GOP_OUTPUT_NAME_0), value = 0, flags = DEFAULT | MANUFACTURING | INTERACTIVE, key = AUTO_ID(AGP_KEY_6); + option text = STRING_TOKEN(STR_GOP_OUTPUT_NAME_1), value = 1, flags = 0; + option text = STRING_TOKEN(STR_GOP_OUTPUT_NAME_2), value = 2, flags = 0; + option text = STRING_TOKEN(STR_GOP_OUTPUT_NAME_3), value = 3, flags = 0; + option text = STRING_TOKEN(STR_GOP_OUTPUT_NAME_4), value = 4, flags = 0; + option text = STRING_TOKEN(STR_GOP_OUTPUT_NAME_5), value = 5, flags = 0; + option text = STRING_TOKEN(STR_GOP_OUTPUT_NAME_6), value = 6, flags = 0; + endoneof; + endif; //suppressif GopOutputCount != 7 + + suppressif NOT ideqval AMI_GOP_POLICY_SETUP_DATA.GopOutputCount == 0x8; + oneof varid = SETUP_DATA.GopOutputSelect, + prompt = STRING_TOKEN(STR_GOP_OUTPUT_SELECT), + help = STRING_TOKEN(STR_GOP_OUTPUT_HELP), + option text = STRING_TOKEN(STR_GOP_OUTPUT_NAME_0), value = 0, flags = DEFAULT | MANUFACTURING | INTERACTIVE, key = AUTO_ID(AGP_KEY_7); + option text = STRING_TOKEN(STR_GOP_OUTPUT_NAME_1), value = 1, flags = 0; + option text = STRING_TOKEN(STR_GOP_OUTPUT_NAME_2), value = 2, flags = 0; + option text = STRING_TOKEN(STR_GOP_OUTPUT_NAME_3), value = 3, flags = 0; + option text = STRING_TOKEN(STR_GOP_OUTPUT_NAME_4), value = 4, flags = 0; + option text = STRING_TOKEN(STR_GOP_OUTPUT_NAME_5), value = 5, flags = 0; + option text = STRING_TOKEN(STR_GOP_OUTPUT_NAME_6), value = 6, flags = 0; + option text = STRING_TOKEN(STR_GOP_OUTPUT_NAME_7), value = 7, flags = 0; + endoneof; + endif; //suppressif GopOutputCount != 8 + //endif; //suppressif GopDeviceCount < 1 +/* + SEPARATOR + + suppressif ideqval AMI_GOP_POLICY_SETUP_DATA.GopDeviceCount == 0x0 OR + ideqval AMI_GOP_POLICY_SETUP_DATA.GopDeviceCount == 0x1; + SUBTITLE(STRING_TOKEN(STR_GOP_DEVICE_NAME_1)) + SUBTITLE(STRING_TOKEN(STR_GOP_DRIVER_NAME_1)) + endif; //suppressif GopDeviceCount < 2 + + SEPARATOR + + suppressif ideqval AMI_GOP_POLICY_SETUP_DATA.GopDeviceCount == 0x0 OR + ideqval AMI_GOP_POLICY_SETUP_DATA.GopDeviceCount == 0x1 OR + ideqval AMI_GOP_POLICY_SETUP_DATA.GopDeviceCount == 0x2; + SUBTITLE(STRING_TOKEN(STR_GOP_DEVICE_NAME_2)) + SUBTITLE(STRING_TOKEN(STR_GOP_DRIVER_NAME_2)) + endif; //suppressif GopDeviceCount < 3 + + SEPARATOR + + suppressif ideqval AMI_GOP_POLICY_SETUP_DATA.GopDeviceCount == 0x0 OR + ideqval AMI_GOP_POLICY_SETUP_DATA.GopDeviceCount == 0x1 OR + ideqval AMI_GOP_POLICY_SETUP_DATA.GopDeviceCount == 0x2 OR + ideqval AMI_GOP_POLICY_SETUP_DATA.GopDeviceCount == 0x3; + SUBTITLE(STRING_TOKEN(STR_GOP_DEVICE_NAME_3)) + SUBTITLE(STRING_TOKEN(STR_GOP_DRIVER_NAME_3)) + endif; //suppressif GopDeviceCount < 4 +*/ + endform; + +#endif //FORM_SET_FORM + +#endif //ADVANCED_FORM_SET + +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2012, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** diff --git a/Board/EM/AmiGopPolicy/AmiGopPolicy.sdl b/Board/EM/AmiGopPolicy/AmiGopPolicy.sdl new file mode 100644 index 0000000..61cbe39 --- /dev/null +++ b/Board/EM/AmiGopPolicy/AmiGopPolicy.sdl @@ -0,0 +1,268 @@ +#********************************************************************** +#********************************************************************** +#** ** +#** (C)Copyright 1985-2012, American Megatrends, Inc. ** +#** ** +#** All Rights Reserved. ** +#** ** +#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +#** ** +#** Phone: (770)-246-8600 ** +#** ** +#********************************************************************** +#********************************************************************** + +#********************************************************************** +# $Header: /Alaska/SOURCE/Modules/AmiGopPolicy/AmiGopPolicy.sdl 5 12/18/12 11:02p Josephlin $ +# +# $Revision: 5 $ +# +# $Date: 12/18/12 11:02p $ +#********************************************************************** +# Revision History +# ---------------- +# $Log: /Alaska/SOURCE/Modules/AmiGopPolicy/AmiGopPolicy.sdl $ +# +# 5 12/18/12 11:02p Josephlin +# [TAG] EIP108311 +# [Category] Improvement +# [Description] Create eLINK "OemGopEdidOverrideGetEdidList" for easy +# to implement EdidOverrideProtocol in project. +# [Files] AmiGopPolicy.c +# AmiGopPolicy.sdl +# AmiGopPolicy.mak +# AmiGopPolicyLib.c +# +# 4 7/26/12 7:30a Josephlin +# Update File Header. +# +# 3 7/25/12 5:29a Josephlin +# [TAG] EIP93957 +# [Category] Improvement +# [Description] Added ELINK for sd and uni file overriding. This would +# be more flexible then we are using token. +# [Files] AmiGopPolicy.sdl +# +# 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:44a 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 +# +#********************************************************************** +# +# +# Name: AmiGopPolicy.sdl +# +# Description: AmiGopPolicy parameters file. +# +# +#********************************************************************** + +TOKEN + Name = "AmiGopPolicy" + Value = "1" + Help = "Main Switch to Enable AmiGopPolicy in Platform" + TokenType = Boolean + TargetEQU = Yes + TargetMAK = Yes + Master = Yes +End + +TOKEN + Name = "OEM_EDID_OVERRIDE_PROTOCOL_SUPPORT" + Value = "0" + Help = "If set, Include EDID Override Protocol support in Project." + TokenType = Boolean + TargetH = Yes +End + +TOKEN + Name = "AmiGopPolicySetupData" + Value = "$(AMI_GOP_POLICY_SD_FILE)" + TokenType = File + TargetMAK = Yes +End + +TOKEN + Name = "AmiGopPolicySetupString" + Value = "$(AMI_GOP_POLICY_UNI_FILE)" + TokenType = File + TargetMAK = Yes +End + +PATH + Name = "AMIGOPPOLICY_DIR" +End + +MODULE + File = "AmiGopPolicy.mak" +End + +ELINK + Name = "AMI_GOP_POLICY_SD_FILE" + Help = "AmiGopPolicy Setup Data file. Note: This eLink only permit to include one file." + InvokeOrder = ReplaceParent +End + +ELINK + Name = "AMI_GOP_POLICY_UNI_FILE" + Help = "AmiGopPolicy Setup Data file. Note: This eLink only permit to include one file." + InvokeOrder = ReplaceParent +End + +ELINK + Name = "$(AMIGOPPOLICY_DIR)\AmiGopPolicy.sd" + Parent = "AMI_GOP_POLICY_SD_FILE" + InvokeOrder = AfterParent +End + +ELINK + Name = "$(AMIGOPPOLICY_DIR)\AmiGopPolicy.uni" + Parent = "AMI_GOP_POLICY_UNI_FILE" + InvokeOrder = AfterParent +End + +ELINK + Name = "ConnectAmiGopPolicyConOut," + Parent = "ConnectVgaConOut," + InvokeOrder = BeforeParent +End + +ELINK + Name = "$(BUILD_DIR)\AmiGopPolicy.sdb" + Parent = "SETUP_SDBS" + Priority = 90 + InvokeOrder = AfterParent +End + +ELINK + Name = "$(AmiGopPolicySetupData)" + Parent = "SETUP_DEFINITIONS" + Priority = 90 + InvokeOrder = AfterParent +End + +ELINK + Name = "InitAmiGopPolicyStrings," + Parent = "SetupStringInit" + InvokeOrder = AfterParent +End + +ELINK + Name = "AmiGopPolicyEntryPoint," + Parent = "BdsEntryInitialize" + InvokeOrder = AfterParent +End + +ELINK + Name = "OemGopDeviceCheckList" + InvokeOrder = ReplaceParent +End + +ELINK + Name = "AmiDefaultGopDeviceCheck," + Parent = "OemGopDeviceCheckList" + InvokeOrder = AfterParent +End + +ELINK + Name = "OemGopSwitchHookList" + InvokeOrder = ReplaceParent +End + +ELINK + Name = "AmiDefaultGopSwitchFunction," + Parent = "OemGopSwitchHookList" + InvokeOrder = AfterParent +End + +ELINK + Name = "OemGopEdidOverrideGetEdidList" + InvokeOrder = ReplaceParent +End + +ELINK + Name = "AmiDefaultGopEdidOverrideGetEdid," + Parent = "OemGopEdidOverrideGetEdidList" + Token = "OEM_EDID_OVERRIDE_PROTOCOL_SUPPORT" "=" "1" + InvokeOrder = AfterParent +End + +ELINK + Name = "ITEM_CALLBACK(ADVANCED_FORM_SET_CLASS,0,AGP_KEY_0,AmiGopSwitchCallback)," + Parent = "SetupItemCallbacks" + InvokeOrder = AfterParent +End + +ELINK + Name = "ITEM_CALLBACK(ADVANCED_FORM_SET_CLASS,0,AGP_KEY_1,AmiGopSwitchCallback)," + Parent = "SetupItemCallbacks" + InvokeOrder = AfterParent +End + +ELINK + Name = "ITEM_CALLBACK(ADVANCED_FORM_SET_CLASS,0,AGP_KEY_2,AmiGopSwitchCallback)," + Parent = "SetupItemCallbacks" + InvokeOrder = AfterParent +End + +ELINK + Name = "ITEM_CALLBACK(ADVANCED_FORM_SET_CLASS,0,AGP_KEY_3,AmiGopSwitchCallback)," + Parent = "SetupItemCallbacks" + InvokeOrder = AfterParent +End + +ELINK + Name = "ITEM_CALLBACK(ADVANCED_FORM_SET_CLASS,0,AGP_KEY_4,AmiGopSwitchCallback)," + Parent = "SetupItemCallbacks" + InvokeOrder = AfterParent +End + +ELINK + Name = "ITEM_CALLBACK(ADVANCED_FORM_SET_CLASS,0,AGP_KEY_5,AmiGopSwitchCallback)," + Parent = "SetupItemCallbacks" + InvokeOrder = AfterParent +End + +ELINK + Name = "ITEM_CALLBACK(ADVANCED_FORM_SET_CLASS,0,AGP_KEY_6,AmiGopSwitchCallback)," + Parent = "SetupItemCallbacks" + InvokeOrder = AfterParent +End + +ELINK + Name = "ITEM_CALLBACK(ADVANCED_FORM_SET_CLASS,0,AGP_KEY_7,AmiGopSwitchCallback)," + Parent = "SetupItemCallbacks" + InvokeOrder = AfterParent +End + +#********************************************************************** +#********************************************************************** +#** ** +#** (C)Copyright 1985-2012, American Megatrends, Inc. ** +#** ** +#** All Rights Reserved. ** +#** ** +#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +#** ** +#** Phone: (770)-246-8600 ** +#** ** +#********************************************************************** +#********************************************************************** diff --git a/Board/EM/AmiGopPolicy/AmiGopPolicy.uni b/Board/EM/AmiGopPolicy/AmiGopPolicy.uni new file mode 100644 index 0000000..5d15b5b Binary files /dev/null and b/Board/EM/AmiGopPolicy/AmiGopPolicy.uni differ diff --git a/Board/EM/AmiGopPolicy/AmiGopPolicyLib.c b/Board/EM/AmiGopPolicy/AmiGopPolicyLib.c new file mode 100644 index 0000000..00d9f3c --- /dev/null +++ b/Board/EM/AmiGopPolicy/AmiGopPolicyLib.c @@ -0,0 +1,461 @@ +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2012, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** + +//********************************************************************** +// $Header: /Alaska/SOURCE/Modules/AmiGopPolicy/AmiGopPolicyLib.c 9 12/18/12 11:04p Josephlin $ +// +// $Revision: 9 $ +// +// $Date: 12/18/12 11:04p $ +//********************************************************************** +// Revision History +// ---------------- +// $Log: /Alaska/SOURCE/Modules/AmiGopPolicy/AmiGopPolicyLib.c $ +// +// 9 12/18/12 11:04p Josephlin +// [TAG] EIP108311 +// [Category] Improvement +// [Description] Create eLINK "OemGopEdidOverrideGetEdidList" for easy +// to implement EdidOverrideProtocol in project. +// [Files] AmiGopPolicy.c +// AmiGopPolicy.sdl +// AmiGopPolicy.mak +// AmiGopPolicyLib.c +// +// 8 10/29/12 5:53a Josephlin +// [TAG] EIP103432 +// [Category] Bug Fix +// [Severity] Normal +// [Symptom] System hang up druing display switching with external GOP +// card. +// [RootCause] Compiler optimize issue. +// [Solution] Using the optimize pragma to prevent system hang up druing +// display switching. +// +// 7 8/23/12 5:50a Josephlin +// Change eLink handling processing to consider the hierarchy of +// xxxxxHookList. This is able to avoid that get incorrect status. +// +// 6 8/23/12 2:41a Josephlin +// Remove unnecessary conditionally including to fix build fail problem if +// CSM_SUPPORT = OFF. +// +// 5 7/30/12 5:31a Josephlin +// Removed bus number checking in AmiDefaultGopDeviceCheck() to consider +// the DSC-only platform supporting. +// +// 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:44a 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 +// +//********************************************************************** +// +// +// Name: AmiGopPolicyLib.c +// +// Description: AmiGopPolicy initialization code in the Library stage +// +// +//********************************************************************** + +//---------------------------------------------------------------------- +// Include(s) +//---------------------------------------------------------------------- + +#include +#include +#include +#include +#include +#include +#include + +#include +#if OEM_EDID_OVERRIDE_PROTOCOL_SUPPORT +#include +#endif + +//---------------------------------------------------------------------- +// Constant, Macro and Type Definition(s) +//---------------------------------------------------------------------- +// Constant Definition(s) + +// Macro Definition(s) + +// Type Definition(s) + +typedef EFI_STATUS (OEM_GOP_DEVICE_CHECK) ( + IN EFI_HANDLE ControllerHandle, + IN EFI_HANDLE DriverBindingHandle, + IN EFI_PCI_IO_PROTOCOL *PciIo +); + +typedef EFI_STATUS (OEM_GOP_SWITCH_HOOK) ( + IN EFI_HANDLE ControllerHandle, + IN EFI_HANDLE DriverBindingHandle, + IN SETUP_DATA *SetupData, + IN EFI_DEVICE_PATH_PROTOCOL *DevicePath +); + +#if OEM_EDID_OVERRIDE_PROTOCOL_SUPPORT +typedef EFI_STATUS (OEM_GOP_EDID_OVERRIDE_GET_EDID) ( + IN EFI_EDID_OVERRIDE_PROTOCOL *This, + IN EFI_HANDLE *ChildHandle, + OUT UINT32 *Attributes, + IN OUT UINTN *EdidSize, + IN OUT UINT8 **Edid +); +#endif + +extern OEM_GOP_DEVICE_CHECK OEM_GOP_DEVICE_CHECK_LIST EndOfOemGopDeviceCheckList; +extern OEM_GOP_SWITCH_HOOK OEM_GOP_SWITCH_HOOK_LIST EndOfOemGopSwitchHookList; +#if OEM_EDID_OVERRIDE_PROTOCOL_SUPPORT +extern OEM_GOP_EDID_OVERRIDE_GET_EDID OEM_GOP_EDID_OVERRIDE_GET_EDID_LIST EndOfOemGopEdidOverrideGetEdidList; +#endif + +// Function Prototype(s) + +EFI_STATUS ConnectGopDevicePath ( + IN EFI_HANDLE DriverBindingHandle, + IN EFI_DEVICE_PATH_PROTOCOL *pPath ); + +//---------------------------------------------------------------------- +// Variable and External Declaration(s) +//---------------------------------------------------------------------- +// Variable Declaration(s) + +OEM_GOP_DEVICE_CHECK* OemGopDeviceCheckList[] = {OEM_GOP_DEVICE_CHECK_LIST NULL}; +OEM_GOP_SWITCH_HOOK* OemGopSwitchHookList[] = {OEM_GOP_SWITCH_HOOK_LIST NULL}; +#if OEM_EDID_OVERRIDE_PROTOCOL_SUPPORT +OEM_GOP_EDID_OVERRIDE_GET_EDID* OemGopEdidOverrideGetEdidList[] = {OEM_GOP_EDID_OVERRIDE_GET_EDID_LIST NULL}; +#endif + +// GUID Definition(s) + +static EFI_GUID gAmiCsmThunkProtocolGuid = AMI_CSM_THUNK_PROTOCOL_GUID; + +// Protocol Definition(s) + +// External Declaration(s) + +// Function Definition(s) + +//---------------------------------------------------------------------- + +#pragma optimize("", off) + +// +//---------------------------------------------------------------------- +// Name: AmiGopDeviceCheck +// +// Description: None. +// +// Input: None. +// +// Output: None. +// +// Notes: None. +// +//---------------------------------------------------------------------- +// + +EFI_STATUS +AmiGopDeviceCheck ( + IN EFI_HANDLE ControllerHandle, + IN EFI_HANDLE DriverBindingHandle, + IN EFI_PCI_IO_PROTOCOL *PciIo ) +{ + EFI_STATUS Status = EFI_SUCCESS; + UINTN i; + + for (i = 0; OemGopDeviceCheckList[i] != NULL; i++) { + Status = OemGopDeviceCheckList[i] (ControllerHandle, DriverBindingHandle, PciIo); + if(!EFI_ERROR(Status)) break; + } + + return Status; +} + +// +//---------------------------------------------------------------------- +// Name: AmiDefaultGopDeviceCheck +// +// Description: Check if this VGA supports Display Switching function. +// +// Input: IN EFI_HANDLE ControllerHandle +// IN EFI_HANDLE DriverBindingHandle +// IN EFI_PCI_IO_PROTOCOL *PciIo +// +// Output: None. +// +// Notes: Display Switching function may failed because the GOP +// Driver is not supporting. Please contact VGA vendor to +// check for this function supporting. +// +//---------------------------------------------------------------------- +// + +EFI_STATUS +AmiDefaultGopDeviceCheck ( + IN EFI_HANDLE ControllerHandle, + IN EFI_HANDLE DriverBindingHandle, + IN EFI_PCI_IO_PROTOCOL *PciIo ) +{ + EFI_STATUS Status; + UINT8 PciClassCode; + + if (!PciIo) return EFI_INVALID_PARAMETER; + + // Check if this is ThunkDriver + Status = pBS->OpenProtocol( + DriverBindingHandle, + &gAmiCsmThunkProtocolGuid, + NULL, + NULL, + NULL, + EFI_OPEN_PROTOCOL_TEST_PROTOCOL); + if (!EFI_ERROR(Status)) return EFI_UNSUPPORTED; + + // Check if this is VGA controller + Status = PciIo->Pci.Read (PciIo, EfiPciIoWidthUint8, PCI_BCC, 1, &PciClassCode); + if (EFI_ERROR(Status) || (PciClassCode != PCI_CL_DISPLAY)) return EFI_UNSUPPORTED; + + return EFI_SUCCESS; +} + +// +//---------------------------------------------------------------------- +// Name: AmiGopSwitchHook +// +// Description: None. +// +// Input: None. +// +// Output: None. +// +// Notes: None. +// +//---------------------------------------------------------------------- +// + +EFI_STATUS +AmiGopSwitchHook ( + IN EFI_HANDLE ControllerHandle, + IN EFI_HANDLE DriverBindingHandle, + IN SETUP_DATA *SetupData, + IN EFI_DEVICE_PATH_PROTOCOL *DevicePath ) +{ + EFI_STATUS Status = EFI_SUCCESS; + UINTN i; + + for (i = 0; OemGopSwitchHookList[i] != NULL; i++) { + Status = OemGopSwitchHookList[i] (ControllerHandle, DriverBindingHandle, SetupData, DevicePath); + if(!EFI_ERROR(Status)) break; + } + + return Status; +} + +// +//---------------------------------------------------------------------- +// Name: AmiDefaultGopSwitchFunction +// +// Description: None. +// +// Input: None. +// +// Output: None. +// +// Notes: None. +// +//---------------------------------------------------------------------- +// + +EFI_STATUS +AmiDefaultGopSwitchFunction ( + IN EFI_HANDLE ControllerHandle, + IN EFI_HANDLE DriverBindingHandle, + IN SETUP_DATA *SetupData, + IN EFI_DEVICE_PATH_PROTOCOL *DevicePath ) +{ + EFI_STATUS Status = EFI_SUCCESS; + + Status = pBS->DisconnectController (ControllerHandle, NULL, NULL); + Status = ConnectGopDevicePath(DriverBindingHandle, DevicePath); + + return Status; +} + +#if OEM_EDID_OVERRIDE_PROTOCOL_SUPPORT +// +//---------------------------------------------------------------------- +// Name: AmiGopEdidOverrideGetEdid +// +// Description: None. +// +// Input: None. +// +// Output: None. +// +// Notes: None. +// +//---------------------------------------------------------------------- +// + +EFI_STATUS +AmiGopEdidOverrideGetEdid ( + IN EFI_EDID_OVERRIDE_PROTOCOL *This, + IN EFI_HANDLE *ChildHandle, + OUT UINT32 *Attributes, + IN OUT UINTN *EdidSize, + IN OUT UINT8 **Edid ) +{ + EFI_STATUS Status = EFI_SUCCESS; + UINTN i; + + for (i = 0; OemGopEdidOverrideGetEdidList[i] != NULL; i++) { + Status = OemGopEdidOverrideGetEdidList[i] (This, ChildHandle, Attributes, EdidSize, Edid); + if(!EFI_ERROR(Status)) break; + } + + return Status; +} + +// +//---------------------------------------------------------------------- +// Name: AmiDefaultGopEdidOverrideGetEdid +// +// Description: None. +// +// Input: None. +// +// Output: None. +// +// Notes: None. +// +//---------------------------------------------------------------------- +// + +EFI_STATUS +AmiDefaultGopEdidOverrideGetEdid ( + IN EFI_EDID_OVERRIDE_PROTOCOL *This, + IN EFI_HANDLE *ChildHandle, + OUT UINT32 *Attributes, + IN OUT UINTN *EdidSize, + IN OUT UINT8 **Edid ) +{ + EFI_STATUS Status = EFI_UNSUPPORTED; + + return EFI_UNSUPPORTED; +} +#endif + +#pragma optimize("", on) + +// +//---------------------------------------------------------------------- +// Name: ConnectGopDevicePath +// +// Description: None. +// +// Input: None. +// +// Output: None. +// +// Notes: None. +// +//---------------------------------------------------------------------- +// + +EFI_STATUS +ConnectGopDevicePath ( + IN EFI_HANDLE DriverBindingHandle, + IN EFI_DEVICE_PATH_PROTOCOL *pPath ) +{ + EFI_HANDLE Handle; + EFI_STATUS Status; + EFI_STATUS ConnectStatus = EFI_UNSUPPORTED; + + if (pPath == NULL) return EFI_INVALID_PARAMETER; + while (TRUE) + { + EFI_DEVICE_PATH_PROTOCOL *pLastPath=NULL, *pFirstNode = pPath; + if (isEndNode(pPath)) + { + if (pPath->SubType == END_ENTIRE_SUBTYPE) break; + pPath++; + continue; + } + while(TRUE){ + EFI_DEVICE_PATH_PROTOCOL *Dp; + UINT8 SubType; + + pPath = pFirstNode; + + //LocateDevicePath can not work with multi-instance device paths. + //Prepare single instance device path and call LocateDevicePath + Dp = DPGetEndNode(pPath); + SubType = Dp->SubType; + Dp->SubType=END_ENTIRE_SUBTYPE; + Status = pBS->LocateDevicePath(&gEfiDevicePathProtocolGuid, &pPath, &Handle); + Dp->SubType=SubType; + if (EFI_ERROR(Status)) break; + + if (pPath==pLastPath) break; + pLastPath = pPath; + ConnectStatus = pBS->ConnectController(Handle, &DriverBindingHandle, pPath, TRUE); + if (EFI_ERROR(ConnectStatus)) break; + else return ConnectStatus; + } + while (!isEndNode(pPath)) + pPath = NEXT_NODE(pPath); + } + + return ConnectStatus; +} + +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2012, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** 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 +// +//********************************************************************** +// +// +// Name: AmiGopPolicySetup.c +// +// Description: AmiGopPolicy Setup Routines. +// +// +//********************************************************************** + +//---------------------------------------------------------------------- +// Include(s) +//---------------------------------------------------------------------- + +#include +#include +#include +#include "AmiCspLib.h" +#include +#include +#include +#include "AmiGopPolicy.h" + +#include +#include +#include +#include +#include + +//---------------------------------------------------------------------- +// 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) + +//---------------------------------------------------------------------- + +// +//---------------------------------------------------------------------- +// +// Procedure: InitAmiGopPolicyStrings +// +// Description: Initializes AmiGopPolicy Setup String +// +// Parameters: HiiHandle - Handle to HII database +// Class - Indicates the setup class +// +// Returns: None +// +// Notes: +// +//---------------------------------------------------------------------- +// + +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 ); +} + +// +//---------------------------------------------------------------------- +// +// Procedure: AmiGopSwitchCallback +// +// Description: None. +// +// Input: None. +// +// Output: None. +// +// Notes: None. +// +//---------------------------------------------------------------------- +// + +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; +} + +// +//---------------------------------------------------------------------- +// +// 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. +// +//---------------------------------------------------------------------- +// + +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; +} + +// +//---------------------------------------------------------------------------- +// Name: GetDriverBindingHandle +// +// Description: None. +// +// Input: None. +// +// Output: None. +// +// Notes: None. +// +//---------------------------------------------------------------------------- +// + +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; +} + +// +//---------------------------------------------------------------------------- +// Name: GetDriverHandleBuffer +// +// Description: None. +// +// Input: None. +// +// Output: None. +// +// Notes: None. +// +//---------------------------------------------------------------------------- +// + +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; +} + +// +//---------------------------------------------------------------------------- +// +// 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: +// +//---------------------------------------------------------------------------- +// + +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; +} + +// +//---------------------------------------------------------------------------- +// +// 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: +// +//---------------------------------------------------------------------------- +// + +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; +} + +// +//---------------------------------------------------------------------- +// +// Procedure: GetEdidDiscoveredHandlesManagedByDriver +// +// Description: None. +// +// Input: None. +// +// Output: None. +// +// Notes: None. +// +//---------------------------------------------------------------------- +// + +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; +} + +// +//---------------------------------------------------------------------------- +// +// 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: +// +//---------------------------------------------------------------------------- +// + +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; +} + +// +//---------------------------------------------------------------------- +// +// Procedure: GetDeviceName +// +// Description: None. +// +// Input: None. +// +// Output: None. +// +// Notes: None. +// +//---------------------------------------------------------------------- +// + +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 ** +//** ** +//********************************************************************** +//********************************************************************** -- cgit v1.2.3