summaryrefslogtreecommitdiff
path: root/EDK/MiniSetup/uefi2.1/Parse.c
diff options
context:
space:
mode:
Diffstat (limited to 'EDK/MiniSetup/uefi2.1/Parse.c')
-rw-r--r--EDK/MiniSetup/uefi2.1/Parse.c4700
1 files changed, 4700 insertions, 0 deletions
diff --git a/EDK/MiniSetup/uefi2.1/Parse.c b/EDK/MiniSetup/uefi2.1/Parse.c
new file mode 100644
index 0000000..31579d1
--- /dev/null
+++ b/EDK/MiniSetup/uefi2.1/Parse.c
@@ -0,0 +1,4700 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (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
+//
+//*************************************************************************
+//<AMI_FHDR_START>
+//
+// Name: Parse.c
+//
+// Description:
+//
+//<AMI_FHDR_END>
+//*************************************************************************
+
+//---------------------------------------------------------------------------
+
+#include "Minisetup.h"
+#include "TseUefiHii.h"
+
+#define PARSE_START_INDEX 1
+//---------------------------------------------------------------------------
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: PageLink
+//
+// Description:
+//
+// Fields: Name Type Description
+//----------------------------------------------------------------------------
+// FormID UINT16
+// ParentPageID UINT16
+// PageNum UINT16
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+typedef struct PAGELINK
+{
+ UINT16 FormID; // number from hpk
+ UINT16 ParentPageID; // number from the tool
+ UINT16 PageNum; // number assigned by the tool
+}PageLink;
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: FormSetLinks
+//
+// Description:
+//
+// Fields: Name Type Description
+//----------------------------------------------------------------------------
+// PageCount UINT16
+// PageLink[20] PageLink
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+typedef struct FORMSETLINKS
+{
+ UINT16 PageCount;
+ PageLink PageLink[20];
+}FormSetLinks;
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// 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
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+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
+
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: _AddFormSetVariable
+//
+// Description:
+//
+// Parameter:
+//
+// Return value:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+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;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: _CleanVarKeyTable
+//
+// Description: Clean VarKey Table
+//
+// Parameter: None
+//
+// Return value: None
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID _CleanVarKeyTable()
+{
+ PVAR_KEY_TABLE pVarTable = VarKeyTable.Next;
+
+ while(pVarTable)
+ {
+ VarKeyTable.Next = pVarTable->Next;
+ MemFreePointer(&pVarTable);
+ pVarTable = VarKeyTable.Next;
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: _GetControlKeyToken
+//
+// Description: Get ControlKey Token
+//
+// Parameter: None
+//
+// Return value: None
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+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;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: _GetControlDevicePathId
+//
+// Description: Get Control DevicePathId
+//
+// Parameter:
+//
+// Return value: UINT16
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+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;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// 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
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+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;
+ }
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: _GetHelpToken
+//
+// Description: Get Control Question Help Token
+//
+// Parameter:
+//
+// Return value: UINT16
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+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;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: _GetPageIdIndex
+//
+// Description: Get Page ID index
+//
+// Parameter:
+//
+// Return value: UINT16
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+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;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: _GetPageNumFromFormID
+//
+// Description: Get Page Id from Form Id
+//
+// Parameter:
+//
+// Return value: UINT16
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+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;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: _GetPageParent
+//
+// Description: Get Parent Page PageID
+//
+// Parameter:
+//
+// Return value: UINT16
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+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;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: _GetQuestionToken
+//
+// Description: Get Control Question Prompt
+//
+// Parameter:
+//
+// Return value: UINT16
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+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;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: _GetSubFormCount
+//
+// Description: Count the subform and Ref inside the formset
+//
+// Parameter:
+//
+// Return value: UINTN
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+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;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: _GetVarNumFromVarID
+//
+// Description: Get Variable Index
+//
+// Parameter:
+//
+// Return value: UINT32
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+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;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: _InitFormsetLinks
+//
+// Description: Init Formset Links
+//
+// Parameter:
+//
+// Return value:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+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;j<FSetLinks->PageCount;j++)
+ {
+ if(FSetLinks->PageLink[j].FormID == RootPageinFormSet)
+ {
+ RootPageID = FSetLinks->PageLink[j].PageNum;
+ break;
+ }
+ }
+
+ _PageIdList = EfiLibAllocateZeroPool(FSetLinks->PageCount*sizeof(UINT16));
+ for(j=0;j<FSetLinks->PageCount;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(k<FSetLinks->PageCount)
+ {
+ 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;n<FSetLinks->PageCount;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;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: _IsVarGuidPresent
+//
+// Description: Check if the Variable Guid is already defined
+//
+// Parameter:
+//
+// Return value: UINT8
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+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;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// 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
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+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
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: GetValueFromOpCode
+//
+// Description: Gets the value from the opcode
+//
+// Parameter: EFI_IFR_OP_HEADER *,
+// EFI_HII_VALUE *,
+// INTN
+//
+// Return value: VOID
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+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;
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: EvaluateReadWrite
+//
+// Description: Evaluates read write conditions
+//
+// Parameter: UINT8 *,
+// CONTROL_INFO *,
+// EFI_HII_VALUE *
+//
+// Return value: VOID
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+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));
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: _AddHpkControls
+//
+// Description: Add Control Setup Data
+//
+// Parameter:
+//
+// Return value: UINTN
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+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;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: AddControlToList
+//
+// Description:
+//
+// Parameter: CONTROL_INFO *ControlInfo
+// UINT32 ControlSize
+//
+// Return value: EFI_STATUS
+// EFI_SUCCESS
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+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;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: AddPageIdToList
+//
+// Description:
+//
+// Parameter: PAGE_ID_INFO *NewPageIdInfo
+//
+// Return value: EFI_STATUS -
+// EFI_SUCCESS -
+// EFI_OUT_OF_RESOURCES -
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+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;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: AddPageToList
+//
+// Description:
+//
+// Parameter: PAGE_INFO *NewPageInfo
+// UINT32 PageSize
+//
+// Return value: EFI_STATUS
+// EFI_SUCCESS
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+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;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: AddVariableToList
+//
+// Description:
+//
+// Parameter:
+//
+//
+// Return value: EFI_STATUS
+// EFI_SUCCESS -
+// EFI_OUT_OF_RESOURCES -
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+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;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// 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 -
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+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;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// 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
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+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;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+// 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
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+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--;
+ }
+ }
+ }
+ }
+
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+// 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
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+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;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: _ReplacePageWithNewPage
+//
+// Description:
+//
+// Parameter:
+//
+// Return value:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+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;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: _InvalidateExistingPage
+//
+// Description:
+//
+// Parameter:
+//
+// Return value:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+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;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// 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:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+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
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: CreateEventforIFR
+//
+// Description: To create Event if any control has RefreshID opcode
+//
+//
+// Parameter: CONTROL_INFO*
+//
+// Return value: EFI_STATUS
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+//#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 **
+//** **
+//**********************************************************************
+//**********************************************************************