]> git.proxmox.com Git - mirror_edk2.git/blob - Tools/Source/GenBuild/org/tianocore/build/pcd/action/CollectPCDAction.java
7b86e6b88fc4e680bfa83c5828641315862218e6
[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 = (Token)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 List<Token> list = initTokens;
793 java.util.Collections.sort(list, comparator);
794 initCode = processTokens(initTokens);
795
796 //
797 // Generate Structure Declaration for PcdTokens without Default Value
798 // PEI_PCD_DATABASE_UNINIT
799 //
800 list = uninitTokens;
801 java.util.Collections.sort(list, comparator);
802 uninitCode = processTokens(uninitTokens);
803
804 //
805 // Generate size info Macro for all Tables
806 //
807 macroStr += guidTable.getSizeMacro();
808 macroStr += stringTable.getSizeMacro();
809 macroStr += skuIdTable.getSizeMacro();
810 macroStr += localTokenNumberTable.getSizeMacro();
811 macroStr += exMapTable.getSizeMacro();
812
813 //
814 // Generate existance info Macro for all Tables
815 //
816 macroStr += guidTable.getExistanceMacro();
817 macroStr += stringTable.getExistanceMacro();
818 macroStr += skuIdTable.getExistanceMacro();
819 macroStr += localTokenNumberTable.getExistanceMacro();
820 macroStr += exMapTable.getExistanceMacro();
821
822 //
823 // Generate Structure Declaration for PcdTokens with Default Value
824 // for example PEI_PCD_DATABASE_INIT
825 //
826 initDeclStr += "typedef struct {" + newLine;
827 {
828 initDeclStr += tab + exMapTable.getTypeDeclaration();
829 initDeclStr += tab + guidTable.getTypeDeclaration();
830 initDeclStr += tab + localTokenNumberTable.getTypeDeclaration();
831 initDeclStr += tab + stringTable.getTypeDeclaration();
832 initDeclStr += tab + sizeTable.getTypeDeclaration();
833 initDeclStr += tab + skuIdTable.getTypeDeclaration();
834 if (phase.equalsIgnoreCase("PEI")) {
835 initDeclStr += tab + "SKU_ID SystemSkuId;" + newLine;
836 }
837
838 decla = initCode.get(new String("Declaration"));
839 for (i = 0; i < decla.size(); i++) {
840 initDeclStr += tab + decla.get(i) + declNewLine;
841 }
842
843 //
844 // Generate Structure Declaration for PcdToken with SkuEnabled
845 //
846 decla = initCode.get("DeclarationForSku");
847
848 for (i = 0; i < decla.size(); i++) {
849 initDeclStr += tab + decla.get(i) + declNewLine;
850 }
851 }
852 initDeclStr += String.format("} %s_PCD_DATABASE_INIT;\r\n\r\n", phase);
853
854 //
855 // Generate MACRO for structure intialization of PCDTokens with Default Value
856 // The sequence must match the sequence of declaration of the memembers in the structure
857 String tmp = String.format("%s_PCD_DATABASE_INIT g%sPcdDbInit = { ", phase.toUpperCase(), phase.toUpperCase());
858 initInstStr += tmp + newLine;
859 initInstStr += tab + genInstantiationStr(exMapTable.getInstantiation()) + commaNewLine;
860 initInstStr += tab + genInstantiationStr(guidTable.getInstantiation()) + commaNewLine;
861 initInstStr += tab + genInstantiationStr(localTokenNumberTable.getInstantiation()) + commaNewLine;
862 initInstStr += tab + genInstantiationStr(stringTable.getInstantiation()) + commaNewLine;
863 initInstStr += tab + genInstantiationStr(sizeTable.getInstantiation()) + commaNewLine;
864 initInstStr += tab + genInstantiationStr(skuIdTable.getInstantiation()) + commaNewLine;
865 //
866 // For SystemSkuId
867 //
868 if (phase.equalsIgnoreCase("PEI")) {
869 initInstStr += tab + "0" + tab + "/* SystemSkuId */" + commaNewLine;
870 }
871
872 inst = initCode.get("Instantiation");
873 for (i = 0; i < inst.size(); i++) {
874 initInstStr += tab + inst.get(i) + commaNewLine;
875 }
876
877 inst = initCode.get("InstantiationForSku");
878 for (i = 0; i < inst.size(); i++) {
879 initInstStr += tab + inst.get(i);
880 if (i != inst.size() - 1) {
881 initInstStr += commaNewLine;
882 }
883 }
884
885 initInstStr += "};";
886
887 uninitDeclStr += "typedef struct {" + newLine;
888 {
889 decla = uninitCode.get("Declaration");
890 if (decla.size() == 0) {
891 uninitDeclStr += "UINT8 dummy /* The UINT struct is empty */" + declNewLine;
892 } else {
893
894 for (i = 0; i < decla.size(); i++) {
895 uninitDeclStr += tab + decla.get(i) + declNewLine;
896 }
897
898 decla = uninitCode.get("DeclarationForSku");
899
900 for (i = 0; i < decla.size(); i++) {
901 uninitDeclStr += tab + decla.get(i) + declNewLine;
902 }
903 }
904 }
905 uninitDeclStr += String.format("} %s_PCD_DATABASE_UNINIT;\r\n\r\n", phase);
906
907 cString = initInstStr + newLine;
908 hString = macroStr + newLine
909 + initDeclStr + newLine
910 + uninitDeclStr + newLine
911 + newLine;
912
913 hString += String.format("#define PCD_%s_SERVICE_DRIVER_VERSION %d", phase, version);
914
915 }
916
917 private String genInstantiationStr (ArrayList<String> alStr) {
918 String str = "";
919 for (int i = 0; i< alStr.size(); i++) {
920 str += "\t" + alStr.get(i);
921 if (i != alStr.size() - 1) {
922 str += "\r\n";
923 }
924 }
925
926 return str;
927 }
928
929 private HashMap<String, ArrayList<String>> processTokens (List<Token> alToken) {
930
931 HashMap <String, ArrayList<String>> map = new HashMap<String, ArrayList<String>>();
932
933 ArrayList<String> decl = new ArrayList<String>();
934 ArrayList<String> declForSkuEnableType = new ArrayList<String>();
935 ArrayList<String> inst = new ArrayList<String>();
936 ArrayList<String> instForSkuEnableType = new ArrayList<String>();
937
938 for (int index = 0; index < alToken.size(); index++) {
939 Token token = alToken.get(index);
940
941 if (token.skuEnabled) {
942 //
943 // BugBug: Schema only support Data type now
944 //
945 int tableIdx;
946
947 tableIdx = skuIdTable.add(token);
948
949 decl.add(getSkuEnabledTypeDeclaration(token));
950 if (token.hasDefaultValue()) {
951 inst.add(getSkuEnabledTypeInstantiaion(token, tableIdx));
952 }
953
954 declForSkuEnableType.add(getDataTypeDeclarationForSkuEnabled(token));
955 if (token.hasDefaultValue()) {
956 instForSkuEnableType.add(getDataTypeInstantiationForSkuEnabled(token));
957 }
958
959 } else {
960 if (token.hiiEnabled) {
961 decl.add(getVariableEnableTypeDeclaration(token));
962 inst.add(getVariableEnableInstantiation(token));
963 } else if (token.vpdEnabled) {
964 decl.add(getVpdEnableTypeDeclaration(token));
965 inst.add(getVpdEnableTypeInstantiation(token));
966 } else if (token.isStringType()) {
967 decl.add(getStringTypeDeclaration(token));
968 inst.add(getStringTypeInstantiation(stringTable.add(token.getStringTypeString(), token), token));
969 }
970 else {
971 decl.add(getDataTypeDeclaration(token));
972 if (token.hasDefaultValue()) {
973 inst.add(getDataTypeInstantiation(token));
974 }
975 }
976 }
977
978 sizeTable.add(token);
979 localTokenNumberTable.add(token);
980 token.assignedtokenNumber = assignedTokenNumber++;
981
982 }
983
984 map.put("Declaration", decl);
985 map.put("DeclarationForSku", declForSkuEnableType);
986 map.put("Instantiation", inst);
987 map.put("InstantiationForSku", instForSkuEnableType);
988
989 return map;
990 }
991
992 private String getSkuEnabledTypeDeclaration (Token token) {
993 return String.format("SKU_HEAD %s;\r\n", token.getPrimaryKeyString());
994 }
995
996 private String getSkuEnabledTypeInstantiaion (Token token, int SkuTableIdx) {
997
998 String offsetof = String.format(PcdDatabase.offsetOfSkuHeadStrTemplate, phase, token.hasDefaultValue()? "Init" : "Uninit", token.getPrimaryKeyString());
999 return String.format("{ %s, %d }", offsetof, SkuTableIdx);
1000 }
1001
1002 private String getDataTypeDeclarationForSkuEnabled (Token token) {
1003 String typeStr = "";
1004
1005 if (token.datumType == Token.DATUM_TYPE.UINT8) {
1006 typeStr = "UINT8 %s_%s[%d];\r\n";
1007 } else if (token.datumType == Token.DATUM_TYPE.UINT16) {
1008 typeStr = "UINT16 %s_%s[%d];\r\n";
1009 } else if (token.datumType == Token.DATUM_TYPE.UINT32) {
1010 typeStr = "UINT32 %s_%s[%d];\r\n";
1011 } else if (token.datumType == Token.DATUM_TYPE.UINT64) {
1012 typeStr = "UINT64 %s_%s[%d];\r\n";
1013 } else if (token.datumType == Token.DATUM_TYPE.BOOLEAN) {
1014 typeStr = "BOOLEAN %s_%s[%d];\r\n";
1015 } else if (token.datumType == Token.DATUM_TYPE.POINTER) {
1016 return String.format("UINT8 %s_s[%d];\r\n", token.getPrimaryKeyString(), "SkuDataTable", token.datumSize * token.maxSkuCount);
1017 }
1018
1019 return String.format(typeStr, token.getPrimaryKeyString(), "SkuDataTable", token.maxSkuCount);
1020
1021 }
1022
1023 private String getDataTypeInstantiationForSkuEnabled (Token token) {
1024 String str = "";
1025
1026 if (token.datumType == Token.DATUM_TYPE.POINTER) {
1027 return String.format("UINT8 %s_s[%d]", token.getPrimaryKeyString(), "SkuDataTable", token.datumSize * token.maxSkuCount);
1028 } else {
1029 str = "{ ";
1030 for (int idx = 0; idx < token.maxSkuCount; idx++) {
1031 str += token.skuData.get(idx).toString();
1032 if (idx != token.maxSkuCount - 1) {
1033 str += ", ";
1034 }
1035 }
1036 str += "}";
1037
1038 return str;
1039 }
1040
1041 }
1042
1043 private String getDataTypeInstantiation (Token token) {
1044
1045 if (token.datumType == Token.DATUM_TYPE.POINTER) {
1046 return String.format("%s /* %s */", token.datum.toString(), token.getPrimaryKeyString());
1047 } else {
1048 return String.format("%s /* %s */", token.datum.toString(), token.getPrimaryKeyString());
1049 }
1050 }
1051
1052
1053 private String getDataTypeDeclaration (Token token) {
1054
1055 String typeStr = "";
1056
1057 if (token.datumType == Token.DATUM_TYPE.UINT8) {
1058 typeStr = "UINT8";
1059 } else if (token.datumType == Token.DATUM_TYPE.UINT16) {
1060 typeStr = "UINT16";
1061 } else if (token.datumType == Token.DATUM_TYPE.UINT32) {
1062 typeStr = "UINT32";
1063 } else if (token.datumType == Token.DATUM_TYPE.UINT64) {
1064 typeStr = "UINT64";
1065 } else if (token.datumType == Token.DATUM_TYPE.BOOLEAN) {
1066 typeStr = "BOOLEAN";
1067 } else if (token.datumType == Token.DATUM_TYPE.POINTER) {
1068 return String.format("UINT8 %s[%d]", token.getPrimaryKeyString(), token.datumSize);
1069 } else {
1070 }
1071
1072 return String.format("%s %s", typeStr, token.getPrimaryKeyString());
1073 }
1074
1075 private String getVpdEnableTypeDeclaration (Token token) {
1076 return String.format("VPD_HEAD %s", token.getPrimaryKeyString());
1077 }
1078
1079 private String getVpdEnableTypeInstantiation (Token token) {
1080 return String.format("{ %d } /* %s */", token.vpdOffset,
1081 token.getPrimaryKeyString());
1082 }
1083
1084 private String getStringTypeDeclaration (Token token) {
1085 return String.format("UINT16 %s", token.getPrimaryKeyString());
1086 }
1087
1088 private String getStringTypeInstantiation (int StringTableIdx, Token token) {
1089 return String.format ("%d /* %s */", StringTableIdx,
1090 token.getPrimaryKeyString());
1091 }
1092
1093
1094 private String getVariableEnableTypeDeclaration (Token token) {
1095 return String.format("VARIABLE_HEAD %s", token.getPrimaryKeyString());
1096 }
1097
1098 private String getVariableEnableInstantiation (Token token) {
1099 return String.format("{ %d, %d, %d } /* %s */", guidTable.add(token.variableGuid, token.getPrimaryKeyString()),
1100 stringTable.add(token.variableName, token),
1101 token.variableOffset,
1102 token.getPrimaryKeyString());
1103 }
1104
1105 public int getTotalTokenNumber () {
1106 return sizeTable.getTableLen();
1107 }
1108
1109 public static String getPcdDatabaseCommonDefinitions ()
1110 throws EntityException {
1111
1112 String retStr = "";
1113 try {
1114 File file = new File(GlobalData.getWorkspacePath() + File.separator +
1115 "Tools" + File.separator +
1116 "Conf" + File.separator +
1117 "Pcd" + File.separator +
1118 "PcdDatabaseCommonDefinitions.sample");
1119 System.out.println(GlobalData.getWorkspacePath());
1120 FileReader reader = new FileReader(file);
1121 BufferedReader in = new BufferedReader(reader);
1122 String str;
1123 while ((str = in.readLine()) != null) {
1124 retStr = retStr +"\r\n" + str;
1125 }
1126 } catch (Exception ex) {
1127 throw new EntityException("Fatal error when generating PcdDatabase Common Definitions");
1128 }
1129
1130 return retStr;
1131 }
1132
1133 public static String getPcdDxeDatabaseDefinitions ()
1134 throws EntityException {
1135
1136 String retStr = "";
1137 try {
1138 File file = new File(GlobalData.getWorkspacePath() + File.separator +
1139 "Tools" + File.separator +
1140 "Conf" + File.separator +
1141 "Pcd" + File.separator +
1142 "PcdDatabaseDxeDefinitions.sample");
1143 FileReader reader = new FileReader(file);
1144 BufferedReader in = new BufferedReader(reader);
1145 String str;
1146 while ((str = in.readLine()) != null) {
1147 retStr = retStr +"\r\n" + str;
1148 }
1149 } catch (Exception ex) {
1150 throw new EntityException("Fatal error when generating PcdDatabase Dxe Definitions");
1151 }
1152
1153 return retStr;
1154 }
1155
1156 public static String getPcdPeiDatabaseDefinitions ()
1157 throws EntityException {
1158
1159 String retStr = "";
1160 try {
1161 File file = new File(GlobalData.getWorkspacePath() + File.separator +
1162 "Tools" + File.separator +
1163 "Conf" + File.separator +
1164 "Pcd" + File.separator +
1165 "PcdDatabasePeiDefinitions.sample");
1166 FileReader reader = new FileReader(file);
1167 BufferedReader in = new BufferedReader(reader);
1168 String str;
1169 while ((str = in.readLine()) != null) {
1170 retStr = retStr +"\r\n" + str;
1171 }
1172 } catch (Exception ex) {
1173 throw new EntityException("Fatal error when generating PcdDatabase Pei Definitions");
1174 }
1175
1176 return retStr;
1177 }
1178
1179 }
1180
1181 /** This action class is to collect PCD information from MSA, SPD, FPD xml file.
1182 This class will be used for wizard and build tools, So it can *not* inherit
1183 from buildAction or UIAction.
1184 **/
1185 public class CollectPCDAction {
1186 /// memoryDatabase hold all PCD information collected from SPD, MSA, FPD.
1187 private MemoryDatabaseManager dbManager;
1188
1189 /// Workspacepath hold the workspace information.
1190 private String workspacePath;
1191
1192 /// FPD file is the root file.
1193 private String fpdFilePath;
1194
1195 /// Message level for CollectPCDAction.
1196 private int originalMessageLevel;
1197
1198 /**
1199 Set WorkspacePath parameter for this action class.
1200
1201 @param workspacePath parameter for this action
1202 **/
1203 public void setWorkspacePath(String workspacePath) {
1204 this.workspacePath = workspacePath;
1205 }
1206
1207 /**
1208 Set action message level for CollectPcdAction tool.
1209
1210 The message should be restored when this action exit.
1211
1212 @param actionMessageLevel parameter for this action
1213 **/
1214 public void setActionMessageLevel(int actionMessageLevel) {
1215 originalMessageLevel = ActionMessage.messageLevel;
1216 ActionMessage.messageLevel = actionMessageLevel;
1217 }
1218
1219 /**
1220 Set FPDFileName parameter for this action class.
1221
1222 @param fpdFilePath fpd file path
1223 **/
1224 public void setFPDFilePath(String fpdFilePath) {
1225 this.fpdFilePath = fpdFilePath;
1226 }
1227
1228 /**
1229 Common function interface for outer.
1230
1231 @param workspacePath The path of workspace of current build or analysis.
1232 @param fpdFilePath The fpd file path of current build or analysis.
1233 @param messageLevel The message level for this Action.
1234
1235 @throws Exception The exception of this function. Because it can *not* be predict
1236 where the action class will be used. So only Exception can be throw.
1237
1238 **/
1239 public void perform(String workspacePath, String fpdFilePath,
1240 int messageLevel) throws Exception {
1241 setWorkspacePath(workspacePath);
1242 setFPDFilePath(fpdFilePath);
1243 setActionMessageLevel(messageLevel);
1244 checkParameter();
1245 execute();
1246 ActionMessage.messageLevel = originalMessageLevel;
1247 }
1248
1249 /**
1250 Core execution function for this action class.
1251
1252 This function work flows will be:
1253 1) Get all token's platform information from FPD, and create token object into memory database.
1254 2) Get all token's module information from MSA, and create usage instance for every module's PCD entry.
1255 3) Get all token's inherited information from MSA's library, and create usage instance
1256 for module who consume this library and create usage instance for library for building.
1257 4) Collect token's package information from SPD, update these information for token in memory
1258 database.
1259 5) Generate 3 strings for a) All modules using Dynamic(Ex) PCD entry. (Token Number)
1260 b) PEI PCD Database (C Structure) for PCD Service PEIM
1261 c) DXE PCD Database (C structure) for PCD Service DXE
1262
1263
1264 @throws EntityException Exception indicate failed to execute this action.
1265
1266 **/
1267 private void execute() throws EntityException {
1268 FrameworkPlatformDescriptionDocument fpdDoc = null;
1269 Object[][] modulePCDArray = null;
1270 Map<String, XmlObject> docMap = null;
1271 ModuleSADocument.ModuleSA[] moduleSAs = null;
1272 UsageInstance usageInstance = null;
1273 String packageName = null;
1274 String packageFullPath = null;
1275 int index = 0;
1276 int libraryIndex = 0;
1277 int pcdArrayIndex = 0;
1278 List<String> listLibraryInstance = null;
1279 String componentTypeStr = null;
1280
1281 //
1282 // Collect all PCD information defined in FPD file.
1283 // Evenry token defind in FPD will be created as an token into
1284 // memory database.
1285 //
1286 fpdDoc = createTokenInDBFromFPD();
1287
1288 //
1289 // Searching MSA and SPD document.
1290 // The information of MSA will be used to create usage instance into database.
1291 // The information of SPD will be used to update the token information in database.
1292 //
1293
1294 HashMap<String, XmlObject> map = new HashMap<String, XmlObject>();
1295 map.put("FrameworkPlatformDescription", fpdDoc);
1296 SurfaceAreaQuery.setDoc(map);
1297
1298 moduleSAs = SurfaceAreaQuery.getFpdModules();
1299 for(index = 0; index < moduleSAs.length; index ++) {
1300 //
1301 // Get module document and use SurfaceAreaQuery to get PCD information
1302 //
1303 docMap = GlobalData.getDoc(moduleSAs[index].getModuleName());
1304 SurfaceAreaQuery.setDoc(docMap);
1305 modulePCDArray = SurfaceAreaQuery.getModulePCDTokenArray();
1306 componentTypeStr = SurfaceAreaQuery.getComponentType();
1307 packageName =
1308 GlobalData.getPackageNameForModule(moduleSAs[index].getModuleName());
1309 packageFullPath = this.workspacePath + File.separator +
1310 GlobalData.getPackagePath(packageName) +
1311 packageName + ".spd";
1312
1313 if(modulePCDArray != null) {
1314 //
1315 // If current MSA contains <PCDs> information, then create usage
1316 // instance for PCD information from MSA
1317 //
1318 for(pcdArrayIndex = 0; pcdArrayIndex < modulePCDArray.length;
1319 pcdArrayIndex ++) {
1320 usageInstance =
1321 createUsageInstanceFromMSA(moduleSAs[index].getModuleName(),
1322 modulePCDArray[pcdArrayIndex]);
1323
1324 if(usageInstance == null) {
1325 continue;
1326 }
1327 //
1328 // Get remaining PCD information from the package which this module belongs to
1329 //
1330 updateTokenBySPD(usageInstance, packageFullPath);
1331 }
1332 }
1333
1334 //
1335 // Get inherit PCD information which inherit from library instance of this module.
1336 //
1337 listLibraryInstance =
1338 SurfaceAreaQuery.getLibraryInstance(moduleSAs[index].getArch().toString(),
1339 CommonDefinition.AlwaysConsumed);
1340 if(listLibraryInstance != null) {
1341 for(libraryIndex = 0; libraryIndex < listLibraryInstance.size();
1342 libraryIndex ++) {
1343 inheritPCDFromLibraryInstance(listLibraryInstance.get(libraryIndex),
1344 moduleSAs[index].getModuleName(),
1345 packageName,
1346 componentTypeStr);
1347 }
1348 }
1349 }
1350
1351 //
1352 // Call Private function genPcdDatabaseSourceCode (void); ComponentTypeBsDriver
1353 // 1) Generate for PEI, DXE PCD DATABASE's definition and initialization.
1354 //
1355 genPcdDatabaseSourceCode ();
1356
1357 }
1358
1359 /**
1360 This function generates source code for PCD Database.
1361
1362 @param void
1363 @throws EntityException If the token does *not* exist in memory database.
1364
1365 **/
1366
1367 private void genPcdDatabaseSourceCode ()
1368 throws EntityException {
1369 String PcdCommonHeaderString = PcdDatabase.getPcdDatabaseCommonDefinitions ();
1370
1371 ArrayList<Token> alPei = new ArrayList<Token> ();
1372 ArrayList<Token> alDxe = new ArrayList<Token> ();
1373
1374 dbManager.getTwoPhaseDynamicRecordArray(alPei, alDxe);
1375 PcdDatabase pcdPeiDatabase = new PcdDatabase (alPei, "PEI", 0);
1376 pcdPeiDatabase.genCode();
1377 dbManager.PcdPeimHString = PcdCommonHeaderString + pcdPeiDatabase.getHString()
1378 + PcdDatabase.getPcdPeiDatabaseDefinitions();
1379 dbManager.PcdPeimCString = pcdPeiDatabase.getCString();
1380
1381 PcdDatabase pcdDxeDatabase = new PcdDatabase (alDxe,
1382 "DXE",
1383 alPei.size()
1384 );
1385 pcdDxeDatabase.genCode();
1386 dbManager.PcdDxeHString = dbManager.PcdPeimHString + pcdDxeDatabase.getHString()
1387 + PcdDatabase.getPcdDxeDatabaseDefinitions();
1388 dbManager.PcdDxeCString = pcdDxeDatabase.getCString();
1389 }
1390
1391 /**
1392 This function will collect inherit PCD information from library for a module.
1393
1394 This function will create two usage instance for inherited PCD token, one is
1395 for module and another is for library.
1396 For module, if it inherited a PCD token from library, this PCD token's value
1397 should be instanced in module level, and belongs to module.
1398 For library, it also need a usage instance for build.
1399
1400 @param libraryName The name of library instance.
1401 @param moduleName The name of module.
1402 @param packageName The name of package while module belongs to.
1403 @param parentcomponentType The component type of module.
1404
1405 @throws EntityException If the token does *not* exist in memory database.
1406
1407 **/
1408 private void inheritPCDFromLibraryInstance(String libraryName,
1409 String moduleName,
1410 String packageName,
1411 String parentcomponentType)
1412 throws EntityException {
1413 Map<String, XmlObject> docMap = null;
1414 String primaryKeyString = null;
1415 Object[][] libPcdDataArray = null;
1416 UUID nullUUID = new UUID(0,0);
1417 UUID platformUUID = nullUUID;
1418 UUID tokenSpaceGuid = null;
1419 int tokenIndex = 0;
1420 Token token = null;
1421 Token.PCD_TYPE pcdType = Token.PCD_TYPE.UNKNOWN;
1422 UsageInstance usageInstance = null;
1423 String packageFullPath = null;
1424
1425 //
1426 // Query PCD information from library's document.
1427 //
1428 docMap = GlobalData.getDoc(libraryName);
1429 SurfaceAreaQuery.setDoc(docMap);
1430 libPcdDataArray = SurfaceAreaQuery.getModulePCDTokenArray();
1431
1432 if(libPcdDataArray == null) {
1433 return;
1434 }
1435
1436 for(tokenIndex = 0; tokenIndex < libPcdDataArray.length; tokenIndex ++) {
1437 tokenSpaceGuid =((UUID)libPcdDataArray[tokenIndex][2] == null) ?
1438 nullUUID :(UUID)libPcdDataArray[tokenIndex][2];
1439
1440 //
1441 // Get token from memory database. The token must be created from FPD already.
1442 //
1443 primaryKeyString = Token.getPrimaryKeyString((String)libPcdDataArray[tokenIndex][0],
1444 tokenSpaceGuid,
1445 platformUUID
1446 );
1447
1448 if(dbManager.isTokenInDatabase(primaryKeyString)) {
1449 token = dbManager.getTokenByKey(primaryKeyString);
1450 } else {
1451 throw new EntityException("The PCD token " + primaryKeyString +
1452 " defined in module " + moduleName +
1453 " does not exist in FPD file!");
1454 }
1455
1456 //
1457 // Create usage instance for module.
1458 //
1459 pcdType = Token.getpcdTypeFromString((String)libPcdDataArray[tokenIndex][1]);
1460 usageInstance = new UsageInstance(token,
1461 Token.PCD_USAGE.ALWAYS_CONSUMED,
1462 pcdType,
1463 CommonDefinition.getComponentType(parentcomponentType),
1464 libPcdDataArray[tokenIndex][3],
1465 null,
1466 (String) libPcdDataArray[tokenIndex][5],
1467 "",
1468 moduleName,
1469 packageName,
1470 true);
1471 if(Token.PCD_USAGE.UNKNOWN == token.isUsageInstanceExist(moduleName)) {
1472 token.addUsageInstance(usageInstance);
1473
1474 packageFullPath = this.workspacePath + File.separator +
1475 GlobalData.getPackagePath(packageName) +
1476 packageName + ".spd";
1477 updateTokenBySPD(usageInstance, packageFullPath);
1478 }
1479
1480 //
1481 // We need create second usage instance for inherited case, which
1482 // add library as an usage instance, because when build a module, and
1483 // if module inherited from base library, then build process will build
1484 // library at first.
1485 //
1486 if(Token.PCD_USAGE.UNKNOWN == token.isUsageInstanceExist(libraryName)) {
1487 packageName = GlobalData.getPackageNameForModule(libraryName);
1488 usageInstance = new UsageInstance(token,
1489 Token.PCD_USAGE.ALWAYS_CONSUMED,
1490 pcdType,
1491 CommonDefinition.ComponentTypeLibrary,
1492 libPcdDataArray[tokenIndex][3],
1493 null,
1494 (String)libPcdDataArray[tokenIndex][5],
1495 "",
1496 libraryName,
1497 packageName,
1498 false);
1499 token.addUsageInstance(usageInstance);
1500 }
1501 }
1502 }
1503
1504 /**
1505 Create usage instance for PCD token defined in MSA document
1506
1507 A PCD token maybe used by many modules, and every module is one of usage
1508 instance of this token. For ALWAY_CONSUMED, SOMETIMES_CONSUMED, it is
1509 consumer type usage instance of this token, and for ALWAYS_PRODUCED,
1510 SOMETIMES_PRODUCED, it is produce type usage instance.
1511
1512 @param moduleName The name of module
1513 @param tokenInfoInMsa The PCD token information array retrieved from MSA.
1514
1515 @return UsageInstance The usage instance created in memroy database.
1516
1517 @throws EntityException If token did not exist in database yet.
1518
1519 **/
1520 private UsageInstance createUsageInstanceFromMSA(String moduleName,
1521 Object[] tokenInfoInMsa)
1522 throws EntityException {
1523 String packageName = null;
1524 UsageInstance usageInstance = null;
1525 UUID tokenSpaceGuid = null;
1526 UUID nullUUID = new UUID(0,0);
1527 String primaryKeyString = null;
1528 UUID platformTokenSpace = nullUUID;
1529 Token token = null;
1530 Token.PCD_TYPE pcdType = Token.PCD_TYPE.UNKNOWN;
1531 Token.PCD_USAGE pcdUsage = Token.PCD_USAGE.UNKNOWN;
1532
1533 tokenSpaceGuid =((UUID)tokenInfoInMsa[2] == null) ? nullUUID :(UUID)tokenInfoInMsa[2];
1534
1535 primaryKeyString = Token.getPrimaryKeyString((String)tokenInfoInMsa[0],
1536 tokenSpaceGuid,
1537 platformTokenSpace);
1538
1539 //
1540 // Get token object from memory database firstly.
1541 //
1542 if(dbManager.isTokenInDatabase(primaryKeyString)) {
1543 token = dbManager.getTokenByKey(primaryKeyString);
1544 } else {
1545 throw new EntityException("The PCD token " + primaryKeyString + " defined in module " +
1546 moduleName + " does not exist in FPD file!" );
1547 }
1548 pcdType = Token.getpcdTypeFromString((String)tokenInfoInMsa[1]);
1549 pcdUsage = Token.getUsageFromString((String)tokenInfoInMsa[4]);
1550
1551 packageName = GlobalData.getPackageNameForModule(moduleName);
1552
1553 if(Token.PCD_USAGE.UNKNOWN != token.isUsageInstanceExist(moduleName)) {
1554 //
1555 // BUGBUG: It is legal that same base name exist in one FPD file. In furture
1556 // we should use "Guid, Version, Package" and "Arch" to differ a module.
1557 // So currently, warning should be disabled.
1558 //
1559 //ActionMessage.warning(this,
1560 // "In module " + moduleName + " exist more than one PCD token " + token.cName
1561 // );
1562 return null;
1563 }
1564
1565 //
1566 // BUGBUG: following code could be enabled at current schema. Because
1567 // current schema does not provide usage information.
1568 //
1569 // For FEATRURE_FLAG, FIXED_AT_BUILD, PATCH_IN_MODULE type PCD token, his
1570 // usage is always ALWAYS_CONSUMED
1571 //
1572 //if((pcdType != Token.PCD_TYPE.DYNAMIC) &&
1573 // (pcdType != Token.PCD_TYPE.DYNAMIC_EX)) {
1574 pcdUsage = Token.PCD_USAGE.ALWAYS_CONSUMED;
1575 //}
1576
1577 usageInstance = new UsageInstance(token,
1578 pcdUsage,
1579 pcdType,
1580 CommonDefinition.getComponentType(SurfaceAreaQuery.getComponentType()),
1581 tokenInfoInMsa[3],
1582 null,
1583 (String) tokenInfoInMsa[5],
1584 "",
1585 moduleName,
1586 packageName,
1587 false);
1588
1589 //
1590 // Use default value defined in MSA to update datum of token,
1591 // if datum of token does not defined in FPD file.
1592 //
1593 if((token.datum == null) &&(tokenInfoInMsa[3] != null)) {
1594 token.datum = tokenInfoInMsa[3];
1595 }
1596
1597 token.addUsageInstance(usageInstance);
1598
1599 return usageInstance;
1600 }
1601
1602 /**
1603 Create token instance object into memory database, the token information
1604 comes for FPD file. Normally, FPD file will contain all token platform
1605 informations.
1606
1607 This fucntion should be executed at firsly before others collection work
1608 such as searching token information from MSA, SPD.
1609
1610 @return FrameworkPlatformDescriptionDocument The FPD document instance for furture usage.
1611
1612 @throws EntityException Failed to parse FPD xml file.
1613
1614 **/
1615 private FrameworkPlatformDescriptionDocument createTokenInDBFromFPD()
1616 throws EntityException {
1617 XmlObject doc = null;
1618 FrameworkPlatformDescriptionDocument fpdDoc = null;
1619 int index = 0;
1620 List<PcdBuildData> pcdBuildDataArray = new ArrayList<PcdBuildData>();
1621 PcdBuildData pcdBuildData = null;
1622 Token token = null;
1623 UUID nullUUID = new UUID(0,0);
1624 UUID platformTokenSpace= nullUUID;
1625 List skuDataArray = new ArrayList();
1626 SkuInstance skuInstance = null;
1627 int skuIndex = 0;
1628
1629 //
1630 // Get all tokens from FPD file and create token into database.
1631 //
1632
1633 try {
1634 doc = XmlObject.Factory.parse(new File(fpdFilePath));
1635 } catch(IOException ioE) {
1636 throw new EntityException("Can't find the FPD xml fle:" + fpdFilePath);
1637 } catch(XmlException xmlE) {
1638 throw new EntityException("Can't parse the FPD xml fle:" + fpdFilePath);
1639 }
1640
1641 //
1642 // Get memoryDatabaseManager instance from GlobalData.
1643 //
1644 if((dbManager = GlobalData.getPCDMemoryDBManager()) == null) {
1645 throw new EntityException("The instance of PCD memory database manager is null");
1646 }
1647
1648 dbManager = new MemoryDatabaseManager();
1649
1650 if(!(doc instanceof FrameworkPlatformDescriptionDocument)) {
1651 throw new EntityException("File " + fpdFilePath +
1652 " is not a FrameworkPlatformDescriptionDocument");
1653 }
1654
1655 fpdDoc =(FrameworkPlatformDescriptionDocument)doc;
1656
1657 //
1658 // Add all tokens in FPD into Memory Database.
1659 //
1660 pcdBuildDataArray =
1661 fpdDoc.getFrameworkPlatformDescription().getPcdBuildDeclarations().getPcdBuildDataList();
1662 for(index = 0;
1663 index < fpdDoc.getFrameworkPlatformDescription().getPcdBuildDeclarations().sizeOfPcdBuildDataArray();
1664 index ++) {
1665 pcdBuildData = pcdBuildDataArray.get(index);
1666 token = new Token(pcdBuildData.getCName(), new UUID(0, 0), new UUID(0, 0));
1667 //
1668 // BUGBUG: in FPD, <defaultValue> should be defined as <Value>
1669 //
1670 token.datum = pcdBuildData.getDefaultValue();
1671 token.tokenNumber = Integer.decode(pcdBuildData.getToken().getStringValue());
1672 token.hiiEnabled = pcdBuildData.getHiiEnable();
1673 token.variableGuid = Token.getGUIDFromSchemaObject(pcdBuildData.getVariableGuid());
1674 token.variableName = pcdBuildData.getVariableName();
1675 token.variableOffset = Integer.decode(pcdBuildData.getDataOffset());
1676 token.skuEnabled = pcdBuildData.getSkuEnable();
1677 token.maxSkuCount = Integer.decode(pcdBuildData.getMaxSku());
1678 token.skuId = Integer.decode(pcdBuildData.getSkuId());
1679 token.skuDataArrayEnabled = pcdBuildData.getSkuDataArrayEnable();
1680 token.assignedtokenNumber = Integer.decode(pcdBuildData.getToken().getStringValue());
1681 skuDataArray = pcdBuildData.getSkuDataArray1();
1682 token.datumType = Token.getdatumTypeFromString(pcdBuildData.getDatumType().toString());
1683 token.datumSize = pcdBuildData.getDatumSize();
1684
1685 if(skuDataArray != null) {
1686 for(skuIndex = 0; skuIndex < skuDataArray.size(); skuIndex ++) {
1687 //
1688 // BUGBUG: Now in current schema, The value is defined as String type,
1689 // it is not correct, the type should be same as the datumType
1690 //
1691 skuInstance = new SkuInstance(((PcdBuildData.SkuData)skuDataArray.get(skuIndex)).getId(),
1692 ((PcdBuildData.SkuData)skuDataArray.get(skuIndex)).getValue());
1693 token.skuData.add(skuInstance);
1694 }
1695 }
1696
1697 if(dbManager.isTokenInDatabase(Token.getPrimaryKeyString(token.cName,
1698 token.tokenSpaceName,
1699 platformTokenSpace))) {
1700 //
1701 // If found duplicate token, Should tool be hold?
1702 //
1703 ActionMessage.warning(this,
1704 "Token " + token.cName + " exists in token database");
1705 continue;
1706 }
1707 token.pcdType = Token.getpcdTypeFromString(pcdBuildData.getItemType().toString());
1708 dbManager.addTokenToDatabase(Token.getPrimaryKeyString(token.cName,
1709 token.tokenSpaceName,
1710 platformTokenSpace),
1711 token);
1712 }
1713
1714 return fpdDoc;
1715 }
1716
1717 /**
1718 Update PCD token in memory database by help information in SPD.
1719
1720 After create token from FPD and create usage instance from MSA, we should collect
1721 PCD package level information from SPD and update token information in memory
1722 database.
1723
1724 @param usageInstance The usage instance defined in MSA and want to search in SPD.
1725 @param packageFullPath The SPD file path.
1726
1727 @throws EntityException Failed to parse SPD xml file.
1728
1729 **/
1730 private void updateTokenBySPD(UsageInstance usageInstance,
1731 String packageFullPath)
1732 throws EntityException {
1733 PackageSurfaceAreaDocument pkgDoc = null;
1734 PcdDefinitions pcdDefinitions = null;
1735 List<PcdDefinitions.PcdEntry> pcdEntryArray = new ArrayList<PcdDefinitions.PcdEntry>();
1736 int index = 0;
1737 boolean isFoundInSpd = false;
1738 Token.DATUM_TYPE datumType = Token.DATUM_TYPE.UNKNOWN;
1739
1740 try {
1741 pkgDoc =(PackageSurfaceAreaDocument)XmlObject.Factory.parse(new File(packageFullPath));
1742 } catch(IOException ioE) {
1743 throw new EntityException("Can't find the FPD xml fle:" + packageFullPath);
1744 } catch(XmlException xmlE) {
1745 throw new EntityException("Can't parse the FPD xml fle:" + packageFullPath);
1746 }
1747 pcdDefinitions = pkgDoc.getPackageSurfaceArea().getPcdDefinitions();
1748 //
1749 // It is illege for SPD file does not contains any PCD information.
1750 //
1751 if (pcdDefinitions == null) {
1752 return;
1753 }
1754
1755 pcdEntryArray = pcdDefinitions.getPcdEntryList();
1756 if (pcdEntryArray == null) {
1757 return;
1758 }
1759 for(index = 0; index < pcdEntryArray.size(); index ++) {
1760 if(pcdEntryArray.get(index).getCName().equalsIgnoreCase(
1761 usageInstance.parentToken.cName)) {
1762 isFoundInSpd = true;
1763 //
1764 // From SPD file , we can get following information.
1765 // Token: Token number defined in package level.
1766 // PcdItemType: This item does not single one. It means all supported item type.
1767 // datumType: UINT8, UNIT16, UNIT32, UINT64, VOID*, BOOLEAN
1768 // datumSize: The size of default value or maxmine size.
1769 // defaultValue: This value is defined in package level.
1770 // HelpText: The help text is provided in package level.
1771 //
1772
1773 usageInstance.parentToken.tokenNumber = Integer.decode(pcdEntryArray.get(index).getToken());
1774
1775 if(pcdEntryArray.get(index).getDatumType() != null) {
1776 datumType = Token.getdatumTypeFromString(
1777 pcdEntryArray.get(index).getDatumType().toString());
1778 if(usageInstance.parentToken.datumType == Token.DATUM_TYPE.UNKNOWN) {
1779 usageInstance.parentToken.datumType = datumType;
1780 } else {
1781 if(datumType != usageInstance.parentToken.datumType) {
1782 throw new EntityException("Different datum types are defined for Token :" +
1783 usageInstance.parentToken.cName);
1784 }
1785 }
1786
1787 } else {
1788 throw new EntityException("The datum type for token " + usageInstance.parentToken.cName +
1789 " is not defind in SPD file " + packageFullPath);
1790 }
1791
1792 usageInstance.defaultValueInSPD = pcdEntryArray.get(index).getDefaultValue();
1793 usageInstance.helpTextInSPD = "Help Text in SPD";
1794
1795 //
1796 // If token's datum is not valid, it indicate that datum is not provided
1797 // in FPD and defaultValue is not provided in MSA, then use defaultValue
1798 // in SPD as the datum of token.
1799 //
1800 if(usageInstance.parentToken.datum == null) {
1801 if(pcdEntryArray.get(index).getDefaultValue() != null) {
1802 usageInstance.parentToken.datum = pcdEntryArray.get(index).getDefaultValue();
1803 } else {
1804 throw new EntityException("FPD does not provide datum for token " + usageInstance.parentToken.cName +
1805 ", MSA and SPD also does not provide <defaultValue> for this token!");
1806 }
1807 }
1808 }
1809 }
1810 }
1811
1812 /**
1813 check parameter for this action.
1814
1815 @throws EntityException Bad parameter.
1816 **/
1817 private void checkParameter() throws EntityException {
1818 File file = null;
1819
1820 if((fpdFilePath == null) ||(workspacePath == null)) {
1821 throw new EntityException("WorkspacePath and FPDFileName should be blank for CollectPCDAtion!");
1822 }
1823
1824 if(fpdFilePath.length() == 0 || workspacePath.length() == 0) {
1825 throw new EntityException("WorkspacePath and FPDFileName should be blank for CollectPCDAtion!");
1826 }
1827
1828 file = new File(workspacePath);
1829 if(!file.exists()) {
1830 throw new EntityException("WorkpacePath " + workspacePath + " does not exist!");
1831 }
1832
1833 file = new File(fpdFilePath);
1834
1835 if(!file.exists()) {
1836 throw new EntityException("FPD File " + fpdFilePath + " does not exist!");
1837 }
1838 }
1839
1840 /**
1841 Test case function
1842
1843 @param argv parameter from command line
1844 **/
1845 public static void main(String argv[]) throws EntityException {
1846 CollectPCDAction ca = new CollectPCDAction();
1847 ca.setWorkspacePath("G:/mdk");
1848 ca.setFPDFilePath("G:/mdk/EdkNt32Pkg/build/Nt32.fpd");
1849 ca.setActionMessageLevel(ActionMessage.MAX_MESSAGE_LEVEL);
1850 GlobalData.initInfo("Tools" + File.separator + "Conf" + File.separator + "FrameworkDatabase.db",
1851 "G:/mdk");
1852 ca.execute();
1853 }
1854 }