2 Implement Functions to convert IFR Opcode in format defined in Framework HII specification to
3 format defined in UEFI HII Specification.
5 Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.<BR>
6 This program and the accompanying materials
7 are licensed and made available under the terms and conditions of the BSD License
8 which accompanies this distribution. The full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
16 #include "HiiDatabase.h"
17 #include "UefiIfrDefault.h"
20 The dynamic creation of these opcodes is supported in Framework HII modules.
21 Therefore, Framework HII Thunk module only map these opcode between Framework
22 HII's definitions to UEFI HII's.
29 IFR_OPCODE_MAP QuestionOpcodeMap
[] = {
30 { FRAMEWORK_EFI_IFR_ONE_OF_OP
, EFI_IFR_ONE_OF_OP
},
31 { FRAMEWORK_EFI_IFR_CHECKBOX_OP
, EFI_IFR_CHECKBOX_OP
},
32 { FRAMEWORK_EFI_IFR_NUMERIC_OP
, EFI_IFR_NUMERIC_OP
},
33 { FRAMEWORK_EFI_IFR_ONE_OF_OPTION_OP
, EFI_IFR_ONE_OF_OPTION_OP
},
34 { FRAMEWORK_EFI_IFR_ORDERED_LIST_OP
, EFI_IFR_ORDERED_LIST_OP
}
38 Translate a Framework Question Opcode to UEFI Question Opcode.
40 @param FwOp Framework Opcode.
41 @param UefiOp UEFI Opcode.
43 @retval EFI_SUCCESS The UEFI opcode is found and returned.
44 @retval EFI_NOT_FOUND The UEFI opcode is not found.
54 for (Index
= 0; Index
< sizeof (QuestionOpcodeMap
) / sizeof (QuestionOpcodeMap
[0]); Index
++) {
55 if (FwOp
== QuestionOpcodeMap
[Index
].FrameworkIfrOp
) {
56 *UefiOp
= QuestionOpcodeMap
[Index
].UefiIfrOp
;
61 *UefiOp
= (UINT8
) (EFI_IFR_LAST_OPCODE
+ 1);
66 Translate a Framework Question ID to UEFI Question ID.
68 @param FormSet FormSet context
69 @param FwOpCode Framework Opcode
70 @param FwQId Framework Question Id
71 @param UefiQId UEFI Question ID.
73 @retval EFI_SUCCESS The UEFI Question Id is found and returned.
74 @retval EFI_NOT_FOUND The UEFI Question Id is not found.
78 IN CONST FORM_BROWSER_FORMSET
*FormSet
,
85 LIST_ENTRY
*StatementList
;
86 FORM_BROWSER_FORM
*Form
;
87 FORM_BROWSER_STATEMENT
*Statement
;
88 FORM_BROWSER_STATEMENT
*StatementFound
;
94 StatementFound
= NULL
;
96 FormList
= GetFirstNode (&FormSet
->FormListHead
);
98 while (!IsNull (&FormSet
->FormListHead
, FormList
)) {
99 Form
= FORM_BROWSER_FORM_FROM_LINK (FormList
);
101 StatementList
= GetFirstNode (&Form
->StatementListHead
);
103 while (!IsNull (&Form
->StatementListHead
, StatementList
)) {
104 Statement
= FORM_BROWSER_STATEMENT_FROM_LINK (StatementList
);
105 if (Statement
->VarStoreId
!= 0 && Statement
->Storage
->Type
== EFI_HII_VARSTORE_BUFFER
) {
106 if (FwQId
== Statement
->VarStoreInfo
.VarOffset
) {
107 Status
= QuestionOpFwToUefi (FwOpCode
, &UefiOp
);
108 ASSERT_EFI_ERROR (Status
);
110 if ((UefiOp
== Statement
->Operand
) && (FormSet
->DefaultVarStoreId
== Statement
->VarStoreId
)) {
112 // If ASSERT here, the Framework VFR file has two Questions with all three attibutes the same:
113 // 1) Same Question Type,
114 // 2) Same Variable Storage
115 // 3) Refering to the Same offset in Variable Map (NvMap).
116 // This is ambigurity as FwQIdToUefiQId () can't find which UEFI Question
119 // One possible solution is to remove the one of the duplicated questions in this Form Set.
121 ASSERT (StatementFound
== NULL
);
122 StatementFound
= Statement
;
125 // Continue the search to check if the Form Set contains more than one questins that has the 3 attributes
132 StatementList
= GetNextNode (&Form
->StatementListHead
, StatementList
);
135 FormList
= GetNextNode (&FormSet
->FormListHead
, FormList
);
138 if (StatementFound
!= NULL
) {
139 *UefiQId
= StatementFound
->QuestionId
;
143 return EFI_NOT_FOUND
;
147 Assign a Question ID.
149 If FwQuestionId is 0, then assign a new question ID. The new question ID
150 is MaxQuestionId incremented by 1. The MaxQuestionId of FormSet is also
153 If FwQuestionId is not 0, then it is used as the Framework Question ID.
158 @return The Framework Question ID.
162 IN UINT16 FwQuestionId
,
163 IN FORM_BROWSER_FORMSET
*FormSet
166 if (FwQuestionId
== 0) {
167 FormSet
->MaxQuestionId
++;
168 return FormSet
->MaxQuestionId
;
175 Create UEFI HII Text Opcode from a Framework HII Text Opcode.
177 @param UefiUpdateDataHandle The newly created UEFI HII opcode is appended to UefiUpdateDataHandle.
178 @param FwOpcode The input Framework Opcode.
180 @retval NULL There is not enough space left in Buffer to add the opcode.
181 @retval Other A pointer to the created opcode.
185 F2UCreateTextOpCode (
186 IN OUT VOID
*UefiUpdateDataHandle
,
187 IN CONST FRAMEWORK_EFI_IFR_TEXT
*FwOpcode
190 EFI_IFR_TEXT UTextOpCode
;
192 if ((FwOpcode
->Flags
& EFI_IFR_FLAG_INTERACTIVE
) == 0) {
193 ZeroMem (&UTextOpCode
, sizeof(UTextOpCode
));
195 UTextOpCode
.Header
.OpCode
= EFI_IFR_TEXT_OP
;
196 UTextOpCode
.Header
.Length
= (UINT8
) sizeof (EFI_IFR_TEXT
);
198 UTextOpCode
.Statement
.Help
= FwOpcode
->Help
;
200 UTextOpCode
.Statement
.Prompt
= FwOpcode
->Text
;
201 UTextOpCode
.TextTwo
= FwOpcode
->TextTwo
;
203 return HiiCreateRawOpCodes (UefiUpdateDataHandle
, (UINT8
*) &UTextOpCode
, sizeof(UTextOpCode
));
206 // Iteractive Text Opcode is EFI_IFR_ACTION
208 return HiiCreateActionOpCode (UefiUpdateDataHandle
, FwOpcode
->Key
, FwOpcode
->Text
, FwOpcode
->Help
, EFI_IFR_FLAG_CALLBACK
, 0);
213 Create UEFI HII Reference Opcode from a Framework HII Reference Opcode.
215 @param UefiUpdateDataHandle The newly created UEFI HII opcode is appended to UefiUpdateDataHandle.
216 @param FwOpcode The input Framework Opcode.
218 @retval NULL There is not enough space left in Buffer to add the opcode.
219 @retval Other A pointer to the created opcode.
223 F2UCreateReferenceOpCode (
224 IN OUT VOID
*UefiUpdateDataHandle
,
225 IN CONST FRAMEWORK_EFI_IFR_REF
*FwOpcode
230 ZeroMem (&UOpcode
, sizeof(UOpcode
));
232 UOpcode
.Header
.Length
= (UINT8
) sizeof (UOpcode
);
233 UOpcode
.Header
.OpCode
= EFI_IFR_REF_OP
;
235 UOpcode
.Question
.Header
.Prompt
= FwOpcode
->Prompt
;
236 UOpcode
.Question
.Header
.Help
= FwOpcode
->Help
;
237 UOpcode
.Question
.QuestionId
= FwOpcode
->Key
;
239 UOpcode
.FormId
= FwOpcode
->FormId
;
242 // We only map EFI_IFR_FLAG_INTERACTIVE and EFI_IFR_FLAG_RESET_REQUIRED to
243 // UEFI IFR Opcode flags. The rest flags are obsolete.
245 UOpcode
.Question
.Flags
= (UINT8
) (FwOpcode
->Flags
& (EFI_IFR_FLAG_INTERACTIVE
| EFI_IFR_FLAG_RESET_REQUIRED
));
247 return HiiCreateRawOpCodes (UefiUpdateDataHandle
, (UINT8
*) &UOpcode
, sizeof(UOpcode
));
251 Create UEFI HII "One Of Option" Opcode from a Framework HII "One Of Option" Opcode.
253 @param UefiUpdateDataHandle The newly created UEFI HII opcode is appended to UefiUpdateDataHandle.
254 @param FwOpcode The input Framework Opcode.
255 @param Width The size of the One Of Option. 1 bytes or 2 bytes.
257 @retval NULL There is not enough space left in Buffer to add the opcode.
258 @retval Other A pointer to the created opcode.
262 F2UCreateOneOfOptionOpCode (
263 IN OUT VOID
*UefiUpdateDataHandle
,
264 IN CONST FRAMEWORK_EFI_IFR_ONE_OF_OPTION
*FwOpcode
,
268 EFI_IFR_ONE_OF_OPTION UOpcode
;
270 ZeroMem (&UOpcode
, sizeof(UOpcode
));
272 UOpcode
.Header
.Length
= (UINT8
) sizeof (UOpcode
);
273 UOpcode
.Header
.OpCode
= EFI_IFR_ONE_OF_OPTION_OP
;
275 UOpcode
.Option
= FwOpcode
->Option
;
276 CopyMem (&UOpcode
.Value
.u8
, &FwOpcode
->Value
, Width
);
279 // #define EFI_IFR_FLAG_DEFAULT 0x01
280 // #define EFI_IFR_FLAG_MANUFACTURING 0x02
281 // #define EFI_IFR_OPTION_DEFAULT 0x10
282 // #define EFI_IFR_OPTION_DEFAULT_MFG 0x20
284 UOpcode
.Flags
= (UINT8
) (UOpcode
.Flags
| (FwOpcode
->Flags
& (EFI_IFR_FLAG_DEFAULT
| EFI_IFR_FLAG_MANUFACTURING
)) << 4);
288 UOpcode
.Type
= EFI_IFR_TYPE_NUM_SIZE_8
;
292 UOpcode
.Type
= EFI_IFR_TYPE_NUM_SIZE_16
;
300 return HiiCreateRawOpCodes (UefiUpdateDataHandle
, (UINT8
*) &UOpcode
, sizeof(UOpcode
));
304 Create a GUID Opcode EFI_IFR_GUID_OPTIONKEY to map the Framework One Of Option callback key
305 to a UEFI Question ID. This information is used to invoke the Framework HII Browser Callback
306 function. The opcode is appened to UefiUpdateDataHandle.
308 @param UefiUpdateDataHandle The UEFI Update Data buffer.
309 @param QuestionId The UEFI Question ID.
310 @param OptionValue The value of the "One Of Option".
311 @param KeyValue The Framework "One Of Option" callback key.
313 @retval NULL There is not enough space left in Buffer to add the opcode.
314 @retval Other A pointer to the created opcode.
317 CreateGuidOptionKeyOpCode (
318 IN OUT VOID
*UefiUpdateDataHandle
,
319 IN EFI_QUESTION_ID QuestionId
,
320 IN UINT16 OptionValue
,
321 IN EFI_QUESTION_ID KeyValue
324 EFI_IFR_GUID_OPTIONKEY
*UOpcode
;
326 UOpcode
= (EFI_IFR_GUID_OPTIONKEY
*) HiiCreateGuidOpCode (
327 UefiUpdateDataHandle
,
328 &gEfiIfrFrameworkGuid
,
330 sizeof (EFI_IFR_GUID_OPTIONKEY
)
333 UOpcode
->ExtendOpCode
= EFI_IFR_EXTEND_OP_OPTIONKEY
;
334 UOpcode
->QuestionId
= QuestionId
;
335 CopyMem (&UOpcode
->OptionValue
, &OptionValue
, sizeof (OptionValue
));
336 UOpcode
->KeyValue
= KeyValue
;
338 return (UINT8
*) UOpcode
;
342 Create UEFI HII "One Of" Opcode from a Framework HII "One Of" Opcode.
344 @param UefiUpdateDataHandle The newly created UEFI HII opcode is appended to UefiUpdateDataHandle.
345 @param ThunkContext The HII Thunk Context.
346 @param FwOpcode The input Framework Opcode.
347 @param NextFwOpcode Returns the position of the next Framework Opcode after EFI_IFR_END_ONE_OF_OP of
349 @param OpcodeCount The number of Opcode for the complete Framework "One Of" Opcode.
351 @retval NULL There is not enough space left in Buffer to add the opcode.
352 @retval Other A pointer to the created opcode.
356 F2UCreateOneOfOpCode (
357 IN OUT VOID
*UefiUpdateDataHandle
,
358 IN HII_THUNK_CONTEXT
*ThunkContext
,
359 IN CONST FRAMEWORK_EFI_IFR_ONE_OF
*FwOpcode
,
360 OUT FRAMEWORK_EFI_IFR_OP_HEADER
**NextFwOpcode
,
361 OUT UINTN
*OpcodeCount
365 EFI_IFR_ONE_OF UOpcode
;
366 FRAMEWORK_EFI_IFR_OP_HEADER
*FwOpHeader
;
367 FRAMEWORK_EFI_IFR_ONE_OF_OPTION
*FwOneOfOp
;
369 UINT8
*OneOfOpCodeBuffer
;
371 ASSERT (NextFwOpcode
!= NULL
);
372 ASSERT (OpcodeCount
!= NULL
);
374 ZeroMem (&UOpcode
, sizeof(UOpcode
));
377 UOpcode
.Header
.Length
= (UINT8
) sizeof (UOpcode
);
378 UOpcode
.Header
.OpCode
= EFI_IFR_ONE_OF_OP
;
379 UOpcode
.Header
.Scope
= 1;
381 UOpcode
.Question
.Header
.Prompt
= FwOpcode
->Prompt
;
382 UOpcode
.Question
.Header
.Help
= FwOpcode
->Help
;
383 UOpcode
.Question
.VarStoreId
= ThunkContext
->FormSet
->DefaultVarStoreId
;
384 UOpcode
.Question
.VarStoreInfo
.VarOffset
= FwOpcode
->QuestionId
;
387 // Go over the Framework IFR binary to get the QuestionId for generated UEFI One Of Option opcode
389 FwOpHeader
= (FRAMEWORK_EFI_IFR_OP_HEADER
*) ((UINT8
*) FwOpcode
+ FwOpcode
->Header
.Length
);
390 while (FwOpHeader
->OpCode
!= EFI_IFR_END_ONE_OF_OP
) {
391 ASSERT (FwOpHeader
->OpCode
== FRAMEWORK_EFI_IFR_ONE_OF_OPTION_OP
);
393 FwOneOfOp
= (FRAMEWORK_EFI_IFR_ONE_OF_OPTION
*) FwOpHeader
;
394 if ((FwOneOfOp
->Flags
& EFI_IFR_FLAG_INTERACTIVE
) != 0) {
395 UOpcode
.Question
.Flags
|= EFI_IFR_FLAG_CALLBACK
;
397 if (UOpcode
.Question
.QuestionId
== 0) {
398 Status
= FwQIdToUefiQId (ThunkContext
->FormSet
, FwOpcode
->Header
.OpCode
, FwOpcode
->QuestionId
, &UOpcode
.Question
.QuestionId
);
399 if (EFI_ERROR (Status
)) {
400 UOpcode
.Question
.QuestionId
= AssignQuestionId (FwOneOfOp
->Key
, ThunkContext
->FormSet
);
406 if ((FwOneOfOp
->Flags
& EFI_IFR_FLAG_RESET_REQUIRED
) == EFI_IFR_FLAG_RESET_REQUIRED
) {
407 UOpcode
.Question
.Flags
|= EFI_IFR_FLAG_RESET_REQUIRED
;
410 FwOpHeader
= (FRAMEWORK_EFI_IFR_OP_HEADER
*) ((UINT8
*) FwOpHeader
+ FwOpHeader
->Length
);
414 if (UOpcode
.Question
.QuestionId
== 0) {
416 // Assign QuestionId if still not assigned.
418 Status
= FwQIdToUefiQId (ThunkContext
->FormSet
, FwOpcode
->Header
.OpCode
, FwOpcode
->QuestionId
, &UOpcode
.Question
.QuestionId
);
419 if (EFI_ERROR (Status
)) {
420 UOpcode
.Question
.QuestionId
= AssignQuestionId (FwOpcode
->QuestionId
, ThunkContext
->FormSet
);
424 OneOfOpCodeBuffer
= HiiCreateRawOpCodes (UefiUpdateDataHandle
, (UINT8
*) &UOpcode
, sizeof (UOpcode
));
425 if (OneOfOpCodeBuffer
== NULL
) {
431 // Go over again the Framework IFR binary to build the UEFI One Of Option opcodes.
433 FwOpHeader
= (FRAMEWORK_EFI_IFR_OP_HEADER
*) ((UINT8
*) FwOpcode
+ FwOpcode
->Header
.Length
);
434 while (FwOpHeader
->OpCode
!= EFI_IFR_END_ONE_OF_OP
) {
436 FwOneOfOp
= (FRAMEWORK_EFI_IFR_ONE_OF_OPTION
*) FwOpHeader
;
438 OpCodeBuffer
= F2UCreateOneOfOptionOpCode (UefiUpdateDataHandle
, (FRAMEWORK_EFI_IFR_ONE_OF_OPTION
*) FwOpHeader
, FwOpcode
->Width
);
439 if (OpCodeBuffer
== NULL
) {
443 OpCodeBuffer
= CreateGuidOptionKeyOpCode (UefiUpdateDataHandle
, UOpcode
.Question
.QuestionId
, FwOneOfOp
->Value
, FwOneOfOp
->Key
);
444 if (OpCodeBuffer
== NULL
) {
448 FwOpHeader
= (FRAMEWORK_EFI_IFR_OP_HEADER
*) ((UINT8
*) FwOpHeader
+ FwOpHeader
->Length
);
452 OpCodeBuffer
= HiiCreateEndOpCode (UefiUpdateDataHandle
);
453 if (OpCodeBuffer
!= NULL
) {
454 *NextFwOpcode
= (FRAMEWORK_EFI_IFR_OP_HEADER
*)((UINT8
*) FwOpHeader
+ FwOpHeader
->Length
);
458 return OneOfOpCodeBuffer
;
462 Create UEFI HII "Ordered List" Opcode from a Framework HII "Ordered List" Opcode.
464 @param UefiUpdateDataHandle The newly created UEFI HII opcode is appended to UefiUpdateDataHandle.
465 @param ThunkContext The HII Thunk Context.
466 @param FwOpcode The input Framework Opcode.
467 @param NextFwOpcode Returns the position of the next Framework Opcode after EFI_IFR_END_ONE_OF_OP of
469 @param OpcodeCount The number of Opcode for the complete Framework "Ordered List" Opcode.
471 @retval NULL There is not enough space left in Buffer to add the opcode.
472 @retval Other A pointer to the created opcode.
476 F2UCreateOrderedListOpCode (
477 IN OUT VOID
*UefiUpdateDataHandle
,
478 IN HII_THUNK_CONTEXT
*ThunkContext
,
479 IN CONST FRAMEWORK_EFI_IFR_ORDERED_LIST
*FwOpcode
,
480 OUT FRAMEWORK_EFI_IFR_OP_HEADER
**NextFwOpcode
,
481 OUT UINTN
*OpcodeCount
484 EFI_IFR_ORDERED_LIST UOpcode
;
486 FRAMEWORK_EFI_IFR_OP_HEADER
*FwOpHeader
;
487 FRAMEWORK_EFI_IFR_ONE_OF_OPTION
*FwOneOfOp
;
489 UINT8
*OrderListOpCode
;
491 ZeroMem (&UOpcode
, sizeof(UOpcode
));
494 UOpcode
.Header
.Length
= (UINT8
) sizeof (UOpcode
);
495 UOpcode
.Header
.OpCode
= EFI_IFR_ORDERED_LIST_OP
;
496 UOpcode
.Header
.Scope
= 1;
498 UOpcode
.Question
.Header
.Prompt
= FwOpcode
->Prompt
;
499 UOpcode
.Question
.Header
.Help
= FwOpcode
->Help
;
500 UOpcode
.Question
.VarStoreId
= ThunkContext
->FormSet
->DefaultVarStoreId
;
501 UOpcode
.Question
.VarStoreInfo
.VarOffset
= FwOpcode
->QuestionId
;
503 UOpcode
.MaxContainers
= FwOpcode
->MaxEntries
;
506 // Go over the Framework IFR binary to get the QuestionId for generated UEFI One Of Option opcode
508 FwOpHeader
= (FRAMEWORK_EFI_IFR_OP_HEADER
*) ((UINT8
*) FwOpcode
+ FwOpcode
->Header
.Length
);
509 while (FwOpHeader
->OpCode
!= EFI_IFR_END_ONE_OF_OP
) {
510 ASSERT (FwOpHeader
->OpCode
== FRAMEWORK_EFI_IFR_ONE_OF_OPTION_OP
);
512 FwOneOfOp
= (FRAMEWORK_EFI_IFR_ONE_OF_OPTION
*) FwOpHeader
;
513 if ((FwOneOfOp
->Flags
& EFI_IFR_FLAG_INTERACTIVE
) != 0) {
514 UOpcode
.Question
.Flags
|= EFI_IFR_FLAG_CALLBACK
;
516 if (UOpcode
.Question
.QuestionId
== 0) {
517 Status
= FwQIdToUefiQId (ThunkContext
->FormSet
, FwOpcode
->Header
.OpCode
, FwOpcode
->QuestionId
, &UOpcode
.Question
.QuestionId
);
518 if (EFI_ERROR (Status
)) {
519 UOpcode
.Question
.QuestionId
= AssignQuestionId (FwOneOfOp
->Key
, ThunkContext
->FormSet
);
525 if ((FwOneOfOp
->Flags
& EFI_IFR_FLAG_RESET_REQUIRED
) == EFI_IFR_FLAG_RESET_REQUIRED
) {
526 UOpcode
.Question
.Flags
|= EFI_IFR_FLAG_RESET_REQUIRED
;
529 FwOpHeader
= (FRAMEWORK_EFI_IFR_OP_HEADER
*) ((UINT8
*) FwOpHeader
+ FwOpHeader
->Length
);
532 if (UOpcode
.Question
.QuestionId
== 0) {
533 Status
= FwQIdToUefiQId (ThunkContext
->FormSet
, FwOpcode
->Header
.OpCode
, FwOpcode
->QuestionId
, &UOpcode
.Question
.QuestionId
);
534 if (EFI_ERROR (Status
)) {
535 UOpcode
.Question
.QuestionId
= AssignQuestionId (FwOpcode
->QuestionId
, ThunkContext
->FormSet
);
539 OrderListOpCode
= HiiCreateRawOpCodes (UefiUpdateDataHandle
, (UINT8
*) &UOpcode
, sizeof(UOpcode
));
540 if (OrderListOpCode
== NULL
) {
545 FwOpHeader
= (FRAMEWORK_EFI_IFR_OP_HEADER
*) ((UINT8
*) FwOpcode
+ FwOpcode
->Header
.Length
);
546 while (FwOpHeader
->OpCode
!= EFI_IFR_END_ONE_OF_OP
) {
548 // Each entry of Order List in Framework HII is always 1 byte in size
550 OpcodeBuffer
= F2UCreateOneOfOptionOpCode (UefiUpdateDataHandle
, (CONST FRAMEWORK_EFI_IFR_ONE_OF_OPTION
*) FwOpHeader
, 1);
551 if (OpcodeBuffer
== NULL
) {
554 FwOpHeader
= (FRAMEWORK_EFI_IFR_OP_HEADER
*) ((UINT8
*) FwOpHeader
+ FwOpHeader
->Length
);
558 OpcodeBuffer
= HiiCreateEndOpCode (UefiUpdateDataHandle
);
559 if (OpcodeBuffer
!= NULL
) {
560 *NextFwOpcode
= (FRAMEWORK_EFI_IFR_OP_HEADER
*)((UINT8
*) FwOpHeader
+ FwOpHeader
->Length
);
564 return OrderListOpCode
;
568 Create UEFI HII CheckBox Opcode from a Framework HII Checkbox Opcode.
570 @param UefiUpdateDataHandle The newly created UEFI HII opcode is appended to UefiUpdateDataHandle.
571 @param ThunkContext The HII Thunk Context.
572 @param FwOpcode The input Framework Opcode.
574 @retval NULL There is not enough space left in Buffer to add the opcode.
575 @retval Other A pointer to the created opcode.
579 F2UCreateCheckBoxOpCode (
580 IN OUT VOID
*UefiUpdateDataHandle
,
581 IN HII_THUNK_CONTEXT
*ThunkContext
,
582 IN CONST FRAMEWORK_EFI_IFR_CHECKBOX
*FwOpcode
586 EFI_IFR_CHECKBOX UOpcode
;
588 ZeroMem (&UOpcode
, sizeof(UOpcode
));
590 UOpcode
.Header
.Length
= (UINT8
) sizeof (UOpcode
);
591 UOpcode
.Header
.OpCode
= EFI_IFR_CHECKBOX_OP
;
593 UOpcode
.Question
.Header
.Prompt
= FwOpcode
->Prompt
;
594 UOpcode
.Question
.Header
.Help
= FwOpcode
->Help
;
596 if (FwOpcode
->Key
== 0) {
597 Status
= FwQIdToUefiQId (ThunkContext
->FormSet
, FwOpcode
->Header
.OpCode
, FwOpcode
->QuestionId
, &UOpcode
.Question
.QuestionId
);
598 if (EFI_ERROR (Status
)) {
600 // Add a new opcode and it will not trigger call back. So we just reuse the FW QuestionId.
602 UOpcode
.Question
.QuestionId
= AssignQuestionId (FwOpcode
->QuestionId
, ThunkContext
->FormSet
);
605 UOpcode
.Question
.QuestionId
= FwOpcode
->Key
;
610 // EFI_IFR_FLAG_INTERACTIVE,
611 // EFI_IFR_FLAG_RESET_REQUIRED,
612 // to UEFI IFR Opcode Question flags. The rest flags are obsolete.
614 UOpcode
.Question
.Flags
= (UINT8
) (FwOpcode
->Flags
& (EFI_IFR_FLAG_INTERACTIVE
| EFI_IFR_FLAG_RESET_REQUIRED
));
617 UOpcode
.Question
.VarStoreId
= ThunkContext
->FormSet
->DefaultVarStoreId
;
618 UOpcode
.Question
.VarStoreInfo
.VarOffset
= FwOpcode
->QuestionId
;
621 // We also map these 2 flags:
622 // EFI_IFR_FLAG_DEFAULT,
623 // EFI_IFR_FLAG_MANUFACTURING,
624 // to UEFI IFR CheckBox Opcode default flags.
626 UOpcode
.Flags
= (UINT8
) (FwOpcode
->Flags
& (EFI_IFR_FLAG_DEFAULT
| EFI_IFR_FLAG_MANUFACTURING
));
628 return HiiCreateRawOpCodes (UefiUpdateDataHandle
, (UINT8
*) &UOpcode
, sizeof(UOpcode
));
633 Create UEFI HII Numeric Opcode from a Framework HII Numeric Opcode.
635 @param UefiUpdateDataHandle The newly created UEFI HII opcode is appended to UefiUpdateDataHandle.
636 @param ThunkContext The HII Thunk Context.
637 @param FwOpcode The input Framework Opcode.
639 @retval NULL There is not enough space left in Buffer to add the opcode.
640 @retval Other A pointer to the created opcode.
644 F2UCreateNumericOpCode (
645 IN OUT VOID
*UefiUpdateDataHandle
,
646 IN HII_THUNK_CONTEXT
*ThunkContext
,
647 IN CONST FRAMEWORK_EFI_IFR_NUMERIC
*FwOpcode
651 EFI_IFR_NUMERIC UOpcode
;
652 EFI_IFR_DEFAULT UOpcodeDefault
;
653 UINT8
*NumbericOpCode
;
656 ZeroMem (&UOpcode
, sizeof(UOpcode
));
658 if (FwOpcode
->Key
== 0) {
659 Status
= FwQIdToUefiQId (ThunkContext
->FormSet
, FwOpcode
->Header
.OpCode
, FwOpcode
->QuestionId
, &UOpcode
.Question
.QuestionId
);
660 if (EFI_ERROR (Status
)) {
662 // Add a new opcode and it will not trigger call back. So we just reuse the FW QuestionId.
664 UOpcode
.Question
.QuestionId
= AssignQuestionId (FwOpcode
->QuestionId
, ThunkContext
->FormSet
);
667 UOpcode
.Question
.QuestionId
= FwOpcode
->Key
;
670 UOpcode
.Header
.Length
= (UINT8
) sizeof (UOpcode
);
671 UOpcode
.Header
.OpCode
= EFI_IFR_NUMERIC_OP
;
673 // We need to create a nested default value for the UEFI Numeric Opcode.
674 // So turn on the scope.
676 UOpcode
.Header
.Scope
= 1;
678 UOpcode
.Question
.Header
.Prompt
= FwOpcode
->Prompt
;
679 UOpcode
.Question
.Header
.Help
= FwOpcode
->Help
;
681 UOpcode
.Question
.VarStoreId
= ThunkContext
->FormSet
->DefaultVarStoreId
;
682 UOpcode
.Question
.VarStoreInfo
.VarOffset
= FwOpcode
->QuestionId
;
684 UOpcode
.Question
.Flags
= (UINT8
) (FwOpcode
->Flags
& (EFI_IFR_FLAG_INTERACTIVE
| EFI_IFR_FLAG_RESET_REQUIRED
));
687 // Framework Numeric values are all in UINT16 and displayed as decimal.
689 UOpcode
.data
.u16
.MinValue
= FwOpcode
->Minimum
;
690 UOpcode
.data
.u16
.MaxValue
= FwOpcode
->Maximum
;
691 UOpcode
.data
.u16
.Step
= FwOpcode
->Step
;
693 switch (FwOpcode
->Width
) {
696 UOpcode
.Flags
= EFI_IFR_NUMERIC_SIZE_1
| EFI_IFR_DISPLAY_UINT_DEC
;
701 UOpcode
.Flags
= EFI_IFR_NUMERIC_SIZE_2
| EFI_IFR_DISPLAY_UINT_DEC
;
711 NumbericOpCode
= HiiCreateRawOpCodes (UefiUpdateDataHandle
, (UINT8
*) &UOpcode
, sizeof(UOpcode
));
712 if (NumbericOpCode
== NULL
) {
717 // We need to create a default value.
719 ZeroMem (&UOpcodeDefault
, sizeof (UOpcodeDefault
));
720 UOpcodeDefault
.Header
.Length
= (UINT8
) sizeof (UOpcodeDefault
);
721 UOpcodeDefault
.Header
.OpCode
= EFI_IFR_DEFAULT_OP
;
723 UOpcodeDefault
.DefaultId
= 0;
725 switch (FwOpcode
->Width
) {
728 UOpcodeDefault
.Type
= EFI_IFR_TYPE_NUM_SIZE_8
;
733 UOpcodeDefault
.Type
= EFI_IFR_TYPE_NUM_SIZE_16
;
738 CopyMem (&UOpcodeDefault
.Value
.u8
, &FwOpcode
->Default
, FwOpcode
->Width
);
740 OpcodeBuffer
= HiiCreateRawOpCodes (UefiUpdateDataHandle
, (UINT8
*) &UOpcodeDefault
, sizeof(UOpcodeDefault
));
741 if (OpcodeBuffer
== NULL
) {
745 OpcodeBuffer
= HiiCreateEndOpCode (UefiUpdateDataHandle
);
746 if (OpcodeBuffer
== NULL
) {
750 return NumbericOpCode
;
755 Create UEFI HII String Opcode from a Framework HII String Opcode.
757 @param UefiUpdateDataHandle The newly created UEFI HII opcode is appended to UefiUpdateDataHandle.
758 @param ThunkContext The HII Thunk Context.
759 @param FwOpcode The input Framework Opcode.
761 @retval NULL There is not enough space left in Buffer to add the opcode.
762 @retval Other A pointer to the created opcode.
766 F2UCreateStringOpCode (
767 IN OUT VOID
*UefiUpdateDataHandle
,
768 IN HII_THUNK_CONTEXT
*ThunkContext
,
769 IN CONST FRAMEWORK_EFI_IFR_STRING
*FwOpcode
772 EFI_IFR_STRING UOpcode
;
775 ZeroMem (&UOpcode
, sizeof(UOpcode
));
777 if (FwOpcode
->Key
== 0) {
778 Status
= FwQIdToUefiQId (ThunkContext
->FormSet
, FwOpcode
->Header
.OpCode
, FwOpcode
->QuestionId
, &UOpcode
.Question
.QuestionId
);
779 if (EFI_ERROR (Status
)) {
781 // Add a new opcode and it will not trigger call back. So we just reuse the FW QuestionId.
783 UOpcode
.Question
.QuestionId
= AssignQuestionId (FwOpcode
->QuestionId
, ThunkContext
->FormSet
);
786 UOpcode
.Question
.QuestionId
= FwOpcode
->Key
;
789 UOpcode
.Header
.Length
= (UINT8
) sizeof (UOpcode
);
790 UOpcode
.Header
.OpCode
= EFI_IFR_STRING_OP
;
792 UOpcode
.Question
.Header
.Prompt
= FwOpcode
->Prompt
;
793 UOpcode
.Question
.Header
.Help
= FwOpcode
->Help
;
795 UOpcode
.Question
.Flags
= (UINT8
) (FwOpcode
->Flags
& (EFI_IFR_FLAG_INTERACTIVE
| EFI_IFR_FLAG_RESET_REQUIRED
));
797 UOpcode
.Question
.VarStoreId
= ThunkContext
->FormSet
->DefaultVarStoreId
;
798 UOpcode
.Question
.VarStoreInfo
.VarOffset
= FwOpcode
->QuestionId
;
800 UOpcode
.MinSize
= FwOpcode
->MinSize
;
801 UOpcode
.MaxSize
= FwOpcode
->MaxSize
;
802 UOpcode
.Flags
= EFI_IFR_STRING_MULTI_LINE
;
804 return HiiCreateRawOpCodes (UefiUpdateDataHandle
, (UINT8
*) &UOpcode
, sizeof(UOpcode
));
808 Create UEFI HII Banner Opcode from a Framework HII Banner Opcode.
810 @param UefiUpdateDataHandle The newly created UEFI HII opcode is appended to UefiUpdateDataHandle.
811 @param FwOpcode The input Framework Opcode.
813 @retval NULL There is not enough space left in Buffer to add the opcode.
814 @retval Other A pointer to the created opcode.
818 F2UCreateBannerOpCode (
819 IN OUT VOID
*UefiUpdateDataHandle
,
820 IN CONST EFI_IFR_BANNER
*FwOpcode
823 EFI_IFR_GUID_BANNER
*UOpcode
;
825 UOpcode
= (EFI_IFR_GUID_BANNER
*) HiiCreateGuidOpCode (
826 UefiUpdateDataHandle
,
829 sizeof (EFI_IFR_GUID_BANNER
)
832 UOpcode
->ExtendOpCode
= EFI_IFR_EXTEND_OP_BANNER
;
833 UOpcode
->Title
= FwOpcode
->Title
;
834 UOpcode
->LineNumber
= FwOpcode
->LineNumber
;
835 UOpcode
->Alignment
= FwOpcode
->Alignment
;
837 return (UINT8
*) UOpcode
;
841 Create a Hii Update data Handle used to call IfrLibUpdateForm.
843 @param ThunkContext The HII Thunk Context.
844 @param FwUpdateData The Framework Update Data.
845 @param UefiOpCodeHandle The UEFI opcode handle.
847 @retval EFI_SUCCESS The UEFI Update Data is created successfully.
848 @retval EFI_UNSUPPORTED There is unsupported opcode in FwUpdateData.
849 @retval EFI_OUT_OF_RESOURCES There is not enough resource.
852 FwUpdateDataToUefiUpdateData (
853 IN HII_THUNK_CONTEXT
*ThunkContext
,
854 IN CONST EFI_HII_UPDATE_DATA
*FwUpdateData
,
855 IN VOID
*UefiOpCodeHandle
858 FRAMEWORK_EFI_IFR_OP_HEADER
*FwOpCode
;
859 FRAMEWORK_EFI_IFR_OP_HEADER
*NextFwOpCode
;
863 LIST_ENTRY
*StorageList
;
864 FORMSET_STORAGE
*Storage
;
865 FORM_BROWSER_FORMSET
*FormSet
;
866 CHAR16
*DefaultVarStoreName
;
867 UINT16 DefaultVarStoreId
;
868 EFI_IFR_VARSTORE_SELECT
*SelectVarOp
;
870 FwOpCode
= (FRAMEWORK_EFI_IFR_OP_HEADER
*) &FwUpdateData
->Data
;
872 FormSet
= ThunkContext
->FormSet
;
873 DefaultVarStoreId
= FormSet
->DefaultVarStoreId
;
874 DefaultVarStoreName
= FormSet
->OriginalDefaultVarStoreName
;
876 for (Index
= 0; Index
< FwUpdateData
->DataCount
; Index
+= DataCount
) {
877 switch (FwOpCode
->OpCode
) {
878 case FRAMEWORK_EFI_IFR_SUBTITLE_OP
:
879 OpCodeBuffer
= HiiCreateSubTitleOpCode (UefiOpCodeHandle
, ((FRAMEWORK_EFI_IFR_SUBTITLE
*) FwOpCode
)->SubTitle
, 0, 0, 0);
883 case FRAMEWORK_EFI_IFR_TEXT_OP
:
884 OpCodeBuffer
= F2UCreateTextOpCode (UefiOpCodeHandle
, (FRAMEWORK_EFI_IFR_TEXT
*) FwOpCode
);
888 case FRAMEWORK_EFI_IFR_REF_OP
:
889 OpCodeBuffer
= F2UCreateReferenceOpCode (UefiOpCodeHandle
, (FRAMEWORK_EFI_IFR_REF
*) FwOpCode
);
893 case FRAMEWORK_EFI_IFR_ONE_OF_OP
:
894 OpCodeBuffer
= F2UCreateOneOfOpCode (UefiOpCodeHandle
, ThunkContext
, (FRAMEWORK_EFI_IFR_ONE_OF
*) FwOpCode
, &NextFwOpCode
, &DataCount
);
895 if (OpCodeBuffer
!= NULL
) {
896 FwOpCode
= NextFwOpCode
;
898 // FwOpCode is already updated to point to the next opcode.
904 case FRAMEWORK_EFI_IFR_ORDERED_LIST_OP
:
905 OpCodeBuffer
= F2UCreateOrderedListOpCode (UefiOpCodeHandle
, ThunkContext
, (FRAMEWORK_EFI_IFR_ORDERED_LIST
*) FwOpCode
, &NextFwOpCode
, &DataCount
);
906 if (OpCodeBuffer
!= NULL
) {
907 FwOpCode
= NextFwOpCode
;
909 // FwOpCode is already updated to point to the next opcode.
915 case FRAMEWORK_EFI_IFR_CHECKBOX_OP
:
916 OpCodeBuffer
= F2UCreateCheckBoxOpCode (UefiOpCodeHandle
, ThunkContext
, (FRAMEWORK_EFI_IFR_CHECKBOX
*) FwOpCode
);
920 case FRAMEWORK_EFI_IFR_STRING_OP
:
921 OpCodeBuffer
= F2UCreateStringOpCode (UefiOpCodeHandle
, ThunkContext
, (FRAMEWORK_EFI_IFR_STRING
*) FwOpCode
);
925 case EFI_IFR_BANNER_OP
:
926 OpCodeBuffer
= F2UCreateBannerOpCode (UefiOpCodeHandle
, (EFI_IFR_BANNER
*) FwOpCode
);
930 case EFI_IFR_END_ONE_OF_OP
:
931 OpCodeBuffer
= HiiCreateEndOpCode (UefiOpCodeHandle
);
935 case FRAMEWORK_EFI_IFR_NUMERIC_OP
:
936 OpCodeBuffer
= F2UCreateNumericOpCode (UefiOpCodeHandle
, ThunkContext
, (FRAMEWORK_EFI_IFR_NUMERIC
*) FwOpCode
);
940 case EFI_IFR_VARSTORE_SELECT_OP
:
941 OpCodeBuffer
= (UINT8
*) FwOpCode
;
942 SelectVarOp
= (EFI_IFR_VARSTORE_SELECT
*) FwOpCode
;
944 // Check whether the selected VarId is in StorageList.
946 StorageList
= GetFirstNode (&FormSet
->StorageListHead
);
947 while (!IsNull (&FormSet
->StorageListHead
, StorageList
)) {
948 Storage
= FORMSET_STORAGE_FROM_LINK (StorageList
);
949 if (Storage
->VarStoreId
== SelectVarOp
->VarId
) {
952 StorageList
= GetNextNode (&FormSet
->StorageListHead
, StorageList
);
954 ASSERT (!IsNull (&FormSet
->StorageListHead
, StorageList
));
956 // Change VarStoreId to the selected VarId.
958 FormSet
->DefaultVarStoreId
= SelectVarOp
->VarId
;
959 if (SelectVarOp
->VarId
== DefaultVarStoreId
) {
960 FormSet
->OriginalDefaultVarStoreName
= DefaultVarStoreName
;
967 return EFI_UNSUPPORTED
;
970 if (OpCodeBuffer
== NULL
) {
971 return EFI_OUT_OF_RESOURCES
;
974 FwOpCode
= (FRAMEWORK_EFI_IFR_OP_HEADER
*)((UINT8
*) FwOpCode
+ FwOpCode
->Length
);
978 // Revert FromSet default varstore ID.
980 FormSet
->DefaultVarStoreId
= DefaultVarStoreId
;
981 FormSet
->OriginalDefaultVarStoreName
= DefaultVarStoreName
;