]> git.proxmox.com Git - mirror_edk2.git/blame - EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/OpcodeCreation.c
Correct FeatureFlagExpress PCD format based on INF spec.
[mirror_edk2.git] / EdkCompatibilityPkg / Compatibility / FrameworkHiiToUefiHiiThunk / OpcodeCreation.c
CommitLineData
5391c4f1 1/** @file\r
2Implement Functions to convert IFR Opcode in format defined in Framework HII specification to\r
3format defined in UEFI HII Specification.\r
4\r
5Copyright (c) 2007, Intel Corporation\r
6All rights reserved. This program and the accompanying materials\r
7are licensed and made available under the terms and conditions of the BSD License\r
8which accompanies this distribution. The full text of the license may be found at\r
9http://opensource.org/licenses/bsd-license.php\r
10\r
11THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
12WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
13\r
14**/\r
03254710 15\r
5391c4f1 16#include "HiiDatabase.h"\r
5391c4f1 17#include "UefiIfrDefault.h"\r
18\r
19EFI_GUID mTianoExtendedOpcodeGuid = EFI_IFR_TIANO_GUID;\r
20\r
a9d85320 21\r
22EFI_IFR_GUID_OPTIONKEY mOptionKeyTemplate = {\r
23 {EFI_IFR_GUID_OP, sizeof (EFI_IFR_GUID_OPTIONKEY), 0},\r
24 EFI_IFR_FRAMEWORK_GUID,\r
25 EFI_IFR_EXTEND_OP_OPTIONKEY,\r
26 0,\r
725c7e22 27 {0},\r
a9d85320 28 0\r
29};\r
30\r
03254710 31/**\r
32 The dynamic creation of these opcodes is supported in Framework HII modules.\r
33 Therefore, Framework HII Thunk module only map these opcode between Framework\r
34 HII's definitions to UEFI HII's.\r
35**/\r
a9d85320 36typedef struct { \r
37 UINT8 FrameworkIfrOp;\r
38 UINT8 UefiIfrOp;\r
39} IFR_OPCODE_MAP;\r
03254710 40 \r
a9d85320 41IFR_OPCODE_MAP mQuestionOpcodeMap [] = {\r
42 { FRAMEWORK_EFI_IFR_ONE_OF_OP, EFI_IFR_ONE_OF_OP},\r
43 { FRAMEWORK_EFI_IFR_CHECKBOX_OP, EFI_IFR_CHECKBOX_OP},\r
44 { FRAMEWORK_EFI_IFR_NUMERIC_OP, EFI_IFR_NUMERIC_OP},\r
45 { FRAMEWORK_EFI_IFR_ONE_OF_OPTION_OP, EFI_IFR_ONE_OF_OPTION_OP},\r
46 { FRAMEWORK_EFI_IFR_ORDERED_LIST_OP, EFI_IFR_ORDERED_LIST_OP}\r
47};\r
48\r
03254710 49/**\r
50 Translate a Framework Question Opcode to UEFI Question Opcode.\r
51\r
52 @param FwOp Framework Opcode.\r
53 @param UefiOp UEFI Opcode.\r
54\r
55 @retval EFI_SUCCESS The UEFI opcode is found and returned.\r
56 @retval EFI_NOT_FOUND The UEFI opcode is not found.\r
57**/\r
a9d85320 58EFI_STATUS\r
59QuestionOpFwToUefi (\r
60 IN UINT8 FwOp,\r
61 OUT UINT8 *UefiOp\r
62 )\r
63{\r
64 UINTN Index;\r
65\r
66 for (Index = 0; Index < sizeof (mQuestionOpcodeMap) / sizeof (mQuestionOpcodeMap[0]); Index++) {\r
67 if (FwOp == mQuestionOpcodeMap[Index].FrameworkIfrOp) {\r
68 *UefiOp = mQuestionOpcodeMap[Index].UefiIfrOp;\r
69 return EFI_SUCCESS;\r
70 }\r
71 }\r
72\r
e24d48ac 73 *UefiOp = (UINT8) (FRAMEWORK_EFI_IFR_LAST_OPCODE + 1);\r
a9d85320 74 return EFI_NOT_FOUND;\r
75}\r
76\r
03254710 77/**\r
78 Translate a Framework Question Opcode to UEFI Question Opcode.\r
79\r
80 @param FwOp Framework Opcode.\r
81 @param UefiOp UEFI Opcode.\r
a9d85320 82\r
03254710 83 @retval EFI_SUCCESS The UEFI opcode is found and returned.\r
84 @retval EFI_NOT_FOUND The UEFI opcode is not found.\r
85**/\r
a9d85320 86EFI_STATUS\r
87FwQIdToUefiQId (\r
88 IN CONST FORM_BROWSER_FORMSET *FormSet,\r
a9d85320 89 IN UINT8 FwOpCode,\r
90 IN UINT16 FwQId,\r
91 OUT UINT16 *UefiQId\r
92 )\r
93{\r
94 LIST_ENTRY *FormList;\r
95 LIST_ENTRY *StatementList;\r
96 FORM_BROWSER_FORM *Form;\r
97 FORM_BROWSER_STATEMENT *Statement;\r
03254710 98 FORM_BROWSER_STATEMENT *StatementFound;\r
a9d85320 99 EFI_STATUS Status;\r
100 UINT8 UefiOp;\r
03254710 101 \r
a9d85320 102\r
103 *UefiQId = 0;\r
03254710 104 StatementFound = NULL;\r
a9d85320 105\r
106 FormList = GetFirstNode (&FormSet->FormListHead);\r
107\r
108 while (!IsNull (&FormSet->FormListHead, FormList)) {\r
109 Form = FORM_BROWSER_FORM_FROM_LINK (FormList);\r
110\r
111 StatementList = GetFirstNode (&Form->StatementListHead);\r
112\r
113 while (!IsNull (&Form->StatementListHead, StatementList)) {\r
114 Statement = FORM_BROWSER_STATEMENT_FROM_LINK (StatementList);\r
115 if (Statement->VarStoreId != 0 && Statement->Storage->Type == EFI_HII_VARSTORE_BUFFER) {\r
116 if (FwQId == Statement->VarStoreInfo.VarOffset) {\r
117 Status = QuestionOpFwToUefi (FwOpCode, &UefiOp);\r
118 ASSERT_EFI_ERROR (Status);\r
119\r
03254710 120 if ((UefiOp == Statement->Operand) && (FormSet->DefaultVarStoreId == Statement->VarStoreId)) {\r
a9d85320 121 //\r
03254710 122 // If ASSERT here, the Framework VFR file has two Questions with all three attibutes the same:\r
123 // 1) Same Question Type, \r
124 // 2) Same Variable Storage\r
125 // 3) Refering to the Same offset in Variable Map (NvMap). \r
126 // This is ambigurity as FwQIdToUefiQId () can't find which UEFI Question \r
127 // ID to return. \r
a9d85320 128 //\r
03254710 129 // One possible solution is to remove the one of the duplicated questions in this Form Set.\r
a9d85320 130 //\r
03254710 131 ASSERT (StatementFound == NULL);\r
132 StatementFound= Statement;\r
a9d85320 133\r
03254710 134 //\r
135 // Continue the search to check if the Form Set contains more than one questins that has the 3 attributes\r
136 // with same value.\r
137 //\r
a9d85320 138 }\r
139 }\r
140 }\r
141\r
142 StatementList = GetNextNode (&Form->StatementListHead, StatementList);\r
143 }\r
144\r
145 FormList = GetNextNode (&FormSet->FormListHead, FormList);\r
146 }\r
03254710 147\r
148 if (StatementFound != NULL) {\r
149 *UefiQId = StatementFound->QuestionId;\r
150 return EFI_SUCCESS;\r
151 }\r
a9d85320 152 \r
153 return EFI_NOT_FOUND;\r
154}\r
155\r
156\r
157\r
5391c4f1 158#define LOCAL_UPDATE_DATA_BUFFER_INCREMENTAL 0x1000\r
03254710 159/**\r
160 Append the newly created OpCode buffer to EFI_HII_UPDATE_DATA buffer.\r
161 Increase the Data buffer in EFI_HII_UPDATE_DATA if the EFI_HII_UPDATE_DATA \r
162 buffer's Data Buffer does not have space left for the newly created\r
163 OpCode.\r
164\r
165 @param OpCodeBuf The newly created OpCode Buffer to be appended to \r
166 EFI_HII_UPDATE_DATA buffer.\r
167 @param OpCodeBufSize The size of OpCodeBuf.\r
168 @param UefiUpdateData The EFI_HII_UPDATE_DATA to be appended.\r
169\r
170 @retval EFI_SUCCESS The OpCode buffer is appended to EFI_HII_UPDATE_DATA successfull.\r
171 @retval EFI_OUT_OF_RESOURCES There is not enough memory.\r
172**/\r
5391c4f1 173EFI_STATUS\r
174AppendToUpdateBuffer (\r
175 IN CONST UINT8 *OpCodeBuf,\r
03254710 176 IN UINTN OpCodeBufSize,\r
177 IN OUT EFI_HII_UPDATE_DATA *UefiUpdateData\r
5391c4f1 178 )\r
179{\r
180 UINT8 * NewBuff;\r
181 \r
03254710 182 if (UefiUpdateData->Offset + OpCodeBufSize > UefiUpdateData->BufferSize) {\r
183 NewBuff = AllocateCopyPool (UefiUpdateData->BufferSize + LOCAL_UPDATE_DATA_BUFFER_INCREMENTAL, UefiUpdateData->Data);\r
5391c4f1 184 if (NewBuff == NULL) {\r
185 return EFI_OUT_OF_RESOURCES;\r
186 }\r
03254710 187 UefiUpdateData->BufferSize += LOCAL_UPDATE_DATA_BUFFER_INCREMENTAL;\r
188 FreePool (UefiUpdateData->Data);\r
189 UefiUpdateData->Data = NewBuff;\r
5391c4f1 190 }\r
191 \r
03254710 192 CopyMem (UefiUpdateData->Data + UefiUpdateData->Offset, OpCodeBuf, OpCodeBufSize);\r
193 UefiUpdateData->Offset += (UINT32) OpCodeBufSize;\r
5391c4f1 194\r
195 return EFI_SUCCESS;\r
196}\r
197\r
03254710 198/**\r
199 Assign a Question ID.\r
200\r
201 If FwQuestionId is 0, then assign a new question ID. The new question ID\r
202 is MaxQuestionId incremented by 1. The MaxQuestionId of FormSet is also\r
203 incremented by 1.\r
204\r
205 If FwQuestionId is not 0, then it is used as the Framework Question ID.\r
206\r
207 @return The Framework Question ID.\r
208**/\r
8ea58c07 209EFI_QUESTION_ID\r
210AssignQuestionId (\r
a9d85320 211 IN UINT16 FwQuestionId,\r
212 IN FORM_BROWSER_FORMSET *FormSet\r
8ea58c07 213 )\r
214{\r
215 if (FwQuestionId == 0) {\r
a9d85320 216 FormSet->MaxQuestionId++;\r
217 return FormSet->MaxQuestionId;\r
8ea58c07 218 } else {\r
219 return FwQuestionId;\r
220 }\r
221}\r
0368663f 222\r
03254710 223/**\r
224 Create UEFI HII "End Of" Opcode and append it to UefiUpdateData buffer.\r
225\r
226 @param UefiUpdateData The newly created UEFI HII opcode is appended to UefiUpdateData.\r
227\r
228 @retval EFI_SUCCESS The UEFI HII opcode is created successfully and appended to UefiUpdateData.\r
229 @retval EFI_OUT_OF_RESOURCE There is not enough resource.\r
230 \r
231**/\r
5391c4f1 232EFI_STATUS\r
233UCreateEndOfOpcode (\r
03254710 234 IN OUT EFI_HII_UPDATE_DATA *UefiUpdateData\r
5391c4f1 235 )\r
236{\r
237 EFI_IFR_END UOpcode;\r
238\r
239 ZeroMem (&UOpcode, sizeof (UOpcode));\r
240\r
241 UOpcode.Header.OpCode = EFI_IFR_END_OP;\r
242 UOpcode.Header.Length = sizeof (UOpcode);\r
243\r
03254710 244 return AppendToUpdateBuffer ((UINT8 *)&UOpcode, sizeof(UOpcode), UefiUpdateData);\r
5391c4f1 245}\r
246\r
03254710 247/**\r
248 Create UEFI HII Subtitle Opcode from a Framework HII Subtitle Opcode.\r
249\r
250 @param FwOpcode The input Framework Opcode.\r
251 @param UefiUpdateData The newly created UEFI HII opcode is appended to UefiUpdateData.\r
252\r
253 @retval EFI_SUCCESS The UEFI HII opcode is created successfully and appended to UefiUpdateData.\r
254 @retval EFI_OUT_OF_RESOURCE There is not enough resource.\r
255 \r
256**/\r
5391c4f1 257EFI_STATUS\r
258F2UCreateSubtitleOpCode (\r
03254710 259 IN CONST FRAMEWORK_EFI_IFR_SUBTITLE *FwOpcode,\r
260 IN OUT EFI_HII_UPDATE_DATA *UefiUpdateData\r
5391c4f1 261 )\r
262{\r
263 EFI_IFR_SUBTITLE UOpcode;\r
264\r
265 ZeroMem (&UOpcode, sizeof(UOpcode));\r
266\r
267 UOpcode.Header.OpCode = EFI_IFR_SUBTITLE_OP;\r
268 UOpcode.Header.Length = sizeof (EFI_IFR_SUBTITLE);\r
269\r
03254710 270 UOpcode.Statement.Prompt = FwOpcode->SubTitle;\r
5391c4f1 271\r
03254710 272 return AppendToUpdateBuffer ((UINT8 *)&UOpcode, sizeof(UOpcode), UefiUpdateData);\r
5391c4f1 273}\r
274\r
03254710 275/**\r
276 Create UEFI HII Text Opcode from a Framework HII Text Opcode.\r
277\r
278 @param FwOpcode The input Framework Opcode.\r
279 @param UefiUpdateData The newly created UEFI HII opcode is appended to UefiUpdateData.\r
280\r
281 @retval EFI_SUCCESS The UEFI HII opcode is created successfully and appended to UefiUpdateData.\r
282 @retval EFI_OUT_OF_RESOURCE There is not enough resource.\r
283 \r
284**/\r
5391c4f1 285EFI_STATUS\r
286F2UCreateTextOpCode (\r
03254710 287 IN CONST FRAMEWORK_EFI_IFR_TEXT *FwOpcode,\r
288 IN OUT EFI_HII_UPDATE_DATA *UefiUpdateData\r
5391c4f1 289 )\r
290{\r
0368663f 291 EFI_IFR_TEXT UTextOpCode;\r
292 EFI_IFR_ACTION UActionOpCode;\r
5391c4f1 293\r
03254710 294 if ((FwOpcode->Flags & FRAMEWORK_EFI_IFR_FLAG_INTERACTIVE) == 0) {\r
0368663f 295 ZeroMem (&UTextOpCode, sizeof(UTextOpCode));\r
296 \r
297 UTextOpCode.Header.OpCode = EFI_IFR_TEXT_OP;\r
298 UTextOpCode.Header.Length = sizeof (EFI_IFR_TEXT);\r
5391c4f1 299\r
03254710 300 UTextOpCode.Statement.Help = FwOpcode->Help;\r
5391c4f1 301\r
03254710 302 UTextOpCode.Statement.Prompt = FwOpcode->Text;\r
303 UTextOpCode.TextTwo = FwOpcode->TextTwo;\r
0368663f 304 \r
03254710 305 return AppendToUpdateBuffer ((UINT8 *) &UTextOpCode, sizeof(UTextOpCode), UefiUpdateData);\r
0368663f 306 } else {\r
307 //\r
308 // Iteractive Text Opcode is EFI_IFR_ACTION\r
309 //\r
310\r
311 ZeroMem (&UActionOpCode, sizeof (UActionOpCode));\r
312\r
313 UActionOpCode.Header.OpCode = EFI_IFR_ACTION_OP;\r
314 UActionOpCode.Header.Length = sizeof (EFI_IFR_ACTION);\r
315\r
03254710 316 UActionOpCode.Question.Header.Prompt = FwOpcode->Text;\r
317 UActionOpCode.Question.Header.Help = FwOpcode->Help;\r
0368663f 318 UActionOpCode.Question.Flags = EFI_IFR_FLAG_CALLBACK;\r
03254710 319 UActionOpCode.Question.QuestionId = FwOpcode->Key;\r
0368663f 320\r
03254710 321 return AppendToUpdateBuffer ((UINT8 *) &UActionOpCode, sizeof(UActionOpCode), UefiUpdateData);\r
0368663f 322 \r
323 }\r
5391c4f1 324}\r
325\r
03254710 326/**\r
327 Create UEFI HII Reference Opcode from a Framework HII Reference Opcode.\r
328\r
329 @param FwOpcode The input Framework Opcode.\r
330 @param UefiUpdateData The newly created UEFI HII opcode is appended to UefiUpdateData.\r
331\r
332 @retval EFI_SUCCESS The UEFI HII opcode is created successfully and appended to UefiUpdateData.\r
333 @retval EFI_OUT_OF_RESOURCE There is not enough resource.\r
334 \r
335**/\r
5391c4f1 336EFI_STATUS\r
03254710 337F2UCreateReferenceOpCode (\r
5391c4f1 338 IN CONST FRAMEWORK_EFI_IFR_REF *FwOpcode,\r
03254710 339 IN OUT EFI_HII_UPDATE_DATA *UefiUpdateData\r
5391c4f1 340 )\r
341{\r
342 EFI_IFR_REF UOpcode;\r
343\r
344 ZeroMem (&UOpcode, sizeof(UOpcode));\r
345\r
346 UOpcode.Header.Length = sizeof(UOpcode);\r
347 UOpcode.Header.OpCode = EFI_IFR_REF_OP;\r
348\r
349 UOpcode.Question.Header.Prompt = FwOpcode->Prompt;\r
350 UOpcode.Question.Header.Help = FwOpcode->Help;\r
351 UOpcode.Question.QuestionId = FwOpcode->Key;\r
352\r
353 UOpcode.FormId = FwOpcode->FormId;\r
354\r
355 //\r
356 // We only map FRAMEWORK_EFI_IFR_FLAG_INTERACTIVE and FRAMEWORK_EFI_IFR_FLAG_RESET_REQUIRED to \r
357 // UEFI IFR Opcode flags. The rest flags are obsolete.\r
358 //\r
98b16b9d 359 UOpcode.Question.Flags = (UINT8) (FwOpcode->Flags & (FRAMEWORK_EFI_IFR_FLAG_INTERACTIVE | FRAMEWORK_EFI_IFR_FLAG_RESET_REQUIRED));\r
5391c4f1 360 \r
361\r
03254710 362 return AppendToUpdateBuffer ((UINT8 *) &UOpcode, sizeof(UOpcode), UefiUpdateData);\r
5391c4f1 363}\r
364\r
365\r
03254710 366/**\r
367 Create UEFI HII "One Of Option" Opcode from a Framework HII "One Of Option" Opcode.\r
368\r
369 @param FwOpcode The input Framework Opcode.\r
370 @param Width The size of the One Of Option. 1 bytes or 2 bytes.\r
371 @param UefiUpdateData The newly created UEFI HII opcode is appended to UefiUpdateData.\r
372\r
373 @retval EFI_SUCCESS The UEFI HII opcode is created successfully and appended to UefiUpdateData.\r
374 @retval EFI_OUT_OF_RESOURCE There is not enough resource.\r
375 \r
376**/\r
5391c4f1 377EFI_STATUS\r
378F2UCreateOneOfOptionOpCode (\r
379 IN CONST FRAMEWORK_EFI_IFR_ONE_OF_OPTION *FwOpcode,\r
380 IN UINTN Width,\r
03254710 381 IN OUT EFI_HII_UPDATE_DATA *UefiUpdateData\r
5391c4f1 382 )\r
383{\r
384 EFI_IFR_ONE_OF_OPTION UOpcode;\r
385\r
386 ZeroMem (&UOpcode, sizeof(UOpcode));\r
387\r
388 UOpcode.Header.Length = sizeof(UOpcode);\r
389 UOpcode.Header.OpCode = EFI_IFR_ONE_OF_OPTION_OP;\r
390\r
391 UOpcode.Option = FwOpcode->Option;\r
392 CopyMem (&UOpcode.Value.u8, &FwOpcode->Value, Width);\r
393\r
394 //\r
03254710 395 // #define FRAMEWORK_EFI_IFR_FLAG_DEFAULT 0x01\r
396 // #define FRAMEWORK_EFI_IFR_FLAG_MANUFACTURING 0x02\r
397 // #define EFI_IFR_OPTION_DEFAULT 0x10\r
398 // #define EFI_IFR_OPTION_DEFAULT_MFG 0x20\r
5391c4f1 399 //\r
98b16b9d 400 UOpcode.Flags = (UINT8) (UOpcode.Flags | (FwOpcode->Flags & (FRAMEWORK_EFI_IFR_FLAG_DEFAULT | FRAMEWORK_EFI_IFR_FLAG_MANUFACTURING)) << 4);\r
5391c4f1 401\r
402 switch (Width) {\r
403 case 1:\r
404 UOpcode.Type = EFI_IFR_TYPE_NUM_SIZE_8;\r
405 break;\r
406 \r
407 case 2:\r
408 UOpcode.Type = EFI_IFR_TYPE_NUM_SIZE_16;\r
409 break;\r
410 \r
411 default:\r
412 ASSERT (FALSE);\r
413 return EFI_UNSUPPORTED;\r
414 }\r
415\r
03254710 416 return AppendToUpdateBuffer ((UINT8 *) &UOpcode, sizeof(UOpcode), UefiUpdateData);\r
5391c4f1 417}\r
418\r
03254710 419/**\r
420 Create a GUID Opcode EFI_IFR_GUID_OPTIONKEY to map the Framework One Of Option callback key\r
421 to a UEFI Question ID. This information is used to invoke the Framework HII Browser Callback\r
422 function. The opcode is appened to UefiUpdateData.\r
423\r
424 @param QuestionId The UEFI Question ID.\r
425 @param OptionValue The value of the "One Of Option".\r
426 @param KeyValue The Framework "One Of Option" callback key.\r
427 @param UefiDat The UEFI Update Data buffer.\r
428\r
429 @retval EFI_SUCCESS The UEFI HII opcode is created successfully and appended to UefiUpdateData.\r
430 @retval EFI_OUT_OF_RESOURCE There is not enough resource.\r
431**/\r
432\r
a9d85320 433EFI_STATUS\r
434CreateGuidOptionKeyOpCode (\r
435 IN EFI_QUESTION_ID QuestionId,\r
436 IN UINT16 OptionValue,\r
437 IN EFI_QUESTION_ID KeyValue,\r
03254710 438 IN OUT EFI_HII_UPDATE_DATA *UefiUpdateData\r
a9d85320 439 )\r
440{\r
441 EFI_IFR_GUID_OPTIONKEY UOpcode;\r
442\r
443 CopyMem (&UOpcode, &mOptionKeyTemplate, sizeof (EFI_IFR_GUID_OPTIONKEY));\r
444\r
445 UOpcode.QuestionId = QuestionId;\r
446 CopyMem (&UOpcode.OptionValue, &OptionValue, sizeof (OptionValue)); \r
447 UOpcode.KeyValue = KeyValue;\r
448 \r
03254710 449 return AppendToUpdateBuffer ((UINT8 *) &UOpcode, sizeof(UOpcode), UefiUpdateData);\r
a9d85320 450}\r
5391c4f1 451\r
03254710 452/**\r
453 Create UEFI HII "One Of" Opcode from a Framework HII "One Of" Opcode.\r
454\r
455 @param ThunkContext The HII Thunk Context.\r
456 @param FwOpcode The input Framework Opcode.\r
457 @param UefiUpdateData The newly created UEFI HII opcode is appended to UefiUpdateData.\r
458 @param NextFwOpcode Returns the position of the next Framework Opcode after FRAMEWORK_EFI_IFR_END_ONE_OF_OP of\r
459 the "One Of Option".\r
460 @param OpcodeCount The number of Opcode for the complete Framework "One Of" Opcode.\r
461 \r
462 @retval EFI_SUCCESS The UEFI HII opcode is created successfully and appended to UefiUpdateData.\r
463 @retval EFI_OUT_OF_RESOURCE There is not enough resource.\r
464 \r
465**/\r
5391c4f1 466EFI_STATUS\r
467F2UCreateOneOfOpCode (\r
0368663f 468 IN HII_THUNK_CONTEXT *ThunkContext,\r
5391c4f1 469 IN CONST FRAMEWORK_EFI_IFR_ONE_OF *FwOpcode,\r
03254710 470 IN OUT EFI_HII_UPDATE_DATA *UefiUpdateData,\r
c64feb92 471 OUT FRAMEWORK_EFI_IFR_OP_HEADER **NextFwOpcode,\r
03254710 472 OUT UINTN *OpcodeCount\r
5391c4f1 473 )\r
474{\r
0368663f 475 EFI_STATUS Status;\r
476 EFI_IFR_ONE_OF UOpcode;\r
477 FRAMEWORK_EFI_IFR_OP_HEADER *FwOpHeader;\r
478 FRAMEWORK_EFI_IFR_ONE_OF_OPTION *FwOneOfOp;\r
5391c4f1 479\r
c64feb92 480 ASSERT (NextFwOpcode != NULL);\r
03254710 481 ASSERT (OpcodeCount != NULL);\r
c64feb92 482\r
5391c4f1 483 ZeroMem (&UOpcode, sizeof(UOpcode));\r
03254710 484 *OpcodeCount = 0;\r
5391c4f1 485\r
486 UOpcode.Header.Length = sizeof(UOpcode);\r
487 UOpcode.Header.OpCode = EFI_IFR_ONE_OF_OP;\r
488 UOpcode.Header.Scope = 1;\r
489\r
490 UOpcode.Question.Header.Prompt = FwOpcode->Prompt;\r
491 UOpcode.Question.Header.Help = FwOpcode->Help;\r
03254710 492 UOpcode.Question.VarStoreId = ThunkContext->FormSet->DefaultVarStoreId;\r
133a9dfb 493 UOpcode.Question.VarStoreInfo.VarOffset = FwOpcode->QuestionId;\r
494 \r
5391c4f1 495 //\r
496 // Go over the Framework IFR binary to get the QuestionId for generated UEFI One Of Option opcode\r
497 //\r
5391c4f1 498 FwOpHeader = (FRAMEWORK_EFI_IFR_OP_HEADER *) ((UINT8 *) FwOpcode + FwOpcode->Header.Length);\r
499 while (FwOpHeader->OpCode != FRAMEWORK_EFI_IFR_END_ONE_OF_OP) {\r
500 ASSERT (FwOpHeader->OpCode == FRAMEWORK_EFI_IFR_ONE_OF_OPTION_OP);\r
501 \r
502 FwOneOfOp = (FRAMEWORK_EFI_IFR_ONE_OF_OPTION *) FwOpHeader;\r
0368663f 503 if ((FwOneOfOp->Flags & FRAMEWORK_EFI_IFR_FLAG_INTERACTIVE) != 0) {\r
504 UOpcode.Question.Flags |= EFI_IFR_FLAG_CALLBACK;\r
505 \r
506 if (UOpcode.Question.QuestionId == 0) {\r
03254710 507 Status = FwQIdToUefiQId (ThunkContext->FormSet, FwOpcode->Header.OpCode, FwOpcode->QuestionId, &UOpcode.Question.QuestionId);\r
0368663f 508 if (EFI_ERROR (Status)) {\r
a9d85320 509 UOpcode.Question.QuestionId = AssignQuestionId (FwOneOfOp->Key, ThunkContext->FormSet);\r
0368663f 510 }\r
133a9dfb 511 }\r
0368663f 512\r
0368663f 513 }\r
514\r
515 if (FwOneOfOp->Flags & FRAMEWORK_EFI_IFR_FLAG_RESET_REQUIRED) {\r
516 UOpcode.Question.Flags |= EFI_IFR_FLAG_RESET_REQUIRED;\r
5391c4f1 517 }\r
518\r
519 FwOpHeader = (FRAMEWORK_EFI_IFR_OP_HEADER *) ((UINT8 *) FwOpHeader + FwOpHeader->Length);\r
520 }\r
521\r
0368663f 522\r
523 if (UOpcode.Question.QuestionId == 0) {\r
524 //\r
525 // Assign QuestionId if still not assigned.\r
526 //\r
03254710 527 Status = FwQIdToUefiQId (ThunkContext->FormSet, FwOpcode->Header.OpCode, FwOpcode->QuestionId, &UOpcode.Question.QuestionId);\r
0368663f 528 if (EFI_ERROR (Status)) {\r
a9d85320 529 UOpcode.Question.QuestionId = AssignQuestionId (FwOpcode->QuestionId, ThunkContext->FormSet);\r
0368663f 530 }\r
531 }\r
532 \r
03254710 533 Status = AppendToUpdateBuffer ((UINT8 *) &UOpcode, sizeof (UOpcode), UefiUpdateData);\r
0368663f 534 if (EFI_ERROR (Status)) {\r
535 return Status;\r
536 }\r
03254710 537 *OpcodeCount += 1;\r
0368663f 538\r
5391c4f1 539 //\r
540 // Go over again the Framework IFR binary to build the UEFI One Of Option opcodes.\r
541 //\r
542 FwOpHeader = (FRAMEWORK_EFI_IFR_OP_HEADER *) ((UINT8 *) FwOpcode + FwOpcode->Header.Length);\r
543 while (FwOpHeader->OpCode != FRAMEWORK_EFI_IFR_END_ONE_OF_OP) {\r
a9d85320 544\r
545 FwOneOfOp = (FRAMEWORK_EFI_IFR_ONE_OF_OPTION *) FwOpHeader;\r
546 \r
03254710 547 Status = F2UCreateOneOfOptionOpCode ((FRAMEWORK_EFI_IFR_ONE_OF_OPTION *) FwOpHeader, FwOpcode->Width, UefiUpdateData);\r
5391c4f1 548 if (EFI_ERROR (Status)) {\r
549 return Status;\r
550 }\r
a9d85320 551\r
03254710 552 Status = CreateGuidOptionKeyOpCode (UOpcode.Question.QuestionId, FwOneOfOp->Value, FwOneOfOp->Key, UefiUpdateData);\r
a9d85320 553 if (EFI_ERROR (Status)) {\r
554 return Status;\r
555 }\r
c64feb92 556 FwOpHeader = (FRAMEWORK_EFI_IFR_OP_HEADER *) ((UINT8 *) FwOpHeader + FwOpHeader->Length);\r
03254710 557 *OpcodeCount += 1;\r
5391c4f1 558 }\r
559\r
03254710 560 Status = UCreateEndOfOpcode (UefiUpdateData);\r
5391c4f1 561 if (!EFI_ERROR (Status)) {\r
562 *NextFwOpcode = (FRAMEWORK_EFI_IFR_OP_HEADER *)((UINT8 *) FwOpHeader + FwOpHeader->Length);\r
03254710 563 *OpcodeCount += 1;\r
5391c4f1 564 }\r
565\r
566 return Status;\r
567}\r
568\r
03254710 569/**\r
570 Create UEFI HII "Ordered List" Opcode from a Framework HII "Ordered List" Opcode.\r
571\r
572 @param ThunkContext The HII Thunk Context.\r
573 @param FwOpcode The input Framework Opcode.\r
574 @param UefiUpdateData The newly created UEFI HII opcode is appended to UefiUpdateData.\r
575 @param NextFwOpcode Returns the position of the next Framework Opcode after FRAMEWORK_EFI_IFR_END_ONE_OF_OP of\r
576 the "Ordered List".\r
577 @param OpcodeCount The number of Opcode for the complete Framework "Ordered List" Opcode.\r
578 \r
579 @retval EFI_SUCCESS The UEFI HII opcode is created successfully and appended to UefiUpdateData.\r
580 @retval EFI_OUT_OF_RESOURCE There is not enough resource.\r
581 \r
582**/\r
5391c4f1 583EFI_STATUS\r
584F2UCreateOrderedListOpCode (\r
03254710 585 IN HII_THUNK_CONTEXT *ThunkContext,\r
5391c4f1 586 IN CONST FRAMEWORK_EFI_IFR_ORDERED_LIST *FwOpcode,\r
03254710 587 IN OUT EFI_HII_UPDATE_DATA *UefiUpdateData,\r
588 OUT FRAMEWORK_EFI_IFR_OP_HEADER **NextFwOpcode,\r
589 OUT UINTN *OpcodeCount\r
5391c4f1 590 )\r
591{\r
592 EFI_IFR_ORDERED_LIST UOpcode;\r
593 EFI_STATUS Status;\r
594 FRAMEWORK_EFI_IFR_OP_HEADER *FwOpHeader;\r
0368663f 595 FRAMEWORK_EFI_IFR_ONE_OF_OPTION *FwOneOfOp;\r
5391c4f1 596\r
597 ZeroMem (&UOpcode, sizeof(UOpcode));\r
03254710 598 *OpcodeCount = 0;\r
5391c4f1 599\r
600 UOpcode.Header.Length = sizeof(UOpcode);\r
601 UOpcode.Header.OpCode = EFI_IFR_ORDERED_LIST_OP;\r
602 UOpcode.Header.Scope = 1;\r
603\r
604 UOpcode.Question.Header.Prompt = FwOpcode->Prompt;\r
605 UOpcode.Question.Header.Help = FwOpcode->Help;\r
03254710 606 UOpcode.Question.VarStoreId = ThunkContext->FormSet->DefaultVarStoreId;\r
133a9dfb 607 UOpcode.Question.VarStoreInfo.VarOffset = FwOpcode->QuestionId;\r
5391c4f1 608\r
609 UOpcode.MaxContainers = FwOpcode->MaxEntries;\r
0368663f 610\r
611 //\r
612 // Go over the Framework IFR binary to get the QuestionId for generated UEFI One Of Option opcode\r
613 //\r
614 FwOpHeader = (FRAMEWORK_EFI_IFR_OP_HEADER *) ((UINT8 *) FwOpcode + FwOpcode->Header.Length);\r
615 while (FwOpHeader->OpCode != FRAMEWORK_EFI_IFR_END_ONE_OF_OP) {\r
616 ASSERT (FwOpHeader->OpCode == FRAMEWORK_EFI_IFR_ONE_OF_OPTION_OP);\r
617 \r
618 FwOneOfOp = (FRAMEWORK_EFI_IFR_ONE_OF_OPTION *) FwOpHeader;\r
619 if ((FwOneOfOp->Flags & FRAMEWORK_EFI_IFR_FLAG_INTERACTIVE) != 0) {\r
620 UOpcode.Question.Flags |= EFI_IFR_FLAG_CALLBACK;\r
621 \r
622 if (UOpcode.Question.QuestionId == 0) {\r
03254710 623 Status = FwQIdToUefiQId (ThunkContext->FormSet, FwOpcode->Header.OpCode, FwOpcode->QuestionId, &UOpcode.Question.QuestionId);\r
0368663f 624 if (EFI_ERROR (Status)) {\r
a9d85320 625 UOpcode.Question.QuestionId = AssignQuestionId (FwOneOfOp->Key, ThunkContext->FormSet);\r
0368663f 626 }\r
627\r
628 }\r
629 }\r
630\r
631 if (FwOneOfOp->Flags & FRAMEWORK_EFI_IFR_FLAG_RESET_REQUIRED) {\r
632 UOpcode.Question.Flags |= EFI_IFR_FLAG_RESET_REQUIRED;\r
633 }\r
634\r
635 FwOpHeader = (FRAMEWORK_EFI_IFR_OP_HEADER *) ((UINT8 *) FwOpHeader + FwOpHeader->Length);\r
636 }\r
637\r
638 if (UOpcode.Question.QuestionId == 0) {\r
03254710 639 Status = FwQIdToUefiQId (ThunkContext->FormSet, FwOpcode->Header.OpCode, FwOpcode->QuestionId, &UOpcode.Question.QuestionId);\r
0368663f 640 if (EFI_ERROR (Status)) {\r
a9d85320 641 UOpcode.Question.QuestionId = AssignQuestionId (FwOpcode->QuestionId, ThunkContext->FormSet);\r
0368663f 642 }\r
643 }\r
5391c4f1 644 \r
03254710 645 Status = AppendToUpdateBuffer ((UINT8 *) &UOpcode, sizeof(UOpcode), UefiUpdateData);\r
5391c4f1 646 if (EFI_ERROR (Status)) {\r
647 return Status;\r
648 }\r
03254710 649 *OpcodeCount += 1;\r
5391c4f1 650\r
651 FwOpHeader = (FRAMEWORK_EFI_IFR_OP_HEADER *) ((UINT8 *) FwOpcode + FwOpcode->Header.Length);\r
652 while (FwOpHeader->OpCode != FRAMEWORK_EFI_IFR_END_ONE_OF_OP) {\r
0368663f 653 //\r
654 // Each entry of Order List in Framework HII is always 1 byte in size\r
655 //\r
03254710 656 Status = F2UCreateOneOfOptionOpCode ((CONST FRAMEWORK_EFI_IFR_ONE_OF_OPTION *) FwOpHeader, 1, UefiUpdateData);\r
5391c4f1 657 if (EFI_ERROR (Status)) {\r
658 return Status;\r
659 }\r
c64feb92 660 FwOpHeader = (FRAMEWORK_EFI_IFR_OP_HEADER *) ((UINT8 *) FwOpHeader + FwOpHeader->Length);\r
03254710 661 *OpcodeCount += 1;\r
5391c4f1 662 }\r
663\r
03254710 664 Status = UCreateEndOfOpcode (UefiUpdateData);\r
5391c4f1 665 if (!EFI_ERROR (Status)) {\r
666 *NextFwOpcode = (FRAMEWORK_EFI_IFR_OP_HEADER *)((UINT8 *) FwOpHeader + FwOpHeader->Length);\r
03254710 667 *OpcodeCount += 1;\r
5391c4f1 668 }\r
669\r
c64feb92 670 return Status;\r
5391c4f1 671}\r
672\r
03254710 673/**\r
674 Create UEFI HII CheckBox Opcode from a Framework HII Checkbox Opcode.\r
5391c4f1 675\r
03254710 676 @param ThunkContext The HII Thunk Context.\r
677 @param FwOpcode The input Framework Opcode.\r
678 @param UefiUpdateData The newly created UEFI HII opcode is appended to UefiUpdateData.\r
5391c4f1 679\r
03254710 680 @retval EFI_SUCCESS The UEFI HII opcode is created successfully and appended to UefiUpdateData.\r
681 @retval EFI_OUT_OF_RESOURCE There is not enough resource.\r
682 \r
683**/\r
5391c4f1 684EFI_STATUS\r
685F2UCreateCheckBoxOpCode (\r
0368663f 686 IN HII_THUNK_CONTEXT *ThunkContext,\r
5391c4f1 687 IN CONST FRAMEWORK_EFI_IFR_CHECKBOX *FwOpcode,\r
03254710 688 IN OUT EFI_HII_UPDATE_DATA *UefiUpdateData\r
5391c4f1 689 )\r
690{\r
0368663f 691 EFI_STATUS Status;\r
5391c4f1 692 EFI_IFR_CHECKBOX UOpcode;\r
693\r
694 ZeroMem (&UOpcode, sizeof(UOpcode));\r
695\r
696 UOpcode.Header.Length = sizeof(UOpcode);\r
697 UOpcode.Header.OpCode = EFI_IFR_CHECKBOX_OP;\r
698\r
699 UOpcode.Question.Header.Prompt = FwOpcode->Prompt;\r
700 UOpcode.Question.Header.Help = FwOpcode->Help;\r
701\r
0368663f 702 if (FwOpcode->Key == 0) {\r
03254710 703 Status = FwQIdToUefiQId (ThunkContext->FormSet, FwOpcode->Header.OpCode, FwOpcode->QuestionId, &UOpcode.Question.QuestionId);\r
0368663f 704 if (EFI_ERROR (Status)) {\r
705 //\r
706 // Add a new opcode and it will not trigger call back. So we just reuse the FW QuestionId.\r
707 //\r
a9d85320 708 UOpcode.Question.QuestionId = AssignQuestionId (FwOpcode->QuestionId, ThunkContext->FormSet);\r
0368663f 709 }\r
710 } else {\r
711 UOpcode.Question.QuestionId = FwOpcode->Key;\r
712 }\r
713\r
5391c4f1 714 //\r
03254710 715 // We map 2 flags:\r
5391c4f1 716 // FRAMEWORK_EFI_IFR_FLAG_INTERACTIVE, \r
717 // FRAMEWORK_EFI_IFR_FLAG_RESET_REQUIRED,\r
718 // to UEFI IFR Opcode Question flags. The rest flags are obsolete.\r
719 //\r
98b16b9d 720 UOpcode.Question.Flags = (UINT8) (FwOpcode->Flags & (FRAMEWORK_EFI_IFR_FLAG_INTERACTIVE | FRAMEWORK_EFI_IFR_FLAG_RESET_REQUIRED));\r
5391c4f1 721\r
03254710 722\r
723 UOpcode.Question.VarStoreId = ThunkContext->FormSet->DefaultVarStoreId;\r
724 UOpcode.Question.VarStoreInfo.VarOffset = FwOpcode->QuestionId;\r
725\r
5391c4f1 726 //\r
03254710 727 // We also map these 2 flags:\r
0368663f 728 // FRAMEWORK_EFI_IFR_FLAG_DEFAULT, \r
729 // FRAMEWORK_EFI_IFR_FLAG_MANUFACTURING,\r
5391c4f1 730 // to UEFI IFR CheckBox Opcode default flags.\r
731 //\r
98b16b9d 732 UOpcode.Flags = (UINT8) (FwOpcode->Flags & (FRAMEWORK_EFI_IFR_FLAG_DEFAULT | FRAMEWORK_EFI_IFR_FLAG_MANUFACTURING));\r
5391c4f1 733\r
03254710 734 return AppendToUpdateBuffer ((UINT8 *) &UOpcode, sizeof(UOpcode), UefiUpdateData);\r
5391c4f1 735}\r
736\r
737\r
03254710 738/**\r
739 Create UEFI HII Numeric Opcode from a Framework HII Numeric Opcode.\r
5391c4f1 740\r
03254710 741 @param ThunkContext The HII Thunk Context.\r
742 @param FwOpcode The input Framework Opcode.\r
743 @param UefiUpdateData The newly created UEFI HII opcode is appended to UefiUpdateData.\r
5391c4f1 744\r
03254710 745 @retval EFI_SUCCESS The UEFI HII opcode is created successfully and appended to UefiUpdateData.\r
746 @retval EFI_OUT_OF_RESOURCE There is not enough resource.\r
747 \r
748**/\r
5391c4f1 749EFI_STATUS\r
750F2UCreateNumericOpCode (\r
a3318eaf 751 IN HII_THUNK_CONTEXT *ThunkContext,\r
5391c4f1 752 IN CONST FRAMEWORK_EFI_IFR_NUMERIC *FwOpcode,\r
03254710 753 IN OUT EFI_HII_UPDATE_DATA *UefiUpdateData\r
5391c4f1 754 )\r
755{\r
756 EFI_STATUS Status;\r
757 EFI_IFR_NUMERIC UOpcode;\r
758 EFI_IFR_DEFAULT UOpcodeDefault;\r
759\r
760 ZeroMem (&UOpcode, sizeof(UOpcode));\r
761\r
0368663f 762 if (FwOpcode->Key == 0) {\r
03254710 763 Status = FwQIdToUefiQId (ThunkContext->FormSet, FwOpcode->Header.OpCode, FwOpcode->QuestionId, &UOpcode.Question.QuestionId);\r
0368663f 764 if (EFI_ERROR (Status)) {\r
765 //\r
766 // Add a new opcode and it will not trigger call back. So we just reuse the FW QuestionId.\r
767 //\r
a9d85320 768 UOpcode.Question.QuestionId = AssignQuestionId (FwOpcode->QuestionId, ThunkContext->FormSet);\r
0368663f 769 }\r
770 } else {\r
771 UOpcode.Question.QuestionId = FwOpcode->Key;\r
772 }\r
773\r
5391c4f1 774 UOpcode.Header.Length = sizeof(UOpcode);\r
775 UOpcode.Header.OpCode = EFI_IFR_NUMERIC_OP;\r
776 //\r
777 // We need to create a nested default value for the UEFI Numeric Opcode.\r
778 // So turn on the scope.\r
779 //\r
8ea58c07 780 UOpcode.Header.Scope = 1;\r
5391c4f1 781\r
782 UOpcode.Question.Header.Prompt = FwOpcode->Prompt;\r
783 UOpcode.Question.Header.Help = FwOpcode->Help;\r
784\r
03254710 785 UOpcode.Question.VarStoreId = ThunkContext->FormSet->DefaultVarStoreId;\r
5391c4f1 786 UOpcode.Question.VarStoreInfo.VarOffset = FwOpcode->QuestionId;\r
787\r
98b16b9d 788 UOpcode.Question.Flags = (UINT8) (FwOpcode->Flags & (FRAMEWORK_EFI_IFR_FLAG_INTERACTIVE | FRAMEWORK_EFI_IFR_FLAG_RESET_REQUIRED));\r
5391c4f1 789\r
790 //\r
791 // Framework Numeric values are all in UINT16 and displayed as decimal.\r
792 //\r
793 UOpcode.data.u16.MinValue = FwOpcode->Minimum;\r
794 UOpcode.data.u16.MaxValue = FwOpcode->Maximum;\r
795 UOpcode.data.u16.Step = FwOpcode->Step;\r
796\r
797 switch (FwOpcode->Width) {\r
798 case 1: \r
799 {\r
8ea58c07 800 UOpcode.Flags = EFI_IFR_NUMERIC_SIZE_1 | EFI_IFR_DISPLAY_UINT_DEC; \r
5391c4f1 801 break;\r
802 } \r
803 case 2: \r
804 {\r
8ea58c07 805 UOpcode.Flags = EFI_IFR_NUMERIC_SIZE_2 | EFI_IFR_DISPLAY_UINT_DEC; \r
5391c4f1 806 break;\r
807 }\r
808 default: \r
809 {\r
810 ASSERT (FALSE);\r
811 return EFI_INVALID_PARAMETER;\r
812 }\r
813 }\r
814 \r
03254710 815 Status = AppendToUpdateBuffer ((UINT8 *) &UOpcode, sizeof(UOpcode), UefiUpdateData);\r
5391c4f1 816 if (EFI_ERROR (Status)) {\r
817 return Status;\r
818 }\r
819\r
820 //\r
f274810c 821 // We need to create a default value.\r
5391c4f1 822 //\r
8ea58c07 823 ZeroMem (&UOpcodeDefault, sizeof (UOpcodeDefault));\r
824 UOpcodeDefault.Header.Length = sizeof (UOpcodeDefault);\r
825 UOpcodeDefault.Header.OpCode = EFI_IFR_DEFAULT_OP;\r
5391c4f1 826\r
8ea58c07 827 UOpcodeDefault.DefaultId = 0;\r
5391c4f1 828\r
8ea58c07 829 switch (FwOpcode->Width) {\r
830 case 1: \r
831 {\r
832 UOpcodeDefault.Type = EFI_IFR_TYPE_NUM_SIZE_8;\r
833 break;\r
834 } \r
835 case 2: \r
836 {\r
837 UOpcodeDefault.Type = EFI_IFR_TYPE_NUM_SIZE_16;\r
838 break;\r
5391c4f1 839 }\r
8ea58c07 840 }\r
5391c4f1 841\r
8ea58c07 842 CopyMem (&UOpcodeDefault.Value.u8, &FwOpcode->Default, FwOpcode->Width);\r
5391c4f1 843\r
03254710 844 Status = AppendToUpdateBuffer ((UINT8 *) &UOpcodeDefault, sizeof(UOpcodeDefault), UefiUpdateData);\r
8ea58c07 845 if (EFI_ERROR (Status)) {\r
846 return Status;\r
5391c4f1 847 }\r
03254710 848 Status = UCreateEndOfOpcode (UefiUpdateData);\r
5391c4f1 849\r
850 return Status;\r
851}\r
852\r
853\r
03254710 854/**\r
855 Create UEFI HII String Opcode from a Framework HII String Opcode.\r
5391c4f1 856\r
03254710 857 @param ThunkContext The HII Thunk Context.\r
858 @param FwOpcode The input Framework Opcode.\r
859 @param UefiUpdateData The newly created UEFI HII opcode is appended to UefiUpdateData.\r
5391c4f1 860\r
03254710 861 @retval EFI_SUCCESS The UEFI HII opcode is created successfully and appended to UefiUpdateData.\r
862 @retval EFI_OUT_OF_RESOURCE There is not enough resource.\r
863 \r
864**/\r
5391c4f1 865EFI_STATUS\r
866F2UCreateStringOpCode (\r
03254710 867 IN HII_THUNK_CONTEXT *ThunkContext,\r
5391c4f1 868 IN CONST FRAMEWORK_EFI_IFR_STRING *FwOpcode,\r
03254710 869 IN OUT EFI_HII_UPDATE_DATA *UefiUpdateData\r
5391c4f1 870 )\r
871{\r
872 EFI_IFR_STRING UOpcode;\r
873\r
874 ZeroMem (&UOpcode, sizeof(UOpcode));\r
875\r
0368663f 876 if (FwOpcode->Key == 0) {\r
03254710 877 FwQIdToUefiQId (ThunkContext->FormSet, FwOpcode->Header.OpCode, FwOpcode->QuestionId, &UOpcode.Question.QuestionId);\r
0368663f 878 } else {\r
879 UOpcode.Question.QuestionId = FwOpcode->Key;\r
880 }\r
881\r
5391c4f1 882 UOpcode.Header.Length = sizeof(UOpcode);\r
883 UOpcode.Header.OpCode = EFI_IFR_STRING_OP;\r
884\r
885 UOpcode.Question.Header.Prompt = FwOpcode->Prompt;\r
886 UOpcode.Question.Header.Help = FwOpcode->Help;\r
887\r
888 UOpcode.Question.QuestionId = FwOpcode->Key;\r
98b16b9d 889 UOpcode.Question.Flags = (UINT8) (FwOpcode->Flags & (FRAMEWORK_EFI_IFR_FLAG_INTERACTIVE | FRAMEWORK_EFI_IFR_FLAG_RESET_REQUIRED));\r
5391c4f1 890\r
03254710 891 UOpcode.Question.VarStoreId = ThunkContext->FormSet->DefaultVarStoreId;\r
892 UOpcode.Question.VarStoreInfo.VarOffset = FwOpcode->QuestionId;\r
893\r
5391c4f1 894 UOpcode.MinSize = FwOpcode->MinSize;\r
895 UOpcode.MaxSize = FwOpcode->MaxSize;\r
896 UOpcode.Flags = EFI_IFR_STRING_MULTI_LINE;\r
897\r
03254710 898 return AppendToUpdateBuffer ((UINT8 *) &UOpcode, sizeof(UOpcode), UefiUpdateData);\r
5391c4f1 899}\r
900\r
03254710 901/**\r
902 Create UEFI HII Banner Opcode from a Framework HII Banner Opcode.\r
903\r
904 @param FwOpcode The input Framework Opcode.\r
905 @param UefiUpdateData The newly created UEFI HII opcode is appended to UefiUpdateData.\r
5391c4f1 906\r
03254710 907 @retval EFI_SUCCESS The UEFI HII opcode is created successfully and appended to UefiUpdateData.\r
908 @retval EFI_OUT_OF_RESOURCE There is not enough resource.\r
909 \r
910**/\r
5391c4f1 911EFI_STATUS\r
912F2UCreateBannerOpCode (\r
913 IN CONST FRAMEWORK_EFI_IFR_BANNER *FwOpcode,\r
03254710 914 IN OUT EFI_HII_UPDATE_DATA *UefiUpdateData\r
5391c4f1 915 )\r
916{\r
917 EFI_IFR_GUID_BANNER UOpcode;\r
918\r
919 ZeroMem (&UOpcode, sizeof(UOpcode));\r
920\r
921 UOpcode.Header.Length = sizeof(UOpcode);\r
922 UOpcode.Header.OpCode = EFI_IFR_GUID_OP;\r
923\r
924 CopyMem (&UOpcode.Guid, &mTianoExtendedOpcodeGuid, sizeof (EFI_GUID));\r
925 UOpcode.ExtendOpCode = EFI_IFR_EXTEND_OP_BANNER;\r
926 UOpcode.Title = FwOpcode->Title;\r
927 UOpcode.LineNumber = FwOpcode->LineNumber;\r
928 UOpcode.Alignment = FwOpcode->Alignment;\r
929\r
03254710 930 return AppendToUpdateBuffer ((UINT8 *) &UOpcode, sizeof(UOpcode), UefiUpdateData);\r
5391c4f1 931}\r
932\r
03254710 933/**\r
934 Create a EFI_HII_UPDATE_DATA structure used to call IfrLibUpdateForm.\r
5391c4f1 935\r
03254710 936 @param ThunkContext The HII Thunk Context.\r
937 @param FwUpdateData The Framework Update Data.\r
938 @param UefiUpdateData The UEFI Update Data.\r
939\r
940 @retval EFI_SUCCESS The UEFI Update Data is created successfully.\r
941 @retval EFI_UNSUPPORTED There is unsupported opcode in FwUpdateData.\r
942 @retval EFI_OUT_OF_RESOURCES There is not enough resource.\r
943**/\r
5391c4f1 944EFI_STATUS\r
0368663f 945FwUpdateDataToUefiUpdateData (\r
03254710 946 IN HII_THUNK_CONTEXT *ThunkContext,\r
947 IN CONST FRAMEWORK_EFI_HII_UPDATE_DATA *FwUpdateData,\r
948 OUT EFI_HII_UPDATE_DATA **UefiUpdateData\r
5391c4f1 949 )\r
950{\r
0368663f 951 FRAMEWORK_EFI_IFR_OP_HEADER *FwOpCode;\r
952 FRAMEWORK_EFI_IFR_OP_HEADER *NextFwOpCode;\r
953 EFI_HII_UPDATE_DATA *UefiOpCode;\r
5391c4f1 954 UINTN Index;\r
955 EFI_STATUS Status;\r
c64feb92 956 UINTN DataCount;\r
5391c4f1 957\r
0368663f 958 UefiOpCode = AllocateZeroPool (sizeof (EFI_HII_UPDATE_DATA));\r
959 if (UefiOpCode == NULL) {\r
5391c4f1 960 return EFI_OUT_OF_RESOURCES;\r
961 }\r
962 \r
0368663f 963 UefiOpCode->Data = AllocateZeroPool (LOCAL_UPDATE_DATA_BUFFER_INCREMENTAL);\r
964 if (UefiOpCode->Data == NULL) {\r
5391c4f1 965 return EFI_OUT_OF_RESOURCES;\r
966 }\r
967\r
0368663f 968 UefiOpCode->BufferSize = LOCAL_UPDATE_DATA_BUFFER_INCREMENTAL;\r
969 UefiOpCode->Offset = 0;\r
5391c4f1 970\r
03254710 971 FwOpCode = (FRAMEWORK_EFI_IFR_OP_HEADER *) &FwUpdateData->Data;\r
5391c4f1 972\r
03254710 973 for (Index = 0; Index < FwUpdateData->DataCount; Index += DataCount) {\r
0368663f 974 switch (FwOpCode->OpCode) {\r
5391c4f1 975 case FRAMEWORK_EFI_IFR_SUBTITLE_OP:\r
0368663f 976 Status = F2UCreateSubtitleOpCode ((FRAMEWORK_EFI_IFR_SUBTITLE *) FwOpCode, UefiOpCode);\r
977 DataCount = 1;\r
5391c4f1 978 break;\r
979 \r
980 case FRAMEWORK_EFI_IFR_TEXT_OP:\r
0368663f 981 Status = F2UCreateTextOpCode ((FRAMEWORK_EFI_IFR_TEXT *) FwOpCode, UefiOpCode); \r
982 DataCount = 1;\r
5391c4f1 983 break;\r
984\r
985 case FRAMEWORK_EFI_IFR_REF_OP:\r
03254710 986 Status = F2UCreateReferenceOpCode ((FRAMEWORK_EFI_IFR_REF *) FwOpCode, UefiOpCode); \r
0368663f 987 DataCount = 1;\r
5391c4f1 988 break;\r
989 \r
990 case FRAMEWORK_EFI_IFR_ONE_OF_OP:\r
03254710 991 Status = F2UCreateOneOfOpCode (ThunkContext, (FRAMEWORK_EFI_IFR_ONE_OF *) FwOpCode, UefiOpCode, &NextFwOpCode, &DataCount);\r
5391c4f1 992 if (!EFI_ERROR (Status)) {\r
0368663f 993 FwOpCode = NextFwOpCode;\r
5391c4f1 994 //\r
0368663f 995 // FwOpCode is already updated to point to the next opcode.\r
5391c4f1 996 //\r
997 continue;\r
998 }\r
999 break;\r
1000\r
1001 case FRAMEWORK_EFI_IFR_ORDERED_LIST_OP:\r
03254710 1002 Status = F2UCreateOrderedListOpCode (ThunkContext, (FRAMEWORK_EFI_IFR_ORDERED_LIST *) FwOpCode, UefiOpCode, &NextFwOpCode, &DataCount);\r
5391c4f1 1003 if (!EFI_ERROR (Status)) {\r
0368663f 1004 FwOpCode = NextFwOpCode;\r
5391c4f1 1005 //\r
0368663f 1006 // FwOpCode is already updated to point to the next opcode.\r
5391c4f1 1007 //\r
1008 continue;\r
1009 }\r
1010 break;\r
1011 \r
1012 case FRAMEWORK_EFI_IFR_CHECKBOX_OP:\r
03254710 1013 Status = F2UCreateCheckBoxOpCode (ThunkContext, (FRAMEWORK_EFI_IFR_CHECKBOX *) FwOpCode, UefiOpCode); \r
0368663f 1014 DataCount = 1;\r
5391c4f1 1015 break;\r
1016\r
1017 case FRAMEWORK_EFI_IFR_STRING_OP:\r
03254710 1018 Status = F2UCreateStringOpCode (ThunkContext, (FRAMEWORK_EFI_IFR_STRING *) FwOpCode, UefiOpCode); \r
0368663f 1019 DataCount = 1;\r
5391c4f1 1020 break;\r
1021\r
1022 case FRAMEWORK_EFI_IFR_BANNER_OP:\r
0368663f 1023 Status = F2UCreateBannerOpCode ((FRAMEWORK_EFI_IFR_BANNER *) FwOpCode, UefiOpCode); \r
1024 DataCount = 1;\r
5391c4f1 1025 break;\r
1026\r
1027 case FRAMEWORK_EFI_IFR_END_ONE_OF_OP:\r
0368663f 1028 Status = UCreateEndOfOpcode (UefiOpCode);\r
1029 DataCount = 1;\r
5391c4f1 1030 break;\r
0368663f 1031\r
8ea58c07 1032 case FRAMEWORK_EFI_IFR_NUMERIC_OP:\r
03254710 1033 Status = F2UCreateNumericOpCode (ThunkContext, (FRAMEWORK_EFI_IFR_NUMERIC *) FwOpCode, UefiOpCode);\r
8ea58c07 1034 DataCount = 1;\r
1035 break;\r
1036\r
5391c4f1 1037 default:\r
1038 ASSERT (FALSE);\r
1039 return EFI_UNSUPPORTED;\r
1040 }\r
1041\r
1042 if (EFI_ERROR (Status)) {\r
0368663f 1043 FreePool (UefiOpCode->Data);\r
1044 FreePool (UefiOpCode);\r
5391c4f1 1045 return Status;\r
1046 }\r
1047\r
0368663f 1048 FwOpCode = (FRAMEWORK_EFI_IFR_OP_HEADER *)((UINT8 *) FwOpCode + FwOpCode->Length);\r
5391c4f1 1049 }\r
1050\r
03254710 1051 *UefiUpdateData = UefiOpCode;\r
5391c4f1 1052 \r
1053 return EFI_SUCCESS;\r
1054}\r
1055\r