1 /** @file 2 Parser for IFR binary encoding. 3 4 Copyright (c) 2008 - 2014, Intel Corporation. All rights reserved.<BR> 5 This program and the accompanying materials 6 are licensed and made available under the terms and conditions of the BSD License 7 which accompanies this distribution. The full text of the license may be found at 8 http://opensource.org/licenses/bsd-license.php 9 10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 12 13 **/ 14 15 #include "HiiDatabase.h" 16 17 #include "UefiIfrParserExpression.h" 18 19 UINT16 mStatementIndex; 20 21 BOOLEAN mInScopeSubtitle; 22 BOOLEAN mInScopeSuppress; 23 BOOLEAN mInScopeGrayOut; 24 25 EFI_GUID mFrameworkHiiCompatibilityGuid = EFI_IFR_FRAMEWORK_GUID; 26 extern EFI_GUID mTianoHiiIfrGuid; 27 28 /** 29 Find the question's OneOfOptionMap list in FormSet 30 based on the input question Id. 31 32 @param FormSet FormSet context. 33 @param QuestionId Unique ID to specicy the question in FormSet. 34 35 @return the found OneOfOptionMap list. If not found, NULL will return. 36 **/ 37 LIST_ENTRY * 38 GetOneOfOptionMapEntryListHead ( 39 IN CONST FORM_BROWSER_FORMSET *FormSet, 40 IN UINT16 QuestionId 41 ) 42 { 43 LIST_ENTRY *Link; 44 ONE_OF_OPTION_MAP *Map; 45 46 Link = GetFirstNode (&FormSet->OneOfOptionMapListHead); 47 48 while (!IsNull (&FormSet->OneOfOptionMapListHead, Link)) { 49 Map = ONE_OF_OPTION_MAP_FROM_LINK (Link); 50 if (QuestionId == Map->QuestionId) { 51 return &Map->OneOfOptionMapEntryListHead; 52 } 53 Link = GetNextNode (&FormSet->OneOfOptionMapListHead, Link); 54 } 55 56 return NULL; 57 } 58 59 /** 60 Free OneOfOption map list. 61 62 @param OneOfOptionMapListHead Pointer to list header of OneOfOptionMap list. 63 64 **/ 65 VOID 66 DestoryOneOfOptionMap ( 67 IN LIST_ENTRY *OneOfOptionMapListHead 68 ) 69 { 70 ONE_OF_OPTION_MAP *Map; 71 ONE_OF_OPTION_MAP_ENTRY *MapEntry; 72 LIST_ENTRY *Link; 73 LIST_ENTRY *Link2; 74 75 while (!IsListEmpty (OneOfOptionMapListHead)) { 76 Link = GetFirstNode (OneOfOptionMapListHead); 77 78 Map = ONE_OF_OPTION_MAP_FROM_LINK (Link); 79 80 while (!IsListEmpty (&Map->OneOfOptionMapEntryListHead)) { 81 Link2 = GetFirstNode (&Map->OneOfOptionMapEntryListHead); 82 83 MapEntry = ONE_OF_OPTION_MAP_ENTRY_FROM_LINK (Link2); 84 85 RemoveEntryList (Link2); 86 87 FreePool (MapEntry); 88 } 89 90 RemoveEntryList (Link); 91 FreePool (Map); 92 } 93 } 94 95 96 /** 97 Initialize Statement header members. 98 99 @param OpCodeData Pointer of the raw OpCode data. 100 @param FormSet Pointer of the current FormSe. 101 @param Form Pointer of the current Form. 102 103 @return The Statement. 104 105 **/ 106 FORM_BROWSER_STATEMENT * 107 CreateStatement ( 108 IN UINT8 *OpCodeData, 109 IN OUT FORM_BROWSER_FORMSET *FormSet, 110 IN OUT FORM_BROWSER_FORM *Form 111 ) 112 { 113 FORM_BROWSER_STATEMENT *Statement; 114 EFI_IFR_STATEMENT_HEADER *StatementHdr; 115 116 if (Form == NULL) { 117 // 118 // We are currently not in a Form Scope, so just skip this Statement 119 // 120 return NULL; 121 } 122 123 Statement = &FormSet->StatementBuffer[mStatementIndex]; 124 mStatementIndex++; 125 126 InitializeListHead (&Statement->DefaultListHead); 127 InitializeListHead (&Statement->OptionListHead); 128 129 Statement->Signature = FORM_BROWSER_STATEMENT_SIGNATURE; 130 131 Statement->Operand = ((EFI_IFR_OP_HEADER *) OpCodeData)->OpCode; 132 133 StatementHdr = (EFI_IFR_STATEMENT_HEADER *) (OpCodeData + sizeof (EFI_IFR_OP_HEADER)); 134 CopyMem (&Statement->Prompt, &StatementHdr->Prompt, sizeof (EFI_STRING_ID)); 135 CopyMem (&Statement->Help, &StatementHdr->Help, sizeof (EFI_STRING_ID)); 136 137 Statement->InSubtitle = mInScopeSubtitle; 138 139 // 140 // Insert this Statement into current Form 141 // 142 InsertTailList (&Form->StatementListHead, &Statement->Link); 143 144 return Statement; 145 } 146 147 /** 148 Initialize Question's members. 149 150 @param OpCodeData Pointer of the raw OpCode data. 151 @param FormSet Pointer of the current FormSet. 152 @param Form Pointer of the current Form. 153 154 @return The Question. 155 156 **/ 157 FORM_BROWSER_STATEMENT * 158 CreateQuestion ( 159 IN UINT8 *OpCodeData, 160 IN OUT FORM_BROWSER_FORMSET *FormSet, 161 IN OUT FORM_BROWSER_FORM *Form 162 ) 163 { 164 FORM_BROWSER_STATEMENT *Statement; 165 EFI_IFR_QUESTION_HEADER *QuestionHdr; 166 LIST_ENTRY *Link; 167 FORMSET_STORAGE *Storage; 168 169 Statement = CreateStatement (OpCodeData, FormSet, Form); 170 if (Statement == NULL) { 171 return NULL; 172 } 173 174 QuestionHdr = (EFI_IFR_QUESTION_HEADER *) (OpCodeData + sizeof (EFI_IFR_OP_HEADER)); 175 CopyMem (&Statement->QuestionId, &QuestionHdr->QuestionId, sizeof (EFI_QUESTION_ID)); 176 CopyMem (&Statement->VarStoreId, &QuestionHdr->VarStoreId, sizeof (EFI_VARSTORE_ID)); 177 CopyMem (&Statement->VarStoreInfo.VarOffset, &QuestionHdr->VarStoreInfo.VarOffset, sizeof (UINT16)); 178 179 if (FormSet->MaxQuestionId < QuestionHdr->QuestionId) { 180 FormSet->MaxQuestionId = QuestionHdr->QuestionId; 181 } 182 183 Statement->QuestionFlags = QuestionHdr->Flags; 184 185 if (Statement->VarStoreId == 0) { 186 // 187 // VarStoreId of zero indicates no variable storage 188 // 189 return Statement; 190 } 191 192 // 193 // Find Storage for this Question 194 // 195 Link = GetFirstNode (&FormSet->StorageListHead); 196 while (!IsNull (&FormSet->StorageListHead, Link)) { 197 Storage = FORMSET_STORAGE_FROM_LINK (Link); 198 199 if (Storage->VarStoreId == Statement->VarStoreId) { 200 Statement->Storage = Storage; 201 break; 202 } 203 204 Link = GetNextNode (&FormSet->StorageListHead, Link); 205 } 206 ASSERT (Statement->Storage != NULL); 207 208 return Statement; 209 } 210 211 /** 212 Allocate a FORMSET_STORAGE data structure and insert to FormSet Storage List. 213 214 @param FormSet Pointer of the current FormSet 215 216 @return Pointer to a FORMSET_STORAGE data structure. 217 218 **/ 219 FORMSET_STORAGE * 220 CreateStorage ( 221 IN FORM_BROWSER_FORMSET *FormSet 222 ) 223 { 224 FORMSET_STORAGE *Storage; 225 226 Storage = AllocateZeroPool (sizeof (FORMSET_STORAGE)); 227 ASSERT (Storage != NULL); 228 Storage->Signature = FORMSET_STORAGE_SIGNATURE; 229 InsertTailList (&FormSet->StorageListHead, &Storage->Link); 230 231 return Storage; 232 } 233 234 /** 235 Free resources of a storage 236 237 @param Storage Pointer of the storage 238 239 @return None. 240 241 **/ 242 VOID 243 DestroyStorage ( 244 IN FORMSET_STORAGE *Storage 245 ) 246 { 247 if (Storage == NULL) { 248 return; 249 } 250 251 if (Storage->Name!= NULL) { 252 FreePool (Storage->Name); 253 } 254 255 FreePool (Storage); 256 } 257 258 259 /** 260 Free resources of a Statement 261 262 @param Statement Pointer of the Statement 263 264 @return None. 265 266 **/ 267 VOID 268 DestroyStatement ( 269 IN OUT FORM_BROWSER_STATEMENT *Statement 270 ) 271 { 272 LIST_ENTRY *Link; 273 QUESTION_DEFAULT *Default; 274 QUESTION_OPTION *Option; 275 276 // 277 // Free Default value List 278 // 279 while (!IsListEmpty (&Statement->DefaultListHead)) { 280 Link = GetFirstNode (&Statement->DefaultListHead); 281 Default = QUESTION_DEFAULT_FROM_LINK (Link); 282 RemoveEntryList (&Default->Link); 283 284 gBS->FreePool (Default); 285 } 286 287 // 288 // Free Options List 289 // 290 while (!IsListEmpty (&Statement->OptionListHead)) { 291 Link = GetFirstNode (&Statement->OptionListHead); 292 Option = QUESTION_OPTION_FROM_LINK (Link); 293 RemoveEntryList (&Option->Link); 294 295 gBS->FreePool (Option); 296 } 297 298 } 299 300 301 302 /** 303 Free resources of a Form 304 305 @param Form Pointer of the Form 306 307 @return None. 308 309 **/ 310 VOID 311 DestroyForm ( 312 IN OUT FORM_BROWSER_FORM *Form 313 ) 314 { 315 LIST_ENTRY *Link; 316 FORM_BROWSER_STATEMENT *Statement; 317 318 // 319 // Free Statements/Questions 320 // 321 while (!IsListEmpty (&Form->StatementListHead)) { 322 Link = GetFirstNode (&Form->StatementListHead); 323 Statement = FORM_BROWSER_STATEMENT_FROM_LINK (Link); 324 RemoveEntryList (&Statement->Link); 325 326 DestroyStatement (Statement); 327 } 328 329 // 330 // Free this Form 331 // 332 gBS->FreePool (Form); 333 } 334 335 336 /** 337 Free resources allocated for a FormSet 338 339 @param FormSet Pointer of the FormSet 340 341 @return None. 342 343 **/ 344 VOID 345 DestroyFormSet ( 346 IN OUT FORM_BROWSER_FORMSET *FormSet 347 ) 348 { 349 LIST_ENTRY *Link; 350 FORMSET_STORAGE *Storage; 351 FORMSET_DEFAULTSTORE *DefaultStore; 352 FORM_BROWSER_FORM *Form; 353 354 // 355 // Free IFR binary buffer 356 // 357 FreePool (FormSet->IfrBinaryData); 358 359 // 360 // Free FormSet Storage 361 // 362 if (FormSet->StorageListHead.ForwardLink != NULL) { 363 while (!IsListEmpty (&FormSet->StorageListHead)) { 364 Link = GetFirstNode (&FormSet->StorageListHead); 365 Storage = FORMSET_STORAGE_FROM_LINK (Link); 366 RemoveEntryList (&Storage->Link); 367 368 DestroyStorage (Storage); 369 } 370 } 371 372 // 373 // Free FormSet Default Store 374 // 375 if (FormSet->DefaultStoreListHead.ForwardLink != NULL) { 376 while (!IsListEmpty (&FormSet->DefaultStoreListHead)) { 377 Link = GetFirstNode (&FormSet->DefaultStoreListHead); 378 DefaultStore = FORMSET_DEFAULTSTORE_FROM_LINK (Link); 379 RemoveEntryList (&DefaultStore->Link); 380 381 gBS->FreePool (DefaultStore); 382 } 383 } 384 385 // 386 // Free Forms 387 // 388 if (FormSet->FormListHead.ForwardLink != NULL) { 389 while (!IsListEmpty (&FormSet->FormListHead)) { 390 Link = GetFirstNode (&FormSet->FormListHead); 391 Form = FORM_BROWSER_FORM_FROM_LINK (Link); 392 RemoveEntryList (&Form->Link); 393 394 DestroyForm (Form); 395 } 396 } 397 398 if (FormSet->StatementBuffer != NULL) { 399 FreePool (FormSet->StatementBuffer); 400 } 401 402 DestoryOneOfOptionMap (&FormSet->OneOfOptionMapListHead); 403 404 if (FormSet->OriginalDefaultVarStoreName != NULL) { 405 FreePool (FormSet->OriginalDefaultVarStoreName); 406 } 407 408 FreePool (FormSet); 409 } 410 411 412 /** 413 Tell whether this Operand is an Expression OpCode or not 414 415 @param Operand Operand of an IFR OpCode. 416 417 @retval TRUE This is an Expression OpCode. 418 @retval FALSE Not an Expression OpCode. 419 420 **/ 421 BOOLEAN 422 IsExpressionOpCode ( 423 IN UINT8 Operand 424 ) 425 { 426 if (((Operand >= EFI_IFR_EQ_ID_VAL_OP) && (Operand <= EFI_IFR_NOT_OP)) || 427 ((Operand >= EFI_IFR_MATCH_OP) && (Operand <= EFI_IFR_SET_OP)) || 428 ((Operand >= EFI_IFR_EQUAL_OP) && (Operand <= EFI_IFR_SPAN_OP)) || 429 (Operand == EFI_IFR_CATENATE_OP) || 430 (Operand == EFI_IFR_TO_LOWER_OP) || 431 (Operand == EFI_IFR_TO_UPPER_OP) || 432 (Operand == EFI_IFR_MAP_OP) || 433 (Operand == EFI_IFR_VERSION_OP) || 434 (Operand == EFI_IFR_SECURITY_OP)) { 435 return TRUE; 436 } else { 437 return FALSE; 438 } 439 } 440 441 442 /** 443 Calculate number of Statemens(Questions) and Expression OpCodes. 444 445 @param FormSet The FormSet to be counted. 446 @param NumberOfStatement Number of Statemens(Questions) 447 @param NumberOfExpression Number of Expression OpCodes 448 449 @return None. 450 451 **/ 452 VOID 453 CountOpCodes ( 454 IN FORM_BROWSER_FORMSET *FormSet, 455 IN OUT UINT16 *NumberOfStatement, 456 IN OUT UINT16 *NumberOfExpression 457 ) 458 { 459 UINT16 StatementCount; 460 UINT16 ExpressionCount; 461 UINT8 *OpCodeData; 462 UINTN Offset; 463 UINTN OpCodeLen; 464 465 Offset = 0; 466 StatementCount = 0; 467 ExpressionCount = 0; 468 469 while (Offset < FormSet->IfrBinaryLength) { 470 OpCodeData = FormSet->IfrBinaryData + Offset; 471 OpCodeLen = ((EFI_IFR_OP_HEADER *) OpCodeData)->Length; 472 Offset += OpCodeLen; 473 474 if (IsExpressionOpCode (((EFI_IFR_OP_HEADER *) OpCodeData)->OpCode)) { 475 ExpressionCount++; 476 } else { 477 StatementCount++; 478 } 479 } 480 481 *NumberOfStatement = StatementCount; 482 *NumberOfExpression = ExpressionCount; 483 } 484 485 486 /** 487 Parse opcodes in the formset IFR binary. 488 489 @param FormSet Pointer of the FormSet data structure. 490 491 @retval EFI_SUCCESS Opcode parse success. 492 @retval Other Opcode parse fail. 493 494 **/ 495 EFI_STATUS 496 ParseOpCodes ( 497 IN FORM_BROWSER_FORMSET *FormSet 498 ) 499 { 500 EFI_STATUS Status; 501 UINT16 Index; 502 FORM_BROWSER_FORM *CurrentForm; 503 FORM_BROWSER_STATEMENT *CurrentStatement; 504 UINT8 Operand; 505 UINT8 Scope; 506 UINTN OpCodeOffset; 507 UINTN OpCodeLength; 508 UINT8 *OpCodeData; 509 UINT8 ScopeOpCode; 510 FORMSET_STORAGE *Storage; 511 FORMSET_DEFAULTSTORE *DefaultStore; 512 QUESTION_DEFAULT *CurrentDefault; 513 QUESTION_OPTION *CurrentOption; 514 CHAR8 *AsciiString; 515 UINT16 NumberOfStatement; 516 UINT16 NumberOfExpression; 517 EFI_IMAGE_ID *ImageId; 518 EFI_HII_VALUE *Value; 519 LIST_ENTRY *OneOfOptinMapEntryListHead; 520 EFI_IFR_GUID_OPTIONKEY *OptionMap; 521 ONE_OF_OPTION_MAP *OneOfOptionMap; 522 ONE_OF_OPTION_MAP_ENTRY *OneOfOptionMapEntry; 523 UINT8 OneOfType; 524 EFI_IFR_ONE_OF *OneOfOpcode; 525 HII_THUNK_CONTEXT *ThunkContext; 526 EFI_IFR_FORM_MAP_METHOD *MapMethod; 527 528 mInScopeSubtitle = FALSE; 529 mInScopeSuppress = FALSE; 530 mInScopeGrayOut = FALSE; 531 CurrentDefault = NULL; 532 CurrentOption = NULL; 533 MapMethod = NULL; 534 ThunkContext = UefiHiiHandleToThunkContext ((CONST HII_THUNK_PRIVATE_DATA*) mHiiThunkPrivateData, FormSet->HiiHandle); 535 536 // 537 // Set to a invalid value. 538 // 539 OneOfType = (UINT8) -1; 540 541 // 542 // Get the number of Statements and Expressions 543 // 544 CountOpCodes (FormSet, &NumberOfStatement, &NumberOfExpression); 545 FormSet->NumberOfStatement = NumberOfStatement; 546 547 mStatementIndex = 0; 548 FormSet->StatementBuffer = AllocateZeroPool (NumberOfStatement * sizeof (FORM_BROWSER_STATEMENT)); 549 if (FormSet->StatementBuffer == NULL) { 550 return EFI_OUT_OF_RESOURCES; 551 } 552 553 InitializeListHead (&FormSet->StorageListHead); 554 InitializeListHead (&FormSet->DefaultStoreListHead); 555 InitializeListHead (&FormSet->FormListHead); 556 InitializeListHead (&FormSet->OneOfOptionMapListHead); 557 558 CurrentForm = NULL; 559 CurrentStatement = NULL; 560 561 ResetScopeStack (); 562 563 OpCodeOffset = 0; 564 while (OpCodeOffset < FormSet->IfrBinaryLength) { 565 OpCodeData = FormSet->IfrBinaryData + OpCodeOffset; 566 567 OpCodeLength = ((EFI_IFR_OP_HEADER *) OpCodeData)->Length; 568 OpCodeOffset += OpCodeLength; 569 Operand = ((EFI_IFR_OP_HEADER *) OpCodeData)->OpCode; 570 Scope = ((EFI_IFR_OP_HEADER *) OpCodeData)->Scope; 571 572 // 573 // If scope bit set, push onto scope stack 574 // 575 if (Scope != 0) { 576 PushScope (Operand); 577 } 578 579 if (IsExpressionOpCode (Operand)) { 580 continue; 581 } 582 583 // 584 // Parse the Opcode 585 // 586 switch (Operand) { 587 588 case EFI_IFR_FORM_SET_OP: 589 // 590 // check the formset GUID 591 // 592 if (!CompareGuid ((EFI_GUID *)(VOID *)&FormSet->Guid, (EFI_GUID *)(VOID *)&((EFI_IFR_FORM_SET *) OpCodeData)->Guid)) { 593 return EFI_INVALID_PARAMETER; 594 } 595 596 CopyMem (&FormSet->FormSetTitle, &((EFI_IFR_FORM_SET *) OpCodeData)->FormSetTitle, sizeof (EFI_STRING_ID)); 597 CopyMem (&FormSet->Help, &((EFI_IFR_FORM_SET *) OpCodeData)->Help, sizeof (EFI_STRING_ID)); 598 break; 599 600 case EFI_IFR_FORM_OP: 601 // 602 // Create a new Form for this FormSet 603 // 604 CurrentForm = AllocateZeroPool (sizeof (FORM_BROWSER_FORM)); 605 ASSERT (CurrentForm != NULL); 606 CurrentForm->Signature = FORM_BROWSER_FORM_SIGNATURE; 607 608 InitializeListHead (&CurrentForm->StatementListHead); 609 610 CopyMem (&CurrentForm->FormId, &((EFI_IFR_FORM *) OpCodeData)->FormId, sizeof (UINT16)); 611 CopyMem (&CurrentForm->FormTitle, &((EFI_IFR_FORM *) OpCodeData)->FormTitle, sizeof (EFI_STRING_ID)); 612 613 // 614 // Insert into Form list of this FormSet 615 // 616 InsertTailList (&FormSet->FormListHead, &CurrentForm->Link); 617 break; 618 619 case EFI_IFR_FORM_MAP_OP: 620 // 621 // Create a new Form Map for this FormSet 622 // 623 CurrentForm = AllocateZeroPool (sizeof (FORM_BROWSER_FORM)); 624 ASSERT (CurrentForm != NULL); 625 CurrentForm->Signature = FORM_BROWSER_FORM_SIGNATURE; 626 627 InitializeListHead (&CurrentForm->StatementListHead); 628 629 CopyMem (&CurrentForm->FormId, &((EFI_IFR_FORM *) OpCodeData)->FormId, sizeof (UINT16)); 630 MapMethod = (EFI_IFR_FORM_MAP_METHOD *) (OpCodeData + sizeof (EFI_IFR_FORM_MAP)); 631 632 // 633 // FormMap Form must contain at least one Map Method. 634 // 635 if (((EFI_IFR_OP_HEADER *) OpCodeData)->Length < ((UINTN) (UINT8 *) (MapMethod + 1) - (UINTN) OpCodeData)) { 636 return EFI_INVALID_PARAMETER; 637 } 638 639 // 640 // Try to find the standard form map method. 641 // 642 while (((UINTN) (UINT8 *) MapMethod - (UINTN) OpCodeData) < ((EFI_IFR_OP_HEADER *) OpCodeData)->Length) { 643 if (CompareGuid ((EFI_GUID *) (VOID *) &MapMethod->MethodIdentifier, &gEfiHiiStandardFormGuid)) { 644 CopyMem (&CurrentForm->FormTitle, &MapMethod->MethodTitle, sizeof (EFI_STRING_ID)); 645 break; 646 } 647 MapMethod ++; 648 } 649 // 650 // If the standard form map method is not found, the first map method title will be used. 651 // 652 if (CurrentForm->FormTitle == 0) { 653 MapMethod = (EFI_IFR_FORM_MAP_METHOD *) (OpCodeData + sizeof (EFI_IFR_FORM_MAP)); 654 CopyMem (&CurrentForm->FormTitle, &MapMethod->MethodTitle, sizeof (EFI_STRING_ID)); 655 } 656 657 // 658 // Insert into Form list of this FormSet 659 // 660 InsertTailList (&FormSet->FormListHead, &CurrentForm->Link); 661 break; 662 663 // 664 // Storage 665 // 666 case EFI_IFR_VARSTORE_OP: 667 // 668 // Create a buffer Storage for this FormSet 669 // 670 Storage = CreateStorage (FormSet); 671 Storage->Type = EFI_HII_VARSTORE_BUFFER; 672 673 CopyMem (&Storage->VarStoreId, &((EFI_IFR_VARSTORE *) OpCodeData)->VarStoreId, sizeof (EFI_VARSTORE_ID)); 674 CopyMem (&Storage->Guid, &((EFI_IFR_VARSTORE *) OpCodeData)->Guid, sizeof (EFI_GUID)); 675 CopyMem (&Storage->Size, &((EFI_IFR_VARSTORE *) OpCodeData)->Size, sizeof (UINT16)); 676 677 AsciiString = (CHAR8 *) ((EFI_IFR_VARSTORE *) OpCodeData)->Name; 678 Storage->Name = AllocateZeroPool (AsciiStrSize (AsciiString) * 2); 679 ASSERT (Storage->Name != NULL); 680 for (Index = 0; AsciiString[Index] != 0; Index++) { 681 Storage->Name[Index] = (CHAR16) AsciiString[Index]; 682 } 683 684 break; 685 686 case EFI_IFR_VARSTORE_NAME_VALUE_OP: 687 // 688 // Framework IFR doesn't support Name/Value VarStore opcode 689 // 690 if (ThunkContext != NULL && ThunkContext->ByFrameworkHiiNewPack) { 691 ASSERT (FALSE); 692 } 693 694 // 695 // Create a name/value Storage for this FormSet 696 // 697 Storage = CreateStorage (FormSet); 698 Storage->Type = EFI_HII_VARSTORE_NAME_VALUE; 699 700 CopyMem (&Storage->VarStoreId, &((EFI_IFR_VARSTORE_NAME_VALUE *) OpCodeData)->VarStoreId, sizeof (EFI_VARSTORE_ID)); 701 CopyMem (&Storage->Guid, &((EFI_IFR_VARSTORE_NAME_VALUE *) OpCodeData)->Guid, sizeof (EFI_GUID)); 702 703 break; 704 705 case EFI_IFR_VARSTORE_EFI_OP: 706 // 707 // Create a EFI variable Storage for this FormSet 708 // 709 Storage = CreateStorage (FormSet); 710 Storage->Type = EFI_HII_VARSTORE_EFI_VARIABLE; 711 712 CopyMem (&Storage->VarStoreId, &((EFI_IFR_VARSTORE_EFI *) OpCodeData)->VarStoreId, sizeof (EFI_VARSTORE_ID)); 713 CopyMem (&Storage->Guid, &((EFI_IFR_VARSTORE_EFI *) OpCodeData)->Guid, sizeof (EFI_GUID)); 714 CopyMem (&Storage->Attributes, &((EFI_IFR_VARSTORE_EFI *) OpCodeData)->Attributes, sizeof (UINT32)); 715 break; 716 717 // 718 // DefaultStore 719 // 720 case EFI_IFR_DEFAULTSTORE_OP: 721 DefaultStore = AllocateZeroPool (sizeof (FORMSET_DEFAULTSTORE)); 722 ASSERT (DefaultStore != NULL); 723 DefaultStore->Signature = FORMSET_DEFAULTSTORE_SIGNATURE; 724 725 CopyMem (&DefaultStore->DefaultId, &((EFI_IFR_DEFAULTSTORE *) OpCodeData)->DefaultId, sizeof (UINT16)); 726 CopyMem (&DefaultStore->DefaultName, &((EFI_IFR_DEFAULTSTORE *) OpCodeData)->DefaultName, sizeof (EFI_STRING_ID)); 727 728 // 729 // Insert to DefaultStore list of this Formset 730 // 731 InsertTailList (&FormSet->DefaultStoreListHead, &DefaultStore->Link); 732 break; 733 734 // 735 // Statements 736 // 737 case EFI_IFR_SUBTITLE_OP: 738 CurrentStatement = CreateStatement (OpCodeData, FormSet, CurrentForm); 739 ASSERT (CurrentStatement != NULL); 740 CurrentStatement->Flags = ((EFI_IFR_SUBTITLE *) OpCodeData)->Flags; 741 742 if (Scope != 0) { 743 mInScopeSubtitle = TRUE; 744 } 745 break; 746 747 case EFI_IFR_TEXT_OP: 748 CurrentStatement = CreateStatement (OpCodeData, FormSet, CurrentForm); 749 ASSERT (CurrentStatement != NULL); 750 751 CopyMem (&CurrentStatement->TextTwo, &((EFI_IFR_TEXT *) OpCodeData)->TextTwo, sizeof (EFI_STRING_ID)); 752 break; 753 754 // 755 // Questions 756 // 757 case EFI_IFR_ACTION_OP: 758 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm); 759 ASSERT (CurrentStatement != NULL); 760 761 if (OpCodeLength == sizeof (EFI_IFR_ACTION_1)) { 762 // 763 // No QuestionConfig present, so no configuration string will be processed 764 // 765 CurrentStatement->QuestionConfig = 0; 766 } else { 767 CopyMem (&CurrentStatement->QuestionConfig, &((EFI_IFR_ACTION *) OpCodeData)->QuestionConfig, sizeof (EFI_STRING_ID)); 768 } 769 break; 770 771 case EFI_IFR_RESET_BUTTON_OP: 772 CurrentStatement = CreateStatement (OpCodeData, FormSet, CurrentForm); 773 ASSERT (CurrentStatement != NULL); 774 CopyMem (&CurrentStatement->DefaultId, &((EFI_IFR_RESET_BUTTON *) OpCodeData)->DefaultId, sizeof (EFI_DEFAULT_ID)); 775 break; 776 777 case EFI_IFR_REF_OP: 778 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm); 779 ASSERT (CurrentStatement != NULL); 780 781 CopyMem (&CurrentStatement->RefFormId, &((EFI_IFR_REF *) OpCodeData)->FormId, sizeof (EFI_FORM_ID)); 782 if (OpCodeLength >= sizeof (EFI_IFR_REF2)) { 783 CopyMem (&CurrentStatement->RefQuestionId, &((EFI_IFR_REF2 *) OpCodeData)->QuestionId, sizeof (EFI_QUESTION_ID)); 784 785 if (OpCodeLength >= sizeof (EFI_IFR_REF3)) { 786 CopyMem (&CurrentStatement->RefFormSetId, &((EFI_IFR_REF3 *) OpCodeData)->FormSetId, sizeof (EFI_GUID)); 787 788 if (OpCodeLength >= sizeof (EFI_IFR_REF4)) { 789 CopyMem (&CurrentStatement->RefDevicePath, &((EFI_IFR_REF4 *) OpCodeData)->DevicePath, sizeof (EFI_STRING_ID)); 790 } 791 } 792 } 793 break; 794 795 case EFI_IFR_ONE_OF_OP: 796 case EFI_IFR_NUMERIC_OP: 797 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm); 798 ASSERT (CurrentStatement != NULL); 799 800 CurrentStatement->Flags = ((EFI_IFR_ONE_OF *) OpCodeData)->Flags; 801 Value = &CurrentStatement->HiiValue; 802 803 switch (CurrentStatement->Flags & EFI_IFR_NUMERIC_SIZE) { 804 case EFI_IFR_NUMERIC_SIZE_1: 805 CurrentStatement->Minimum = ((EFI_IFR_NUMERIC *) OpCodeData)->data.u8.MinValue; 806 CurrentStatement->Maximum = ((EFI_IFR_NUMERIC *) OpCodeData)->data.u8.MaxValue; 807 CurrentStatement->Step = ((EFI_IFR_NUMERIC *) OpCodeData)->data.u8.Step; 808 CurrentStatement->StorageWidth = (UINT16) sizeof (UINT8); 809 Value->Type = EFI_IFR_TYPE_NUM_SIZE_8; 810 break; 811 812 case EFI_IFR_NUMERIC_SIZE_2: 813 CopyMem (&CurrentStatement->Minimum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u16.MinValue, sizeof (UINT16)); 814 CopyMem (&CurrentStatement->Maximum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u16.MaxValue, sizeof (UINT16)); 815 CopyMem (&CurrentStatement->Step, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u16.Step, sizeof (UINT16)); 816 CurrentStatement->StorageWidth = (UINT16) sizeof (UINT16); 817 Value->Type = EFI_IFR_TYPE_NUM_SIZE_16; 818 break; 819 820 case EFI_IFR_NUMERIC_SIZE_4: 821 CopyMem (&CurrentStatement->Minimum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u32.MinValue, sizeof (UINT32)); 822 CopyMem (&CurrentStatement->Maximum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u32.MaxValue, sizeof (UINT32)); 823 CopyMem (&CurrentStatement->Step, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u32.Step, sizeof (UINT32)); 824 CurrentStatement->StorageWidth = (UINT16) sizeof (UINT32); 825 Value->Type = EFI_IFR_TYPE_NUM_SIZE_32; 826 break; 827 828 case EFI_IFR_NUMERIC_SIZE_8: 829 CopyMem (&CurrentStatement->Minimum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u64.MinValue, sizeof (UINT64)); 830 CopyMem (&CurrentStatement->Maximum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u64.MaxValue, sizeof (UINT64)); 831 CopyMem (&CurrentStatement->Step, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u64.Step, sizeof (UINT64)); 832 CurrentStatement->StorageWidth = (UINT16) sizeof (UINT64); 833 Value->Type = EFI_IFR_TYPE_NUM_SIZE_64; 834 break; 835 836 default: 837 break; 838 } 839 840 if (Operand == EFI_IFR_ONE_OF_OP) { 841 OneOfOpcode = (EFI_IFR_ONE_OF *) OpCodeData; 842 OneOfType = (UINT8) (OneOfOpcode->Flags & EFI_IFR_NUMERIC_SIZE); 843 } 844 break; 845 846 case EFI_IFR_ORDERED_LIST_OP: 847 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm); 848 ASSERT (CurrentStatement != NULL); 849 850 CurrentStatement->Flags = ((EFI_IFR_ORDERED_LIST *) OpCodeData)->Flags; 851 CurrentStatement->MaxContainers = ((EFI_IFR_ORDERED_LIST *) OpCodeData)->MaxContainers; 852 CurrentStatement->StorageWidth = (UINT16)(CurrentStatement->MaxContainers * sizeof (UINT8)); 853 854 // 855 // No buffer type is defined in EFI_IFR_TYPE_VALUE, so a Configuration Driver 856 // has to use FormBrowser2.Callback() to retrieve the uncommited data for 857 // an interactive orderedlist (i.e. with EFI_IFR_FLAG_CALLBACK flag set). 858 // 859 CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_OTHER; 860 CurrentStatement->BufferValue = AllocateZeroPool (CurrentStatement->StorageWidth); 861 862 break; 863 864 case EFI_IFR_CHECKBOX_OP: 865 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm); 866 ASSERT (CurrentStatement != NULL); 867 868 CurrentStatement->Flags = ((EFI_IFR_CHECKBOX *) OpCodeData)->Flags; 869 CurrentStatement->StorageWidth = (UINT16) sizeof (BOOLEAN); 870 CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_BOOLEAN; 871 872 break; 873 874 case EFI_IFR_STRING_OP: 875 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm); 876 ASSERT (CurrentStatement != NULL); 877 878 // 879 // MinSize is the minimum number of characters that can be accepted for this opcode, 880 // MaxSize is the maximum number of characters that can be accepted for this opcode. 881 // The characters are stored as Unicode, so the storage width should multiply 2. 882 // 883 CurrentStatement->Minimum = ((EFI_IFR_STRING *) OpCodeData)->MinSize; 884 CurrentStatement->Maximum = ((EFI_IFR_STRING *) OpCodeData)->MaxSize; 885 CurrentStatement->StorageWidth = (UINT16)((UINTN) CurrentStatement->Maximum * sizeof (UINT16)); 886 CurrentStatement->Flags = ((EFI_IFR_STRING *) OpCodeData)->Flags; 887 888 CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_STRING; 889 CurrentStatement->BufferValue = AllocateZeroPool (CurrentStatement->StorageWidth); 890 891 break; 892 893 case EFI_IFR_PASSWORD_OP: 894 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm); 895 ASSERT (CurrentStatement != NULL); 896 897 // 898 // MinSize is the minimum number of characters that can be accepted for this opcode, 899 // MaxSize is the maximum number of characters that can be accepted for this opcode. 900 // The characters are stored as Unicode, so the storage width should multiply 2. 901 // 902 CopyMem (&CurrentStatement->Minimum, &((EFI_IFR_PASSWORD *) OpCodeData)->MinSize, sizeof (UINT16)); 903 CopyMem (&CurrentStatement->Maximum, &((EFI_IFR_PASSWORD *) OpCodeData)->MaxSize, sizeof (UINT16)); 904 CurrentStatement->StorageWidth = (UINT16)((UINTN) CurrentStatement->Maximum * sizeof (UINT16)); 905 906 CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_STRING; 907 CurrentStatement->BufferValue = AllocateZeroPool (CurrentStatement->StorageWidth); 908 909 break; 910 911 case EFI_IFR_DATE_OP: 912 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm); 913 ASSERT (CurrentStatement != NULL); 914 915 CurrentStatement->Flags = ((EFI_IFR_DATE *) OpCodeData)->Flags; 916 CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_DATE; 917 918 break; 919 920 case EFI_IFR_TIME_OP: 921 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm); 922 ASSERT (CurrentStatement != NULL); 923 924 CurrentStatement->Flags = ((EFI_IFR_TIME *) OpCodeData)->Flags; 925 CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_TIME; 926 927 break; 928 929 // 930 // Default 931 // 932 case EFI_IFR_DEFAULT_OP: 933 // 934 // EFI_IFR_DEFAULT appear in scope of a Question, 935 // It creates a default value for the current question. 936 // A Question may have more than one Default value which have different default types. 937 // 938 CurrentDefault = AllocateZeroPool (sizeof (QUESTION_DEFAULT)); 939 ASSERT (CurrentDefault != NULL); 940 CurrentDefault->Signature = QUESTION_DEFAULT_SIGNATURE; 941 942 CurrentDefault->Value.Type = ((EFI_IFR_DEFAULT *) OpCodeData)->Type; 943 CopyMem (&CurrentDefault->DefaultId, &((EFI_IFR_DEFAULT *) OpCodeData)->DefaultId, sizeof (UINT16)); 944 CopyMem (&CurrentDefault->Value.Value, &((EFI_IFR_DEFAULT *) OpCodeData)->Value, sizeof (EFI_IFR_TYPE_VALUE)); 945 ExtendValueToU64 (&CurrentDefault->Value); 946 947 // 948 // Insert to Default Value list of current Question 949 // 950 InsertTailList (&CurrentStatement->DefaultListHead, &CurrentDefault->Link); 951 952 break; 953 954 // 955 // Option 956 // 957 case EFI_IFR_ONE_OF_OPTION_OP: 958 // 959 // EFI_IFR_ONE_OF_OPTION appear in scope of a Question. 960 // It create a selection for use in current Question. 961 // 962 CurrentOption = AllocateZeroPool (sizeof (QUESTION_OPTION)); 963 ASSERT (CurrentOption != NULL); 964 CurrentOption->Signature = QUESTION_OPTION_SIGNATURE; 965 966 CurrentOption->Flags = ((EFI_IFR_ONE_OF_OPTION *) OpCodeData)->Flags; 967 CurrentOption->Value.Type = ((EFI_IFR_ONE_OF_OPTION *) OpCodeData)->Type; 968 CopyMem (&CurrentOption->Text, &((EFI_IFR_ONE_OF_OPTION *) OpCodeData)->Option, sizeof (EFI_STRING_ID)); 969 CopyMem (&CurrentOption->Value.Value, &((EFI_IFR_ONE_OF_OPTION *) OpCodeData)->Value, sizeof (EFI_IFR_TYPE_VALUE)); 970 ExtendValueToU64 (&CurrentOption->Value); 971 972 // 973 // Insert to Option list of current Question 974 // 975 InsertTailList (&CurrentStatement->OptionListHead, &CurrentOption->Link); 976 break; 977 978 // 979 // Conditional 980 // 981 case EFI_IFR_NO_SUBMIT_IF_OP: 982 case EFI_IFR_INCONSISTENT_IF_OP: 983 break; 984 985 case EFI_IFR_SUPPRESS_IF_OP: 986 break; 987 988 case EFI_IFR_GRAY_OUT_IF_OP: 989 break; 990 991 case EFI_IFR_DISABLE_IF_OP: 992 // 993 // Framework IFR doesn't support DisableIf opcode 994 // 995 if (ThunkContext != NULL && ThunkContext->ByFrameworkHiiNewPack) { 996 ASSERT (FALSE); 997 } 998 999 // 1000 // Expression 1001 // 1002 case EFI_IFR_VALUE_OP: 1003 case EFI_IFR_READ_OP: 1004 case EFI_IFR_WRITE_OP: 1005 break; 1006 1007 case EFI_IFR_RULE_OP: 1008 break; 1009 1010 // 1011 // Image 1012 // 1013 case EFI_IFR_IMAGE_OP: 1014 // 1015 // Get ScopeOpcode from top of stack 1016 // 1017 PopScope (&ScopeOpCode); 1018 PushScope (ScopeOpCode); 1019 1020 switch (ScopeOpCode) { 1021 case EFI_IFR_FORM_SET_OP: 1022 ImageId = &FormSet->ImageId; 1023 break; 1024 1025 case EFI_IFR_FORM_OP: 1026 case EFI_IFR_FORM_MAP_OP: 1027 ASSERT (CurrentForm != NULL); 1028 ImageId = &CurrentForm->ImageId; 1029 break; 1030 1031 case EFI_IFR_ONE_OF_OPTION_OP: 1032 ASSERT (CurrentOption != NULL); 1033 ImageId = &CurrentOption->ImageId; 1034 break; 1035 1036 default: 1037 // 1038 // Make sure CurrentStatement is not NULL. 1039 // If it is NULL, 1) ParseOpCodes functions may parse the IFR wrongly. Or 2) the IFR 1040 // file is wrongly generated by tools such as VFR Compiler. 1041 // 1042 ASSERT (CurrentStatement != NULL); 1043 ImageId = &CurrentStatement->ImageId; 1044 break; 1045 } 1046 1047 ASSERT (ImageId != NULL); 1048 CopyMem (ImageId, &((EFI_IFR_IMAGE *) OpCodeData)->Id, sizeof (EFI_IMAGE_ID)); 1049 break; 1050 1051 // 1052 // Refresh 1053 // 1054 case EFI_IFR_REFRESH_OP: 1055 ASSERT (CurrentStatement != NULL); 1056 CurrentStatement->RefreshInterval = ((EFI_IFR_REFRESH *) OpCodeData)->RefreshInterval; 1057 break; 1058 1059 // 1060 // Vendor specific 1061 // 1062 case EFI_IFR_GUID_OP: 1063 OptionMap = (EFI_IFR_GUID_OPTIONKEY *) OpCodeData; 1064 1065 if (CompareGuid (&mTianoHiiIfrGuid, (EFI_GUID *)(OpCodeData + sizeof (EFI_IFR_OP_HEADER)))) { 1066 // 1067 // Tiano specific GUIDed opcodes 1068 // 1069 switch (((EFI_IFR_GUID_LABEL *) OpCodeData)->ExtendOpCode) { 1070 case EFI_IFR_EXTEND_OP_LABEL: 1071 // 1072 // just ignore label 1073 // 1074 break; 1075 1076 1077 case EFI_IFR_EXTEND_OP_CLASS: 1078 CopyMem (&FormSet->Class, &((EFI_IFR_GUID_CLASS *) OpCodeData)->Class, sizeof (UINT16)); 1079 break; 1080 1081 case EFI_IFR_EXTEND_OP_SUBCLASS: 1082 CopyMem (&FormSet->SubClass, &((EFI_IFR_GUID_SUBCLASS *) OpCodeData)->SubClass, sizeof (UINT16)); 1083 break; 1084 1085 default: 1086 break; 1087 } 1088 } else if (CompareGuid ((EFI_GUID *)(VOID *)&OptionMap->Guid, &mFrameworkHiiCompatibilityGuid)) { 1089 if (OptionMap->ExtendOpCode == EFI_IFR_EXTEND_OP_OPTIONKEY) { 1090 OneOfOptinMapEntryListHead = GetOneOfOptionMapEntryListHead (FormSet, OptionMap->QuestionId); 1091 if (OneOfOptinMapEntryListHead == NULL) { 1092 OneOfOptionMap = AllocateZeroPool (sizeof (ONE_OF_OPTION_MAP)); 1093 ASSERT (OneOfOptionMap != NULL); 1094 1095 OneOfOptionMap->Signature = ONE_OF_OPTION_MAP_SIGNATURE; 1096 OneOfOptionMap->QuestionId = OptionMap->QuestionId; 1097 1098 // 1099 // Make sure OneOfType is initialized. 1100 // 1101 ASSERT (OneOfType != (UINT8) -1); 1102 OneOfOptionMap->ValueType = OneOfType; 1103 InitializeListHead (&OneOfOptionMap->OneOfOptionMapEntryListHead); 1104 OneOfOptinMapEntryListHead = &OneOfOptionMap->OneOfOptionMapEntryListHead; 1105 InsertTailList (&FormSet->OneOfOptionMapListHead, &OneOfOptionMap->Link); 1106 } 1107 OneOfOptionMapEntry = AllocateZeroPool (sizeof (ONE_OF_OPTION_MAP_ENTRY)); 1108 ASSERT (OneOfOptionMapEntry != NULL); 1109 1110 OneOfOptionMapEntry->Signature = ONE_OF_OPTION_MAP_ENTRY_SIGNATURE; 1111 OneOfOptionMapEntry->FwKey = OptionMap->KeyValue; 1112 CopyMem (&OneOfOptionMapEntry->Value, &OptionMap->OptionValue, sizeof (EFI_IFR_TYPE_VALUE)); 1113 1114 InsertTailList (OneOfOptinMapEntryListHead, &OneOfOptionMapEntry->Link); 1115 } 1116 } 1117 break; 1118 1119 // 1120 // Scope End 1121 // 1122 case EFI_IFR_END_OP: 1123 Status = PopScope (&ScopeOpCode); 1124 if (EFI_ERROR (Status)) { 1125 ResetScopeStack (); 1126 return Status; 1127 } 1128 1129 switch (ScopeOpCode) { 1130 case EFI_IFR_FORM_SET_OP: 1131 // 1132 // End of FormSet, update FormSet IFR binary length 1133 // to stop parsing substantial OpCodes 1134 // 1135 FormSet->IfrBinaryLength = OpCodeOffset; 1136 break; 1137 1138 case EFI_IFR_FORM_OP: 1139 case EFI_IFR_FORM_MAP_OP: 1140 // 1141 // End of Form 1142 // 1143 CurrentForm = NULL; 1144 break; 1145 1146 case EFI_IFR_ONE_OF_OPTION_OP: 1147 // 1148 // End of Option 1149 // 1150 CurrentOption = NULL; 1151 break; 1152 1153 case EFI_IFR_SUBTITLE_OP: 1154 mInScopeSubtitle = FALSE; 1155 break; 1156 1157 case EFI_IFR_NO_SUBMIT_IF_OP: 1158 case EFI_IFR_INCONSISTENT_IF_OP: 1159 // 1160 // Ignore end of EFI_IFR_NO_SUBMIT_IF and EFI_IFR_INCONSISTENT_IF 1161 // 1162 break; 1163 1164 case EFI_IFR_GRAY_OUT_IF_OP: 1165 mInScopeGrayOut = FALSE; 1166 break; 1167 1168 default: 1169 if (IsExpressionOpCode (ScopeOpCode)) { 1170 } 1171 break; 1172 } 1173 break; 1174 1175 default: 1176 break; 1177 } 1178 } 1179 1180 return EFI_SUCCESS; 1181 } 1182 1183 1184 1185 1186