Add in GetNextToken and Register Callback Function funtionality for DXE Driver.
[mirror_edk2.git] / Tools / Source / GenBuild / org / tianocore / build / pcd / action / CollectPCDAction.java
1 /** @file
2 CollectPCDAction class.
3
4 This action class is to collect PCD information from MSA, SPD, FPD xml file.
5 This class will be used for wizard and build tools, So it can *not* inherit
6 from buildAction or wizardAction.
7
8 Copyright (c) 2006, Intel Corporation
9 All rights reserved. This program and the accompanying materials
10 are licensed and made available under the terms and conditions of the BSD License
11 which accompanies this distribution. The full text of the license may be found at
12 http://opensource.org/licenses/bsd-license.php
13
14 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
15 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
16
17 **/
18 package org.tianocore.build.pcd.action;
19
20 import java.io.BufferedReader;
21 import java.io.File;
22 import java.io.FileReader;
23 import java.io.IOException;
24 import java.util.ArrayList;
25 import java.util.Collections;
26 import java.util.Comparator;
27 import java.util.HashMap;
28 import java.util.List;
29 import java.util.Map;
30 import java.util.UUID;
31
32 import org.apache.xmlbeans.XmlException;
33 import org.apache.xmlbeans.XmlObject;
34 import org.tianocore.FrameworkPlatformDescriptionDocument;
35 import org.tianocore.ModuleSADocument;
36 import org.tianocore.PackageSurfaceAreaDocument;
37 import org.tianocore.PcdBuildDeclarationsDocument.PcdBuildDeclarations.PcdBuildData;
38 import org.tianocore.PcdDefinitionsDocument.PcdDefinitions;
39 import org.tianocore.build.autogen.CommonDefinition;
40 import org.tianocore.build.global.GlobalData;
41 import org.tianocore.build.global.SurfaceAreaQuery;
42 import org.tianocore.build.pcd.action.ActionMessage;
43 import org.tianocore.build.pcd.entity.MemoryDatabaseManager;
44 import org.tianocore.build.pcd.entity.SkuInstance;
45 import org.tianocore.build.pcd.entity.Token;
46 import org.tianocore.build.pcd.entity.UsageInstance;
47 import org.tianocore.build.pcd.exception.EntityException;
48
49 class StringTable {
50 private ArrayList<String> al;
51 private ArrayList<String> alComments;
52 private String phase;
53 int len;
54 int bodyStart;
55 int bodyLineNum;
56
57 public StringTable (String phase) {
58 this.phase = phase;
59 al = new ArrayList<String>();
60 alComments = new ArrayList<String>();
61 len = 0;
62 bodyStart = 0;
63 bodyLineNum = 0;
64 }
65
66 public String getSizeMacro () {
67 return String.format(PcdDatabase.StringTableSizeMacro, phase, getSize());
68 }
69
70 private int getSize () {
71 //
72 // We have at least one Unicode Character in the table.
73 //
74 return len == 0 ? 1 : len;
75 }
76
77 public int getTableLen () {
78 return al.size() == 0 ? 1 : al.size();
79 }
80
81 public String getExistanceMacro () {
82 return String.format(PcdDatabase.StringTableExistenceMacro, phase, (al.size() == 0)? "TRUE":"FALSE");
83 }
84
85 public String getTypeDeclaration () {
86
87 String output;
88
89 final String stringTable = "StringTable";
90 final String tab = "\t";
91 final String newLine = ";\r\n";
92
93 output = "/* StringTable */\r\n";
94
95 if (al.size() == 0) {
96 output += tab + String.format("UINT16 %s[1] /* StringTable is Empty */", stringTable) + newLine;
97 }
98
99 for (int i = 0; i < al.size(); i++) {
100 String str = al.get(i);
101
102 if (i == 0) {
103 //
104 // StringTable is a well-known name in the PCD DXE driver
105 //
106 output += tab + String.format("UINT16 %s[%d] /* %s */", stringTable, str.length() + 1, alComments.get(i)) + newLine;
107 } else {
108 output += tab + String.format("UINT16 %s_%d[%d] /* %s */", stringTable, i, str.length() + 1, alComments.get(i)) + newLine;
109 }
110 }
111
112 return output;
113
114 }
115
116 public ArrayList<String> getInstantiation () {
117 ArrayList<String> output = new ArrayList<String>();
118
119 output.add("/* StringTable */");
120
121 if (al.size() == 0) {
122 output.add("{ 0 }");
123 } else {
124 String str;
125
126 for (int i = 0; i < al.size(); i++) {
127 str = String.format("L\"%s\" /* %s */", al.get(i), alComments.get(i));
128 if (i != al.size() - 1) {
129 str += ",";
130 }
131 output.add(str);
132 }
133 }
134
135 return output;
136 }
137
138 public int add (String str, Token token) {
139 int i;
140
141 i = len;
142 //
143 // Include the NULL character at the end of String
144 //
145 len += str.length() + 1;
146 al.add(str);
147 alComments.add(token.getPrimaryKeyString());
148
149 return i;
150 }
151 }
152
153 class SizeTable {
154 private ArrayList<Integer> al;
155 private ArrayList<String> alComments;
156 private String phase;
157 private int len;
158 private int bodyStart;
159 private int bodyLineNum;
160
161 public SizeTable (String phase) {
162 this.phase = phase;
163 al = new ArrayList<Integer>();
164 alComments = new ArrayList<String>();
165 len = 0;
166 bodyStart = 0;
167 bodyLineNum = 0;
168 }
169
170 public String getTypeDeclaration () {
171 return String.format(PcdDatabase.SizeTableDeclaration, phase);
172 }
173
174 public ArrayList<String> getInstantiation () {
175 ArrayList<String> Output = new ArrayList<String>();
176
177 Output.add("/* SizeTable */");
178 Output.add("{");
179 bodyStart = 2;
180
181 if (al.size() == 0) {
182 Output.add("0");
183 } else {
184 for (int index = 0; index < al.size(); index++) {
185 Integer n = al.get(index);
186 String str = n.toString();
187
188 if (index != (al.size() - 1)) {
189 str += ",";
190 }
191
192 str += " /* " + alComments.get(index) + " */";
193 Output.add(str);
194 bodyLineNum++;
195
196 }
197 }
198 Output.add("}");
199
200 return Output;
201 }
202
203 public int getBodyStart() {
204 return bodyStart;
205 }
206
207 public int getBodyLineNum () {
208 return bodyLineNum;
209 }
210
211 public int add (Token token) {
212 int index = len;
213
214 len++;
215 al.add(token.datumSize);
216 alComments.add(token.getPrimaryKeyString());
217
218 return index;
219 }
220
221 private int getDatumSize(Token token) {
222 /*
223 switch (token.datumType) {
224 case Token.DATUM_TYPE.UINT8:
225 return 1;
226 default:
227 return 0;
228 }
229 */
230 return 0;
231 }
232
233 public int getTableLen () {
234 return al.size() == 0 ? 1 : al.size();
235 }
236
237 }
238
239 class GuidTable {
240 private ArrayList<UUID> al;
241 private ArrayList<String> alComments;
242 private String phase;
243 private int len;
244 private int bodyStart;
245 private int bodyLineNum;
246
247 public GuidTable (String phase) {
248 this.phase = phase;
249 al = new ArrayList<UUID>();
250 alComments = new ArrayList<String>();
251 len = 0;
252 bodyStart = 0;
253 bodyLineNum = 0;
254 }
255
256 public String getSizeMacro () {
257 return String.format(PcdDatabase.GuidTableSizeMacro, phase, getSize());
258 }
259
260 private int getSize () {
261 return (al.size() == 0)? 1 : al.size();
262 }
263
264 public String getExistanceMacro () {
265 return String.format(PcdDatabase.GuidTableExistenceMacro, phase, (al.size() == 0)? "TRUE":"FALSE");
266 }
267
268 public String getTypeDeclaration () {
269 return String.format(PcdDatabase.GuidTableDeclaration, phase);
270 }
271
272 private String getUuidCString (UUID uuid) {
273 String[] guidStrArray;
274
275 guidStrArray =(uuid.toString()).split("-");
276
277 return String.format("{ 0x%s, 0x%s, 0x%s, { 0x%s, 0x%s, 0x%s, 0x%s, 0x%s, 0x%s, 0x%s, 0x%s } }",
278 guidStrArray[0],
279 guidStrArray[1],
280 guidStrArray[2],
281 (guidStrArray[3].substring(0, 2)),
282 (guidStrArray[3].substring(2, 4)),
283 (guidStrArray[4].substring(0, 2)),
284 (guidStrArray[4].substring(2, 4)),
285 (guidStrArray[4].substring(4, 6)),
286 (guidStrArray[4].substring(6, 8)),
287 (guidStrArray[4].substring(8, 10)),
288 (guidStrArray[4].substring(10, 12))
289 );
290 }
291
292 public ArrayList<String> getInstantiation () {
293 ArrayList<String> Output = new ArrayList<String>();
294
295 Output.add("/* GuidTable */");
296 Output.add("{");
297 bodyStart = 2;
298
299 if (al.size() == 0) {
300 Output.add(getUuidCString(new UUID(0, 0)));
301 }
302
303 for (Object u : al) {
304 UUID uuid = (UUID)u;
305 String str = getUuidCString(uuid);
306
307 if (al.indexOf(u) != (al.size() - 1)) {
308 str += ",";
309 }
310 Output.add(str);
311 bodyLineNum++;
312
313 }
314 Output.add("}");
315
316 return Output;
317 }
318
319 public int getBodyStart() {
320 return bodyStart;
321 }
322
323 public int getBodyLineNum () {
324 return bodyLineNum;
325 }
326
327 public int add (UUID uuid, String name) {
328 int index = len;
329 //
330 // Include the NULL character at the end of String
331 //
332 len++;
333 al.add(uuid);
334
335 return index;
336 }
337
338 public int getTableLen () {
339 return al.size() == 0 ? 0 : al.size();
340 }
341
342 }
343
344 class SkuIdTable {
345 private ArrayList<Integer[]> al;
346 private ArrayList<String> alComment;
347 private String phase;
348 private int len;
349 private int bodyStart;
350 private int bodyLineNum;
351
352 public SkuIdTable (String phase) {
353 this.phase = phase;
354 al = new ArrayList<Integer[]>();
355 alComment = new ArrayList<String>();
356 bodyStart = 0;
357 bodyLineNum = 0;
358 len = 0;
359 }
360
361 public String getSizeMacro () {
362 return String.format(PcdDatabase.SkuIdTableSizeMacro, phase, getSize());
363 }
364
365 private int getSize () {
366 return (al.size() == 0)? 1 : al.size();
367 }
368
369 public String getExistanceMacro () {
370 return String.format(PcdDatabase.SkuTableExistenceMacro, phase, (al.size() == 0)? "TRUE":"FALSE");
371 }
372
373 public String getTypeDeclaration () {
374 return String.format(PcdDatabase.SkuIdTableDeclaration, phase);
375 }
376
377 public ArrayList<String> getInstantiation () {
378 ArrayList<String> Output = new ArrayList<String> ();
379
380 Output.add("/* SkuIdTable */");
381 Output.add("{");
382 bodyStart = 2;
383
384 if (al.size() == 0) {
385 Output.add("0");
386 }
387
388 for (int index = 0; index < al.size(); index++) {
389 String str;
390
391 str = "/* " + alComment.get(index) + "*/ ";
392 str += "/* MaxSku */ ";
393
394
395 Integer[] ia = al.get(index);
396
397 str += ia[0].toString() + ", ";
398 for (int index2 = 1; index2 < ia.length; index2++) {
399 str += ia[index2].toString();
400 if (index != al.size() - 1) {
401 str += ", ";
402 }
403 }
404
405 Output.add(str);
406 bodyLineNum++;
407
408 }
409
410 Output.add("}");
411
412 return Output;
413 }
414
415 public int add (Token token) {
416
417 int index;
418
419 Integer [] skuIds = new Integer[token.maxSkuCount + 1];
420 skuIds[0] = new Integer(token.maxSkuCount);
421 for (index = 1; index < skuIds.length; index++) {
422 skuIds[index] = new Integer(token.skuData.get(index - 1).id);
423 }
424
425 index = len;
426
427 len += skuIds.length;
428 al.add(skuIds);
429 alComment.add(token.getPrimaryKeyString());
430
431 return index;
432 }
433
434 public int getTableLen () {
435 return al.size() == 0 ? 1 : al.size();
436 }
437
438 }
439
440 class LocalTokenNumberTable {
441 private ArrayList<String> al;
442 private ArrayList<String> alComment;
443 private String phase;
444 private int len;
445 private int bodyStart;
446 private int bodyLineNum;
447
448 public LocalTokenNumberTable (String phase) {
449 this.phase = phase;
450 al = new ArrayList<String>();
451 alComment = new ArrayList<String>();
452 bodyStart = 0;
453 bodyLineNum = 0;
454
455 len = 0;
456 }
457
458 public String getSizeMacro () {
459 return String.format(PcdDatabase.LocalTokenNumberTableSizeMacro, phase, getSize());
460 }
461
462 public int getSize () {
463 return (al.size() == 0)? 1 : al.size();
464 }
465
466 public String getExistanceMacro () {
467 return String.format(PcdDatabase.DatabaseExistenceMacro, phase, (al.size() == 0)? "TRUE":"FALSE");
468 }
469
470 public String getTypeDeclaration () {
471 return String.format(PcdDatabase.LocalTokenNumberTableDeclaration, phase);
472 }
473
474 public ArrayList<String> getInstantiation () {
475 ArrayList<String> output = new ArrayList<String>();
476
477 output.add("/* LocalTokenNumberTable */");
478 output.add("{");
479 bodyStart = 2;
480
481 if (al.size() == 0) {
482 output.add("0");
483 }
484
485 for (int index = 0; index < al.size(); index++) {
486 String str;
487
488 str = (String)al.get(index);
489
490 str += " /* " + alComment.get(index) + " */ ";
491
492
493 if (index != (al.size() - 1)) {
494 str += ",";
495 }
496
497 output.add(str);
498
499 }
500
501 bodyLineNum = al.size();
502
503 output.add("}");
504
505 return output;
506 }
507
508 public int add (Token token) {
509 int index = len;
510 String str;
511
512 len++;
513
514 str = String.format(PcdDatabase.offsetOfStrTemplate, phase, token.hasDefaultValue() ? "Init" : "Uninit", token.getPrimaryKeyString());
515
516 if (token.isStringType()) {
517 str += " | PCD_TYPE_STRING";
518 }
519
520 if (token.skuEnabled) {
521 str += " | PCD_TYPE_SKU_ENABLED";
522 }
523
524 if (token.hiiEnabled) {
525 str += " | PCD_TYPE_HII";
526 }
527
528 if (token.vpdEnabled) {
529 str += " | PCD_TYPE_VPD";
530 }
531
532 al.add(str);
533 alComment.add(token.getPrimaryKeyString());
534
535 return index;
536 }
537 }
538
539 class ExMapTable {
540
541 class ExTriplet {
542 public Integer guidTableIdx;
543 public Long exTokenNumber;
544 public Long localTokenIdx;
545
546 public ExTriplet (int guidTableIdx, long exTokenNumber, long localTokenIdx) {
547 this.guidTableIdx = new Integer(guidTableIdx);
548 this.exTokenNumber = new Long(exTokenNumber);
549 this.localTokenIdx = new Long(localTokenIdx);
550 }
551 }
552
553 private ArrayList<ExTriplet> al;
554 private ArrayList<String> alComment;
555 private String phase;
556 private int len;
557 private int bodyStart;
558 private int bodyLineNum;
559 private int base;
560
561 public ExMapTable (String phase) {
562 this.phase = phase;
563 al = new ArrayList<ExTriplet>();
564 alComment = new ArrayList<String>();
565 bodyStart = 0;
566 bodyLineNum = 0;
567 len = 0;
568 }
569
570 public String getSizeMacro () {
571 return String.format(PcdDatabase.ExMapTableSizeMacro, phase, getTableLen())
572 + String.format(PcdDatabase.ExTokenNumber, phase, al.size());
573 }
574
575 private int getSize () {
576 return (al.size() == 0)? 1 : al.size();
577 }
578
579 public String getExistanceMacro () {
580 return String.format(PcdDatabase.ExMapTableExistenceMacro, phase, (al.size() == 0)? "TRUE":"FALSE");
581 }
582
583 public String getTypeDeclaration () {
584 return String.format(PcdDatabase.ExMapTableDeclaration, phase);
585 }
586
587 public ArrayList<String> getInstantiation () {
588 ArrayList<String> Output = new ArrayList<String>();
589
590 Output.add("/* ExMapTable */");
591 Output.add("{");
592 bodyStart = 2;
593
594 if (al.size() == 0) {
595 Output.add("{0, 0, 0}");
596 }
597
598 int index;
599 for (index = 0; index < al.size(); index++) {
600 String str;
601
602 ExTriplet e = (ExTriplet)al.get(index);
603
604 str = "{ " + e.exTokenNumber.toString() + ", ";
605 str += e.localTokenIdx.toString() + ", ";
606 str += e.guidTableIdx.toString();
607
608 str += " /* " + alComment.get(index) + " */";
609
610 if (index != al.size() - 1) {
611 str += ",";
612 }
613
614 Output.add(str);
615 bodyLineNum++;
616
617 }
618
619 Output.add("}");
620
621 return Output;
622 }
623
624 public int add (int localTokenIdx, long exTokenNum, int guidTableIdx, String name) {
625 int index = len;
626
627 len++;
628 al.add(new ExTriplet(guidTableIdx, exTokenNum, localTokenIdx));
629 alComment.add(name);
630
631 return index;
632 }
633
634 public int getTableLen () {
635 return al.size() == 0 ? 1 : al.size();
636 }
637
638 }
639
640 class PcdDatabase {
641
642 public final static String ExMapTableDeclaration = "DYNAMICEX_MAPPING ExMapTable[%s_EXMAPPING_TABLE_SIZE];\r\n";
643 public final static String GuidTableDeclaration = "EFI_GUID GuidTable[%s_GUID_TABLE_SIZE];\r\n";
644 public final static String LocalTokenNumberTableDeclaration = "UINT32 LocalTokenNumberTable[%s_LOCAL_TOKEN_NUMBER];\r\n";
645 public final static String StringTableDeclaration = "UINT16 StringTable[%s_STRING_TABLE_SIZE];\r\n";
646 public final static String SizeTableDeclaration = "UINT16 SizeTable[%s_LOCAL_TOKEN_NUMBER];\r\n";
647 public final static String SkuIdTableDeclaration = "UINT8 SkuIdTable[%s_SKUID_TABLE_SIZE];\r\n";
648
649
650 public final static String ExMapTableSizeMacro = "#define %s_EXMAPPING_TABLE_SIZE %d\r\n";
651 public final static String ExTokenNumber = "#define %s_EX_TOKEN_NUMBER %d\r\n";
652 public final static String GuidTableSizeMacro = "#define %s_GUID_TABLE_SIZE %d\r\n";
653 public final static String LocalTokenNumberTableSizeMacro = "#define %s_LOCAL_TOKEN_NUMBER %d\r\n";
654 public final static String StringTableSizeMacro = "#define %s_STRING_TABLE_SIZE %d\r\n";
655 public final static String SkuIdTableSizeMacro = "#define %s_SKUID_TABLE_SIZE %d\r\n";
656
657
658 public final static String ExMapTableExistenceMacro = "#define %s_EXMAP_TABLE_EMPTY %s\r\n";
659 public final static String GuidTableExistenceMacro = "#define %s_GUID_TABLE_EMPTY %s\r\n";
660 public final static String DatabaseExistenceMacro = "#define %s_DATABASE_EMPTY %s\r\n";
661 public final static String StringTableExistenceMacro = "#define %s_STRING_TABLE_EMPTY %s\r\n";
662 public final static String SkuTableExistenceMacro = "#define %s_SKUID_TABLE_EMPTY %s\r\n";
663
664 public final static String offsetOfSkuHeadStrTemplate = "offsetof(%s_PCD_DATABASE, %s.%s_SkuDataTable)";
665 public final static String offsetOfStrTemplate = "offsetof(%s_PCD_DATABASE, %s.%s)";
666
667 private StringTable stringTable;
668 private GuidTable guidTable;
669 private LocalTokenNumberTable localTokenNumberTable;
670 private SkuIdTable skuIdTable;
671 private SizeTable sizeTable;
672 private ExMapTable exMapTable;
673
674 private ArrayList<Token> alTokens;
675 private String phase;
676 private int assignedTokenNumber;
677
678 //
679 // After Major changes done to the PCD
680 // database generation class PcdDatabase
681 // Please increment the version and please
682 // also update the version number in PCD
683 // service PEIM and DXE driver accordingly.
684 //
685 private final int version = 1;
686
687 private String hString;
688 private String cString;
689
690
691 class AlignmentSizeComp implements Comparator<Token> {
692 public int compare (Token a, Token b) {
693 return getAlignmentSize(b)
694 - getAlignmentSize(a);
695 }
696 }
697
698 public PcdDatabase (ArrayList<Token> alTokens, String exePhase, int startLen) {
699 phase = exePhase;
700
701 stringTable = new StringTable(phase);
702 guidTable = new GuidTable(phase);
703 localTokenNumberTable = new LocalTokenNumberTable(phase);
704 skuIdTable = new SkuIdTable(phase);
705 sizeTable = new SizeTable(phase);
706 exMapTable = new ExMapTable(phase);
707
708 assignedTokenNumber = startLen;
709 this.alTokens = alTokens;
710 }
711
712 private void getTwoGroupsOfTokens (ArrayList<Token> alTokens, List<Token> initTokens, List<Token> uninitTokens) {
713 for (int i = 0; i < alTokens.size(); i++) {
714 Token t = alTokens.get(i);
715 if (t.hasDefaultValue()) {
716 initTokens.add(t);
717 } else {
718 uninitTokens.add(t);
719 }
720 }
721
722 return;
723 }
724
725 private int getAlignmentSize (Token token) {
726 if (token.hiiEnabled) {
727 return 2;
728 }
729
730 if (token.vpdEnabled) {
731 return 4;
732 }
733
734 if (token.isStringType()) {
735 return 2;
736 }
737
738 switch (token.datumType) {
739 case UINT8:
740 return 1;
741 case UINT16:
742 return 2;
743 case UINT32:
744 return 4;
745 case UINT64:
746 return 8;
747 case POINTER:
748 return 1;
749 case BOOLEAN:
750 return 1;
751 }
752 return 1;
753 }
754
755 public String getCString () {
756 return cString;
757 }
758
759 public String getHString () {
760 return hString;
761 }
762
763 public void genCode () {
764
765 final String newLine = "\r\n";
766 final String declNewLine = ";\r\n";
767 final String tab = "\t";
768 final String commaNewLine = ", \r\n";
769
770 int i;
771 ArrayList<String> decla;
772 ArrayList<String> inst;
773
774 String macroStr = "";
775 String initDeclStr = "";
776 String initInstStr = "";
777 String uninitDeclStr = "";
778
779 List<Token> initTokens = new ArrayList<Token> ();
780 List<Token> uninitTokens = new ArrayList<Token> ();
781
782 HashMap <String, ArrayList<String>> initCode = new HashMap<String, ArrayList<String>> ();
783 HashMap <String, ArrayList<String>> uninitCode = new HashMap<String, ArrayList<String>> ();
784
785 getTwoGroupsOfTokens (alTokens, initTokens, uninitTokens);
786
787 //
788 // Generate Structure Declaration for PcdTokens without Default Value
789 // PEI_PCD_DATABASE_INIT
790 //
791 java.util.Comparator<Token> comparator = new AlignmentSizeComp();
792 java.util.Collections.sort(initTokens, comparator);
793 initCode = processTokens(initTokens);
794
795 //
796 // Generate Structure Declaration for PcdTokens without Default Value
797 // PEI_PCD_DATABASE_UNINIT
798 //
799 java.util.Collections.sort(uninitTokens, comparator);
800 uninitCode = processTokens(uninitTokens);
801
802 //
803 // Generate size info Macro for all Tables
804 //
805 macroStr += guidTable.getSizeMacro();
806 macroStr += stringTable.getSizeMacro();
807 macroStr += skuIdTable.getSizeMacro();
808 macroStr += localTokenNumberTable.getSizeMacro();
809 macroStr += exMapTable.getSizeMacro();
810
811 //
812 // Generate existance info Macro for all Tables
813 //
814 macroStr += guidTable.getExistanceMacro();
815 macroStr += stringTable.getExistanceMacro();
816 macroStr += skuIdTable.getExistanceMacro();
817 macroStr += localTokenNumberTable.getExistanceMacro();
818 macroStr += exMapTable.getExistanceMacro();
819
820 //
821 // Generate Structure Declaration for PcdTokens with Default Value
822 // for example PEI_PCD_DATABASE_INIT
823 //
824 initDeclStr += "typedef struct {" + newLine;
825 {
826 initDeclStr += tab + exMapTable.getTypeDeclaration();
827 initDeclStr += tab + guidTable.getTypeDeclaration();
828 initDeclStr += tab + localTokenNumberTable.getTypeDeclaration();
829 initDeclStr += tab + stringTable.getTypeDeclaration();
830 initDeclStr += tab + sizeTable.getTypeDeclaration();
831 initDeclStr += tab + skuIdTable.getTypeDeclaration();
832 if (phase.equalsIgnoreCase("PEI")) {
833 initDeclStr += tab + "SKU_ID SystemSkuId;" + newLine;
834 }
835
836 decla = initCode.get(new String("Declaration"));
837 for (i = 0; i < decla.size(); i++) {
838 initDeclStr += tab + decla.get(i) + declNewLine;
839 }
840
841 //
842 // Generate Structure Declaration for PcdToken with SkuEnabled
843 //
844 decla = initCode.get("DeclarationForSku");
845
846 for (i = 0; i < decla.size(); i++) {
847 initDeclStr += tab + decla.get(i) + declNewLine;
848 }
849 }
850 initDeclStr += String.format("} %s_PCD_DATABASE_INIT;\r\n\r\n", phase);
851
852 //
853 // Generate MACRO for structure intialization of PCDTokens with Default Value
854 // The sequence must match the sequence of declaration of the memembers in the structure
855 String tmp = String.format("%s_PCD_DATABASE_INIT g%sPcdDbInit = { ", phase.toUpperCase(), phase.toUpperCase());
856 initInstStr += tmp + newLine;
857 initInstStr += tab + genInstantiationStr(exMapTable.getInstantiation()) + commaNewLine;
858 initInstStr += tab + genInstantiationStr(guidTable.getInstantiation()) + commaNewLine;
859 initInstStr += tab + genInstantiationStr(localTokenNumberTable.getInstantiation()) + commaNewLine;
860 initInstStr += tab + genInstantiationStr(stringTable.getInstantiation()) + commaNewLine;
861 initInstStr += tab + genInstantiationStr(sizeTable.getInstantiation()) + commaNewLine;
862 initInstStr += tab + genInstantiationStr(skuIdTable.getInstantiation()) + commaNewLine;
863 //
864 // For SystemSkuId
865 //
866 if (phase.equalsIgnoreCase("PEI")) {
867 initInstStr += tab + "0" + tab + "/* SystemSkuId */" + commaNewLine;
868 }
869
870 inst = initCode.get("Instantiation");
871 for (i = 0; i < inst.size(); i++) {
872 initInstStr += tab + inst.get(i) + commaNewLine;
873 }
874
875 inst = initCode.get("InstantiationForSku");
876 for (i = 0; i < inst.size(); i++) {
877 initInstStr += tab + inst.get(i);
878 if (i != inst.size() - 1) {
879 initInstStr += commaNewLine;
880 }
881 }
882
883 initInstStr += "};";
884
885 uninitDeclStr += "typedef struct {" + newLine;
886 {
887 decla = uninitCode.get("Declaration");
888 if (decla.size() == 0) {
889 uninitDeclStr += "UINT8 dummy /* The UINT struct is empty */" + declNewLine;
890 } else {
891
892 for (i = 0; i < decla.size(); i++) {
893 uninitDeclStr += tab + decla.get(i) + declNewLine;
894 }
895
896 decla = uninitCode.get("DeclarationForSku");
897
898 for (i = 0; i < decla.size(); i++) {
899 uninitDeclStr += tab + decla.get(i) + declNewLine;
900 }
901 }
902 }
903 uninitDeclStr += String.format("} %s_PCD_DATABASE_UNINIT;\r\n\r\n", phase);
904
905 cString = initInstStr + newLine;
906 hString = macroStr + newLine
907 + initDeclStr + newLine
908 + uninitDeclStr + newLine
909 + newLine;
910
911 hString += String.format("#define PCD_%s_SERVICE_DRIVER_VERSION %d", phase, version);
912
913 }
914
915 private String genInstantiationStr (ArrayList<String> alStr) {
916 String str = "";
917 for (int i = 0; i< alStr.size(); i++) {
918 str += "\t" + alStr.get(i);
919 if (i != alStr.size() - 1) {
920 str += "\r\n";
921 }
922 }
923
924 return str;
925 }
926
927 private HashMap<String, ArrayList<String>> processTokens (List<Token> alToken) {
928
929 HashMap <String, ArrayList<String>> map = new HashMap<String, ArrayList<String>>();
930
931 ArrayList<String> decl = new ArrayList<String>();
932 ArrayList<String> declForSkuEnableType = new ArrayList<String>();
933 ArrayList<String> inst = new ArrayList<String>();
934 ArrayList<String> instForSkuEnableType = new ArrayList<String>();
935
936 for (int index = 0; index < alToken.size(); index++) {
937 Token token = alToken.get(index);
938
939 if (token.skuEnabled) {
940 //
941 // BugBug: Schema only support Data type now
942 //
943 int tableIdx;
944
945 tableIdx = skuIdTable.add(token);
946
947 decl.add(getSkuEnabledTypeDeclaration(token));
948 if (token.hasDefaultValue()) {
949 inst.add(getSkuEnabledTypeInstantiaion(token, tableIdx));
950 }
951
952 declForSkuEnableType.add(getDataTypeDeclarationForSkuEnabled(token));
953 if (token.hasDefaultValue()) {
954 instForSkuEnableType.add(getDataTypeInstantiationForSkuEnabled(token));
955 }
956
957 } else {
958 if (token.hiiEnabled) {
959 decl.add(getVariableEnableTypeDeclaration(token));
960 inst.add(getVariableEnableInstantiation(token));
961 } else if (token.vpdEnabled) {
962 decl.add(getVpdEnableTypeDeclaration(token));
963 inst.add(getVpdEnableTypeInstantiation(token));
964 } else if (token.isStringType()) {
965 decl.add(getStringTypeDeclaration(token));
966 inst.add(getStringTypeInstantiation(stringTable.add(token.getStringTypeString(), token), token));
967 }
968 else {
969 decl.add(getDataTypeDeclaration(token));
970 if (token.hasDefaultValue()) {
971 inst.add(getDataTypeInstantiation(token));
972 }
973 }
974 }
975
976 sizeTable.add(token);
977 localTokenNumberTable.add(token);
978 token.assignedtokenNumber = assignedTokenNumber++;
979
980 }
981
982 map.put("Declaration", decl);
983 map.put("DeclarationForSku", declForSkuEnableType);
984 map.put("Instantiation", inst);
985 map.put("InstantiationForSku", instForSkuEnableType);
986
987 return map;
988 }
989
990 private String getSkuEnabledTypeDeclaration (Token token) {
991 return String.format("SKU_HEAD %s;\r\n", token.getPrimaryKeyString());
992 }
993
994 private String getSkuEnabledTypeInstantiaion (Token token, int SkuTableIdx) {
995
996 String offsetof = String.format(PcdDatabase.offsetOfSkuHeadStrTemplate, phase, token.hasDefaultValue()? "Init" : "Uninit", token.getPrimaryKeyString());
997 return String.format("{ %s, %d }", offsetof, SkuTableIdx);
998 }
999
1000 private String getDataTypeDeclarationForSkuEnabled (Token token) {
1001 String typeStr = "";
1002
1003 if (token.datumType == Token.DATUM_TYPE.UINT8) {
1004 typeStr = "UINT8 %s_%s[%d];\r\n";
1005 } else if (token.datumType == Token.DATUM_TYPE.UINT16) {
1006 typeStr = "UINT16 %s_%s[%d];\r\n";
1007 } else if (token.datumType == Token.DATUM_TYPE.UINT32) {
1008 typeStr = "UINT32 %s_%s[%d];\r\n";
1009 } else if (token.datumType == Token.DATUM_TYPE.UINT64) {
1010 typeStr = "UINT64 %s_%s[%d];\r\n";
1011 } else if (token.datumType == Token.DATUM_TYPE.BOOLEAN) {
1012 typeStr = "BOOLEAN %s_%s[%d];\r\n";
1013 } else if (token.datumType == Token.DATUM_TYPE.POINTER) {
1014 return String.format("UINT8 %s_s[%d];\r\n", token.getPrimaryKeyString(), "SkuDataTable", token.datumSize * token.maxSkuCount);
1015 }
1016
1017 return String.format(typeStr, token.getPrimaryKeyString(), "SkuDataTable", token.maxSkuCount);
1018
1019 }
1020
1021 private String getDataTypeInstantiationForSkuEnabled (Token token) {
1022 String str = "";
1023
1024 if (token.datumType == Token.DATUM_TYPE.POINTER) {
1025 return String.format("UINT8 %s_s[%d]", token.getPrimaryKeyString(), "SkuDataTable", token.datumSize * token.maxSkuCount);
1026 } else {
1027 str = "{ ";
1028 for (int idx = 0; idx < token.maxSkuCount; idx++) {
1029 str += token.skuData.get(idx).toString();
1030 if (idx != token.maxSkuCount - 1) {
1031 str += ", ";
1032 }
1033 }
1034 str += "}";
1035
1036 return str;
1037 }
1038
1039 }
1040
1041 private String getDataTypeInstantiation (Token token) {
1042
1043 if (token.datumType == Token.DATUM_TYPE.POINTER) {
1044 return String.format("%s /* %s */", token.datum.toString(), token.getPrimaryKeyString());
1045 } else {
1046 return String.format("%s /* %s */", token.datum.toString(), token.getPrimaryKeyString());
1047 }
1048 }
1049
1050
1051 private String getDataTypeDeclaration (Token token) {
1052
1053 String typeStr = "";
1054
1055 if (token.datumType == Token.DATUM_TYPE.UINT8) {
1056 typeStr = "UINT8";
1057 } else if (token.datumType == Token.DATUM_TYPE.UINT16) {
1058 typeStr = "UINT16";
1059 } else if (token.datumType == Token.DATUM_TYPE.UINT32) {
1060 typeStr = "UINT32";
1061 } else if (token.datumType == Token.DATUM_TYPE.UINT64) {
1062 typeStr = "UINT64";
1063 } else if (token.datumType == Token.DATUM_TYPE.BOOLEAN) {
1064 typeStr = "BOOLEAN";
1065 } else if (token.datumType == Token.DATUM_TYPE.POINTER) {
1066 return String.format("UINT8 %s[%d]", token.getPrimaryKeyString(), token.datumSize);
1067 } else {
1068 }
1069
1070 return String.format("%s %s", typeStr, token.getPrimaryKeyString());
1071 }
1072
1073 private String getVpdEnableTypeDeclaration (Token token) {
1074 return String.format("VPD_HEAD %s", token.getPrimaryKeyString());
1075 }
1076
1077 private String getVpdEnableTypeInstantiation (Token token) {
1078 return String.format("{ %d } /* %s */", token.vpdOffset,
1079 token.getPrimaryKeyString());
1080 }
1081
1082 private String getStringTypeDeclaration (Token token) {
1083 return String.format("UINT16 %s", token.getPrimaryKeyString());
1084 }
1085
1086 private String getStringTypeInstantiation (int StringTableIdx, Token token) {
1087 return String.format ("%d /* %s */", StringTableIdx,
1088 token.getPrimaryKeyString());
1089 }
1090
1091
1092 private String getVariableEnableTypeDeclaration (Token token) {
1093 return String.format("VARIABLE_HEAD %s", token.getPrimaryKeyString());
1094 }
1095
1096 private String getVariableEnableInstantiation (Token token) {
1097 return String.format("{ %d, %d, %d } /* %s */", guidTable.add(token.variableGuid, token.getPrimaryKeyString()),
1098 stringTable.add(token.variableName, token),
1099 token.variableOffset,
1100 token.getPrimaryKeyString());
1101 }
1102
1103 public int getTotalTokenNumber () {
1104 return sizeTable.getTableLen();
1105 }
1106
1107 public static String getPcdDatabaseCommonDefinitions ()
1108 throws EntityException {
1109
1110 String retStr = "";
1111 try {
1112 File file = new File(GlobalData.getWorkspacePath() + File.separator +
1113 "Tools" + File.separator +
1114 "Conf" + File.separator +
1115 "Pcd" + File.separator +
1116 "PcdDatabaseCommonDefinitions.sample");
1117 System.out.println(GlobalData.getWorkspacePath());
1118 FileReader reader = new FileReader(file);
1119 BufferedReader in = new BufferedReader(reader);
1120 String str;
1121 while ((str = in.readLine()) != null) {
1122 retStr = retStr +"\r\n" + str;
1123 }
1124 } catch (Exception ex) {
1125 throw new EntityException("Fatal error when generating PcdDatabase Common Definitions");
1126 }
1127
1128 return retStr;
1129 }
1130
1131 public static String getPcdDxeDatabaseDefinitions ()
1132 throws EntityException {
1133
1134 String retStr = "";
1135 try {
1136 File file = new File(GlobalData.getWorkspacePath() + File.separator +
1137 "Tools" + File.separator +
1138 "Conf" + File.separator +
1139 "Pcd" + File.separator +
1140 "PcdDatabaseDxeDefinitions.sample");
1141 FileReader reader = new FileReader(file);
1142 BufferedReader in = new BufferedReader(reader);
1143 String str;
1144 while ((str = in.readLine()) != null) {
1145 retStr = retStr +"\r\n" + str;
1146 }
1147 } catch (Exception ex) {
1148 throw new EntityException("Fatal error when generating PcdDatabase Dxe Definitions");
1149 }
1150
1151 return retStr;
1152 }
1153
1154 public static String getPcdPeiDatabaseDefinitions ()
1155 throws EntityException {
1156
1157 String retStr = "";
1158 try {
1159 File file = new File(GlobalData.getWorkspacePath() + File.separator +
1160 "Tools" + File.separator +
1161 "Conf" + File.separator +
1162 "Pcd" + File.separator +
1163 "PcdDatabasePeiDefinitions.sample");
1164 FileReader reader = new FileReader(file);
1165 BufferedReader in = new BufferedReader(reader);
1166 String str;
1167 while ((str = in.readLine()) != null) {
1168 retStr = retStr +"\r\n" + str;
1169 }
1170 } catch (Exception ex) {
1171 throw new EntityException("Fatal error when generating PcdDatabase Pei Definitions");
1172 }
1173
1174 return retStr;
1175 }
1176
1177 }
1178
1179 /** This action class is to collect PCD information from MSA, SPD, FPD xml file.
1180 This class will be used for wizard and build tools, So it can *not* inherit
1181 from buildAction or UIAction.
1182 **/
1183 public class CollectPCDAction {
1184 /// memoryDatabase hold all PCD information collected from SPD, MSA, FPD.
1185 private MemoryDatabaseManager dbManager;
1186
1187 /// Workspacepath hold the workspace information.
1188 private String workspacePath;
1189
1190 /// FPD file is the root file.
1191 private String fpdFilePath;
1192
1193 /// Message level for CollectPCDAction.
1194 private int originalMessageLevel;
1195
1196 /**
1197 Set WorkspacePath parameter for this action class.
1198
1199 @param workspacePath parameter for this action
1200 **/
1201 public void setWorkspacePath(String workspacePath) {
1202 this.workspacePath = workspacePath;
1203 }
1204
1205 /**
1206 Set action message level for CollectPcdAction tool.
1207
1208 The message should be restored when this action exit.
1209
1210 @param actionMessageLevel parameter for this action
1211 **/
1212 public void setActionMessageLevel(int actionMessageLevel) {
1213 originalMessageLevel = ActionMessage.messageLevel;
1214 ActionMessage.messageLevel = actionMessageLevel;
1215 }
1216
1217 /**
1218 Set FPDFileName parameter for this action class.
1219
1220 @param fpdFilePath fpd file path
1221 **/
1222 public void setFPDFilePath(String fpdFilePath) {
1223 this.fpdFilePath = fpdFilePath;
1224 }
1225
1226 /**
1227 Common function interface for outer.
1228
1229 @param workspacePath The path of workspace of current build or analysis.
1230 @param fpdFilePath The fpd file path of current build or analysis.
1231 @param messageLevel The message level for this Action.
1232
1233 @throws Exception The exception of this function. Because it can *not* be predict
1234 where the action class will be used. So only Exception can be throw.
1235
1236 **/
1237 public void perform(String workspacePath, String fpdFilePath,
1238 int messageLevel) throws Exception {
1239 setWorkspacePath(workspacePath);
1240 setFPDFilePath(fpdFilePath);
1241 setActionMessageLevel(messageLevel);
1242 checkParameter();
1243 execute();
1244 ActionMessage.messageLevel = originalMessageLevel;
1245 }
1246
1247 /**
1248 Core execution function for this action class.
1249
1250 This function work flows will be:
1251 1) Get all token's platform information from FPD, and create token object into memory database.
1252 2) Get all token's module information from MSA, and create usage instance for every module's PCD entry.
1253 3) Get all token's inherited information from MSA's library, and create usage instance
1254 for module who consume this library and create usage instance for library for building.
1255 4) Collect token's package information from SPD, update these information for token in memory
1256 database.
1257 5) Generate 3 strings for a) All modules using Dynamic(Ex) PCD entry. (Token Number)
1258 b) PEI PCD Database (C Structure) for PCD Service PEIM
1259 c) DXE PCD Database (C structure) for PCD Service DXE
1260
1261
1262 @throws EntityException Exception indicate failed to execute this action.
1263
1264 **/
1265 private void execute() throws EntityException {
1266 FrameworkPlatformDescriptionDocument fpdDoc = null;
1267 Object[][] modulePCDArray = null;
1268 Map<String, XmlObject> docMap = null;
1269 ModuleSADocument.ModuleSA[] moduleSAs = null;
1270 UsageInstance usageInstance = null;
1271 String packageName = null;
1272 String packageFullPath = null;
1273 int index = 0;
1274 int libraryIndex = 0;
1275 int pcdArrayIndex = 0;
1276 List<String> listLibraryInstance = null;
1277 String componentTypeStr = null;
1278
1279 //
1280 // Collect all PCD information defined in FPD file.
1281 // Evenry token defind in FPD will be created as an token into
1282 // memory database.
1283 //
1284 fpdDoc = createTokenInDBFromFPD();
1285
1286 //
1287 // Searching MSA and SPD document.
1288 // The information of MSA will be used to create usage instance into database.
1289 // The information of SPD will be used to update the token information in database.
1290 //
1291
1292 HashMap<String, XmlObject> map = new HashMap<String, XmlObject>();
1293 map.put("FrameworkPlatformDescription", fpdDoc);
1294 SurfaceAreaQuery.setDoc(map);
1295
1296 moduleSAs = SurfaceAreaQuery.getFpdModules();
1297 for(index = 0; index < moduleSAs.length; index ++) {
1298 //
1299 // Get module document and use SurfaceAreaQuery to get PCD information
1300 //
1301 docMap = GlobalData.getDoc(moduleSAs[index].getModuleName());
1302 SurfaceAreaQuery.setDoc(docMap);
1303 modulePCDArray = SurfaceAreaQuery.getModulePCDTokenArray();
1304 componentTypeStr = SurfaceAreaQuery.getComponentType();
1305 packageName =
1306 GlobalData.getPackageNameForModule(moduleSAs[index].getModuleName());
1307 packageFullPath = this.workspacePath + File.separator +
1308 GlobalData.getPackagePath(packageName) +
1309 packageName + ".spd";
1310
1311 if(modulePCDArray != null) {
1312 //
1313 // If current MSA contains <PCDs> information, then create usage
1314 // instance for PCD information from MSA
1315 //
1316 for(pcdArrayIndex = 0; pcdArrayIndex < modulePCDArray.length;
1317 pcdArrayIndex ++) {
1318 usageInstance =
1319 createUsageInstanceFromMSA(moduleSAs[index].getModuleName(),
1320 modulePCDArray[pcdArrayIndex]);
1321
1322 if(usageInstance == null) {
1323 continue;
1324 }
1325 //
1326 // Get remaining PCD information from the package which this module belongs to
1327 //
1328 updateTokenBySPD(usageInstance, packageFullPath);
1329 }
1330 }
1331
1332 //
1333 // Get inherit PCD information which inherit from library instance of this module.
1334 //
1335 listLibraryInstance =
1336 SurfaceAreaQuery.getLibraryInstance(moduleSAs[index].getArch().toString(),
1337 CommonDefinition.AlwaysConsumed);
1338 if(listLibraryInstance != null) {
1339 for(libraryIndex = 0; libraryIndex < listLibraryInstance.size();
1340 libraryIndex ++) {
1341 inheritPCDFromLibraryInstance(listLibraryInstance.get(libraryIndex),
1342 moduleSAs[index].getModuleName(),
1343 packageName,
1344 componentTypeStr);
1345 }
1346 }
1347 }
1348
1349 //
1350 // Call Private function genPcdDatabaseSourceCode (void); ComponentTypeBsDriver
1351 // 1) Generate for PEI, DXE PCD DATABASE's definition and initialization.
1352 //
1353 genPcdDatabaseSourceCode ();
1354
1355 }
1356
1357 /**
1358 This function generates source code for PCD Database.
1359
1360 @param void
1361 @throws EntityException If the token does *not* exist in memory database.
1362
1363 **/
1364
1365 private void genPcdDatabaseSourceCode ()
1366 throws EntityException {
1367 String PcdCommonHeaderString = PcdDatabase.getPcdDatabaseCommonDefinitions ();
1368
1369 ArrayList<Token> alPei = new ArrayList<Token> ();
1370 ArrayList<Token> alDxe = new ArrayList<Token> ();
1371
1372 dbManager.getTwoPhaseDynamicRecordArray(alPei, alDxe);
1373 PcdDatabase pcdPeiDatabase = new PcdDatabase (alPei, "PEI", 0);
1374 pcdPeiDatabase.genCode();
1375 dbManager.PcdPeimHString = PcdCommonHeaderString + pcdPeiDatabase.getHString()
1376 + PcdDatabase.getPcdPeiDatabaseDefinitions();
1377 dbManager.PcdPeimCString = pcdPeiDatabase.getCString();
1378
1379 PcdDatabase pcdDxeDatabase = new PcdDatabase (alDxe,
1380 "DXE",
1381 alPei.size()
1382 );
1383 pcdDxeDatabase.genCode();
1384 dbManager.PcdDxeHString = dbManager.PcdPeimHString + pcdDxeDatabase.getHString()
1385 + PcdDatabase.getPcdDxeDatabaseDefinitions();
1386 dbManager.PcdDxeCString = pcdDxeDatabase.getCString();
1387 }
1388
1389 /**
1390 This function will collect inherit PCD information from library for a module.
1391
1392 This function will create two usage instance for inherited PCD token, one is
1393 for module and another is for library.
1394 For module, if it inherited a PCD token from library, this PCD token's value
1395 should be instanced in module level, and belongs to module.
1396 For library, it also need a usage instance for build.
1397
1398 @param libraryName The name of library instance.
1399 @param moduleName The name of module.
1400 @param packageName The name of package while module belongs to.
1401 @param parentcomponentType The component type of module.
1402
1403 @throws EntityException If the token does *not* exist in memory database.
1404
1405 **/
1406 private void inheritPCDFromLibraryInstance(String libraryName,
1407 String moduleName,
1408 String packageName,
1409 String parentcomponentType)
1410 throws EntityException {
1411 Map<String, XmlObject> docMap = null;
1412 String primaryKeyString = null;
1413 Object[][] libPcdDataArray = null;
1414 UUID nullUUID = new UUID(0,0);
1415 UUID platformUUID = nullUUID;
1416 UUID tokenSpaceGuid = null;
1417 int tokenIndex = 0;
1418 Token token = null;
1419 Token.PCD_TYPE pcdType = Token.PCD_TYPE.UNKNOWN;
1420 UsageInstance usageInstance = null;
1421 String packageFullPath = null;
1422
1423 //
1424 // Query PCD information from library's document.
1425 //
1426 docMap = GlobalData.getDoc(libraryName);
1427 SurfaceAreaQuery.setDoc(docMap);
1428 libPcdDataArray = SurfaceAreaQuery.getModulePCDTokenArray();
1429
1430 if(libPcdDataArray == null) {
1431 return;
1432 }
1433
1434 for(tokenIndex = 0; tokenIndex < libPcdDataArray.length; tokenIndex ++) {
1435 tokenSpaceGuid =((UUID)libPcdDataArray[tokenIndex][2] == null) ?
1436 nullUUID :(UUID)libPcdDataArray[tokenIndex][2];
1437
1438 //
1439 // Get token from memory database. The token must be created from FPD already.
1440 //
1441 primaryKeyString = Token.getPrimaryKeyString((String)libPcdDataArray[tokenIndex][0],
1442 tokenSpaceGuid,
1443 platformUUID
1444 );
1445
1446 if(dbManager.isTokenInDatabase(primaryKeyString)) {
1447 token = dbManager.getTokenByKey(primaryKeyString);
1448 } else {
1449 throw new EntityException("The PCD token " + primaryKeyString +
1450 " defined in module " + moduleName +
1451 " does not exist in FPD file!");
1452 }
1453
1454 //
1455 // Create usage instance for module.
1456 //
1457 pcdType = Token.getpcdTypeFromString((String)libPcdDataArray[tokenIndex][1]);
1458 usageInstance = new UsageInstance(token,
1459 Token.PCD_USAGE.ALWAYS_CONSUMED,
1460 pcdType,
1461 CommonDefinition.getComponentType(parentcomponentType),
1462 libPcdDataArray[tokenIndex][3],
1463 null,
1464 (String) libPcdDataArray[tokenIndex][5],
1465 "",
1466 moduleName,
1467 packageName,
1468 true);
1469 if(Token.PCD_USAGE.UNKNOWN == token.isUsageInstanceExist(moduleName)) {
1470 token.addUsageInstance(usageInstance);
1471
1472 packageFullPath = this.workspacePath + File.separator +
1473 GlobalData.getPackagePath(packageName) +
1474 packageName + ".spd";
1475 updateTokenBySPD(usageInstance, packageFullPath);
1476 }
1477
1478 //
1479 // We need create second usage instance for inherited case, which
1480 // add library as an usage instance, because when build a module, and
1481 // if module inherited from base library, then build process will build
1482 // library at first.
1483 //
1484 if(Token.PCD_USAGE.UNKNOWN == token.isUsageInstanceExist(libraryName)) {
1485 packageName = GlobalData.getPackageNameForModule(libraryName);
1486 usageInstance = new UsageInstance(token,
1487 Token.PCD_USAGE.ALWAYS_CONSUMED,
1488 pcdType,
1489 CommonDefinition.ComponentTypeLibrary,
1490 libPcdDataArray[tokenIndex][3],
1491 null,
1492 (String)libPcdDataArray[tokenIndex][5],
1493 "",
1494 libraryName,
1495 packageName,
1496 false);
1497 token.addUsageInstance(usageInstance);
1498 }
1499 }
1500 }
1501
1502 /**
1503 Create usage instance for PCD token defined in MSA document
1504
1505 A PCD token maybe used by many modules, and every module is one of usage
1506 instance of this token. For ALWAY_CONSUMED, SOMETIMES_CONSUMED, it is
1507 consumer type usage instance of this token, and for ALWAYS_PRODUCED,
1508 SOMETIMES_PRODUCED, it is produce type usage instance.
1509
1510 @param moduleName The name of module
1511 @param tokenInfoInMsa The PCD token information array retrieved from MSA.
1512
1513 @return UsageInstance The usage instance created in memroy database.
1514
1515 @throws EntityException If token did not exist in database yet.
1516
1517 **/
1518 private UsageInstance createUsageInstanceFromMSA(String moduleName,
1519 Object[] tokenInfoInMsa)
1520 throws EntityException {
1521 String packageName = null;
1522 UsageInstance usageInstance = null;
1523 UUID tokenSpaceGuid = null;
1524 UUID nullUUID = new UUID(0,0);
1525 String primaryKeyString = null;
1526 UUID platformTokenSpace = nullUUID;
1527 Token token = null;
1528 Token.PCD_TYPE pcdType = Token.PCD_TYPE.UNKNOWN;
1529 Token.PCD_USAGE pcdUsage = Token.PCD_USAGE.UNKNOWN;
1530
1531 tokenSpaceGuid =((UUID)tokenInfoInMsa[2] == null) ? nullUUID :(UUID)tokenInfoInMsa[2];
1532
1533 primaryKeyString = Token.getPrimaryKeyString((String)tokenInfoInMsa[0],
1534 tokenSpaceGuid,
1535 platformTokenSpace);
1536
1537 //
1538 // Get token object from memory database firstly.
1539 //
1540 if(dbManager.isTokenInDatabase(primaryKeyString)) {
1541 token = dbManager.getTokenByKey(primaryKeyString);
1542 } else {
1543 throw new EntityException("The PCD token " + primaryKeyString + " defined in module " +
1544 moduleName + " does not exist in FPD file!" );
1545 }
1546 pcdType = Token.getpcdTypeFromString((String)tokenInfoInMsa[1]);
1547 pcdUsage = Token.getUsageFromString((String)tokenInfoInMsa[4]);
1548
1549 packageName = GlobalData.getPackageNameForModule(moduleName);
1550
1551 if(Token.PCD_USAGE.UNKNOWN != token.isUsageInstanceExist(moduleName)) {
1552 //
1553 // BUGBUG: It is legal that same base name exist in one FPD file. In furture
1554 // we should use "Guid, Version, Package" and "Arch" to differ a module.
1555 // So currently, warning should be disabled.
1556 //
1557 //ActionMessage.warning(this,
1558 // "In module " + moduleName + " exist more than one PCD token " + token.cName
1559 // );
1560 return null;
1561 }
1562
1563 //
1564 // BUGBUG: following code could be enabled at current schema. Because
1565 // current schema does not provide usage information.
1566 //
1567 // For FEATRURE_FLAG, FIXED_AT_BUILD, PATCH_IN_MODULE type PCD token, his
1568 // usage is always ALWAYS_CONSUMED
1569 //
1570 //if((pcdType != Token.PCD_TYPE.DYNAMIC) &&
1571 // (pcdType != Token.PCD_TYPE.DYNAMIC_EX)) {
1572 pcdUsage = Token.PCD_USAGE.ALWAYS_CONSUMED;
1573 //}
1574
1575 usageInstance = new UsageInstance(token,
1576 pcdUsage,
1577 pcdType,
1578 CommonDefinition.getComponentType(SurfaceAreaQuery.getComponentType()),
1579 tokenInfoInMsa[3],
1580 null,
1581 (String) tokenInfoInMsa[5],
1582 "",
1583 moduleName,
1584 packageName,
1585 false);
1586
1587 //
1588 // Use default value defined in MSA to update datum of token,
1589 // if datum of token does not defined in FPD file.
1590 //
1591 if((token.datum == null) &&(tokenInfoInMsa[3] != null)) {
1592 token.datum = tokenInfoInMsa[3];
1593 }
1594
1595 token.addUsageInstance(usageInstance);
1596
1597 return usageInstance;
1598 }
1599
1600 /**
1601 Create token instance object into memory database, the token information
1602 comes for FPD file. Normally, FPD file will contain all token platform
1603 informations.
1604
1605 This fucntion should be executed at firsly before others collection work
1606 such as searching token information from MSA, SPD.
1607
1608 @return FrameworkPlatformDescriptionDocument The FPD document instance for furture usage.
1609
1610 @throws EntityException Failed to parse FPD xml file.
1611
1612 **/
1613 private FrameworkPlatformDescriptionDocument createTokenInDBFromFPD()
1614 throws EntityException {
1615 XmlObject doc = null;
1616 FrameworkPlatformDescriptionDocument fpdDoc = null;
1617 int index = 0;
1618 List<PcdBuildData> pcdBuildDataArray = new ArrayList<PcdBuildData>();
1619 PcdBuildData pcdBuildData = null;
1620 Token token = null;
1621 UUID nullUUID = new UUID(0,0);
1622 UUID platformTokenSpace= nullUUID;
1623 List skuDataArray = new ArrayList();
1624 SkuInstance skuInstance = null;
1625 int skuIndex = 0;
1626
1627 //
1628 // Get all tokens from FPD file and create token into database.
1629 //
1630
1631 try {
1632 doc = XmlObject.Factory.parse(new File(fpdFilePath));
1633 } catch(IOException ioE) {
1634 throw new EntityException("Can't find the FPD xml fle:" + fpdFilePath);
1635 } catch(XmlException xmlE) {
1636 throw new EntityException("Can't parse the FPD xml fle:" + fpdFilePath);
1637 }
1638
1639 //
1640 // Get memoryDatabaseManager instance from GlobalData.
1641 //
1642 if((dbManager = GlobalData.getPCDMemoryDBManager()) == null) {
1643 throw new EntityException("The instance of PCD memory database manager is null");
1644 }
1645
1646 dbManager = new MemoryDatabaseManager();
1647
1648 if(!(doc instanceof FrameworkPlatformDescriptionDocument)) {
1649 throw new EntityException("File " + fpdFilePath +
1650 " is not a FrameworkPlatformDescriptionDocument");
1651 }
1652
1653 fpdDoc =(FrameworkPlatformDescriptionDocument)doc;
1654
1655 //
1656 // Add all tokens in FPD into Memory Database.
1657 //
1658 pcdBuildDataArray =
1659 fpdDoc.getFrameworkPlatformDescription().getPcdBuildDeclarations().getPcdBuildDataList();
1660 for(index = 0;
1661 index < fpdDoc.getFrameworkPlatformDescription().getPcdBuildDeclarations().sizeOfPcdBuildDataArray();
1662 index ++) {
1663 pcdBuildData = pcdBuildDataArray.get(index);
1664 token = new Token(pcdBuildData.getCName(), new UUID(0, 0), new UUID(0, 0));
1665 //
1666 // BUGBUG: in FPD, <defaultValue> should be defined as <Value>
1667 //
1668 token.datum = pcdBuildData.getDefaultValue();
1669 token.tokenNumber = Integer.decode(pcdBuildData.getToken().getStringValue());
1670 token.hiiEnabled = pcdBuildData.getHiiEnable();
1671 token.variableGuid = Token.getGUIDFromSchemaObject(pcdBuildData.getVariableGuid());
1672 token.variableName = pcdBuildData.getVariableName();
1673 token.variableOffset = Integer.decode(pcdBuildData.getDataOffset());
1674 token.skuEnabled = pcdBuildData.getSkuEnable();
1675 token.maxSkuCount = Integer.decode(pcdBuildData.getMaxSku());
1676 token.skuId = Integer.decode(pcdBuildData.getSkuId());
1677 token.skuDataArrayEnabled = pcdBuildData.getSkuDataArrayEnable();
1678 token.assignedtokenNumber = Integer.decode(pcdBuildData.getToken().getStringValue());
1679 skuDataArray = pcdBuildData.getSkuDataArray1();
1680 token.datumType = Token.getdatumTypeFromString(pcdBuildData.getDatumType().toString());
1681 token.datumSize = pcdBuildData.getDatumSize();
1682
1683 if(skuDataArray != null) {
1684 for(skuIndex = 0; skuIndex < skuDataArray.size(); skuIndex ++) {
1685 //
1686 // BUGBUG: Now in current schema, The value is defined as String type,
1687 // it is not correct, the type should be same as the datumType
1688 //
1689 skuInstance = new SkuInstance(((PcdBuildData.SkuData)skuDataArray.get(skuIndex)).getId(),
1690 ((PcdBuildData.SkuData)skuDataArray.get(skuIndex)).getValue());
1691 token.skuData.add(skuInstance);
1692 }
1693 }
1694
1695 if(dbManager.isTokenInDatabase(Token.getPrimaryKeyString(token.cName,
1696 token.tokenSpaceName,
1697 platformTokenSpace))) {
1698 //
1699 // If found duplicate token, Should tool be hold?
1700 //
1701 ActionMessage.warning(this,
1702 "Token " + token.cName + " exists in token database");
1703 continue;
1704 }
1705 token.pcdType = Token.getpcdTypeFromString(pcdBuildData.getItemType().toString());
1706 dbManager.addTokenToDatabase(Token.getPrimaryKeyString(token.cName,
1707 token.tokenSpaceName,
1708 platformTokenSpace),
1709 token);
1710 }
1711
1712 return fpdDoc;
1713 }
1714
1715 /**
1716 Update PCD token in memory database by help information in SPD.
1717
1718 After create token from FPD and create usage instance from MSA, we should collect
1719 PCD package level information from SPD and update token information in memory
1720 database.
1721
1722 @param usageInstance The usage instance defined in MSA and want to search in SPD.
1723 @param packageFullPath The SPD file path.
1724
1725 @throws EntityException Failed to parse SPD xml file.
1726
1727 **/
1728 private void updateTokenBySPD(UsageInstance usageInstance,
1729 String packageFullPath)
1730 throws EntityException {
1731 PackageSurfaceAreaDocument pkgDoc = null;
1732 PcdDefinitions pcdDefinitions = null;
1733 List<PcdDefinitions.PcdEntry> pcdEntryArray = new ArrayList<PcdDefinitions.PcdEntry>();
1734 int index = 0;
1735 boolean isFoundInSpd = false;
1736 Token.DATUM_TYPE datumType = Token.DATUM_TYPE.UNKNOWN;
1737
1738 try {
1739 pkgDoc =(PackageSurfaceAreaDocument)XmlObject.Factory.parse(new File(packageFullPath));
1740 } catch(IOException ioE) {
1741 throw new EntityException("Can't find the FPD xml fle:" + packageFullPath);
1742 } catch(XmlException xmlE) {
1743 throw new EntityException("Can't parse the FPD xml fle:" + packageFullPath);
1744 }
1745 pcdDefinitions = pkgDoc.getPackageSurfaceArea().getPcdDefinitions();
1746 //
1747 // It is illege for SPD file does not contains any PCD information.
1748 //
1749 if (pcdDefinitions == null) {
1750 return;
1751 }
1752
1753 pcdEntryArray = pcdDefinitions.getPcdEntryList();
1754 if (pcdEntryArray == null) {
1755 return;
1756 }
1757 for(index = 0; index < pcdEntryArray.size(); index ++) {
1758 if(pcdEntryArray.get(index).getCName().equalsIgnoreCase(
1759 usageInstance.parentToken.cName)) {
1760 isFoundInSpd = true;
1761 //
1762 // From SPD file , we can get following information.
1763 // Token: Token number defined in package level.
1764 // PcdItemType: This item does not single one. It means all supported item type.
1765 // datumType: UINT8, UNIT16, UNIT32, UINT64, VOID*, BOOLEAN
1766 // datumSize: The size of default value or maxmine size.
1767 // defaultValue: This value is defined in package level.
1768 // HelpText: The help text is provided in package level.
1769 //
1770
1771 usageInstance.parentToken.tokenNumber = Integer.decode(pcdEntryArray.get(index).getToken());
1772
1773 if(pcdEntryArray.get(index).getDatumType() != null) {
1774 datumType = Token.getdatumTypeFromString(
1775 pcdEntryArray.get(index).getDatumType().toString());
1776 if(usageInstance.parentToken.datumType == Token.DATUM_TYPE.UNKNOWN) {
1777 usageInstance.parentToken.datumType = datumType;
1778 } else {
1779 if(datumType != usageInstance.parentToken.datumType) {
1780 throw new EntityException("Different datum types are defined for Token :" +
1781 usageInstance.parentToken.cName);
1782 }
1783 }
1784
1785 } else {
1786 throw new EntityException("The datum type for token " + usageInstance.parentToken.cName +
1787 " is not defind in SPD file " + packageFullPath);
1788 }
1789
1790 usageInstance.defaultValueInSPD = pcdEntryArray.get(index).getDefaultValue();
1791 usageInstance.helpTextInSPD = "Help Text in SPD";
1792
1793 //
1794 // If token's datum is not valid, it indicate that datum is not provided
1795 // in FPD and defaultValue is not provided in MSA, then use defaultValue
1796 // in SPD as the datum of token.
1797 //
1798 if(usageInstance.parentToken.datum == null) {
1799 if(pcdEntryArray.get(index).getDefaultValue() != null) {
1800 usageInstance.parentToken.datum = pcdEntryArray.get(index).getDefaultValue();
1801 } else {
1802 throw new EntityException("FPD does not provide datum for token " + usageInstance.parentToken.cName +
1803 ", MSA and SPD also does not provide <defaultValue> for this token!");
1804 }
1805 }
1806 }
1807 }
1808 }
1809
1810 /**
1811 check parameter for this action.
1812
1813 @throws EntityException Bad parameter.
1814 **/
1815 private void checkParameter() throws EntityException {
1816 File file = null;
1817
1818 if((fpdFilePath == null) ||(workspacePath == null)) {
1819 throw new EntityException("WorkspacePath and FPDFileName should be blank for CollectPCDAtion!");
1820 }
1821
1822 if(fpdFilePath.length() == 0 || workspacePath.length() == 0) {
1823 throw new EntityException("WorkspacePath and FPDFileName should be blank for CollectPCDAtion!");
1824 }
1825
1826 file = new File(workspacePath);
1827 if(!file.exists()) {
1828 throw new EntityException("WorkpacePath " + workspacePath + " does not exist!");
1829 }
1830
1831 file = new File(fpdFilePath);
1832
1833 if(!file.exists()) {
1834 throw new EntityException("FPD File " + fpdFilePath + " does not exist!");
1835 }
1836 }
1837
1838 /**
1839 Test case function
1840
1841 @param argv parameter from command line
1842 **/
1843 public static void main(String argv[]) throws EntityException {
1844 CollectPCDAction ca = new CollectPCDAction();
1845 ca.setWorkspacePath("G:/mdk");
1846 ca.setFPDFilePath("G:/mdk/EdkNt32Pkg/build/Nt32.fpd");
1847 ca.setActionMessageLevel(ActionMessage.MAX_MESSAGE_LEVEL);
1848 GlobalData.initInfo("Tools" + File.separator + "Conf" + File.separator + "FrameworkDatabase.db",
1849 "G:/mdk");
1850 ca.execute();
1851 }
1852 }