1 /*++ 2 3 Copyright (c) 2004 - 2010, Intel Corporation. All rights reserved.<BR> 4 This program and the accompanying materials 5 are licensed and made available under the terms and conditions of the BSD License 6 which accompanies this distribution. The full text of the license may be found at 7 http://opensource.org/licenses/bsd-license.php 8 9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 11 12 Module Name: 13 14 VfrFormPkg.cpp 15 16 Abstract: 17 18 --*/ 19 20 #include "stdio.h" 21 #include "VfrFormPkg.h" 22 23 /* 24 * The definition of CFormPkg's member function 25 */ 26 27 SPendingAssign::SPendingAssign ( 28 IN INT8 *Key, 29 IN VOID *Addr, 30 IN UINT32 Len, 31 IN UINT32 LineNo, 32 IN INT8 *Msg 33 ) 34 { 35 mKey = NULL; 36 mAddr = Addr; 37 mLen = Len; 38 mFlag = PENDING; 39 mLineNo = LineNo; 40 mMsg = NULL; 41 mNext = NULL; 42 43 if (Key != NULL) { 44 mKey = new INT8[strlen (Key) + 1]; 45 if (mKey != NULL) { 46 strcpy (mKey, Key); 47 } 48 } 49 50 if (Msg != NULL) { 51 mMsg = new INT8[strlen (Msg) + 1]; 52 if (mMsg != NULL) { 53 strcpy (mMsg, Msg); 54 } 55 } 56 } 57 58 SPendingAssign::~SPendingAssign ( 59 VOID 60 ) 61 { 62 if (mKey != NULL) { 63 delete mKey; 64 } 65 mAddr = NULL; 66 mLen = 0; 67 mLineNo = 0; 68 if (mMsg != NULL) { 69 delete mMsg; 70 } 71 mNext = NULL; 72 } 73 74 VOID 75 SPendingAssign::SetAddrAndLen ( 76 IN VOID *Addr, 77 IN UINT32 LineNo 78 ) 79 { 80 mAddr = Addr; 81 mLineNo = LineNo; 82 } 83 84 VOID 85 SPendingAssign::AssignValue ( 86 IN VOID *Addr, 87 IN UINT32 Len 88 ) 89 { 90 memcpy (mAddr, Addr, (mLen < Len ? mLen : Len)); 91 mFlag = ASSIGNED; 92 } 93 94 INT8 * 95 SPendingAssign::GetKey ( 96 VOID 97 ) 98 { 99 return mKey; 100 } 101 102 CFormPkg::CFormPkg ( 103 IN UINT32 BufferSize = 4096 104 ) 105 { 106 CHAR8 *BufferStart; 107 CHAR8 *BufferEnd; 108 SBufferNode *Node; 109 110 mPkgLength = 0; 111 mBufferNodeQueueHead = NULL; 112 mCurrBufferNode = NULL; 113 114 Node = new SBufferNode; 115 if (Node == NULL) { 116 return ; 117 } 118 BufferStart = new CHAR8[BufferSize]; 119 if (BufferStart == NULL) { 120 return; 121 } 122 BufferEnd = BufferStart + BufferSize; 123 124 memset (BufferStart, 0, BufferSize); 125 Node->mBufferStart = BufferStart; 126 Node->mBufferEnd = BufferEnd; 127 Node->mBufferFree = BufferStart; 128 Node->mNext = NULL; 129 130 mBufferSize = BufferSize; 131 mBufferNodeQueueHead = Node; 132 mBufferNodeQueueTail = Node; 133 mCurrBufferNode = Node; 134 } 135 136 CFormPkg::~CFormPkg () 137 { 138 SBufferNode *pBNode; 139 SPendingAssign *pPNode; 140 141 while (mBufferNodeQueueHead != NULL) { 142 pBNode = mBufferNodeQueueHead; 143 mBufferNodeQueueHead = mBufferNodeQueueHead->mNext; 144 if (pBNode->mBufferStart != NULL) { 145 delete pBNode->mBufferStart; 146 delete pBNode; 147 } 148 } 149 mBufferNodeQueueTail = NULL; 150 mCurrBufferNode = NULL; 151 152 while (PendingAssignList != NULL) { 153 pPNode = PendingAssignList; 154 PendingAssignList = PendingAssignList->mNext; 155 delete pPNode; 156 } 157 PendingAssignList = NULL; 158 } 159 160 CHAR8 * 161 CFormPkg::IfrBinBufferGet ( 162 IN UINT32 Len 163 ) 164 { 165 CHAR8 *BinBuffer = NULL; 166 167 if ((Len == 0) || (Len > mBufferSize)) { 168 return NULL; 169 } 170 171 if ((mCurrBufferNode->mBufferFree + Len) <= mCurrBufferNode->mBufferEnd) { 172 BinBuffer = mCurrBufferNode->mBufferFree; 173 mCurrBufferNode->mBufferFree += Len; 174 } else { 175 SBufferNode *Node; 176 177 Node = new SBufferNode; 178 if (Node == NULL) { 179 return NULL; 180 } 181 182 Node->mBufferStart = new CHAR8[mBufferSize]; 183 if (Node->mBufferStart == NULL) { 184 delete Node; 185 return NULL; 186 } else { 187 memset (Node->mBufferStart, 0, mBufferSize); 188 Node->mBufferEnd = Node->mBufferStart + mBufferSize; 189 Node->mBufferFree = Node->mBufferStart; 190 Node->mNext = NULL; 191 } 192 193 if (mBufferNodeQueueTail == NULL) { 194 mBufferNodeQueueHead = mBufferNodeQueueTail = Node; 195 } else { 196 mBufferNodeQueueTail->mNext = Node; 197 mBufferNodeQueueTail = Node; 198 } 199 mCurrBufferNode = Node; 200 201 // 202 // Now try again. 203 // 204 BinBuffer = mCurrBufferNode->mBufferFree; 205 mCurrBufferNode->mBufferFree += Len; 206 } 207 208 mPkgLength += Len; 209 210 return BinBuffer; 211 } 212 213 inline 214 UINT32 215 CFormPkg::GetPkgLength ( 216 VOID 217 ) 218 { 219 return mPkgLength; 220 } 221 222 VOID 223 CFormPkg::Open ( 224 VOID 225 ) 226 { 227 mReadBufferNode = mBufferNodeQueueHead; 228 mReadBufferOffset = 0; 229 } 230 231 VOID 232 CFormPkg::Close ( 233 VOID 234 ) 235 { 236 mReadBufferNode = NULL; 237 mReadBufferOffset = 0; 238 } 239 240 UINT32 241 CFormPkg::Read ( 242 IN CHAR8 *Buffer, 243 IN UINT32 Size 244 ) 245 { 246 UINT32 Index; 247 248 if ((Size == 0) || (Buffer == NULL)) { 249 return 0; 250 } 251 252 if (mReadBufferNode == NULL) { 253 return 0; 254 } 255 256 for (Index = 0; Index < Size; Index++) { 257 if ((mReadBufferNode->mBufferStart + mReadBufferOffset) < mReadBufferNode->mBufferFree) { 258 Buffer[Index] = mReadBufferNode->mBufferStart[mReadBufferOffset++]; 259 } else { 260 if ((mReadBufferNode = mReadBufferNode->mNext) == NULL) { 261 return Index; 262 } else { 263 mReadBufferOffset = 0; 264 Buffer[Index] = mReadBufferNode->mBufferStart[mReadBufferOffset++]; 265 } 266 } 267 } 268 269 return Size; 270 } 271 272 EFI_VFR_RETURN_CODE 273 CFormPkg::BuildPkgHdr ( 274 OUT EFI_HII_PACKAGE_HEADER **PkgHdr 275 ) 276 { 277 if (PkgHdr == NULL) { 278 return VFR_RETURN_FATAL_ERROR; 279 } 280 281 if (((*PkgHdr) = new EFI_HII_PACKAGE_HEADER) == NULL) { 282 return VFR_RETURN_OUT_FOR_RESOURCES; 283 } 284 285 (*PkgHdr)->Type = EFI_HII_PACKAGE_FORMS; 286 (*PkgHdr)->Length = mPkgLength + sizeof (EFI_HII_PACKAGE_HEADER); 287 return VFR_RETURN_SUCCESS; 288 } 289 290 EFI_VFR_RETURN_CODE 291 CFormPkg::BuildPkg ( 292 IN FILE *Output 293 ) 294 { 295 EFI_VFR_RETURN_CODE Ret; 296 CHAR8 Buffer[1024]; 297 UINT32 Size; 298 EFI_HII_PACKAGE_HEADER *PkgHdr; 299 300 if (Output == NULL) { 301 return VFR_RETURN_FATAL_ERROR; 302 } 303 304 if ((Ret = BuildPkgHdr(&PkgHdr)) != VFR_RETURN_SUCCESS) { 305 return Ret; 306 } 307 fwrite (PkgHdr, sizeof (EFI_HII_PACKAGE_HEADER), 1, Output); 308 delete PkgHdr; 309 310 Open (); 311 while ((Size = Read (Buffer, 1024)) != 0) { 312 fwrite (Buffer, Size, 1, Output); 313 } 314 Close (); 315 316 return VFR_RETURN_SUCCESS; 317 } 318 319 VOID 320 CFormPkg::_WRITE_PKG_LINE ( 321 IN FILE *pFile, 322 IN UINT32 LineBytes, 323 IN INT8 *LineHeader, 324 IN INT8 *BlkBuf, 325 IN UINT32 BlkSize 326 ) 327 { 328 UINT32 Index; 329 330 if ((pFile == NULL) || (LineHeader == NULL) || (BlkBuf == NULL)) { 331 return; 332 } 333 334 for (Index = 0; Index < BlkSize; Index++) { 335 if ((Index % LineBytes) == 0) { 336 fprintf (pFile, "\n%s", LineHeader); 337 } 338 fprintf (pFile, "0x%02X, ", (UINT8)BlkBuf[Index]); 339 } 340 } 341 342 VOID 343 CFormPkg::_WRITE_PKG_END ( 344 IN FILE *pFile, 345 IN UINT32 LineBytes, 346 IN INT8 *LineHeader, 347 IN INT8 *BlkBuf, 348 IN UINT32 BlkSize 349 ) 350 { 351 UINT32 Index; 352 353 if ((BlkSize == 0) || (pFile == NULL) || (LineHeader == NULL) || (BlkBuf == NULL)) { 354 return; 355 } 356 357 for (Index = 0; Index < BlkSize - 1; Index++) { 358 if ((Index % LineBytes) == 0) { 359 fprintf (pFile, "\n%s", LineHeader); 360 } 361 fprintf (pFile, "0x%02X, ", (UINT8)BlkBuf[Index]); 362 } 363 364 if ((Index % LineBytes) == 0) { 365 fprintf (pFile, "\n%s", LineHeader); 366 } 367 fprintf (pFile, "0x%02X\n", (UINT8)BlkBuf[Index]); 368 } 369 370 #define BYTES_PRE_LINE 0x10 371 372 EFI_VFR_RETURN_CODE 373 CFormPkg::GenCFile ( 374 IN INT8 *BaseName, 375 IN FILE *pFile 376 ) 377 { 378 EFI_VFR_RETURN_CODE Ret; 379 INT8 Buffer[BYTES_PRE_LINE * 8]; 380 EFI_HII_PACKAGE_HEADER *PkgHdr; 381 UINT32 PkgLength = 0; 382 UINT32 ReadSize = 0; 383 384 if ((BaseName == NULL) || (pFile == NULL)) { 385 return VFR_RETURN_FATAL_ERROR; 386 } 387 388 fprintf (pFile, "\nunsigned char %sBin[] = {\n", BaseName); 389 390 if ((Ret = BuildPkgHdr(&PkgHdr)) != VFR_RETURN_SUCCESS) { 391 return Ret; 392 } 393 394 fprintf (pFile, " // ARRAY LENGTH\n"); 395 PkgLength = PkgHdr->Length + sizeof (UINT32); 396 _WRITE_PKG_LINE(pFile, BYTES_PRE_LINE, " ", (INT8 *)&PkgLength, sizeof (UINT32)); 397 398 fprintf (pFile, "\n\n // PACKAGE HEADER\n"); 399 _WRITE_PKG_LINE(pFile, BYTES_PRE_LINE, " ", (INT8 *)PkgHdr, sizeof (EFI_HII_PACKAGE_HEADER)); 400 PkgLength = sizeof (EFI_HII_PACKAGE_HEADER); 401 402 fprintf (pFile, "\n\n // PACKAGE DATA\n"); 403 Open (); 404 while ((ReadSize = Read ((CHAR8 *)Buffer, BYTES_PRE_LINE * 8)) != 0) { 405 PkgLength += ReadSize; 406 if (PkgLength < PkgHdr->Length) { 407 _WRITE_PKG_LINE (pFile, BYTES_PRE_LINE, " ", Buffer, ReadSize); 408 } else { 409 _WRITE_PKG_END (pFile, BYTES_PRE_LINE, " ", Buffer, ReadSize); 410 } 411 } 412 Close (); 413 414 delete PkgHdr; 415 fprintf (pFile, "\n};\n"); 416 417 return VFR_RETURN_SUCCESS; 418 } 419 420 EFI_VFR_RETURN_CODE 421 CFormPkg::AssignPending ( 422 IN INT8 *Key, 423 IN VOID *ValAddr, 424 IN UINT32 ValLen, 425 IN UINT32 LineNo, 426 IN INT8 *Msg 427 ) 428 { 429 SPendingAssign *pNew; 430 431 pNew = new SPendingAssign (Key, ValAddr, ValLen, LineNo, Msg); 432 if (pNew == NULL) { 433 return VFR_RETURN_OUT_FOR_RESOURCES; 434 } 435 436 pNew->mNext = PendingAssignList; 437 PendingAssignList = pNew; 438 return VFR_RETURN_SUCCESS; 439 } 440 441 VOID 442 CFormPkg::DoPendingAssign ( 443 IN INT8 *Key, 444 IN VOID *ValAddr, 445 IN UINT32 ValLen 446 ) 447 { 448 SPendingAssign *pNode; 449 450 if ((Key == NULL) || (ValAddr == NULL)) { 451 return; 452 } 453 454 for (pNode = PendingAssignList; pNode != NULL; pNode = pNode->mNext) { 455 if (strcmp (pNode->mKey, Key) == 0) { 456 pNode->AssignValue (ValAddr, ValLen); 457 } 458 } 459 } 460 461 bool 462 CFormPkg::HavePendingUnassigned ( 463 VOID 464 ) 465 { 466 SPendingAssign *pNode; 467 468 for (pNode = PendingAssignList; pNode != NULL; pNode = pNode->mNext) { 469 if (pNode->mFlag == PENDING) { 470 return TRUE; 471 } 472 } 473 474 return FALSE; 475 } 476 477 VOID 478 CFormPkg::PendingAssignPrintAll ( 479 VOID 480 ) 481 { 482 SPendingAssign *pNode; 483 484 for (pNode = PendingAssignList; pNode != NULL; pNode = pNode->mNext) { 485 if (pNode->mFlag == PENDING) { 486 gCVfrErrorHandle.PrintMsg (pNode->mLineNo, pNode->mKey, "Error", pNode->mMsg); 487 } 488 } 489 } 490 491 CFormPkg gCFormPkg; 492 493 SIfrRecord::SIfrRecord ( 494 VOID 495 ) 496 { 497 mIfrBinBuf = NULL; 498 mBinBufLen = 0; 499 mLineNo = 0xFFFFFFFF; 500 mOffset = 0xFFFFFFFF; 501 mNext = NULL; 502 } 503 504 SIfrRecord::~SIfrRecord ( 505 VOID 506 ) 507 { 508 mIfrBinBuf = NULL; 509 mLineNo = 0xFFFFFFFF; 510 mOffset = 0xFFFFFFFF; 511 mBinBufLen = 0; 512 mNext = NULL; 513 } 514 515 CIfrRecordInfoDB::CIfrRecordInfoDB ( 516 VOID 517 ) 518 { 519 mSwitch = FALSE; 520 mRecordCount = EFI_IFR_RECORDINFO_IDX_START; 521 mIfrRecordListHead = NULL; 522 mIfrRecordListTail = NULL; 523 } 524 525 CIfrRecordInfoDB::~CIfrRecordInfoDB ( 526 VOID 527 ) 528 { 529 SIfrRecord *pNode; 530 531 while (mIfrRecordListHead != NULL) { 532 pNode = mIfrRecordListHead; 533 mIfrRecordListHead = mIfrRecordListHead->mNext; 534 delete pNode; 535 } 536 } 537 538 SIfrRecord * 539 CIfrRecordInfoDB::GetRecordInfoFromIdx ( 540 IN UINT32 RecordIdx 541 ) 542 { 543 UINT32 Idx; 544 SIfrRecord *pNode = NULL; 545 546 if (RecordIdx == EFI_IFR_RECORDINFO_IDX_INVALUD) { 547 return NULL; 548 } 549 550 for (Idx = (EFI_IFR_RECORDINFO_IDX_START + 1), pNode = mIfrRecordListHead; 551 (Idx != RecordIdx) && (pNode != NULL); 552 Idx++, pNode = pNode->mNext) 553 ; 554 555 return pNode; 556 } 557 558 UINT32 559 CIfrRecordInfoDB::IfrRecordRegister ( 560 IN UINT32 LineNo, 561 IN CHAR8 *IfrBinBuf, 562 IN UINT8 BinBufLen, 563 IN UINT32 Offset 564 ) 565 { 566 SIfrRecord *pNew; 567 568 if (mSwitch == FALSE) { 569 return EFI_IFR_RECORDINFO_IDX_INVALUD; 570 } 571 572 if ((pNew = new SIfrRecord) == NULL) { 573 return EFI_IFR_RECORDINFO_IDX_INVALUD; 574 } 575 576 if (mIfrRecordListHead == NULL) { 577 mIfrRecordListHead = pNew; 578 mIfrRecordListTail = pNew; 579 } else { 580 mIfrRecordListTail->mNext = pNew; 581 mIfrRecordListTail = pNew; 582 } 583 mRecordCount++; 584 585 return mRecordCount; 586 } 587 588 VOID 589 CIfrRecordInfoDB::IfrRecordInfoUpdate ( 590 IN UINT32 RecordIdx, 591 IN UINT32 LineNo, 592 IN CHAR8 *BinBuf, 593 IN UINT8 BinBufLen, 594 IN UINT32 Offset 595 ) 596 { 597 SIfrRecord *pNode; 598 SIfrRecord *Prev; 599 600 if ((pNode = GetRecordInfoFromIdx (RecordIdx)) == NULL) { 601 return; 602 } 603 604 if (LineNo == 0) { 605 // 606 // Line number is not specified explicitly, try to use line number of previous opcode 607 // 608 Prev = GetRecordInfoFromIdx (RecordIdx - 1); 609 if (Prev != NULL) { 610 LineNo = Prev->mLineNo; 611 } 612 } 613 pNode->mLineNo = LineNo; 614 pNode->mOffset = Offset; 615 pNode->mBinBufLen = BinBufLen; 616 pNode->mIfrBinBuf = BinBuf; 617 } 618 619 VOID 620 CIfrRecordInfoDB::IfrRecordOutput ( 621 IN FILE *File, 622 IN UINT32 LineNo 623 ) 624 { 625 SIfrRecord *pNode; 626 UINT8 Index; 627 628 if (mSwitch == FALSE) { 629 return; 630 } 631 632 if (File == NULL) { 633 return; 634 } 635 636 for (pNode = mIfrRecordListHead; pNode != NULL; pNode = pNode->mNext) { 637 if (pNode->mLineNo == LineNo) { 638 fprintf (File, ">%08X: ", pNode->mOffset); 639 if (pNode->mIfrBinBuf != NULL) { 640 for (Index = 0; Index < pNode->mBinBufLen; Index++) { 641 fprintf (File, "%02X ", (UINT8)(pNode->mIfrBinBuf[Index])); 642 } 643 } 644 fprintf (File, "\n"); 645 } 646 } 647 } 648 649 CIfrRecordInfoDB gCIfrRecordInfoDB; 650 651 VOID 652 CIfrObj::_EMIT_PENDING_OBJ ( 653 VOID 654 ) 655 { 656 CHAR8 *ObjBinBuf = NULL; 657 658 ObjBinBuf = gCFormPkg.IfrBinBufferGet (mObjBinLen); 659 if (ObjBinBuf != NULL) { 660 memcpy (ObjBinBuf, mObjBinBuf, mObjBinLen); 661 } 662 663 if (mObjBinBuf != NULL) { 664 delete mObjBinBuf; 665 mObjBinBuf = ObjBinBuf; 666 } 667 } 668 669 /* 670 * The definition of CIfrObj's member function 671 */ 672 static struct { 673 UINT8 mSize; 674 UINT8 mScope; 675 } gOpcodeSizesScopeTable[] = { 676 { 0, 0 }, // EFI_IFR_INVALID - 0x00 677 { sizeof (EFI_IFR_FORM), 1 }, // EFI_IFR_FORM_OP 678 { sizeof (EFI_IFR_SUBTITLE), 1 }, // EFI_IFR_SUBTITLE_OP 679 { sizeof (EFI_IFR_TEXT), 0 }, // EFI_IFR_TEXT_OP 680 { sizeof (EFI_IFR_IMAGE), 0 }, // EFI_IFR_IMAGE_OP 681 { sizeof (EFI_IFR_ONE_OF), 1 }, // EFI_IFR_ONE_OF_OP - 0x05 682 { sizeof (EFI_IFR_CHECKBOX), 1}, // EFI_IFR_CHECKBOX_OP 683 { sizeof (EFI_IFR_NUMERIC), 1 }, // EFI_IFR_NUMERIC_OP 684 { sizeof (EFI_IFR_PASSWORD), 1 }, // EFI_IFR_PASSWORD_OP 685 { sizeof (EFI_IFR_ONE_OF_OPTION), 0 }, // EFI_IFR_ONE_OF_OPTION_OP 686 { sizeof (EFI_IFR_SUPPRESS_IF), 1 }, // EFI_IFR_SUPPRESS_IF - 0x0A 687 { sizeof (EFI_IFR_LOCKED), 0 }, // EFI_IFR_LOCKED_OP 688 { sizeof (EFI_IFR_ACTION), 1 }, // EFI_IFR_ACTION_OP 689 { sizeof (EFI_IFR_RESET_BUTTON), 1 }, // EFI_IFR_RESET_BUTTON_OP 690 { sizeof (EFI_IFR_FORM_SET), 1 }, // EFI_IFR_FORM_SET_OP -0xE 691 { sizeof (EFI_IFR_REF), 0 }, // EFI_IFR_REF_OP 692 { sizeof (EFI_IFR_NO_SUBMIT_IF), 1}, // EFI_IFR_NO_SUBMIT_IF_OP -0x10 693 { sizeof (EFI_IFR_INCONSISTENT_IF), 1 }, // EFI_IFR_INCONSISTENT_IF_OP 694 { sizeof (EFI_IFR_EQ_ID_VAL), 0 }, // EFI_IFR_EQ_ID_VAL_OP 695 { sizeof (EFI_IFR_EQ_ID_ID), 0 }, // EFI_IFR_EQ_ID_ID_OP 696 { sizeof (EFI_IFR_EQ_ID_LIST), 0 }, // EFI_IFR_EQ_ID_LIST_OP - 0x14 697 { sizeof (EFI_IFR_AND), 0 }, // EFI_IFR_AND_OP 698 { sizeof (EFI_IFR_OR), 0 }, // EFI_IFR_OR_OP 699 { sizeof (EFI_IFR_NOT), 0 }, // EFI_IFR_NOT_OP 700 { sizeof (EFI_IFR_RULE), 1 }, // EFI_IFR_RULE_OP 701 { sizeof (EFI_IFR_GRAY_OUT_IF), 1 }, // EFI_IFR_GRAYOUT_IF_OP - 0x19 702 { sizeof (EFI_IFR_DATE), 1 }, // EFI_IFR_DATE_OP 703 { sizeof (EFI_IFR_TIME), 1 }, // EFI_IFR_TIME_OP 704 { sizeof (EFI_IFR_STRING), 1 }, // EFI_IFR_STRING_OP 705 { sizeof (EFI_IFR_REFRESH), 0 }, // EFI_IFR_REFRESH_OP 706 { sizeof (EFI_IFR_DISABLE_IF), 1 }, // EFI_IFR_DISABLE_IF_OP - 0x1E 707 { 0, 0 }, // 0x1F 708 { sizeof (EFI_IFR_TO_LOWER), 0 }, // EFI_IFR_TO_LOWER_OP - 0x20 709 { sizeof (EFI_IFR_TO_UPPER), 0 }, // EFI_IFR_TO_UPPER_OP - 0x21 710 { 0, 0 }, // 0x22 711 { sizeof (EFI_IFR_ORDERED_LIST), 1 }, // EFI_IFR_ORDERED_LIST_OP - 0x23 712 { sizeof (EFI_IFR_VARSTORE), 0 }, // EFI_IFR_VARSTORE_OP 713 { sizeof (EFI_IFR_VARSTORE_NAME_VALUE), 0 }, // EFI_IFR_VARSTORE_NAME_VALUE_OP 714 { sizeof (EFI_IFR_VARSTORE_EFI), 0 }, // EFI_IFR_VARSTORE_EFI_OP 715 { sizeof (EFI_IFR_VARSTORE_DEVICE), 1 }, // EFI_IFR_VARSTORE_DEVICE_OP 716 { sizeof (EFI_IFR_VERSION), 0 }, // EFI_IFR_VERSION_OP - 0x28 717 { sizeof (EFI_IFR_END), 0 }, // EFI_IFR_END_OP 718 { sizeof (EFI_IFR_MATCH), 1 }, // EFI_IFR_MATCH_OP - 0x2A 719 { 0, 0 }, { 0, 0} , { 0, 0} , { 0, 0} , // 0x2B ~ 0x2E 720 { sizeof (EFI_IFR_EQUAL), 0 }, // EFI_IFR_EQUAL_OP - 0x2F 721 { sizeof (EFI_IFR_NOT_EQUAL), 0 }, // EFI_IFR_NOT_EQUAL_OP 722 { sizeof (EFI_IFR_GREATER_THAN), 0 }, // EFI_IFR_GREATER_THAN_OP 723 { sizeof (EFI_IFR_GREATER_EQUAL), 0 }, // EFI_IFR_GREATER_EQUAL_OP 724 { sizeof (EFI_IFR_LESS_THAN), 0 }, // EFI_IFR_LESS_THAN_OP 725 { sizeof (EFI_IFR_LESS_EQUAL), 0 }, // EFI_IFR_LESS_EQUAL_OP - 0x34 726 { sizeof (EFI_IFR_BITWISE_AND), 0 }, // EFI_IFR_BITWISE_AND_OP 727 { sizeof (EFI_IFR_BITWISE_OR), 0 }, // EFI_IFR_BITWISE_OR_OP 728 { sizeof (EFI_IFR_BITWISE_NOT), 0 }, // EFI_IFR_BITWISE_NOT_OP 729 { sizeof (EFI_IFR_SHIFT_LEFT), 0 }, // EFI_IFR_SHIFT_LEFT_OP 730 { sizeof (EFI_IFR_SHIFT_RIGHT), 0 }, // EFI_IFR_SHIFT_RIGHT_OP 731 { sizeof (EFI_IFR_ADD), 0 }, // EFI_IFR_ADD_OP - 0x3A 732 { sizeof (EFI_IFR_SUBTRACT), 0 }, // EFI_IFR_SUBTRACT_OP 733 { sizeof (EFI_IFR_MULTIPLY), 0 }, // EFI_IFR_MULTIPLY_OP 734 { sizeof (EFI_IFR_DIVIDE), 0 }, // EFI_IFR_DIVIDE_OP 735 { sizeof (EFI_IFR_MODULO), 0 }, // EFI_IFR_MODULO_OP - 0x3E 736 { sizeof (EFI_IFR_RULE_REF), 0 }, // EFI_IFR_RULE_REF_OP 737 { sizeof (EFI_IFR_QUESTION_REF1), 0 }, // EFI_IFR_QUESTION_REF1_OP 738 { sizeof (EFI_IFR_QUESTION_REF2), 0 }, // EFI_IFR_QUESTION_REF2_OP - 0x41 739 { sizeof (EFI_IFR_UINT8), 0}, // EFI_IFR_UINT8 740 { sizeof (EFI_IFR_UINT16), 0}, // EFI_IFR_UINT16 741 { sizeof (EFI_IFR_UINT32), 0}, // EFI_IFR_UINT32 742 { sizeof (EFI_IFR_UINT64), 0}, // EFI_IFR_UTNT64 743 { sizeof (EFI_IFR_TRUE), 0 }, // EFI_IFR_TRUE_OP - 0x46 744 { sizeof (EFI_IFR_FALSE), 0 }, // EFI_IFR_FALSE_OP 745 { sizeof (EFI_IFR_TO_UINT), 0 }, // EFI_IFR_TO_UINT_OP 746 { sizeof (EFI_IFR_TO_STRING), 0 }, // EFI_IFR_TO_STRING_OP 747 { sizeof (EFI_IFR_TO_BOOLEAN), 0 }, // EFI_IFR_TO_BOOLEAN_OP 748 { sizeof (EFI_IFR_MID), 0 }, // EFI_IFR_MID_OP 749 { sizeof (EFI_IFR_FIND), 0 }, // EFI_IFR_FIND_OP 750 { sizeof (EFI_IFR_TOKEN), 0 }, // EFI_IFR_TOKEN_OP 751 { sizeof (EFI_IFR_STRING_REF1), 0 }, // EFI_IFR_STRING_REF1_OP - 0x4E 752 { sizeof (EFI_IFR_STRING_REF2), 0 }, // EFI_IFR_STRING_REF2_OP 753 { sizeof (EFI_IFR_CONDITIONAL), 0 }, // EFI_IFR_CONDITIONAL_OP 754 { sizeof (EFI_IFR_QUESTION_REF3), 0 }, // EFI_IFR_QUESTION_REF3_OP 755 { sizeof (EFI_IFR_ZERO), 0 }, // EFI_IFR_ZERO_OP 756 { sizeof (EFI_IFR_ONE), 0 }, // EFI_IFR_ONE_OP 757 { sizeof (EFI_IFR_ONES), 0 }, // EFI_IFR_ONES_OP 758 { sizeof (EFI_IFR_UNDEFINED), 0 }, // EFI_IFR_UNDEFINED_OP 759 { sizeof (EFI_IFR_LENGTH), 0 }, // EFI_IFR_LENGTH_OP 760 { sizeof (EFI_IFR_DUP), 0 }, // EFI_IFR_DUP_OP - 0x57 761 { sizeof (EFI_IFR_THIS), 0 }, // EFI_IFR_THIS_OP 762 { sizeof (EFI_IFR_SPAN), 0 }, // EFI_IFR_SPAN_OP 763 { sizeof (EFI_IFR_VALUE), 1 }, // EFI_IFR_VALUE_OP 764 { sizeof (EFI_IFR_DEFAULT), 0 }, // EFI_IFR_DEFAULT_OP 765 { sizeof (EFI_IFR_DEFAULTSTORE), 0 }, // EFI_IFR_DEFAULTSTORE_OP - 0x5C 766 { 0, 0}, // 0x5D 767 { sizeof (EFI_IFR_CATENATE), 0 }, // EFI_IFR_CATENATE_OP 768 { sizeof (EFI_IFR_GUID), 0 }, // EFI_IFR_GUID_OP 769 }; 770 771 #ifdef CIFROBJ_DEUBG 772 static struct { 773 INT8 *mIfrName; 774 } gIfrObjPrintDebugTable[] = { 775 "EFI_IFR_INVALID", "EFI_IFR_FORM", "EFI_IFR_SUBTITLE", "EFI_IFR_TEXT", "EFI_IFR_IMAGE", "EFI_IFR_ONE_OF", 776 "EFI_IFR_CHECKBOX", "EFI_IFR_NUMERIC", "EFI_IFR_PASSWORD", "EFI_IFR_ONE_OF_OPTION", "EFI_IFR_SUPPRESS_IF", "EFI_IFR_LOCKED", 777 "EFI_IFR_ACTION", "EFI_IFR_RESET_BUTTON", "EFI_IFR_FORM_SET", "EFI_IFR_REF", "EFI_IFR_NO_SUBMIT_IF", "EFI_IFR_INCONSISTENT_IF", 778 "EFI_IFR_EQ_ID_VAL", "EFI_IFR_EQ_ID_ID", "EFI_IFR_EQ_ID_LIST", "EFI_IFR_AND", "EFI_IFR_OR", "EFI_IFR_NOT", 779 "EFI_IFR_RULE", "EFI_IFR_GRAY_OUT_IF", "EFI_IFR_DATE", "EFI_IFR_TIME", "EFI_IFR_STRING", "EFI_IFR_REFRESH", 780 "EFI_IFR_DISABLE_IF", "EFI_IFR_INVALID", "EFI_IFR_TO_LOWER", "EFI_IFR_TO_UPPER", "EFI_IFR_INVALID", "EFI_IFR_ORDERED_LIST", 781 "EFI_IFR_VARSTORE", "EFI_IFR_VARSTORE_NAME_VALUE", "EFI_IFR_VARSTORE_EFI", "EFI_IFR_VARSTORE_DEVICE", "EFI_IFR_VERSION", "EFI_IFR_END", 782 "EFI_IFR_MATCH", "EFI_IFR_INVALID", "EFI_IFR_INVALID", "EFI_IFR_INVALID", "EFI_IFR_INVALID", "EFI_IFR_EQUAL", 783 "EFI_IFR_NOT_EQUAL", "EFI_IFR_GREATER_THAN", "EFI_IFR_GREATER_EQUAL", "EFI_IFR_LESS_THAN", "EFI_IFR_LESS_EQUAL", "EFI_IFR_BITWISE_AND", 784 "EFI_IFR_BITWISE_OR", "EFI_IFR_BITWISE_NOT", "EFI_IFR_SHIFT_LEFT", "EFI_IFR_SHIFT_RIGHT", "EFI_IFR_ADD", "EFI_IFR_SUBTRACT", 785 "EFI_IFR_MULTIPLY", "EFI_IFR_DIVIDE", "EFI_IFR_MODULO", "EFI_IFR_RULE_REF", "EFI_IFR_QUESTION_REF1", "EFI_IFR_QUESTION_REF2", 786 "EFI_IFR_UINT8", "EFI_IFR_UINT16", "EFI_IFR_UINT32", "EFI_IFR_UINT64", "EFI_IFR_TRUE", "EFI_IFR_FALSE", 787 "EFI_IFR_TO_UINT", "EFI_IFR_TO_STRING", "EFI_IFR_TO_BOOLEAN", "EFI_IFR_MID", "EFI_IFR_FIND", "EFI_IFR_TOKEN", 788 "EFI_IFR_STRING_REF1","EFI_IFR_STRING_REF2", "EFI_IFR_CONDITIONAL", "EFI_IFR_QUESTION_REF3", "EFI_IFR_ZERO", "EFI_IFR_ONE", 789 "EFI_IFR_ONES", "EFI_IFR_UNDEFINED", "EFI_IFR_LENGTH", "EFI_IFR_DUP", "EFI_IFR_THIS", "EFI_IFR_SPAN", 790 "EFI_IFR_VALUE", "EFI_IFR_DEFAULT", "EFI_IFR_DEFAULTSTORE", "EFI_IFR_INVALID", "EFI_IFR_CATENATE", "EFI_IFR_GUID", 791 }; 792 793 VOID 794 CIFROBJ_DEBUG_PRINT ( 795 IN UINT8 OpCode 796 ) 797 { 798 printf ("======Create IFR [%s]\n", gIfrObjPrintDebugTable[OpCode].mIfrName); 799 } 800 #else 801 802 #define CIFROBJ_DEBUG_PRINT(OpCode) 803 804 #endif 805 806 bool gCreateOp = TRUE; 807 808 CIfrObj::CIfrObj ( 809 IN UINT8 OpCode, 810 OUT CHAR8 **IfrObj, 811 IN UINT8 ObjBinLen, 812 IN BOOLEAN DelayEmit 813 ) 814 { 815 mDelayEmit = DelayEmit; 816 mPkgOffset = gCFormPkg.GetPkgLength (); 817 mObjBinLen = (ObjBinLen == 0) ? gOpcodeSizesScopeTable[OpCode].mSize : ObjBinLen; 818 mObjBinBuf = ((DelayEmit == FALSE) && (gCreateOp == TRUE)) ? gCFormPkg.IfrBinBufferGet (mObjBinLen) : new CHAR8[EFI_IFR_MAX_LENGTH]; 819 mRecordIdx = (gCreateOp == TRUE) ? gCIfrRecordInfoDB.IfrRecordRegister (0xFFFFFFFF, mObjBinBuf, mObjBinLen, mPkgOffset) : EFI_IFR_RECORDINFO_IDX_INVALUD; 820 821 if (IfrObj != NULL) { 822 *IfrObj = mObjBinBuf; 823 } 824 825 CIFROBJ_DEBUG_PRINT (OpCode); 826 } 827 828 CIfrObj::~CIfrObj ( 829 VOID 830 ) 831 { 832 if ((mDelayEmit == TRUE) && ((gCreateOp == TRUE))) { 833 _EMIT_PENDING_OBJ (); 834 } 835 836 gCIfrRecordInfoDB.IfrRecordInfoUpdate (mRecordIdx, mLineNo, mObjBinBuf, mObjBinLen, mPkgOffset); 837 } 838 839 /* 840 * The definition of CIfrObj's member function 841 */ 842 UINT8 gScopeCount = 0; 843 844 CIfrOpHeader::CIfrOpHeader ( 845 IN UINT8 OpCode, 846 IN VOID *StartAddr, 847 IN UINT8 Length 848 ) : mHeader ((EFI_IFR_OP_HEADER *)StartAddr) 849 { 850 mHeader->OpCode = OpCode; 851 mHeader->Length = (Length == 0) ? gOpcodeSizesScopeTable[OpCode].mSize : Length; 852 mHeader->Scope = (gOpcodeSizesScopeTable[OpCode].mScope + gScopeCount > 0) ? 1 : 0; 853 } 854 855 CIfrOpHeader::CIfrOpHeader ( 856 IN CIfrOpHeader &OpHdr 857 ) 858 { 859 mHeader = OpHdr.mHeader; 860 } 861 862 UINT32 CIfrForm::FormIdBitMap[EFI_FREE_FORM_ID_BITMAP_SIZE] = {0, }; 863