//************************************************************************* //************************************************************************* //** ** //** (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/AMITSE2_0/AMITSE/Uefi2.1/Parse.c 68 7/12/14 12:23p Arunsb $ // // $Revision: 68 $ // // $Date: 7/12/14 12:23p $ //************************************************************************* // Revision History // ---------------- // $Log: /Alaska/SOURCE/Modules/AMITSE2_0/AMITSE/Uefi2.1/Parse.c $ // // 68 7/12/14 12:23p Arunsb // [TAG] EIP174938 // [Category] Bug Fix // [Severity:] Normal // [Symptom:] Arrow mark shown when driver health page published // [Root Cause] Driver health formset considered as dynamic page so arrow // shown // [Solution] For driverhealth formset DynamicPageCount variable not // incremented. Returned EFI_ABORTED in parseform for driverhealth formset // so DynamicPageCount not incremented so arrow will not be shown. // [Files] Parse.c and uefi21wapper.c // // 67 5/02/14 5:48a Arunsb // [TAG] EIP156258 // [Category] Improvement // [Description] Providing ELINK option to suppress the handle // comparison on dynamic parsing // [Files] AMITSE.mak, AMITSE.sdl, commonoem.c, commonoem.h and Parse.c // // 66 5/02/14 4:42a Premkumara // [TAG] EIP95647 // [Category] Improvement // [Description] Dynamic Forms need to hide. // [Files] AMITSE.mak, AMITSE.sdl, CommonOem.c, Parse.c // // 65 5/01/14 10:29p Arunsb // EIP148837 change reverted, this is specially for Aptio5 customization // // 64 5/01/14 6:40p Premkumara // Resolved build error // // 63 5/01/14 4:42p Premkumara // [TAG] EIP151552 // [Category] Bug Fix // [Severity] Minor // [Symptom] IScsi Configuration option throws exception on pressing it // after 'Esc' is done to move back to previous page. // [RootCause] When "Save and Exit" in iScsi page is selected to create // new controls, while parsing PageInfo->PageParentID is not handled // properly. So while initializing menu title menu menu->CurrEntry is not // setting properly because of ParentPageID. // [Solution] While parsing PageInfo->PageParentID is not handled // properly. So while initializing menu title menu menu->CurrEntry is not // setting properly so that menu will be initialize and draw proper data. // [Files] Parse.c // // 62 5/01/14 4:09p Premkumara // [TAG] EIP148837 // [Category] Bug Fix // [Severity] Minor // [Symptom] Checkbox Control control is not working in dynamic page. // [RootCause] TSE is treating both the OneOf control and CheckBox // Control as CONTROL_TYPE_POPUPSEL // During dynamic parsing TSE is changing the Control type to // CONTROL_TYPE_POPUPSEL if it is CheckBox. // That's Why in ESA ComboBox is coming instead of CheckBox. // [Solution] For Dynamic Parsing after creating the Control Info i am // calling GetCheckBoxStyle() to get the Type as // CONTROL_TYPE_CHECKBOX for CheckBox Control. // [Files] Parse.c // // 61 12/04/13 2:56a Premkumara // [TAG] EIP139099 // [Category] New Feature // [Description] Supress formset other than // EFI_HII_PLATFORM_SETUP_FORMSET_GUID and // EFI_HII_DRIVER_HEALTH_FORMSET_GUID through elink based on token // [Files] AMITSE.sdl, AMITSE.mak, CommonOem.c, Hii.c, Parse.c, // TseUefiHii.h // // 60 6/10/13 12:21p Arunsb // EIP122907 EFI_IFR_TYPE_OTHER support provided. // // 59 5/22/13 11:11a Arunsb // Fixed these issues, // -If control has submit/inconsistent and its form has condition over it // then it will hang, // - Read write opcode hang // // 58 5/22/13 10:19a Premkumara // [TAG] EIP120418 // [Category] Improvement // [Issue Faced] When any suppressif, grayoutif, disableif over // the form then HPKTool crashes // [Root Cause] The end of suppressif, grayoutif, disableif // over the form were not handle properly // [Solution] The suppressif,grayoutif,disable are pushed // and end of suppressif, grayoutif, disableif over the form are popupout // properly at the end of parsing form // [Files] Parse.c // // 57 5/20/13 3:36a Premkumara // [TAG] EIP124286 // [Category] Bug Fix // [Severity] Minor // [Symptom] Optimal Defaults are not loading on pressing ResetButton // [RootCause] While filling defaults for DefaultOp2 optimal defaults // are skipped in __UpdateDefaults() fn // [Solution] If default ID EFI_IFR_DEFAULT_OP is found then fill // default link for all types of defaults // [Files] Parse.c // // 56 4/17/13 2:29p Arunsb // [TAG] EIP109812, 107774 // [Category] Improvement // [Description] Provide support for EFI_IFR_TYPE_REF and EFI_IFR_REF5 // [Files] Hii.c, HiiCallback.c, Parse.c and TseUefiHii.h // // 55 4/16/13 9:58a Arunsb // Missed HII structures added in TSE itself. So Hii structure names // changed. // // 54 4/02/13 8:21a Arunsb // [TAG] EIP113919, EIP114842 // [Category] Improvement // [Description] Provide support for EFI_IFR_WRITE, EFI_IFR_READ, // EFI_IFR_GET, EFI_IFR_SET and EFI_IFR_MAP_OP. // [Files] Setupdata.h, ctrlcond.c, expression.c, hii.c and parse.c // // 53 3/29/13 8:19a Arunsb // [TAG] EIP111061 // [Category] Improvement // [Description] Provide support for efivarstore opcode // [Files] Parse.c and tseuefihii.h // // 52 3/25/13 8:05a Premkumara // [TAG] EIP105468 // [Category] New Feature // [Description] Support for EFI_IFR_REFRESH_ID opcode for Offline // Parsing // [Files] Parse.c, Hii.c, Setupdata.h // // 51 3/20/13 10:42a Blaines // [TAG] - EIP 116513 // [Category]- Defect // [Symptom]- System hangs while navigating SAS Card UEFI HII Page, when // TSE_MULTILINE_CONTROLS is enabled. // // [Root cause] // The Hii page contained EFI_IFR_ACTION controls with a refresh value // greater than zero. When DEBUG_MODE is enabled, // The increased page draw completion time caused the Action timer to // expire. The constant page refresh prevented the call // to function ActionReadKey from the function ActionGetAction. // // [Solution]- Set the refresh value for EFI_IFR_ACTION controls only if // AMI CALLBACK value is used. // // [Files] // - Parse.c // // 50 3/20/13 9:29a Premkumara // [TAG] EIP116566 // [Category] Bug Fix // [Severity] Important // [Symptom] Fixed Boot Order Issue // [RootCause] Some controls are using checkbox(from runtime pages) // value to suppress some controls in SuperIO configuration page. // Dynamic parsing is modifying Checkbox controls optimal and failsafe // defaults by setting size=1 irrespective of presence of defaults. // [Solution] Setting size =0/1 based on presence of fail safe/Optimal // defaults for CheckBox controls. // [Files] Parse.c // // // 48 3/15/13 2:15a Premkumara // [TAG] EIP85745 & 109814 // [Category] Improvement // [Description] Support for Modal Form Support as per UEFI 2.3.1 // [Files] Parse.c, Page.c, Menu.c, Hotclick.c // // 47 12/21/12 8:34p Blaines // [TAG] EIP 108987 // [Category] Defect // [Symptom] SAS controller card HII menus hang when selecting and HII // pack update occurs. // [RootCause] The Setup maintains a page data cache when hii packs are // created, and will normally try to reuse the page data when hii packs // are removed/updated. If the existing page data cannot be reused, the // function _InvalidateExistingPage is called, but the // NewPageInfo->PageParentID is updated with the // OldPageInfo->PageParentID. // This resulted in circular page reference, causing the function // MenuInitialize (menu.c) to enter an infinite loop. // // [Solution] In the function _InvalidateExistingPage, remove the code // that changes NewPageInfo->PageParentID with the // OldPageInfo->PageParentID. // // [Files Changed] // - Parse.c // // // 46 10/18/12 6:04a Arunsb // Updated for 2.16.1235 QA submission // // 16 10/10/12 12:41p Arunsb // Synched the source for v2.16.1232, backup with Aptio // // 44 9/25/12 8:31a Rajashakerg // [TAG] EIP94424 // [Category] Improvement // [Description] Some form can't normal display when add Hii item will // in runtime during // [Files] AMITSE.sdl, AMITSE.mak, Parse.c // // 43 9/18/12 2:15a Rajashakerg // [TAG] EIP88658 // [Category] Bug Fix // [Severity] Normal // [Symptom] Minisetup crashes after controller reconnection during Hii // callback // [RootCause] Minisetup crashes after controller reconnection during // callback. since we have new packs and new handles. // [Solution] Additional checks for invalid ptrs were added // [Files] Hii.c, Parse.c, Uefi21Wapper.c // // 42 2/02/12 3:12a Premkumara // Updated with CheckBox scope issue. // // 41 2/02/12 3:03a Premkumara // [TAG] EIP75066 // [Category] Improvement // [Description] Support loading defaults for Ordelist controls // [Files] Ordlistbox.c, Uefi21Wapper.c, CtrlCond.c, HiiCallback.c, // Parse.c, Uefi20Wapper.c, TseUefihiil.h // // 40 1/20/12 1:59a Arunsb // [TAG] EIP80424 // [Category] Bug Fix // [Severity] Normal // [Symptom] Circular reference is not updated after pack update which // leads to RSOD // [RootCause] Circular reference is not updated after pack update which // leads to RSOD // [Solution] Setting NewPageInfo->PageHandle before calling // _AdvAddPageToList() so that Circular reference is updated properly // [Files] Parse.c // // 39 1/17/12 5:39a Premkumara // [TAG] EIP80422 // [Category] Bug Fix // [Severity] Minor // [Symptom] Update Defaults for Checkbox controls doesn't support scope // [RootCause] The flaw in this is that this code will never get // executed as the scope of a Checkbox control is always 1 // [Solution] Comment the scope check if(CheckBoxOp->Header.Scope == 0) // in _UpdateDefaults() function to execute if scope is 0 // [Files] Parse.c // // 38 11/30/11 6:34a Premkumara // [TAG] EIP71351 // [Category] Bug Fix // [Severity] Important // [Symptom] Setup Crash when iSCSI is loaded // [RootCause] Aptio giving length as 0xe(matches size of // EFI_IFR_ONE_OF_OPTION) but in latest EDKII driver it is 0x1c. // [Solution] change the length as j += ((EFI_IFR_OP_HEADER*)(buff + i + // j))->Length; // [Files] Parse.c, Hii.c, Variable.c, Minisetupext.c, // // 37 11/14/11 2:43p Blaines // [TAG] - EIP 75481 // [Category]- Function Request // [Synopsis]- TSE debug print infrastructure. // [Description]- Add TSE debug print info for basic functions such as // Hiiparsing, HiiNotifications, HiiCallbacks. Variables, and Ifrforms // data. // [Files] // AMITSE.sdl, AmiTSEStr.uni, CommonHelper.c, commonoem.c, FakeTokens.c // Globals.c, Minisetup.cif, Minisetup.h, print.c, FormBrowser2.c, Hii.c, // HiiCallback.c, HiiNotificationHandler.c, Parse.c, TseUefiHii.h, // Uefi21Wrapper.c, setupdbg.h // // 36 11/14/11 4:27a Arunsb // [TAG] EIP72540 // [Category] Bug Fix // [Severity] Important // [Symptom] Advance page disappear on using 4.6.2_TSE_2_14_1219 // [RootCause] Offline pages also considered in dynamic parsing // [Solution] Offline pages are not considered in dynamic parsing // [Files] hii.c and parse.c // // 35 11/10/11 11:47a Premkumara // [TAG] EIP73396 // [Category] Bug Fix // [Severity] Normal // [Symptom] On Pressing ESC the token SETUP_GO_TO_EXIT_PAGE_ON_EXIT_KEY // key doesnt work in UEFI2.1 // [RootCause] In AddPageIdToList() function. // If PageIdSize = 0 then first pageInfo will not copy into PageIdInfoPtr // [Solution] In Parse.c, // - removed PageIdSize =0 in AddPageIdToList() function. If PageIdSize = // 0 then first pageInfo will not copy into PageIdInfoPtr // [Files] Parse.c // // 34 9/29/11 3:24p Madhans // File Checkin comments corrected. // // 33 8/26/11 6:12p Blaines // [TAG] EIP68354 // [Category] Bug Fix // [Severity] Normal // [Symptom] non-refresh date control is gets refreshed // [RootCause] Date controls that don't have IFR_REFRESH_OP are being // assumed to have it. The Flags are not checked for type // QF_DATE_STORAGE_TIME. // [Solution] The Flags are checked for type QF_DATE_STORAGE_TIME. // [Files] TseLite: Time.c, Date.c // Uefi21: Parese.c, Uefi21Wrapper.c // // 31 6/30/11 4:19a Arunsb // [TAG] EIP57661 // [Category] New Feature // [Description] Boot manager algorithm for interaction with Driver // Health protocol. // Dynamic parsing changed for driver health config. page // via sendform. // [Files] amitse.cif, amitse.sdl, faketokens.c, amitsestr.uni, // commonhelper.c, uefisetup.ini, tsedrvhealth.h, // amivfr.h, minisetupbin.mak, // hiistring21.c, hiistring20.c, tseadvanced.c, special.c, // special.h, boot.h, minisetup.h, // uefi20wapper.c, formbrowser2.c, hii.c, parse.c and // uefi21wapper.c. // // 30 6/28/11 2:40p Arunsb // Build error resolved // // 29 6/28/11 9:38a Arunsb // EIP 56405 . Review comment addressed // Comment: Uncomment the 2.1 EFI Varstore support part. // // 28 6/24/11 10:16a Premkumara // [TAG] EIP62310, EIP 59743, EIP 62308 // [Category] Improvement // [Description] Merge all SupportEFI_IFR_SUPPRESS_IF_OP, // EFI_IFR_GRAYOUT_IF_OP, // cases in one case // [Files] Parse.c // // 27 6/23/11 4:02p Rajashakerg // [TAG] EIP55762, 58925, 59971 // [Category] New Feature // [Description] Support REF2,REF3 and REF4 in AMITSE // Support direct form navigation path // Improper layout of controls in the root page when Dynamic pages are // added using the Legacy Setup Style // // [Files] setupdata.h, CommonHelper.c, AMITSE.sdl, Legacy\Legacy.c, // Legacy\style.h, Legacy\style.h, frame.c, minisetupext.c, // minisetupext.h, numeric.c, page.c Popupstring.c, Hii.c, // Uefi21Wrapper.c, Parse.c Hii.c // // 26 6/22/11 5:17p Arunsb // [TAG] EIP56405 // [Category] New Feature // [Description] Support for EFI_IFR_VARSTORE_NAME_VALUE opcode // [Files] Hii.c, parse.c and uefi21wapper.c // // 25 6/22/11 9:27a Premkumara // [TAG] EIP 62310, EIP 59743, EIP 62308 // [Description] SupportEFI_IFR_SUPPRESS_IF_OP, EFI_IFR_GRAYOUT_IF_OP, // EFI_IFR_DISABLE_IF_OP Over the Form or Formset // [Files] parse.c // // 24 6/08/11 4:52p Arunsb // [TAG] EIP61650 // [Category] Bug Fix // [Severity] Minor // [Symptom] Cannot edit time field when using new "time" format // [RootCause] Default refresh interval set to all the time variables // [Solution] Default refresh interval provided only for RTC time // variable // [Files] uefi2.1\Parse.c // // 23 6/01/11 4:11p Madhans // [TAG] EIP61588 // [Category] Bug Fix // [Severity] Important // [Symptom] Advanced -> ISCSI -> Add an attempt-> Mac Address -> Save // changes causes the system to hang. // [RootCause] Dynamic update for the goto control to same target page // was not updated correctly. // [Solution] Fixed to update the control destination page correctly. // [Files] parse.c // special.c // // 22 5/31/11 9:52a Premkumara // [TAG] EIP48930 // [Description] Boot override hangs with exception 0x0d // [Files] Parse.c, hii.c // // 21 4/29/11 4:46p Arunsb // For 2.13 public patch release IFR RefX feature is omitted // // 20 4/22/11 6:09p Arunsb // [TAG] EIP59002 // [Category] Bug Fix // [Severity] Normal // [RootCause] Refresh interval not set properly // [Solution] If control has callback then it is handled in // EFI_IFR_ACTION_OP // also. // [Files] Parse.c // // 19 4/20/11 5:37p Blaines // [TAG] - EIP 55762 // [Category]- Action Item // [Synopsis]- Add support for IFR RefX controls. // [Files] - setupdata.h, special.c, frame.c, Hii.c, Parse.c, // Uefi21Wrapper.c // // 18 3/28/11 11:03p Madhans // [TAG] EIP56414 // [Category] Improvement // [Description] TSE: Support for EFI_IFR_NO_SUBMIT_IF opcode // [Files] Callback.c, FakeToken.c, AMITSEstr.uni, Parse.c, CtrlCond.c, // CtrlCond.h, ctrlcond.h, ctrlcond.c // // 17 3/28/11 9:49p Premkumara // [TAG] EIP52562 // [Category] Improvement // [Description] Need to have the Fixed Limit in AMITSE module for // Controls, Pages and Variable etc. // [Files] TSEUefiHii.h, Hii.c, Parse.c, hii.c // // 16 3/28/11 5:34p Rajashakerg // [TAG] EIP56896 // [Category] Improvement // [Description] // TSE: Support for EFI_IFR_LOCKED opcode // [Files] Parse.c // // 15 3/18/11 2:46a Rajashakerg // [TAG] EIP56124 // [Category] New Feature // [Description] TSE: Support for EFI_IFR_DEFAULT opcode // [Files] Parse.c, TseUefiHii.h // // 14 3/09/11 7:26p Madhans // [TAG] EIPEIP48615 // [Category] Improvement // [Description] To support UEFI 2.1 RefreshOp. Based in Refersh Rate // Controls are refershed periodically. // [Files] minisetupext.h // SubMenu.h // SubMenu.c // Memo.c // Memo.h // numeric.c // numeric.h // time.c // Date.c // PopupSel.c // PopupSel.h // PopupString.c // PopupString.h // ordlistbox.c // minisetupext.c // UefiAction.c // hii.h // Uefi20wapper.c // hiicallback.c // Parse.c // tseuefihii.h // Uefi21wapper.c // // 13 2/10/11 12:32p Blaines // [TAG] - EIP 53146 // [Category]- New Feature // [Description] -Add the support to Move the Dynamic IFR Pages under // subpages. It should be customizable to move around. // // 12 12/28/10 12:31p Madhans // To update the Tag of EIp 46998. UEFI option ROM menus disappear in // Setup when certain options are selected. // No file changed but Comment updated right // // 11 12/06/10 5:48p Madhans // [TAG] - EIP 49488 // [Category]- Defect // [Severity]- Mordarate // [Symptom]- ISCSI Pages not working. // [Rootcause] Variable Entry that is added by offline parsing is left // untouched and it cause the issue when locating the varible based on // GUID and Variable Name. // [Solution]- Fixed when adding Variable to the list to check for NULL // Variable handle. // [Files] - Parse.c // // 10 12/02/10 2:39p Madhans // [TAG] - EIP 48169 // [Category]- Enhancement // [Severity]- Mordarate // [Symptom]- Code Cleanup and Compiler Warning need to resolved. // [Rootcause] Warnings reported when we build AMI higher Warning level. // [Solution]- 1. Fix the warnings and do the code cleanup. // 2. Introduce proper checks. // 3. change the popupSel.c to not change the Option/variable // cache to default or first option // when the variable cache is not matching with any of // option. // [Files] - commonoem.c bbs.c boot.c hiistring.c resource.c // popuppassword.c popupsel.c // expression.c hii.c parse.c // // 9 10/27/10 4:25p Madhans // [TAG] EIP46998 // [Category] Defect // [Symptom] Some user action on PCIx with UEFI Hii Pages causes Setup // screen pages and menu disappers. // [RootCause] UEFI 2.1 parsing code is not handling the Removepack and // New pack sequance properly. Normally UpdatePack // does the removepack and AddPack. // [Solution] UEFI 2.1 parsing code fixed to handle above case correctly. // [Files] hii.c HiiNotificationHandler.c Parse.c TseUefiHii.h // uefi21wapper.c // // 8 9/16/10 8:38p Madhans // Update for TSE 2.10. Refer Changelog.log for more details. // // 13 9/15/10 1:53p Madhans // To fix the Issues Parent page fixing with Dynamic update of Pages. // // 11 9/07/10 1:43p Blaines // Support loading defaults for Data&Time in UEFI 2.1 // // 10 8/12/10 1:11p Blaines // EIP-40946 : Fix root page processing to support Award Style setup. // // 9 8/10/10 7:14p Madhans // EIP 40555 : To avoid Compilation issues with Fareast Windows. // // 8 6/17/10 4:19p Madhans // To fix the circular Page referance // // 7 6/17/10 2:47p Madhans // Fix for parsing correctly. // in Dyncamic parsing Fix the parent pages. // // 6 6/14/10 7:14p Madhans // Dynamic parsing support // // 5 3/11/10 5:43p Madhans // Coding Standards Update // // 4 2/15/10 10:19p Madhans // to support EDK nt32 version // // 3 11/19/09 5:31p Presannar // Updated TSE include file name to not clash with CORE file // // 2 8/11/09 2:57p Presannar // Added fn _AdvAddPageToList, _ReplacePageWithNewPage and // _AdvAddControlToList to handle dynamic updation of IFR data // Renamed _GetDefaultValue as GetDefaultValue // Modified _GetQuestionToken to get prompt of Ordered List opcode // Modified AddControlToList and AddPageToList to do Advanced Parsing // Added fn _ReplacePageWithNewPage and _InvalidateExistingPage to help in // handling Adv Page parsing // // 1 7/24/09 6:54p Presannar // // 5 5/28/09 11:49a Presannar // Bug fixes and clean up // // 3 5/19/09 11:29a Presannar // Removed check for Handle, while searching for existing Variable Info. // This is a temporary fix. The issue needs to be analyzed further to // check Handle also. // // 2 5/13/09 10:43a Presannar // When EFI_IFR_DEFAULT_OP was encountered, its scope got ignored when // skipping the opcode. Special handling of EFI_IFR_DEFAULT_OP case was // removed to allow the default case to take care of it. // Added File Header // //************************************************************************* // // // Name: Parse.c // // Description: // // //************************************************************************* //--------------------------------------------------------------------------- #include "Minisetup.h" #include "TseUefiHii.h" #define PARSE_START_INDEX 1 //--------------------------------------------------------------------------- // //---------------------------------------------------------------------------- // Name: PageLink // // Description: // // Fields: Name Type Description //---------------------------------------------------------------------------- // FormID UINT16 // ParentPageID UINT16 // PageNum UINT16 //---------------------------------------------------------------------------- // typedef struct PAGELINK { UINT16 FormID; // number from hpk UINT16 ParentPageID; // number from the tool UINT16 PageNum; // number assigned by the tool }PageLink; // //---------------------------------------------------------------------------- // Name: FormSetLinks // // Description: // // Fields: Name Type Description //---------------------------------------------------------------------------- // PageCount UINT16 // PageLink[20] PageLink //---------------------------------------------------------------------------- // typedef struct FORMSETLINKS { UINT16 PageCount; PageLink PageLink[20]; }FormSetLinks; // //---------------------------------------------------------------------------- // Name: *PVAR_KEY_TABLE, VAR_KEY_TABLE // // Description: // // Fields: Name Type Description //---------------------------------------------------------------------------- // VarId UINT16 // Index PageLink // Handle EFI_HII_HANDLE // *Next struct _VAR_KEY_TABLE //---------------------------------------------------------------------------- // typedef struct _VAR_KEY_TABLE { UINT32 VarId; UINT16 Index; EFI_HII_HANDLE Handle; struct _VAR_KEY_TABLE *Next; }*PVAR_KEY_TABLE, VAR_KEY_TABLE; //---------------------------------------------------------------------------- // MACRO DEFINITIONS //---------------------------------------------------------------------------- #define START_EVAL_IF 0x8000 #define END_EVAL_IF 0x8001 #define DEFAULT_REFRESH_RATE 0x01 #define DEFAULT_DATETIME_REFRESH 0x05 #define CONTROL_TYPE_MASK 0x0FFF #define STANDARD_FORM_MAP_GUID { 0x3bd2f4ec, 0xe524, 0x46e4, 0xa9, 0xd8, 0x51, 0x1, 0x17, 0x42, 0x55, 0x62 } #ifndef TSE_FOR_APTIO_4_50 #define EFI_HII_PACKAGE_FORMS EFI_HII_PACKAGE_FORM #include "tianohii.h" #endif //---------------------------------------------------------------------------- // VARIABLE DECLARATIONS //---------------------------------------------------------------------------- static FormSetLinks *FSetLinks; VAR_KEY_TABLE VarKeyTable; BOOLEAN ResetCondVars = TRUE; BOOLEAN ResetVars = TRUE; BOOLEAN Inconsistant = FALSE; BOOLEAN NoSubmitIf = FALSE; // EIP: NO_SUBMIT_IF BOOLEAN IsRecursive = FALSE; UINT8 DefaultStoreCount = 0; UINT32 CtrlVar = 0; UINT32 gnewCtrlVar = 0; UINT32 PageOffset; UINT32 PageVar = 0; UINT32 gRefreshIdCount = 0; //No. of controls with Refresh Id set UINTN gDynamicPageCount=0; VOID *gConditionalOverFormPtr = NULL;//EIP-120418 BOOLEAN updateformcondvars = TRUE; BOOLEAN gConditionOverForm = FALSE; //BOOLEAN IsRefreshIdSet = FALSE; EFI_GUID RefreshEventGroupId; REFRESH_ID_INFO *gRefreshIdInfo = NULL; EFI_GUID StandardFormGuid = STANDARD_FORM_MAP_GUID; //--------------------------------------------------------------------------- // EXTERN VARIABLES //--------------------------------------------------------------------------- extern PAGE_ID_INFO *PageIdInfoPtr; extern PAGE_ID_LIST *PageIdListPtr; extern PAGE_INFO *FirstPage; extern PAGE_INFO *NewPageInfo; extern PAGE_INFO *PageInfoPtr; extern PAGE_LIST *PageListPtr; extern VARIABLE_LIST *VariableListPtr; extern VARIABLE_INFO *VariableInfoPtr; extern UINT32 AllocatedFirstPageSize, FirstPageOffset; extern UINT32 ControlListSize, ControlListOffset; extern UINT32 PageIdInfoSize, PageIdInfoOffset; extern UINT32 PageIdListSize, PageIdListOffset; extern UINT32 PageInfoSize, PageInfoOffset; extern UINT32 PageListSize, PageListOffset; extern UINT32 VariableListSize, VariableListOffset; extern UINT32 VariableInfoSize, VariableInfoOffset; extern UINTN TotalRootPages; extern SETUP_LINK *gSetupData ; extern VOID **gSfHandles; extern EFI_GUID *gGuidDump; //EIP64253 offline vfr pages hided extern UINTN gGuidDumpCount; //--------------------------------------------------------------------------- // EXTERN FUNCTIONS //--------------------------------------------------------------------------- extern BOOLEAN IsGroupDynamicPages(); extern BOOLEAN IsOrphanPagesAsRootPage(); extern EFI_STATUS DebugShowControlInfo(UINT32 formID, VOID *passedCtrlInfo) ; extern VOID DebugShowPageInfo(UINT32 formID, VOID *passedPageInfo) ; extern VOID ResetExpressionStack ( VOID ); extern EFI_STATUS PushExpression (IN EFI_HII_VALUE *Value); extern EFI_STATUS PopExpression (IN EFI_HII_VALUE *Value); extern INTN CompareHiiValue (IN EFI_HII_VALUE *Value1,IN EFI_HII_VALUE *Value2,IN EFI_HII_HANDLE HiiHandle OPTIONAL); extern EFI_STATUS _GetValueFromQuestionId(UINT16 QuestionId, UINT16 PageId, EFI_HII_VALUE **Value); extern EFI_STATUS VarGetValue( UINT32 variable, UINT32 offset, UINTN size, VOID *buffer ); extern VOID *gFirstPageRef; extern UINT32 GetUefiSpecVersion (VOID); extern BOOLEAN ShowClassGuidFormsets (TSE_EFI_IFR_FORM_SET *SetupFormSet );//EIP-139099 extern BOOLEAN HideDynamicFormsets (EFI_GUID *FormSetGuid );//EIP-95647 //--------------------------------------------------------------------------- // FUNCTION DECLARATIONS //--------------------------------------------------------------------------- EFI_STATUS _AddVariable(UINT8 *IFRData, EFI_HII_HANDLE Handle); EFI_STATUS _InitFormsetLinks(char *buff, UINTN InitFormNum); EFI_STATUS _AdvAddPageToList(PAGE_INFO *NewPageInfo, UINT32 PageSize); EFI_STATUS _ReplacePageWithNewPage(PAGE_INFO *OldPageInfo, PAGE_INFO *NewPageInfo, UINT32 PageSize); EFI_STATUS _InvalidateExistingPage(PAGE_INFO *OldPageInfo, PAGE_INFO *NewPageInfo); VOID RefreshGroupOnCallBack(EFI_EVENT Event, VOID *Context); UINT8 _IsVarGuidPresent(EFI_GUID *VarGuid, int *Index); UINT16 _GetPageIdIndex(EFI_GUID *FormGuid, UINT16 FormClass, UINT16 FormSubClass); UINT16 _GetPageParent(int PageNum); UINT32 _AddFormSetVariable(EFI_GUID *VarGuid); UINT32 _AdvAddControlToList(CONTROL_INFO *ControlInfo, UINT32 ControlSize); UINT32 _GetVarNumFromVarID(UINT32 ID, EFI_HII_HANDLE Handle, void *); UINTN _AddHpkControls(EFI_HII_HANDLE Handle, UINT8 *buff,UINTN Size, PAGE_INFO **NewPageInfo, UINT32 *AllocatedPageSize, UINT32 *PageOffset); UINTN _GetSubFormCount(UINT8 *buff); UINT16 _GetQuestionToken(UINT8 *ifrData) ; VOID _CleanVarKeyTable(); EFI_STATUS CreateEventforIFR (CONTROL_INFO *control_Info );//EIP-105468 // //---------------------------------------------------------------------------- // // Procedure: _AddFormSetVariable // // Description: // // Parameter: // // Return value: //---------------------------------------------------------------------------- // UINT32 _AddFormSetVariable(EFI_GUID * VarGuid) { VARIABLE_INFO Variable; UINT32 i; MemSet(&Variable, sizeof(Variable), 0); MemCopy((&Variable.VariableGuid),VarGuid,sizeof(EFI_GUID)); Variable.VariableAttributes = 0x7; // BT+RT+NV EfiStrCpy(Variable.VariableName,L"Setup"); i = VariableListPtr->VariableCount; AddVariableToList(&Variable); return i; } //---------------------------------------------------------------------------- // Procedure: _DisplayErrorMessage // // Description: Function to display Error message when TSE supported limit exceeds // //---------------------------------------------------------------------------- EFI_STATUS _DisplayErrorMessage(CHAR16 *Temp) { EFI_EVENT Event; EFI_STATUS status = EFI_SUCCESS;; status = PostManagerDisplayInfoBox(L" Unrecoverable Error",Temp,20,&Event); if(status) { gST->ConOut->OutputString(gST->ConOut,Temp); } return status; } //---------------------------------------------------------------------------- // Procedure: _AddVariable // // Description: //---------------------------------------------------------------------------- BOOLEAN VariableHandleSuppressed (EFI_GUID *VariableGuid, CHAR16 *VariableName); EFI_STATUS _AddVariable(UINT8 *IFRData, EFI_HII_HANDLE Handle) { EFI_GUID *guid=NULL; EFI_STATUS status = EFI_SUCCESS; VARIABLE_INFO *variable=NULL; VARIABLE_INFO newVariable; PVAR_KEY_TABLE pVarTable; EFI_IFR_OP_HEADER *opHeader = (EFI_IFR_OP_HEADER*)IFRData; EFI_IFR_VARSTORE *varstore=NULL; AMI_EFI_IFR_VARSTORE_EFI *efivarstore; EFI_IFR_VARSTORE_NAME_VALUE *nameValuevarstore; char *str2; CHAR16 *varNamePtr; UINT16 i; UINT16 varId = 0; UINT16 varName[40]; UINT16 varstoreSize = 0; UINT32 attributes = 0; UINT32 extAttributes = 0; UINTN varfound = 0; BOOLEAN bGreaterUEFIVersion = FALSE; SETUP_DEBUG_UEFI ( "\n[TSE] Entering _AddVariable()\n" ); switch(opHeader->OpCode) { case EFI_IFR_VARSTORE_OP: varstore = (EFI_IFR_VARSTORE*)IFRData; guid = &(varstore->Guid); varId = varstore->VarStoreId; varstoreSize = varstore->Size; attributes |= 0; extAttributes |= VARIABLE_ATTRIBUTE_VARSTORE; str2 = (char*)varstore->Name; //Convert to unicode string MemSet(varName, sizeof(varName), 0); i = 0; for(varNamePtr = varName; *str2; *varNamePtr = *str2, str2++, varNamePtr++) ; break; case EFI_IFR_VARSTORE_EFI_OP: efivarstore = (AMI_EFI_IFR_VARSTORE_EFI*)IFRData; guid = &(efivarstore->Guid); varId = efivarstore->VarStoreId; attributes |= efivarstore->Attributes; extAttributes |= VARIABLE_ATTRIBUTE_EFI_VARSTORE; if ((GetUefiSpecVersion()) > 0x2001E) //If UEFI spec version is greater than 2.3 then store the Name and size from the opcode { bGreaterUEFIVersion = TRUE; //set it to True for version great than 2.3 str2 = (char*)efivarstore->Name; //name of the opcode //Convert to unicode string MemSet(varName, sizeof(varName), 0); i = 0; for(varNamePtr = varName; *str2; *varNamePtr = *str2, str2++, varNamePtr++) ; varstoreSize = efivarstore->Size; //size of the varstore } break; case EFI_IFR_VARSTORE_NAME_VALUE_OP: nameValuevarstore = (EFI_IFR_VARSTORE_NAME_VALUE*)IFRData; guid = &(nameValuevarstore->Guid); varId = nameValuevarstore->VarStoreId; EfiStrCpy (varName, L""); attributes |= 0; extAttributes |= VARIABLE_ATTRIBUTE_NAMEVALUE; break; default: break; } // check that the variable is not already in the list for(i=0; i < VariableListPtr->VariableCount; i++) { variable = (VARIABLE_INFO*)((UINT8 *)VariableInfoPtr + VariableListPtr->VariableList[i]); if( EfiCompareGuid(guid, &(variable->VariableGuid)) )//Compare Guid { switch(opHeader->OpCode) { case EFI_IFR_VARSTORE_OP: if((EfiStrCmp(varName, variable->VariableName) ==0)) { if ((Handle == variable->VariableHandle) || VariableHandleSuppressed (guid, varName)) { varfound=1; break; } // Aptio SETUP Patch. refer EIP 39861 // In aptio If it Setup Variable all the forms refers same varstore. if((i==0) || UefiIsEfiVariable(i, variable)) { varfound=1; break; } if(variable->VariableHandle == NULL) { // if Variable Handle is zero, then it added from OFFline parsing and we need use this // Entry if the size also matchs. if(varstore->Size == variable->VariableSize) { variable->VariableHandle = Handle; varfound=1; break; } } } break; case EFI_IFR_VARSTORE_EFI_OP: if (bGreaterUEFIVersion) //If UEFI spec version is greater than 2.3, then use the name to find the variable { if((EfiStrCmp(varName, variable->VariableName) ==0)) { if ((Handle == variable->VariableHandle) || VariableHandleSuppressed (guid, varName)) { varfound=1; break; } // Aptio SETUP Patch. refer EIP 39861 // In aptio If it Setup Variable all the forms refers same varstore. if((i==0) || UefiIsEfiVariable(i, variable)) { varfound=1; break; } if(variable->VariableHandle == NULL) { // if Variable Handle is zero, then it added from OFFline parsing and we need use this // Entry if the size also matchs. if(efivarstore->Size == variable->VariableSize) { variable->VariableHandle = Handle; varfound=1; break; } } } } else { if((variable->ExtendedAttibutes & VARIABLE_ATTRIBUTE_EFI_VARSTORE) == VARIABLE_ATTRIBUTE_EFI_VARSTORE && variable->VariableAttributes == attributes) { varfound = 1; } } break; case EFI_IFR_VARSTORE_NAME_VALUE_OP: varfound = 1; break; } if(varfound) { break; } } } if(!varfound) { MemSet(&newVariable, sizeof(VARIABLE_INFO), 0); newVariable.VariableID = varId; MemCopy((&newVariable.VariableGuid),guid,sizeof(EFI_GUID)); newVariable.VariableAttributes = attributes; newVariable.ExtendedAttibutes = extAttributes; newVariable.VariableHandle = Handle; if(opHeader->OpCode == EFI_IFR_VARSTORE_OP) { EfiStrCpy(newVariable.VariableName, varName); newVariable.VariableSize = varstoreSize; } else if ((EFI_IFR_VARSTORE_EFI_OP == opHeader->OpCode) && (bGreaterUEFIVersion)) //Name is available in the opcode only if UEFI spec followed is { //greater than 2.3 EfiStrCpy(newVariable.VariableName, varName); newVariable.VariableSize = varstoreSize; } AddVariableToList(&newVariable); }else { variable->VariableID = varId; variable->VariableHandle = Handle; variable->ExtendedAttibutes = extAttributes; if(opHeader->OpCode == EFI_IFR_VARSTORE_OP) { variable->VariableSize = varstoreSize; } else if (EFI_IFR_VARSTORE_NAME_VALUE_OP == opHeader->OpCode) { EfiStrCpy (variable->VariableName, varName); } else if ((EFI_IFR_VARSTORE_EFI_OP == opHeader->OpCode) && (bGreaterUEFIVersion)) //Size is available in the opcode only if UEFI spec followed is { //greater than 2.3 variable->VariableSize = varstoreSize; } } pVarTable = &VarKeyTable; while(pVarTable->Next) pVarTable = pVarTable->Next; pVarTable->Next = EfiLibAllocateZeroPool(sizeof(VAR_KEY_TABLE)); if(pVarTable->Next == NULL) { status = EFI_OUT_OF_RESOURCES; goto DONE; } pVarTable = pVarTable->Next; pVarTable->VarId = varId; pVarTable->Handle = Handle; pVarTable->Index = i; DONE: SETUP_DEBUG_UEFI( "\n[TSE] Exiting _AddVariable(), status = 0x%x \n" , status ); return status; } // //---------------------------------------------------------------------------- // // Procedure: _CleanVarKeyTable // // Description: Clean VarKey Table // // Parameter: None // // Return value: None //---------------------------------------------------------------------------- // VOID _CleanVarKeyTable() { PVAR_KEY_TABLE pVarTable = VarKeyTable.Next; while(pVarTable) { VarKeyTable.Next = pVarTable->Next; MemFreePointer(&pVarTable); pVarTable = VarKeyTable.Next; } } // //---------------------------------------------------------------------------- // // Procedure: _GetControlKeyToken // // Description: Get ControlKey Token // // Parameter: None // // Return value: None //---------------------------------------------------------------------------- // UINT16 _GetControlKeyToken(UINT8 *IFRData) { EFI_IFR_OP_HEADER *opHeader = (EFI_IFR_OP_HEADER*)IFRData; EFI_IFR_QUESTION_HEADER *question; UINT16 questionKey = 0; switch(opHeader->OpCode) { case EFI_IFR_ONE_OF_OP: // 0x05 case EFI_IFR_CHECKBOX_OP: // 0x06 case EFI_IFR_NUMERIC_OP: // 0x07 case EFI_IFR_PASSWORD_OP: // 0x08 case EFI_IFR_ACTION_OP: // 0x0C case EFI_IFR_RESET_BUTTON_OP: // 0x0D case EFI_IFR_REF_OP: // 0x0F case EFI_IFR_DATE_OP: // 0x1A case EFI_IFR_TIME_OP: // 0x1B case EFI_IFR_STRING_OP: // 0x1C case EFI_IFR_ORDERED_LIST_OP: // 0x23 question = (EFI_IFR_QUESTION_HEADER*)((UINT8*)IFRData + sizeof(EFI_IFR_OP_HEADER)); questionKey = question->QuestionId; break; case EFI_IFR_RULE_OP: // 0x18 questionKey = ((EFI_IFR_RULE*)((UINT8*)IFRData))->RuleId; break; default: break; } return questionKey; } // //---------------------------------------------------------------------------- // // Procedure: _GetControlDevicePathId // // Description: Get Control DevicePathId // // Parameter: // // Return value: UINT16 //---------------------------------------------------------------------------- // UINT16 _GetControlDevicePathId(UINT8 *IFRData) { EFI_IFR_OP_HEADER *opHeader = (EFI_IFR_OP_HEADER*)IFRData; UINTN inScope = 0; UINTN i = 0; UINT16 devicePath = 0; BOOLEAN found = FALSE; if(opHeader->Scope) { do { switch(opHeader->OpCode) { case EFI_IFR_VARSTORE_DEVICE_OP: devicePath = ((EFI_IFR_VARSTORE_DEVICE*)((UINT8*)IFRData + i))->DevicePath; found = TRUE; break; case EFI_IFR_END_OP: inScope--; break; default: if(opHeader->Scope) { inScope++; } } i += opHeader->Length; opHeader = (EFI_IFR_OP_HEADER*)(IFRData + i); }while(inScope || found); } return devicePath; } // //---------------------------------------------------------------------------- // // Procedure: GetDefaultValue // // Description: Get Default Value // // Input: UINT8 Type // EFI_IFR_TYPE_VALUE *Value // UINT16 *Size - [IN/OUT] parameter - IN for the type // EFI_IFR_TYPE_BUFFER. For all other types, // as OUT parameter // VOID *DefValue // // Output: Void //---------------------------------------------------------------------------- // VOID GetDefaultValue(UINT8 Type, EFI_IFR_TYPE_VALUE *Value, UINT16 *Size, VOID *DefValue, UINT8 *TempData) { UINT8 *Data = TempData; switch(Type) { case EFI_IFR_TYPE_NUM_SIZE_8: *Size = (UINT16)sizeof(UINT8); *(UINT8*)DefValue = Value->u8; break; case EFI_IFR_TYPE_NUM_SIZE_16: case EFI_IFR_TYPE_STRING: *Size = (UINT16)sizeof(UINT16); *(UINT16*)DefValue = Value->u16; break; case EFI_IFR_TYPE_NUM_SIZE_32: *Size = (UINT16)sizeof(UINT32); *(UINT32*)DefValue = Value->u32; break; case EFI_IFR_TYPE_NUM_SIZE_64: *Size = (UINT16)sizeof(UINT64); *(UINT64*)DefValue = Value->u64; break; case EFI_IFR_TYPE_DATE: *Size = sizeof(EFI_HII_DATE); MemCopy(DefValue, &(Value->date), sizeof(EFI_HII_DATE)); break; case EFI_IFR_TYPE_TIME: *Size = sizeof(EFI_HII_TIME); MemCopy(DefValue, &(Value->time), sizeof(EFI_HII_TIME)); break; case EFI_IFR_TYPE_BUFFER: // Size will be received as parameter MemCopy(DefValue, Value, *Size); break; case EFI_IFR_TYPE_REF: //EIP109812, 107774 // Size will be received as parameter MemCopy (DefValue, Value, *Size); break; case EFI_IFR_TYPE_BOOLEAN: *Size = 1; MemCopy(DefValue, &(Value->b), *Size); break; case EFI_IFR_TYPE_OTHER: { UINTN ScopeCount = 0; EFI_IFR_OP_HEADER *OpHeader = (EFI_IFR_OP_HEADER *)Data; EFI_IFR_DEFAULT *DefaultOp = NULL; *Size = 0; if (OpHeader->Scope) { ScopeCount ++; OpHeader = (EFI_IFR_OP_HEADER *)((UINT8 *)OpHeader + OpHeader->Length); if (OpHeader->Scope) { ScopeCount ++; if (EFI_IFR_VALUE_OP == OpHeader->OpCode) { OpHeader = (EFI_IFR_OP_HEADER *)((UINT8 *)OpHeader + OpHeader->Length); switch (OpHeader->OpCode) { case EFI_IFR_UINT8_OP: *Size = (UINT16)sizeof (UINT8); *(UINT8 *)DefValue = *(UINT8 *)((UINT8 *)OpHeader + sizeof (EFI_IFR_OP_HEADER)); break; case EFI_IFR_UINT16_OP: *Size = (UINT16)sizeof (UINT16); *(UINT16 *)DefValue = *(UINT16 *)((UINT8 *)OpHeader + sizeof (EFI_IFR_OP_HEADER)); break; case EFI_IFR_UINT32_OP: *Size = (UINT16)sizeof (UINT32); *(UINT32 *)DefValue = *(UINT32 *)((UINT8 *)OpHeader + sizeof (EFI_IFR_OP_HEADER)); break; case EFI_IFR_UINT64_OP: *Size = (UINT16)sizeof (UINT64); *(UINT64 *)DefValue = *(UINT64 *)((UINT8 *)OpHeader + sizeof (EFI_IFR_OP_HEADER)); break; default: *Size = 0; break; } } } } while (ScopeCount) { OpHeader = (EFI_IFR_OP_HEADER *)((UINT8 *)OpHeader + OpHeader->Length); if (EFI_IFR_END_OP == OpHeader->OpCode) { ScopeCount --; } } } break; default: *Size = 0; *(UINT8*)DefValue = 0; break; } } // //---------------------------------------------------------------------------- // // Procedure: _GetHelpToken // // Description: Get Control Question Help Token // // Parameter: // // Return value: UINT16 //---------------------------------------------------------------------------- // UINT16 _GetHelpToken(UINT8 *ifrData) { EFI_IFR_OP_HEADER *headerPtr = (EFI_IFR_OP_HEADER*)ifrData; UINT16 token = 0; switch ( headerPtr->OpCode ) { case EFI_IFR_TEXT_OP: { EFI_IFR_TEXT *ptr = (EFI_IFR_TEXT*)headerPtr; token = ptr->Statement.Help; } break; case EFI_IFR_ORDERED_LIST_OP: { EFI_IFR_ORDERED_LIST *ptr = (EFI_IFR_ORDERED_LIST*)headerPtr; token = ptr->Question.Header.Help; } break; case EFI_IFR_ONE_OF_OP: { EFI_IFR_ONE_OF *ptr = (EFI_IFR_ONE_OF*)headerPtr; token = ptr->Question.Header.Help; } break; case EFI_IFR_CHECKBOX_OP: { EFI_IFR_CHECKBOX *ptr = (EFI_IFR_CHECKBOX*)headerPtr; token = ptr->Question.Header.Help; } break; case EFI_IFR_DATE_OP: case EFI_IFR_TIME_OP: case EFI_IFR_NUMERIC_OP: { EFI_IFR_NUMERIC *ptr = (EFI_IFR_NUMERIC*)headerPtr; token = ptr->Question.Header.Help; } break; case EFI_IFR_PASSWORD_OP: { EFI_IFR_PASSWORD *ptr = (EFI_IFR_PASSWORD*)headerPtr; token = ptr->Question.Header.Help; } break; case EFI_IFR_ACTION_OP: { EFI_IFR_ACTION *ptr = (EFI_IFR_ACTION*)headerPtr; token = ptr->Question.Header.Help; } break; case EFI_IFR_RESET_BUTTON_OP: { EFI_IFR_RESET_BUTTON *ptr = (EFI_IFR_RESET_BUTTON*)headerPtr; #ifdef TSE_FOR_APTIO_4_50 token = ptr->Statement.Help; #else token = ptr->Question.Header.Help; #endif } case EFI_IFR_REF_OP: { EFI_IFR_REF *ptr = (EFI_IFR_REF*)headerPtr; token = ptr->Question.Header.Help; } break; case EFI_IFR_STRING_OP: { EFI_IFR_STRING *ptr = (EFI_IFR_STRING*)headerPtr; token = ptr->Question.Header.Help; } break; default: break; } return token; } // //---------------------------------------------------------------------------- // // Procedure: _GetPageIdIndex // // Description: Get Page ID index // // Parameter: // // Return value: UINT16 //---------------------------------------------------------------------------- // UINT16 _GetPageIdIndex(EFI_GUID * FormGuid, UINT16 FormClass, UINT16 FormSubClass) { UINT16 i; PAGE_ID_INFO *pageId; if(PageIdListPtr == NULL) { PageIdListSize = 128; PageIdListPtr = (PAGE_ID_LIST *)EfiLibAllocateZeroPool(128); PageIdListOffset = sizeof(UINT32); // Points to first Offset of PageIdList } //search if this combination exists for(i = 0; i < PageIdListPtr->PageIdCount ; i++) { pageId = (PAGE_ID_INFO *) ((UINT8 *)PageIdInfoPtr + PageIdListPtr->PageIdList[i]); if( EfiCompareGuid(FormGuid,&(pageId->PageGuid)) )//Compare Guid { if(FormClass == pageId->PageClass)//Compare class { if(FormSubClass == pageId->PageSubClass)//Compare SubClass { break; //found entry } } } } if(i >= PageIdListPtr->PageIdCount) { PAGE_ID_INFO NewPageId; MemCopy(&(NewPageId.PageGuid),FormGuid,sizeof(EFI_GUID)); NewPageId.PageClass = FormClass; NewPageId.PageSubClass = FormSubClass; i = (UINT16)PageIdListPtr->PageIdCount; AddPageIdToList(&NewPageId); } return i; } // //---------------------------------------------------------------------------- // // Procedure: _GetPageNumFromFormID // // Description: Get Page Id from Form Id // // Parameter: // // Return value: UINT16 //---------------------------------------------------------------------------- // UINT16 _GetPageNumFromFormID(UINTN FormID) { UINTN i=0; do{ if(FSetLinks->PageLink[i].FormID == FormID) { return (FSetLinks->PageLink[i].PageNum); break; } }while(i++ < FSetLinks->PageCount); return 0; } // //---------------------------------------------------------------------------- // // Procedure: _GetPageParent // // Description: Get Parent Page PageID // // Parameter: // // Return value: UINT16 //---------------------------------------------------------------------------- // UINT16 _GetPageParent(int PageNum) { UINT16 i=0; do{ if(FSetLinks->PageLink[i].PageNum == PageNum ) { return (FSetLinks->PageLink[i].ParentPageID ); break; } }while( i++ < FSetLinks->PageCount ); return 0; } // //---------------------------------------------------------------------------- // // Procedure: _GetQuestionToken // // Description: Get Control Question Prompt // // Parameter: // // Return value: UINT16 //---------------------------------------------------------------------------- // UINT16 _GetQuestionToken(UINT8 *ifrData) { EFI_IFR_OP_HEADER *headerPtr = (EFI_IFR_OP_HEADER*)ifrData; UINT16 token = 0; switch ( headerPtr->OpCode ) { case EFI_IFR_TEXT_OP: { EFI_IFR_TEXT *ptr = (EFI_IFR_TEXT*)headerPtr; token = ptr->Statement.Prompt; } break; case EFI_IFR_ONE_OF_OP: { EFI_IFR_ONE_OF *ptr = (EFI_IFR_ONE_OF*)headerPtr; token = ptr->Question.Header.Prompt; } break; case EFI_IFR_CHECKBOX_OP: { EFI_IFR_CHECKBOX *ptr = (EFI_IFR_CHECKBOX*)headerPtr; token = ptr->Question.Header.Prompt; } break; case EFI_IFR_DATE_OP: case EFI_IFR_TIME_OP: case EFI_IFR_NUMERIC_OP: { EFI_IFR_NUMERIC *ptr = (EFI_IFR_NUMERIC*)headerPtr; token = ptr->Question.Header.Prompt; } break; case EFI_IFR_ORDERED_LIST_OP: { EFI_IFR_ORDERED_LIST *ptr = (EFI_IFR_ORDERED_LIST *)headerPtr; token = ptr->Question.Header.Prompt; } break; case EFI_IFR_PASSWORD_OP: { EFI_IFR_PASSWORD *ptr = (EFI_IFR_PASSWORD*)headerPtr; token = ptr->Question.Header.Prompt; } break; case EFI_IFR_ACTION_OP: { EFI_IFR_ACTION *ptr = (EFI_IFR_ACTION*)headerPtr; token = ptr->Question.Header.Prompt; } break; case EFI_IFR_RESET_BUTTON_OP: { EFI_IFR_RESET_BUTTON *ptr = (EFI_IFR_RESET_BUTTON*)headerPtr; #ifdef TSE_FOR_APTIO_4_50 token = ptr->Statement.Prompt; #else token = ptr->Question.Header.Prompt; #endif } break; case EFI_IFR_REF_OP: { EFI_IFR_REF *ptr = (EFI_IFR_REF*)headerPtr; token = ptr->Question.Header.Prompt; } break; case EFI_IFR_STRING_OP: { EFI_IFR_STRING *ptr = (EFI_IFR_STRING*)headerPtr; token = ptr->Question.Header.Prompt; } break; case EFI_IFR_SUBTITLE_OP: { EFI_IFR_SUBTITLE *ptr = (EFI_IFR_SUBTITLE*)headerPtr; token = ptr->Statement.Prompt; } break; default: break; } return token; } // //---------------------------------------------------------------------------- // // Procedure: _GetSubFormCount // // Description: Count the subform and Ref inside the formset // // Parameter: // // Return value: UINTN //---------------------------------------------------------------------------- // UINTN _GetSubFormCount(UINT8 *buff) { UINTN *tmpFormIDBuf; UINTN MaxPagecount=100; UINTN PageCount= 0; UINTN i=0, j=0, found =0; INTN ScopeCount = 0; EFI_IFR_OP_HEADER *Header; tmpFormIDBuf = (UINTN*)EfiLibAllocateZeroPool(MaxPagecount*sizeof(UINTN)); //go thru the forms and get the links, creating the lookup table also do { Header = (EFI_IFR_OP_HEADER*)(buff+i); switch(Header->OpCode ) { case EFI_IFR_FORM_OP: // find parent in lookup table and then the parent pageNum to link // Add page if is not in lookup table already found=0; j=0; while( (found==0) && ( j < PageCount ) ){ if(tmpFormIDBuf[j] == ((EFI_IFR_FORM*)Header)->FormId ) { found =1; break; } j++; } if(!found) { // pages in the root(no parent) tmpFormIDBuf[PageCount] = ((EFI_IFR_FORM*)Header)->FormId ; PageCount++; } break; case EFI_IFR_FORM_MAP_OP: // find parent in lookup table and then the parent pageNum to link // Add page if is not in lookup table already found=0; j=0; while((found==0) && (j < PageCount)) { if(tmpFormIDBuf[j] == ((AMI_EFI_IFR_FORM_MAP *)Header)->FormId) { found =1; } j++; } if(!found) { // pages in the root(no parent) tmpFormIDBuf[PageCount] = ((AMI_EFI_IFR_FORM_MAP *)Header)->FormId ; PageCount++; } break; case EFI_IFR_REF_OP: // add to lookup table adding the PageID and ParentPageID // Add page if is not in lookup table already found=0; j=0; while((found==0) && (j < PageCount)) { if(tmpFormIDBuf[j] == ((EFI_IFR_REF*)Header)->FormId) { found =1; } j++; } if(!found) { // pages in the root(no parent) tmpFormIDBuf[PageCount] = ((EFI_IFR_REF*)Header)->FormId ; PageCount++; } break; case EFI_IFR_END_OP: ScopeCount--; break; default: break; } if(Header->Scope) { ScopeCount++; } // If the Buffer is not enough the reallocate more if(PageCount >= MaxPagecount) { UINTN *tmpBuf; MaxPagecount +=50; tmpBuf = (UINTN*)EfiLibAllocateZeroPool(MaxPagecount*sizeof(UINTN)); MemCopy(tmpBuf,tmpFormIDBuf,sizeof(UINTN)*PageCount); MemFreePointer(&tmpFormIDBuf); tmpFormIDBuf = tmpBuf; } i+=Header->Length; }while(ScopeCount != 0); MemFreePointer(&tmpFormIDBuf); return PageCount; } // //---------------------------------------------------------------------------- // // Procedure: _GetVarNumFromVarID // // Description: Get Variable Index // // Parameter: // // Return value: UINT32 //---------------------------------------------------------------------------- // UINT32 _GetVarNumFromVarID (UINT32 ID, EFI_HII_HANDLE Handle, void *IfrData) { PVAR_KEY_TABLE pVarTable = VarKeyTable.Next; UINT16 *varString; UINT16 Width = 0; VARIABLE_INFO *Variable = NULL; VARIABLE_INFO newVariable; EFI_STATUS Status = EFI_SUCCESS; EFI_IFR_QUESTION_HEADER *QuestionHeader = NULL; while(pVarTable) { if ((pVarTable->VarId == ID) && (pVarTable->Handle == Handle)) { Variable = (VARIABLE_INFO*)((UINT8 *)VariableInfoPtr + VariableListPtr->VariableList [pVarTable->Index]); if (Variable) { if (VARIABLE_ATTRIBUTE_NAMEVALUE == (Variable->ExtendedAttibutes & VARIABLE_ATTRIBUTE_NAMEVALUE)) { QuestionHeader = (EFI_IFR_QUESTION_HEADER *)((UINT8 *)IfrData + sizeof (EFI_IFR_OP_HEADER)); varString = HiiGetString (Variable->VariableHandle, QuestionHeader->VarStoreInfo.VarName); Width = UefiGetWidth (IfrData); if (varString) { if (0 == (EfiStrLen (Variable->VariableName))) { Variable->VariableSize = Width; EfiStrCpy (Variable->VariableName, varString); } else { MemSet (&newVariable, sizeof (VARIABLE_INFO), 0); EfiCopyMem (&newVariable, Variable, sizeof (VARIABLE_INFO)); newVariable.VariableSize = Width; EfiStrCpy (newVariable.VariableName, varString); Status = AddVariableToList (&newVariable); if (!EFI_ERROR (Status)) { return gnewCtrlVar; } } } } return (pVarTable->Index); } } pVarTable = pVarTable->Next; } return 0; } // //---------------------------------------------------------------------------- // // Procedure: _InitFormsetLinks // // Description: Init Formset Links // // Parameter: // // Return value: //---------------------------------------------------------------------------- // EFI_STATUS _InitFormsetLinks(char *buff,UINTN InitFormNum) { EFI_STATUS status = EFI_SUCCESS; EFI_IFR_OP_HEADER *Header; UINTN j=0, found =0, InitForm = InitFormNum; UINTN ScopeCount = 0, count = 0; UINT16 RootPageinFormSet=0,RootPageID=0; UINT16 *_PageIdList = (UINT16 *)NULL, _PageIdListCount = 0; EFI_FORM_ID tempFormID = 0; SETUP_DEBUG_UEFI( "\n[TSE] Entering _InitFormsetLinks()\n"); // allocate memory for data if(FSetLinks != NULL) MemFreePointer(&FSetLinks); count = _GetSubFormCount(buff); FSetLinks = (FormSetLinks*)EfiLibAllocateZeroPool(sizeof(FormSetLinks) + count * sizeof(PageLink)); if(FSetLinks == NULL) { status = EFI_OUT_OF_RESOURCES; goto DONE; } //go thru the forms and get the links, creating the lookup table also do { Header = (EFI_IFR_OP_HEADER*)(buff); switch(Header->OpCode ) { case EFI_IFR_FORM_OP: // find parent in lookup table and then the parent pageNum to link // Add page if is not in lookup table already found = 0; j = 0; while( (found == 0) && ( j < FSetLinks->PageCount ) ) { if(FSetLinks->PageLink[j].FormID == ((EFI_IFR_FORM*)Header)->FormId ) { FSetLinks->PageLink[j].PageNum = (UINT16)InitForm++; found = 1; break; } j++; } if(found == 0) { if(!RootPageinFormSet) RootPageinFormSet = ((EFI_IFR_FORM*)Header)->FormId; // pages in the root(no parent) FSetLinks->PageLink[FSetLinks->PageCount].FormID = ((EFI_IFR_FORM*)Header)->FormId ; if(IsOrphanPagesAsRootPage()) { FSetLinks->PageLink[FSetLinks->PageCount].ParentPageID = 0; } else { if(RootPageinFormSet == ((EFI_IFR_FORM*)Header)->FormId) FSetLinks->PageLink[FSetLinks->PageCount].ParentPageID = 0; else FSetLinks->PageLink[FSetLinks->PageCount].ParentPageID = FSetLinks->PageLink[0].PageNum; } FSetLinks->PageLink[FSetLinks->PageCount].PageNum = (UINT16)InitForm++; FSetLinks->PageCount++; } if(Header->Scope) { ScopeCount++; } break; case EFI_IFR_FORM_MAP_OP: // find parent in lookup table and then the parent pageNum to link // Add page if is not in lookup table already found = 0; j = 0; while( (found == 0) && ( j < FSetLinks->PageCount ) ) { if(FSetLinks->PageLink[j].FormID == ((AMI_EFI_IFR_FORM_MAP *)Header)->FormId ) { FSetLinks->PageLink[j].PageNum = (UINT16)InitForm++; found = 1; break; } j++; } if(found == 0) { if(!RootPageinFormSet) RootPageinFormSet = ((AMI_EFI_IFR_FORM_MAP *)Header)->FormId; // pages in the root(no parent) FSetLinks->PageLink[FSetLinks->PageCount].FormID = ((AMI_EFI_IFR_FORM_MAP *)Header)->FormId ; if(IsOrphanPagesAsRootPage()) { FSetLinks->PageLink[FSetLinks->PageCount].ParentPageID = 0; } else { if(RootPageinFormSet == ((AMI_EFI_IFR_FORM_MAP *)Header)->FormId) FSetLinks->PageLink[FSetLinks->PageCount].ParentPageID = 0; else FSetLinks->PageLink[FSetLinks->PageCount].ParentPageID = FSetLinks->PageLink[0].PageNum; } FSetLinks->PageLink[FSetLinks->PageCount].PageNum = (UINT16)InitForm++; FSetLinks->PageCount++; } if(Header->Scope) { ScopeCount++; } case EFI_IFR_REF_OP: // add to lookup table adding the PageID and ParentPageID // Add page if is not in lookup table already found = 0; j = 0; while( (found == 0) && ( j < FSetLinks->PageCount ) ) { tempFormID = ((EFI_IFR_REF*)Header)->FormId; if(tempFormID == 0) //If the EFI_IFR_REFX FormId is invalid { tempFormID = (UINT16)InitForm; // Set the check FormId to the current FormId } if(FSetLinks->PageLink[j].FormID == tempFormID) { if(RootPageinFormSet != FSetLinks->PageLink[j].FormID) { if(FSetLinks->PageLink[j].PageNum != (UINT16)InitForm-1) // Parent of the Page can't be same page id. { FSetLinks->PageLink[j].ParentPageID = (UINT16)InitForm-1; } } found = 1; } j++; } if(found == 0) { // sub pages if(((EFI_IFR_FORM*)Header)->FormId) //If the the FormId is valid, store it { FSetLinks->PageLink[FSetLinks->PageCount].FormID = ((EFI_IFR_REF*)Header)->FormId ; } else{ //Else store the current FormId FSetLinks->PageLink[FSetLinks->PageCount].FormID = (UINT16)InitForm; } FSetLinks->PageLink[FSetLinks->PageCount].ParentPageID = (UINT16)InitForm-1; FSetLinks->PageLink[FSetLinks->PageCount].PageNum = 0; FSetLinks->PageCount++; } break; case EFI_IFR_END_OP: ScopeCount--; break; default: if(Header->Scope) { ScopeCount++; } break; } buff += Header->Length; }while(ScopeCount != 0); // Fix to find the Circulr Links. for(j=0;jPageCount;j++) { if(FSetLinks->PageLink[j].FormID == RootPageinFormSet) { RootPageID = FSetLinks->PageLink[j].PageNum; break; } } _PageIdList = EfiLibAllocateZeroPool(FSetLinks->PageCount*sizeof(UINT16)); for(j=0;jPageCount;j++) { UINT16 k,CurrentPageId,m,n; BOOLEAN IsCircular=TRUE; // Default if(FSetLinks->PageLink[j].ParentPageID == 0) continue; // Rootpage. CurrentPageId = FSetLinks->PageLink[j].PageNum; MemSet(_PageIdList, FSetLinks->PageCount*sizeof(UINT16), 0); _PageIdListCount = 0; k=0; while(kPageCount) { if(FSetLinks->PageLink[k].PageNum == CurrentPageId) { _PageIdList[_PageIdListCount++] = CurrentPageId; CurrentPageId = FSetLinks->PageLink[k].ParentPageID; if(CurrentPageId == RootPageID) break; // Root found. // Check if it circular. for(m=0;(m<_PageIdListCount)&& IsCircular ;m++) { if(_PageIdList[m] == CurrentPageId) // Circular pages.. Fix the PageIdList[0] { for(n=0;nPageCount;n++) { if(FSetLinks->PageLink[n].PageNum == _PageIdList[0]) { FSetLinks->PageLink[n].ParentPageID = RootPageID; IsCircular = FALSE; break; } } } } if(!IsCircular) break; k=0; continue; } k++; } } MemFreePointer(&_PageIdList); DONE: SETUP_DEBUG_UEFI( "\n[TSE] Exiting _InitFormsetLinks(), status = 0x%x \n" , status ); return status; } // //---------------------------------------------------------------------------- // // Procedure: _IsVarGuidPresent // // Description: Check if the Variable Guid is already defined // // Parameter: // // Return value: UINT8 //---------------------------------------------------------------------------- // UINT8 _IsVarGuidPresent(EFI_GUID * VarGuid, int * Index) { UINT32 i=0; VARIABLE_INFO *Variable; for(i=0; i < VariableListPtr->VariableCount; i++) { Variable = (VARIABLE_INFO *) ((UINT8 *)VariableInfoPtr + VariableListPtr->VariableList[i]); if( EfiCompareGuid(VarGuid,&(Variable->VariableGuid)) )//Compare Guid if( (EfiStrCmp(L"Setup",Variable->VariableName) ==0) || (EfiStrCmp(L"setup",Variable->VariableName) ==0 )) { *Index = i; return TRUE; } } return FALSE; } // //---------------------------------------------------------------------------- // // Procedure: _UpdateDefaults // // Description: Get Control Defaults // // Parameter: EFI_HII_HANDLE Handle, // VOID *Data, // UINT16 *size, // VOID *Failsafe, // VOID *Optimal, // DEFAULT_VALUE **defaultValue, // struct _CONTROL_FLAGS *Control_Flags, // VOID *ConditionalPtr // // Return value: UINT8 //---------------------------------------------------------------------------- // UINT8 _UpdateDefaults( EFI_HII_HANDLE Handle, VOID *Data, UINT16 *size, VOID **FailsafeValue, VOID **OptimalValue, DEFAULT_VALUE **defaultValue, struct _CONTROL_FLAGS *Control_Flags, VOID *ConditionalPtr) { EFI_IFR_OP_HEADER *OpHeader; EFI_QUESTION_ID QuestionId = 0; EFI_IFR_ONE_OF *OneOfOp = (EFI_IFR_ONE_OF *)NULL; EFI_IFR_ONE_OF_OPTION *OneOfOption = (EFI_IFR_ONE_OF_OPTION *)NULL; EFI_IFR_CHECKBOX *CheckBoxOp = (EFI_IFR_CHECKBOX *)NULL; EFI_IFR_NUMERIC *NumericOp = (EFI_IFR_NUMERIC *)NULL; EFI_IFR_ORDERED_LIST *OrderedListOp = (EFI_IFR_ORDERED_LIST *)NULL; EFI_IFR_PASSWORD *PasswordOp = (EFI_IFR_PASSWORD *)NULL; EFI_IFR_ACTION *ActionOp = (EFI_IFR_ACTION *)NULL; EFI_IFR_STRING *StringOp = (EFI_IFR_STRING *)NULL; EFI_IFR_DEFAULT *DefaultOp = (EFI_IFR_DEFAULT *)NULL; EFI_IFR_REF *RefOp = (EFI_IFR_REF *)NULL; EFI_IFR_DATE *DateOp = (EFI_IFR_DATE *)NULL; EFI_IFR_TIME *TimeOp = (EFI_IFR_TIME *)NULL; EFI_STRING_ID varName = 0; VARIABLE_INFO *varInfo = (VARIABLE_INFO *)NULL; UINT8 Flags=0, questionFlags = 0; UINTN ScopeCount = 0; UINT16 *varString = (UINT16 *)NULL; int i=0; UINT8 defaultCount = 0;//EIP: 56124 Declaration to count the defaults of the control VOID *Failsafe = NULL; VOID *Optimal = NULL; UINT16 RecommandedDefaultSize=0; UINT8 DefaultSize = 0; SETUP_DEBUG_UEFI( "\n[TSE] Entering _UpdateDefaults()\n"); // Assume the default values are 64 bits or less. If the values are larger, // we will re-allocate more space. Failsafe = EfiLibAllocateZeroPool (sizeof (UINT64)); if(NULL == Failsafe) { return 0; } Optimal = EfiLibAllocateZeroPool (sizeof (UINT64)); if(NULL == Optimal) { MemFreePointer (Failsafe); return 0; } do { OpHeader = (EFI_IFR_OP_HEADER*)((UINT8*)Data + i); switch(OpHeader->OpCode) { // ------ text -------------- case EFI_IFR_TEXT_OP: //(only interactive) break; // ------ ref -------------- case EFI_IFR_REF_OP: // uses only interactive , but to signal that a key has to be passed // back to a consumer (this behavior is not defined in TSE as of 5/20/05) RefOp = (EFI_IFR_REF*)((UINT8*)Data + i); questionFlags = RefOp->Question.Flags; break; // ------ one of -------------- case EFI_IFR_ONE_OF_OP: OneOfOp = (EFI_IFR_ONE_OF*)((UINT8*)Data + i); QuestionId = OneOfOp->Question.VarStoreInfo.VarOffset; CtrlVar = _GetVarNumFromVarID(OneOfOp->Question.VarStoreId, Handle, (void *)OneOfOp); varName = OneOfOp->Question.VarStoreInfo.VarName; questionFlags = OneOfOp->Question.Flags; DefaultSize = 1 << (OneOfOp->Flags & 0x0F); //if 0, the size is 1 so adding with 1 break; // ------ one of option-------------- case EFI_IFR_ONE_OF_OPTION_OP: OneOfOption = (EFI_IFR_ONE_OF_OPTION*)((UINT8*)Data + i); Flags =OneOfOption->Flags; if((Flags & EFI_IFR_OPTION_DEFAULT) == EFI_IFR_OPTION_DEFAULT) { GetDefaultValue(OneOfOption->Type, &(OneOfOption->Value), size, Optimal,(UINT8*)Data + i); } if((Flags & EFI_IFR_OPTION_DEFAULT_MFG) == EFI_IFR_OPTION_DEFAULT_MFG) { GetDefaultValue(OneOfOption->Type, &(OneOfOption->Value), size, Failsafe,(UINT8*)Data + i); } break; // ------ checkbox -------------- case EFI_IFR_CHECKBOX_OP: CheckBoxOp = (EFI_IFR_CHECKBOX*)Data; CtrlVar = _GetVarNumFromVarID(CheckBoxOp->Question.VarStoreId, Handle, (void *)CheckBoxOp); QuestionId = CheckBoxOp->Question.VarStoreInfo.VarOffset; varName = CheckBoxOp->Question.VarStoreInfo.VarName; questionFlags = CheckBoxOp->Question.Flags; //if(CheckBoxOp->Header.Scope == 0) EIP-80422 //{ Flags = CheckBoxOp->Flags ; //*size = sizeof(UINT8); *(UINT8*)Optimal = (Flags & EFI_IFR_CHECKBOX_DEFAULT)? 1 : 0; if (*(UINT8*)Optimal) *size = sizeof(UINT8);//EIP-116566 Set size if it has default *(UINT8*)Failsafe = (Flags & EFI_IFR_CHECKBOX_DEFAULT_MFG)? 1 : 0; if (*(UINT8*)Failsafe) *size = sizeof(UINT8);//EIP-116566 Set size if it has default Control_Flags->ControlRefresh = 0; //} DefaultSize = 1; break; // ------ numeric -------------- case EFI_IFR_NUMERIC_OP: NumericOp = (EFI_IFR_NUMERIC*)((UINT8*)Data + i); Control_Flags->ControlRefresh = 0; questionFlags = NumericOp->Question.Flags; QuestionId = NumericOp->Question.VarStoreInfo.VarOffset; CtrlVar = _GetVarNumFromVarID(NumericOp->Question.VarStoreId, Handle, (void *)NumericOp); varName = NumericOp->Question.VarStoreInfo.VarName; DefaultSize = 1 << (NumericOp->Flags & 0x0F); //if 0, the size is 1 so adding with 1 break; // ------ ordered list -------------- case EFI_IFR_ORDERED_LIST_OP: OrderedListOp = (EFI_IFR_ORDERED_LIST*)((UINT8*)Data + i); QuestionId = OrderedListOp->Question.VarStoreInfo.VarOffset; CtrlVar = _GetVarNumFromVarID(OrderedListOp->Question.VarStoreId, Handle, (void *)OrderedListOp); varName = OrderedListOp->Question.VarStoreInfo.VarName; questionFlags =OrderedListOp->Question.Flags; DefaultSize = OrderedListOp->MaxContainers; break; // ------ date -------------- case EFI_IFR_DATE_OP: DateOp = (EFI_IFR_DATE*)((UINT8*)Data + i); CtrlVar = _GetVarNumFromVarID(DateOp->Question.VarStoreId, Handle, (void *)DateOp); varName = DateOp->Question.VarStoreInfo.VarName; questionFlags =DateOp->Question.Flags; QuestionId = DateOp->Question.VarStoreInfo.VarOffset; if ((DateOp->Flags & EFI_QF_DATE_STORAGE) == QF_DATE_STORAGE_TIME) { Control_Flags->ControlRefresh = DEFAULT_DATETIME_REFRESH; /**refresh*/ } break; // ------ time -------------- case EFI_IFR_TIME_OP: TimeOp = (EFI_IFR_TIME*)((UINT8*)Data + i); CtrlVar = _GetVarNumFromVarID(TimeOp->Question.VarStoreId, Handle, (void *)TimeOp); varName = TimeOp->Question.VarStoreInfo.VarName; questionFlags =TimeOp->Question.Flags; QuestionId = TimeOp->Question.VarStoreInfo.VarOffset; if ((TimeOp->Flags & QF_TIME_STORAGE) == QF_TIME_STORAGE_TIME) //EIP 61650 Not able to edit the normal storage time opcode { Control_Flags->ControlRefresh = DEFAULT_DATETIME_REFRESH; } //Control_Flags->ControlRefresh = DEFAULT_DATETIME_REFRESH; break; // ------ string -------------- case EFI_IFR_STRING_OP: StringOp = (EFI_IFR_STRING*)Data; questionFlags = StringOp->Question.Flags; QuestionId = StringOp->Question.VarStoreInfo.VarOffset; CtrlVar = _GetVarNumFromVarID(StringOp->Question.VarStoreId, Handle, (void *)StringOp); varName = StringOp->Question.VarStoreInfo.VarName; break; // ------ End op -------------- case EFI_IFR_END_OP: if(ScopeCount) { ScopeCount--; } break; // ------ password-------------- case EFI_IFR_PASSWORD_OP: PasswordOp = (EFI_IFR_PASSWORD*)Data; questionFlags = PasswordOp->Question.Flags; CtrlVar = _GetVarNumFromVarID(PasswordOp->Question.VarStoreId, Handle, (void *)PasswordOp); QuestionId = PasswordOp->Question.VarStoreInfo.VarOffset; varName = PasswordOp->Question.VarStoreInfo.VarName; break; // ------- Action -------------- case EFI_IFR_ACTION_OP: ActionOp = (EFI_IFR_ACTION*)Data; questionFlags = ActionOp->Question.Flags; CtrlVar = _GetVarNumFromVarID(ActionOp->Question.VarStoreId, Handle, (void *)ActionOp); QuestionId = ActionOp->Question.VarStoreInfo.VarOffset; // if ((questionFlags & EFI_IFR_FLAG_CALLBACK) && (Control_Flags->ControlRefresh == 0)) //EIP:116513 Do refresh only if AMI CALLBACK value is used. if(ConditionalPtr != NULL) { if(INTERACTIVE_TEXT_VALUE == UefiTseLiteGetAmiCallbackIndex(ConditionalPtr,ActionOp )) Control_Flags->ControlRefresh = DEFAULT_REFRESH_RATE; } break; // ------- Reset Button -------------- case EFI_IFR_RESET_BUTTON_OP: break; // ------ default -------------- case EFI_IFR_DEFAULT_OP: DefaultOp = (EFI_IFR_DEFAULT*)((UINT8*)Data + i); if(DefaultOp->Type == EFI_IFR_TYPE_BUFFER) //Update the size value for the EFI_IFR_TYPE_BUFFER { //Update size for the array of value stored in VALUE field excluding size for op_header, DefaultId & Type *size = ((EFI_IFR_OP_HEADER*)DefaultOp)->Length - sizeof(EFI_IFR_OP_HEADER) - sizeof(UINT16) - sizeof(UINT8); } else if(DefaultOp->Type == EFI_IFR_TYPE_REF) //ifREf5 Opcode with default value, value is obtained as size of EFI_HII_REF EIP109812, 107774 { //buffer is of size EFI_HII_REF. *size = sizeof(AMI_EFI_HII_REF); } if(DefaultOp->Header.Scope && DefaultOp->Type > EFI_IFR_TYPE_BUFFER) { // retrieve default value from within scope (evaluate EFI_IFR_VALUE) Control_Flags->ControlEvaluateDefault = TRUE; } else if(DefaultOp->DefaultId == EFI_HII_DEFAULT_CLASS_STANDARD) { // if Optimal is not large enough to hold the buffer, allocate more space for it. if (*size > sizeof (UINT64)) { Optimal = MemReallocateZeroPool (Optimal, sizeof (UINT64), (UINTN) *size); } GetDefaultValue(DefaultOp->Type, &(DefaultOp->Value), size, Optimal,(UINT8*)Data + i); if ((0 == *size) && (DefaultOp->Type == EFI_IFR_TYPE_OTHER)) // GetDefaultValue will return 0 if need Evalutaion Control_Flags->ControlEvaluateDefault = TRUE; else if (DefaultSize) { *size = DefaultSize; } } else if(DefaultOp->DefaultId == EFI_IFR_OPTION_DEFAULT_MFG) { // if Failsafe is not large enough to hold the buffer, allocate more space for it. if (*size > sizeof (UINT64)) { Failsafe = MemReallocateZeroPool (Failsafe, sizeof (UINT64), (UINTN) *size); } GetDefaultValue(DefaultOp->Type, &(DefaultOp->Value), size, Failsafe,(UINT8*)Data + i); if ((0 == *size) && (DefaultOp->Type == EFI_IFR_TYPE_OTHER)) Control_Flags->ControlEvaluateDefault = TRUE; else if (DefaultSize) { *size = DefaultSize; } } //else //EIP-124286 Commented since it will not fill Standard and above case defaults for default2 when ResetButton is pressed { // EIp : 56124 Defautls are stored as linked list DEFAULT_VALUE *defaults = NULL; if(*defaultValue == NULL) { *defaultValue = (DEFAULT_VALUE*)EfiLibAllocateZeroPool(sizeof(DEFAULT_VALUE)); defaults = *defaultValue; }else { for(defaults = *defaultValue; defaults->Next; defaults = defaults->Next) ; defaults->Next = (DEFAULT_VALUE*)EfiLibAllocateZeroPool(sizeof(DEFAULT_VALUE)); defaults = defaults->Next; } defaults->DefaultId = DefaultOp->DefaultId; GetDefaultValue(DefaultOp->Type, &(DefaultOp->Value), size, &defaults->Value, (UINT8*)Data + i); if((*size == 0 ) && (DefaultOp->Type == EFI_IFR_TYPE_OTHER)) Control_Flags->ControlEvaluateDefault = TRUE; else if (DefaultSize) *size = DefaultSize; defaultCount++; } // DefaultSize = 0; //If defaultstore 2 is present then changing to 0 will mal function so commented. break; // ------ refresh -------------- case EFI_IFR_REFRESH_OP: Control_Flags->ControlRefresh = ((EFI_IFR_REFRESH*)((UINT8*)Data + i))->RefreshInterval; // SetupData's ControlRefresh Granularity is 1/20 Sec (TSE_REFRESH_GRANURALITY) and makesure it does not cross BYTE size Control_Flags->ControlRefresh = (UINT8)( ((Control_Flags->ControlRefresh*TSE_REFRESH_GRANURALITY) <= 0xFF)? (Control_Flags->ControlRefresh*TSE_REFRESH_GRANURALITY): 0xFF); break; // ------ refresh id -------------- case EFI_IFR_REFRESH_ID_OP: MemCopy( &RefreshEventGroupId, &(((AMI_EFI_IFR_REFRESH_ID *)((UINT8*)Data + i))->RefreshEventGroupId), sizeof(EFI_GUID) ); Control_Flags->RefreshID = TRUE;//EIP-105468 break; // ------ inconsistent if -------------- case EFI_IFR_INCONSISTENT_IF_OP: if(IsRecursive == FALSE) { Inconsistant = TRUE; } break; //----locked-----EIP:56896 case EFI_IFR_LOCKED_OP: questionFlags |= EFI_IFR_FLAG_READ_ONLY; break; //EIP : -------------- NO_SUBMIT_IF -------------- case EFI_IFR_NO_SUBMIT_IF_OP: if(IsRecursive == FALSE) { NoSubmitIf = TRUE; } break; default: break; } if(OpHeader->Scope) { ScopeCount++; } i += OpHeader->Length; }while(ScopeCount != 0); Control_Flags->ControlReset = (questionFlags & EFI_IFR_FLAG_RESET_REQUIRED)? 1 : 0; Control_Flags->ControlReadOnly = (questionFlags & EFI_IFR_FLAG_READ_ONLY)? 1 : 0; Control_Flags->ControlInteractive = (questionFlags & EFI_IFR_FLAG_CALLBACK)? 1 : 0; if(CtrlVar) { varInfo = (VARIABLE_INFO*)((UINT8 *)VariableInfoPtr + VariableListPtr->VariableList[CtrlVar]); if(varInfo->ExtendedAttibutes) { varInfo->VariableNameId = varName; varString = HiiGetString(varInfo->VariableHandle, varName); if(varString && (EfiStrLen(varInfo->VariableName) == 0)) { EfiStrCpy(varInfo->VariableName, varString); } } } *FailsafeValue = Failsafe; *OptimalValue = Optimal; SETUP_DEBUG_UEFI( "\n[TSE] Exiting _UpdateDefaults()\n") ; return defaultCount;//EIP:56124 Returning the Default count for the control } // //---------------------------------------------------------------------------- // // Procedure: GetValueFromOpCode // // Description: Gets the value from the opcode // // Parameter: EFI_IFR_OP_HEADER *, // EFI_HII_VALUE *, // INTN // // Return value: VOID //---------------------------------------------------------------------------- // VOID GetValueFromOpCode (EFI_IFR_OP_HEADER *ifrData, EFI_HII_VALUE *Value, INTN Result) { EFI_HII_VALUE Data1; EFI_HII_VALUE Data2; EFI_STATUS Status = EFI_SUCCESS; EfiZeroMem (&Data1, sizeof (EFI_HII_VALUE)); EfiZeroMem (&Data1, sizeof (EFI_HII_VALUE)); EfiZeroMem (Value, sizeof (EFI_HII_VALUE)); switch (ifrData->OpCode) { case EFI_IFR_EQUAL_OP: Value->Value.b = (Result == 0) ? TRUE : FALSE; break; case EFI_IFR_NOT_EQUAL_OP: Value->Value.b = (Result != 0) ? TRUE : FALSE; break; case EFI_IFR_GREATER_EQUAL_OP: Value->Value.b = (Result >= 0) ? TRUE : FALSE; break; case EFI_IFR_GREATER_THAN_OP: Value->Value.b = (Result > 0) ? TRUE : FALSE; break; case EFI_IFR_LESS_EQUAL_OP: Value->Value.b = (Result <= 0) ? TRUE : FALSE; break; case EFI_IFR_LESS_THAN_OP: Value->Value.b = (Result < 0) ? TRUE : FALSE; break; case EFI_IFR_UINT8_OP: Value->Type = EFI_IFR_TYPE_NUM_SIZE_8; Value->Value.u8 = ((EFI_IFR_UINT8*)ifrData)->Value; break; case EFI_IFR_UINT16_OP: Value->Type = EFI_IFR_TYPE_NUM_SIZE_16; Value->Value.u16 = ((EFI_IFR_UINT16*)ifrData)->Value; break; case EFI_IFR_UINT32_OP: Value->Type = EFI_IFR_TYPE_NUM_SIZE_32; Value->Value.u32 = ((EFI_IFR_UINT32*)ifrData)->Value; break; case EFI_IFR_UINT64_OP: Value->Type = EFI_IFR_TYPE_NUM_SIZE_64; Value->Value.u64 = ((EFI_IFR_UINT64*)ifrData)->Value; break; case EFI_IFR_NOT_OP: Status = PopExpression (Value); if (EFI_ERROR (Status)) { break; } if (Value->Type != EFI_IFR_TYPE_BOOLEAN) { break; } Value->Value.b = !Value->Value.b; break; case EFI_IFR_AND_OP: case EFI_IFR_OR_OP: // // Two Boolean operator // Status = PopExpression (&Data2); if (EFI_ERROR (Status)) { break; } if (Data2.Type != EFI_IFR_TYPE_BOOLEAN) { break; } // // Pop another expression from the expression stack // Status = PopExpression (&Data1); if (EFI_ERROR (Status)) { break; } if (Data1.Type != EFI_IFR_TYPE_BOOLEAN) { break; } if (ifrData->OpCode == EFI_IFR_AND_OP) { Value->Value.b = Data1.Value.b && Data2.Value.b; } else { Value->Value.b = Data1.Value.b || Data2.Value.b; } break; // // binary-op // case EFI_IFR_ADD_OP: case EFI_IFR_SUBTRACT_OP: case EFI_IFR_MULTIPLY_OP: case EFI_IFR_DIVIDE_OP: case EFI_IFR_MODULO_OP: case EFI_IFR_BITWISE_AND_OP: case EFI_IFR_BITWISE_OR_OP: case EFI_IFR_SHIFT_LEFT_OP: case EFI_IFR_SHIFT_RIGHT_OP: // // Pop an expression from the expression stack // Status = PopExpression (&Data2); if (EFI_ERROR (Status)) { break; } if (Data2.Type > EFI_IFR_TYPE_DATE) { Status = EFI_INVALID_PARAMETER; break; } // // Pop another expression from the expression stack // Status = PopExpression (&Data1); if (EFI_ERROR (Status)) { break; } if (Data1.Type > EFI_IFR_TYPE_DATE) { break; } Value->Type = EFI_IFR_TYPE_NUM_SIZE_64; switch (ifrData->OpCode) { case EFI_IFR_ADD_OP: Value->Value.u64 = Data1.Value.u64 + Data2.Value.u64; break; case EFI_IFR_SUBTRACT_OP: Value->Value.u64 = Data1.Value.u64 - Data2.Value.u64; break; case EFI_IFR_MULTIPLY_OP: Value->Value.u64 = MultU64x32 (Data1.Value.u64, (UINT32)Data2.Value.u64); break; case EFI_IFR_DIVIDE_OP: Value->Value.u64 = AmiTseDivU64x32 (Data1.Value.u64, (UINT32)Data2.Value.u64,NULL); break; case EFI_IFR_MODULO_OP: Value->Value.u64 = 0; AmiTseDivU64x32(Data1.Value.u64, (UINT32)Data2.Value.u64, (UINTN*)Value->Value.u64); break; case EFI_IFR_BITWISE_AND_OP: Value->Value.u64 = Data1.Value.u64 & Data2.Value.u64; break; case EFI_IFR_BITWISE_OR_OP: Value->Value.u64 = Data1.Value.u64 | Data2.Value.u64; break; case EFI_IFR_SHIFT_LEFT_OP: Value->Value.u64 = LShiftU64 (Data1.Value.u64, (UINTN) Data2.Value.u64); break; case EFI_IFR_SHIFT_RIGHT_OP: Value->Value.u64 = RShiftU64 (Data1.Value.u64, (UINTN) Data2.Value.u64); break; default: break; } default: Value->Type = EFI_IFR_TYPE_UNDEFINED; break; } } // //---------------------------------------------------------------------------- // // Procedure: EvaluateReadWrite // // Description: Evaluates read write conditions // // Parameter: UINT8 *, // CONTROL_INFO *, // EFI_HII_VALUE * // // Return value: VOID //---------------------------------------------------------------------------- // EFI_STATUS GetRWVariableID (UINT16 RWVarStoreId, CONTROL_INFO *ControlInfo, UINT16 *VarStoreId); VOID EvaluateReadWrite(UINT8 *buf, CONTROL_INFO *ControlInfo, EFI_HII_VALUE *Value1) { EFI_HII_VALUE *Value=NULL; EFI_HII_VALUE *questionValue=NULL; EFI_IFR_TYPE_VALUE questionValue1; UINT64 qValue=0; EFI_HII_VALUE Data1; EFI_HII_VALUE Data2; EFI_HII_VALUE Data3; EFI_IFR_OP_HEADER *ifrData = NULL; EFI_STATUS Status; INTN Result; UINTN i = 0; UINTN j = 0; EFI_QUESTION_ID questionId = 0; AMI_EFI_IFR_GET *IfrGet =NULL; AMI_EFI_IFR_SET *IfrSet =NULL; UINTN dataWidth = 0; UINT16 Size = 0; EFI_IFR_QUESTION_HEADER *questionHdr = NULL; UINT64 def; UINTN ScopeCount = 0; ResetExpressionStack (); questionValue = (EFI_HII_VALUE*)EfiLibAllocateZeroPool(sizeof(EFI_HII_VALUE)); EfiZeroMem (questionValue, sizeof (EFI_HII_VALUE)); EfiZeroMem (&Data1, sizeof (EFI_HII_VALUE)); EfiZeroMem (&Data2, sizeof (EFI_HII_VALUE)); EfiZeroMem (&Data3, sizeof (EFI_HII_VALUE)); Value = &Data3; Value->Type = EFI_IFR_TYPE_BOOLEAN; ifrData = (EFI_IFR_OP_HEADER*)buf; do { if(ifrData->Scope) { ScopeCount++; } switch(ifrData->OpCode) { case EFI_IFR_THIS_OP: Status = _GetValueFromQuestionId(ControlInfo->ControlKey, ControlInfo->ControlPageID, &questionValue); if(EFI_ERROR(Status)) { goto DONE; } Value = questionValue; break; case EFI_IFR_END_OP: if(ScopeCount) { ScopeCount--; } goto DONE; case EFI_IFR_GET_OP: { UINT16 VarStoreId = 0; IfrGet = (AMI_EFI_IFR_GET *)ifrData; GetDefaultValue(IfrGet->VarStoreType,&questionValue1, &Size, &def, (UINT8 *)ifrData); Status = GetRWVariableID (IfrGet->VarStoreId, ControlInfo, &VarStoreId); if(EFI_ERROR(Status)) { goto DONE; } Status = VarGetValue(VarStoreId, IfrGet->VarStoreInfo.VarOffset, (( Size > sizeof(UINT64))? sizeof(UINT64) : Size ), &qValue); if(EFI_ERROR(Status)) { goto DONE; } Value->Value.u64 = qValue; break; } case EFI_IFR_SET_OP: { UINT16 VarStoreId = 0; IfrSet = (AMI_EFI_IFR_SET *)ifrData; GetDefaultValue(IfrSet->VarStoreType,&questionValue1, &Size, &def, (UINT8 *)ifrData); Status = GetRWVariableID (IfrSet->VarStoreId, ControlInfo, &VarStoreId); if(EFI_ERROR(Status)) { goto DONE; } Status = PopExpression (&Data1); if (EFI_ERROR (Status)) { goto DONE; } qValue = Data1.Value.u64; if(Data1.Type != EFI_IFR_TYPE_UNDEFINED){ Status = VarSetValue(VarStoreId, IfrSet->VarStoreInfo.VarOffset, (( Size > sizeof(UINT64))? sizeof(UINT64) : Size ), &qValue); } if(EFI_ERROR(Status)) { goto DONE; } Value->Type = Data1.Type; Value->Value.u64 = qValue; break; } case EFI_IFR_MAP_OP: Status = PopExpression (&Data1); if (EFI_ERROR (Status)) { goto DONE; } i+=ifrData->Length; ifrData = (EFI_IFR_OP_HEADER*)(buf + i); while (ifrData->OpCode != EFI_IFR_END_OP) { GetValueFromOpCode(ifrData,Value,Result); Result = CompareHiiValue (&Data1, Value,NULL); i+=ifrData->Length; ifrData = (EFI_IFR_OP_HEADER*)(buf + i); //Skip its pair so incrementing ifrData if (0 == Result) { GetValueFromOpCode(ifrData,Value,Result); //Retreiving the value while(ifrData->OpCode != EFI_IFR_END_OP) { i+=ifrData->Length; ifrData = (EFI_IFR_OP_HEADER*)(buf + i); } } else { i+=ifrData->Length; ifrData = (EFI_IFR_OP_HEADER*)(buf + i); } } if ((EFI_IFR_END_OP == ifrData->OpCode) && (ScopeCount)) //Since endopcode validated before itself here we decrementing scope { ScopeCount --; } break; case EFI_IFR_CONDITIONAL_OP: // // Pop third expression from the expression stack // Status = PopExpression (&Data3); if (EFI_ERROR (Status)) { goto DONE; } // // Pop second expression from the expression stack // Status = PopExpression (&Data2); if (EFI_ERROR (Status)) { goto DONE; } // // Pop first expression from the expression stack // Status = PopExpression (&Data1); if (EFI_ERROR (Status)) { goto DONE; } if (Data1.Value.b) { Value = &Data2; } else { Value = &Data3; } break; case EFI_IFR_EQUAL_OP: case EFI_IFR_NOT_EQUAL_OP: case EFI_IFR_GREATER_EQUAL_OP: case EFI_IFR_GREATER_THAN_OP: case EFI_IFR_LESS_EQUAL_OP: case EFI_IFR_LESS_THAN_OP: // // Compare two integer, string, boolean or date/time // Status = PopExpression (&Data2); if (EFI_ERROR (Status)) { goto DONE; } if (Data2.Type > EFI_IFR_TYPE_BOOLEAN && Data2.Type != EFI_IFR_TYPE_STRING) { Status = EFI_INVALID_PARAMETER; goto DONE; } // // Pop another expression from the expression stack // Status = PopExpression (&Data1); if (EFI_ERROR (Status)) { goto DONE; } Result = CompareHiiValue (&Data1, &Data2,NULL); if (Result == EFI_INVALID_PARAMETER) { Status = EFI_INVALID_PARAMETER; goto DONE; } GetValueFromOpCode(ifrData,Value,Result); break; case EFI_IFR_UINT8_OP: case EFI_IFR_UINT16_OP: case EFI_IFR_UINT32_OP: case EFI_IFR_UINT64_OP: GetValueFromOpCode(ifrData,Value,Result); break; // binary-op case EFI_IFR_ADD_OP: case EFI_IFR_SUBTRACT_OP: case EFI_IFR_MULTIPLY_OP: case EFI_IFR_DIVIDE_OP: case EFI_IFR_MODULO_OP: case EFI_IFR_BITWISE_AND_OP: case EFI_IFR_BITWISE_OR_OP: case EFI_IFR_SHIFT_LEFT_OP: case EFI_IFR_SHIFT_RIGHT_OP: GetValueFromOpCode(ifrData,Value,Result); break; case EFI_IFR_UNDEFINED_OP: Value1->Type = EFI_IFR_TYPE_UNDEFINED; return; default: goto DONE; break; } PushExpression(Value); DONE: i += ((EFI_IFR_OP_HEADER*)(buf + i))->Length; ifrData = (EFI_IFR_OP_HEADER*)(buf + i); } while(ScopeCount); MemFreePointer(&questionValue); Status = PopExpression (&Data1); if(EFI_ERROR (Status)){ Data1.Type = EFI_IFR_TYPE_UNDEFINED; } MemCopy(Value1,&Data1,sizeof(EFI_HII_VALUE)); } // //---------------------------------------------------------------------------- // // Procedure: _AddHpkControls // // Description: Add Control Setup Data // // Parameter: // // Return value: UINTN //---------------------------------------------------------------------------- // UINTN _AddHpkControls(EFI_HII_HANDLE Handle, UINT8 *buff,UINTN Size, PAGE_INFO **NewPageInfo, UINT32 *AllocatedPageSize, UINT32 *PageOffset) { CONTROL_FLAGS control_Flags; CONTROL_INFO *control_Info; CONTROL_INFO *NotifyContext = (CONTROL_INFO*)NULL; EFI_IFR_OP_HEADER *opHeader= NULL; EFI_EVENT RefreshIdEvent = (EFI_EVENT)NULL; EFI_IFR_OP_HEADER *opHdrPtr= (EFI_IFR_OP_HEADER *)NULL; BOOLEAN addControl = TRUE; BOOLEAN updatecondvars = TRUE; UINT8 opCode = 0; UINT16 controlLabel = 0; UINT16 controlIndex = 0; UINT16 destPageID =0xFFFF; UINT16 controlType = 0; UINT16 devicePathId = 0; UINT16 helpOffset = 0; UINT16 questionId = 0; UINT16 opcodeNum = 0; UINT16 defaults_size=0; UINT16 controlKey = 0; UINT32 controlSize = 0; UINT32 controlOffset = 0; INT32 ifCounter = 0; VOID *ctrlFailSafe = NULL; VOID *ctrlOptimal = NULL; UINTN i =0, end=0,j=0,index=0, itr = 0; VOID *conditionalPtr = NULL; VOID *controlPtr = NULL; BOOLEAN Formlock = FALSE;//EIP:56896 support for Formlock UINT16 refQuestionId = 0; //EIP: 55762 EFI_STATUS Status = EFI_SUCCESS; INT32 ScopeCount = 0; DEFAULT_VALUE *defaultValue = NULL, *Temp= NULL;//EIP:56214 Declaration for the Default value SETUP_DEBUG_UEFI("\n[TSE] Entering _AddHpkControls\n"); // for loop for the number of controls of this while(i < Size ) { addControl = TRUE; MemSet(&control_Flags, sizeof(CONTROL_FLAGS), 0); control_Flags.ControlVisible =0x1; controlType = 0; CtrlVar = 0; destPageID =0xFFFF; opHeader = (EFI_IFR_OP_HEADER*)(buff + i); if(opHeader->Scope) { PushScope(opHeader->OpCode); } // control type switch(opHeader->OpCode) { case EFI_IFR_SUBTITLE_OP: controlType = CONTROL_TYPE_MEMO; break; case EFI_IFR_TEXT_OP: controlType = CONTROL_TYPE_TEXT; break; case EFI_IFR_ONE_OF_OP: case EFI_IFR_CHECKBOX_OP: controlType = CONTROL_TYPE_POPUPSEL; break; case EFI_IFR_NUMERIC_OP: controlType = CONTROL_TYPE_NUMERIC; break; case EFI_IFR_PASSWORD_OP: controlType = CONTROL_TYPE_PASSWORD; break; case EFI_IFR_ACTION_OP: controlType = CONTROL_TYPE_ACTION; break; case EFI_IFR_MODAL_TAG_OP: //EIP-85745 Modal Support (*NewPageInfo)->PageFlags.PageModal = 1; break; case EFI_IFR_RESET_BUTTON_OP: controlType = CONTROL_TYPE_RESET; break; case EFI_IFR_REF_OP: controlType = CONTROL_TYPE_SUBMENU; destPageID = _GetPageNumFromFormID(((EFI_IFR_REF*)((char*)buff +i))->FormId); //EIP: 55762 Start if(opHeader->Length >= sizeof(EFI_IFR_REF2)) { refQuestionId = ((EFI_IFR_REF2*)((char*)buff +i))->QuestionId; } //EIP: 55762 End break; case EFI_IFR_INCONSISTENT_IF_OP: controlType = INCONSISTENT_IF; break; //EIP : NO_SUBMIT_IF case EFI_IFR_NO_SUBMIT_IF_OP: controlType = NO_SUBMIT_IF; break; case EFI_IFR_RULE_OP: controlType = CONTROL_TYPE_RULE; conditionalPtr = (VOID *)((UINT8 *)opHeader + sizeof(EFI_IFR_RULE)); break; case EFI_IFR_END_OP: PopScope(&opCode); switch(opCode) { case EFI_IFR_FORM_OP: case EFI_IFR_FORM_MAP_OP: i += opHeader->Length; end =1; break; case EFI_IFR_NO_SUBMIT_IF_OP: case EFI_IFR_INCONSISTENT_IF_OP: case EFI_IFR_SUPPRESS_IF_OP: case EFI_IFR_GRAY_OUT_IF_OP: case EFI_IFR_DISABLE_IF_OP: controlType = --ifCounter? 0 : END_EVAL_IF; break; default: controlType = 0; break; } addControl = FALSE; break; case EFI_IFR_DATE_OP: controlType = CONTROL_TYPE_DATE; break; case EFI_IFR_TIME_OP: controlType = CONTROL_TYPE_TIME; break; case EFI_IFR_STRING_OP: controlType = CONTROL_TYPE_POPUP_STRING; break; case EFI_IFR_SUPPRESS_IF_OP: //case EFI_IFR_NO_SUBMIT_IF_OP: case EFI_IFR_GRAY_OUT_IF_OP: case EFI_IFR_DISABLE_IF_OP: controlType = START_EVAL_IF; addControl =FALSE; break; case EFI_IFR_ORDERED_LIST_OP: controlType = CONTROL_TYPE_ORDERED_LIST; break; case EFI_IFR_VARSTORE_OP: case EFI_IFR_VARSTORE_NAME_VALUE_OP: case EFI_IFR_VARSTORE_EFI_OP: _AddVariable((UINT8*)opHeader, Handle); addControl =FALSE; break; //EIP:56896 Form lock support provided. case EFI_IFR_LOCKED_OP: Formlock = TRUE; break; default: addControl = FALSE; break; } switch(controlType) { //EIP : NO_SUBMIT_IF case NO_SUBMIT_IF: case INCONSISTENT_IF: case START_EVAL_IF: // IF for grayout,suppress, no submit and disable if(updatecondvars == 1) { updatecondvars = 0; conditionalPtr = (gConditionOverForm == TRUE) ? gConditionalOverFormPtr : (VOID *)opHeader; } ifCounter++; break; case END_EVAL_IF: conditionalPtr = NULL; updatecondvars = TRUE; ifCounter = 0; break; default: break; } if(end ==1) break; if(addControl) { defaults_size =0; controlKey = _GetControlKeyToken((UINT8*)opHeader); devicePathId = _GetControlDevicePathId((UINT8*)opHeader); helpOffset = _GetHelpToken((UINT8*)opHeader); questionId = _GetQuestionToken((UINT8*)opHeader); DefaultStoreCount = _UpdateDefaults(Handle, (void *)opHeader, &defaults_size, &ctrlFailSafe, &ctrlOptimal, &defaultValue,&control_Flags, conditionalPtr); //EIP:56896 Checking for the Formlock condition if(Formlock) control_Flags.ControlReadOnly = 1; //EIP:56124 Allocating the control Size depending on the default count of the control controlSize = sizeof(CONTROL_INFO) + defaults_size * 2+ DefaultStoreCount*(sizeof(UINT16) + defaults_size); control_Info = EfiLibAllocateZeroPool(controlSize); if(control_Info == NULL) { i = Size; goto DONE; } controlPtr = (VOID *)opHeader; if(controlType == INCONSISTENT_IF ) { controlType = CONTROL_TYPE_MSGBOX; controlPtr = 0; } //EIP : NO_SUBMIT_IF if(controlType == NO_SUBMIT_IF ) { controlType = NO_SUBMIT_IF; controlPtr = 0; } /* Update Control Info*/ /* * control_Info->ControlHandle * HII Handle to the formset that contains this control */ control_Info->ControlHandle = Handle; /* * control_Info->ControlVariable * Overrides the variable ID for this specific control */ control_Info->ControlVariable = CtrlVar; /* * control_Info->ControlConditionalVariable * Conditional variable ID?s for this control * or * For UEFI 2.1 Use the following. * control_Info->ControlKey * control_Info->DefaultStoreCount * control_Info->Reserved */ control_Info->ControlKey = controlKey; control_Info->DevicePathId = devicePathId; control_Info->DefaultStoreCount = DefaultStoreCount; /* * control_Info->ControlType * Type of the control on the page */ control_Info->ControlType = controlType & CONTROL_TYPE_MASK; /* * control_Info->ControlPageID * Page ID that contains this control */ control_Info->ControlPageID = PageListPtr ? (UINT16)PageListPtr->PageCount:1; /* * control_Info->ControlDestPageID * Dest PageId. Only needed for controls of type CONTROL_TYPE_SUBMENU */ control_Info->ControlDestPageID = destPageID; /* * control_Info->DestQuestionID * Question Id that will be selected refered page is visited. Only needed for controls of type CONTROL_TYPE_SUBMENU */ control_Info->DestQuestionID = refQuestionId; //EIP: 55762 /* * control_Info->ControlFlags * Various attributes for a specific control */ control_Info->ControlFlags = control_Flags; /* * control_Info->ControlHelp * Token for help string for this control */ control_Info->ControlHelp = helpOffset; /* * control_Info->ControlLabel * One-based label number that this control is ?linked to? */ control_Info->ControlLabel = controlLabel; /* * control_Info->ControlIndex * Zero-based opcode number from the last label */ control_Info->ControlIndex = controlIndex; /* * control_Info->ControlLabelCount * Number of opcodes associated with this control's label */ control_Info->ControlLabelCount = opcodeNum; /* * control_Info->ControlPtr * Pointer to control data in HII */ control_Info->ControlPtr = (VOID *)controlPtr; /* * control_Info->ControlConditionalPtr * Pointer to control condition data in HII */ control_Info->ControlConditionalPtr = (gConditionOverForm == TRUE) ? gConditionalOverFormPtr :(VOID *)conditionalPtr; /* * control_Info->ControlDataLength * Length of HII data for control */ control_Info->ControlDataLength = defaults_size; /* * control_Info->ControlDataWidth * Width of data (in bytes) for this control */ control_Info->ControlDataWidth = defaults_size; /* * control_Info->QuestionId * QuestionId of this control */ control_Info->QuestionId = questionId; //READ/WRTIE opcode opHeader if((*NewPageInfo)->PageFlags.PageStdMap){ if (opHeader->Scope && controlType && addControl) { UINT32 scopeCount = 0; BOOLEAN scoped = TRUE; if(opHeader->OpCode == EFI_IFR_SUBTITLE_OP) { EFI_IFR_OP_HEADER *nextOpHeader = (EFI_IFR_OP_HEADER *)((UINT8 *)opHeader + opHeader->Length); if(nextOpHeader->OpCode != EFI_IFR_END_OP) scoped = FALSE; } itr = 0; while(scoped) { opHdrPtr = (EFI_IFR_OP_HEADER*)((UINT8*)controlPtr + itr); switch(opHdrPtr->OpCode) { case EFI_IFR_READ_OP: case EFI_IFR_WRITE_OP: case EFI_IFR_MAP_OP: control_Info->ControlFlags.ControlRWEvaluate = 1; scoped = FALSE; break; case EFI_IFR_END_OP: if(scopeCount) { scopeCount--; } if (!scopeCount) //Check for sudden scopeCount from previous statement scoped = FALSE; break; } if(opHdrPtr->Scope) { scopeCount++; } itr += opHdrPtr->Length ; } } } if(defaults_size) { /* * control_Info[sizeof(CONTROL_INFO)] * Used when user selects load failsafe value */ /* * control_Info[sizeof(CONTROL_INFO) + valSize] * Used when user selects load optimal value */ /* //EIP: 56124 Storing the default information by using Memcopy MemCopy((UINT8 *)control_Info + sizeof(CONTROL_INFO), &ctrlFailSafe, defaults_size); MemCopy((UINT8 *)control_Info + sizeof(CONTROL_INFO)+ defaults_size, &ctrlOptimal, defaults_size); if(DefaultStoreCount) { index=0; while(index < DefaultStoreCount) { MemCopy((UINT8 *)control_Info+sizeof(CONTROL_INFO) + (defaults_size * 2)+ (index *(sizeof(UINT16) + defaults_size)), &defaultValue->DefaultId, sizeof(UINT16) ); MemCopy((UINT8 *)control_Info + sizeof(CONTROL_INFO) + (defaults_size * 2) + (index *(sizeof(UINT16) + defaults_size)) + sizeof(UINT16) , &defaultValue->Value, defaults_size ); defaultValue = defaultValue->Next; index++; } } */ Temp = defaultValue; switch(defaults_size) { case 1: // BYTE *((UINT8 *) ((UINT8 *)control_Info + sizeof(CONTROL_INFO))) = *((UINT8 *) ctrlFailSafe); *((UINT8 *) ((UINT8 *)control_Info + sizeof(CONTROL_INFO) + defaults_size)) = *((UINT8 *)ctrlOptimal); if(DefaultStoreCount) {//copy the defaults to the location in the control info index=0; while(index < DefaultStoreCount) { MemCopy((UINT8 *)control_Info+sizeof(CONTROL_INFO) + (defaults_size * 2)+ (index *(sizeof(UINT16) + defaults_size)), &Temp->DefaultId, sizeof(UINT16) ); *((UINT8 *) ( (UINT8 *)control_Info + sizeof(CONTROL_INFO)+(defaults_size * 2)+(index *(sizeof(UINT16) + defaults_size))+ sizeof(UINT16) )) = (UINT8 ) (Temp->Value); Temp = Temp->Next; index++; } } break; case 2: //WORD *((UINT16 *) ((UINT8 *)control_Info + sizeof(CONTROL_INFO))) = *((UINT16 *)ctrlFailSafe); *((UINT16 *) ((UINT8 *)control_Info + sizeof(CONTROL_INFO) + defaults_size)) = *((UINT16 *)ctrlOptimal); if(DefaultStoreCount) {//copy the defaults to the location in the control info index=0; while(index < DefaultStoreCount) { MemCopy((UINT8 *)control_Info+sizeof(CONTROL_INFO) + (defaults_size * 2)+ (index *(sizeof(UINT16) + defaults_size)), &Temp->DefaultId, sizeof(UINT16) ); *((UINT16 *) ( (UINT8 *)control_Info + sizeof(CONTROL_INFO)+(defaults_size * 2)+(index *(sizeof(UINT16) + defaults_size))+ sizeof(UINT16) ) )= (UINT16 ) (Temp->Value); Temp = Temp->Next; index++; } } break; case 4: //DWORD *((UINT32 *) ((UINT8 *)control_Info + sizeof(CONTROL_INFO))) = *((UINT32 *)ctrlFailSafe); *((UINT32 *) ((UINT8 *)control_Info + sizeof(CONTROL_INFO) + defaults_size)) = *((UINT32 *)ctrlOptimal); if(DefaultStoreCount) {//copy the defaults to the location in the control info index=0; while(index < DefaultStoreCount) { MemCopy((UINT8 *)control_Info+sizeof(CONTROL_INFO) + (defaults_size * 2)+ (index *(sizeof(UINT16) + defaults_size)), &Temp->DefaultId, sizeof(UINT16) ); *((UINT32 *) ( (UINT8 *)control_Info + sizeof(CONTROL_INFO)+(defaults_size * 2)+(index *(sizeof(UINT16) + defaults_size))+ sizeof(UINT16) )) = (UINT32) (Temp->Value); Temp = Temp->Next; index++; } } break; case 8: //QWORD *((UINT64 *) ((UINT8 *)control_Info + sizeof(CONTROL_INFO))) = *((UINT64 *)ctrlFailSafe); *((UINT64 *) ((UINT8 *)control_Info + sizeof(CONTROL_INFO) + defaults_size)) = *((UINT64 *)ctrlOptimal); if(DefaultStoreCount) {//copy the defaults to the location in the control info index=0; while(index < DefaultStoreCount) { MemCopy((UINT8 *)control_Info+sizeof(CONTROL_INFO) + (defaults_size * 2)+ (index *(sizeof(UINT16) + defaults_size)), &Temp->DefaultId, sizeof(UINT16) ); *((UINT64 *) ( (UINT8 *)control_Info + sizeof(CONTROL_INFO)+(defaults_size * 2)+(index *(sizeof(UINT16) + defaults_size))+ sizeof(UINT16) )) = (UINT64) (Temp->Value); Temp = Temp->Next; index++; } } break; default: // MemCopy the value equivalent to the default buffer size MemCopy( ((UINT8 *)control_Info + sizeof(CONTROL_INFO)) , (UINT8 *)ctrlFailSafe, defaults_size); MemCopy( ((UINT8 *)control_Info + sizeof(CONTROL_INFO) + defaults_size) , (UINT8 *)ctrlOptimal, defaults_size); break; } } //Create group event using Refresh Id GUID if ( control_Info->ControlFlags.RefreshID )//EIP-105468 { Status = CreateEventforIFR (control_Info); if (EFI_ERROR (Status)) { i = Size; goto DONE; } } //EIP-148837 /*if(IsRefreshIdSet) { ++gRefreshIdCount; //increament the refresh id control count NotifyContext = EfiLibAllocateZeroPool(sizeof(CONTROL_INFO)); if(NotifyContext == NULL) { i = Size; goto DONE; } MemCopy(NotifyContext, control_Info, sizeof(CONTROL_INFO)); gBS->CreateEventEx ( EFI_EVENT_NOTIFY_SIGNAL, EFI_TPL_CALLBACK, (EFI_EVENT_NOTIFY)RefreshGroupOnCallBack, (void*)NotifyContext, &RefreshEventGroupId, &RefreshIdEvent ); IsRefreshIdSet = FALSE; if(RefreshIdEvent == NULL) { i = Size; goto DONE; } //store the Event and Context for this control, to be freed on exiting the application. gRefreshIdInfo = MemReallocateZeroPool(gRefreshIdInfo, sizeof(REFRESH_ID_INFO)*(gRefreshIdCount-1), sizeof(REFRESH_ID_INFO)*gRefreshIdCount); if(gRefreshIdInfo == NULL) { i = Size; goto DONE; } gRefreshIdInfo[gRefreshIdCount-1].pEvent = RefreshIdEvent; gRefreshIdInfo[gRefreshIdCount-1].pNotifyContext = (UINT8*)NotifyContext; }*/ while(defaultValue != NULL) { Temp=defaultValue; defaultValue = defaultValue->Next; MemFreePointer(&Temp); } controlOffset = AddControlToList(control_Info, controlSize); CreatePage(NewPageInfo, AllocatedPageSize, PageOffset, &controlOffset, sizeof(UINT32)); MemFreePointer(&control_Info); if (controlType & ~CONTROL_TYPE_MASK) { controlOffset = 0; CreatePage(NewPageInfo, AllocatedPageSize, PageOffset, &controlOffset, sizeof(UINT32)); } } MemFreePointer (&ctrlFailSafe); MemFreePointer (&ctrlOptimal); j= opHeader->Length; if (opHeader->Scope && controlType && addControl) { UINT32 scopeCount = 0; BOOLEAN scoped = TRUE; if(opHeader->OpCode == EFI_IFR_SUBTITLE_OP) { EFI_IFR_OP_HEADER *nextOpHeader = (EFI_IFR_OP_HEADER *)((UINT8 *)opHeader + opHeader->Length); if(nextOpHeader->OpCode != EFI_IFR_END_OP) scoped = FALSE; } while(scoped) { switch(((EFI_IFR_OP_HEADER*)(buff + i + j))->OpCode) { case EFI_IFR_ONE_OF_OPTION_OP: //j += sizeof(EFI_IFR_ONE_OF_OPTION); //EIP71351 j += ((EFI_IFR_OP_HEADER*)(buff + i + j))->Length; //Aptio giving length as 0xe(matches size of EFI_IFR_ONE_OF_OPTION) but in latest EDKII driver it is 0x1c. break; case EFI_IFR_END_OP: if(scopeCount) { scopeCount--; j += ((EFI_IFR_OP_HEADER*)(buff + i + j))->Length; }else { scoped = FALSE; } break; default: if(((EFI_IFR_OP_HEADER*)(buff + i + j))->Scope) { scopeCount++; } j += ((EFI_IFR_OP_HEADER*)(buff + i + j))->Length; break; } // Increase Control Index to account above control and final EFI_IFR_END_OP controlIndex++; } } // // Add Inconsistant Control for Control that have INCONSISTANT_IF embedded within // their scope. Eg. BOOLEAN | DATE | NUMERIC | ORDERED_LIST | STRING | TIME // if(Inconsistant) { BOOLEAN BackupgConditionOverForm = FALSE; Inconsistant = FALSE; IsRecursive = TRUE; BackupgConditionOverForm = gConditionOverForm; //To have the current control as condptr. If saving condition over form as condptr then it will hang gConditionOverForm = FALSE; _AddHpkControls(Handle, buff + i + opHeader->Length, j - opHeader->Length, NewPageInfo, AllocatedPageSize, PageOffset); gConditionOverForm = BackupgConditionOverForm; IsRecursive = FALSE; } //EIP : NO_SUBMIT_IF if(NoSubmitIf) { BOOLEAN BackupgConditionOverForm = FALSE; NoSubmitIf = FALSE; IsRecursive = TRUE; BackupgConditionOverForm = gConditionOverForm; //To have the current control as condptr if has condition over form as condptr then it will hang gConditionOverForm = FALSE; _AddHpkControls(Handle, buff + i + opHeader->Length, j - opHeader->Length, NewPageInfo, AllocatedPageSize, PageOffset); gConditionOverForm = BackupgConditionOverForm; IsRecursive = FALSE; } i= i+ j; }; DONE: SETUP_DEBUG_UEFI("\n[TSE] Exiting _AddHpkControls\n"); return i; } // //---------------------------------------------------------------------------- // // Procedure: AddControlToList // // Description: // // Parameter: CONTROL_INFO *ControlInfo // UINT32 ControlSize // // Return value: EFI_STATUS // EFI_SUCCESS //---------------------------------------------------------------------------- // UINT32 AddControlToList(CONTROL_INFO *ControlInfo, UINT32 ControlSize) { // EFI_STATUS status = EFI_SUCCESS; UINT32 offset = 0; UINT32 u32Compensation = 0; SETUP_DEBUG_UEFI( "\n[TSE] Entering AddControlToList(), QuestionId: %d \n", ControlInfo->QuestionId ); #if TSE_DEBUG_MESSAGES if((gDbgPrint & PRINT_UEFI_PARSE)== PRINT_UEFI_PARSE) DebugShowControlInfo( ControlInfo->ControlPageID, ControlInfo) ; #endif if(gIFRChangeNotify) { offset = _AdvAddControlToList(ControlInfo, ControlSize); if(offset) { goto DONE; } } u32Compensation = (sizeof(UINT64) - (ControlSize % sizeof(UINT64))) % sizeof(UINT64); if((ControlListOffset + ControlSize + u32Compensation ) >= ControlListSize) { //Allocate 4k at a time gControlInfo = MemReallocateZeroPool( gControlInfo, ControlListSize, ControlListSize + 4096 ); /* if(gControlInfo == NULL) { status = EFI_OUT_OF_RESOURCES; offset = -1; goto DONE; } */ ControlListSize+=4096; } MemCopy((UINT8 *)gControlInfo + ControlListOffset, ControlInfo, ControlSize); offset = ControlListOffset; ControlListOffset += (ControlSize + u32Compensation); DONE: SETUP_DEBUG_UEFI( "\n[TSE] Exiting AddControlToList()\n"); return offset; } // //---------------------------------------------------------------------------- // // Procedure: AddPageIdToList // // Description: // // Parameter: PAGE_ID_INFO *NewPageIdInfo // // Return value: EFI_STATUS - // EFI_SUCCESS - // EFI_OUT_OF_RESOURCES - //---------------------------------------------------------------------------- // EFI_STATUS AddPageIdToList(PAGE_ID_INFO *NewPageIdInfo) { EFI_STATUS status = EFI_SUCCESS; UINT32 offset; UINT32 PageIdSize = sizeof(PAGE_ID_INFO); SETUP_DEBUG_UEFI( "\n[TSE] Entering AddPageIdToList(), PageClass: 0x%x, PageSubClass: 0x%x,\n", NewPageIdInfo->PageClass, NewPageIdInfo->PageSubClass); //@VgDebug if( PageIdInfoPtr == NULL ) PageIdInfoOffset = PageIdInfoSize = 0; //EIP-73396 Removed (PageIdSize=0) since size is 0 the first PageInfo will not copy to PageIdInfoPtr if(PageIdInfoOffset + PageIdSize >= PageIdInfoSize) { //Allocate 4k at a time PageIdInfoPtr = MemReallocateZeroPool( PageIdInfoPtr, PageIdInfoSize, PageIdInfoSize + 256 ); if(PageIdInfoPtr == NULL) { status = EFI_OUT_OF_RESOURCES; goto DONE; } PageIdInfoSize+=256; } MemCopy((UINT8 *)PageIdInfoPtr + PageIdInfoOffset, NewPageIdInfo, PageIdSize); offset = PageIdInfoOffset; PageIdInfoOffset += PageIdSize; if(!PageIdListPtr) { PageIdListSize = 128; PageIdListPtr = EfiLibAllocateZeroPool(PageIdListSize); if(PageIdListPtr == NULL) { status = EFI_OUT_OF_RESOURCES; goto DONE; } PageIdListPtr->PageIdList[PageIdListPtr->PageIdCount] = offset; PageIdListPtr->PageIdCount = 1; PageIdListOffset = sizeof(PAGE_ID_LIST); } else { if(PageIdListOffset + sizeof(UINT32) >= PageIdListSize) { PageIdListPtr = MemReallocateZeroPool(PageIdListPtr, PageIdListSize, PageIdListSize + 128); if(PageIdInfoPtr == NULL) { status = EFI_OUT_OF_RESOURCES; goto DONE; } PageIdListSize += 128; } PageIdListPtr->PageIdList[PageIdListPtr->PageIdCount] = offset; PageIdListPtr->PageIdCount++; PageIdListOffset += sizeof(UINT32); } DONE: SETUP_DEBUG_UEFI( "\n[TSE] Exiting AddPageIdToList(), status = 0x%x \n" , status ); return status; } // //---------------------------------------------------------------------------- // // Procedure: AddPageToList // // Description: // // Parameter: PAGE_INFO *NewPageInfo // UINT32 PageSize // // Return value: EFI_STATUS // EFI_SUCCESS //---------------------------------------------------------------------------- // EFI_STATUS AddPageToList(PAGE_INFO *NewPageInfo, UINT32 PageSize) { EFI_STATUS status = EFI_SUCCESS; UINT32 offset; UINT32 ReallocSize=4096; SETUP_DEBUG_UEFI( "\n[TSE] Entering AddPageToList(), PageFormID: %d \n", NewPageInfo->PageFormID ); #if TSE_DEBUG_MESSAGES if((gDbgPrint & PRINT_UEFI_PARSE)== PRINT_UEFI_PARSE) DebugShowPageInfo(NewPageInfo->PageFormID, NewPageInfo) ; #endif if(gIFRChangeNotify) { status = _AdvAddPageToList(NewPageInfo, PageSize); if(status == EFI_SUCCESS) { goto DONE; } status = EFI_SUCCESS;// EIP 88658 : Minisetup crashes after controller reconnection during Hii callback } if(PageInfoOffset + PageSize >= PageInfoSize) { if(ReallocSize < PageSize) ReallocSize = (PageSize & 0xFFFFF000) + 4096; PageInfoPtr = MemReallocateZeroPool( PageInfoPtr, PageInfoSize, PageInfoSize + ReallocSize ); //Allocate 4k at a time if(PageInfoPtr == NULL) { status = EFI_OUT_OF_RESOURCES; goto DONE; } PageInfoSize+=ReallocSize; } MemCopy((UINT8 *)PageInfoPtr + PageInfoOffset, NewPageInfo, PageSize); offset = PageInfoOffset; PageInfoOffset += PageSize; if(!PageListPtr) { PageListSize = 512; PageListPtr = EfiLibAllocateZeroPool(PageListSize); if(PageListPtr == NULL) { status = EFI_OUT_OF_RESOURCES; goto DONE; } /* Leave space for offset of Page 0 */ PageListPtr->PageCount = 1; PageListPtr->PageList[PageListPtr->PageCount] = offset; PageListPtr->PageCount++; PageListOffset = sizeof(PAGE_LIST)+sizeof(UINT32); } else { if(PageListOffset + sizeof(UINT32) >= PageListSize) { PageListPtr = MemReallocateZeroPool(PageListPtr, PageListSize, PageListSize + 128); if(PageListPtr == NULL) { status = EFI_OUT_OF_RESOURCES; goto DONE; } PageListSize += 128; } PageListPtr->PageList[PageListPtr->PageCount] = offset; PageListPtr->PageCount++; PageListOffset += sizeof(UINT32); } DONE: SETUP_DEBUG_UEFI( "\n[TSE] Exiting AddPageToList(), status = 0x%x \n" , status ) ; return status; } // //---------------------------------------------------------------------------- // // Procedure: AddVariableToList // // Description: // // Parameter: // // // Return value: EFI_STATUS // EFI_SUCCESS - // EFI_OUT_OF_RESOURCES - //---------------------------------------------------------------------------- // EFI_STATUS AddVariableToList(VARIABLE_INFO *NewVariableInfo) { EFI_STATUS status = EFI_SUCCESS; UINT32 offset; UINT32 VariableSize = sizeof(VARIABLE_INFO); SETUP_DEBUG_UEFI( "\n[TSE] Entering AddVariableToList(), VariableName: %s\n", NewVariableInfo->VariableName); if(VariableInfoOffset + VariableSize >= VariableInfoSize) { //Allocate 4k at a time VariableInfoPtr = MemReallocateZeroPool( VariableInfoPtr, VariableInfoSize, VariableInfoSize + 256 ); if(VariableInfoPtr == NULL) { status = EFI_OUT_OF_RESOURCES; goto DONE; } VariableInfoSize += 256; } MemCopy((UINT8 *)VariableInfoPtr + VariableInfoOffset, NewVariableInfo, VariableSize); offset = VariableInfoOffset; VariableInfoOffset += VariableSize; if(!VariableListPtr) { VariableListSize = 128; VariableListPtr = EfiLibAllocateZeroPool(VariableListSize); if(VariableListPtr == NULL) { status = EFI_OUT_OF_RESOURCES; goto DONE; } VariableListPtr->VariableList[VariableListPtr->VariableCount] = offset; VariableListPtr->VariableCount = 1; VariableListOffset = sizeof(VARIABLE_LIST); } else { if(VariableListOffset + sizeof(UINT32) >= VariableListSize) { VariableListPtr = MemReallocateZeroPool(VariableListPtr, VariableListSize, VariableListSize + 128); if(VariableListPtr == NULL) { status = EFI_OUT_OF_RESOURCES; goto DONE; } VariableListSize += 128; } VariableListPtr->VariableList[VariableListPtr->VariableCount] = offset; gnewCtrlVar = VariableListPtr->VariableCount; VariableListPtr->VariableCount++; // EIP : Display Error message variable exceeds Maximum variable supported in TSE if(VariableListPtr->VariableCount >= MAX_VARIABLE) { CHAR16 *Temp = L"Reached TSE Maximum supported variables"; _DisplayErrorMessage(Temp); ASSERT(0); } VariableListOffset += sizeof(UINT32); } DONE: SETUP_DEBUG_UEFI( "\n[TSE] Exiting AddVariableToList(), status = 0x%x \n" , status ); return status; } // //---------------------------------------------------------------------------- // // Procedure: CreatePage // // Description: // // Parameter: PAGE_INFO **PageInfo // UINT32 *AllocatedSize // UINT32 *Offset // VOID *Buff // UINT32 BuffSize // // Return value: EFI_STATUS // EFI_SUCCESS - // EFI_OUT_OF_RESOURCES - //---------------------------------------------------------------------------- // EFI_STATUS CreatePage(PAGE_INFO **PageInfo, UINT32 *AllocatedSize, UINT32 *Offset, VOID *Buff, UINT32 BuffSize) { EFI_STATUS status = EFI_SUCCESS; SETUP_DEBUG_UEFI( "\n[TSE] Entering CreatePage()\n"); if(!(*AllocatedSize)) { //creating a new page *PageInfo = EfiLibAllocateZeroPool(BuffSize); if(PageInfo == NULL) { status = EFI_OUT_OF_RESOURCES; goto DONE; } *AllocatedSize = BuffSize; MemCopy(*PageInfo, Buff, BuffSize); if((*PageInfo)->PageControls.ControlCount) *Offset = BuffSize; else //We have space to store one more offset //*Offset = BuffSize - sizeof((*PageInfo)->PageControls.ControlList[0]); *Offset = (UINT32)((UINTN)(&(*PageInfo)->PageControls.ControlList[0]) - (UINTN)(*PageInfo)); } else { //adding offsets if(*Offset + BuffSize >= *AllocatedSize) { //Allocate 128 bytes at a time *PageInfo = MemReallocateZeroPool( *PageInfo, *AllocatedSize, *AllocatedSize + 128 ); if(PageInfo == NULL) { status = EFI_OUT_OF_RESOURCES; goto DONE; } *AllocatedSize+=128; } MemCopy((UINT8 *)(*PageInfo) + *Offset, Buff, BuffSize); *Offset += BuffSize; (*PageInfo)->PageControls.ControlCount++; } DONE: SETUP_DEBUG_UEFI( "\n[TSE] Exiting CreatePage(), status = 0x%x \n" , status ); return status; } // //---------------------------------------------------------------------------- // // Procedure: ParseForm // // Description: Parse the HII Package for the Form Pack and parse the FormPack // // Parameter: IFRPackage - The Header of the Package to parse. // // Return value: EFI_STATUS - Return the Status of the Parsing //---------------------------------------------------------------------------- // EFI_STATUS ParseForm(SETUP_LINK *Setup_Link) { EFI_STATUS status = EFI_SUCCESS; EFI_HII_PACKAGE_HEADER *pkgHdr; EFI_IFR_FORM_SET *formSet = NULL; EFI_IFR_FORM *form = (EFI_IFR_FORM *)NULL; AMI_EFI_IFR_FORM_MAP_METHOD *formMapMethod = (AMI_EFI_IFR_FORM_MAP_METHOD *) NULL; AMI_EFI_IFR_FORM_MAP *formMap = (AMI_EFI_IFR_FORM_MAP *) NULL; EFI_IFR_GUID_CLASS *guidClassOp; EFI_IFR_GUID_SUBCLASS *guidSubClassOp; EFI_IFR_OP_HEADER *opHeader; EFI_GUID DriverHealthHiiGuid = EFI_HII_DRIVER_HEALTH_FORMSET_GUID; EFI_GUID CredentialHiiGuid = EFI_HII_USER_CREDENTIAL_FORMSET_GUID; extern EFI_GUID *gFSetGuid; UINT16 FormSetTitle = 0 ; UINT32 formOffset = 0, ifOverformCounter = 0; UINT8 Opcode = 0; CONTROL_INFO *control_Info; UINT8 opCode = 0; UINT16 extendOpCode = 0; UINT16 fsClass = 0; UINT16 fsSubClass = 0; UINT32 controlOffset = 0; UINT32 varIndex = 0; UINTN i = 0,formMapLength =0,formType = 0; UINTN jIndex = 0; PVAR_KEY_TABLE pVarTable; UINT32 allocatedPageSize = 0; PAGE_INFO *tmpPgInfo; UINT8 *ifrData = NULL; SETUP_DEBUG_UEFI ( "\n[TSE] Entering ParseForm()\n" ); pkgHdr = (EFI_HII_PACKAGE_HEADER*)Setup_Link->FormSet; if(pkgHdr->Type != EFI_HII_PACKAGE_FORMS) { status = EFI_UNSUPPORTED; goto DONE; } ifrData = ((UINT8 *)pkgHdr) + sizeof(EFI_HII_PACKAGE_HEADER); while(i < pkgHdr->Length) { opHeader = (EFI_IFR_OP_HEADER*)(ifrData + i); switch(opHeader->OpCode) { case EFI_IFR_SUPPRESS_IF_OP: case EFI_IFR_DISABLE_IF_OP: case EFI_IFR_GRAY_OUT_IF_OP: if(updateformcondvars == 1)//EIP-120418 Support suppressif,grayoutif, DisableIf over form { updateformcondvars = 0; gConditionOverForm = TRUE; gConditionalOverFormPtr = (void*)opHeader; } PushScope(opHeader->OpCode); ifOverformCounter++; break; case EFI_IFR_FORM_SET_OP: formSet = (EFI_IFR_FORM_SET*)opHeader; FormSetTitle = formSet->FormSetTitle; if ( !ShowClassGuidFormsets( (TSE_EFI_IFR_FORM_SET*)formSet) ) //EIP-139099 If ClassGuid is matches then continue parsing to display formset { FormSetTitle = 0;//Clear FormSetTitle i += (pkgHdr->Length - opHeader->Length); //Change i value to end of Pkg to skip parsing forms,etc,. status = EFI_ABORTED; gConditionOverForm = FALSE; updateformcondvars = 1; break; } if ( HideDynamicFormsets(&formSet->Guid) ) //EIP-95647 Suppressing formsets mentioned in elink AMITSE_SUPPRESS_DYNAMIC_FORMSET_LIST { FormSetTitle = 0; i += (pkgHdr->Length - opHeader->Length); status = EFI_ABORTED; gConditionOverForm = FALSE; updateformcondvars = 1; break; } PushScope(opHeader->OpCode); if(_IsVarGuidPresent(&formSet->Guid, &varIndex) == FALSE) { varIndex = _AddFormSetVariable(&formSet->Guid); } for(pVarTable = &VarKeyTable ; pVarTable->Next; pVarTable= pVarTable->Next) ; pVarTable->Next = EfiLibAllocateZeroPool(sizeof(VAR_KEY_TABLE)); if(pVarTable->Next == NULL) { status = EFI_OUT_OF_RESOURCES; goto DONE; } pVarTable = pVarTable->Next; pVarTable->VarId = 0; pVarTable->Index = (UINT16)varIndex; // create the pages lookup table _InitFormsetLinks((char*)ifrData, PageListPtr ? PageListPtr->PageCount:1); // add NULL control above submenu in main controlOffset = 0; CreatePage(&FirstPage, &AllocatedFirstPageSize, &FirstPageOffset, &controlOffset, sizeof(UINT32)); // add second null control for splitting the page in 2 halves if (TotalRootPages == 7) { controlOffset = 0; CreatePage(&FirstPage, &AllocatedFirstPageSize, &FirstPageOffset, &controlOffset, sizeof(UINT32)); } control_Info = (CONTROL_INFO*)EfiLibAllocateZeroPool(sizeof(CONTROL_INFO)); if(control_Info == NULL) { status = EFI_OUT_OF_RESOURCES; goto DONE; } // add the submenu control to main form that points to this form. control_Info->ControlHandle = Setup_Link->Handle; control_Info->ControlType = CONTROL_TYPE_SUBMENU; control_Info->ControlDestPageID = PageListPtr ? ((UINT16)PageListPtr->PageCount):1 ; control_Info->ControlFlags.ControlVisible = 1; if(!IsGroupDynamicPages()) //EIP: 59971 control_Info->ControlPtr = (VOID*)gFirstPageRef; /* What is this here for? controlInfo->ControlPtr = (UINTN)gSetupData[HiiIndex].FormSet + sizeof(EFI_HII_PACK_HEADER) + sizeof(EFI_IFR_FORM_SET) + TotalRootPages * sizeof(EFI_IFR_REF); */ controlOffset = AddControlToList(control_Info, sizeof(CONTROL_INFO)); CreatePage(&FirstPage, &AllocatedFirstPageSize, &FirstPageOffset, &controlOffset, sizeof(UINT32)); MemFreePointer(&control_Info); TotalRootPages++; break; case EFI_IFR_FORM_OP: case EFI_IFR_FORM_MAP_OP: if(opHeader->OpCode == EFI_IFR_FORM_OP) form = (EFI_IFR_FORM*)opHeader; else{ formMap =(AMI_EFI_IFR_FORM_MAP *)opHeader; formMapMethod =(AMI_EFI_IFR_FORM_MAP_METHOD *)((UINT8 *)formMap + sizeof(AMI_EFI_IFR_FORM_MAP)); formMapLength = sizeof(AMI_EFI_IFR_FORM_MAP); // // FormMap Form must contain at least one Map Method. // if (opHeader->Length < (formMapLength + sizeof(AMI_EFI_IFR_FORM_MAP_METHOD))) { return EFI_INVALID_PARAMETER; } // // Try to find the standard form map method. // while (formMapLength < opHeader->Length) { if (EfiCompareGuid((EFI_GUID *) (VOID *) &formMapMethod->MethodIdentifier, &StandardFormGuid)) { formType = 1; break; } formMapMethod ++; formMapLength+= sizeof(AMI_EFI_IFR_FORM_MAP_METHOD); } if(!formType) formMapMethod =(AMI_EFI_IFR_FORM_MAP_METHOD *)((UINT8 *)formMap + sizeof(AMI_EFI_IFR_FORM_MAP)); } tmpPgInfo = (PAGE_INFO*)EfiLibAllocateZeroPool(sizeof(PAGE_INFO)); if(tmpPgInfo == NULL) { status = EFI_OUT_OF_RESOURCES; goto DONE; } allocatedPageSize = PageOffset = 0; NewPageInfo = NULL; tmpPgInfo->PageFormID = (opHeader->OpCode == EFI_IFR_FORM_OP) ? form->FormId : formMap->FormId; tmpPgInfo->PageID = PageListPtr ? (UINT16) PageListPtr->PageCount : 1; tmpPgInfo->PageIdIndex = _GetPageIdIndex(&formSet->Guid, fsClass, fsSubClass); tmpPgInfo->PageHandle = Setup_Link->Handle; tmpPgInfo->PageParentID = PageListPtr ? _GetPageParent(PageListPtr->PageCount) : 0; tmpPgInfo->PageSubTitle = (opHeader->OpCode == EFI_IFR_FORM_OP) ? form->FormTitle :formMapMethod->MethodTitle; if(formType &&opHeader->OpCode == EFI_IFR_FORM_MAP_OP ){ tmpPgInfo->PageFlags.PageStdMap = 1; } else{ tmpPgInfo->PageFlags.PageStdMap = 0; } //tmpPgInfo->PageSubTitle = form->FormTitle; for (jIndex = 0; jIndex < gGuidDumpCount; jIndex ++) //EIP64253 Check for offline vfr's { if (EfiCompareGuid (&gGuidDump [jIndex], &formSet->Guid)) { break; } } if (jIndex == gGuidDumpCount) //EIP64253 If offline vfr dont hide it { //EIP 94424 : Some form can't normal display when add Hii item will in runtime during //EIP:68341 Support for displaying FormSet Title if (tmpPgInfo->PageParentID == 0) { tmpPgInfo->PageSubTitle = FormSetTitle ; } //Check for Dynamic Page Flag if (tmpPgInfo->PageParentID == 0 && IsGroupDynamicPages()) //PageParentID is 0 && SDL token is true { //then set as dynamic page // if (!EfiCompareGuid (&formSet->Guid, &DriverHealthHiiGuid) || (NULL != gSfHandles)) //EIP 57661 Not to show the form with EFI_HII_DRIVER_HEALTH_FORMSET_GUID // { if ((NULL == gSfHandles) && (!EfiCompareGuid (&formSet->Guid, &DriverHealthHiiGuid)) && (!EfiCompareGuid (&formSet->Guid, &CredentialHiiGuid)) ) { tmpPgInfo->PageFlags.PageDynamic = TRUE ; } if ((NULL == gSfHandles) && (EfiCompareGuid (&formSet->Guid, &DriverHealthHiiGuid))) //EIP174938 if driverhealth page we have to not consider it as dynamic page so returning aborted { //If not returning aborted then arrow will displayed status = EFI_ABORTED; } // } tmpPgInfo->PageFlags.PageVisible = TRUE; if ( tmpPgInfo->PageFlags.PageDynamic) //EIP-151552 Title is changing to MAIN and causing crashing while navigating from dynamic page to root page { tmpPgInfo->PageParentID = gDynamicParentPage; } } if( (tmpPgInfo->PageParentID == 0) && (NULL != gSfHandles)) { if ((NULL == gFSetGuid) && (!EfiCompareGuid (&formSet->Guid, &DriverHealthHiiGuid)) && (!EfiCompareGuid (&formSet->Guid, &CredentialHiiGuid)) ) { tmpPgInfo->PageFlags.PageVisible = FALSE; } else if ((NULL != gFSetGuid) && (EfiCompareGuid (&formSet->Guid, gFSetGuid))) { tmpPgInfo->PageFlags.PageVisible = FALSE; } else tmpPgInfo->PageFlags.PageVisible = TRUE; } } /* * Add tmpPgInfo to PageInfo and PageList Structures. * Memory for tmpPgInfo->PageControls.ControlList[0] * will be allocated later when adding controls */ CreatePage(&NewPageInfo, &allocatedPageSize, &PageOffset, tmpPgInfo, sizeof(PAGE_INFO)); MemFreePointer(&tmpPgInfo); i += _AddHpkControls(Setup_Link->Handle, (UINT8*)opHeader, pkgHdr->Length - i, &NewPageInfo, &allocatedPageSize, &PageOffset); AddPageToList(NewPageInfo, PageOffset); // EIP: Display Error message when Control count exceeds MAX_CONTROLS supported if(NewPageInfo->PageControls.ControlCount >= MAX_CONTROLS) { CHAR16 *Temp = L"Reached TSE Maximum supported Controls"; _DisplayErrorMessage(Temp); ASSERT(0); } MemFreePointer(&NewPageInfo); /* The Form Opcode Length is already added */ continue; case EFI_IFR_GUID_OP: extendOpCode = (UINT8)*((UINT8*)opHeader + sizeof(EFI_IFR_GUID)); switch(extendOpCode) { case EFI_IFR_EXTEND_OP_LABEL: //0x0 break; case EFI_IFR_EXTEND_OP_BANNER: //0x1 break; case EFI_IFR_EXTEND_OP_TIMEOUT: //0x2 break; case EFI_IFR_EXTEND_OP_CLASS: //0x3 guidClassOp = (EFI_IFR_GUID_CLASS*)opHeader; fsClass = guidClassOp->Class; break; case EFI_IFR_EXTEND_OP_SUBCLASS: //0x4 guidSubClassOp = (EFI_IFR_GUID_SUBCLASS*)opHeader; fsSubClass = guidSubClassOp->SubClass; break; default: break; } break; case EFI_IFR_VARSTORE_OP: // 0x24 case EFI_IFR_VARSTORE_NAME_VALUE_OP: //0x25 case EFI_IFR_VARSTORE_EFI_OP: // 0x26 _AddVariable((UINT8*)opHeader, Setup_Link->Handle); break; case EFI_IFR_DEFAULTSTORE_OP: break; case EFI_IFR_END_OP: PopScope(&opCode); if(EFI_IFR_SUPPRESS_IF_OP == opCode || EFI_IFR_GRAY_OUT_IF_OP == opCode || EFI_IFR_DISABLE_IF_OP == opCode) { --ifOverformCounter;//Resetting flags gConditionOverForm = FALSE; updateformcondvars = 1; } if(opCode == EFI_IFR_FORM_SET_OP) { if(FSetLinks !=NULL) { MemFreePointer(&FSetLinks); FSetLinks = NULL; } i += sizeof(EFI_HII_PACKAGE_HEADER); } // To match the Scoping. Don't abort the parsing. // Suppressif in the Form level need to be supported. /* else0 { status = EFI_ABORTED; goto DONE; } */ break; default: if(opHeader->Scope) PushScope(opHeader->OpCode); break; } i += opHeader->Length; } _CleanVarKeyTable(); Setup_Link->Added = 1; DONE: SETUP_DEBUG_UEFI ("\n[TSE] Exiting ParseForm(), status = 0x%x \n" , status ); return status; } // //--------------------------------------------------------------------------- // Procedure: _AdvAddControlToList // // Description: Add control info the control list // // Input: CONTROL_INFO *ControlInfo - Pointer to the CONTROL_INFO // UINT32 ControlSize - Size the control info // // Output: UINT32 offset - Return the control list offset //--------------------------------------------------------------------------- // UINT32 _AdvAddControlToList(CONTROL_INFO *ControlInfo, UINT32 ControlSize) { CONTROL_INFO *ctrlInfo = (CONTROL_INFO*)gControlInfo; UINT32 ctrlSize = 0; UINT32 offset = 0; UINT32 u32Compensation = 0; UINT32 ctrlListOffset = 0; SETUP_DEBUG_UEFI( "\n[TSE] Entering _AdvAddControlToList()\n"); do { if(ctrlInfo == NULL) { break; //If ctrlInfo is invalid } if(ctrlListOffset == ControlListOffset) { break; } //ctrlSize = sizeof(CONTROL_INFO) + ctrlInfo->ControlDataWidth * 2; ctrlSize = sizeof(CONTROL_INFO) + (2* ctrlInfo->ControlDataWidth) + (ctrlInfo->DefaultStoreCount * (sizeof(UINT16)+ctrlInfo->ControlDataWidth)); if(ctrlInfo->ControlHandle == NULL && ctrlSize == ControlSize) { // Add the Control MemCopy(ctrlInfo, ControlInfo, ControlSize); offset = ctrlListOffset; break; } // Skip to the Next Control in gControl u32Compensation = (sizeof(UINT64) - (ctrlSize % sizeof(UINT64))) % sizeof(UINT64); ctrlListOffset += (ctrlSize + u32Compensation); ctrlInfo = (CONTROL_INFO *)((UINT8 *)ctrlInfo + ctrlSize + u32Compensation); }while(TRUE); SETUP_DEBUG_UEFI( "\n[TSE] Exiting _AdvAddControlToList()\n"); return offset; } VOID UpdateCtrlDestPageID(VOID * Handle, UINT16 NewPageID) { UINT32 page = PARSE_START_INDEX; UINT32 control = 0; for(;page < PageListPtr->PageCount; page++) { PAGE_INFO *pgInfo = (PAGE_INFO *)((UINT8 *)PageInfoPtr + PageListPtr->PageList[page]); if(pgInfo->PageHandle == Handle) { for(control = 0;control < pgInfo->PageControls.ControlCount; control++) { CONTROL_INFO *controlInfo = NULL; controlInfo = (CONTROL_INFO*)((UINT8 *)gControlInfo + pgInfo->PageControls.ControlList[control]); if((NewPageID < controlInfo->ControlDestPageID) && (controlInfo->ControlDestPageID != 0xFFFF)) { controlInfo->ControlDestPageID--; } } } } } // //--------------------------------------------------------------------------- // Procedure: _AdvAddPageToList // // Description: Add page into to the page list // // Input: PAGE_INFO *NewPageInfo - Pointer to new page info structure // UINT32 PageSize - Page into size // // Output: EFI_STATUS status - EFI_SUCCESS if successful, else EFI_ERROR //--------------------------------------------------------------------------- // EFI_STATUS _AdvAddPageToList(PAGE_INFO *NewPageInfo, UINT32 PageSize) { EFI_STATUS status = EFI_SUCCESS; UINT32 ii = 0; UINT16 pageNo=0; SETUP_DEBUG_UEFI( "\n[TSE] Entering _AdvAddPageToList()\n"); for(ii = PARSE_START_INDEX; ii < PageListPtr->PageCount; ii++) { PAGE_INFO *pageInfo = (PAGE_INFO *)((UINT8 *)PageInfoPtr + PageListPtr->PageList[ii]); if(pageInfo->PageHandle == (VOID *)(UINTN)0xFFFF) { if(pageInfo->PageFormID == NewPageInfo->PageFormID) { if(pageInfo->PageControls.ControlCount == NewPageInfo->PageControls.ControlCount) { pageNo = NewPageInfo->PageID; pageInfo->PageHandle = NewPageInfo->PageHandle; //EIP-80424 // Updated in old page location itself status = _ReplacePageWithNewPage(pageInfo, NewPageInfo, PageSize); }else { status = _InvalidateExistingPage(pageInfo, NewPageInfo); status = EFI_UNSUPPORTED; } break; } } } if(pageNo) { // Search in FSetLink for the Page and update PageID and ParentPageID for(ii = 0; ii < FSetLinks->PageCount; ii++) { if(FSetLinks->PageLink[ii].FormID != NewPageInfo->PageFormID) { if(FSetLinks->PageLink[ii].ParentPageID == pageNo) { FSetLinks->PageLink[ii].ParentPageID = NewPageInfo->PageID; } if(FSetLinks->PageLink[ii].PageNum > pageNo) { FSetLinks->PageLink[ii].PageNum--; } } else { //FSetLinks->PageLink[ii].ParentPageID = NewPageInfo->PageParentID; FSetLinks->PageLink[ii].PageNum = NewPageInfo->PageID; } if(FSetLinks->PageLink[ii].ParentPageID > pageNo) FSetLinks->PageLink[ii].ParentPageID--; } for(ii = PARSE_START_INDEX; ii < PageListPtr->PageCount; ii++) { PAGE_INFO *pageInfo = (PAGE_INFO *)((UINT8 *)PageInfoPtr + PageListPtr->PageList[ii]); if(pageInfo->PageHandle == NewPageInfo->PageHandle) { if(pageInfo->PageParentID == pageNo) pageInfo->PageParentID = NewPageInfo->PageID; if(pageInfo->PageParentID > pageNo) pageInfo->PageParentID--; } } UpdateCtrlDestPageID(NewPageInfo->PageHandle, pageNo); } SETUP_DEBUG_UEFI( "\n[TSE] Exiting _AdvAddPageToList(), status = 0x%x \n" , status ); return status; } // //---------------------------------------------------------------------------- // // Procedure: _ReplacePageWithNewPage // // Description: // // Parameter: // // Return value: //---------------------------------------------------------------------------- // EFI_STATUS _ReplacePageWithNewPage(PAGE_INFO *OldPageInfo, PAGE_INFO *NewPageInfo, UINT32 PageSize) { EFI_STATUS status = EFI_SUCCESS; UINT32 page = PARSE_START_INDEX; UINT32 control = 0; SETUP_DEBUG_UEFI( "\n[TSE] Entering _ReplacePageWithNewPage()\n"); // Go thru NewPageInfo CtrlList and update Control PageId for(;control < NewPageInfo->PageControls.ControlCount; control++) { CONTROL_INFO *controlInfo = NULL; controlInfo = (CONTROL_INFO *)((UINTN)gControlInfo + NewPageInfo->PageControls.ControlList[control]); // Update the ControlDestPageID if it pointing to the same page. if(controlInfo->ControlDestPageID == controlInfo->ControlPageID) controlInfo->ControlDestPageID = OldPageInfo->PageID; controlInfo->ControlPageID = OldPageInfo->PageID; } // Go thru all PageList with the same Handle as NewPageInfo and // Go thru their CtrlList and Update any destination PageID that // refers this page for(;page < PageListPtr->PageCount; page++) { PAGE_INFO *pgInfo = (PAGE_INFO *)((UINT8 *)PageInfoPtr + PageListPtr->PageList[page]); if(pgInfo->PageHandle == NewPageInfo->PageHandle) { for(control = 0;control < pgInfo->PageControls.ControlCount; control++) { CONTROL_INFO *controlInfo = NULL; controlInfo = (CONTROL_INFO*)((UINT8 *)gControlInfo + pgInfo->PageControls.ControlList[control]); if(_GetPageNumFromFormID(NewPageInfo->PageFormID) == controlInfo->ControlDestPageID) { controlInfo->ControlDestPageID = OldPageInfo->PageID; } } if(pgInfo->PageParentID == NewPageInfo->PageID) pgInfo->PageParentID = OldPageInfo->PageID; } } // Update NewPageInfo PageId and ParentPageId NewPageInfo->PageID = OldPageInfo->PageID; // NewPageInfo->PageParentID = OldPageInfo->PageParentID; // Copy NewPageInfo to pageInfo MemCopy(OldPageInfo, NewPageInfo, PageSize); SETUP_DEBUG_UEFI( "\n[TSE] Exiting _ReplacePageWithNewPage(), status = 0x%x \n" , status ); return status; } // //---------------------------------------------------------------------------- // // Procedure: _InvalidateExistingPage // // Description: // // Parameter: // // Return value: //---------------------------------------------------------------------------- // EFI_STATUS _InvalidateExistingPage(PAGE_INFO *OldPageInfo, PAGE_INFO *NewPageInfo) { EFI_STATUS status = EFI_SUCCESS; UINT32 page = 0; SETUP_DEBUG_UEFI( "\n[TSE] Entering _InvalidateExistingPage()\n"); // Search thru gPages for pages with Controls with destination page // that refer OldPage and change them to point to NewPage for(page = PARSE_START_INDEX; page < PageListPtr->PageCount; page++) { UINT32 control = 0; PAGE_INFO *pgInfo = (PAGE_INFO *)((UINTN)PageInfoPtr + PageListPtr->PageList[page]); if(pgInfo->PageHandle == NewPageInfo->PageHandle) { for(control = 0; control < pgInfo->PageControls.ControlCount; control++) { CONTROL_INFO *controlInfo = NULL; controlInfo = (CONTROL_INFO *)((UINTN)gControlInfo + pgInfo->PageControls.ControlList[control]); if(controlInfo->ControlDestPageID == _GetPageNumFromFormID(NewPageInfo->PageFormID)) { controlInfo->ControlDestPageID = NewPageInfo->PageID; } } } } //EIP: 108987 May cause circular page reference. //NewPageInfo->PageParentID = OldPageInfo->PageParentID; SETUP_DEBUG_UEFI( "\n[TSE] Exiting _InvalidateExistingPage(), status = 0x%x \n" , status ) ; return status; } // //---------------------------------------------------------------------------- // // Procedure: RefreshGroupOnCallBack // // Description: Callback function which refreshes Controls of a Group which are // set with refresh Id // // Parameter: EFI_EVENT Event, VOID *Context // // Return value: //---------------------------------------------------------------------------- // VOID RefreshGroupOnCallBack(EFI_EVENT Event, VOID *Context) { EFI_STATUS Status = EFI_SUCCESS; CONTROL_INFO *control_Info; UINT16 Key; control_Info = (CONTROL_INFO*)Context; Key = UefiGetControlKey (control_Info); //refresh the control Status = UefiRefershQuestionValueNvRAM (control_Info); if (UefiIsInteractive (control_Info)) { UefiPreControlUpdate (control_Info); Status = CallFormCallBack (control_Info, Key, 0, AMI_CALLBACK_CONTROL_UPDATE);//EIP-53480: Updated the action to AMI_CALLBACK_CONTROL_UPDATE } //check if the control is in the current page, and redraw only then. if((Status == EFI_SUCCESS) && (control_Info->ControlPageID == gApp->CurrentPage)) { gApp->CompleteRedraw = TRUE; } } //EIP-105468 Starts // //---------------------------------------------------------------------------- // // Procedure: CreateEventforIFR // // Description: To create Event if any control has RefreshID opcode // // // Parameter: CONTROL_INFO* // // Return value: EFI_STATUS //---------------------------------------------------------------------------- // //#define EFI_REFRESH_ID_GUID { 0x68a6632a, 0x5120, 0x45c3, 0x9b, 0x8e, 0xfc, 0xbf, 0x8c, 0xa0, 0xe7, 0x2e } EFI_STATUS CreateEventforIFR (CONTROL_INFO *control_Info ) { EFI_STATUS Status = EFI_SUCCESS; CONTROL_INFO *NotifyContext = (CONTROL_INFO*)NULL; EFI_EVENT RefreshIdEvent = (EFI_EVENT)NULL; UINTN i = 0; //EFI_GUID RefreshIDGuid = EFI_REFRESH_ID_GUID; //MemCopy( &RefreshEventGroupId, &RefreshIDGuid, sizeof(EFI_GUID) ); // MemCopy( &RefreshEventGroupId, &(((AMI_EFI_IFR_REFRESH_ID *)control_Info->ControlPtr)->RefreshEventGroupId), sizeof(EFI_GUID) ); //Create group event using Refresh Id GUID ++gRefreshIdCount; //increament the refresh id control count NotifyContext = EfiLibAllocateZeroPool(sizeof(CONTROL_INFO)); if(NotifyContext == NULL) { Status = EFI_OUT_OF_RESOURCES; goto DONE; } MemCopy(NotifyContext, control_Info, sizeof(CONTROL_INFO)); gBS->CreateEventEx ( EFI_EVENT_NOTIFY_SIGNAL, EFI_TPL_CALLBACK, (EFI_EVENT_NOTIFY)RefreshGroupOnCallBack, (void*)NotifyContext, &RefreshEventGroupId, &RefreshIdEvent ); if(RefreshIdEvent == NULL) { Status = EFI_UNSUPPORTED; goto DONE; } //store the Event and Context for this control, to be freed on exiting the application. gRefreshIdInfo = MemReallocateZeroPool(gRefreshIdInfo, sizeof(REFRESH_ID_INFO)*(gRefreshIdCount-1), sizeof(REFRESH_ID_INFO)*gRefreshIdCount); if(gRefreshIdInfo == NULL) { Status = EFI_OUT_OF_RESOURCES; goto DONE; } gRefreshIdInfo[gRefreshIdCount-1].pEvent = RefreshIdEvent; gRefreshIdInfo[gRefreshIdCount-1].pNotifyContext = (UINT8*)NotifyContext; DONE: return Status; } //********************************************************************** //********************************************************************** //** ** //** (C)Copyright 1985-2014, American Megatrends, Inc. ** //** ** //** All Rights Reserved. ** //** ** //** 5555 Oakbrook Pkwy, Building 200,Norcross, Georgia 30093 ** //** ** //** Phone: (770)-246-8600 ** //** ** //********************************************************************** //**********************************************************************