]> git.proxmox.com Git - mirror_edk2.git/blame - Tools/Source/GenBuild/org/tianocore/build/pcd/action/PCDAutoGenAction.java
Fix a bug of unreference PCD token defined in FPD does *not* be autogened into emulat...
[mirror_edk2.git] / Tools / Source / GenBuild / org / tianocore / build / pcd / action / PCDAutoGenAction.java
CommitLineData
878ddf1f 1/** @file\r
2 PCDAutoGenAction class.\r
3\r
4 This class is to manage how to generate the PCD information into Autogen.c and\r
5 Autogen.h.\r
6 \r
7Copyright (c) 2006, Intel Corporation\r
8All rights reserved. This program and the accompanying materials\r
9are licensed and made available under the terms and conditions of the BSD License\r
10which accompanies this distribution. The full text of the license may be found at\r
11http://opensource.org/licenses/bsd-license.php\r
12 \r
13THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
14WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
15\r
16**/\r
17package org.tianocore.build.pcd.action;\r
18\r
19import java.io.File;\r
20import java.util.List;\r
21\r
22import org.tianocore.build.global.GlobalData;\r
23import org.tianocore.build.pcd.entity.MemoryDatabaseManager;\r
24import org.tianocore.build.pcd.entity.Token;\r
25import org.tianocore.build.pcd.entity.UsageInstance;\r
26import org.tianocore.build.pcd.exception.BuildActionException;\r
27import org.tianocore.build.pcd.exception.EntityException;\r
28\r
29/** This class is to manage how to generate the PCD information into Autogen.c and\r
30 Autogen.h.\r
31**/\r
32public class PCDAutoGenAction extends BuildAction {\r
33 ///\r
34 /// The reference of DBManager in GlobalData class.\r
35 ///\r
36 private MemoryDatabaseManager dbManager;\r
37 ///\r
38 /// The name of module which is analysised currently.\r
39 ///\r
40 private String moduleName;\r
41 ///\r
42 /// Wheter current module is PCD emulated driver. It is only for \r
43 /// emulated PCD driver and will be kept until PCD IMAGE tool ready.\r
44 ///\r
45 private boolean isEmulatedPCDDriver;\r
46 ///\r
47 /// The generated string for header file.\r
48 ///\r
49 private String hAutoGenString;\r
50 ///\r
51 /// The generated string for C code file.\r
52 ///\r
53 private String cAutoGenString; \r
54\r
55 /**\r
56 Set parameter ModuleName\r
57 \r
58 @param moduleName the module name parameter.\r
59 **/\r
60 public void setModuleName(String moduleName) {\r
61 this.moduleName = moduleName;\r
62 }\r
63\r
64 /**\r
65 Set parameter isEmulatedPCDDriver\r
66 \r
67 @param isEmulatedPCDDriver whether this module is PeiEmulatedPCD driver\r
68 **/\r
69 public void setIsEmulatedPCDDriver(boolean isEmulatedPCDDriver) {\r
70 this.isEmulatedPCDDriver = isEmulatedPCDDriver;\r
71 }\r
72\r
73 /**\r
74 Get the output of generated string for header file.\r
75 \r
76 @return the string of header file for PCD\r
77 **/\r
78 public String OutputH() {\r
79 return hAutoGenString;\r
80 }\r
81\r
82 /**\r
83 Get the output of generated string for C Code file.\r
84 \r
85 @return the string of C code file for PCD\r
86 **/\r
87 public String OutputC() {\r
88 return cAutoGenString;\r
89 }\r
90\r
91 /**\r
92 Construct function\r
93 \r
94 This function mainly initialize some member variable.\r
95 \r
96 @param moduleName Parameter of this action class.\r
97 @param isEmulatedPCDDriver Parameter of this action class.\r
98 **/\r
99 public PCDAutoGenAction(String moduleName, boolean isEmulatedPCDDriver) {\r
100 dbManager = null;\r
101 setIsEmulatedPCDDriver(isEmulatedPCDDriver);\r
102 setModuleName(moduleName);\r
103 }\r
104\r
105 /**\r
106 check the parameter for action class.\r
107 \r
108 @throws BuildActionException Bad parameter.\r
109 **/\r
110 void checkParameter() throws BuildActionException {\r
111 if(!isEmulatedPCDDriver &&(moduleName == null)) {\r
112 throw new BuildActionException("Wrong module name parameter for PCDAutoGenAction tool!");\r
113 }\r
114\r
115 if(!isEmulatedPCDDriver && moduleName.length() == 0) {\r
116 throw new BuildActionException("Wrong module name parameter for PCDAutoGenAction tool!");\r
117 }\r
878ddf1f 118 }\r
119\r
120 /**\r
121 Core execution function for this action class.\r
122 \r
123 All PCD information of this module comes from memory dabase. The collection\r
124 work should be done before this action execution.\r
125 Currently, we should generated all PCD information(maybe all dynamic) as array \r
126 in Pei emulated driver for simulating PCD runtime database. \r
127 \r
128 @throws BuildActionException Failed to execute this aciton class.\r
129 **/\r
130 void performAction() throws BuildActionException {\r
131 ActionMessage.debug(this, \r
132 "Starting PCDAutoGenAction to generate autogen.h and autogen.c!...");\r
845fdeba 133 \r
134 //\r
135 // Check the PCD memory database manager is valid.\r
136 //\r
137 if(GlobalData.getPCDMemoryDBManager() == null) {\r
138 throw new BuildActionException("Memory database has not been initlizated!");\r
139 }\r
140\r
141 dbManager = GlobalData.getPCDMemoryDBManager();\r
142\r
143 if(dbManager.getDBSize() == 0) {\r
144 return; \r
145 }\r
146\r
147 ActionMessage.debug(this,\r
148 "PCD memory database contains " + dbManager.getDBSize() + " PCD tokens");\r
878ddf1f 149\r
150 hAutoGenString = "";\r
151 cAutoGenString = "";\r
152\r
153 if(isEmulatedPCDDriver) {\r
154 generateAutogenForPCDEmulatedDriver();\r
155 } else {\r
156 generateAutogenForModule();\r
157 }\r
158 }\r
159\r
160 /**\r
161 Generate the autogen string for a common module.\r
162 \r
163 All PCD information of this module comes from memory dabase. The collection\r
164 work should be done before this action execution.\r
165 **/\r
166 private void generateAutogenForModule()\r
167 {\r
168 int index;\r
169 List<UsageInstance> usageInstanceArray;\r
170\r
171 usageInstanceArray = dbManager.getUsageInstanceArrayByModuleName(moduleName);\r
172\r
173 if(usageInstanceArray.size() != 0) {\r
174 //\r
175 // Add "#include 'PcdLib.h'" for Header file\r
176 //\r
177 hAutoGenString = "#include <MdePkg/Include/Library/PcdLib.h>\r\n";\r
178 }\r
179\r
180 for(index = 0; index < usageInstanceArray.size(); index ++) {\r
181 ActionMessage.debug(this,\r
182 "Module " + moduleName + "'s PCD [" + Integer.toHexString(index) + \r
183 "]: " + usageInstanceArray.get(index).parentToken.cName);\r
184 try {\r
185 usageInstanceArray.get(index).generateAutoGen();\r
186 hAutoGenString += usageInstanceArray.get(index).getHAutogenStr() + "\r\n";\r
187 cAutoGenString += usageInstanceArray.get(index).getCAutogenStr() + "\r\n";\r
188 } catch(EntityException exp) {\r
189 throw new BuildActionException(exp.getMessage());\r
190 }\r
191 }\r
192\r
193 ActionMessage.debug(this,\r
194 "Module " + moduleName + "'s PCD header file:\r\n" + hAutoGenString + "\r\n"\r
195 );\r
196 ActionMessage.debug(this,\r
197 "Module " + moduleName + "'s PCD C file:\r\n" + cAutoGenString + "\r\n"\r
198 );\r
199 }\r
200\r
201 /**\r
202 Generate all PCD autogen string and the emulated PCD IMAGE array for emulated driver.\r
203 \r
204 Currently, we should generated all PCD information(maybe all dynamic) as array \r
205 in Pei emulated driver for simulating PCD runtime database. \r
206 \r
207 **/\r
208 private void generateAutogenForPCDEmulatedDriver() {\r
209 int index;\r
210 Token[] tokenArray;\r
211 UsageInstance usageInstance;\r
212\r
213 //\r
214 // Add "#include 'PcdLib.h'" for Header file\r
215 //\r
216 hAutoGenString = "#include <MdePkg/Include/Library/PcdLib.h>\r\n";\r
217\r
218 tokenArray = dbManager.getRecordArray();\r
219 for(index = 0; index < tokenArray.length; index ++) {\r
220 //\r
221 // Get one consumer instance and generate autogen for this token.\r
222 //\r
223 if(tokenArray[index].consumers != null ) {\r
98fc92fc 224 if(tokenArray[index].consumers.size() != 0) {\r
225 usageInstance = tokenArray[index].consumers.get(0);\r
226 try {\r
227 usageInstance.generateAutoGen();\r
228 } catch(EntityException exp) {\r
229 throw new BuildActionException(exp.getMessage());\r
230 }\r
231 \r
232 hAutoGenString += usageInstance.getHAutogenStr();\r
233 cAutoGenString += usageInstance.getCAutogenStr();\r
234 \r
235 hAutoGenString += "\r\n";\r
236 cAutoGenString += "\r\n";\r
237 } else {\r
238 //\r
239 // If the PCD does *not* usded by any module, also generate \r
240 // it into autogen.h/autogen.c in Pcd driver according the\r
241 // information in FPD file.\r
242 //\r
243 generateUnReferencePcdAutogenString(tokenArray[index]);\r
878ddf1f 244 }\r
878ddf1f 245 }\r
246 }\r
247\r
248 generatePCDEmulatedArray(tokenArray);\r
249\r
250 ActionMessage.debug(this,\r
251 "PCD emulated driver's header: \r\n" + hAutoGenString + "\r\n"\r
252 );\r
253 ActionMessage.debug(this,\r
254 "PCD emulated driver's C code: \r\n" + cAutoGenString + "\r\n"\r
255 );\r
256\r
257 }\r
258\r
98fc92fc 259 /**\r
260 Generate unreference token definition string for PCD emulated string. \r
261 \r
262 Maybe some PCD token definition in FPD but not used by any module or library, we \r
263 should also generate token definition in autoge.h/autogen.c, because maybe some\r
264 driver loaded in shell will use this PCD. \r
265\r
266 @param token The token who want be generated autogen string.\r
267 \r
268 **/\r
269 private void generateUnReferencePcdAutogenString(Token token) {\r
270 hAutoGenString += String.format("#define _PCD_TOKEN_%s 0x%016x\r\n", \r
271 token.cName, token.tokenNumber);\r
272 switch (token.pcdType) {\r
273 case FEATURE_FLAG:\r
274 hAutoGenString += String.format(\r
275 "#define _PCD_VALUE_%s %s\r\n", \r
276 token.cName, \r
277 token.datum.toString()\r
278 );\r
279 hAutoGenString += String.format(\r
280 "extern const BOOLEAN _gPcd_FixedAtBuild_%s;\r\n", \r
281 token.cName\r
282 );\r
283 cAutoGenString += String.format(\r
284 "GLOBAL_REMOVE_IF_UNREFERENCED const BOOLEAN _gPcd_FixedAtBuild_%s = _PCD_VALUE_%s;\r\n",\r
285 token.cName,\r
286 token.cName\r
287 );\r
288 hAutoGenString += String.format(\r
289 "#define _PCD_MODE_%s_%s _PCD_VALUE_%s\r\n",\r
290 Token.GetAutogenDefinedatumTypeString(token.datumType),\r
291 token.cName,\r
292 token.cName\r
293 );\r
294 break;\r
295 case FIXED_AT_BUILD:\r
296 hAutoGenString += String.format(\r
297 "#define _PCD_VALUE_%s %s\r\n", \r
298 token.cName, \r
299 token.datum.toString()\r
300 );\r
301 hAutoGenString += String.format(\r
302 "extern const %s _gPcd_FixedAtBuild_%s;\r\n",\r
303 Token.getAutogendatumTypeString(token.datumType),\r
304 token.cName\r
305 );\r
306 cAutoGenString += String.format(\r
307 "GLOBAL_REMOVE_IF_UNREFERENCED const %s _gPcd_FixedAtBuild_%s = _PCD_VALUE_%s;\r\n",\r
308 Token.getAutogendatumTypeString(token.datumType),\r
309 token.cName,\r
310 token.cName\r
311 );\r
312 hAutoGenString += String.format(\r
313 "#define _PCD_MODE_%s_%s _PCD_VALUE_%s\r\n",\r
314 Token.GetAutogenDefinedatumTypeString(token.datumType),\r
315 token.cName,\r
316 token.cName\r
317 );\r
318 break;\r
319 case PATCHABLE_IN_MODULE:\r
320 hAutoGenString += String.format(\r
321 "#define _PCD_VALUE_%s %s\r\n", \r
322 token.cName, \r
323 token.datum.toString()\r
324 );\r
325 hAutoGenString += String.format(\r
326 "extern %s _gPcd_BinaryPatch_%s;\r\n",\r
327 Token.getAutogendatumTypeString(token.datumType),\r
328 token.cName\r
329 );\r
330 cAutoGenString += String.format(\r
331 "GLOBAL_REMOVE_IF_UNREFERENCED %s _gPcd_BinaryPatch_%s = _PCD_VALUE_%s;\r\n",\r
332 Token.getAutogendatumTypeString(token.datumType),\r
333 token.cName,\r
334 token.cName\r
335 );\r
336 hAutoGenString += String.format(\r
337 "#define _PCD_MODE_%s_%s _gPcd_BinaryPatch_%s\r\n",\r
338 Token.GetAutogenDefinedatumTypeString(token.datumType),\r
339 token.cName,\r
340 token.cName\r
341 );\r
342 break;\r
343 case DYNAMIC:\r
344 hAutoGenString += String.format(\r
345 "#define _PCD_MODE_%s_%s LibPcdGet%s(_PCD_TOKEN_%s)\r\n",\r
346 Token.GetAutogenDefinedatumTypeString(token.datumType),\r
347 token.cName,\r
348 Token.getAutogenLibrarydatumTypeString(token.datumType),\r
349 token.cName\r
350 );\r
351 break;\r
352 case DYNAMIC_EX:\r
353 break;\r
354 default:\r
355 ActionMessage.warning(this, \r
356 "The PCD_TYPE setted by platform is unknown"\r
357 );\r
358 }\r
359\r
360 hAutoGenString += "\r\n";\r
361 cAutoGenString += "\r\n";\r
362 }\r
363 \r
878ddf1f 364 /**\r
365 Generate PCDEmulated array in PCDEmulated driver for emulated runtime database.\r
366 \r
367 @param tokenArray All PCD token in memory database.\r
368 \r
369 @throws BuildActionException Unknown PCD_TYPE\r
370 **/\r
371 private void generatePCDEmulatedArray(Token[] tokenArray)\r
372 throws BuildActionException {\r
373 int index;\r
374 Token token;\r
375 String[] guidStrArray;\r
376 String value;\r
377\r
378 //\r
379 // The value of String type of PCD entry maybe use byte array but not string direcly\r
380 // such as {0x1, 0x2, 0x3}, and define PCD1_STRING_Value as L"string define here"\r
381 // For this case, we should generate a string array to C output and use the address\r
382 // of generated string array.\r
383 //\r
384 for(index = 0; index < tokenArray.length; index ++) {\r
385 token = tokenArray[index];\r
386\r
878ddf1f 387 value = token.datum.toString();\r
388 if(token.datumType == Token.DATUM_TYPE.POINTER) {\r
389 if(!((value.charAt(0) == 'L' && value.charAt(1) == '"') ||(value.charAt(0) == '"'))) {\r
390 cAutoGenString += String.format("UINT8 _mPcdArray%08x[] = %s;\r\n", \r
391 index, \r
392 value\r
393 );\r
394 }\r
395 }\r
396 }\r
397\r
398 //\r
399 // Output emulated PCD entry array\r
400 //\r
401 cAutoGenString += "\r\nEMULATED_PCD_ENTRY gEmulatedPcdEntry[] = {\r\n";\r
402\r
403 for(index = 0; index < tokenArray.length; index ++) {\r
404 token = tokenArray[index];\r
405\r
878ddf1f 406 if(index != 0) {\r
407 cAutoGenString += ",\r\n";\r
408 }\r
409\r
410 //\r
411 // Print Start "{" for a Token item in array\r
412 //\r
413 cAutoGenString += " {\r\n";\r
414\r
415 //\r
416 // Print Token Name\r
417 //\r
418 cAutoGenString += String.format(" _PCD_TOKEN_%s,\r\n", token.cName);\r
419\r
420 //\r
421 // Print Hii information\r
422 //\r
423 if(token.hiiEnabled) {\r
424 cAutoGenString += String.format(" TRUE,\r\n");\r
425 } else {\r
426 cAutoGenString += String.format(" FALSE,\r\n");\r
427 }\r
428\r
429 //\r
430 // Print sku information\r
431 //\r
432 if(token.skuEnabled) {\r
433 cAutoGenString += String.format(" TRUE,\r\n");\r
434 } else {\r
435 cAutoGenString += String.format(" FALSE,\r\n");\r
436 }\r
437\r
438 //\r
439 // Print maxSkuCount\r
440 //\r
441 cAutoGenString += String.format(" %d,\r\n", token.maxSkuCount);\r
442\r
443 cAutoGenString += String.format(" %d,\r\n", token.skuId);\r
444\r
445 if(token.variableGuid == null) {\r
446 cAutoGenString += " { 0x00000000, 0x0000, 0x0000, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },\r\n";\r
447 } else {\r
448 guidStrArray =(token.variableGuid.toString()).split("-");\r
449\r
450 cAutoGenString += 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\n",\r
451 guidStrArray[0],\r
452 guidStrArray[1],\r
453 guidStrArray[2],\r
454 (guidStrArray[3].substring(0, 2)),\r
455 (guidStrArray[3].substring(2, 4)),\r
456 (guidStrArray[4].substring(0, 2)),\r
457 (guidStrArray[4].substring(2, 4)),\r
458 (guidStrArray[4].substring(4, 6)),\r
459 (guidStrArray[4].substring(6, 8)),\r
460 (guidStrArray[4].substring(8, 10)),\r
461 (guidStrArray[4].substring(10, 12))\r
462 );\r
463\r
464 }\r
465\r
466 value = token.datum.toString();\r
467 if(token.datumType == Token.DATUM_TYPE.POINTER) {\r
468 if((value.charAt(0) == 'L' && value.charAt(1) == '"') || value.charAt(0) == '"') {\r
469 cAutoGenString += String.format(" sizeof(_PCD_VALUE_%s),\r\n", token.cName);\r
470 cAutoGenString += String.format(" 0, %s, %s,\r\n", token.variableName, value);\r
471 } else {\r
472 cAutoGenString += String.format(" sizeof(_mPcdArray%08x),\r\n", index);\r
473 cAutoGenString += String.format(" 0, &_mPcdArray%08x, %s,\r\n", index, token.variableName);\r
474 }\r
475 } else {\r
476 switch(token.datumType) {\r
477 case UINT8:\r
478 cAutoGenString += " 1,\r\n";\r
479 break;\r
480 case UINT16:\r
481 cAutoGenString += " 2,\r\n";\r
482 break;\r
483 case UINT32:\r
484 cAutoGenString += " 4,\r\n";\r
485 break;\r
486 case UINT64:\r
487 cAutoGenString += " 8,\r\n";\r
488 break;\r
489 case BOOLEAN:\r
490 cAutoGenString += " 1,\r\n";\r
491 break;\r
492 default:\r
493 throw new BuildActionException("Unknown datum size");\r
494 }\r
495 cAutoGenString += String.format(" %s, %s, NULL,\r\n", value, token.variableName);\r
496 }\r
497\r
498 //\r
499 // Print end "}" for a token item in array\r
500 //\r
501 cAutoGenString += " }";\r
502 }\r
503\r
504 cAutoGenString += "\r\n};\r\n";\r
505 cAutoGenString += "\r\n";\r
506 cAutoGenString += "UINTN\r\n";\r
507 cAutoGenString += "GetPcdDataBaseSize(\r\n";\r
508 cAutoGenString += " VOID\r\n";\r
509 cAutoGenString += " )\r\n";\r
510 cAutoGenString += "{\r\n";\r
511 cAutoGenString += " return sizeof(gEmulatedPcdEntry);\r\n";\r
512 cAutoGenString += "}\r\n";\r
513 }\r
514\r
515 /**\r
516 Test case function\r
517\r
518 @param argv paramter from command line\r
519 **/\r
520 public static void main(String argv[]) {\r
98fc92fc 521 String logFilePath = "M:/tianocore/edk2/trunk/edk2/EdkNt32Pkg/Nt32.fpd";\r
878ddf1f 522\r
523 //\r
524 // At first, CollectPCDAction should be invoked to collect\r
525 // all PCD information from SPD, MSA, FPD.\r
526 //\r
527 CollectPCDAction collectionAction = new CollectPCDAction();\r
528 GlobalData.initInfo("Tools" + File.separator + "Conf" + File.separator + "FrameworkDatabase.db",\r
98fc92fc 529 "M:/tianocore/edk2/trunk/edk2");\r
878ddf1f 530\r
531 GlobalData.getPCDMemoryDBManager().setLogFileName(logFilePath + ".PCDMemroyDatabaseLog.txt");\r
532\r
533 try {\r
98fc92fc 534 collectionAction.perform("M:/tianocore/edk2/trunk/edk2", \r
878ddf1f 535 logFilePath,\r
536 ActionMessage.MAX_MESSAGE_LEVEL);\r
537 } catch(Exception e) {\r
538 e.printStackTrace();\r
539 }\r
540\r
541 //\r
542 // Then execute the PCDAuotoGenAction to get generated Autogen.h and Autogen.c\r
543 //\r
98fc92fc 544 PCDAutoGenAction autogenAction = new PCDAutoGenAction("PcdEmulator",\r
878ddf1f 545 true\r
546 );\r
547 autogenAction.execute();\r
98fc92fc 548 System.out.println (autogenAction.hAutoGenString);\r
549 System.out.println (autogenAction.cAutoGenString);\r
550\r
878ddf1f 551 }\r
552}\r