+++ /dev/null
-/** @file\r
-Implement Functions to convert IFR Opcode in format defined in Framework HII specification to\r
-format defined in UEFI HII Specification.\r
-\r
-Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.<BR>\r
-This program and the accompanying materials\r
-are licensed and made available under the terms and conditions of the BSD License\r
-which accompanies this distribution. The full text of the license may be found at\r
-http://opensource.org/licenses/bsd-license.php\r
-\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-\r
-**/\r
-\r
-#include "HiiDatabase.h"\r
-#include "UefiIfrDefault.h"\r
-\r
-/**\r
- The dynamic creation of these opcodes is supported in Framework HII modules.\r
- Therefore, Framework HII Thunk module only map these opcode between Framework\r
- HII's definitions to UEFI HII's.\r
-**/\r
-typedef struct { \r
- UINT8 FrameworkIfrOp;\r
- UINT8 UefiIfrOp;\r
-} IFR_OPCODE_MAP;\r
- \r
-IFR_OPCODE_MAP QuestionOpcodeMap[] = {\r
- { FRAMEWORK_EFI_IFR_ONE_OF_OP, EFI_IFR_ONE_OF_OP},\r
- { FRAMEWORK_EFI_IFR_CHECKBOX_OP, EFI_IFR_CHECKBOX_OP},\r
- { FRAMEWORK_EFI_IFR_NUMERIC_OP, EFI_IFR_NUMERIC_OP},\r
- { FRAMEWORK_EFI_IFR_ONE_OF_OPTION_OP, EFI_IFR_ONE_OF_OPTION_OP},\r
- { FRAMEWORK_EFI_IFR_ORDERED_LIST_OP, EFI_IFR_ORDERED_LIST_OP}\r
-};\r
-\r
-/**\r
- Translate a Framework Question Opcode to UEFI Question Opcode.\r
-\r
- @param FwOp Framework Opcode.\r
- @param UefiOp UEFI Opcode.\r
-\r
- @retval EFI_SUCCESS The UEFI opcode is found and returned.\r
- @retval EFI_NOT_FOUND The UEFI opcode is not found.\r
-**/\r
-EFI_STATUS\r
-QuestionOpFwToUefi (\r
- IN UINT8 FwOp,\r
- OUT UINT8 *UefiOp\r
- )\r
-{\r
- UINTN Index;\r
-\r
- for (Index = 0; Index < ARRAY_SIZE (QuestionOpcodeMap); Index++) {\r
- if (FwOp == QuestionOpcodeMap[Index].FrameworkIfrOp) {\r
- *UefiOp = QuestionOpcodeMap[Index].UefiIfrOp;\r
- return EFI_SUCCESS;\r
- }\r
- }\r
-\r
- *UefiOp = (UINT8) (EFI_IFR_LAST_OPCODE + 1);\r
- return EFI_NOT_FOUND;\r
-}\r
-\r
-/**\r
- Translate a Framework Question ID to UEFI Question ID.\r
-\r
- @param FormSet FormSet context\r
- @param FwOpCode Framework Opcode\r
- @param FwQId Framework Question Id\r
- @param UefiQId UEFI Question ID.\r
-\r
- @retval EFI_SUCCESS The UEFI Question Id is found and returned.\r
- @retval EFI_NOT_FOUND The UEFI Question Id is not found.\r
-**/\r
-EFI_STATUS\r
-FwQIdToUefiQId (\r
- IN CONST FORM_BROWSER_FORMSET *FormSet,\r
- IN UINT8 FwOpCode,\r
- IN UINT16 FwQId,\r
- OUT UINT16 *UefiQId\r
- )\r
-{\r
- LIST_ENTRY *FormList;\r
- LIST_ENTRY *StatementList;\r
- FORM_BROWSER_FORM *Form;\r
- FORM_BROWSER_STATEMENT *Statement;\r
- FORM_BROWSER_STATEMENT *StatementFound;\r
- EFI_STATUS Status;\r
- UINT8 UefiOp;\r
- \r
-\r
- *UefiQId = 0;\r
- StatementFound = NULL;\r
-\r
- FormList = GetFirstNode (&FormSet->FormListHead);\r
-\r
- while (!IsNull (&FormSet->FormListHead, FormList)) {\r
- Form = FORM_BROWSER_FORM_FROM_LINK (FormList);\r
-\r
- StatementList = GetFirstNode (&Form->StatementListHead);\r
-\r
- while (!IsNull (&Form->StatementListHead, StatementList)) {\r
- Statement = FORM_BROWSER_STATEMENT_FROM_LINK (StatementList);\r
- if (Statement->VarStoreId != 0 && Statement->Storage->Type == EFI_HII_VARSTORE_BUFFER) {\r
- if (FwQId == Statement->VarStoreInfo.VarOffset) {\r
- Status = QuestionOpFwToUefi (FwOpCode, &UefiOp);\r
- ASSERT_EFI_ERROR (Status);\r
-\r
- if ((UefiOp == Statement->Operand) && (FormSet->DefaultVarStoreId == Statement->VarStoreId)) {\r
- //\r
- // If ASSERT here, the Framework VFR file has two Questions with all three attibutes the same:\r
- // 1) Same Question Type, \r
- // 2) Same Variable Storage\r
- // 3) Refering to the Same offset in Variable Map (NvMap). \r
- // This is ambigurity as FwQIdToUefiQId () can't find which UEFI Question \r
- // ID to return. \r
- //\r
- // One possible solution is to remove the one of the duplicated questions in this Form Set.\r
- //\r
- ASSERT (StatementFound == NULL);\r
- StatementFound= Statement;\r
-\r
- //\r
- // Continue the search to check if the Form Set contains more than one questins that has the 3 attributes\r
- // with same value.\r
- //\r
- }\r
- }\r
- }\r
-\r
- StatementList = GetNextNode (&Form->StatementListHead, StatementList);\r
- }\r
-\r
- FormList = GetNextNode (&FormSet->FormListHead, FormList);\r
- }\r
-\r
- if (StatementFound != NULL) {\r
- *UefiQId = StatementFound->QuestionId;\r
- return EFI_SUCCESS;\r
- }\r
- \r
- return EFI_NOT_FOUND;\r
-}\r
-\r
-/**\r
- Assign a Question ID.\r
-\r
- If FwQuestionId is 0, then assign a new question ID. The new question ID\r
- is MaxQuestionId incremented by 1. The MaxQuestionId of FormSet is also\r
- incremented by 1.\r
-\r
- If FwQuestionId is not 0, then it is used as the Framework Question ID.\r
-\r
- @param FwQuestionId \r
- @param FormSet \r
-\r
- @return The Framework Question ID.\r
-**/\r
-EFI_QUESTION_ID\r
-AssignQuestionId (\r
- IN UINT16 FwQuestionId,\r
- IN FORM_BROWSER_FORMSET *FormSet\r
- )\r
-{\r
- if (FwQuestionId == 0) {\r
- FormSet->MaxQuestionId++;\r
- return FormSet->MaxQuestionId;\r
- } else {\r
- return FwQuestionId;\r
- }\r
-}\r
-\r
-/**\r
- Create UEFI HII Text Opcode from a Framework HII Text Opcode.\r
-\r
- @param UefiUpdateDataHandle The newly created UEFI HII opcode is appended to UefiUpdateDataHandle.\r
- @param FwOpcode The input Framework Opcode.\r
-\r
- @retval NULL There is not enough space left in Buffer to add the opcode.\r
- @retval Other A pointer to the created opcode.\r
- \r
-**/\r
-UINT8 *\r
-F2UCreateTextOpCode (\r
- IN OUT VOID *UefiUpdateDataHandle,\r
- IN CONST FRAMEWORK_EFI_IFR_TEXT *FwOpcode\r
- )\r
-{\r
- EFI_IFR_TEXT UTextOpCode;\r
-\r
- if ((FwOpcode->Flags & EFI_IFR_FLAG_INTERACTIVE) == 0) {\r
- ZeroMem (&UTextOpCode, sizeof(UTextOpCode));\r
- \r
- UTextOpCode.Header.OpCode = EFI_IFR_TEXT_OP;\r
- UTextOpCode.Header.Length = (UINT8) sizeof (EFI_IFR_TEXT);\r
-\r
- UTextOpCode.Statement.Help = FwOpcode->Help;\r
-\r
- UTextOpCode.Statement.Prompt = FwOpcode->Text;\r
- UTextOpCode.TextTwo = FwOpcode->TextTwo;\r
- \r
- return HiiCreateRawOpCodes (UefiUpdateDataHandle, (UINT8 *) &UTextOpCode, sizeof(UTextOpCode));\r
- } else {\r
- //\r
- // Iteractive Text Opcode is EFI_IFR_ACTION\r
- //\r
- return HiiCreateActionOpCode (UefiUpdateDataHandle, FwOpcode->Key, FwOpcode->Text, FwOpcode->Help, EFI_IFR_FLAG_CALLBACK, 0);\r
- }\r
-}\r
-\r
-/**\r
- Create UEFI HII Reference Opcode from a Framework HII Reference Opcode.\r
-\r
- @param UefiUpdateDataHandle The newly created UEFI HII opcode is appended to UefiUpdateDataHandle.\r
- @param FwOpcode The input Framework Opcode.\r
-\r
- @retval NULL There is not enough space left in Buffer to add the opcode.\r
- @retval Other A pointer to the created opcode.\r
- \r
-**/\r
-UINT8 *\r
-F2UCreateReferenceOpCode (\r
- IN OUT VOID *UefiUpdateDataHandle,\r
- IN CONST FRAMEWORK_EFI_IFR_REF *FwOpcode\r
- )\r
-{\r
- EFI_IFR_REF UOpcode;\r
-\r
- ZeroMem (&UOpcode, sizeof(UOpcode));\r
-\r
- UOpcode.Header.Length = (UINT8) sizeof (UOpcode);\r
- UOpcode.Header.OpCode = EFI_IFR_REF_OP;\r
-\r
- UOpcode.Question.Header.Prompt = FwOpcode->Prompt;\r
- UOpcode.Question.Header.Help = FwOpcode->Help;\r
- UOpcode.Question.QuestionId = FwOpcode->Key;\r
-\r
- UOpcode.FormId = FwOpcode->FormId;\r
-\r
- //\r
- // We only map EFI_IFR_FLAG_INTERACTIVE and EFI_IFR_FLAG_RESET_REQUIRED to \r
- // UEFI IFR Opcode flags. The rest flags are obsolete.\r
- //\r
- UOpcode.Question.Flags = (UINT8) (FwOpcode->Flags & (EFI_IFR_FLAG_INTERACTIVE | EFI_IFR_FLAG_RESET_REQUIRED));\r
- \r
- return HiiCreateRawOpCodes (UefiUpdateDataHandle, (UINT8 *) &UOpcode, sizeof(UOpcode));\r
-}\r
-\r
-/**\r
- Create UEFI HII "One Of Option" Opcode from a Framework HII "One Of Option" Opcode.\r
-\r
- @param UefiUpdateDataHandle The newly created UEFI HII opcode is appended to UefiUpdateDataHandle.\r
- @param FwOpcode The input Framework Opcode.\r
- @param Width The size of the One Of Option. 1 bytes or 2 bytes.\r
-\r
- @retval NULL There is not enough space left in Buffer to add the opcode.\r
- @retval Other A pointer to the created opcode.\r
- \r
-**/\r
-UINT8 *\r
-F2UCreateOneOfOptionOpCode (\r
- IN OUT VOID *UefiUpdateDataHandle,\r
- IN CONST FRAMEWORK_EFI_IFR_ONE_OF_OPTION *FwOpcode,\r
- IN UINTN Width\r
- )\r
-{\r
- EFI_IFR_ONE_OF_OPTION UOpcode;\r
-\r
- ZeroMem (&UOpcode, sizeof(UOpcode));\r
-\r
- UOpcode.Header.Length = (UINT8) sizeof (UOpcode);\r
- UOpcode.Header.OpCode = EFI_IFR_ONE_OF_OPTION_OP;\r
-\r
- UOpcode.Option = FwOpcode->Option;\r
- CopyMem (&UOpcode.Value.u8, &FwOpcode->Value, Width);\r
-\r
- //\r
- // #define EFI_IFR_FLAG_DEFAULT 0x01\r
- // #define EFI_IFR_FLAG_MANUFACTURING 0x02\r
- // #define EFI_IFR_OPTION_DEFAULT 0x10\r
- // #define EFI_IFR_OPTION_DEFAULT_MFG 0x20\r
- //\r
- UOpcode.Flags = (UINT8) (UOpcode.Flags | (FwOpcode->Flags & (EFI_IFR_FLAG_DEFAULT | EFI_IFR_FLAG_MANUFACTURING)) << 4);\r
-\r
- switch (Width) {\r
- case 1:\r
- UOpcode.Type = EFI_IFR_TYPE_NUM_SIZE_8;\r
- break;\r
- \r
- case 2:\r
- UOpcode.Type = EFI_IFR_TYPE_NUM_SIZE_16;\r
- break;\r
- \r
- default:\r
- ASSERT (FALSE);\r
- return NULL;\r
- }\r
-\r
- return HiiCreateRawOpCodes (UefiUpdateDataHandle, (UINT8 *) &UOpcode, sizeof(UOpcode));\r
-}\r
-\r
-/**\r
- Create a GUID Opcode EFI_IFR_GUID_OPTIONKEY to map the Framework One Of Option callback key\r
- to a UEFI Question ID. This information is used to invoke the Framework HII Browser Callback\r
- function. The opcode is appened to UefiUpdateDataHandle.\r
-\r
- @param UefiUpdateDataHandle The UEFI Update Data buffer.\r
- @param QuestionId The UEFI Question ID.\r
- @param OptionValue The value of the "One Of Option".\r
- @param KeyValue The Framework "One Of Option" callback key.\r
-\r
- @retval NULL There is not enough space left in Buffer to add the opcode.\r
- @retval Other A pointer to the created opcode.\r
-**/\r
-UINT8 *\r
-CreateGuidOptionKeyOpCode (\r
- IN OUT VOID *UefiUpdateDataHandle,\r
- IN EFI_QUESTION_ID QuestionId,\r
- IN UINT16 OptionValue,\r
- IN EFI_QUESTION_ID KeyValue\r
- )\r
-{\r
- EFI_IFR_GUID_OPTIONKEY *UOpcode;\r
- \r
- UOpcode = (EFI_IFR_GUID_OPTIONKEY *) HiiCreateGuidOpCode (\r
- UefiUpdateDataHandle, \r
- &gEfiIfrFrameworkGuid, \r
- NULL,\r
- sizeof (EFI_IFR_GUID_OPTIONKEY)\r
- );\r
-\r
- UOpcode->ExtendOpCode = EFI_IFR_EXTEND_OP_OPTIONKEY;\r
- UOpcode->QuestionId = QuestionId;\r
- CopyMem (&UOpcode->OptionValue, &OptionValue, sizeof (OptionValue)); \r
- UOpcode->KeyValue = KeyValue;\r
-\r
- return (UINT8 *) UOpcode;\r
-}\r
-\r
-/**\r
- Create UEFI HII "One Of" Opcode from a Framework HII "One Of" Opcode.\r
-\r
- @param UefiUpdateDataHandle The newly created UEFI HII opcode is appended to UefiUpdateDataHandle.\r
- @param ThunkContext The HII Thunk Context.\r
- @param FwOpcode The input Framework Opcode.\r
- @param NextFwOpcode Returns the position of the next Framework Opcode after EFI_IFR_END_ONE_OF_OP of\r
- the "One Of Option".\r
- @param OpcodeCount The number of Opcode for the complete Framework "One Of" Opcode.\r
- \r
- @retval NULL There is not enough space left in Buffer to add the opcode.\r
- @retval Other A pointer to the created opcode.\r
- \r
-**/\r
-UINT8 *\r
-F2UCreateOneOfOpCode (\r
- IN OUT VOID *UefiUpdateDataHandle,\r
- IN HII_THUNK_CONTEXT *ThunkContext,\r
- IN CONST FRAMEWORK_EFI_IFR_ONE_OF *FwOpcode,\r
- OUT FRAMEWORK_EFI_IFR_OP_HEADER **NextFwOpcode,\r
- OUT UINTN *OpcodeCount\r
- )\r
-{\r
- EFI_STATUS Status;\r
- EFI_IFR_ONE_OF UOpcode;\r
- FRAMEWORK_EFI_IFR_OP_HEADER *FwOpHeader;\r
- FRAMEWORK_EFI_IFR_ONE_OF_OPTION *FwOneOfOp;\r
- UINT8 *OpCodeBuffer;\r
- UINT8 *OneOfOpCodeBuffer;\r
-\r
- ASSERT (NextFwOpcode != NULL);\r
- ASSERT (OpcodeCount != NULL);\r
-\r
- ZeroMem (&UOpcode, sizeof(UOpcode));\r
- *OpcodeCount = 0;\r
-\r
- UOpcode.Header.Length = (UINT8) sizeof (UOpcode);\r
- UOpcode.Header.OpCode = EFI_IFR_ONE_OF_OP;\r
- UOpcode.Header.Scope = 1;\r
-\r
- UOpcode.Question.Header.Prompt = FwOpcode->Prompt;\r
- UOpcode.Question.Header.Help = FwOpcode->Help;\r
- UOpcode.Question.VarStoreId = ThunkContext->FormSet->DefaultVarStoreId;\r
- UOpcode.Question.VarStoreInfo.VarOffset = FwOpcode->QuestionId;\r
- \r
- //\r
- // Go over the Framework IFR binary to get the QuestionId for generated UEFI One Of Option opcode\r
- //\r
- FwOpHeader = (FRAMEWORK_EFI_IFR_OP_HEADER *) ((UINT8 *) FwOpcode + FwOpcode->Header.Length);\r
- while (FwOpHeader->OpCode != EFI_IFR_END_ONE_OF_OP) {\r
- ASSERT (FwOpHeader->OpCode == FRAMEWORK_EFI_IFR_ONE_OF_OPTION_OP);\r
- \r
- FwOneOfOp = (FRAMEWORK_EFI_IFR_ONE_OF_OPTION *) FwOpHeader;\r
- if ((FwOneOfOp->Flags & EFI_IFR_FLAG_INTERACTIVE) != 0) {\r
- UOpcode.Question.Flags |= EFI_IFR_FLAG_CALLBACK;\r
- \r
- if (UOpcode.Question.QuestionId == 0) {\r
- Status = FwQIdToUefiQId (ThunkContext->FormSet, FwOpcode->Header.OpCode, FwOpcode->QuestionId, &UOpcode.Question.QuestionId);\r
- if (EFI_ERROR (Status)) {\r
- UOpcode.Question.QuestionId = AssignQuestionId (FwOneOfOp->Key, ThunkContext->FormSet);\r
- }\r
- }\r
-\r
- }\r
-\r
- if ((FwOneOfOp->Flags & EFI_IFR_FLAG_RESET_REQUIRED) == EFI_IFR_FLAG_RESET_REQUIRED) {\r
- UOpcode.Question.Flags |= EFI_IFR_FLAG_RESET_REQUIRED;\r
- }\r
-\r
- FwOpHeader = (FRAMEWORK_EFI_IFR_OP_HEADER *) ((UINT8 *) FwOpHeader + FwOpHeader->Length);\r
- }\r
-\r
-\r
- if (UOpcode.Question.QuestionId == 0) {\r
- //\r
- // Assign QuestionId if still not assigned.\r
- //\r
- Status = FwQIdToUefiQId (ThunkContext->FormSet, FwOpcode->Header.OpCode, FwOpcode->QuestionId, &UOpcode.Question.QuestionId);\r
- if (EFI_ERROR (Status)) {\r
- UOpcode.Question.QuestionId = AssignQuestionId (FwOpcode->QuestionId, ThunkContext->FormSet);\r
- }\r
- }\r
- \r
- OneOfOpCodeBuffer = HiiCreateRawOpCodes (UefiUpdateDataHandle, (UINT8 *) &UOpcode, sizeof (UOpcode));\r
- if (OneOfOpCodeBuffer == NULL) {\r
- return NULL;\r
- }\r
- *OpcodeCount += 1;\r
-\r
- //\r
- // Go over again the Framework IFR binary to build the UEFI One Of Option opcodes.\r
- //\r
- FwOpHeader = (FRAMEWORK_EFI_IFR_OP_HEADER *) ((UINT8 *) FwOpcode + FwOpcode->Header.Length);\r
- while (FwOpHeader->OpCode != EFI_IFR_END_ONE_OF_OP) {\r
-\r
- FwOneOfOp = (FRAMEWORK_EFI_IFR_ONE_OF_OPTION *) FwOpHeader;\r
- \r
- OpCodeBuffer = F2UCreateOneOfOptionOpCode (UefiUpdateDataHandle, (FRAMEWORK_EFI_IFR_ONE_OF_OPTION *) FwOpHeader, FwOpcode->Width);\r
- if (OpCodeBuffer == NULL) {\r
- return NULL;\r
- }\r
-\r
- OpCodeBuffer = CreateGuidOptionKeyOpCode (UefiUpdateDataHandle, UOpcode.Question.QuestionId, FwOneOfOp->Value, FwOneOfOp->Key);\r
- if (OpCodeBuffer == NULL) {\r
- return NULL;\r
- }\r
-\r
- FwOpHeader = (FRAMEWORK_EFI_IFR_OP_HEADER *) ((UINT8 *) FwOpHeader + FwOpHeader->Length);\r
- *OpcodeCount += 1;\r
- }\r
-\r
- OpCodeBuffer = HiiCreateEndOpCode (UefiUpdateDataHandle);\r
- if (OpCodeBuffer != NULL) {\r
- *NextFwOpcode = (FRAMEWORK_EFI_IFR_OP_HEADER *)((UINT8 *) FwOpHeader + FwOpHeader->Length);\r
- *OpcodeCount += 1;\r
- }\r
-\r
- return OneOfOpCodeBuffer;\r
-}\r
-\r
-/**\r
- Create UEFI HII "Ordered List" Opcode from a Framework HII "Ordered List" Opcode.\r
-\r
- @param UefiUpdateDataHandle The newly created UEFI HII opcode is appended to UefiUpdateDataHandle.\r
- @param ThunkContext The HII Thunk Context.\r
- @param FwOpcode The input Framework Opcode.\r
- @param NextFwOpcode Returns the position of the next Framework Opcode after EFI_IFR_END_ONE_OF_OP of\r
- the "Ordered List".\r
- @param OpcodeCount The number of Opcode for the complete Framework "Ordered List" Opcode.\r
- \r
- @retval NULL There is not enough space left in Buffer to add the opcode.\r
- @retval Other A pointer to the created opcode.\r
- \r
-**/\r
-UINT8 *\r
-F2UCreateOrderedListOpCode (\r
- IN OUT VOID *UefiUpdateDataHandle,\r
- IN HII_THUNK_CONTEXT *ThunkContext,\r
- IN CONST FRAMEWORK_EFI_IFR_ORDERED_LIST *FwOpcode,\r
- OUT FRAMEWORK_EFI_IFR_OP_HEADER **NextFwOpcode,\r
- OUT UINTN *OpcodeCount\r
- )\r
-{\r
- EFI_IFR_ORDERED_LIST UOpcode;\r
- EFI_STATUS Status;\r
- FRAMEWORK_EFI_IFR_OP_HEADER *FwOpHeader;\r
- FRAMEWORK_EFI_IFR_ONE_OF_OPTION *FwOneOfOp;\r
- UINT8 *OpcodeBuffer; \r
- UINT8 *OrderListOpCode;\r
-\r
- ZeroMem (&UOpcode, sizeof(UOpcode));\r
- *OpcodeCount = 0;\r
-\r
- UOpcode.Header.Length = (UINT8) sizeof (UOpcode);\r
- UOpcode.Header.OpCode = EFI_IFR_ORDERED_LIST_OP;\r
- UOpcode.Header.Scope = 1;\r
-\r
- UOpcode.Question.Header.Prompt = FwOpcode->Prompt;\r
- UOpcode.Question.Header.Help = FwOpcode->Help;\r
- UOpcode.Question.VarStoreId = ThunkContext->FormSet->DefaultVarStoreId;\r
- UOpcode.Question.VarStoreInfo.VarOffset = FwOpcode->QuestionId;\r
-\r
- UOpcode.MaxContainers = FwOpcode->MaxEntries;\r
-\r
- //\r
- // Go over the Framework IFR binary to get the QuestionId for generated UEFI One Of Option opcode\r
- //\r
- FwOpHeader = (FRAMEWORK_EFI_IFR_OP_HEADER *) ((UINT8 *) FwOpcode + FwOpcode->Header.Length);\r
- while (FwOpHeader->OpCode != EFI_IFR_END_ONE_OF_OP) {\r
- ASSERT (FwOpHeader->OpCode == FRAMEWORK_EFI_IFR_ONE_OF_OPTION_OP);\r
- \r
- FwOneOfOp = (FRAMEWORK_EFI_IFR_ONE_OF_OPTION *) FwOpHeader;\r
- if ((FwOneOfOp->Flags & EFI_IFR_FLAG_INTERACTIVE) != 0) {\r
- UOpcode.Question.Flags |= EFI_IFR_FLAG_CALLBACK;\r
- \r
- if (UOpcode.Question.QuestionId == 0) {\r
- Status = FwQIdToUefiQId (ThunkContext->FormSet, FwOpcode->Header.OpCode, FwOpcode->QuestionId, &UOpcode.Question.QuestionId);\r
- if (EFI_ERROR (Status)) {\r
- UOpcode.Question.QuestionId = AssignQuestionId (FwOneOfOp->Key, ThunkContext->FormSet);\r
- }\r
-\r
- }\r
- }\r
-\r
- if ((FwOneOfOp->Flags & EFI_IFR_FLAG_RESET_REQUIRED) == EFI_IFR_FLAG_RESET_REQUIRED) {\r
- UOpcode.Question.Flags |= EFI_IFR_FLAG_RESET_REQUIRED;\r
- }\r
-\r
- FwOpHeader = (FRAMEWORK_EFI_IFR_OP_HEADER *) ((UINT8 *) FwOpHeader + FwOpHeader->Length);\r
- }\r
-\r
- if (UOpcode.Question.QuestionId == 0) {\r
- Status = FwQIdToUefiQId (ThunkContext->FormSet, FwOpcode->Header.OpCode, FwOpcode->QuestionId, &UOpcode.Question.QuestionId);\r
- if (EFI_ERROR (Status)) {\r
- UOpcode.Question.QuestionId = AssignQuestionId (FwOpcode->QuestionId, ThunkContext->FormSet);\r
- }\r
- }\r
- \r
- OrderListOpCode = HiiCreateRawOpCodes (UefiUpdateDataHandle, (UINT8 *) &UOpcode, sizeof(UOpcode));\r
- if (OrderListOpCode == NULL) {\r
- return NULL;\r
- }\r
- *OpcodeCount += 1;\r
-\r
- FwOpHeader = (FRAMEWORK_EFI_IFR_OP_HEADER *) ((UINT8 *) FwOpcode + FwOpcode->Header.Length);\r
- while (FwOpHeader->OpCode != EFI_IFR_END_ONE_OF_OP) {\r
- //\r
- // Each entry of Order List in Framework HII is always 1 byte in size\r
- //\r
- OpcodeBuffer = F2UCreateOneOfOptionOpCode (UefiUpdateDataHandle, (CONST FRAMEWORK_EFI_IFR_ONE_OF_OPTION *) FwOpHeader, 1);\r
- if (OpcodeBuffer == NULL) {\r
- return NULL;\r
- }\r
- FwOpHeader = (FRAMEWORK_EFI_IFR_OP_HEADER *) ((UINT8 *) FwOpHeader + FwOpHeader->Length);\r
- *OpcodeCount += 1;\r
- }\r
-\r
- OpcodeBuffer = HiiCreateEndOpCode (UefiUpdateDataHandle);\r
- if (OpcodeBuffer != NULL) {\r
- *NextFwOpcode = (FRAMEWORK_EFI_IFR_OP_HEADER *)((UINT8 *) FwOpHeader + FwOpHeader->Length);\r
- *OpcodeCount += 1;\r
- }\r
-\r
- return OrderListOpCode;\r
-}\r
-\r
-/**\r
- Create UEFI HII CheckBox Opcode from a Framework HII Checkbox Opcode.\r
-\r
- @param UefiUpdateDataHandle The newly created UEFI HII opcode is appended to UefiUpdateDataHandle.\r
- @param ThunkContext The HII Thunk Context.\r
- @param FwOpcode The input Framework Opcode.\r
-\r
- @retval NULL There is not enough space left in Buffer to add the opcode.\r
- @retval Other A pointer to the created opcode.\r
- \r
-**/\r
-UINT8 *\r
-F2UCreateCheckBoxOpCode (\r
- IN OUT VOID *UefiUpdateDataHandle,\r
- IN HII_THUNK_CONTEXT *ThunkContext,\r
- IN CONST FRAMEWORK_EFI_IFR_CHECKBOX *FwOpcode\r
- )\r
-{\r
- EFI_STATUS Status;\r
- EFI_IFR_CHECKBOX UOpcode;\r
-\r
- ZeroMem (&UOpcode, sizeof(UOpcode));\r
-\r
- UOpcode.Header.Length = (UINT8) sizeof (UOpcode);\r
- UOpcode.Header.OpCode = EFI_IFR_CHECKBOX_OP;\r
-\r
- UOpcode.Question.Header.Prompt = FwOpcode->Prompt;\r
- UOpcode.Question.Header.Help = FwOpcode->Help;\r
-\r
- if (FwOpcode->Key == 0) {\r
- Status = FwQIdToUefiQId (ThunkContext->FormSet, FwOpcode->Header.OpCode, FwOpcode->QuestionId, &UOpcode.Question.QuestionId);\r
- if (EFI_ERROR (Status)) {\r
- //\r
- // Add a new opcode and it will not trigger call back. So we just reuse the FW QuestionId.\r
- //\r
- UOpcode.Question.QuestionId = AssignQuestionId (FwOpcode->QuestionId, ThunkContext->FormSet);\r
- }\r
- } else {\r
- UOpcode.Question.QuestionId = FwOpcode->Key;\r
- }\r
-\r
- //\r
- // We map 2 flags:\r
- // EFI_IFR_FLAG_INTERACTIVE, \r
- // EFI_IFR_FLAG_RESET_REQUIRED,\r
- // to UEFI IFR Opcode Question flags. The rest flags are obsolete.\r
- //\r
- UOpcode.Question.Flags = (UINT8) (FwOpcode->Flags & (EFI_IFR_FLAG_INTERACTIVE | EFI_IFR_FLAG_RESET_REQUIRED));\r
-\r
-\r
- UOpcode.Question.VarStoreId = ThunkContext->FormSet->DefaultVarStoreId;\r
- UOpcode.Question.VarStoreInfo.VarOffset = FwOpcode->QuestionId;\r
-\r
- //\r
- // We also map these 2 flags:\r
- // EFI_IFR_FLAG_DEFAULT, \r
- // EFI_IFR_FLAG_MANUFACTURING,\r
- // to UEFI IFR CheckBox Opcode default flags.\r
- //\r
- UOpcode.Flags = (UINT8) (FwOpcode->Flags & (EFI_IFR_FLAG_DEFAULT | EFI_IFR_FLAG_MANUFACTURING));\r
-\r
- return HiiCreateRawOpCodes (UefiUpdateDataHandle, (UINT8 *) &UOpcode, sizeof(UOpcode));\r
-}\r
-\r
-\r
-/**\r
- Create UEFI HII Numeric Opcode from a Framework HII Numeric Opcode.\r
-\r
- @param UefiUpdateDataHandle The newly created UEFI HII opcode is appended to UefiUpdateDataHandle.\r
- @param ThunkContext The HII Thunk Context.\r
- @param FwOpcode The input Framework Opcode.\r
-\r
- @retval NULL There is not enough space left in Buffer to add the opcode.\r
- @retval Other A pointer to the created opcode.\r
- \r
-**/\r
-UINT8 *\r
-F2UCreateNumericOpCode (\r
- IN OUT VOID *UefiUpdateDataHandle,\r
- IN HII_THUNK_CONTEXT *ThunkContext,\r
- IN CONST FRAMEWORK_EFI_IFR_NUMERIC *FwOpcode\r
- )\r
-{\r
- EFI_STATUS Status;\r
- EFI_IFR_NUMERIC UOpcode;\r
- EFI_IFR_DEFAULT UOpcodeDefault;\r
- UINT8 *NumbericOpCode;\r
- UINT8 *OpcodeBuffer;\r
-\r
- ZeroMem (&UOpcode, sizeof(UOpcode));\r
-\r
- if (FwOpcode->Key == 0) {\r
- Status = FwQIdToUefiQId (ThunkContext->FormSet, FwOpcode->Header.OpCode, FwOpcode->QuestionId, &UOpcode.Question.QuestionId);\r
- if (EFI_ERROR (Status)) {\r
- //\r
- // Add a new opcode and it will not trigger call back. So we just reuse the FW QuestionId.\r
- //\r
- UOpcode.Question.QuestionId = AssignQuestionId (FwOpcode->QuestionId, ThunkContext->FormSet);\r
- }\r
- } else {\r
- UOpcode.Question.QuestionId = FwOpcode->Key;\r
- }\r
-\r
- UOpcode.Header.Length = (UINT8) sizeof (UOpcode);\r
- UOpcode.Header.OpCode = EFI_IFR_NUMERIC_OP;\r
- //\r
- // We need to create a nested default value for the UEFI Numeric Opcode.\r
- // So turn on the scope.\r
- //\r
- UOpcode.Header.Scope = 1;\r
-\r
- UOpcode.Question.Header.Prompt = FwOpcode->Prompt;\r
- UOpcode.Question.Header.Help = FwOpcode->Help;\r
-\r
- UOpcode.Question.VarStoreId = ThunkContext->FormSet->DefaultVarStoreId;\r
- UOpcode.Question.VarStoreInfo.VarOffset = FwOpcode->QuestionId;\r
-\r
- UOpcode.Question.Flags = (UINT8) (FwOpcode->Flags & (EFI_IFR_FLAG_INTERACTIVE | EFI_IFR_FLAG_RESET_REQUIRED));\r
-\r
- //\r
- // Framework Numeric values are all in UINT16 and displayed as decimal.\r
- //\r
- UOpcode.data.u16.MinValue = FwOpcode->Minimum;\r
- UOpcode.data.u16.MaxValue = FwOpcode->Maximum;\r
- UOpcode.data.u16.Step = FwOpcode->Step;\r
-\r
- switch (FwOpcode->Width) {\r
- case 1: \r
- {\r
- UOpcode.Flags = EFI_IFR_NUMERIC_SIZE_1 | EFI_IFR_DISPLAY_UINT_DEC; \r
- break;\r
- } \r
- case 2: \r
- {\r
- UOpcode.Flags = EFI_IFR_NUMERIC_SIZE_2 | EFI_IFR_DISPLAY_UINT_DEC; \r
- break;\r
- }\r
- default: \r
- {\r
- ASSERT (FALSE);\r
- return NULL;\r
- }\r
- }\r
- \r
- NumbericOpCode = HiiCreateRawOpCodes (UefiUpdateDataHandle, (UINT8 *) &UOpcode, sizeof(UOpcode));\r
- if (NumbericOpCode == NULL) {\r
- return NULL;\r
- }\r
-\r
- //\r
- // We need to create a default value.\r
- //\r
- ZeroMem (&UOpcodeDefault, sizeof (UOpcodeDefault));\r
- UOpcodeDefault.Header.Length = (UINT8) sizeof (UOpcodeDefault);\r
- UOpcodeDefault.Header.OpCode = EFI_IFR_DEFAULT_OP;\r
-\r
- UOpcodeDefault.DefaultId = 0;\r
-\r
- switch (FwOpcode->Width) {\r
- case 1: \r
- {\r
- UOpcodeDefault.Type = EFI_IFR_TYPE_NUM_SIZE_8;\r
- break;\r
- } \r
- case 2: \r
- {\r
- UOpcodeDefault.Type = EFI_IFR_TYPE_NUM_SIZE_16;\r
- break;\r
- }\r
- }\r
-\r
- CopyMem (&UOpcodeDefault.Value.u8, &FwOpcode->Default, FwOpcode->Width);\r
-\r
- OpcodeBuffer = HiiCreateRawOpCodes (UefiUpdateDataHandle, (UINT8 *) &UOpcodeDefault, sizeof(UOpcodeDefault));\r
- if (OpcodeBuffer == NULL) {\r
- return NULL;\r
- }\r
-\r
- OpcodeBuffer = HiiCreateEndOpCode (UefiUpdateDataHandle);\r
- if (OpcodeBuffer == NULL) {\r
- return NULL;\r
- }\r
-\r
- return NumbericOpCode;\r
-}\r
-\r
-\r
-/**\r
- Create UEFI HII String Opcode from a Framework HII String Opcode.\r
-\r
- @param UefiUpdateDataHandle The newly created UEFI HII opcode is appended to UefiUpdateDataHandle.\r
- @param ThunkContext The HII Thunk Context.\r
- @param FwOpcode The input Framework Opcode.\r
-\r
- @retval NULL There is not enough space left in Buffer to add the opcode.\r
- @retval Other A pointer to the created opcode.\r
- \r
-**/\r
-UINT8 *\r
-F2UCreateStringOpCode (\r
- IN OUT VOID *UefiUpdateDataHandle,\r
- IN HII_THUNK_CONTEXT *ThunkContext,\r
- IN CONST FRAMEWORK_EFI_IFR_STRING *FwOpcode\r
- )\r
-{\r
- EFI_IFR_STRING UOpcode;\r
- EFI_STATUS Status;\r
-\r
- ZeroMem (&UOpcode, sizeof(UOpcode));\r
-\r
- if (FwOpcode->Key == 0) {\r
- Status = FwQIdToUefiQId (ThunkContext->FormSet, FwOpcode->Header.OpCode, FwOpcode->QuestionId, &UOpcode.Question.QuestionId);\r
- if (EFI_ERROR (Status)) {\r
- //\r
- // Add a new opcode and it will not trigger call back. So we just reuse the FW QuestionId.\r
- //\r
- UOpcode.Question.QuestionId = AssignQuestionId (FwOpcode->QuestionId, ThunkContext->FormSet);\r
- }\r
- } else {\r
- UOpcode.Question.QuestionId = FwOpcode->Key;\r
- }\r
-\r
- UOpcode.Header.Length = (UINT8) sizeof (UOpcode);\r
- UOpcode.Header.OpCode = EFI_IFR_STRING_OP;\r
-\r
- UOpcode.Question.Header.Prompt = FwOpcode->Prompt;\r
- UOpcode.Question.Header.Help = FwOpcode->Help;\r
-\r
- UOpcode.Question.Flags = (UINT8) (FwOpcode->Flags & (EFI_IFR_FLAG_INTERACTIVE | EFI_IFR_FLAG_RESET_REQUIRED));\r
-\r
- UOpcode.Question.VarStoreId = ThunkContext->FormSet->DefaultVarStoreId;\r
- UOpcode.Question.VarStoreInfo.VarOffset = FwOpcode->QuestionId;\r
-\r
- UOpcode.MinSize = FwOpcode->MinSize;\r
- UOpcode.MaxSize = FwOpcode->MaxSize;\r
- UOpcode.Flags = EFI_IFR_STRING_MULTI_LINE;\r
-\r
- return HiiCreateRawOpCodes (UefiUpdateDataHandle, (UINT8 *) &UOpcode, sizeof(UOpcode));\r
-}\r
-\r
-/**\r
- Create UEFI HII Banner Opcode from a Framework HII Banner Opcode.\r
-\r
- @param UefiUpdateDataHandle The newly created UEFI HII opcode is appended to UefiUpdateDataHandle.\r
- @param FwOpcode The input Framework Opcode.\r
-\r
- @retval NULL There is not enough space left in Buffer to add the opcode.\r
- @retval Other A pointer to the created opcode.\r
- \r
-**/\r
-UINT8 *\r
-F2UCreateBannerOpCode (\r
- IN OUT VOID *UefiUpdateDataHandle,\r
- IN CONST EFI_IFR_BANNER *FwOpcode\r
- )\r
-{\r
- EFI_IFR_GUID_BANNER *UOpcode;\r
-\r
- UOpcode = (EFI_IFR_GUID_BANNER *) HiiCreateGuidOpCode (\r
- UefiUpdateDataHandle, \r
- &gEfiIfrTianoGuid, \r
- NULL,\r
- sizeof (EFI_IFR_GUID_BANNER)\r
- ); \r
-\r
- UOpcode->ExtendOpCode = EFI_IFR_EXTEND_OP_BANNER;\r
- UOpcode->Title = FwOpcode->Title;\r
- UOpcode->LineNumber = FwOpcode->LineNumber;\r
- UOpcode->Alignment = FwOpcode->Alignment;\r
-\r
- return (UINT8 *) UOpcode;\r
-}\r
-\r
-/**\r
- Create a Hii Update data Handle used to call IfrLibUpdateForm.\r
-\r
- @param ThunkContext The HII Thunk Context.\r
- @param FwUpdateData The Framework Update Data.\r
- @param UefiOpCodeHandle The UEFI opcode handle.\r
-\r
- @retval EFI_SUCCESS The UEFI Update Data is created successfully.\r
- @retval EFI_UNSUPPORTED There is unsupported opcode in FwUpdateData.\r
- @retval EFI_OUT_OF_RESOURCES There is not enough resource.\r
-**/\r
-EFI_STATUS \r
-FwUpdateDataToUefiUpdateData (\r
- IN HII_THUNK_CONTEXT *ThunkContext,\r
- IN CONST EFI_HII_UPDATE_DATA *FwUpdateData,\r
- IN VOID *UefiOpCodeHandle\r
- )\r
-{\r
- FRAMEWORK_EFI_IFR_OP_HEADER *FwOpCode;\r
- FRAMEWORK_EFI_IFR_OP_HEADER *NextFwOpCode;\r
- UINTN Index;\r
- UINTN DataCount;\r
- UINT8 *OpCodeBuffer;\r
- LIST_ENTRY *StorageList;\r
- FORMSET_STORAGE *Storage;\r
- FORM_BROWSER_FORMSET *FormSet;\r
- CHAR16 *DefaultVarStoreName;\r
- UINT16 DefaultVarStoreId;\r
- EFI_IFR_VARSTORE_SELECT *SelectVarOp;\r
-\r
- FwOpCode = (FRAMEWORK_EFI_IFR_OP_HEADER *) &FwUpdateData->Data;\r
-\r
- FormSet = ThunkContext->FormSet;\r
- DefaultVarStoreId = FormSet->DefaultVarStoreId;\r
- DefaultVarStoreName = FormSet->OriginalDefaultVarStoreName;\r
-\r
- for (Index = 0; Index < FwUpdateData->DataCount; Index += DataCount) {\r
- switch (FwOpCode->OpCode) {\r
- case FRAMEWORK_EFI_IFR_SUBTITLE_OP:\r
- OpCodeBuffer = HiiCreateSubTitleOpCode (UefiOpCodeHandle, ((FRAMEWORK_EFI_IFR_SUBTITLE *) FwOpCode)->SubTitle, 0, 0, 0);\r
- DataCount = 1;\r
- break;\r
- \r
- case FRAMEWORK_EFI_IFR_TEXT_OP:\r
- OpCodeBuffer = F2UCreateTextOpCode (UefiOpCodeHandle, (FRAMEWORK_EFI_IFR_TEXT *) FwOpCode); \r
- DataCount = 1;\r
- break;\r
-\r
- case FRAMEWORK_EFI_IFR_REF_OP:\r
- OpCodeBuffer = F2UCreateReferenceOpCode (UefiOpCodeHandle, (FRAMEWORK_EFI_IFR_REF *) FwOpCode); \r
- DataCount = 1;\r
- break;\r
- \r
- case FRAMEWORK_EFI_IFR_ONE_OF_OP:\r
- OpCodeBuffer = F2UCreateOneOfOpCode (UefiOpCodeHandle, ThunkContext, (FRAMEWORK_EFI_IFR_ONE_OF *) FwOpCode, &NextFwOpCode, &DataCount);\r
- if (OpCodeBuffer != NULL) {\r
- FwOpCode = NextFwOpCode;\r
- //\r
- // FwOpCode is already updated to point to the next opcode.\r
- //\r
- continue;\r
- }\r
- break;\r
-\r
- case FRAMEWORK_EFI_IFR_ORDERED_LIST_OP:\r
- OpCodeBuffer = F2UCreateOrderedListOpCode (UefiOpCodeHandle, ThunkContext, (FRAMEWORK_EFI_IFR_ORDERED_LIST *) FwOpCode, &NextFwOpCode, &DataCount);\r
- if (OpCodeBuffer != NULL) {\r
- FwOpCode = NextFwOpCode;\r
- //\r
- // FwOpCode is already updated to point to the next opcode.\r
- //\r
- continue;\r
- }\r
- break;\r
- \r
- case FRAMEWORK_EFI_IFR_CHECKBOX_OP:\r
- OpCodeBuffer = F2UCreateCheckBoxOpCode (UefiOpCodeHandle, ThunkContext, (FRAMEWORK_EFI_IFR_CHECKBOX *) FwOpCode); \r
- DataCount = 1;\r
- break;\r
-\r
- case FRAMEWORK_EFI_IFR_STRING_OP:\r
- OpCodeBuffer = F2UCreateStringOpCode (UefiOpCodeHandle, ThunkContext, (FRAMEWORK_EFI_IFR_STRING *) FwOpCode); \r
- DataCount = 1;\r
- break;\r
-\r
- case EFI_IFR_BANNER_OP:\r
- OpCodeBuffer = F2UCreateBannerOpCode (UefiOpCodeHandle, (EFI_IFR_BANNER *) FwOpCode); \r
- DataCount = 1;\r
- break;\r
-\r
- case EFI_IFR_END_ONE_OF_OP:\r
- OpCodeBuffer = HiiCreateEndOpCode (UefiOpCodeHandle);\r
- DataCount = 1;\r
- break;\r
-\r
- case FRAMEWORK_EFI_IFR_NUMERIC_OP:\r
- OpCodeBuffer = F2UCreateNumericOpCode (UefiOpCodeHandle, ThunkContext, (FRAMEWORK_EFI_IFR_NUMERIC *) FwOpCode);\r
- DataCount = 1;\r
- break;\r
- \r
- case EFI_IFR_VARSTORE_SELECT_OP:\r
- OpCodeBuffer = (UINT8 *) FwOpCode;\r
- SelectVarOp = (EFI_IFR_VARSTORE_SELECT *) FwOpCode;\r
- //\r
- // Check whether the selected VarId is in StorageList.\r
- //\r
- StorageList = GetFirstNode (&FormSet->StorageListHead);\r
- while (!IsNull (&FormSet->StorageListHead, StorageList)) {\r
- Storage = FORMSET_STORAGE_FROM_LINK (StorageList);\r
- if (Storage->VarStoreId == SelectVarOp->VarId) {\r
- break;\r
- }\r
- StorageList = GetNextNode (&FormSet->StorageListHead, StorageList);\r
- }\r
- ASSERT (!IsNull (&FormSet->StorageListHead, StorageList));\r
- //\r
- // Change VarStoreId to the selected VarId.\r
- //\r
- FormSet->DefaultVarStoreId = SelectVarOp->VarId;\r
- if (SelectVarOp->VarId == DefaultVarStoreId) {\r
- FormSet->OriginalDefaultVarStoreName = DefaultVarStoreName;\r
- }\r
- DataCount = 1;\r
- break;\r
-\r
- default:\r
- ASSERT (FALSE);\r
- return EFI_UNSUPPORTED;\r
- }\r
-\r
- if (OpCodeBuffer == NULL) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
-\r
- FwOpCode = (FRAMEWORK_EFI_IFR_OP_HEADER *)((UINT8 *) FwOpCode + FwOpCode->Length);\r
- }\r
-\r
- //\r
- // Revert FromSet default varstore ID.\r
- //\r
- FormSet->DefaultVarStoreId = DefaultVarStoreId;\r
- FormSet->OriginalDefaultVarStoreName = DefaultVarStoreName;\r
- return EFI_SUCCESS;\r
-}\r
-\r