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/Setup/Setup.c | 1541 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1541 insertions(+) create mode 100644 Board/EM/Setup/Setup.c (limited to 'Board/EM/Setup/Setup.c') diff --git a/Board/EM/Setup/Setup.c b/Board/EM/Setup/Setup.c new file mode 100644 index 0000000..5900319 --- /dev/null +++ b/Board/EM/Setup/Setup.c @@ -0,0 +1,1541 @@ +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2010, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** + +//********************************************************************** +// $Header: /Alaska/BIN/Board/Setup/Setup.c 67 10/04/12 4:50p Artems $ +// +// $Revision: 67 $ +// +// $Date: 10/04/12 4:50p $ +//********************************************************************** +// Revision History +// ---------------- +// $Log: /Alaska/BIN/Board/Setup/Setup.c $ +// +// 67 10/04/12 4:50p Artems +// [TAG] EIP N/A +// [Category] Spec Update +// [Severity] Minor +// [Description] Added missing function headers for CHM builder +// [Files] Setup.c +// +// 66 8/29/12 2:42p Artems +// [TAG] EIP N/A +// [Category] Bug Fix +// [Severity] Normal +// [Symptom] setup control interactive callback doesn't work +// [RootCause] When there are no runtime-registered callbacks, +// build-time callbacks don't present in callback list +// [Solution] Fixed code logic to handle situation with no runtime +// callbacks +// [Files] AmiSetupProtocol.c Setup.c +// +// 65 8/28/12 4:10p Artems +// [TAG] EIP N/A +// [Category] New Feature +// [Description] Add infrastructure to support runtime registration of +// setup controls callbacks +// [Files] Setup.c Setup.h Setup.cif AmiSetupProtocol.c +// AmiSetupProtocol.h +// +// 64 4/12/12 4:41p Artems +// [TAG] EIP81090 +// [Category] Improvement +// [Description] Show specification version in 2 or 3 digits format +// depending on value (i.e. 2.1 or 2.3.1) +// [Files] Setup.c +// +// 63 7/01/11 3:15p Artems +// Added project build number to project version string +// +// 62 6/21/11 9:24a Felixp +// EIP58960: Callback function is updateed to return status of the eLink +// based callback routine back to the browser. +// +// 61 3/21/11 4:15p Felixp +// Enhancement: Callback function is updated to set ActionRequest to NONE. +// +// 60 3/08/11 12:09p Felixp +// Bug fix (EIP 55443): Password length restriction message is updated +// to work properly during language switch. +// +// 59 2/08/11 3:32p Artems +// Reduced function header comment line to fit CHM file +// +// 58 2/07/11 5:25p Artems +// EIP 53374: Replaced tabs with spaces +// +// 57 2/04/11 7:59p Artems +// Added PI 1.1 support +// +// 1 2/02/11 5:16p Artems +// +// 56 9/07/10 11:05p Felixp +// Minor fix: Spelling error (EIP 39919) +// +// 55 2/24/10 11:50a Felixp +// Use CORE_COMBINED_VERSION token. +// Initialize UEFI Specification compliancy string +// Initialize min/max password length string +// +// 54 2/05/10 2:11p Felixp +// +// 53 2/05/10 2:10p Felixp +// Improvements in the Setup Callback Mechanism. +// - The definition of the type of the Setup Callback Handling +// function, +// registered using ITEM_CALLBACK eLink, is moved from Setup.c to +// Setup.h(Core file). +// The type is renamed from UPDATE_ITEM to +// SETUP_ITEM_CALLBACK_HANDLER. +// - The return type of the Setup Callback Handling function is changed +// from VOID to EFI_STATUS. +// The status only matters for UEFI 2.1 Configurations. If UEFI 2.1 +// callback handler returns +// any status other than EFI_UNSUPPORTED, processing of the +// callback handler list, +// defined by the SetupItemCallbacks eLink, is terminated and +// control is returned back to the HII browser. +// - New GetCallbackParameters function is added. The function provides +// access to all callback +// parameters received from the HII browser. +// +// 52 11/25/09 11:40a Felixp +// +// 51 11/25/09 11:36a Felixp +// Action parameter of the Callback function is updated based on UEFI +// errata +// +// 50 11/23/09 5:03p Felixp +// SetupCallBack structure is updated to use formset GUID from Setup.h. +// DEFAULT_LANGUAGE is replaced with DEFAULT_LANGUAGE_CODE, which is +// passed from make file using /D +// +// 49 10/21/09 3:21p Felixp +// LastLang/LastLangCodes - use different variable for UEFI 2.0 and UEFI +// 2.1 modes +// +// 48 10/21/09 3:15p Felixp +// +// 46 10/09/09 6:43p Felixp +// UEFI 2.1 Support (the component is updated to support Framework and +// UEFI 2.1 HII). +// +// 45 7/01/09 2:34p Felixp +// SetupEntry updated to use absence of LastLangCodes variable (instead of +// Lang or Setup) as an indication of the first boot. +// +// 44 6/30/09 2:33p Robert +// comment corrections +// +// 43 6/30/09 2:28p Robert +// Comment updates +// +// 42 6/30/09 11:42a Robert +// Added Comment and updated parts for coding standards +// +// 41 5/22/09 6:46p Felixp +// Minor bug fix in InitStrings function +// +// 40 2/23/09 10:18a Oleksiyy +// Bug fix (EIP 18214) Build process failed if too many SetupItemCallbacks +// in one command line. Solution is to +// forward SETUP_ITEM_CALLBACK_LIST definition into SetupCallbackList.h +// file, generated during the build process (in Setup.mak), and include it +// into Setup.c. +// +// 39 10/10/08 4:44p Felixp +// UEFI2.0 Language Variable added and code to sync up values of the new +// and old language varaibles. +// +// 38 4/18/08 6:32p Felixp +// Undo previous status code reporting changed. +// They are not needed because the same status codes are reported by the +// TSE included with Core 4.6.3.2 +// +// 36 2/21/08 5:19p Felixp +// 1. CMOS handling code removed because it's platform specific and does +// not belong in generic Setup module. +// 2. Core version string updated to use CORE_BUILD_NUMBER +// +// 33 1/24/08 1:21p Felixp +// ALWAYS_PUBLISH_HII_RESOURCES SDL token added +// +// 32 10/30/07 11:24a Felixp +// SDL tokens to hide advanced, chipset, and security formsets added +// +// 31 9/05/07 8:31p Felixp +// Bug fix in Lang variable initialization. +// +// 28 8/31/07 12:43a Felixp +// SetupEntry updated to support defaults generated during build process. +// +// 27 3/19/07 8:50a Felixp +// Bug fix in SetupEntry +// +// 26 3/18/07 12:42p Felixp +// 1. Code clean up +// 2. Initialization of LangCodes variable when SetupCallback is not +// invoked +// +// 25 3/06/07 3:12p Vyacheslava +// Support for initialization of the Lang and LangCodes variables based on +// available languages in HII. +// +// 22 12/05/06 12:25p Felixp +// Use date/time stamps from TimeStamp.h instead of C __DATE__ macro +// +// 20 10/30/06 7:16p Felixp +// Bug fix in Setup variable initialization (HII 0.92 related changes) +// +// 19 10/30/06 5:45p Felixp +// Updated to be complient with HII Spec. 0.92 (used to be 0.91) +// +// 18 10/07/06 11:13a Felixp +// Add "x64" to the BIOS version in x64 mode +// +// 17 5/23/06 4:20a Felixp +// FW Verion extraction logic changed +// +// 12 2/06/06 6:30p Felixp +// Support for Callbacks added +// +// 11 11/08/05 5:13a Felixp +// 1. Now resources are only loaded if Setup is about to be launched +// 2. Support for unconditional (w/o user intervention) launch of Setup +// when NVRAM is blank +// +// 8 7/19/05 10:09p Felixp +// 1. InitString modified to update string for all languages +// 2. Memory information removed (moved to NB) +// +// 6 7/14/05 7:06p Felixp +// Setup variable initialization with default values added +// +// 2 5/31/05 11:21a Felixp +// CPU frequency display disabled +// +// 10 5/24/05 3:07p Felixp +// Modular setup framework implemented +// +// 7 3/25/05 7:12p Felixp +// SetupInit Protocol installed +// +// 5 3/17/05 7:50p Felixp +// form callback support added +// +// 4 3/17/05 2:00p Felixp +// 1. LoadResources updated to support multiple form sets +// 2. Setup variable created +// +// 2 3/07/05 7:06p Felixp +// support for embedded resources added +// +//********************************************************************** +// +// +// Name: Setup.c +// +// Description: +// This file contains supporting functions, data types and data that +// correspond to the Setup driver. +// +// +//********************************************************************** + +//======================================================================= +// Includes +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if EFI_SPECIFICATION_VERSION>0x20000 +#include +#include +#else +#include +#endif +#include "SetupPrivate.h" +#include +#include + +//======================================================================= +// MACROs +#define STR CONVERT_TO_WSTRING + +#if EFI_SPECIFICATION_VERSION>0x20000 +#define LastLangCodes L"PlatformLastLangCodes" +#define LastLang L"PlatformLastLang" +#define NativeLangCodes L"PlatformLangCodes" +#define CompatLangCodes L"LangCodes" +#define NativeLang L"PlatformLang" +#define CompatLang L"Lang" +#define LangNativeListToCompatList RfcListToIsoList +#define LangToCompat RfcToIso +#define LangToNative IsoToRfc +#define GetFirstLang GetFirstRfcLang +#else +#define LastLangCodes L"LastLangCodes" +#define LastLang L"LastLang" +#define NativeLangCodes L"LangCodes" +#define CompatLangCodes L"PlatformLangCodes" +#define NativeLang L"Lang" +#define CompatLang L"PlatformLang" +#define LangNativeListToCompatList IsoListToRfcList +#define LangToCompat IsoToRfc +#define LangToNative RfcToIso +#define GetFirstLang GetFirstIsoLang +#endif + +//======================================================================= +// GUIDs +static EFI_GUID guidSetup = SETUP_GUID; +static EFI_GUID guidEfiVar = EFI_GLOBAL_VARIABLE; + +//======================================================================= +// Module specific global variables +EFI_HANDLE ThisImageHandle = NULL; +#if EFI_SPECIFICATION_VERSION>0x20000 +static EFI_HII_STRING_PROTOCOL *HiiString=NULL; +static EFI_HII_DATABASE_PROTOCOL *HiiDatabase=NULL; +#else +EFI_HII_PROTOCOL *pHii = NULL; +#endif +UINT8 Setup[sizeof(SETUP_DATA)]; + +// +//---------------------------------------------------------------------------- +// Name: SETUP_CALLBACK +// +// Fields: Type Name Description +// EFI_FORM_CALLBACK_PROTOCOL Callback - Callback Protocol Instance for the +// Class and SubClass defined below +// UINT16 Class - Value defined to identify a particular Hii form +// UINT16 SubClass - Secondary value used to uniquely define the an Hii form +// +// Description: +// These Data Structure define a structure used to match a specific +// Callback Protocol to an HII Form through the use of Class and SubClass +// values +// +// Notes: +//---------------------------------------------------------------------------- +// +typedef struct { +#if EFI_SPECIFICATION_VERSION>0x20000 + EFI_HII_CONFIG_ACCESS_PROTOCOL Callback; +#else + EFI_FORM_CALLBACK_PROTOCOL Callback; +#endif + UINT16 Class, SubClass; +} SETUP_CALLBACK; + +#if EFI_SPECIFICATION_VERSION>0x20000 +EFI_STATUS Callback( + IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This, + IN EFI_BROWSER_ACTION Action, + IN EFI_QUESTION_ID KeyValue, + IN UINT8 Type, + IN EFI_IFR_TYPE_VALUE *Value, + OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest +); +#else +EFI_STATUS Callback( + IN EFI_FORM_CALLBACK_PROTOCOL *This, + IN UINT16 KeyValue, + IN EFI_IFR_DATA_ARRAY *Data, + OUT EFI_HII_CALLBACK_PACKET **Packet +); +#endif + +EFI_STATUS InitAmiSetupProtocol(VOID); + +// +//---------------------------------------------------------------------------- +// Name: Callback_Protocols +// +// Description: +// These Variable definitions define the different formsets and what Callback +// protocol should be used for each one +// +//---------------------------------------------------------------------------- +// +SETUP_CALLBACK MainCallbackProtocol = {{NULL,NULL,Callback},MAIN_FORM_SET_CLASS,0}; +SETUP_CALLBACK AdvancedCallbackProtocol = {{NULL,NULL,Callback},ADVANCED_FORM_SET_CLASS,0}; +SETUP_CALLBACK ChipsetCallbackProtocol = {{NULL,NULL,Callback},CHIPSET_FORM_SET_CLASS,0}; +SETUP_CALLBACK BootCallbackProtocol = {{NULL,NULL,Callback},BOOT_FORM_SET_CLASS,0}; +SETUP_CALLBACK SecurityCallbackProtocol = {{NULL,NULL,Callback},SECURITY_FORM_SET_CLASS,0}; +SETUP_CALLBACK ExitCallbackProtocol = {{NULL,NULL,Callback},EXIT_FORM_SET_CLASS,0}; + +EFI_GUID MainFormSetGuid = MAIN_FORM_SET_GUID; +EFI_GUID AdvancedFormSetGuid = ADVANCED_FORM_SET_GUID; +EFI_GUID ChipsetFormSetGuid = CHIPSET_FORM_SET_GUID; +EFI_GUID BootFormSetGuid = BOOT_FORM_SET_GUID; +EFI_GUID SecurityFormSetGuid = SECURITY_FORM_SET_GUID; +EFI_GUID ExitFormSetGuid = EXIT_FORM_SET_GUID; + + +// +//---------------------------------------------------------------------------- +// Name: SetupCallBack +// +// Fields: Type Name Description +// EFI_GUID* pGuid - GUID used for future references +// EFI_FORM_CALLBACK_PROTOCOL* pFormCallback - Structure that defines the Callback +// that occurs for this package +// UINT16 Class - Formset Class of the Form Callback Protocol passed in +// UINT16 SubClass - Formset Sub Class of the Form Callback Protocol passed in +// EFI_HII_HANDLE HiiHandle - handle that identifies used Hii Package +// +// Description: +// This array contains the different Hii packages that are used in the system +// +// Notes: +// The HiiHandle is updated in the LoadResources function when the Hii Packages +// are loaded +//---------------------------------------------------------------------------- +// +CALLBACK_INFO SetupCallBack[] = { + // Last field in every structure will be filled by the Setup + { &MainFormSetGuid, &MainCallbackProtocol.Callback, MAIN_FORM_SET_CLASS, 0, 0}, + { &AdvancedFormSetGuid, &AdvancedCallbackProtocol.Callback, ADVANCED_FORM_SET_CLASS, 0, 0}, + { &ChipsetFormSetGuid, &ChipsetCallbackProtocol.Callback, CHIPSET_FORM_SET_CLASS, 0, 0}, + { &BootFormSetGuid, &BootCallbackProtocol.Callback, BOOT_FORM_SET_CLASS, 0, 0}, + { &SecurityFormSetGuid, &SecurityCallbackProtocol.Callback, SECURITY_FORM_SET_CLASS, 0, 0}, + { &ExitFormSetGuid, &ExitCallbackProtocol.Callback, EXIT_FORM_SET_CLASS, 0, 0} +}; + +// +//---------------------------------------------------------------------------- +// Name: FormsetVisible +// +// Description: +// This array contains information that indicates to the system whether or not +// a formset is visible when Setup is loaded. +// +// Reference: +// SetupCallBack +// +// Notes: +// Formset index in this array should match with the formset index in the +// SetupCallBack array +// +//---------------------------------------------------------------------------- +// +BOOLEAN FormsetVisible[] = { + TRUE, //Main formset is always displayed + SHOW_ADVANCED_FORMSET, //Advanced formset + SHOW_CHIPSET_FORMSET, //Chipset formset + TRUE, //Boot formset is always displayed + SHOW_SECURITY_FORMSET, //Security formset + TRUE //Exit formset is always displayed +}; + +#define NUMBER_OF_FORMSETS (sizeof(SetupCallBack)/sizeof(CALLBACK_INFO)) + +// +//---------------------------------------------------------------------------- +// Name: InitString +// +// Description: +// This function updates a string defined by the StrRef Parameter in the HII +// database with the string and data passed in. +// +// Input: +// EFI_HII_HANDLE HiiHandle - handle that identifies used Hii Package +// STRING_REF StrRef - String Token defining string in the database to update +// CHAR16 *sFormat - string with format descriptors in it +// ... - extra paramaters that define data that correlate to the format +// descriptors in the String +// +// Output: +// None +// +// Notes: +//---------------------------------------------------------------------------- +// +VOID InitString(EFI_HII_HANDLE HiiHandle, STRING_REF StrRef, CHAR16 *sFormat, ...) +{ + CHAR16 s[1024]; + va_list ArgList = va_start(ArgList,sFormat); + Swprintf_s_va_list(s,sizeof(s),sFormat,ArgList); + va_end(ArgList); + HiiLibSetString(HiiHandle, StrRef, s); +} + +// +//---------------------------------------------------------------------------- +// Name: RevisionToString +// +// Description: +// This function converts spec revision number to string +// +// Input: +// OUT CHAR16 *String - pointer to string to store output +// IN UINT32 Revision - spec revision number +// +// Output: +// None +// +//---------------------------------------------------------------------------- +// +VOID RevisionToString( + OUT CHAR16 *String, + IN UINT32 Revision +) +{ + UINT16 Major; + UINT16 MinorH; + UINT16 MinorL; + UINT16 *Walker; + + Walker = (UINT16 *)&Revision; + Major = *(Walker + 1); + MinorH = *Walker / 10; + MinorL = *Walker % 10; + + if(MinorL != 0) + Swprintf(String, L"%d.%d.%d", Major, MinorH, MinorL); + else + Swprintf(String, L"%d.%d", Major, MinorH); +} + + +// +//---------------------------------------------------------------------------- +// Name: InitMain +// +// Description: +// This function updates a few generic BIOS strings that are used on the +// setup pages. +// +// Input: +// EFI_HII_HANDLE HiiHandle - handle that identifies used Hii Package +// +// Output: +// None +// +// Notes: +//---------------------------------------------------------------------------- +// +VOID InitMain(EFI_HII_HANDLE HiiHandle) +{ + DXE_SERVICES *DxeTable; + CHAR16 efi[10]; + CHAR16 pi[10]; + + ///////////////// BIOS ///////////////////////////////////// + CHAR16 *FirmwareVendor = (pST->FirmwareVendor) + ? pST->FirmwareVendor + : CONVERT_TO_WSTRING(CORE_VENDOR); + UINT32 FirmwareRevision = (pST->FirmwareRevision) + ? pST->FirmwareRevision + : CORE_COMBINED_VERSION; + + InitString( + HiiHandle,STRING_TOKEN(STR_BIOS_VENDOR_VALUE), + L"%s", FirmwareVendor + ); + InitString( + HiiHandle,STRING_TOKEN(STR_BIOS_CORE_VERSION_VALUE), + L"%d.%d.%d.%d", + ((UINT16*)&pST->FirmwareRevision)[1], + *(UINT16*)&pST->FirmwareRevision / 100, + *(UINT16*)&pST->FirmwareRevision % 100 / 10, + *(UINT16*)&pST->FirmwareRevision % 10 + ); + InitString( + HiiHandle,STRING_TOKEN(STR_BIOS_VERSION_VALUE), +#if PROJECT_BUILD_NUMBER_IN_TITLE_SUPPORTED && defined (PROJECT_BUILD) +#ifdef EFIx64 + L"%s %d.%02d.%03d x64", +#else + L"%s %d.%02d.%03d", +#endif + STR(PROJECT_TAG), PROJECT_MAJOR_VERSION, PROJECT_MINOR_VERSION, PROJECT_BUILD +#else //#if PROJECT_BUILD_NUMBER_IN_TITLE_SUPPORTED && defined (PROJECT_BUILD) +#ifdef EFIx64 + L"%s %d.%02d x64", +#else + L"%s %d.%02d", +#endif + STR(PROJECT_TAG), PROJECT_MAJOR_VERSION, PROJECT_MINOR_VERSION +#endif//#if PROJECT_BUILD_NUMBER_IN_TITLE_SUPPORTED && defined (PROJECT_BUILD) + ); + InitString( + HiiHandle,STRING_TOKEN(STR_BIOS_DATE_VALUE), + L"%s %s", L_TODAY, L_NOW + ); + VERIFY_EFI_ERROR(LibGetDxeSvcTbl(&DxeTable)); + + RevisionToString(efi, pST->Hdr.Revision); + RevisionToString(pi, DxeTable->Hdr.Revision); + + InitString( + HiiHandle,STRING_TOKEN(STR_BIOS_COMPLIANCY_VALUE), + L"UEFI %s; PI %s", efi, pi + ); +} + +VOID InitParts(EFI_HII_HANDLE HiiHandle, UINT16 Class); + +// +//---------------------------------------------------------------------------- +// Name: InitStrings +// +// Description: +// This function is called for each Formset and initializes strings based on +// the porting provided and then updates the HII database +// +// Input: +// EFI_HII_HANDLE HiiHandle - handle that that identifies used Hii Package +// CALLBACK_INFO *pCallBackFound - pointer to an instance of CALLBACK_INFO +// that works with HiiHandle +// +// Output: +// None +// +// Notes: +//---------------------------------------------------------------------------- +// +VOID InitStrings( + EFI_HII_HANDLE HiiHandle, + CALLBACK_INFO *pCallBackFound +) +{ + if (!pCallBackFound || !pCallBackFound->HiiHandle) return; + + InitParts(HiiHandle, pCallBackFound->Class); + switch(pCallBackFound->Class) + { + case MAIN_FORM_SET_CLASS: + InitMain(HiiHandle); + break; + case SECURITY_FORM_SET_CLASS: + { + InitString( + HiiHandle,STRING_TOKEN(STR_MIN_PASSWORD_LENGTH__VALUE), + L"%d", PASSWORD_MIN_SIZE + ); + InitString( + HiiHandle,STRING_TOKEN(STR_MAX_PASSWORD_LENGTH__VALUE), + L"%d", PASSWORD_MAX_SIZE + ); + break; + } + } +#if EFI_SPECIFICATION_VERSION>0x20000 +// TODO: Defaults initialization +#else +{ + EFI_HII_VARIABLE_PACK_LIST *pVarPackList, *pVarPack; + + // Get default values from IFR initialized with default values + if (EFI_ERROR(pHii->GetDefaultImage( + pHii, HiiHandle, EFI_IFR_FLAG_DEFAULT, &pVarPackList + ))) return; + + // Find Setup variable(default varstore) in the returned variable list + for(pVarPack = pVarPackList; pVarPack->NextVariablePack != NULL; pVarPack = pVarPack->NextVariablePack) + { + EFI_HII_VARIABLE_PACK *pVar = pVarPack->VariablePack; + UINTN i; + UINT8 *p, *q; + //default varstore has id set to 0 + if (pVar->VariableId != 0) continue; + //if size does not match, don't update the setup data + if (pVar->Header.Length - sizeof(*pVar) - pVar->VariableNameLength != sizeof(Setup)) + { + TRACE(( + TRACE_DXE_CORE, + "ERROR: Setup data size mismatch:\n\t" + "Setup variable size: %d\n\t" + "Default varstore size: %d\n", + sizeof(Setup), + pVar->Header.Length - sizeof(*pVar) - pVar->VariableNameLength + )); + break; + } + p = (UINT8*)&Setup; + q = (UINT8*)(pVar + 1) + pVar->VariableNameLength; + for(i = 0; i < sizeof(Setup); i++) p[i] |= q[i]; + break; + } + pBS->FreePool(pVarPackList); +} +#endif +} + +// +//---------------------------------------------------------------------------- +// +// Procedure: InitLanguages +// +// Description: +// Determine the current language that will be used based on language +// related EFI Variables. +// +// Input: +// EFI_HII_HANDLE HiiHandle - handle that that identifies used Hii Package +// +// Output: +// None +// +// Notes: +//---------------------------------------------------------------------------- +// +VOID InitLanguages(EFI_HII_HANDLE HiiHandle) +{ + UINTN Size = 0; +#if EFI_SPECIFICATION_VERSION>0x20000 + EFI_STATUS Status; + CHAR8* LangCodes = NULL; + + if (HiiString == NULL) { + return; + } + + Status = HiiString->GetLanguages(HiiString, HiiHandle, LangCodes, &Size); + if (Status==EFI_BUFFER_TOO_SMALL){ + LangCodes = Malloc(Size); + Status = HiiString->GetLanguages(HiiString, HiiHandle, LangCodes, &Size); + if (EFI_ERROR(Status)) pBS->FreePool(LangCodes); + } + if (EFI_ERROR(Status)){ + Size = sizeof(CONVERT_TO_STRING(DEFAULT_LANGUAGE_CODE)); + LangCodes = Malloc(Size); + pBS->CopyMem( + LangCodes, CONVERT_TO_STRING(DEFAULT_LANGUAGE_CODE), Size + ); + } +#else + EFI_STATUS PrimaryStatus; + EFI_STATUS SecondaryStatus; + UINTN i; + UINTN Index = 0; + CHAR8* LangCodes = NULL; + CHAR16* PrimaryLanguages = NULL; + EFI_STRING SecondaryLanguages = NULL; + + if (pHii == NULL) { + return; + } + + // Get list of available languages + PrimaryStatus = pHii->GetPrimaryLanguages( pHii, + HiiHandle, + &PrimaryLanguages ); + + SecondaryStatus = pHii->GetSecondaryLanguages( pHii, + HiiHandle, + PrimaryLanguages, + &SecondaryLanguages ); + + if ( !EFI_ERROR(PrimaryStatus) ) { + Size = Wcslen(PrimaryLanguages); + } + + if ( !EFI_ERROR(SecondaryStatus) ) { + Size += Wcslen(SecondaryLanguages); + } + + if ( Size == 0 ) { + // Primary and Secondary languages are not available + Size = 3; + LangCodes = Malloc(Size); + pBS->CopyMem( + LangCodes, CONVERT_TO_STRING(DEFAULT_LANGUAGE_CODE), + Size + ); + } else { + LangCodes = MallocZ(Size); + if ( !EFI_ERROR(PrimaryStatus) ) { + // Convert PrimaryLanguages from Unicode to EFI defined ASCII LangCodes + for (i = 0; PrimaryLanguages[i] != 0; i++) { + LangCodes[Index++] = (CHAR8)PrimaryLanguages[i]; + } + pBS->FreePool(PrimaryLanguages); + } + + if ( !EFI_ERROR(SecondaryStatus) ) { + // Convert SecondaryLanguages from Unicode to EFI defined ASCII LangCodes + for (i = 0; SecondaryLanguages[i] != 0; i++) { + LangCodes[Index++] = (CHAR8)SecondaryLanguages[i]; + } + + pBS->FreePool(SecondaryLanguages); + } + } +#endif + //LangCodes is a volatile variable and needs to be initialized during every boot + //However, this routine is not invoked during every boot, + //It is always invoked during the first boot. + //During subsequent boots it is only invoked when user is trying to enter Setup + //In order to initialize LanCodes when this routine is not invoked, let's create + //a non-volatile variable LastLangCodes with the copy of LanCodes. + //This copy is used to initialize LanCodes when this routine is not invoked. + //(This code is part of SynchornizeLanguageVariables routine) + pRS->SetVariable( LastLangCodes, + &guidSetup, + EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE, + Size, + LangCodes ); + + pBS->FreePool(LangCodes); +} + +// +//---------------------------------------------------------------------------- +// +// Procedure: SetupCallback +// +// Description: +// This function publishes all HII resources and initializes the HII databases +// There is a token ALWAYS_PUBLISH_HII_RESOURCES that would call this function +// on every boot not just when the user tries to enter Setup +// +// Input: +// IN EFI_EVENT Event - Event that was triggered +// IN VOID *Context - data pointer to context information +// +// Output: +// None +// +// Notes: +//---------------------------------------------------------------------------- +// +VOID SetupCallback(IN EFI_EVENT Event, IN VOID *Context) +{ + static BOOLEAN ResourcesLoaded = FALSE; + UINT32 i; + +#if EFI_SPECIFICATION_VERSION>0x20000 + if ( !HiiString + && EFI_ERROR(pBS->LocateProtocol( + &gEfiHiiStringProtocolGuid, NULL, &HiiString + )) + ) return ; + if ( !HiiDatabase + && EFI_ERROR(pBS->LocateProtocol( + &gEfiHiiDatabaseProtocolGuid, NULL, &HiiDatabase + )) + ) return ; +#else + if (!pHii && EFI_ERROR(pBS->LocateProtocol(&gEfiHiiProtocolGuid, NULL, &pHii))) return ; +#endif + if (Event) pBS->CloseEvent(Event); + if (ResourcesLoaded) return; + ResourcesLoaded = TRUE; + LoadResources(ThisImageHandle, NUMBER_OF_FORMSETS, SetupCallBack, InitStrings); + //Get list of available languages and initialize Lang and LangCodes variables + //All setup packages share the same string pack + //that's why it is enough to only process single pack in the SetupCallBack array. + InitLanguages(SetupCallBack[0].HiiHandle); + //Hide (remove) formsets if necessary + for(i = 0; i < NUMBER_OF_FORMSETS; i++){ + if (!FormsetVisible[i]) +#if EFI_SPECIFICATION_VERSION>0x20000 + HiiDatabase->RemovePackageList( + HiiDatabase, SetupCallBack[i].HiiHandle + ); +#else + pHii->RemovePack(pHii, SetupCallBack[i].HiiHandle); +#endif + } +} + +// +//---------------------------------------------------------------------------- +// Procedure: IsoToRfc +// +// Description: +// This function takes a language string based on the ISO standard and +// returns a string that represents the same language in the RFC standard +// +// Input: +// IN CHAR8 *IsoLang - ASCII string that represents language in the ISO format +// +// Output: +// CHAR8 * - String that represents RFC version of the ISO language code passed +// +// Notes: +//---------------------------------------------------------------------------- +// +CHAR8* IsoToRfc(IN CHAR8 *IsoLang, OUT UINTN *RfcLangSize){ + UINTN i; + if (IsoLang == NULL) return NULL; + for(i = 0; Iso6392LanguageList[i] != NULL; i++){ + if (MemCmp(Iso6392LanguageList[i], IsoLang, 3) == 0){ + if (RfcLangSize!=NULL) + *RfcLangSize = Strlen(Rfc4646LanguageList[i])+1; + return Rfc4646LanguageList[i]; + } + } + return NULL; +} + +// +//---------------------------------------------------------------------------- +// Procedure: RfcToIso +// +// Description: +// This function takes a language string based on the RFC standard and +// returns a string that represents the same language in the ISO standard +// +// Input: +// IN CHAR8 *RfcLang - ASCII string that represents a language in RFC standard +// +// Output: +// CHAR8 * - String that represents ISO version of the RFC language code passed +// +// Notes: +//---------------------------------------------------------------------------- +// +CHAR8* RfcToIso(IN CHAR8 *RfcLang, OUT UINTN *IsoLangSize){ + UINTN i; + if (RfcLang == NULL) return NULL; + for(i = 0; Rfc4646LanguageList[i] != NULL; i++){ + if (Strcmp(Rfc4646LanguageList[i],RfcLang) == 0){ + if (IsoLangSize!=NULL) *IsoLangSize = 3; + return Iso6392LanguageList[i]; + } + } + return NULL; +} + +// +//---------------------------------------------------------------------------- +// Procedure: IsoListToRfcList +// +// Description: +// This function coverts list of ISO language tags to a list of RFC language tags +// +// Input: +// IN CHAR8 *IsoList - string that represents list of one or more ISO language strings +// IN UINTN IsoListSize - number of ISO entries in the list +// OUT UINTN *RfcListSize - pointer to store size of output buffer +// +// Output: +// VOID * - String that represents the RFC version of the ISO language codes passed +// +// Notes: +// ISO tags are 3 characters in size +// RFC tags are 42(max) characters plus a ';' that ends each tag +//---------------------------------------------------------------------------- +// +CHAR8* IsoListToRfcList(IN CHAR8 *IsoList, IN UINTN IsoListSize, OUT UINTN *RfcListSize){ + CHAR8 *IsoPtr; + CHAR8 *RfcList; + CHAR8 *RfcPtr; + + if (IsoList==NULL || *IsoList==0 || IsoListSize<3) return NULL; + //IsoListSize/3 = number of languages in the list + //RFC4646 defines max lang tag size of 42, plus ';' + RfcList = Malloc(IsoListSize / 3 * (42 + 1)); + if (RfcList == NULL) return NULL; + for(IsoPtr = IsoList, RfcPtr = RfcList; + IsoPtr < IsoList + IsoListSize; + IsoPtr += 3 + ){ + UINTN Length; + CHAR8 *TmpPtr = IsoToRfc(IsoPtr, &Length); + + if (TmpPtr == NULL) continue; + Length--; // string length = string size - 1 + MemCpy(RfcPtr, TmpPtr, Length); + RfcPtr += Length; + *RfcPtr++ = ';'; + } + if (RfcPtr == RfcList){ + pBS->FreePool(RfcList); + if (RfcListSize) *RfcListSize=0; + return NULL; + } + *(RfcPtr - 1) = 0; + if (RfcListSize) *RfcListSize=RfcPtr-RfcList; + return RfcList; +} + +// +//---------------------------------------------------------------------------- +// Procedure: RfcListToIsoList +// +// Description: +// This function coverts list of RFC language tags to a list of ISO language tags +// +// Input: +// IN CHAR8 *RfcList - string that represents list of one or more RFC language strings +// IN UINTN RfcListSize - number of RFC entries in the list +// OUT UINTN *IsoListSize - pointer to store size of output buffer +// +// Output: +// CHAR8 * - A string that corresponds to the ISO version of the RFC language codes +// passed +// +// Notes: +// ISO tags are 3 characters in size +// RFC tags are 42(max) characters plus a ';' that ends each tag +//---------------------------------------------------------------------------- +// +CHAR8* RfcListToIsoList(IN CHAR8 *RfcList, IN UINTN RfcListSize, OUT UINTN *IsoListSize){ + UINTN Size; + CHAR8 *RfcPtr, *RfcEndPtr; + CHAR8 *IsoPtr; + CHAR8 *IsoList; + + if (RfcList==NULL || *RfcList==0) return NULL; + //calculate number of languages in the RfcList + for(Size=3, RfcPtr=RfcList; *RfcPtr!=0; RfcPtr++){ + if (*RfcPtr==';') Size+=3; + } + IsoList = Malloc(Size); + IsoPtr = IsoList; + RfcEndPtr = RfcList; + while(RfcEndPtr < RfcList+RfcListSize){ + CHAR8 *IsoLang; + CHAR8 OriginalChar; + RfcPtr = RfcEndPtr; + while(*RfcEndPtr!=';'&&*RfcEndPtr!=0) RfcEndPtr++; + OriginalChar = *RfcEndPtr; + *RfcEndPtr = 0; + IsoLang=RfcToIso(RfcPtr,NULL); + if (IsoLang!=NULL){ + MemCpy(IsoPtr, IsoLang, 3); + IsoPtr += 3; + } + *RfcEndPtr = OriginalChar; + RfcEndPtr++; + } + if (IsoPtr==IsoList){ + pBS->FreePool(IsoList); + if (IsoListSize) *IsoListSize=0; + return NULL; + } + if (IsoListSize) *IsoListSize=IsoPtr-IsoList; + return IsoList; +} + +// +//---------------------------------------------------------------------------- +// Procedure: GetFirstIsoLang +// +// Description: +// This function returns first language from passed ISO list +// +// Input: +// IN CHAR8 *IsoList - string that represents list of one or more ISO languages +// OUT UINTN *LangSize - pointer to store size of output buffer +// +// Output: +// CHAR8 * - A string that contains first language +// +//---------------------------------------------------------------------------- +// +CHAR8* GetFirstIsoLang(CHAR8* IsoList, UINTN *LangSize){ + if (LangSize) *LangSize=3; + return IsoList; +} + +// +//---------------------------------------------------------------------------- +// Procedure: GetFirstRfcLang +// +// Description: +// This function returns first language from passed RFC list +// +// Input: +// IN CHAR8 *RfcList - string that represents list of one or more RFC languages +// OUT UINTN *LangSize - pointer to store size of output buffer +// +// Output: +// CHAR8 * - A string that contains first language +// +//---------------------------------------------------------------------------- +// +CHAR8* GetFirstRfcLang(CHAR8* RfcList, UINTN *LangSize){ + CHAR8 *RfcPtr; + + for(RfcPtr=RfcList; *RfcPtr!=0 && *RfcPtr!=';'; RfcPtr++); + *RfcPtr=0; + if (LangSize) *LangSize=RfcPtr-RfcList+1; + return RfcList; +} + +// +//---------------------------------------------------------------------------- +// Procedure: GetLangVariable +// +// Description: +// This function returns language variable stored in NVRAM +// +// Input: +// IN CHAR16 *VariableName - Human-readable name of language variable +// EFI_GUID *VariableGuid - pointer to variable GUID +// UINTN *VariableSize - pointer to store output buffer size +// +// Output: +// CHAR8 * - A string that contains list of languages supported by platform +// +//---------------------------------------------------------------------------- +// +CHAR8* GetLangVariable( + CHAR16 *VariableName, EFI_GUID *VariableGuid, UINTN *VariableSize +){ + UINTN Size = 0; + CHAR8 *Buffer = NULL; + EFI_STATUS Status; + + Status = GetEfiVariable(VariableName, VariableGuid, NULL, &Size, &Buffer); + if (EFI_ERROR(Status)) Buffer=NULL; + else if (VariableSize!=NULL) *VariableSize=Size; + return Buffer; +} + +// +//---------------------------------------------------------------------------- +// Procedure: SetLangCodes +// +// Description: +// This function stores "PlatformLangCodes" variable +// +// Input: +// IN CHAR16 *VariableName - Human-readable name of language variable +// CHAR8* LangBuffer - pointer to list of language codes to store +// UINTN LangBufferSize - size of the passed buffer +// +// Output: +// None +// +//---------------------------------------------------------------------------- +// +VOID SetLangCodes(CHAR16 *VariableName, CHAR8* LangBuffer, UINTN LangBufferSize){ + if (LangBuffer==NULL) return; + pRS->SetVariable( + VariableName, &guidEfiVar, + EFI_VARIABLE_BOOTSERVICE_ACCESS | + EFI_VARIABLE_RUNTIME_ACCESS, + LangBufferSize, LangBuffer + ); +} + +// +//---------------------------------------------------------------------------- +// Procedure: SetLang +// +// Description: +// This function stores "PlatformLang" variable +// +// Input: +// IN CHAR16 *VariableName - Human-readable name of language variable +// CHAR8* LangBuffer - pointer to alanguage code to store +// UINTN LangBufferSize - size of the passed buffer +// +// Output: +// None +// +//---------------------------------------------------------------------------- +// +VOID SetLang(CHAR16 *VariableName, CHAR8* LangBuffer, UINTN LangBufferSize){ + if (LangBuffer==NULL) return; + pRS->SetVariable( + VariableName, &guidEfiVar, + EFI_VARIABLE_NON_VOLATILE | + EFI_VARIABLE_BOOTSERVICE_ACCESS | + EFI_VARIABLE_RUNTIME_ACCESS, + LangBufferSize, LangBuffer + ); +} + +// +//---------------------------------------------------------------------------- +// Procedure: SynchornizeLanguageVariables +// +// Description: +// This function makes sure that all the Language variable are set to the +// same value. +// +// Input: +// None +// +// Output: +// None +// +// Notes: +// Uses the following NVRAM variables +// LangCodes, PlatformLangCodes, Lang, PlatformLang, LastLang +//---------------------------------------------------------------------------- +// +VOID SynchornizeLanguageVariables(){ + CHAR8 *NativeLangBuffer; + CHAR8 *CompatLangBuffer; + CHAR8 *NativeLangCodesBuffer; + CHAR8 *CompatLangCodesBuffer; + UINTN NativeLangSize; + UINTN CompatLangSize; + UINTN NativeLangCodesSize; + UINTN CompatLangCodesSize; + BOOLEAN FreeNativeLangBuffer; + + //Set LanCodes variables + NativeLangCodesBuffer = GetLangVariable(LastLangCodes, &guidSetup, &NativeLangCodesSize); + SetLangCodes(NativeLangCodes, NativeLangCodesBuffer, NativeLangCodesSize); + CompatLangCodesBuffer = LangNativeListToCompatList( + NativeLangCodesBuffer, NativeLangCodesSize, &CompatLangCodesSize + ); + SetLangCodes(CompatLangCodes, CompatLangCodesBuffer, CompatLangCodesSize); + pBS->FreePool(CompatLangCodesBuffer); + FreeNativeLangBuffer = FALSE; + + //Set Lang variables + NativeLangBuffer = GetLangVariable(NativeLang, &guidEfiVar, &NativeLangSize); + CompatLangBuffer = GetLangVariable(CompatLang, &guidEfiVar, &CompatLangSize); + if (!NativeLangBuffer && CompatLangBuffer){ + //Derive NativeLang value from the CompatLang + NativeLangBuffer = LangToNative(CompatLangBuffer, &NativeLangSize); + SetLang(NativeLang, NativeLangBuffer, NativeLangSize); + pBS->FreePool(CompatLangBuffer); + }else if (NativeLangBuffer && !CompatLangBuffer) { + //Derive CompatLang value from the NativeLang + CompatLangBuffer = LangToCompat(NativeLangBuffer,&CompatLangSize); + SetLang(CompatLang,CompatLangBuffer,CompatLangSize); + FreeNativeLangBuffer = TRUE; + }else if (!NativeLangBuffer && !CompatLangBuffer) { + //Set NativeLang to the first language from the NativeLangCodes list + NativeLangBuffer = GetFirstLang(NativeLangCodesBuffer, &NativeLangSize); + SetLang(NativeLang, NativeLangBuffer, NativeLangSize); + //Derive CompatLang value from the NativeLang + CompatLangBuffer = LangToCompat(NativeLangBuffer,&CompatLangSize); + SetLang(CompatLang,CompatLangBuffer,CompatLangSize); + }else{ //NativeLang && CompatLang + CHAR8 *CompatLangInNativeFormat = LangToNative(CompatLangBuffer,NULL); + if (!LanguageCodesEqual(CompatLangInNativeFormat,NativeLangBuffer)){ + CHAR8 *LastLangBuffer=GetLangVariable(LastLang, &guidSetup, NULL); + if (LastLangBuffer && LanguageCodesEqual(LastLangBuffer,NativeLangBuffer)){ + pBS->FreePool(NativeLangBuffer); + //Derive NativeLang value from the CompatLang + NativeLangBuffer = LangToNative(CompatLangBuffer, &NativeLangSize); + SetLang(NativeLang, NativeLangBuffer, NativeLangSize); + }else{ + pBS->FreePool(CompatLangBuffer); + //Derive CompatLang value from the NativeLang + CompatLangBuffer = LangToCompat(NativeLangBuffer,&CompatLangSize); + SetLang(CompatLang,CompatLangBuffer,CompatLangSize); + FreeNativeLangBuffer = TRUE; + } + pBS->FreePool(LastLangBuffer); + } + } + pRS->SetVariable( + LastLang, &guidSetup, + EFI_VARIABLE_NON_VOLATILE | + EFI_VARIABLE_BOOTSERVICE_ACCESS, + NativeLangSize, NativeLangBuffer + ); + if (FreeNativeLangBuffer) pBS->FreePool(NativeLangBuffer); + pBS->FreePool(NativeLangCodesBuffer); +} + +// +//---------------------------------------------------------------------------- +// Procedure: IsVarisbleExist +// +// Description: +// Helper routine that checks if a given variable exists +// +// Input: +// IN CHAR16 *VariableName - Name of the variable to check on +// IN EFI_GUID *VendorGuid - GUID of the variable to check on +// +// Output: +// TRUE - if variable exsits +// FALSE - if variable does not exist +// +//---------------------------------------------------------------------------- +// +BOOLEAN IsVariableExist(IN CHAR16 *VariableName, IN EFI_GUID *VendorGuid){ + UINTN Size=0; + return + pRS->GetVariable(VariableName, VendorGuid, NULL, &Size, NULL) + == EFI_BUFFER_TOO_SMALL; +} + +// +//---------------------------------------------------------------------------- +// Procedure: SetupEntry +// +// Description: +// This function is the entry point for the Setup driver. It registers the +// the Setup callback functions and then it checks if the +// "Setup" and "Lang" variables are defined. If not it is a first boot +// (first flash or first boot after BIOS upgrade) and these variables will +// need to be defined. +// If "Setup" and "Lang" variables are defined, then make sure the language +// variables all agree and then return +// +// Input: +// IN EFI_HANDLE ImageHandle - Image handle +// IN EFI_SYSTEM_TABLE *SystemTable - pointer to the UEFI System Table +// +// Output: +// EFI_SUCCESS +// +// Notes: +// +//---------------------------------------------------------------------------- +// +EFI_STATUS SetupEntry( + IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable +) +{ + static EFI_EVENT SetupEnterEvent; + static EFI_GUID guidSetupEnter = AMITSE_SETUP_ENTER_GUID; +#if FORCE_USER_TO_SETUP_ON_FIRST_BOOT + static UINT32 BootFlow = BOOT_FLOW_CONDITION_FIRST_BOOT; + static EFI_GUID guidBootFlow = BOOT_FLOW_VARIABLE_GUID; +#endif + + EFI_HANDLE Handle=NULL; + + ThisImageHandle = ImageHandle; + InitAmiLib(ImageHandle,SystemTable); + InitAmiSetupProtocol(); + pBS->SetMem(Setup, sizeof(Setup), 0); + + if (!IsVariableExist(LastLangCodes, &guidSetup)) + { //If LastLangCodes Variable is not found, + //this is first boot after FW upgrade. + //We have to submit resources to HII to get Setup defaults + //and list of supported languages. + //After that we have to: + // 1. If Setup variable is missing, + // initialize it with Defaults + // 2. If Lang is missing, initialize + // Lang variable. + // 3. Force user to go to Setup + // ( if FORCE_USER_TO_SETUP_ON_FIRST_BOOT SDL token is on). + SetupCallback(NULL, NULL); //submit resources to HII and get defaults + //Setup global variable is initialized during SetupCallback +#if EFI_SPECIFICATION_VERSION>0x20000 +// TODO: Defaults initialization +#else + if (!IsVariableExist(L"Setup", &guidSetup)) + pRS->SetVariable( + L"Setup", &guidSetup, + EFI_VARIABLE_NON_VOLATILE + | EFI_VARIABLE_BOOTSERVICE_ACCESS + | EFI_VARIABLE_RUNTIME_ACCESS, + sizeof(Setup), &Setup + ); +#endif +#if FORCE_USER_TO_SETUP_ON_FIRST_BOOT + if (!IsVariableExist(L"BootFlow", &guidBootFlow)){ + return pRS->SetVariable( + L"BootFlow", &guidBootFlow, + EFI_VARIABLE_BOOTSERVICE_ACCESS, + sizeof(BootFlow), &BootFlow); + } +#endif + } + else + { //otherwise + // Register setup callbacks to submit resources to HII + // only if/when setup is launched +#if ALWAYS_PUBLISH_HII_RESOURCES + SetupCallback(NULL, NULL); +#else + VOID *pSetupRegistration; + RegisterProtocolCallback( + &guidSetupEnter, SetupCallback, + NULL,&SetupEnterEvent, &pSetupRegistration + ); +#endif + } + SynchornizeLanguageVariables(); + return EFI_SUCCESS; +} + +// +//---------------------------------------------------------------------------- +// Name: SETUP_ITEM_CALLBACK +// +// Fields: Type Name Description +// UINT16 Class - Primary identification value of an Hii Formset +// UINT16 SubClass - Secondary identification value of an Hii Formset +// UINT16 Key - A unique value that identifies a specific item on a setup form +// SETUP_ITEM_CALLBACK_HANDLER *UpdateItem - function used to update an item +// defined by the Class, SubClass and Key parameters +// +// Description: +// This Data Structure is used by the setup infrastructure to define +// callback functions that should be used for interacting with setup forms +// or individual questions. +// +// Notes: +// +//---------------------------------------------------------------------------- +// + + +// Brings the definitions of the SDL token defined list of callbacks into this +// file as a list of functions that can be called +#define ITEM_CALLBACK(Class,Subclass,Key,Callback) Callback +extern SETUP_ITEM_CALLBACK_HANDLER SETUP_ITEM_CALLBACK_LIST EndOfList; +#undef ITEM_CALLBACK + +// This creates an array of callbacks to be used +#define ITEM_CALLBACK(Class,Subclass,Key,Callback) {Class,Subclass,Key,&Callback} +SETUP_ITEM_CALLBACK SetupItemCallback[] = { SETUP_ITEM_CALLBACK_LIST {0,0,0,NULL} }; + +CALLBACK_PARAMETERS *CallbackParametersPtr = NULL; +CALLBACK_PARAMETERS* GetCallbackParameters(){ + return CallbackParametersPtr; +} + +static AMI_SETUP_PROTOCOL *AmiSetupProtocol = NULL; + +// +//---------------------------------------------------------------------------- +// Procedure: Callback +// +// Description: +// This function is used to identify the function to call when an interactive +// item has been triggered in the setup browser based on the information in +// the Callback protocol and the SetupCallBack Array +// +// Input: +// IN EFI_FORM_CALLBACK_PROTOCOL *This - Pointer to the instance of the callback +// protocol +// IN UINT16 KeyValue - Unique value that defines the type of data to expect in +// the Data parameter +// IN EFI_IFR_DATA_ARRAY *Data - Data defined by KeyValue Parameter +// OUT EFI_HII_CALLBACK_PACKET **Packet - Data passed from the Callback back to +// the setup Browser +// +// Output: +// EFI_SUCCESS +// +//---------------------------------------------------------------------------- +// +#if EFI_SPECIFICATION_VERSION>0x20000 +EFI_STATUS Callback( + IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This, + IN EFI_BROWSER_ACTION Action, + IN EFI_QUESTION_ID KeyValue, + IN UINT8 Type, + IN EFI_IFR_TYPE_VALUE *Value, + OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest +) +#else +EFI_STATUS Callback( + IN EFI_FORM_CALLBACK_PROTOCOL *This, + IN UINT16 KeyValue, + IN EFI_IFR_DATA_ARRAY *Data, + OUT EFI_HII_CALLBACK_PACKET **Packet +) +#endif +{ + UINTN i; + SETUP_CALLBACK *pCallback = (SETUP_CALLBACK*)This; + CALLBACK_PARAMETERS CallbackParameters; + EFI_STATUS Status; + SETUP_ITEM_CALLBACK *SetupItemCallbacks = NULL; + UINTN FixedSize = sizeof(SetupItemCallback); + UINTN VarSize = 0; + UINT8 *CopyPointer; + BOOLEAN AllocatedBuffer = FALSE; + +#if EFI_SPECIFICATION_VERSION>0x20000 + CallbackParameters.This = (VOID*)This; + CallbackParameters.Action = Action; + CallbackParameters.KeyValue = KeyValue; + CallbackParameters.Type = Type; + CallbackParameters.Value = Value; + CallbackParameters.ActionRequest = ActionRequest; + if (ActionRequest) *ActionRequest=EFI_BROWSER_ACTION_REQUEST_NONE; + Status = EFI_UNSUPPORTED; +#else + CallbackParameters.This = This; + CallbackParameters.KeyValue = KeyValue; + CallbackParameters.Data = Data; + CallbackParameters.Packet = Packet; + Status = EFI_SUCCESS; +#endif + + CallbackParametersPtr = &CallbackParameters; + + if(AmiSetupProtocol == NULL) { + Status = pBS->LocateProtocol(&AmiSetupProtocolGuid, NULL, &AmiSetupProtocol); + } + +//first get callbacks, registered at runtime + Status = AmiSetupProtocol->GetCallbacks(&VarSize, SetupItemCallbacks); + if(Status == EFI_NOT_FOUND) { //no runtime callbacks registered + SetupItemCallbacks = SetupItemCallback; + } else if(Status == EFI_BUFFER_TOO_SMALL) { + Status = pBS->AllocatePool(EfiBootServicesData, VarSize + FixedSize, &SetupItemCallbacks); + if(EFI_ERROR(Status)) + return Status; + AllocatedBuffer = TRUE; + Status = AmiSetupProtocol->GetCallbacks(&VarSize, SetupItemCallbacks); + //now add callbacks registered at build time via eLink + CopyPointer = (UINT8 *)SetupItemCallbacks; + CopyPointer += VarSize; + MemCpy(CopyPointer, SetupItemCallback, FixedSize); + } + + for(i=0; iClass && SetupCallBack[i].SubClass == pCallback->SubClass) + { + SETUP_ITEM_CALLBACK *pItemCallback = SetupItemCallbacks; + while(pItemCallback->UpdateItem) + { + if ( pItemCallback->Class == pCallback->Class + && pItemCallback->SubClass == pCallback->SubClass + && pItemCallback->Key == KeyValue + ){ + Status = pItemCallback->UpdateItem( + SetupCallBack[i].HiiHandle, + pItemCallback->Class, pItemCallback->SubClass, + KeyValue + ); +#if EFI_SPECIFICATION_VERSION>0x20000 + if (Status != EFI_UNSUPPORTED) break; +#endif + } + pItemCallback++; + } + } + CallbackParametersPtr = NULL; + if(AllocatedBuffer) + pBS->FreePool(SetupItemCallbacks); + return Status; +} +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2010, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** -- cgit v1.2.3