]> git.proxmox.com Git - mirror_edk2.git/blob - Tools/Source/GenBuild/org/tianocore/build/pcd/action/CollectPCDAction.java
Add many datum and datum size checking in PCD building tools, These checking work...
[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.math.BigInteger;
25 import java.util.ArrayList;
26 import java.util.Collections;
27 import java.util.Comparator;
28 import java.util.HashMap;
29 import java.util.List;
30 import java.util.Map;
31 import java.util.UUID;
32
33 import org.apache.xmlbeans.XmlException;
34 import org.apache.xmlbeans.XmlObject;
35 import org.tianocore.DynamicPcdBuildDefinitionsDocument;
36 import org.tianocore.DynamicPcdBuildDefinitionsDocument.DynamicPcdBuildDefinitions;
37 import org.tianocore.DynamicPcdBuildDefinitionsDocument.DynamicPcdBuildDefinitions.PcdBuildData;
38 import org.tianocore.DynamicPcdBuildDefinitionsDocument.DynamicPcdBuildDefinitions.PcdBuildData.SkuInfo;
39 import org.tianocore.FrameworkModulesDocument;
40 import org.tianocore.FrameworkPlatformDescriptionDocument;
41 import org.tianocore.FrameworkPlatformDescriptionDocument.FrameworkPlatformDescription;
42 import org.tianocore.ModuleSADocument;
43 import org.tianocore.ModuleSADocument.ModuleSA;
44 import org.tianocore.PackageSurfaceAreaDocument;
45 import org.tianocore.PcdBuildDefinitionDocument.PcdBuildDefinition;
46 import org.tianocore.build.global.GlobalData;
47 import org.tianocore.build.global.SurfaceAreaQuery;
48 import org.tianocore.build.pcd.action.ActionMessage;
49 import org.tianocore.build.pcd.entity.DynamicTokenValue;
50 import org.tianocore.build.pcd.entity.MemoryDatabaseManager;
51 import org.tianocore.build.pcd.entity.SkuInstance;
52 import org.tianocore.build.pcd.entity.Token;
53 import org.tianocore.build.pcd.entity.UsageInstance;
54 import org.tianocore.build.pcd.exception.EntityException;
55
56 class StringTable {
57 private ArrayList<String> al;
58 private ArrayList<String> alComments;
59 private String phase;
60 int len;
61 int bodyStart;
62 int bodyLineNum;
63
64 public StringTable (String phase) {
65 this.phase = phase;
66 al = new ArrayList<String>();
67 alComments = new ArrayList<String>();
68 len = 0;
69 bodyStart = 0;
70 bodyLineNum = 0;
71 }
72
73 public String getSizeMacro () {
74 return String.format(PcdDatabase.StringTableSizeMacro, phase, getSize());
75 }
76
77 private int getSize () {
78 //
79 // We have at least one Unicode Character in the table.
80 //
81 return len == 0 ? 1 : len;
82 }
83
84 public int getTableLen () {
85 return al.size() == 0 ? 1 : al.size();
86 }
87
88 public String getExistanceMacro () {
89 return String.format(PcdDatabase.StringTableExistenceMacro, phase, (al.size() == 0)? "TRUE":"FALSE");
90 }
91
92 public String getTypeDeclaration () {
93
94 String output;
95
96 final String stringTable = "StringTable";
97 final String tab = "\t";
98 final String newLine = ";\r\n";
99
100 output = "/* StringTable */\r\n";
101
102 if (al.size() == 0) {
103 output += tab + String.format("UINT16 %s[1] /* StringTable is Empty */", stringTable) + newLine;
104 }
105
106 for (int i = 0; i < al.size(); i++) {
107 String str = al.get(i);
108
109 if (i == 0) {
110 //
111 // StringTable is a well-known name in the PCD DXE driver
112 //
113 output += tab + String.format("UINT16 %s[%d] /* %s */", stringTable, str.length() + 1, alComments.get(i)) + newLine;
114 } else {
115 output += tab + String.format("UINT16 %s_%d[%d] /* %s */", stringTable, i, str.length() + 1, alComments.get(i)) + newLine;
116 }
117 }
118
119 return output;
120
121 }
122
123 public ArrayList<String> getInstantiation () {
124 ArrayList<String> output = new ArrayList<String>();
125
126 output.add("/* StringTable */");
127
128 if (al.size() == 0) {
129 output.add("{ 0 }");
130 } else {
131 String str;
132
133 for (int i = 0; i < al.size(); i++) {
134 str = String.format("L\"%s\" /* %s */", al.get(i), alComments.get(i));
135 if (i != al.size() - 1) {
136 str += ",";
137 }
138 output.add(str);
139 }
140 }
141
142 return output;
143 }
144
145 public int add (String str, Token token) {
146 int i;
147
148 i = len;
149 //
150 // Include the NULL character at the end of String
151 //
152 len += str.length() + 1;
153 al.add(str);
154 alComments.add(token.getPrimaryKeyString());
155
156 return i;
157 }
158 }
159
160 class SizeTable {
161 private ArrayList<Integer> al;
162 private ArrayList<String> alComments;
163 private String phase;
164 private int len;
165 private int bodyStart;
166 private int bodyLineNum;
167
168 public SizeTable (String phase) {
169 this.phase = phase;
170 al = new ArrayList<Integer>();
171 alComments = new ArrayList<String>();
172 len = 0;
173 bodyStart = 0;
174 bodyLineNum = 0;
175 }
176
177 public String getTypeDeclaration () {
178 return String.format(PcdDatabase.SizeTableDeclaration, phase);
179 }
180
181 public ArrayList<String> getInstantiation () {
182 ArrayList<String> Output = new ArrayList<String>();
183
184 Output.add("/* SizeTable */");
185 Output.add("{");
186 bodyStart = 2;
187
188 if (al.size() == 0) {
189 Output.add("0");
190 } else {
191 for (int index = 0; index < al.size(); index++) {
192 Integer n = al.get(index);
193 String str = n.toString();
194
195 if (index != (al.size() - 1)) {
196 str += ",";
197 }
198
199 str += " /* " + alComments.get(index) + " */";
200 Output.add(str);
201 bodyLineNum++;
202
203 }
204 }
205 Output.add("}");
206
207 return Output;
208 }
209
210 public int getBodyStart() {
211 return bodyStart;
212 }
213
214 public int getBodyLineNum () {
215 return bodyLineNum;
216 }
217
218 public int add (Token token) {
219 int index = len;
220
221 len++;
222 al.add(token.datumSize);
223 alComments.add(token.getPrimaryKeyString());
224
225 return index;
226 }
227
228 private int getDatumSize(Token token) {
229 /*
230 switch (token.datumType) {
231 case Token.DATUM_TYPE.UINT8:
232 return 1;
233 default:
234 return 0;
235 }
236 */
237 return 0;
238 }
239
240 public int getTableLen () {
241 return al.size() == 0 ? 1 : al.size();
242 }
243
244 }
245
246 class GuidTable {
247 private ArrayList<UUID> al;
248 private ArrayList<String> alComments;
249 private String phase;
250 private int len;
251 private int bodyStart;
252 private int bodyLineNum;
253
254 public GuidTable (String phase) {
255 this.phase = phase;
256 al = new ArrayList<UUID>();
257 alComments = new ArrayList<String>();
258 len = 0;
259 bodyStart = 0;
260 bodyLineNum = 0;
261 }
262
263 public String getSizeMacro () {
264 return String.format(PcdDatabase.GuidTableSizeMacro, phase, getSize());
265 }
266
267 private int getSize () {
268 return (al.size() == 0)? 1 : al.size();
269 }
270
271 public String getExistanceMacro () {
272 return String.format(PcdDatabase.GuidTableExistenceMacro, phase, (al.size() == 0)? "TRUE":"FALSE");
273 }
274
275 public String getTypeDeclaration () {
276 return String.format(PcdDatabase.GuidTableDeclaration, phase);
277 }
278
279 private String getUuidCString (UUID uuid) {
280 String[] guidStrArray;
281
282 guidStrArray =(uuid.toString()).split("-");
283
284 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 } }",
285 guidStrArray[0],
286 guidStrArray[1],
287 guidStrArray[2],
288 (guidStrArray[3].substring(0, 2)),
289 (guidStrArray[3].substring(2, 4)),
290 (guidStrArray[4].substring(0, 2)),
291 (guidStrArray[4].substring(2, 4)),
292 (guidStrArray[4].substring(4, 6)),
293 (guidStrArray[4].substring(6, 8)),
294 (guidStrArray[4].substring(8, 10)),
295 (guidStrArray[4].substring(10, 12))
296 );
297 }
298
299 public ArrayList<String> getInstantiation () {
300 ArrayList<String> Output = new ArrayList<String>();
301
302 Output.add("/* GuidTable */");
303 Output.add("{");
304 bodyStart = 2;
305
306 if (al.size() == 0) {
307 Output.add(getUuidCString(new UUID(0, 0)));
308 }
309
310 for (Object u : al) {
311 UUID uuid = (UUID)u;
312 String str = getUuidCString(uuid);
313
314 if (al.indexOf(u) != (al.size() - 1)) {
315 str += ",";
316 }
317 Output.add(str);
318 bodyLineNum++;
319
320 }
321 Output.add("}");
322
323 return Output;
324 }
325
326 public int getBodyStart() {
327 return bodyStart;
328 }
329
330 public int getBodyLineNum () {
331 return bodyLineNum;
332 }
333
334 public int add (UUID uuid, String name) {
335 int index = len;
336 //
337 // Include the NULL character at the end of String
338 //
339 len++;
340 al.add(uuid);
341
342 return index;
343 }
344
345 public int getTableLen () {
346 return al.size() == 0 ? 0 : al.size();
347 }
348
349 }
350
351 class SkuIdTable {
352 private ArrayList<Integer[]> al;
353 private ArrayList<String> alComment;
354 private String phase;
355 private int len;
356 private int bodyStart;
357 private int bodyLineNum;
358
359 public SkuIdTable (String phase) {
360 this.phase = phase;
361 al = new ArrayList<Integer[]>();
362 alComment = new ArrayList<String>();
363 bodyStart = 0;
364 bodyLineNum = 0;
365 len = 0;
366 }
367
368 public String getSizeMacro () {
369 return String.format(PcdDatabase.SkuIdTableSizeMacro, phase, getSize());
370 }
371
372 private int getSize () {
373 return (al.size() == 0)? 1 : al.size();
374 }
375
376 public String getExistanceMacro () {
377 return String.format(PcdDatabase.SkuTableExistenceMacro, phase, (al.size() == 0)? "TRUE":"FALSE");
378 }
379
380 public String getTypeDeclaration () {
381 return String.format(PcdDatabase.SkuIdTableDeclaration, phase);
382 }
383
384 public ArrayList<String> getInstantiation () {
385 ArrayList<String> Output = new ArrayList<String> ();
386
387 Output.add("/* SkuIdTable */");
388 Output.add("{");
389 bodyStart = 2;
390
391 if (al.size() == 0) {
392 Output.add("0");
393 }
394
395 for (int index = 0; index < al.size(); index++) {
396 String str;
397
398 str = "/* " + alComment.get(index) + "*/ ";
399 str += "/* MaxSku */ ";
400
401
402 Integer[] ia = al.get(index);
403
404 str += ia[0].toString() + ", ";
405 for (int index2 = 1; index2 < ia.length; index2++) {
406 str += ia[index2].toString();
407 if (index != al.size() - 1) {
408 str += ", ";
409 }
410 }
411
412 Output.add(str);
413 bodyLineNum++;
414
415 }
416
417 Output.add("}");
418
419 return Output;
420 }
421
422 public int add (Token token) {
423
424 int index;
425
426 Integer [] skuIds = new Integer[token.skuData.size() + 1];
427 skuIds[0] = new Integer(token.skuData.size());
428 for (index = 1; index < skuIds.length; index++) {
429 skuIds[index] = new Integer(token.skuData.get(index - 1).id);
430 }
431
432 index = len;
433
434 len += skuIds.length;
435 al.add(skuIds);
436 alComment.add(token.getPrimaryKeyString());
437
438 return index;
439 }
440
441 public int getTableLen () {
442 return al.size() == 0 ? 1 : al.size();
443 }
444
445 }
446
447 class LocalTokenNumberTable {
448 private ArrayList<String> al;
449 private ArrayList<String> alComment;
450 private String phase;
451 private int len;
452
453 public LocalTokenNumberTable (String phase) {
454 this.phase = phase;
455 al = new ArrayList<String>();
456 alComment = new ArrayList<String>();
457
458 len = 0;
459 }
460
461 public String getSizeMacro () {
462 return String.format(PcdDatabase.LocalTokenNumberTableSizeMacro, phase, getSize())
463 + String.format(PcdDatabase.LocalTokenNumberSizeMacro, phase, al.size());
464 }
465
466 public int getSize () {
467 return (al.size() == 0)? 1 : al.size();
468 }
469
470 public String getExistanceMacro () {
471 return String.format(PcdDatabase.DatabaseExistenceMacro, phase, (al.size() == 0)? "TRUE":"FALSE");
472 }
473
474 public String getTypeDeclaration () {
475 return String.format(PcdDatabase.LocalTokenNumberTableDeclaration, phase);
476 }
477
478 public ArrayList<String> getInstantiation () {
479 ArrayList<String> output = new ArrayList<String>();
480
481 output.add("/* LocalTokenNumberTable */");
482 output.add("{");
483
484 if (al.size() == 0) {
485 output.add("0");
486 }
487
488 for (int index = 0; index < al.size(); index++) {
489 String str;
490
491 str = (String)al.get(index);
492
493 str += " /* " + alComment.get(index) + " */ ";
494
495
496 if (index != (al.size() - 1)) {
497 str += ",";
498 }
499
500 output.add(str);
501
502 }
503
504 output.add("}");
505
506 return output;
507 }
508
509 public int add (Token token) {
510 int index = len;
511 String str;
512
513 len++;
514
515 str = String.format(PcdDatabase.offsetOfStrTemplate, phase, token.hasDefaultValue() ? "Init" : "Uninit", token.getPrimaryKeyString());
516
517 if (token.isStringType()) {
518 str += " | PCD_TYPE_STRING";
519 }
520
521 if (token.isSkuEnable()) {
522 str += " | PCD_TYPE_SKU_ENABLED";
523 }
524
525 if (token.getDefaultSku().type == DynamicTokenValue.VALUE_TYPE.HII_TYPE) {
526 str += " | PCD_TYPE_HII";
527 }
528
529 if (token.getDefaultSku().type == DynamicTokenValue.VALUE_TYPE.VPD_TYPE) {
530 str += " | PCD_TYPE_VPD";
531 }
532
533 al.add(str);
534 alComment.add(token.getPrimaryKeyString());
535
536 return index;
537 }
538 }
539
540 class ExMapTable {
541
542 class ExTriplet {
543 public Integer guidTableIdx;
544 public Long exTokenNumber;
545 public Long localTokenIdx;
546
547 public ExTriplet (int guidTableIdx, long exTokenNumber, long localTokenIdx) {
548 this.guidTableIdx = new Integer(guidTableIdx);
549 this.exTokenNumber = new Long(exTokenNumber);
550 this.localTokenIdx = new Long(localTokenIdx);
551 }
552 }
553
554 private ArrayList<ExTriplet> al;
555 private ArrayList<String> alComment;
556 private String phase;
557 private int len;
558 private int bodyStart;
559 private int bodyLineNum;
560 private int base;
561
562 public ExMapTable (String phase) {
563 this.phase = phase;
564 al = new ArrayList<ExTriplet>();
565 alComment = new ArrayList<String>();
566 bodyStart = 0;
567 bodyLineNum = 0;
568 len = 0;
569 }
570
571 public String getSizeMacro () {
572 return String.format(PcdDatabase.ExMapTableSizeMacro, phase, getTableLen())
573 + String.format(PcdDatabase.ExTokenNumber, phase, al.size());
574 }
575
576 private int getSize () {
577 return (al.size() == 0)? 1 : al.size();
578 }
579
580 public String getExistanceMacro () {
581 return String.format(PcdDatabase.ExMapTableExistenceMacro, phase, (al.size() == 0)? "TRUE":"FALSE");
582 }
583
584 public String getTypeDeclaration () {
585 return String.format(PcdDatabase.ExMapTableDeclaration, phase);
586 }
587
588 public ArrayList<String> getInstantiation () {
589 ArrayList<String> Output = new ArrayList<String>();
590
591 Output.add("/* ExMapTable */");
592 Output.add("{");
593 bodyStart = 2;
594
595 if (al.size() == 0) {
596 Output.add("{0, 0, 0}");
597 }
598
599 int index;
600 for (index = 0; index < al.size(); index++) {
601 String str;
602
603 ExTriplet e = (ExTriplet)al.get(index);
604
605 str = "{ " + e.exTokenNumber.toString() + ", ";
606 str += e.localTokenIdx.toString() + ", ";
607 str += e.guidTableIdx.toString();
608
609 str += " /* " + alComment.get(index) + " */";
610
611 if (index != al.size() - 1) {
612 str += ",";
613 }
614
615 Output.add(str);
616 bodyLineNum++;
617
618 }
619
620 Output.add("}");
621
622 return Output;
623 }
624
625 public int add (int localTokenIdx, long exTokenNum, int guidTableIdx, String name) {
626 int index = len;
627
628 len++;
629 al.add(new ExTriplet(guidTableIdx, exTokenNum, localTokenIdx));
630 alComment.add(name);
631
632 return index;
633 }
634
635 public int getTableLen () {
636 return al.size() == 0 ? 1 : al.size();
637 }
638
639 }
640
641 class PcdDatabase {
642
643 public final static String ExMapTableDeclaration = "DYNAMICEX_MAPPING ExMapTable[%s_EXMAPPING_TABLE_SIZE];\r\n";
644 public final static String GuidTableDeclaration = "EFI_GUID GuidTable[%s_GUID_TABLE_SIZE];\r\n";
645 public final static String LocalTokenNumberTableDeclaration = "UINT32 LocalTokenNumberTable[%s_LOCAL_TOKEN_NUMBER_TABLE_SIZE];\r\n";
646 public final static String StringTableDeclaration = "UINT16 StringTable[%s_STRING_TABLE_SIZE];\r\n";
647 public final static String SizeTableDeclaration = "UINT16 SizeTable[%s_LOCAL_TOKEN_NUMBER_TABLE_SIZE];\r\n";
648 public final static String SkuIdTableDeclaration = "UINT8 SkuIdTable[%s_SKUID_TABLE_SIZE];\r\n";
649
650
651 public final static String ExMapTableSizeMacro = "#define %s_EXMAPPING_TABLE_SIZE %d\r\n";
652 public final static String ExTokenNumber = "#define %s_EX_TOKEN_NUMBER %d\r\n";
653 public final static String GuidTableSizeMacro = "#define %s_GUID_TABLE_SIZE %d\r\n";
654 public final static String LocalTokenNumberTableSizeMacro = "#define %s_LOCAL_TOKEN_NUMBER_TABLE_SIZE %d\r\n";
655 public final static String LocalTokenNumberSizeMacro = "#define %s_LOCAL_TOKEN_NUMBER %d\r\n";
656 public final static String StringTableSizeMacro = "#define %s_STRING_TABLE_SIZE %d\r\n";
657 public final static String SkuIdTableSizeMacro = "#define %s_SKUID_TABLE_SIZE %d\r\n";
658
659
660 public final static String ExMapTableExistenceMacro = "#define %s_EXMAP_TABLE_EMPTY %s\r\n";
661 public final static String GuidTableExistenceMacro = "#define %s_GUID_TABLE_EMPTY %s\r\n";
662 public final static String DatabaseExistenceMacro = "#define %s_DATABASE_EMPTY %s\r\n";
663 public final static String StringTableExistenceMacro = "#define %s_STRING_TABLE_EMPTY %s\r\n";
664 public final static String SkuTableExistenceMacro = "#define %s_SKUID_TABLE_EMPTY %s\r\n";
665
666 public final static String offsetOfSkuHeadStrTemplate = "offsetof(%s_PCD_DATABASE, %s.%s_SkuDataTable)";
667 public final static String offsetOfStrTemplate = "offsetof(%s_PCD_DATABASE, %s.%s)";
668
669 private StringTable stringTable;
670 private GuidTable guidTable;
671 private LocalTokenNumberTable localTokenNumberTable;
672 private SkuIdTable skuIdTable;
673 private SizeTable sizeTable;
674 private ExMapTable exMapTable;
675
676 private ArrayList<Token> alTokens;
677 private String phase;
678 private int assignedTokenNumber;
679
680 //
681 // After Major changes done to the PCD
682 // database generation class PcdDatabase
683 // Please increment the version and please
684 // also update the version number in PCD
685 // service PEIM and DXE driver accordingly.
686 //
687 private final int version = 1;
688
689 private String hString;
690 private String cString;
691
692
693 class AlignmentSizeComp implements Comparator<Token> {
694 public int compare (Token a, Token b) {
695 return getAlignmentSize(b)
696 - getAlignmentSize(a);
697 }
698 }
699
700 public PcdDatabase (ArrayList<Token> alTokens, String exePhase, int startLen) {
701 phase = exePhase;
702
703 stringTable = new StringTable(phase);
704 guidTable = new GuidTable(phase);
705 localTokenNumberTable = new LocalTokenNumberTable(phase);
706 skuIdTable = new SkuIdTable(phase);
707 sizeTable = new SizeTable(phase);
708 exMapTable = new ExMapTable(phase);
709
710 assignedTokenNumber = startLen;
711 this.alTokens = alTokens;
712 }
713
714 private void getTwoGroupsOfTokens (ArrayList<Token> alTokens, List<Token> initTokens, List<Token> uninitTokens) {
715 for (int i = 0; i < alTokens.size(); i++) {
716 Token t = (Token)alTokens.get(i);
717 if (t.hasDefaultValue()) {
718 initTokens.add(t);
719 } else {
720 uninitTokens.add(t);
721 }
722 }
723
724 return;
725 }
726
727 private int getAlignmentSize (Token token) {
728 if (token.getDefaultSku().type == DynamicTokenValue.VALUE_TYPE.HII_TYPE) {
729 return 2;
730 }
731
732 if (token.getDefaultSku().type == DynamicTokenValue.VALUE_TYPE.VPD_TYPE) {
733 return 4;
734 }
735
736 if (token.isStringType()) {
737 return 2;
738 }
739
740 switch (token.datumType) {
741 case UINT8:
742 return 1;
743 case UINT16:
744 return 2;
745 case UINT32:
746 return 4;
747 case UINT64:
748 return 8;
749 case POINTER:
750 return 1;
751 case BOOLEAN:
752 return 1;
753 }
754 return 1;
755 }
756
757 public String getCString () {
758 return cString;
759 }
760
761 public String getHString () {
762 return hString;
763 }
764
765 public void genCode ()
766 throws EntityException {
767
768 final String newLine = "\r\n";
769 final String declNewLine = ";\r\n";
770 final String tab = "\t";
771 final String commaNewLine = ", \r\n";
772
773 int i;
774 ArrayList<String> decla;
775 ArrayList<String> inst;
776
777 String macroStr = "";
778 String initDeclStr = "";
779 String initInstStr = "";
780 String uninitDeclStr = "";
781
782 List<Token> initTokens = new ArrayList<Token> ();
783 List<Token> uninitTokens = new ArrayList<Token> ();
784
785 HashMap <String, ArrayList<String>> initCode = new HashMap<String, ArrayList<String>> ();
786 HashMap <String, ArrayList<String>> uninitCode = new HashMap<String, ArrayList<String>> ();
787
788 getTwoGroupsOfTokens (alTokens, initTokens, uninitTokens);
789
790 //
791 // Generate Structure Declaration for PcdTokens without Default Value
792 // PEI_PCD_DATABASE_INIT
793 //
794 java.util.Comparator<Token> comparator = new AlignmentSizeComp();
795 java.util.Collections.sort(initTokens, comparator);
796 initCode = processTokens(initTokens);
797
798 //
799 // Generate Structure Declaration for PcdTokens without Default Value
800 // PEI_PCD_DATABASE_UNINIT
801 //
802 java.util.Collections.sort(uninitTokens, comparator);
803 uninitCode = processTokens(uninitTokens);
804
805 //
806 // Generate size info Macro for all Tables
807 //
808 macroStr += guidTable.getSizeMacro();
809 macroStr += stringTable.getSizeMacro();
810 macroStr += skuIdTable.getSizeMacro();
811 macroStr += localTokenNumberTable.getSizeMacro();
812 macroStr += exMapTable.getSizeMacro();
813
814 //
815 // Generate existance info Macro for all Tables
816 //
817 macroStr += guidTable.getExistanceMacro();
818 macroStr += stringTable.getExistanceMacro();
819 macroStr += skuIdTable.getExistanceMacro();
820 macroStr += localTokenNumberTable.getExistanceMacro();
821 macroStr += exMapTable.getExistanceMacro();
822
823 //
824 // Generate Structure Declaration for PcdTokens with Default Value
825 // for example PEI_PCD_DATABASE_INIT
826 //
827 initDeclStr += "typedef struct {" + newLine;
828 {
829 initDeclStr += tab + exMapTable.getTypeDeclaration();
830 initDeclStr += tab + guidTable.getTypeDeclaration();
831 initDeclStr += tab + localTokenNumberTable.getTypeDeclaration();
832 initDeclStr += tab + stringTable.getTypeDeclaration();
833 initDeclStr += tab + sizeTable.getTypeDeclaration();
834 initDeclStr += tab + skuIdTable.getTypeDeclaration();
835 if (phase.equalsIgnoreCase("PEI")) {
836 initDeclStr += tab + "SKU_ID SystemSkuId;" + newLine;
837 }
838
839 decla = initCode.get(new String("Declaration"));
840 for (i = 0; i < decla.size(); i++) {
841 initDeclStr += tab + decla.get(i) + declNewLine;
842 }
843
844 //
845 // Generate Structure Declaration for PcdToken with SkuEnabled
846 //
847 decla = initCode.get("DeclarationForSku");
848
849 for (i = 0; i < decla.size(); i++) {
850 initDeclStr += tab + decla.get(i) + declNewLine;
851 }
852 }
853 initDeclStr += String.format("} %s_PCD_DATABASE_INIT;\r\n\r\n", phase);
854
855 //
856 // Generate MACRO for structure intialization of PCDTokens with Default Value
857 // The sequence must match the sequence of declaration of the memembers in the structure
858 String tmp = String.format("%s_PCD_DATABASE_INIT g%sPcdDbInit = { ", phase.toUpperCase(), phase.toUpperCase());
859 initInstStr += tmp + newLine;
860 initInstStr += tab + genInstantiationStr(exMapTable.getInstantiation()) + commaNewLine;
861 initInstStr += tab + genInstantiationStr(guidTable.getInstantiation()) + commaNewLine;
862 initInstStr += tab + genInstantiationStr(localTokenNumberTable.getInstantiation()) + commaNewLine;
863 initInstStr += tab + genInstantiationStr(stringTable.getInstantiation()) + commaNewLine;
864 initInstStr += tab + genInstantiationStr(sizeTable.getInstantiation()) + commaNewLine;
865 initInstStr += tab + genInstantiationStr(skuIdTable.getInstantiation()) + commaNewLine;
866 //
867 // For SystemSkuId
868 //
869 if (phase.equalsIgnoreCase("PEI")) {
870 initInstStr += tab + "0" + tab + "/* SystemSkuId */" + commaNewLine;
871 }
872
873 inst = initCode.get("Instantiation");
874 for (i = 0; i < inst.size(); i++) {
875 initInstStr += tab + inst.get(i) + commaNewLine;
876 }
877
878 inst = initCode.get("InstantiationForSku");
879 for (i = 0; i < inst.size(); i++) {
880 initInstStr += tab + inst.get(i);
881 if (i != inst.size() - 1) {
882 initInstStr += commaNewLine;
883 }
884 }
885
886 initInstStr += "};";
887
888 uninitDeclStr += "typedef struct {" + newLine;
889 {
890 decla = uninitCode.get("Declaration");
891 if (decla.size() == 0) {
892 uninitDeclStr += "UINT8 dummy /* The UINT struct is empty */" + declNewLine;
893 } else {
894
895 for (i = 0; i < decla.size(); i++) {
896 uninitDeclStr += tab + decla.get(i) + declNewLine;
897 }
898
899 decla = uninitCode.get("DeclarationForSku");
900
901 for (i = 0; i < decla.size(); i++) {
902 uninitDeclStr += tab + decla.get(i) + declNewLine;
903 }
904 }
905 }
906 uninitDeclStr += String.format("} %s_PCD_DATABASE_UNINIT;\r\n\r\n", phase);
907
908 cString = initInstStr + newLine;
909 hString = macroStr + newLine
910 + initDeclStr + newLine
911 + uninitDeclStr + newLine
912 + newLine;
913
914 hString += String.format("#define PCD_%s_SERVICE_DRIVER_VERSION %d", phase, version);
915
916 }
917
918 private String genInstantiationStr (ArrayList<String> alStr) {
919 String str = "";
920 for (int i = 0; i< alStr.size(); i++) {
921 str += "\t" + alStr.get(i);
922 if (i != alStr.size() - 1) {
923 str += "\r\n";
924 }
925 }
926
927 return str;
928 }
929
930 private HashMap<String, ArrayList<String>> processTokens (List<Token> alToken)
931 throws EntityException {
932
933 HashMap <String, ArrayList<String>> map = new HashMap<String, ArrayList<String>>();
934
935 ArrayList<String> decl = new ArrayList<String>();
936 ArrayList<String> declForSkuEnableType = new ArrayList<String>();
937 ArrayList<String> inst = new ArrayList<String>();
938 ArrayList<String> instForSkuEnableType = new ArrayList<String>();
939
940 for (int index = 0; index < alToken.size(); index++) {
941 Token token = alToken.get(index);
942
943 if (token.isSkuEnable()) {
944 //
945 // BugBug: Schema only support Data type now
946 //
947 int tableIdx;
948
949 tableIdx = skuIdTable.add(token);
950
951 decl.add(getSkuEnabledTypeDeclaration(token));
952 if (token.hasDefaultValue()) {
953 inst.add(getSkuEnabledTypeInstantiaion(token, tableIdx));
954 }
955
956 declForSkuEnableType.add(getDataTypeDeclarationForSkuEnabled(token));
957 if (token.hasDefaultValue()) {
958 instForSkuEnableType.add(getDataTypeInstantiationForSkuEnabled(token));
959 }
960
961 } else {
962 if (token.getDefaultSku().type == DynamicTokenValue.VALUE_TYPE.HII_TYPE) {
963 decl.add(getVariableEnableTypeDeclaration(token));
964 inst.add(getVariableEnableInstantiation(token));
965 } else if (token.getDefaultSku().type == DynamicTokenValue.VALUE_TYPE.VPD_TYPE) {
966 decl.add(getVpdEnableTypeDeclaration(token));
967 inst.add(getVpdEnableTypeInstantiation(token));
968 } else if (token.isStringType()) {
969 decl.add(getStringTypeDeclaration(token));
970 inst.add(getStringTypeInstantiation(stringTable.add(token.getStringTypeString(), token), token));
971 }
972 else {
973 decl.add(getDataTypeDeclaration(token));
974 if (token.hasDefaultValue()) {
975 inst.add(getDataTypeInstantiation(token));
976 }
977 }
978 }
979
980 sizeTable.add(token);
981 localTokenNumberTable.add(token);
982 token.tokenNumber = assignedTokenNumber++;
983
984 }
985
986 map.put("Declaration", decl);
987 map.put("DeclarationForSku", declForSkuEnableType);
988 map.put("Instantiation", inst);
989 map.put("InstantiationForSku", instForSkuEnableType);
990
991 return map;
992 }
993
994 private String getSkuEnabledTypeDeclaration (Token token) {
995 return String.format("SKU_HEAD %s;\r\n", token.getPrimaryKeyString());
996 }
997
998 private String getSkuEnabledTypeInstantiaion (Token token, int SkuTableIdx) {
999
1000 String offsetof = String.format(PcdDatabase.offsetOfSkuHeadStrTemplate, phase, token.hasDefaultValue()? "Init" : "Uninit", token.getPrimaryKeyString());
1001 return String.format("{ %s, %d }", offsetof, SkuTableIdx);
1002 }
1003
1004 private String getDataTypeDeclarationForSkuEnabled (Token token) {
1005 String typeStr = "";
1006
1007 if (token.datumType == Token.DATUM_TYPE.UINT8) {
1008 typeStr = "UINT8 %s_%s[%d];\r\n";
1009 } else if (token.datumType == Token.DATUM_TYPE.UINT16) {
1010 typeStr = "UINT16 %s_%s[%d];\r\n";
1011 } else if (token.datumType == Token.DATUM_TYPE.UINT32) {
1012 typeStr = "UINT32 %s_%s[%d];\r\n";
1013 } else if (token.datumType == Token.DATUM_TYPE.UINT64) {
1014 typeStr = "UINT64 %s_%s[%d];\r\n";
1015 } else if (token.datumType == Token.DATUM_TYPE.BOOLEAN) {
1016 typeStr = "BOOLEAN %s_%s[%d];\r\n";
1017 } else if (token.datumType == Token.DATUM_TYPE.POINTER) {
1018 return String.format("UINT8 %s_%s[%d];\r\n", token.getPrimaryKeyString(), "SkuDataTable", token.datumSize * token.skuData.size());
1019 }
1020
1021 return String.format(typeStr, token.getPrimaryKeyString(), "SkuDataTable", token.skuData.size());
1022
1023 }
1024
1025 private String getDataTypeInstantiationForSkuEnabled (Token token) {
1026 String str = "";
1027
1028 if (token.datumType == Token.DATUM_TYPE.POINTER) {
1029 return String.format("UINT8 %s_%s[%d]", token.getPrimaryKeyString(), "SkuDataTable", token.datumSize * token.skuData.size());
1030 } else {
1031 str = "{ ";
1032 for (int idx = 0; idx < token.skuData.size(); idx++) {
1033 str += token.skuData.get(idx).toString();
1034 if (idx != token.skuData.size() - 1) {
1035 str += ", ";
1036 }
1037 }
1038 str += "}";
1039
1040 return str;
1041 }
1042
1043 }
1044
1045 private String getDataTypeInstantiation (Token token) {
1046
1047 if (token.datumType == Token.DATUM_TYPE.POINTER) {
1048 return String.format("%s /* %s */", token.getDefaultSku().value, token.getPrimaryKeyString());
1049 } else {
1050 return String.format("%s /* %s */", token.getDefaultSku().value, token.getPrimaryKeyString());
1051 }
1052 }
1053
1054
1055 private String getDataTypeDeclaration (Token token) {
1056
1057 String typeStr = "";
1058
1059 if (token.datumType == Token.DATUM_TYPE.UINT8) {
1060 typeStr = "UINT8";
1061 } else if (token.datumType == Token.DATUM_TYPE.UINT16) {
1062 typeStr = "UINT16";
1063 } else if (token.datumType == Token.DATUM_TYPE.UINT32) {
1064 typeStr = "UINT32";
1065 } else if (token.datumType == Token.DATUM_TYPE.UINT64) {
1066 typeStr = "UINT64";
1067 } else if (token.datumType == Token.DATUM_TYPE.BOOLEAN) {
1068 typeStr = "BOOLEAN";
1069 } else if (token.datumType == Token.DATUM_TYPE.POINTER) {
1070 return String.format("UINT8 %s[%d]", token.getPrimaryKeyString(), token.datumSize);
1071 } else {
1072 }
1073
1074 return String.format("%s %s", typeStr, token.getPrimaryKeyString());
1075 }
1076
1077 private String getVpdEnableTypeDeclaration (Token token) {
1078 return String.format("VPD_HEAD %s", token.getPrimaryKeyString());
1079 }
1080
1081 private String getVpdEnableTypeInstantiation (Token token) {
1082 return String.format("{ %s } /* %s */", token.getDefaultSku().vpdOffset,
1083 token.getPrimaryKeyString());
1084 }
1085
1086 private String getStringTypeDeclaration (Token token) {
1087 return String.format("UINT16 %s", token.getPrimaryKeyString());
1088 }
1089
1090 private String getStringTypeInstantiation (int StringTableIdx, Token token) {
1091 return String.format ("%d /* %s */", StringTableIdx,
1092 token.getPrimaryKeyString());
1093 }
1094
1095
1096 private String getVariableEnableTypeDeclaration (Token token) {
1097 return String.format("VARIABLE_HEAD %s", token.getPrimaryKeyString());
1098 }
1099
1100 private String getVariableEnableInstantiation (Token token)
1101 throws EntityException {
1102 //
1103 // Need scott fix
1104 //
1105 return String.format("{ %d, %d, %s } /* %s */", guidTable.add(token.getDefaultSku().variableGuid, token.getPrimaryKeyString()),
1106 stringTable.add(token.getDefaultSku().getStringOfVariableName(), token),
1107 token.getDefaultSku().variableOffset,
1108 token.getPrimaryKeyString());
1109 }
1110
1111 public int getTotalTokenNumber () {
1112 return sizeTable.getTableLen();
1113 }
1114
1115 public static String getPcdDatabaseCommonDefinitions ()
1116 throws EntityException {
1117
1118 String retStr = "";
1119 try {
1120 File file = new File(GlobalData.getWorkspacePath() + File.separator +
1121 "Tools" + File.separator +
1122 "Conf" + File.separator +
1123 "Pcd" + File.separator +
1124 "PcdDatabaseCommonDefinitions.sample");
1125 FileReader reader = new FileReader(file);
1126 BufferedReader in = new BufferedReader(reader);
1127 String str;
1128 while ((str = in.readLine()) != null) {
1129 retStr = retStr +"\r\n" + str;
1130 }
1131 } catch (Exception ex) {
1132 throw new EntityException("Fatal error when generating PcdDatabase Common Definitions");
1133 }
1134
1135 return retStr;
1136 }
1137
1138 public static String getPcdDxeDatabaseDefinitions ()
1139 throws EntityException {
1140
1141 String retStr = "";
1142 try {
1143 File file = new File(GlobalData.getWorkspacePath() + File.separator +
1144 "Tools" + File.separator +
1145 "Conf" + File.separator +
1146 "Pcd" + File.separator +
1147 "PcdDatabaseDxeDefinitions.sample");
1148 FileReader reader = new FileReader(file);
1149 BufferedReader in = new BufferedReader(reader);
1150 String str;
1151 while ((str = in.readLine()) != null) {
1152 retStr = retStr +"\r\n" + str;
1153 }
1154 } catch (Exception ex) {
1155 throw new EntityException("Fatal error when generating PcdDatabase Dxe Definitions");
1156 }
1157
1158 return retStr;
1159 }
1160
1161 public static String getPcdPeiDatabaseDefinitions ()
1162 throws EntityException {
1163
1164 String retStr = "";
1165 try {
1166 File file = new File(GlobalData.getWorkspacePath() + File.separator +
1167 "Tools" + File.separator +
1168 "Conf" + File.separator +
1169 "Pcd" + File.separator +
1170 "PcdDatabasePeiDefinitions.sample");
1171 FileReader reader = new FileReader(file);
1172 BufferedReader in = new BufferedReader(reader);
1173 String str;
1174 while ((str = in.readLine()) != null) {
1175 retStr = retStr +"\r\n" + str;
1176 }
1177 } catch (Exception ex) {
1178 throw new EntityException("Fatal error when generating PcdDatabase Pei Definitions");
1179 }
1180
1181 return retStr;
1182 }
1183
1184 }
1185
1186 class ModuleInfo {
1187 public ModuleSADocument.ModuleSA module;
1188 public UsageInstance.MODULE_TYPE type;
1189
1190 public ModuleInfo (ModuleSADocument.ModuleSA module, UsageInstance.MODULE_TYPE type) {
1191 this.module = module;
1192 this.type = type;
1193 }
1194 }
1195
1196 /** This action class is to collect PCD information from MSA, SPD, FPD xml file.
1197 This class will be used for wizard and build tools, So it can *not* inherit
1198 from buildAction or UIAction.
1199 **/
1200 public class CollectPCDAction {
1201 /// memoryDatabase hold all PCD information collected from SPD, MSA, FPD.
1202 private MemoryDatabaseManager dbManager;
1203
1204 /// Workspacepath hold the workspace information.
1205 private String workspacePath;
1206
1207 /// FPD file is the root file.
1208 private String fpdFilePath;
1209
1210 /// Message level for CollectPCDAction.
1211 private int originalMessageLevel;
1212
1213 /// Cache the fpd docment instance for private usage.
1214 private FrameworkPlatformDescriptionDocument fpdDocInstance;
1215
1216 /**
1217 Set WorkspacePath parameter for this action class.
1218
1219 @param workspacePath parameter for this action
1220 **/
1221 public void setWorkspacePath(String workspacePath) {
1222 this.workspacePath = workspacePath;
1223 }
1224
1225 /**
1226 Set action message level for CollectPcdAction tool.
1227
1228 The message should be restored when this action exit.
1229
1230 @param actionMessageLevel parameter for this action
1231 **/
1232 public void setActionMessageLevel(int actionMessageLevel) {
1233 originalMessageLevel = ActionMessage.messageLevel;
1234 ActionMessage.messageLevel = actionMessageLevel;
1235 }
1236
1237 /**
1238 Set FPDFileName parameter for this action class.
1239
1240 @param fpdFilePath fpd file path
1241 **/
1242 public void setFPDFilePath(String fpdFilePath) {
1243 this.fpdFilePath = fpdFilePath;
1244 }
1245
1246 /**
1247 Common function interface for outer.
1248
1249 @param workspacePath The path of workspace of current build or analysis.
1250 @param fpdFilePath The fpd file path of current build or analysis.
1251 @param messageLevel The message level for this Action.
1252
1253 @throws Exception The exception of this function. Because it can *not* be predict
1254 where the action class will be used. So only Exception can be throw.
1255
1256 **/
1257 public void perform(String workspacePath, String fpdFilePath,
1258 int messageLevel) throws Exception {
1259 setWorkspacePath(workspacePath);
1260 setFPDFilePath(fpdFilePath);
1261 setActionMessageLevel(messageLevel);
1262 checkParameter();
1263 execute();
1264 ActionMessage.messageLevel = originalMessageLevel;
1265 }
1266
1267 /**
1268 Core execution function for this action class.
1269
1270 This function work flows will be:
1271 1) Collect and prepocess PCD information from FPD file, all PCD
1272 information will be stored into memory database.
1273 2) Generate 3 strings for
1274 a) All modules using Dynamic(Ex) PCD entry.(Token Number)
1275 b) PEI PCDDatabase (C Structure) for PCD Service PEIM.
1276 c) DXE PCD Database (C structure) for PCD Service DXE.
1277
1278
1279 @throws EntityException Exception indicate failed to execute this action.
1280
1281 **/
1282 private void execute() throws EntityException {
1283 //
1284 // Get memoryDatabaseManager instance from GlobalData.
1285 // The memoryDatabaseManager should be initialized for whatever build
1286 // tools or wizard tools
1287 //
1288 if((dbManager = GlobalData.getPCDMemoryDBManager()) == null) {
1289 throw new EntityException("The instance of PCD memory database manager is null");
1290 }
1291
1292 //
1293 // Collect all PCD information defined in FPD file.
1294 // Evenry token defind in FPD will be created as an token into
1295 // memory database.
1296 //
1297 createTokenInDBFromFPD();
1298
1299 //
1300 // Call Private function genPcdDatabaseSourceCode (void); ComponentTypeBsDriver
1301 // 1) Generate for PEI, DXE PCD DATABASE's definition and initialization.
1302 //
1303 genPcdDatabaseSourceCode ();
1304
1305 }
1306
1307 /**
1308 This function generates source code for PCD Database.
1309
1310 @param void
1311 @throws EntityException If the token does *not* exist in memory database.
1312
1313 **/
1314 private void genPcdDatabaseSourceCode()
1315 throws EntityException {
1316 String PcdCommonHeaderString = PcdDatabase.getPcdDatabaseCommonDefinitions ();
1317
1318 ArrayList<Token> alPei = new ArrayList<Token> ();
1319 ArrayList<Token> alDxe = new ArrayList<Token> ();
1320
1321 dbManager.getTwoPhaseDynamicRecordArray(alPei, alDxe);
1322 PcdDatabase pcdPeiDatabase = new PcdDatabase (alPei, "PEI", 0);
1323 pcdPeiDatabase.genCode();
1324 dbManager.PcdPeimHString = PcdCommonHeaderString + pcdPeiDatabase.getHString()
1325 + PcdDatabase.getPcdPeiDatabaseDefinitions();
1326 dbManager.PcdPeimCString = pcdPeiDatabase.getCString();
1327
1328 PcdDatabase pcdDxeDatabase = new PcdDatabase (alDxe,
1329 "DXE",
1330 alPei.size()
1331 );
1332 pcdDxeDatabase.genCode();
1333 dbManager.PcdDxeHString = dbManager.PcdPeimHString + pcdDxeDatabase.getHString()
1334 + PcdDatabase.getPcdDxeDatabaseDefinitions();
1335 dbManager.PcdDxeCString = pcdDxeDatabase.getCString();
1336 }
1337
1338 /**
1339 Get component array from FPD.
1340
1341 This function maybe provided by some Global class.
1342
1343 @return List<ModuleInfo> the component array.
1344
1345 */
1346 private List<ModuleInfo> getComponentsFromFPD()
1347 throws EntityException {
1348 HashMap<String, XmlObject> map = new HashMap<String, XmlObject>();
1349 List<ModuleInfo> allModules = new ArrayList<ModuleInfo>();
1350 ModuleInfo current = null;
1351 int index = 0;
1352 org.tianocore.Components components = null;
1353 FrameworkModulesDocument.FrameworkModules fModules = null;
1354 java.util.List<ModuleSADocument.ModuleSA> modules = null;
1355
1356
1357 if (fpdDocInstance == null) {
1358 try {
1359 fpdDocInstance = (FrameworkPlatformDescriptionDocument)XmlObject.Factory.parse(new File(fpdFilePath));
1360 } catch(IOException ioE) {
1361 throw new EntityException("File IO error for xml file:" + fpdFilePath + "\n" + ioE.getMessage());
1362 } catch(XmlException xmlE) {
1363 throw new EntityException("Can't parse the FPD xml fle:" + fpdFilePath + "\n" + xmlE.getMessage());
1364 }
1365
1366 }
1367
1368 //
1369 // Check whether FPD contians <FramworkModules>
1370 //
1371 fModules = fpdDocInstance.getFrameworkPlatformDescription().getFrameworkModules();
1372 if (fModules == null) {
1373 return null;
1374 }
1375
1376 //
1377 // BUGBUG: The following is work around code, the final component type should be get from
1378 // GlobalData class.
1379 //
1380 components = fModules.getSEC();
1381 if (components != null) {
1382 modules = components.getModuleSAList();
1383 for (index = 0; index < modules.size(); index ++) {
1384 allModules.add(new ModuleInfo(modules.get(index), UsageInstance.MODULE_TYPE.SEC));
1385 }
1386 }
1387
1388 components = fModules.getPEICORE();
1389 if (components != null) {
1390 modules = components.getModuleSAList();
1391 for (index = 0; index < modules.size(); index ++) {
1392 allModules.add(new ModuleInfo(modules.get(index), UsageInstance.MODULE_TYPE.PEI_CORE));
1393 }
1394 }
1395
1396 components = fModules.getPEIM();
1397 if (components != null) {
1398 modules = components.getModuleSAList();
1399 for (index = 0; index < modules.size(); index ++) {
1400 allModules.add(new ModuleInfo(modules.get(index), UsageInstance.MODULE_TYPE.PEIM));
1401 }
1402 }
1403
1404 components = fModules.getDXECORE();
1405 if (components != null) {
1406 modules = components.getModuleSAList();
1407 for (index = 0; index < modules.size(); index ++) {
1408 allModules.add(new ModuleInfo(modules.get(index), UsageInstance.MODULE_TYPE.DXE_CORE));
1409 }
1410 }
1411
1412 components = fModules.getDXEDRIVERS();
1413 if (components != null) {
1414 modules = components.getModuleSAList();
1415 for (index = 0; index < modules.size(); index ++) {
1416 allModules.add(new ModuleInfo(modules.get(index), UsageInstance.MODULE_TYPE.DXE_DRIVERS));
1417 }
1418 }
1419
1420 components = fModules.getOTHERCOMPONENTS();
1421 if (components != null) {
1422 modules = components.getModuleSAList();
1423 for (index = 0; index < modules.size(); index ++) {
1424 allModules.add(new ModuleInfo(modules.get(index), UsageInstance.MODULE_TYPE.OTHER_COMPONENTS));
1425 }
1426 }
1427
1428 return allModules;
1429 }
1430
1431 /**
1432 Create token instance object into memory database, the token information
1433 comes for FPD file. Normally, FPD file will contain all token platform
1434 informations.
1435
1436 @return FrameworkPlatformDescriptionDocument The FPD document instance for furture usage.
1437
1438 @throws EntityException Failed to parse FPD xml file.
1439
1440 **/
1441 private void createTokenInDBFromFPD()
1442 throws EntityException {
1443 int index = 0;
1444 int index2 = 0;
1445 int pcdIndex = 0;
1446 List<PcdBuildDefinition.PcdData> pcdBuildDataArray = new ArrayList<PcdBuildDefinition.PcdData>();
1447 PcdBuildDefinition.PcdData pcdBuildData = null;
1448 Token token = null;
1449 SkuInstance skuInstance = null;
1450 int skuIndex = 0;
1451 List<ModuleInfo> modules = null;
1452 String primaryKey = null;
1453 String exceptionString = null;
1454 UsageInstance usageInstance = null;
1455 String primaryKey1 = null;
1456 String primaryKey2 = null;
1457 boolean isDuplicate = false;
1458 Token.PCD_TYPE pcdType = Token.PCD_TYPE.UNKNOWN;
1459 Token.DATUM_TYPE datumType = Token.DATUM_TYPE.UNKNOWN;
1460 int tokenNumber = 0;
1461 String moduleName = null;
1462 String datum = null;
1463 int maxDatumSize = 0;
1464
1465 //
1466 // ----------------------------------------------
1467 // 1), Get all <ModuleSA> from FPD file.
1468 // ----------------------------------------------
1469 //
1470 modules = getComponentsFromFPD();
1471
1472 if (modules == null) {
1473 throw new EntityException("[FPD file error] No modules in FPD file, Please check whether there are elements in <FrameworkModules> in FPD file!");
1474 }
1475
1476 //
1477 // -------------------------------------------------------------------
1478 // 2), Loop all modules to process <PcdBuildDeclarations> for each module.
1479 // -------------------------------------------------------------------
1480 //
1481 for (index = 0; index < modules.size(); index ++) {
1482 isDuplicate = false;
1483 for (index2 = 0; index2 < index; index2 ++) {
1484 //
1485 // BUGBUG: For transition schema, we can *not* get module's version from
1486 // <ModuleSAs>, It is work around code.
1487 //
1488 primaryKey1 = UsageInstance.getPrimaryKey(modules.get(index).module.getModuleName(),
1489 null,
1490 null,
1491 null,
1492 modules.get(index).module.getArch().toString(),
1493 null);
1494 primaryKey2 = UsageInstance.getPrimaryKey(modules.get(index2).module.getModuleName(),
1495 null,
1496 null,
1497 null,
1498 modules.get(index2).module.getArch().toString(),
1499 null);
1500 if (primaryKey1.equalsIgnoreCase(primaryKey2)) {
1501 isDuplicate = true;
1502 break;
1503 }
1504 }
1505
1506 if (isDuplicate) {
1507 continue;
1508 }
1509
1510 //
1511 // It is legal for a module does not contains ANY pcd build definitions.
1512 //
1513 if (modules.get(index).module.getPcdBuildDefinition() == null) {
1514 continue;
1515 }
1516
1517 pcdBuildDataArray = modules.get(index).module.getPcdBuildDefinition().getPcdDataList();
1518
1519 moduleName = modules.get(index).module.getModuleName();
1520
1521 //
1522 // ----------------------------------------------------------------------
1523 // 2.1), Loop all Pcd entry for a module and add it into memory database.
1524 // ----------------------------------------------------------------------
1525 //
1526 for (pcdIndex = 0; pcdIndex < pcdBuildDataArray.size(); pcdIndex ++) {
1527 pcdBuildData = pcdBuildDataArray.get(pcdIndex);
1528 primaryKey = Token.getPrimaryKeyString(pcdBuildData.getCName(),
1529 translateSchemaStringToUUID(pcdBuildData.getTokenSpaceGuid()));
1530 pcdType = Token.getpcdTypeFromString(pcdBuildData.getItemType().toString());
1531 datumType = Token.getdatumTypeFromString(pcdBuildData.getDatumType().toString());
1532 tokenNumber = Integer.decode(pcdBuildData.getToken().toString());
1533 datum = pcdBuildData.getValue();
1534 maxDatumSize = pcdBuildData.getMaxDatumSize();
1535
1536 //
1537 // Check <TokenSpaceGuid> is exist? In future, because all schema verification will tools
1538 // will check that, following checking code could be removed.
1539 //
1540 if (pcdBuildData.getTokenSpaceGuid() == null) {
1541 exceptionString = String.format("[FPD file error] There is no <TokenSpaceGuid> for PCD %s in module %s! This is required!",
1542 pcdBuildData.getCName(),
1543 moduleName);
1544 throw new EntityException(exceptionString);
1545 }
1546
1547 //
1548 // -------------------------------------------------------------------------------------------
1549 // 2.1.1), Do some necessary checking work for FixedAtBuild, FeatureFlag and PatchableInModule
1550 // -------------------------------------------------------------------------------------------
1551 //
1552 if (!Token.isDynamic(pcdType)) {
1553 //
1554 // Value is required.
1555 //
1556 if (datum == null) {
1557 exceptionString = String.format("[FPD file error] There is no value for PCD entry %s in module %s!",
1558 pcdBuildData.getCName(),
1559 moduleName);
1560 throw new EntityException(exceptionString);
1561 }
1562
1563 //
1564 // Check whether the datum size is matched datum type.
1565 //
1566 if ((exceptionString = verifyDatum(pcdBuildData.getCName(),
1567 moduleName,
1568 datum,
1569 datumType,
1570 maxDatumSize)) != null) {
1571 throw new EntityException(exceptionString);
1572 }
1573 }
1574
1575 //
1576 // ---------------------------------------------------------------------------------
1577 // 2.1.2), Create token or update token information for current anaylized PCD data.
1578 // ---------------------------------------------------------------------------------
1579 //
1580 if (dbManager.isTokenInDatabase(primaryKey)) {
1581 //
1582 // If the token is already exist in database, do some necessary checking
1583 // and add a usage instance into this token in database
1584 //
1585 token = dbManager.getTokenByKey(primaryKey);
1586
1587 //
1588 // checking for DatumType, DatumType should be unique for one PCD used in different
1589 // modules.
1590 //
1591 if (token.datumType != datumType) {
1592 exceptionString = String.format("[FPD file error] The datum type of PCD entry %s is %s, which is different with %s defined in before!",
1593 pcdBuildData.getCName(),
1594 pcdBuildData.getDatumType().toString(),
1595 Token.getStringOfdatumType(token.datumType));
1596 throw new EntityException(exceptionString);
1597 }
1598
1599 //
1600 // Check token number is valid
1601 //
1602 if (tokenNumber != token.tokenNumber) {
1603 exceptionString = String.format("[FPD file error] The token number of PCD entry %s in module %s is different with same PCD entry in other modules!",
1604 pcdBuildData.getCName(),
1605 moduleName);
1606 throw new EntityException(exceptionString);
1607 }
1608
1609 //
1610 // For same PCD used in different modules, the PCD type should all be dynamic or non-dynamic.
1611 //
1612 if (token.isDynamicPCD != Token.isDynamic(pcdType)) {
1613 exceptionString = String.format("[FPD file error] For PCD entry %s in module %s, you define dynamic or non-dynamic PCD type which"+
1614 "is different with others module's",
1615 token.cName,
1616 moduleName);
1617 throw new EntityException(exceptionString);
1618 }
1619
1620 if (token.isDynamicPCD) {
1621 //
1622 // Check datum is equal the datum in dynamic information.
1623 // For dynamic PCD, you can do not write <Value> in sperated every <PcdBuildDefinition> in different <ModuleSA>,
1624 // But if you write, the <Value> must be same as the value in <DynamicPcdBuildDefinitions>.
1625 //
1626 if (!token.isSkuEnable() &&
1627 (token.getDefaultSku().type == DynamicTokenValue.VALUE_TYPE.DEFAULT_TYPE) &&
1628 (datum != null)) {
1629 if (!datum.equalsIgnoreCase(token.getDefaultSku().value)) {
1630 exceptionString = String.format("[FPD file error] For dynamic PCD %s in module %s, the datum in <ModuleSA> is "+
1631 "not equal to the datum in <DynamicPcdBuildDefinitions>, it is "+
1632 "illega! You could no set <Value> in <ModuleSA> for a dynamic PCD!",
1633 token.cName,
1634 moduleName);
1635 throw new EntityException(exceptionString);
1636 }
1637 }
1638
1639 if ((maxDatumSize != 0) &&
1640 (maxDatumSize != token.datumSize)){
1641 exceptionString = String.format("[FPD file error] For dynamic PCD %s in module %s, the max datum size is %d which "+
1642 "is different with <MaxDatumSize> %d defined in <DynamicPcdBuildDefinitions>!",
1643 token.cName,
1644 moduleName,
1645 maxDatumSize,
1646 token.datumSize);
1647 throw new EntityException(exceptionString);
1648 }
1649 }
1650
1651 } else {
1652 //
1653 // If the token is not in database, create a new token instance and add
1654 // a usage instance into this token in database.
1655 //
1656 token = new Token(pcdBuildData.getCName(),
1657 translateSchemaStringToUUID(pcdBuildData.getTokenSpaceGuid()));
1658
1659 token.datumType = datumType;
1660 token.tokenNumber = tokenNumber;
1661 token.isDynamicPCD = Token.isDynamic(pcdType);
1662 token.datumSize = maxDatumSize;
1663
1664 if (token.isDynamicPCD) {
1665 //
1666 // For Dynamic and Dynamic Ex type, need find the dynamic information
1667 // in <DynamicPcdBuildDefinition> section in FPD file.
1668 //
1669 updateDynamicInformation(moduleName,
1670 token,
1671 datum,
1672 maxDatumSize);
1673 }
1674
1675 dbManager.addTokenToDatabase(primaryKey, token);
1676 }
1677
1678 //
1679 // -----------------------------------------------------------------------------------
1680 // 2.1.3), Add the PcdType in current module into this Pcd token's supported PCD type.
1681 // -----------------------------------------------------------------------------------
1682 //
1683 token.updateSupportPcdType(pcdType);
1684
1685 //
1686 // ------------------------------------------------
1687 // 2.1.4), Create an usage instance for this token.
1688 // ------------------------------------------------
1689 //
1690 usageInstance = new UsageInstance(token,
1691 moduleName,
1692 null,
1693 null,
1694 null,
1695 modules.get(index).type,
1696 pcdType,
1697 modules.get(index).module.getArch().toString(),
1698 null,
1699 datum,
1700 maxDatumSize);
1701 token.addUsageInstance(usageInstance);
1702 }
1703 }
1704 }
1705
1706 /**
1707 Verify the datum value according its datum size and datum type, this
1708 function maybe moved to FPD verification tools in future.
1709
1710 @param cName
1711 @param moduleName
1712 @param datum
1713 @param datumType
1714 @param maxDatumSize
1715
1716 @return String
1717 */
1718 /***/
1719 public String verifyDatum(String cName,
1720 String moduleName,
1721 String datum,
1722 Token.DATUM_TYPE datumType,
1723 int maxDatumSize) {
1724 String exceptionString = null;
1725 int value;
1726 BigInteger value64;
1727 String subStr;
1728
1729 if (moduleName == null) {
1730 moduleName = "section <DynamicPcdBuildDefinitions>";
1731 } else {
1732 moduleName = "module " + moduleName;
1733 }
1734
1735 if (maxDatumSize == 0) {
1736 exceptionString = String.format("[FPD file error] You maybe miss <MaxDatumSize> for PCD %s in %s",
1737 cName,
1738 moduleName);
1739 return exceptionString;
1740 }
1741
1742 switch (datumType) {
1743 case UINT8:
1744 if (maxDatumSize != 1) {
1745 exceptionString = String.format("[FPD file error] The datum type of PCD data %s in %s "+
1746 "is UINT8, but datum size is %d, they are not matched!",
1747 cName,
1748 moduleName,
1749 maxDatumSize);
1750 return exceptionString;
1751 }
1752
1753 if (datum != null) {
1754 try {
1755 value = Integer.decode(datum);
1756 } catch (NumberFormatException nfeExp) {
1757 exceptionString = String.format("[FPD file error] The datum for PCD %s in %s is not valid "+
1758 "digital format of UINT8",
1759 cName,
1760 moduleName);
1761 return exceptionString;
1762 }
1763 if (value > 0xFF) {
1764 exceptionString = String.format("[FPD file error] The datum for PCD %s in %s is %s exceed"+
1765 " the max size of UINT8 - 0xFF",
1766 cName,
1767 moduleName,
1768 datum);
1769 return exceptionString;
1770 }
1771 }
1772 break;
1773 case UINT16:
1774 if (maxDatumSize != 2) {
1775 exceptionString = String.format("[FPD file error] The datum type of PCD data %s in %s "+
1776 "is UINT16, but datum size is %d, they are not matched!",
1777 cName,
1778 moduleName,
1779 maxDatumSize);
1780 return exceptionString;
1781 }
1782 if (datum != null) {
1783 try {
1784 value = Integer.decode(datum);
1785 } catch (NumberFormatException nfeExp) {
1786 exceptionString = String.format("[FPD file error] The datum for PCD %s in %s is "+
1787 "not valid digital of UINT16",
1788 cName,
1789 moduleName);
1790 return exceptionString;
1791 }
1792 if (value > 0xFFFF) {
1793 exceptionString = String.format("[FPD file error] The datum for PCD %s in %s is %s "+
1794 "which exceed the range of UINT16 - 0xFFFF",
1795 cName,
1796 moduleName,
1797 datum);
1798 return exceptionString;
1799 }
1800 }
1801 break;
1802 case UINT32:
1803 if (maxDatumSize != 4) {
1804 exceptionString = String.format("[FPD file error] The datum type of PCD data %s in %s "+
1805 "is UINT32, but datum size is %d, they are not matched!",
1806 cName,
1807 moduleName,
1808 maxDatumSize);
1809 return exceptionString;
1810 }
1811
1812 if (datum != null) {
1813 try {
1814 if (datum.length() > 2) {
1815 if ((datum.charAt(0) == '0') &&
1816 ((datum.charAt(1) == 'x') || (datum.charAt(1) == 'X'))){
1817 subStr = datum.substring(2, datum.length());
1818 value64 = new BigInteger(subStr, 16);
1819 } else {
1820 value64 = new BigInteger(datum);
1821 }
1822 } else {
1823 value64 = new BigInteger(datum);
1824 }
1825 } catch (NumberFormatException nfeExp) {
1826 exceptionString = String.format("[FPD file error] The datum for PCD %s in %s is not "+
1827 "valid digital of UINT32",
1828 cName,
1829 moduleName);
1830 return exceptionString;
1831 }
1832
1833 if (value64.bitLength() > 32) {
1834 exceptionString = String.format("[FPD file error] The datum for PCD %s in %s is %s which "+
1835 "exceed the range of UINT32 - 0xFFFFFFFF",
1836 cName,
1837 moduleName,
1838 datum);
1839 return exceptionString;
1840 }
1841 }
1842 break;
1843 case UINT64:
1844 if (maxDatumSize != 8) {
1845 exceptionString = String.format("[FPD file error] The datum type of PCD data %s in %s "+
1846 "is UINT64, but datum size is %d, they are not matched!",
1847 cName,
1848 moduleName,
1849 maxDatumSize);
1850 return exceptionString;
1851 }
1852
1853 if (datum != null) {
1854 try {
1855 if (datum.length() > 2) {
1856 if ((datum.charAt(0) == '0') &&
1857 ((datum.charAt(1) == 'x') || (datum.charAt(1) == 'X'))){
1858 subStr = datum.substring(2, datum.length());
1859 value64 = new BigInteger(subStr, 16);
1860 } else {
1861 value64 = new BigInteger(datum);
1862 }
1863 } else {
1864 value64 = new BigInteger(datum);
1865 }
1866 } catch (NumberFormatException nfeExp) {
1867 exceptionString = String.format("[FPD file error] The datum for PCD %s in %s is not valid"+
1868 " digital of UINT64",
1869 cName,
1870 moduleName);
1871 return exceptionString;
1872 }
1873
1874 if (value64.bitLength() > 64) {
1875 exceptionString = String.format("[FPD file error] The datum for PCD %s in %s is %s "+
1876 "exceed the range of UINT64 - 0xFFFFFFFFFFFFFFFF",
1877 cName,
1878 moduleName,
1879 datum);
1880 return exceptionString;
1881 }
1882 }
1883 break;
1884 case BOOLEAN:
1885 if (maxDatumSize != 1) {
1886 exceptionString = String.format("[FPD file error] The datum type of PCD data %s in %s "+
1887 "is BOOLEAN, but datum size is %d, they are not matched!",
1888 cName,
1889 moduleName,
1890 maxDatumSize);
1891 return exceptionString;
1892 }
1893
1894 if (datum != null) {
1895 if (!(datum.equalsIgnoreCase("TRUE") ||
1896 datum.equalsIgnoreCase("FALSE"))) {
1897 exceptionString = String.format("[FPD file error] The datum type of PCD data %s in %s "+
1898 "is BOOELAN, but value is not 'true'/'TRUE' or 'FALSE'/'false'",
1899 cName,
1900 moduleName);
1901 return exceptionString;
1902 }
1903
1904 }
1905 break;
1906 case POINTER:
1907 if (datum == null) {
1908 break;
1909 }
1910
1911 char ch = datum.charAt(0);
1912 int start, end;
1913 String strValue;
1914 //
1915 // For void* type PCD, only three datum is support:
1916 // 1) Unicode: string with start char is "L"
1917 // 2) Ansci: String start char is ""
1918 // 3) byte array: String start char "{"
1919 //
1920 if (ch == 'L') {
1921 start = datum.indexOf('\"');
1922 end = datum.lastIndexOf('\"');
1923 if ((start > end) ||
1924 (end > datum.length())||
1925 ((start == end) && (datum.length() > 0))) {
1926 exceptionString = String.format("The datum type of PCD %s in %s is VOID* and datum is "+
1927 "a UNICODE string because start with L\", but format maybe"+
1928 "is not right, correct UNICODE string is L\"...\"!",
1929 cName,
1930 moduleName);
1931 return exceptionString;
1932 }
1933
1934 strValue = datum.substring(start + 1, end);
1935 if ((strValue.length() * 2) > maxDatumSize) {
1936 exceptionString = String.format("The datum type of PCD %s in %s is VOID*, and datum is "+
1937 "a UNICODE string, but the datum size is %d exceed to <MaxDatumSize> : %d",
1938 cName,
1939 moduleName,
1940 strValue.length() * 2,
1941 maxDatumSize);
1942 return exceptionString;
1943 }
1944 } else if (ch == '\"'){
1945 start = datum.indexOf('\"');
1946 end = datum.lastIndexOf('\"');
1947 if ((start > end) ||
1948 (end > datum.length())||
1949 ((start == end) && (datum.length() > 0))) {
1950 exceptionString = String.format("The datum type of PCD %s in %s is VOID* and datum is "+
1951 "a ANSCII string because start with \", but format maybe"+
1952 "is not right, correct ANSIC string is \"...\"!",
1953 cName,
1954 moduleName);
1955 return exceptionString;
1956 }
1957 strValue = datum.substring(start + 1, end);
1958 if ((strValue.length()) > maxDatumSize) {
1959 exceptionString = String.format("The datum type of PCD %s in %s is VOID*, and datum is "+
1960 "a ANSCI string, but the datum size is %d which exceed to <MaxDatumSize> : %d",
1961 cName,
1962 moduleName,
1963 strValue.length(),
1964 maxDatumSize);
1965 return exceptionString;
1966 }
1967 } else if (ch =='{') {
1968 String[] strValueArray;
1969
1970 start = datum.indexOf('{');
1971 end = datum.lastIndexOf('}');
1972 strValue = datum.substring(start, end);
1973 strValueArray = strValue.split(",");
1974 if (strValueArray.length > maxDatumSize) {
1975 exceptionString = String.format("The datum type of PCD %s in %s is VOID*, and datum is byte"+
1976 "array, but the number of bytes is %d which exceed to <MaxDatumSzie> : %d!",
1977 cName,
1978 moduleName,
1979 strValueArray.length,
1980 maxDatumSize);
1981 return exceptionString;
1982 }
1983 } else {
1984 exceptionString = String.format("The datum type of PCD %s in %s is VOID*. For VOID* type, you have three format choise:\n "+
1985 "1) UNICODE string: like L\"xxxx\";\r\n"+
1986 "2) ANSIC string: like \"xxx\";\r\n"+
1987 "3) Byte array: like {0x2, 0x45, 0x23}\r\n"+
1988 "But the datum in seems does not following above format!",
1989 cName,
1990 moduleName);
1991 return exceptionString;
1992 }
1993 break;
1994 default:
1995 exceptionString = String.format("[FPD file error] For PCD entry %s in %s, datum type is unknown, it should be one of "+
1996 "UINT8, UINT16, UINT32, UINT64, VOID*, BOOLEAN",
1997 cName,
1998 moduleName);
1999 return exceptionString;
2000 }
2001 return null;
2002 }
2003
2004 /**
2005 Get dynamic information for a dynamic PCD from <DynamicPcdBuildDefinition> seciton in FPD file.
2006
2007 This function should be implemented in GlobalData in future.
2008
2009 @param token The token instance which has hold module's PCD information
2010 @param moduleName The name of module who will use this Dynamic PCD.
2011
2012 @return DynamicPcdBuildDefinitions.PcdBuildData
2013 */
2014 /***/
2015 private DynamicPcdBuildDefinitions.PcdBuildData getDynamicInfoFromFPD(Token token,
2016 String moduleName)
2017 throws EntityException {
2018 int index = 0;
2019 String exceptionString = null;
2020 String dynamicPrimaryKey = null;
2021 DynamicPcdBuildDefinitions dynamicPcdBuildDefinitions = null;
2022 List<DynamicPcdBuildDefinitions.PcdBuildData> dynamicPcdBuildDataArray = null;
2023
2024 //
2025 // If FPD document is not be opened, open and initialize it.
2026 //
2027 if (fpdDocInstance == null) {
2028 try {
2029 fpdDocInstance = (FrameworkPlatformDescriptionDocument)XmlObject.Factory.parse(new File(fpdFilePath));
2030 } catch(IOException ioE) {
2031 throw new EntityException("File IO error for xml file:" + fpdFilePath + "\n" + ioE.getMessage());
2032 } catch(XmlException xmlE) {
2033 throw new EntityException("Can't parse the FPD xml fle:" + fpdFilePath + "\n" + xmlE.getMessage());
2034 }
2035 }
2036
2037 dynamicPcdBuildDefinitions = fpdDocInstance.getFrameworkPlatformDescription().getDynamicPcdBuildDefinitions();
2038 if (dynamicPcdBuildDefinitions == null) {
2039 exceptionString = String.format("[FPD file error] There are no <PcdDynamicBuildDescriptions> in FPD file but contains Dynamic type "+
2040 "PCD entry %s in module %s!",
2041 token.cName,
2042 moduleName);
2043 throw new EntityException(exceptionString);
2044 }
2045
2046 dynamicPcdBuildDataArray = dynamicPcdBuildDefinitions.getPcdBuildDataList();
2047 for (index = 0; index < dynamicPcdBuildDataArray.size(); index ++) {
2048 //
2049 // Check <TokenSpaceGuid> is exist? In future, because all schema verification will tools
2050 // will check that, following checking code could be removed.
2051 //
2052 if (dynamicPcdBuildDataArray.get(index).getTokenSpaceGuid() == null) {
2053 exceptionString = String.format("[FPD file error] There is no <TokenSpaceGuid> for PCD %s in <DynamicPcdBuildDefinitions>! This is required!",
2054 dynamicPcdBuildDataArray.get(index).getCName());
2055 throw new EntityException(exceptionString);
2056 }
2057
2058 dynamicPrimaryKey = Token.getPrimaryKeyString(dynamicPcdBuildDataArray.get(index).getCName(),
2059 translateSchemaStringToUUID(dynamicPcdBuildDataArray.get(index).getTokenSpaceGuid()));
2060 if (dynamicPrimaryKey.equalsIgnoreCase(token.getPrimaryKeyString())) {
2061 return dynamicPcdBuildDataArray.get(index);
2062 }
2063 }
2064
2065 return null;
2066 }
2067
2068 /**
2069 Update dynamic information for PCD entry.
2070
2071 Dynamic information is retrieved from <PcdDynamicBuildDeclarations> in
2072 FPD file.
2073
2074 @param moduleName The name of the module who use this PCD
2075 @param token The token instance
2076 @param datum The <datum> in module's PCD information
2077 @param maxDatumSize The <maxDatumSize> in module's PCD information
2078
2079 @return Token
2080 */
2081 private Token updateDynamicInformation(String moduleName,
2082 Token token,
2083 String datum,
2084 int maxDatumSize)
2085 throws EntityException {
2086 int index = 0;
2087 int offset;
2088 String exceptionString = null;
2089 DynamicTokenValue dynamicValue;
2090 SkuInstance skuInstance = null;
2091 String temp;
2092 boolean hasSkuId0 = false;
2093
2094 List<DynamicPcdBuildDefinitions.PcdBuildData.SkuInfo> skuInfoList = null;
2095 DynamicPcdBuildDefinitions.PcdBuildData dynamicInfo = null;
2096
2097 dynamicInfo = getDynamicInfoFromFPD(token, moduleName);
2098 if (dynamicInfo == null) {
2099 exceptionString = String.format("[FPD file error] For Dynamic PCD %s used by module %s, "+
2100 "there is no dynamic information in <DynamicPcdBuildDefinitions> "+
2101 "in FPD file, but it is required!",
2102 token.cName,
2103 moduleName);
2104 throw new EntityException(exceptionString);
2105 }
2106
2107 token.datumSize = dynamicInfo.getMaxDatumSize();
2108
2109 exceptionString = verifyDatum(token.cName,
2110 moduleName,
2111 null,
2112 token.datumType,
2113 token.datumSize);
2114 if (exceptionString != null) {
2115 throw new EntityException(exceptionString);
2116 }
2117
2118 if ((maxDatumSize != 0) &&
2119 (maxDatumSize != token.datumSize)) {
2120 exceptionString = String.format("FPD file error] For dynamic PCD %s, the datum size in module %s is %d, but "+
2121 "the datum size in <DynamicPcdBuildDefinitions> is %d, they are not match!",
2122 token.cName,
2123 moduleName,
2124 maxDatumSize,
2125 dynamicInfo.getMaxDatumSize());
2126 throw new EntityException(exceptionString);
2127 }
2128
2129 skuInfoList = dynamicInfo.getSkuInfoList();
2130
2131 //
2132 // Loop all sku data
2133 //
2134 for (index = 0; index < skuInfoList.size(); index ++) {
2135 skuInstance = new SkuInstance();
2136 //
2137 // Although SkuId in schema is BigInteger, but in fact, sku id is 32 bit value.
2138 //
2139 temp = skuInfoList.get(index).getSkuId().toString();
2140 skuInstance.id = Integer.decode(temp);
2141 if (skuInstance.id == 0) {
2142 hasSkuId0 = true;
2143 }
2144 //
2145 // Judge whether is DefaultGroup at first, because most case is DefautlGroup.
2146 //
2147 if (skuInfoList.get(index).getValue() != null) {
2148 skuInstance.value.setValue(skuInfoList.get(index).getValue());
2149 if ((exceptionString = verifyDatum(token.cName,
2150 null,
2151 skuInfoList.get(index).getValue(),
2152 token.datumType,
2153 token.datumSize)) != null) {
2154 throw new EntityException(exceptionString);
2155 }
2156
2157 token.skuData.add(skuInstance);
2158
2159 //
2160 // Judege wether is same of datum between module's information
2161 // and dynamic information.
2162 //
2163 if (datum != null) {
2164 if ((skuInstance.id == 0) &&
2165 !datum.equalsIgnoreCase(skuInfoList.get(index).getValue())) {
2166 exceptionString = "[FPD file error] For dynamic PCD " + token.cName + ", the value in module " + moduleName + " is " + datum.toString() + " but the "+
2167 "value of sku 0 data in <DynamicPcdBuildDefinition> is " + skuInstance.value.value + ". They are must be same!"+
2168 " or you could not define value for a dynamic PCD in every <ModuleSA>!";
2169 throw new EntityException(exceptionString);
2170 }
2171 }
2172 continue;
2173 }
2174
2175 //
2176 // Judge whether is HII group case.
2177 //
2178 if (skuInfoList.get(index).getVariableName() != null) {
2179 exceptionString = null;
2180 if (skuInfoList.get(index).getVariableGuid() == null) {
2181 exceptionString = String.format("[FPD file error] For dynamic PCD %s in <DynamicPcdBuildDefinitions> section in FPD "+
2182 "file, who use HII, but there is no <VariableGuid> defined for Sku %d data!",
2183 token.cName,
2184 index);
2185
2186 }
2187
2188 if (skuInfoList.get(index).getVariableOffset() == null) {
2189 exceptionString = String.format("[FPD file error] For dynamic PCD %s in <DynamicPcdBuildDefinitions> section in FPD "+
2190 "file, who use HII, but there is no <VariableOffset> defined for Sku %d data!",
2191 token.cName,
2192 index);
2193 }
2194
2195 if (skuInfoList.get(index).getHiiDefaultValue() == null) {
2196 exceptionString = String.format("[FPD file error] For dynamic PCD %s in <DynamicPcdBuildDefinitions> section in FPD "+
2197 "file, who use HII, but there is no <HiiDefaultValue> defined for Sku %d data!",
2198 token.cName,
2199 index);
2200 }
2201
2202 if (exceptionString != null) {
2203 throw new EntityException(exceptionString);
2204 }
2205
2206 if ((exceptionString = verifyDatum(token.cName,
2207 null,
2208 skuInfoList.get(index).getHiiDefaultValue(),
2209 token.datumType,
2210 token.datumSize)) != null) {
2211 throw new EntityException(exceptionString);
2212 }
2213
2214 offset = Integer.decode(skuInfoList.get(index).getVariableOffset());
2215 if (offset > 0xFFFF) {
2216 throw new EntityException(String.format("[FPD file error] For dynamic PCD %s , the variable offset defined in sku %d data "+
2217 "exceed 64K, it is not allowed!",
2218 token.cName,
2219 index));
2220 }
2221
2222 skuInstance.value.setHiiData(skuInfoList.get(index).getVariableName(),
2223 translateSchemaStringToUUID(skuInfoList.get(index).getVariableGuid().toString()),
2224 skuInfoList.get(index).getVariableOffset(),
2225 skuInfoList.get(index).getHiiDefaultValue());
2226 token.skuData.add(skuInstance);
2227 continue;
2228 }
2229
2230 if (skuInfoList.get(index).getVpdOffset() != null) {
2231 skuInstance.value.setVpdData(skuInfoList.get(index).getVpdOffset());
2232 token.skuData.add(skuInstance);
2233 continue;
2234 }
2235
2236 exceptionString = String.format("[FPD file error] For dynamic PCD %s, the dynamic info must "+
2237 "be one of 'DefaultGroup', 'HIIGroup', 'VpdGroup'.",
2238 token.cName);
2239 throw new EntityException(exceptionString);
2240 }
2241
2242 if (!hasSkuId0) {
2243 exceptionString = String.format("[FPD file error] For dynamic PCD %s in <DynamicPcdBuildDefinitions>, there are "+
2244 "no sku id = 0 data, which is required for every dynamic PCD",
2245 token.cName);
2246 throw new EntityException(exceptionString);
2247 }
2248
2249 return token;
2250 }
2251
2252 /**
2253 Translate the schema string to UUID instance.
2254
2255 In schema, the string of UUID is defined as following two types string:
2256 1) GuidArrayType: pattern = 0x[a-fA-F0-9]{1,8},( )*0x[a-fA-F0-9]{1,4},(
2257 )*0x[a-fA-F0-9]{1,4}(,( )*\{)?(,?( )*0x[a-fA-F0-9]{1,2}){8}( )*(\})?
2258
2259 2) GuidNamingConvention: pattern =
2260 [a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}
2261
2262 This function will convert string and create uuid instance.
2263
2264 @param uuidString UUID string in XML file
2265
2266 @return UUID UUID instance
2267 **/
2268 private UUID translateSchemaStringToUUID(String uuidString)
2269 throws EntityException {
2270 String temp;
2271 String[] splitStringArray;
2272 int index;
2273 int chIndex;
2274 int chLen;
2275
2276 if (uuidString == null) {
2277 return null;
2278 }
2279
2280 if (uuidString.length() == 0) {
2281 return null;
2282 }
2283
2284 if (uuidString.equals("0") ||
2285 uuidString.equalsIgnoreCase("0x0")) {
2286 return new UUID(0, 0);
2287 }
2288
2289 //
2290 // If the UUID schema string is GuidArrayType type then need translate
2291 // to GuidNamingConvention type at first.
2292 //
2293 if ((uuidString.charAt(0) == '0') && ((uuidString.charAt(1) == 'x') || (uuidString.charAt(1) == 'X'))) {
2294 splitStringArray = uuidString.split("," );
2295 if (splitStringArray.length != 11) {
2296 throw new EntityException ("[FPD file error] Wrong format for UUID string: " + uuidString);
2297 }
2298
2299 //
2300 // Remove blank space from these string and remove header string "0x"
2301 //
2302 for (index = 0; index < 11; index ++) {
2303 splitStringArray[index] = splitStringArray[index].trim();
2304 splitStringArray[index] = splitStringArray[index].substring(2, splitStringArray[index].length());
2305 }
2306
2307 //
2308 // Add heading '0' to normalize the string length
2309 //
2310 for (index = 3; index < 11; index ++) {
2311 chLen = splitStringArray[index].length();
2312 for (chIndex = 0; chIndex < 2 - chLen; chIndex ++) {
2313 splitStringArray[index] = "0" + splitStringArray[index];
2314 }
2315 }
2316
2317 //
2318 // construct the final GuidNamingConvention string
2319 //
2320 temp = String.format("%s-%s-%s-%s%s-%s%s%s%s%s%s",
2321 splitStringArray[0],
2322 splitStringArray[1],
2323 splitStringArray[2],
2324 splitStringArray[3],
2325 splitStringArray[4],
2326 splitStringArray[5],
2327 splitStringArray[6],
2328 splitStringArray[7],
2329 splitStringArray[8],
2330 splitStringArray[9],
2331 splitStringArray[10]);
2332 uuidString = temp;
2333 }
2334
2335 return UUID.fromString(uuidString);
2336 }
2337
2338 /**
2339 check parameter for this action.
2340
2341 @throws EntityException Bad parameter.
2342 **/
2343 private void checkParameter() throws EntityException {
2344 File file = null;
2345
2346 if((fpdFilePath == null) ||(workspacePath == null)) {
2347 throw new EntityException("WorkspacePath and FPDFileName should be blank for CollectPCDAtion!");
2348 }
2349
2350 if(fpdFilePath.length() == 0 || workspacePath.length() == 0) {
2351 throw new EntityException("WorkspacePath and FPDFileName should be blank for CollectPCDAtion!");
2352 }
2353
2354 file = new File(workspacePath);
2355 if(!file.exists()) {
2356 throw new EntityException("WorkpacePath " + workspacePath + " does not exist!");
2357 }
2358
2359 file = new File(fpdFilePath);
2360
2361 if(!file.exists()) {
2362 throw new EntityException("FPD File " + fpdFilePath + " does not exist!");
2363 }
2364 }
2365
2366 /**
2367 Test case function
2368
2369 @param argv parameter from command line
2370 **/
2371 public static void main(String argv[]) throws EntityException {
2372 CollectPCDAction ca = new CollectPCDAction();
2373 ca.setWorkspacePath("m:/tianocore_latest/edk2");
2374 ca.setFPDFilePath("m:/tianocore_latest/edk2/EdkNt32Pkg/Nt32.fpd");
2375 ca.setActionMessageLevel(ActionMessage.MAX_MESSAGE_LEVEL);
2376 GlobalData.initInfo("Tools" + File.separator + "Conf" + File.separator + "FrameworkDatabase.db",
2377 "m:/tianocore_latest/edk2");
2378 ca.execute();
2379 }
2380 }