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