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