]> git.proxmox.com Git - mirror_edk2.git/blame - Tools/Source/GenBuild/org/tianocore/build/pcd/action/PcdDatabase.java
This patch make sure that Pcd Dynamic database generation tool is able to handle...
[mirror_edk2.git] / Tools / Source / GenBuild / org / tianocore / build / pcd / action / PcdDatabase.java
CommitLineData
241876c7 1/** @file\r
2 PcdDatabase class.\r
3\r
4Copyright (c) 2006, Intel Corporation\r
5All rights reserved. This program and the accompanying materials\r
6are licensed and made available under the terms and conditions of the BSD License\r
7which accompanies this distribution. The full text of the license may be found at\r
8http://opensource.org/licenses/bsd-license.php\r
af98370e 9\r
241876c7 10THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12\r
13**/\r
14package org.tianocore.build.pcd.action;\r
15\r
241876c7 16import java.util.ArrayList;\r
17import java.util.Comparator;\r
18import java.util.HashMap;\r
241876c7 19import java.util.List;\r
20import java.util.Map;\r
241876c7 21import java.util.UUID;\r
241876c7 22import org.tianocore.pcd.entity.DynamicTokenValue;\r
241876c7 23import org.tianocore.pcd.entity.Token;\r
241876c7 24import org.tianocore.pcd.exception.EntityException;\r
25\r
26/**\r
af98370e 27 CStructTypeDeclaration\r
28\r
241876c7 29 This class is used to store the declaration string, such as\r
af98370e 30 "UINT32 PcdPlatformFlashBaseAddress", of\r
241876c7 31 each memember in the C structure, which is a standard C language\r
32 feature used to implement a simple and efficient database for\r
33 dynamic(ex) type PCD entry.\r
34**/\r
35class CStructTypeDeclaration {\r
36 String key;\r
37 int alignmentSize;\r
38 String cCode;\r
39 boolean initTable;\r
af98370e 40\r
241876c7 41 public CStructTypeDeclaration (String key, int alignmentSize, String cCode, boolean initTable) {\r
42 this.key = key;\r
43 this.alignmentSize = alignmentSize;\r
44 this.cCode = cCode;\r
45 this.initTable = initTable;\r
46 }\r
47}\r
48\r
49/**\r
af98370e 50 StringTable\r
51\r
241876c7 52 This class is used to store the String in a PCD database.\r
af98370e 53\r
241876c7 54**/\r
55class StringTable {\r
d73557df 56 class UnicodeString {\r
57 //\r
58 // In Schema, we define VariableName in DynamicPcdBuildDefinitions in FPD\r
59 // file to be HexWordArrayType. For example, Unicode String L"Setup" is \r
60 // <VariableName>0x0053 0x0065 0x0074 0x0075 0x0070</VariableName>. \r
61 // We use raw to differentiate if the String is in form of L"Setup" (raw is false) or\r
62 // in form of {0x0053, 0x0065, 0x0074, 0x0075, 0x0070}\r
63 //\r
64 // This str is the string that can be pasted directly into the C structure. \r
65 // For example, this str can be two forms:\r
66 // \r
67 // L"Setup",\r
68 // {0x0053, 0065, 0x0074, 0x0075, 0x0070, 0x0000}, //This is another form of L"Setup"\r
69 //\r
70 public String str;\r
71 //\r
72 // This len includes the NULL character at the end of the String.\r
73 //\r
74 public int len;\r
75 \r
76 public UnicodeString (String str, int len) {\r
77 this.str = str;\r
78 this.len = len;\r
79 }\r
80 }\r
81 \r
82 private ArrayList<UnicodeString> al;\r
241876c7 83 private ArrayList<String> alComments;\r
84 private String phase;\r
d73557df 85 int stringTableCharNum;\r
241876c7 86\r
87 public StringTable (String phase) {\r
88 this.phase = phase;\r
d73557df 89 al = new ArrayList<UnicodeString>();\r
241876c7 90 alComments = new ArrayList<String>();\r
d73557df 91 stringTableCharNum = 0;\r
241876c7 92 }\r
93\r
94 public String getSizeMacro () {\r
95 return String.format(PcdDatabase.StringTableSizeMacro, phase, getSize());\r
96 }\r
97\r
98 private int getSize () {\r
99 //\r
100 // We have at least one Unicode Character in the table.\r
101 //\r
d73557df 102 return stringTableCharNum == 0 ? 1 : stringTableCharNum;\r
241876c7 103 }\r
104\r
105 public String getExistanceMacro () {\r
106 return String.format(PcdDatabase.StringTableExistenceMacro, phase, (al.size() == 0)? "TRUE":"FALSE");\r
107 }\r
af98370e 108\r
241876c7 109 public void genCode (ArrayList<CStructTypeDeclaration> declaList, HashMap<String, String> instTable) {\r
110 final String stringTable = "StringTable";\r
111 final String tab = "\t";\r
112 final String newLine = "\r\n";\r
113 final String commaNewLine = ",\r\n";\r
af98370e 114\r
241876c7 115 CStructTypeDeclaration decl;\r
116\r
117 String cDeclCode = "";\r
118 String cInstCode = "";\r
119\r
120 //\r
121 // If we have a empty StringTable\r
122 //\r
123 if (al.size() == 0) {\r
af98370e 124 cDeclCode += String.format("%-20s%s[1]; /* StringTable is empty */", "UINT16", stringTable) + newLine;\r
241876c7 125 decl = new CStructTypeDeclaration (\r
126 stringTable,\r
127 2,\r
128 cDeclCode,\r
129 true\r
af98370e 130 );\r
241876c7 131 declaList.add(decl);\r
132\r
133 cInstCode = String.format("/* %s */", stringTable) + newLine + tab + "{ 0 }";\r
134 instTable.put(stringTable, cInstCode);\r
135 } else {\r
136\r
137 //\r
138 // If there is any String in the StringTable\r
139 //\r
140 for (int i = 0; i < al.size(); i++) {\r
d73557df 141 UnicodeString uStr = al.get(i);\r
241876c7 142 String stringTableName;\r
af98370e 143\r
241876c7 144 if (i == 0) {\r
145 //\r
146 // StringTable is a well-known name in the PCD DXE driver\r
147 //\r
148 stringTableName = stringTable;\r
af98370e 149\r
241876c7 150 } else {\r
151 stringTableName = String.format("%s_%d", stringTable, i);\r
152 cDeclCode += tab;\r
153 }\r
af98370e 154 cDeclCode += String.format("%-20s%s[%d]; /* %s */", "UINT16",\r
d73557df 155 stringTableName, uStr.len,\r
af98370e 156 alComments.get(i))\r
241876c7 157 + newLine;\r
af98370e 158\r
241876c7 159 if (i == 0) {\r
160 cInstCode = "/* StringTable */" + newLine;\r
161 }\r
af98370e 162\r
d73557df 163 cInstCode += tab + String.format("%s /* %s */", uStr.str, alComments.get(i));\r
241876c7 164 if (i != al.size() - 1) {\r
165 cInstCode += commaNewLine;\r
166 }\r
167 }\r
af98370e 168\r
241876c7 169 decl = new CStructTypeDeclaration (\r
170 stringTable,\r
171 2,\r
172 cDeclCode,\r
173 true\r
af98370e 174 );\r
241876c7 175 declaList.add(decl);\r
af98370e 176\r
241876c7 177 instTable.put(stringTable, cInstCode);\r
178 }\r
179 }\r
d73557df 180 \r
181 public int add (List inputStr, Token token) {\r
182 String str;\r
183 \r
184 str = "{";\r
185 \r
186 for (int i = 0; i < inputStr.size(); i++) {\r
187 str += " " + inputStr.get(i) + ",";\r
188 }\r
189 \r
190 str += " 0x0000";\r
191 \r
192 str += "}";\r
193 //\r
194 // This is a raw Unicode String\r
195 //\r
196 return addToTable (str, inputStr.size() + 1, token);\r
197 }\r
241876c7 198\r
199 public int add (String inputStr, Token token) {\r
241876c7 200\r
d73557df 201 int len;\r
241876c7 202 String str = inputStr;\r
af98370e 203\r
241876c7 204 //\r
205 // The input can be two types:\r
af98370e 206 // "L\"Bootmode\"" or "Bootmode".\r
207 // We drop the L\" and \" for the first type.\r
241876c7 208 if (str.startsWith("L\"") && str.endsWith("\"")) {\r
d73557df 209 //\r
210 // Substract the character of "L", """, """.\r
211 // and add in the NULL character. So it is 2.\r
212 //\r
213 len = str.length() - 2;\r
214 } else {\r
215 //\r
216 // Include the NULL character.\r
217 //\r
218 len = str.length() + 1;\r
219 str = "L\"" + str + "\"";\r
241876c7 220 }\r
d73557df 221 \r
222 //\r
223 // After processing, this is L"A String Sample" type of string.\r
224 //\r
225 return addToTable (str, len, token);\r
226 }\r
227 \r
228 private int addToTable (String inputStr, int len, Token token) {\r
229 int i;\r
230 int pos;\r
231\r
241876c7 232 //\r
233 // Check if StringTable has this String already.\r
234 // If so, return the current pos.\r
235 //\r
236 for (i = 0, pos = 0; i < al.size(); i++) {\r
d73557df 237 UnicodeString s = al.get(i);;\r
241876c7 238\r
d73557df 239 if (inputStr.equals(s.str)) {\r
241876c7 240 return pos;\r
241 }\r
d73557df 242 pos += s.len;\r
241876c7 243 }\r
af98370e 244\r
d73557df 245 i = stringTableCharNum;\r
241876c7 246 //\r
247 // Include the NULL character at the end of String\r
248 //\r
d73557df 249 stringTableCharNum += len;\r
250 al.add(new UnicodeString(inputStr, len));\r
241876c7 251 alComments.add(token.getPrimaryKeyString());\r
252\r
253 return i;\r
254 }\r
255}\r
256\r
257/**\r
af98370e 258 SizeTable\r
259\r
241876c7 260 This class is used to store the Size information for\r
261 POINTER TYPE PCD entry in a PCD database.\r
262\r
263**/\r
264class SizeTable {\r
265 private ArrayList<ArrayList<Integer>> al;\r
266 private ArrayList<String> alComments;\r
267 private int len;\r
268 private String phase;\r
af98370e 269\r
241876c7 270 public SizeTable (String phase) {\r
271 al = new ArrayList<ArrayList<Integer>>();\r
272 alComments = new ArrayList<String>();\r
273 len = 0;\r
274 this.phase = phase;\r
275 }\r
276\r
277 public String getSizeMacro () {\r
278 return String.format(PcdDatabase.SizeTableSizeMacro, phase, getSize());\r
279 }\r
af98370e 280\r
241876c7 281 private int getSize() {\r
282 return len == 0 ? 1 : len;\r
283 }\r
284\r
285 public void genCode (ArrayList<CStructTypeDeclaration> declaList, HashMap<String, String> instTable, String phase) {\r
286 final String name = "SizeTable";\r
af98370e 287\r
241876c7 288 CStructTypeDeclaration decl;\r
289 String cCode;\r
290\r
af98370e 291 cCode = String.format(PcdDatabase.SizeTableDeclaration, phase);\r
241876c7 292 decl = new CStructTypeDeclaration (\r
293 name,\r
294 2,\r
295 cCode,\r
296 true\r
af98370e 297 );\r
241876c7 298 declaList.add(decl);\r
299\r
300\r
301 cCode = PcdDatabase.genInstantiationStr(getInstantiation());\r
302 instTable.put(name, cCode);\r
303 }\r
304\r
305 private ArrayList<String> getInstantiation () {\r
306 final String comma = ",";\r
307 ArrayList<String> Output = new ArrayList<String>();\r
308\r
309 Output.add("/* SizeTable */");\r
310 Output.add("{");\r
311 if (al.size() == 0) {\r
312 Output.add("\t0");\r
313 } else {\r
314 for (int index = 0; index < al.size(); index++) {\r
315 ArrayList<Integer> ial = al.get(index);\r
af98370e 316\r
241876c7 317 String str = "\t";\r
af98370e 318\r
241876c7 319 for (int index2 = 0; index2 < ial.size(); index2++) {\r
320 str += " " + ial.get(index2).toString();\r
321 if (index2 != ial.size() - 1) {\r
322 str += comma;\r
323 }\r
324 }\r
325\r
af98370e 326 str += " /* " + alComments.get(index) + " */";\r
327\r
241876c7 328 if (index != (al.size() - 1)) {\r
329 str += comma;\r
330 }\r
331\r
332 Output.add(str);\r
af98370e 333\r
241876c7 334 }\r
335 }\r
336 Output.add("}");\r
337\r
338 return Output;\r
339 }\r
340\r
341 public void add (Token token) {\r
342\r
343 //\r
344 // We only have size information for POINTER type PCD entry.\r
345 //\r
346 if (token.datumType != Token.DATUM_TYPE.POINTER) {\r
347 return;\r
348 }\r
af98370e 349\r
241876c7 350 ArrayList<Integer> ial = token.getPointerTypeSize();\r
af98370e 351\r
352 len+= ial.size();\r
241876c7 353\r
354 al.add(ial);\r
355 alComments.add(token.getPrimaryKeyString());\r
356\r
357 return;\r
358 }\r
af98370e 359\r
241876c7 360}\r
361\r
362/**\r
af98370e 363 GuidTable\r
364\r
241876c7 365 This class is used to store the GUIDs in a PCD database.\r
366**/\r
367class GuidTable {\r
368 private ArrayList<UUID> al;\r
369 private ArrayList<String> alComments;\r
370 private String phase;\r
371 private int len;\r
372 private int bodyLineNum;\r
373\r
374 public GuidTable (String phase) {\r
375 this.phase = phase;\r
376 al = new ArrayList<UUID>();\r
377 alComments = new ArrayList<String>();\r
378 len = 0;\r
379 bodyLineNum = 0;\r
380 }\r
381\r
382 public String getSizeMacro () {\r
383 return String.format(PcdDatabase.GuidTableSizeMacro, phase, getSize());\r
384 }\r
385\r
386 private int getSize () {\r
387 return (al.size() == 0)? 1 : al.size();\r
388 }\r
389\r
390 public String getExistanceMacro () {\r
391 return String.format(PcdDatabase.GuidTableExistenceMacro, phase, (al.size() == 0)? "TRUE":"FALSE");\r
392 }\r
393\r
394 public void genCode (ArrayList<CStructTypeDeclaration> declaList, HashMap<String, String> instTable, String phase) {\r
395 final String name = "GuidTable";\r
af98370e 396\r
241876c7 397 CStructTypeDeclaration decl;\r
398 String cCode = "";\r
399\r
af98370e 400 cCode += String.format(PcdDatabase.GuidTableDeclaration, phase);\r
241876c7 401 decl = new CStructTypeDeclaration (\r
402 name,\r
403 4,\r
404 cCode,\r
405 true\r
af98370e 406 );\r
241876c7 407 declaList.add(decl);\r
408\r
409\r
410 cCode = PcdDatabase.genInstantiationStr(getInstantiation());\r
411 instTable.put(name, cCode);\r
412 }\r
413\r
414 private String getUuidCString (UUID uuid) {\r
415 String[] guidStrArray;\r
416\r
417 guidStrArray =(uuid.toString()).split("-");\r
418\r
419 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}}",\r
420 guidStrArray[0],\r
421 guidStrArray[1],\r
422 guidStrArray[2],\r
423 (guidStrArray[3].substring(0, 2)),\r
424 (guidStrArray[3].substring(2, 4)),\r
425 (guidStrArray[4].substring(0, 2)),\r
426 (guidStrArray[4].substring(2, 4)),\r
427 (guidStrArray[4].substring(4, 6)),\r
428 (guidStrArray[4].substring(6, 8)),\r
429 (guidStrArray[4].substring(8, 10)),\r
430 (guidStrArray[4].substring(10, 12))\r
431 );\r
432 }\r
433\r
434 private ArrayList<String> getInstantiation () {\r
435 ArrayList<String> Output = new ArrayList<String>();\r
436\r
437 Output.add("/* GuidTable */");\r
438 Output.add("{");\r
439\r
440 if (al.size() == 0) {\r
441 Output.add("\t" + getUuidCString(new UUID(0, 0)));\r
442 }\r
af98370e 443\r
241876c7 444 for (int i = 0; i < al.size(); i++) {\r
445 String str = "\t" + getUuidCString(al.get(i));\r
446\r
447 str += "/* " + alComments.get(i) + " */";\r
448 if (i != (al.size() - 1)) {\r
449 str += ",";\r
450 }\r
451 Output.add(str);\r
452 bodyLineNum++;\r
453\r
454 }\r
455 Output.add("}");\r
456\r
457 return Output;\r
458 }\r
459\r
460 public int add (UUID uuid, String name) {\r
461 //\r
462 // Check if GuidTable has this entry already.\r
463 // If so, return the GuidTable index.\r
464 //\r
465 for (int i = 0; i < al.size(); i++) {\r
466 if (al.get(i).compareTo(uuid) == 0) {\r
467 return i;\r
468 }\r
469 }\r
af98370e 470\r
471 len++;\r
241876c7 472 al.add(uuid);\r
473 alComments.add(name);\r
474\r
475 //\r
476 // Return the previous Table Index\r
477 //\r
478 return len - 1;\r
479 }\r
480\r
481}\r
482\r
483/**\r
af98370e 484 SkuIdTable\r
485\r
241876c7 486 This class is used to store the SKU IDs in a PCD database.\r
487\r
488**/\r
489class SkuIdTable {\r
490 private ArrayList<Integer[]> al;\r
491 private ArrayList<String> alComment;\r
492 private String phase;\r
493 private int len;\r
494\r
495 public SkuIdTable (String phase) {\r
496 this.phase = phase;\r
497 al = new ArrayList<Integer[]>();\r
498 alComment = new ArrayList<String>();\r
499 len = 0;\r
500 }\r
501\r
502 public String getSizeMacro () {\r
503 return String.format(PcdDatabase.SkuIdTableSizeMacro, phase, getSize());\r
504 }\r
505\r
506 private int getSize () {\r
507 return (len == 0)? 1 : len;\r
508 }\r
509\r
510 public String getExistanceMacro () {\r
511 return String.format(PcdDatabase.SkuTableExistenceMacro, phase, (al.size() == 0)? "TRUE":"FALSE");\r
512 }\r
513\r
514 public void genCode (ArrayList<CStructTypeDeclaration> declaList, HashMap<String, String> instTable, String phase) {\r
515 final String name = "SkuIdTable";\r
af98370e 516\r
241876c7 517 CStructTypeDeclaration decl;\r
518 String cCode = "";\r
519\r
af98370e 520 cCode += String.format(PcdDatabase.SkuIdTableDeclaration, phase);\r
241876c7 521 decl = new CStructTypeDeclaration (\r
522 name,\r
523 1,\r
524 cCode,\r
525 true\r
af98370e 526 );\r
241876c7 527 declaList.add(decl);\r
528\r
529\r
530 cCode = PcdDatabase.genInstantiationStr(getInstantiation());\r
531 instTable.put(name, cCode);\r
532\r
533 //\r
534 // SystemSkuId is in PEI phase PCD Database\r
535 //\r
536 if (phase.equalsIgnoreCase("PEI")) {\r
537 decl = new CStructTypeDeclaration (\r
538 "SystemSkuId",\r
539 1,\r
540 String.format("%-20sSystemSkuId;\r\n", "SKU_ID"),\r
541 true\r
542 );\r
543 declaList.add(decl);\r
af98370e 544\r
241876c7 545 instTable.put("SystemSkuId", "0");\r
546 }\r
547\r
548 }\r
549\r
550 private ArrayList<String> getInstantiation () {\r
551 ArrayList<String> Output = new ArrayList<String> ();\r
552\r
553 Output.add("/* SkuIdTable */");\r
554 Output.add("{");\r
555\r
556 if (al.size() == 0) {\r
557 Output.add("\t0");\r
558 }\r
af98370e 559\r
241876c7 560 for (int index = 0; index < al.size(); index++) {\r
561 String str;\r
562\r
563 str = "/* " + alComment.get(index) + "*/ ";\r
564 str += "/* MaxSku */ ";\r
565\r
566\r
567 Integer[] ia = al.get(index);\r
568\r
569 str += "\t" + ia[0].toString() + ", ";\r
570 for (int index2 = 1; index2 < ia.length; index2++) {\r
571 str += ia[index2].toString();\r
572 if (!((index2 == ia.length - 1) && (index == al.size() - 1))) {\r
573 str += ", ";\r
574 }\r
575 }\r
576\r
577 Output.add(str);\r
578\r
579 }\r
580\r
581 Output.add("}");\r
582\r
583 return Output;\r
584 }\r
585\r
586 public int add (Token token) {\r
587\r
588 int index;\r
589 int pos;\r
af98370e 590\r
241876c7 591 //\r
592 // Check if this SKU_ID Array is already in the table\r
593 //\r
594 pos = 0;\r
595 for (Object o: al) {\r
596 Integer [] s = (Integer[]) o;\r
597 boolean different = false;\r
598 if (s[0] == token.getSkuIdCount()) {\r
599 for (index = 1; index < s.length; index++) {\r
600 if (s[index] != token.skuData.get(index-1).id) {\r
601 different = true;\r
602 break;\r
603 }\r
604 }\r
605 } else {\r
606 different = true;\r
607 }\r
608 if (different) {\r
609 pos += s[0] + 1;\r
610 } else {\r
611 return pos;\r
612 }\r
613 }\r
614\r
615 Integer [] skuIds = new Integer[token.skuData.size() + 1];\r
616 skuIds[0] = new Integer(token.skuData.size());\r
617 for (index = 1; index < skuIds.length; index++) {\r
618 skuIds[index] = new Integer(token.skuData.get(index - 1).id);\r
619 }\r
620\r
621 index = len;\r
622\r
af98370e 623 len += skuIds.length;\r
241876c7 624 al.add(skuIds);\r
625 alComment.add(token.getPrimaryKeyString());\r
626\r
627 return index;\r
628 }\r
629\r
630}\r
631\r
632class LocalTokenNumberTable {\r
633 private ArrayList<String> al;\r
634 private ArrayList<String> alComment;\r
635 private String phase;\r
636 private int len;\r
637\r
638 public LocalTokenNumberTable (String phase) {\r
639 this.phase = phase;\r
640 al = new ArrayList<String>();\r
641 alComment = new ArrayList<String>();\r
642\r
643 len = 0;\r
644 }\r
645\r
646 public String getSizeMacro () {\r
647 return String.format(PcdDatabase.LocalTokenNumberTableSizeMacro, phase, getSize())\r
648 + String.format(PcdDatabase.LocalTokenNumberSizeMacro, phase, al.size());\r
649 }\r
650\r
651 public int getSize () {\r
652 return (al.size() == 0)? 1 : al.size();\r
653 }\r
654\r
655 public String getExistanceMacro () {\r
656 return String.format(PcdDatabase.DatabaseExistenceMacro, phase, (al.size() == 0)? "TRUE":"FALSE");\r
657 }\r
658\r
659 public void genCode (ArrayList<CStructTypeDeclaration> declaList, HashMap<String, String> instTable, String phase) {\r
660 final String name = "LocalTokenNumberTable";\r
af98370e 661\r
241876c7 662 CStructTypeDeclaration decl;\r
663 String cCode = "";\r
664\r
af98370e 665 cCode += String.format(PcdDatabase.LocalTokenNumberTableDeclaration, phase);\r
241876c7 666 decl = new CStructTypeDeclaration (\r
667 name,\r
668 4,\r
669 cCode,\r
670 true\r
af98370e 671 );\r
241876c7 672 declaList.add(decl);\r
673\r
674 cCode = PcdDatabase.genInstantiationStr(getInstantiation());\r
675 instTable.put(name, cCode);\r
676 }\r
677\r
678 private ArrayList<String> getInstantiation () {\r
679 ArrayList<String> output = new ArrayList<String>();\r
680\r
681 output.add("/* LocalTokenNumberTable */");\r
682 output.add("{");\r
683\r
684 if (al.size() == 0) {\r
685 output.add("\t0");\r
686 }\r
af98370e 687\r
241876c7 688 for (int index = 0; index < al.size(); index++) {\r
689 String str;\r
690\r
691 str = "\t" + (String)al.get(index);\r
692\r
693 str += " /* " + alComment.get(index) + " */ ";\r
694\r
695\r
696 if (index != (al.size() - 1)) {\r
697 str += ",";\r
698 }\r
699\r
700 output.add(str);\r
701\r
702 }\r
703\r
704 output.add("}");\r
705\r
706 return output;\r
707 }\r
708\r
709 public int add (Token token) {\r
710 int index = len;\r
711 String str;\r
712\r
af98370e 713 len++;\r
241876c7 714\r
715 str = String.format(PcdDatabase.offsetOfStrTemplate, phase, token.hasDefaultValue() ? "Init" : "Uninit", token.getPrimaryKeyString());\r
716\r
717 if (token.isUnicodeStringType()) {\r
718 str += " | PCD_TYPE_STRING";\r
719 }\r
720\r
721 if (token.isSkuEnable()) {\r
722 str += " | PCD_TYPE_SKU_ENABLED";\r
723 }\r
724\r
725 if (token.getDefaultSku().type == DynamicTokenValue.VALUE_TYPE.HII_TYPE) {\r
726 str += " | PCD_TYPE_HII";\r
727 }\r
728\r
729 if (token.getDefaultSku().type == DynamicTokenValue.VALUE_TYPE.VPD_TYPE) {\r
730 str += " | PCD_TYPE_VPD";\r
731 }\r
af98370e 732\r
241876c7 733 switch (token.datumType) {\r
734 case UINT8:\r
735 case BOOLEAN:\r
736 str += " | PCD_DATUM_TYPE_UINT8";\r
737 break;\r
738 case UINT16:\r
739 str += " | PCD_DATUM_TYPE_UINT16";\r
740 break;\r
741 case UINT32:\r
742 str += " | PCD_DATUM_TYPE_UINT32";\r
743 break;\r
744 case UINT64:\r
745 str += " | PCD_DATUM_TYPE_UINT64";\r
746 break;\r
747 case POINTER:\r
748 str += " | PCD_DATUM_TYPE_POINTER";\r
749 break;\r
750 }\r
af98370e 751\r
241876c7 752 al.add(str);\r
753 alComment.add(token.getPrimaryKeyString());\r
754\r
755 return index;\r
756 }\r
757}\r
758\r
759/**\r
af98370e 760 ExMapTable\r
761\r
241876c7 762 This class is used to store the table of mapping information\r
763 between DynamicEX ID pair(Guid, TokenNumber) and\r
764 the local token number assigned by PcdDatabase class.\r
765**/\r
766class ExMapTable {\r
767\r
768 /**\r
af98370e 769 ExTriplet\r
770\r
241876c7 771 This class is used to store the mapping information\r
772 between DynamicEX ID pair(Guid, TokenNumber) and\r
773 the local token number assigned by PcdDatabase class.\r
774 **/\r
775 class ExTriplet {\r
776 public Integer guidTableIdx;\r
777 public Long exTokenNumber;\r
778 public Long localTokenIdx;\r
af98370e 779\r
241876c7 780 public ExTriplet (int guidTableIdx, long exTokenNumber, long localTokenIdx) {\r
781 this.guidTableIdx = new Integer(guidTableIdx);\r
782 this.exTokenNumber = new Long(exTokenNumber);\r
783 this.localTokenIdx = new Long(localTokenIdx);\r
784 }\r
785 }\r
786\r
787 private ArrayList<ExTriplet> al;\r
788 private Map<ExTriplet, String> alComment;\r
789 private String phase;\r
790 private int len;\r
791 private int bodyLineNum;\r
af98370e 792\r
241876c7 793 public ExMapTable (String phase) {\r
794 this.phase = phase;\r
795 al = new ArrayList<ExTriplet>();\r
796 alComment = new HashMap<ExTriplet, String>();\r
797 bodyLineNum = 0;\r
798 len = 0;\r
799 }\r
800\r
801 public String getSizeMacro () {\r
802 return String.format(PcdDatabase.ExMapTableSizeMacro, phase, getTableLen())\r
803 + String.format(PcdDatabase.ExTokenNumber, phase, al.size());\r
804 }\r
805\r
806 public String getExistanceMacro () {\r
807 return String.format(PcdDatabase.ExMapTableExistenceMacro, phase, (al.size() == 0)? "TRUE":"FALSE");\r
808 }\r
809\r
810 public void genCode (ArrayList<CStructTypeDeclaration> declaList, HashMap<String, String> instTable, String phase) {\r
811 final String exMapTableName = "ExMapTable";\r
af98370e 812\r
241876c7 813 sortTable();\r
af98370e 814\r
241876c7 815 CStructTypeDeclaration decl;\r
816 String cCode = "";\r
817\r
af98370e 818 cCode += String.format(PcdDatabase.ExMapTableDeclaration, phase);\r
241876c7 819 decl = new CStructTypeDeclaration (\r
820 exMapTableName,\r
821 4,\r
822 cCode,\r
823 true\r
af98370e 824 );\r
241876c7 825 declaList.add(decl);\r
826\r
827\r
828 cCode = PcdDatabase.genInstantiationStr(getInstantiation());\r
829 instTable.put(exMapTableName, cCode);\r
830 }\r
af98370e 831\r
241876c7 832 private ArrayList<String> getInstantiation () {\r
833 ArrayList<String> Output = new ArrayList<String>();\r
834\r
835 Output.add("/* ExMapTable */");\r
836 Output.add("{");\r
837 if (al.size() == 0) {\r
838 Output.add("\t{0, 0, 0}");\r
839 }\r
af98370e 840\r
241876c7 841 int index;\r
842 for (index = 0; index < al.size(); index++) {\r
843 String str;\r
844\r
845 ExTriplet e = (ExTriplet)al.get(index);\r
846\r
847 str = "\t" + "{ " + String.format("0x%08X", e.exTokenNumber) + ", ";\r
848 str += e.localTokenIdx.toString() + ", ";\r
849 str += e.guidTableIdx.toString();\r
850\r
851 str += "}" + " /* " + alComment.get(e) + " */" ;\r
852\r
853 if (index != al.size() - 1) {\r
854 str += ",";\r
855 }\r
856\r
857 Output.add(str);\r
858 bodyLineNum++;\r
859\r
860 }\r
861\r
862 Output.add("}");\r
863\r
864 return Output;\r
865 }\r
866\r
867 public int add (int localTokenIdx, long exTokenNum, int guidTableIdx, String name) {\r
868 int index = len;\r
869\r
870 len++;\r
af98370e 871 ExTriplet et = new ExTriplet(guidTableIdx, exTokenNum, localTokenIdx);\r
241876c7 872\r
873 al.add(et);\r
874 alComment.put(et, name);\r
875\r
876 return index;\r
877 }\r
878\r
879 private int getTableLen () {\r
880 return al.size() == 0 ? 1 : al.size();\r
881 }\r
882\r
883 //\r
884 // To simplify the algorithm for GetNextToken and GetNextTokenSpace in\r
885 // PCD PEIM/Driver, we need to sort the ExMapTable according to the\r
886 // following order:\r
887 // 1) ExGuid\r
888 // 2) ExTokenNumber\r
af98370e 889 //\r
241876c7 890 class ExTripletComp implements Comparator<ExTriplet> {\r
891 public int compare (ExTriplet a, ExTriplet b) {\r
892 if (a.guidTableIdx == b.guidTableIdx ) {\r
893 //\r
894 // exTokenNumber is long, we can't use simple substraction.\r
895 //\r
896 if (a.exTokenNumber > b.exTokenNumber) {\r
897 return 1;\r
898 } else if (a.exTokenNumber == b.exTokenNumber) {\r
899 return 0;\r
900 } else {\r
901 return -1;\r
902 }\r
903 }\r
af98370e 904\r
241876c7 905 return a.guidTableIdx - b.guidTableIdx;\r
906 }\r
907 }\r
908\r
909 private void sortTable () {\r
910 java.util.Comparator<ExTriplet> comparator = new ExTripletComp();\r
911 java.util.Collections.sort(al, comparator);\r
912 }\r
913}\r
914\r
915/**\r
af98370e 916 PcdDatabase\r
917\r
241876c7 918 This class is used to generate C code for Autogen.h and Autogen.c of\r
919 a PCD service DXE driver and PCD service PEIM.\r
920**/\r
921public class PcdDatabase {\r
922\r
923 private final static int SkuHeadAlignmentSize = 4;\r
924 private final String newLine = "\r\n";\r
925 private final String commaNewLine = ",\r\n";\r
926 private final String tab = "\t";\r
927 public final static String ExMapTableDeclaration = "DYNAMICEX_MAPPING ExMapTable[%s_EXMAPPING_TABLE_SIZE];\r\n";\r
928 public final static String GuidTableDeclaration = "EFI_GUID GuidTable[%s_GUID_TABLE_SIZE];\r\n";\r
929 public final static String LocalTokenNumberTableDeclaration = "UINT32 LocalTokenNumberTable[%s_LOCAL_TOKEN_NUMBER_TABLE_SIZE];\r\n";\r
930 public final static String StringTableDeclaration = "UINT16 StringTable[%s_STRING_TABLE_SIZE];\r\n";\r
931 public final static String SizeTableDeclaration = "SIZE_INFO SizeTable[%s_SIZE_TABLE_SIZE];\r\n";\r
932 public final static String SkuIdTableDeclaration = "UINT8 SkuIdTable[%s_SKUID_TABLE_SIZE];\r\n";\r
933\r
934\r
935 public final static String ExMapTableSizeMacro = "#define %s_EXMAPPING_TABLE_SIZE %d\r\n";\r
936 public final static String ExTokenNumber = "#define %s_EX_TOKEN_NUMBER %d\r\n";\r
af98370e 937 public final static String GuidTableSizeMacro = "#define %s_GUID_TABLE_SIZE %d\r\n";\r
241876c7 938 public final static String LocalTokenNumberTableSizeMacro = "#define %s_LOCAL_TOKEN_NUMBER_TABLE_SIZE %d\r\n";\r
939 public final static String LocalTokenNumberSizeMacro = "#define %s_LOCAL_TOKEN_NUMBER %d\r\n";\r
940 public final static String SizeTableSizeMacro = "#define %s_SIZE_TABLE_SIZE %d\r\n";\r
941 public final static String StringTableSizeMacro = "#define %s_STRING_TABLE_SIZE %d\r\n";\r
942 public final static String SkuIdTableSizeMacro = "#define %s_SKUID_TABLE_SIZE %d\r\n";\r
943\r
944\r
af98370e 945 public final static String ExMapTableExistenceMacro = "#define %s_EXMAP_TABLE_EMPTY %s\r\n";\r
241876c7 946 public final static String GuidTableExistenceMacro = "#define %s_GUID_TABLE_EMPTY %s\r\n";\r
947 public final static String DatabaseExistenceMacro = "#define %s_DATABASE_EMPTY %s\r\n";\r
948 public final static String StringTableExistenceMacro = "#define %s_STRING_TABLE_EMPTY %s\r\n";\r
949 public final static String SkuTableExistenceMacro = "#define %s_SKUID_TABLE_EMPTY %s\r\n";\r
950\r
951 public final static String offsetOfSkuHeadStrTemplate = "offsetof(%s_PCD_DATABASE, %s.%s_SkuDataTable)";\r
952 public final static String offsetOfVariableEnabledDefault = "offsetof(%s_PCD_DATABASE, %s.%s_VariableDefault_%d)";\r
953 public final static String offsetOfStrTemplate = "offsetof(%s_PCD_DATABASE, %s.%s)";\r
af98370e 954\r
241876c7 955 private final static String skuDataTableTemplate = "SkuDataTable";\r
956\r
957\r
958 private StringTable stringTable;\r
959 private GuidTable guidTable;\r
960 private LocalTokenNumberTable localTokenNumberTable;\r
961 private SkuIdTable skuIdTable;\r
962 private SizeTable sizeTable;\r
963 private ExMapTable exMapTable;\r
964\r
965 private ArrayList<Token> alTokens;\r
966 private String phase;\r
967 private int assignedTokenNumber;\r
af98370e 968\r
241876c7 969 //\r
970 // Use two class global variable to store\r
af98370e 971 // temperary\r
241876c7 972 //\r
973 private String privateGlobalName;\r
974 private String privateGlobalCCode;\r
975 //\r
976 // After Major changes done to the PCD\r
977 // database generation class PcdDatabase\r
978 // Please increment the version and please\r
979 // also update the version number in PCD\r
980 // service PEIM and DXE driver accordingly.\r
981 //\r
982 private final int version = 2;\r
983\r
984 private String hString;\r
985 private String cString;\r
986\r
987 /**\r
af98370e 988 Constructor for PcdDatabase class.\r
989\r
241876c7 990 <p>We have two PCD dynamic(ex) database for the Framework implementation. One\r
991 for PEI phase and the other for DXE phase. </p>\r
af98370e 992\r
241876c7 993 @param alTokens A ArrayList of Dynamic(EX) PCD entry.\r
994 @param exePhase The phase to generate PCD database for: valid input\r
995 is "PEI" or "DXE".\r
996 @param startLen The starting Local Token Number for the PCD database. For\r
997 PEI phase, the starting Local Token Number starts from 0.\r
998 For DXE phase, the starting Local Token Number starts\r
999 from the total number of PCD entry of PEI phase.\r
1000 @return void\r
1001 **/\r
1002 public PcdDatabase (ArrayList<Token> alTokens, String exePhase, int startLen) {\r
1003 phase = exePhase;\r
1004\r
1005 stringTable = new StringTable(phase);\r
1006 guidTable = new GuidTable(phase);\r
1007 localTokenNumberTable = new LocalTokenNumberTable(phase);\r
1008 skuIdTable = new SkuIdTable(phase);\r
1009 sizeTable = new SizeTable(phase);\r
af98370e 1010 exMapTable = new ExMapTable(phase);\r
241876c7 1011\r
1012 //\r
1013 // Local token number 0 is reserved for INVALID_TOKEN_NUMBER.\r
af98370e 1014 // So we will increment 1 for the startLen passed from the\r
241876c7 1015 // constructor.\r
1016 //\r
1017 assignedTokenNumber = startLen + 1;\r
1018 this.alTokens = alTokens;\r
1019 }\r
1020\r
1021 private void getNonExAndExTokens (ArrayList<Token> alTokens, List<Token> nexTokens, List<Token> exTokens) {\r
1022 for (int i = 0; i < alTokens.size(); i++) {\r
1023 Token t = (Token)alTokens.get(i);\r
1024 if (t.isDynamicEx()) {\r
1025 exTokens.add(t);\r
1026 } else {\r
1027 nexTokens.add(t);\r
1028 }\r
1029 }\r
1030\r
1031 return;\r
1032 }\r
1033\r
1034 private int getDataTypeAlignmentSize (Token token) {\r
1035 switch (token.datumType) {\r
1036 case UINT8:\r
1037 return 1;\r
1038 case UINT16:\r
1039 return 2;\r
1040 case UINT32:\r
1041 return 4;\r
1042 case UINT64:\r
1043 return 8;\r
1044 case POINTER:\r
1045 return 1;\r
1046 case BOOLEAN:\r
1047 return 1;\r
1048 default:\r
1049 return 1;\r
1050 }\r
1051 }\r
af98370e 1052\r
241876c7 1053 private int getHiiPtrTypeAlignmentSize(Token token) {\r
1054 switch (token.datumType) {\r
1055 case UINT8:\r
1056 return 1;\r
1057 case UINT16:\r
1058 return 2;\r
1059 case UINT32:\r
1060 return 4;\r
1061 case UINT64:\r
1062 return 8;\r
1063 case POINTER:\r
1064 if (token.isHiiEnable()) {\r
1065 if (token.isHiiDefaultValueUnicodeStringType()) {\r
1066 return 2;\r
1067 }\r
1068 }\r
1069 return 1;\r
1070 case BOOLEAN:\r
1071 return 1;\r
1072 default:\r
1073 return 1;\r
1074 }\r
1075 }\r
af98370e 1076\r
241876c7 1077 private int getAlignmentSize (Token token) {\r
1078 if (token.getDefaultSku().type == DynamicTokenValue.VALUE_TYPE.HII_TYPE) {\r
1079 return 2;\r
1080 }\r
1081\r
1082 if (token.getDefaultSku().type == DynamicTokenValue.VALUE_TYPE.VPD_TYPE) {\r
1083 return 4;\r
1084 }\r
1085\r
1086 if (token.isUnicodeStringType()) {\r
1087 return 2;\r
1088 }\r
af98370e 1089\r
241876c7 1090 return getDataTypeAlignmentSize(token);\r
1091 }\r
1092\r
1093 public String getCString () {\r
1094 return cString;\r
1095 }\r
1096\r
1097 public String getHString () {\r
1098 return hString;\r
1099 }\r
af98370e 1100\r
241876c7 1101 private void genCodeWorker(Token t,\r
1102 ArrayList<CStructTypeDeclaration> declaList,\r
1103 HashMap<String, String> instTable, String phase)\r
1104 throws EntityException {\r
1105\r
1106 CStructTypeDeclaration decl;\r
1107\r
1108 //\r
1109 // Insert SKU_HEAD if isSkuEnable is true\r
1110 //\r
1111 if (t.isSkuEnable()) {\r
1112 int tableIdx;\r
1113 tableIdx = skuIdTable.add(t);\r
1114 decl = new CStructTypeDeclaration(t.getPrimaryKeyString(),\r
1115 SkuHeadAlignmentSize, getSkuEnabledTypeDeclaration(t), true);\r
1116 declaList.add(decl);\r
1117 instTable.put(t.getPrimaryKeyString(),\r
1118 getSkuEnabledTypeInstantiaion(t, tableIdx));\r
1119 }\r
1120\r
1121 //\r
1122 // Insert PCD_ENTRY declaration and instantiation\r
1123 //\r
1124 getCDeclarationString(t);\r
1125\r
1126 decl = new CStructTypeDeclaration(privateGlobalName,\r
1127 getAlignmentSize(t), privateGlobalCCode, t.hasDefaultValue());\r
1128 declaList.add(decl);\r
1129\r
1130 if (t.hasDefaultValue()) {\r
af98370e 1131 instTable.put(privateGlobalName,\r
241876c7 1132 getTypeInstantiation(t, declaList, instTable, phase)\r
1133 );\r
1134 }\r
1135\r
1136 }\r
1137\r
af98370e 1138 private void ProcessTokens (List<Token> tokens,\r
241876c7 1139 ArrayList<CStructTypeDeclaration> cStructDeclList,\r
1140 HashMap<String, String> cStructInstTable,\r
1141 String phase\r
af98370e 1142 )\r
241876c7 1143 throws EntityException {\r
af98370e 1144\r
241876c7 1145 for (int idx = 0; idx < tokens.size(); idx++) {\r
1146 Token t = tokens.get(idx);\r
af98370e 1147\r
241876c7 1148 genCodeWorker (t, cStructDeclList, cStructInstTable, phase);\r
af98370e 1149\r
241876c7 1150 sizeTable.add(t);\r
1151 localTokenNumberTable.add(t);\r
1152 t.tokenNumber = assignedTokenNumber++;\r
af98370e 1153\r
241876c7 1154 //\r
1155 // Add a mapping if this dynamic PCD entry is a EX type\r
1156 //\r
1157 if (t.isDynamicEx()) {\r
af98370e 1158 exMapTable.add((int)t.tokenNumber,\r
1159 t.dynamicExTokenNumber,\r
1160 guidTable.add(translateSchemaStringToUUID(t.tokenSpaceName), t.getPrimaryKeyString()),\r
241876c7 1161 t.getPrimaryKeyString()\r
1162 );\r
1163 }\r
1164 }\r
1165\r
1166 }\r
af98370e 1167\r
241876c7 1168 public void genCode () throws EntityException {\r
af98370e 1169\r
241876c7 1170 ArrayList<CStructTypeDeclaration> cStructDeclList = new ArrayList<CStructTypeDeclaration>();\r
1171 HashMap<String, String> cStructInstTable = new HashMap<String, String>();\r
af98370e 1172\r
241876c7 1173 List<Token> nexTokens = new ArrayList<Token> ();\r
1174 List<Token> exTokens = new ArrayList<Token> ();\r
1175\r
1176 getNonExAndExTokens (alTokens, nexTokens, exTokens);\r
1177\r
1178 //\r
1179 // We have to process Non-Ex type PCD entry first. The reason is\r
af98370e 1180 // that our optimization assumes that the Token Number of Non-Ex\r
241876c7 1181 // PCD entry start from 1 (for PEI phase) and grows continously upwards.\r
af98370e 1182 //\r
241876c7 1183 // EX type token number starts from the last Non-EX PCD entry and\r
1184 // grows continously upwards.\r
1185 //\r
1186 ProcessTokens (nexTokens, cStructDeclList, cStructInstTable, phase);\r
1187 ProcessTokens (exTokens, cStructDeclList, cStructInstTable, phase);\r
af98370e 1188\r
241876c7 1189 stringTable.genCode(cStructDeclList, cStructInstTable);\r
1190 skuIdTable.genCode(cStructDeclList, cStructInstTable, phase);\r
1191 exMapTable.genCode(cStructDeclList, cStructInstTable, phase);\r
1192 localTokenNumberTable.genCode(cStructDeclList, cStructInstTable, phase);\r
1193 sizeTable.genCode(cStructDeclList, cStructInstTable, phase);\r
1194 guidTable.genCode(cStructDeclList, cStructInstTable, phase);\r
af98370e 1195\r
241876c7 1196 hString = genCMacroCode ();\r
af98370e 1197\r
241876c7 1198 HashMap <String, String> result;\r
af98370e 1199\r
1200 result = genCStructCode(cStructDeclList,\r
1201 cStructInstTable,\r
241876c7 1202 phase\r
1203 );\r
af98370e 1204\r
241876c7 1205 hString += result.get("initDeclStr");\r
1206 hString += result.get("uninitDeclStr");\r
af98370e 1207\r
241876c7 1208 hString += String.format("#define PCD_%s_SERVICE_DRIVER_VERSION %d", phase, version);\r
af98370e 1209\r
241876c7 1210 cString = newLine + newLine + result.get("initInstStr");\r
af98370e 1211\r
241876c7 1212 }\r
af98370e 1213\r
241876c7 1214 private String genCMacroCode () {\r
1215 String macroStr = "";\r
1216\r
1217 //\r
1218 // Generate size info Macro for all Tables\r
1219 //\r
1220 macroStr += guidTable.getSizeMacro();\r
1221 macroStr += stringTable.getSizeMacro();\r
1222 macroStr += skuIdTable.getSizeMacro();\r
1223 macroStr += localTokenNumberTable.getSizeMacro();\r
1224 macroStr += exMapTable.getSizeMacro();\r
1225 macroStr += sizeTable.getSizeMacro();\r
1226\r
1227 //\r
1228 // Generate existance info Macro for all Tables\r
1229 //\r
1230 macroStr += guidTable.getExistanceMacro();\r
1231 macroStr += stringTable.getExistanceMacro();\r
1232 macroStr += skuIdTable.getExistanceMacro();\r
1233 macroStr += localTokenNumberTable.getExistanceMacro();\r
1234 macroStr += exMapTable.getExistanceMacro();\r
1235\r
1236 macroStr += newLine;\r
af98370e 1237\r
241876c7 1238 return macroStr;\r
1239 }\r
af98370e 1240\r
241876c7 1241 private HashMap <String, String> genCStructCode(\r
af98370e 1242 ArrayList<CStructTypeDeclaration> declaList,\r
1243 HashMap<String, String> instTable,\r
241876c7 1244 String phase\r
1245 ) {\r
af98370e 1246\r
241876c7 1247 int i;\r
1248 HashMap <String, String> result = new HashMap<String, String>();\r
1249 HashMap <Integer, ArrayList<String>> alignmentInitDecl = new HashMap<Integer, ArrayList<String>>();\r
1250 HashMap <Integer, ArrayList<String>> alignmentUninitDecl = new HashMap<Integer, ArrayList<String>>();\r
1251 HashMap <Integer, ArrayList<String>> alignmentInitInst = new HashMap<Integer, ArrayList<String>>();\r
af98370e 1252\r
241876c7 1253 //\r
1254 // Initialize the storage for each alignment\r
1255 //\r
1256 for (i = 8; i > 0; i>>=1) {\r
1257 alignmentInitDecl.put(new Integer(i), new ArrayList<String>());\r
1258 alignmentInitInst.put(new Integer(i), new ArrayList<String>());\r
1259 alignmentUninitDecl.put(new Integer(i), new ArrayList<String>());\r
1260 }\r
af98370e 1261\r
241876c7 1262 String initDeclStr = "typedef struct {" + newLine;\r
1263 String initInstStr = String.format("%s_PCD_DATABASE_INIT g%sPcdDbInit = { ", phase.toUpperCase(), phase.toUpperCase()) + newLine;\r
1264 String uninitDeclStr = "typedef struct {" + newLine;\r
1265\r
1266 //\r
af98370e 1267 // Sort all C declaration and instantiation base on Alignment Size\r
241876c7 1268 //\r
1269 for (Object d : declaList) {\r
1270 CStructTypeDeclaration decl = (CStructTypeDeclaration) d;\r
af98370e 1271\r
241876c7 1272 if (decl.initTable) {\r
1273 alignmentInitDecl.get(new Integer(decl.alignmentSize)).add(decl.cCode);\r
1274 alignmentInitInst.get(new Integer(decl.alignmentSize)).add(instTable.get(decl.key));\r
1275 } else {\r
1276 alignmentUninitDecl.get(new Integer(decl.alignmentSize)).add(decl.cCode);\r
1277 }\r
1278 }\r
1279\r
1280 //\r
1281 // Generate code for every alignment size\r
1282 //\r
1283 boolean uinitDatabaseEmpty = true;\r
1284 for (int align = 8; align > 0; align >>= 1) {\r
1285 ArrayList<String> declaListBasedOnAlignment = alignmentInitDecl.get(new Integer(align));\r
1286 ArrayList<String> instListBasedOnAlignment = alignmentInitInst.get(new Integer(align));\r
1287 for (i = 0; i < declaListBasedOnAlignment.size(); i++) {\r
1288 initDeclStr += tab + declaListBasedOnAlignment.get(i);\r
1289 initInstStr += tab + instListBasedOnAlignment.get(i);\r
af98370e 1290\r
241876c7 1291 //\r
1292 // We made a assumption that both PEI_PCD_DATABASE and DXE_PCD_DATABASE\r
1293 // has a least one data memember with alignment size of 1. So we can\r
1294 // remove the last "," in the C structure instantiation string. Luckily,\r
1295 // this is true as both data structure has SKUID_TABLE anyway.\r
1296 //\r
1297 if ((align == 1) && (i == declaListBasedOnAlignment.size() - 1)) {\r
1298 initInstStr += newLine;\r
1299 } else {\r
1300 initInstStr += commaNewLine;\r
1301 }\r
1302 }\r
af98370e 1303\r
241876c7 1304 declaListBasedOnAlignment = alignmentUninitDecl.get(new Integer(align));\r
af98370e 1305\r
241876c7 1306 if (declaListBasedOnAlignment.size() != 0) {\r
1307 uinitDatabaseEmpty = false;\r
1308 }\r
af98370e 1309\r
241876c7 1310 for (Object d : declaListBasedOnAlignment) {\r
1311 String s = (String)d;\r
1312 uninitDeclStr += tab + s;\r
1313 }\r
1314 }\r
af98370e 1315\r
241876c7 1316 if (uinitDatabaseEmpty) {\r
1317 uninitDeclStr += tab + String.format("%-20sdummy; /* PCD_DATABASE_UNINIT is emptry */\r\n", "UINT8");\r
1318 }\r
af98370e 1319\r
241876c7 1320 initDeclStr += String.format("} %s_PCD_DATABASE_INIT;", phase) + newLine + newLine;\r
1321 initInstStr += "};" + newLine;\r
1322 uninitDeclStr += String.format("} %s_PCD_DATABASE_UNINIT;", phase) + newLine + newLine;\r
af98370e 1323\r
241876c7 1324 result.put("initDeclStr", initDeclStr);\r
1325 result.put("initInstStr", initInstStr);\r
1326 result.put("uninitDeclStr", uninitDeclStr);\r
1327\r
1328 return result;\r
1329 }\r
1330\r
1331 public static String genInstantiationStr (ArrayList<String> alStr) {\r
1332 String str = "";\r
1333 for (int i = 0; i< alStr.size(); i++) {\r
1334 if (i != 0) {\r
1335 str += "\t";\r
1336 }\r
1337 str += alStr.get(i);\r
1338 if (i != alStr.size() - 1) {\r
1339 str += "\r\n";\r
1340 }\r
1341 }\r
1342\r
1343 return str;\r
1344 }\r
1345\r
1346 private String getSkuEnabledTypeDeclaration (Token token) {\r
1347 return String.format("%-20s%s;\r\n", "SKU_HEAD", token.getPrimaryKeyString());\r
1348 }\r
1349\r
1350 private String getSkuEnabledTypeInstantiaion (Token token, int SkuTableIdx) {\r
1351\r
1352 String offsetof = String.format(PcdDatabase.offsetOfSkuHeadStrTemplate, phase, token.hasDefaultValue()? "Init" : "Uninit", token.getPrimaryKeyString());\r
1353 return String.format("{ %s, %d } /* SKU_ENABLED: %s */", offsetof, SkuTableIdx, token.getPrimaryKeyString());\r
1354 }\r
1355\r
1356 private String getDataTypeInstantiationForVariableDefault (Token token, String cName, int skuId) {\r
1357 return String.format("%s /* %s */", token.skuData.get(skuId).value.hiiDefaultValue, cName);\r
1358 }\r
1359\r
af98370e 1360 private String getCType (Token t)\r
241876c7 1361 throws EntityException {\r
af98370e 1362\r
241876c7 1363 if (t.isHiiEnable()) {\r
1364 return "VARIABLE_HEAD";\r
1365 }\r
af98370e 1366\r
241876c7 1367 if (t.isVpdEnable()) {\r
1368 return "VPD_HEAD";\r
1369 }\r
af98370e 1370\r
241876c7 1371 if (t.isUnicodeStringType()) {\r
1372 return "STRING_HEAD";\r
1373 }\r
af98370e 1374\r
241876c7 1375 switch (t.datumType) {\r
1376 case UINT64:\r
1377 return "UINT64";\r
1378 case UINT32:\r
1379 return "UINT32";\r
1380 case UINT16:\r
1381 return "UINT16";\r
1382 case UINT8:\r
1383 return "UINT8";\r
1384 case BOOLEAN:\r
1385 return "BOOLEAN";\r
1386 case POINTER:\r
1387 return "UINT8";\r
1388 default:\r
391dbbb1 1389 throw new EntityException("Unknown DatumType in getDataTypeCDeclaration");\r
241876c7 1390 }\r
1391 }\r
af98370e 1392\r
241876c7 1393 //\r
1394 // privateGlobalName and privateGlobalCCode is used to pass output to caller of getCDeclarationString\r
1395 //\r
af98370e 1396 private void getCDeclarationString(Token t)\r
241876c7 1397 throws EntityException {\r
af98370e 1398\r
241876c7 1399 if (t.isSkuEnable()) {\r
1400 privateGlobalName = String.format("%s_%s", t.getPrimaryKeyString(), skuDataTableTemplate);\r
1401 } else {\r
1402 privateGlobalName = t.getPrimaryKeyString();\r
1403 }\r
1404\r
1405 String type = getCType(t);\r
1406 if ((t.datumType == Token.DATUM_TYPE.POINTER) && (!t.isHiiEnable()) && (!t.isUnicodeStringType())) {\r
1407 int bufferSize;\r
1408 if (t.isASCIIStringType()) {\r
1409 //\r
1410 // Build tool will add a NULL string at the end of the ASCII string\r
1411 //\r
1412 bufferSize = t.datumSize + 1;\r
1413 } else {\r
1414 bufferSize = t.datumSize;\r
1415 }\r
1416 privateGlobalCCode = String.format("%-20s%s[%d][%d];\r\n", type, privateGlobalName, t.getSkuIdCount(), bufferSize);\r
1417 } else {\r
1418 privateGlobalCCode = String.format("%-20s%s[%d];\r\n", type, privateGlobalName, t.getSkuIdCount());\r
1419 }\r
1420 }\r
af98370e 1421\r
1422 private String getDataTypeDeclarationForVariableDefault (Token token, String cName, int skuId)\r
241876c7 1423 throws EntityException {\r
1424\r
1425 String typeStr;\r
1426\r
1427 if (token.datumType == Token.DATUM_TYPE.UINT8) {\r
1428 typeStr = "UINT8";\r
1429 } else if (token.datumType == Token.DATUM_TYPE.UINT16) {\r
1430 typeStr = "UINT16";\r
1431 } else if (token.datumType == Token.DATUM_TYPE.UINT32) {\r
1432 typeStr = "UINT32";\r
1433 } else if (token.datumType == Token.DATUM_TYPE.UINT64) {\r
1434 typeStr = "UINT64";\r
1435 } else if (token.datumType == Token.DATUM_TYPE.BOOLEAN) {\r
1436 typeStr = "BOOLEAN";\r
1437 } else if (token.datumType == Token.DATUM_TYPE.POINTER) {\r
1438 int size;\r
1439 if (token.isHiiDefaultValueUnicodeStringType()) {\r
1440 typeStr = "UINT16";\r
1441 //\r
1442 // Include the NULL charactor\r
1443 //\r
1444 size = token.datumSize / 2 + 1;\r
1445 } else {\r
1446 typeStr = "UINT8";\r
1447 if (token.isHiiDefaultValueASCIIStringType()) {\r
1448 //\r
1449 // Include the NULL charactor\r
1450 //\r
1451 size = token.datumSize + 1;\r
1452 } else {\r
1453 size = token.datumSize;\r
1454 }\r
1455 }\r
1456 return String.format("%-20s%s[%d];\r\n", typeStr, cName, size);\r
1457 } else {\r
1458 throw new EntityException("Unknown DATUM_TYPE type in when generating code for VARIABLE_ENABLED PCD entry");\r
1459 }\r
1460\r
1461 return String.format("%-20s%s;\r\n", typeStr, cName);\r
1462 }\r
af98370e 1463\r
241876c7 1464 private String getTypeInstantiation (Token t, ArrayList<CStructTypeDeclaration> declaList, HashMap<String, String> instTable, String phase) throws EntityException {\r
af98370e 1465\r
241876c7 1466 int i;\r
1467\r
1468 String s;\r
1469 s = String.format("/* %s */", t.getPrimaryKeyString()) + newLine;\r
1470 s += tab + "{" + newLine;\r
1471\r
1472 for (i = 0; i < t.skuData.size(); i++) {\r
1473 if (t.isUnicodeStringType()) {\r
1474 s += tab + tab + String.format("{ %d }", stringTable.add(t.skuData.get(i).value.value, t));\r
1475 } else if (t.isHiiEnable()) {\r
1476 /* VPD_HEAD definition\r
1477 typedef struct {\r
1478 UINT16 GuidTableIndex; // Offset in Guid Table in units of GUID.\r
1479 UINT16 StringIndex; // Offset in String Table in units of UINT16.\r
1480 UINT16 Offset; // Offset in Variable\r
1481 UINT16 DefaultValueOffset; // Offset of the Default Value\r
1482 } VARIABLE_HEAD ;\r
1483 */\r
af98370e 1484 String variableDefaultName = String.format("%s_VariableDefault_%d", t.getPrimaryKeyString(), i);\r
1485\r
241876c7 1486 s += tab + tab + String.format("{ %d, %d, %s, %s }", guidTable.add(t.skuData.get(i).value.variableGuid, t.getPrimaryKeyString()),\r
1487 stringTable.add(t.skuData.get(i).value.getStringOfVariableName(), t),\r
1488 t.skuData.get(i).value.variableOffset,\r
1489 String.format("offsetof(%s_PCD_DATABASE, Init.%s)", phase, variableDefaultName)\r
1490 );\r
1491 //\r
1492 // We need to support the default value, so we add the declaration and\r
1493 // the instantiation for the default value.\r
1494 //\r
1495 CStructTypeDeclaration decl = new CStructTypeDeclaration (variableDefaultName,\r
1496 getHiiPtrTypeAlignmentSize(t),\r
1497 getDataTypeDeclarationForVariableDefault(t, variableDefaultName, i),\r
1498 true\r
af98370e 1499 );\r
241876c7 1500 declaList.add(decl);\r
1501 instTable.put(variableDefaultName, getDataTypeInstantiationForVariableDefault (t, variableDefaultName, i));\r
1502 } else if (t.isVpdEnable()) {\r
1503 /* typedef struct {\r
1504 UINT32 Offset;\r
1505 } VPD_HEAD;\r
1506 */\r
1507 s += tab + tab + String.format("{ %s }", t.skuData.get(i).value.vpdOffset);\r
1508 } else {\r
1509 if (t.isByteStreamType()) {\r
1510 //\r
1511 // Byte stream type input has their own "{" "}", so we won't help to insert.\r
1512 //\r
1513 s += tab + tab + String.format(" %s ", t.skuData.get(i).value.value);\r
1514 } else {\r
1515 s += tab + tab + String.format("{ %s }", t.skuData.get(i).value.value);\r
1516 }\r
1517 }\r
af98370e 1518\r
241876c7 1519 if (i != t.skuData.size() - 1) {\r
1520 s += commaNewLine;\r
1521 } else {\r
1522 s += newLine;\r
1523 }\r
1524\r
1525 }\r
af98370e 1526\r
241876c7 1527 s += tab + "}";\r
af98370e 1528\r
241876c7 1529 return s;\r
1530 }\r
af98370e 1531\r
2c0e2bcf 1532 public static String getPcdDatabaseCommonDefinitions () {\r
1533\r
1534 String retStr;\r
1535\r
1536 retStr = "//\r\n";\r
1537 retStr += "// The following definition will be generated by build tool\r\n";\r
1538 retStr += "//\r\n";\r
1539 retStr += "\r\n";\r
1540 retStr += "//\r\n";\r
1541 retStr += "// Common definitions\r\n";\r
1542 retStr += "//\r\n";\r
1543 retStr += "typedef UINT8 SKU_ID;\r\n";\r
1544 retStr += "\r\n";\r
1545 retStr += "#define PCD_TYPE_SHIFT 28\r\n";\r
1546 retStr += "\r\n";\r
1547 retStr += "#define PCD_TYPE_DATA (0x0 << PCD_TYPE_SHIFT)\r\n";\r
1548 retStr += "#define PCD_TYPE_HII (0x8 << PCD_TYPE_SHIFT)\r\n";\r
1549 retStr += "#define PCD_TYPE_VPD (0x4 << PCD_TYPE_SHIFT)\r\n";\r
1550 retStr += "#define PCD_TYPE_SKU_ENABLED (0x2 << PCD_TYPE_SHIFT)\r\n";\r
1551 retStr += "#define PCD_TYPE_STRING (0x1 << PCD_TYPE_SHIFT)\r\n";\r
1552 retStr += "\r\n";\r
1553 retStr += "#define PCD_TYPE_ALL_SET (PCD_TYPE_DATA | PCD_TYPE_HII | PCD_TYPE_VPD | PCD_TYPE_SKU_ENABLED | PCD_TYPE_STRING)\r\n";\r
1554 retStr += "\r\n";\r
1555 retStr += "#define PCD_DATUM_TYPE_SHIFT 24\r\n";\r
1556 retStr += "\r\n";\r
1557 retStr += "#define PCD_DATUM_TYPE_POINTER (0x0 << PCD_DATUM_TYPE_SHIFT)\r\n";\r
1558 retStr += "#define PCD_DATUM_TYPE_UINT8 (0x1 << PCD_DATUM_TYPE_SHIFT)\r\n";\r
1559 retStr += "#define PCD_DATUM_TYPE_UINT16 (0x2 << PCD_DATUM_TYPE_SHIFT)\r\n";\r
1560 retStr += "#define PCD_DATUM_TYPE_UINT32 (0x4 << PCD_DATUM_TYPE_SHIFT)\r\n";\r
1561 retStr += "#define PCD_DATUM_TYPE_UINT64 (0x8 << PCD_DATUM_TYPE_SHIFT)\r\n";\r
1562 retStr += "\r\n";\r
1563 retStr += "#define PCD_DATUM_TYPE_ALL_SET (PCD_DATUM_TYPE_POINTER | \\\r\n";\r
1564 retStr += " PCD_DATUM_TYPE_UINT8 | \\\r\n";\r
1565 retStr += " PCD_DATUM_TYPE_UINT16 | \\\r\n";\r
1566 retStr += " PCD_DATUM_TYPE_UINT32 | \\\r\n";\r
1567 retStr += " PCD_DATUM_TYPE_UINT64)\r\n";\r
1568 retStr += "\r\n";\r
1569 retStr += "\r\n";\r
1570 retStr += "#define PCD_DATABASE_OFFSET_MASK (~(PCD_TYPE_ALL_SET | PCD_DATUM_TYPE_ALL_SET))\r\n";\r
1571 retStr += "\r\n";\r
1572 retStr += "typedef struct {\r\n";\r
1573 retStr += " UINT32 ExTokenNumber;\r\n";\r
1574 retStr += " UINT16 LocalTokenNumber; // PCD Number of this particular platform build\r\n";\r
1575 retStr += " UINT16 ExGuidIndex; // Index of GuidTable\r\n";\r
1576 retStr += "} DYNAMICEX_MAPPING;\r\n";\r
1577 retStr += "\r\n";\r
1578 retStr += "\r\n";\r
1579 retStr += "typedef struct {\r\n";\r
1580 retStr += " UINT32 SkuDataStartOffset; //We have to use offsetof MACRO as we don't know padding done by compiler\r\n";\r
1581 retStr += " UINT32 SkuIdTableOffset; //Offset from the PCD_DB\r\n";\r
1582 retStr += "} SKU_HEAD;\r\n";\r
1583 retStr += "\r\n";\r
1584 retStr += "\r\n";\r
1585 retStr += "typedef struct {\r\n";\r
1586 retStr += " UINT16 GuidTableIndex; // Offset in Guid Table in units of GUID.\r\n";\r
1587 retStr += " UINT16 StringIndex; // Offset in String Table in units of UINT16.\r\n";\r
1588 retStr += " UINT16 Offset; // Offset in Variable\r\n";\r
1589 retStr += " UINT16 DefaultValueOffset; // Offset of the Default Value\r\n";\r
1590 retStr += "} VARIABLE_HEAD ;\r\n";\r
1591 retStr += "\r\n";\r
1592 retStr += "\r\n";\r
1593 retStr += "typedef struct {\r\n";\r
1594 retStr += " UINT32 Offset;\r\n";\r
1595 retStr += "} VPD_HEAD;\r\n";\r
1596 retStr += "\r\n";\r
1597 retStr += "typedef UINT16 STRING_HEAD;\r\n";\r
1598 retStr += "\r\n";\r
1599 retStr += "typedef UINT16 SIZE_INFO;\r\n";\r
1600 retStr += "\r\n";\r
1601 retStr += "#define offsetof(s,m) (UINT32) (UINTN) &(((s *)0)->m)\r\n";\r
1602 retStr += "\r\n";\r
1603 retStr += "\r\n";\r
1604 retStr += "\r\n";\r
1605 \r
1606 return retStr;\r
241876c7 1607 }\r
1608\r
af98370e 1609 public static String getPcdDxeDatabaseDefinitions ()\r
241876c7 1610 throws EntityException {\r
1611\r
1612 String retStr = "";\r
2c0e2bcf 1613 \r
1614 retStr += "\r\n";\r
1615 retStr += "typedef struct {\r\n";\r
1616 retStr += " DXE_PCD_DATABASE_INIT Init;\r\n";\r
1617 retStr += " DXE_PCD_DATABASE_UNINIT Uninit;\r\n";\r
1618 retStr += "} DXE_PCD_DATABASE;\r\n";\r
1619 retStr += "\r\n";\r
1620 retStr += "\r\n";\r
1621 retStr += "typedef struct {\r\n";\r
1622 retStr += " PEI_PCD_DATABASE PeiDb;\r\n";\r
1623 retStr += " DXE_PCD_DATABASE DxeDb;\r\n";\r
1624 retStr += "} PCD_DATABASE;\r\n";\r
1625 retStr += "\r\n";\r
1626 retStr += "#define DXE_NEX_TOKEN_NUMBER (DXE_LOCAL_TOKEN_NUMBER - DXE_EX_TOKEN_NUMBER)\r\n";\r
1627 retStr += "\r\n";\r
1628 retStr += "#define PCD_TOTAL_TOKEN_NUMBER (PEI_LOCAL_TOKEN_NUMBER + DXE_LOCAL_TOKEN_NUMBER)\r\n";\r
1629 retStr += "\r\n";\r
1630 retStr += "\r\n";\r
241876c7 1631\r
1632 return retStr;\r
1633 }\r
1634\r
af98370e 1635 public static String getPcdPeiDatabaseDefinitions ()\r
241876c7 1636 throws EntityException {\r
1637\r
2c0e2bcf 1638 String retStr = "";\r
1639 \r
1640 retStr += "\r\n";\r
1641 retStr += "typedef struct {\r\n";\r
1642 retStr += " PEI_PCD_DATABASE_INIT Init;\r\n";\r
1643 retStr += " PEI_PCD_DATABASE_UNINIT Uninit;\r\n";\r
1644 retStr += "} PEI_PCD_DATABASE;\r\n";\r
1645 retStr += "\r\n";\r
1646 retStr += "#define PEI_NEX_TOKEN_NUMBER (PEI_LOCAL_TOKEN_NUMBER - PEI_EX_TOKEN_NUMBER)\r\n";\r
1647 retStr += "\r\n";\r
241876c7 1648\r
1649 return retStr;\r
1650 }\r
1651\r
1652 /**\r
1653 Translate the schema string to UUID instance.\r
af98370e 1654\r
241876c7 1655 In schema, the string of UUID is defined as following two types string:\r
1656 1) GuidArrayType: pattern = 0x[a-fA-F0-9]{1,8},( )*0x[a-fA-F0-9]{1,4},(\r
1657 )*0x[a-fA-F0-9]{1,4}(,( )*\{)?(,?( )*0x[a-fA-F0-9]{1,2}){8}( )*(\})?\r
af98370e 1658\r
241876c7 1659 2) GuidNamingConvention: pattern =\r
1660 [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}\r
af98370e 1661\r
241876c7 1662 This function will convert string and create uuid instance.\r
af98370e 1663\r
241876c7 1664 @param uuidString UUID string in XML file\r
af98370e 1665\r
241876c7 1666 @return UUID UUID instance\r
1667 **/\r
af98370e 1668 private UUID translateSchemaStringToUUID(String uuidString)\r
241876c7 1669 throws EntityException {\r
1670 String temp;\r
1671 String[] splitStringArray;\r
1672 int index;\r
1673 int chIndex;\r
1674 int chLen;\r
1675\r
1676 if (uuidString == null) {\r
1677 return null;\r
1678 }\r
1679\r
1680 if (uuidString.length() == 0) {\r
1681 return null;\r
1682 }\r
1683\r
1684 if (uuidString.equals("0") ||\r
1685 uuidString.equalsIgnoreCase("0x0")) {\r
1686 return new UUID(0, 0);\r
1687 }\r
1688\r
1689 uuidString = uuidString.replaceAll("\\{", "");\r
1690 uuidString = uuidString.replaceAll("\\}", "");\r
1691\r
1692 //\r
af98370e 1693 // If the UUID schema string is GuidArrayType type then need translate\r
241876c7 1694 // to GuidNamingConvention type at first.\r
af98370e 1695 //\r
241876c7 1696 if ((uuidString.charAt(0) == '0') && ((uuidString.charAt(1) == 'x') || (uuidString.charAt(1) == 'X'))) {\r
1697 splitStringArray = uuidString.split("," );\r
1698 if (splitStringArray.length != 11) {\r
391dbbb1 1699 throw new EntityException ("[FPD file error] Wrong format for GUID string: " + uuidString);\r
241876c7 1700 }\r
1701\r
1702 //\r
1703 // Remove blank space from these string and remove header string "0x"\r
af98370e 1704 //\r
241876c7 1705 for (index = 0; index < 11; index ++) {\r
1706 splitStringArray[index] = splitStringArray[index].trim();\r
1707 splitStringArray[index] = splitStringArray[index].substring(2, splitStringArray[index].length());\r
1708 }\r
1709\r
1710 //\r
1711 // Add heading '0' to normalize the string length\r
af98370e 1712 //\r
241876c7 1713 for (index = 3; index < 11; index ++) {\r
1714 chLen = splitStringArray[index].length();\r
1715 for (chIndex = 0; chIndex < 2 - chLen; chIndex ++) {\r
1716 splitStringArray[index] = "0" + splitStringArray[index];\r
1717 }\r
1718 }\r
1719\r
1720 //\r
1721 // construct the final GuidNamingConvention string\r
af98370e 1722 //\r
241876c7 1723 temp = String.format("%s-%s-%s-%s%s-%s%s%s%s%s%s",\r
1724 splitStringArray[0],\r
1725 splitStringArray[1],\r
1726 splitStringArray[2],\r
1727 splitStringArray[3],\r
1728 splitStringArray[4],\r
1729 splitStringArray[5],\r
1730 splitStringArray[6],\r
1731 splitStringArray[7],\r
1732 splitStringArray[8],\r
1733 splitStringArray[9],\r
1734 splitStringArray[10]);\r
1735 uuidString = temp;\r
1736 }\r
1737\r
1738 return UUID.fromString(uuidString);\r
1739 }\r
391dbbb1 1740}\r