b7d6ec4e395511997acd6692d79cbeee8dbbcab5
[mirror_edk2.git] / Tools / Java / Source / GenBuild / org / tianocore / build / autogen / AutoGen.java
1 /** @file
2 AutoGen class.
3
4 This class is to generate Autogen.h and Autogen.c according to module surface area
5 or library surface area.
6
7 Copyright (c) 2006, Intel Corporation
8 All rights reserved. This program and the accompanying materials
9 are licensed and made available under the terms and conditions of the BSD License
10 which accompanies this distribution. The full text of the license may be found at
11 http://opensource.org/licenses/bsd-license.php
12
13 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
14 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
15
16 **/
17
18 package org.tianocore.build.autogen;
19
20 import java.io.File;
21 import java.io.FileInputStream;
22 import java.io.FileOutputStream;
23 import java.io.FileReader;
24 import java.io.FileWriter;
25 import java.io.IOException;
26 import java.util.ArrayList;
27 import java.util.HashSet;
28 import java.util.Iterator;
29 import java.util.LinkedHashSet;
30 import java.util.LinkedList;
31 import java.util.List;
32 import java.util.Map;
33 import java.util.Set;
34
35 import org.apache.tools.ant.BuildException;
36 import org.apache.xmlbeans.XmlObject;
37 import org.tianocore.build.exception.AutoGenException;
38 import org.tianocore.build.global.GlobalData;
39 import org.tianocore.build.global.SurfaceAreaQuery;
40 import org.tianocore.build.id.ModuleIdentification;
41 import org.tianocore.build.id.PackageIdentification;
42 import org.tianocore.build.pcd.action.PCDAutoGenAction;
43 import org.tianocore.common.definitions.ToolDefinitions;
44 import org.tianocore.common.definitions.EdkDefinitions;
45 import org.tianocore.common.exception.EdkException;
46 import org.tianocore.common.logger.EdkLog;
47
48 /**
49 This class is to generate Autogen.h and Autogen.c according to module surface
50 area or library surface area.
51 **/
52 public class AutoGen {
53 ///
54 /// The output path of Autogen.h and Autogen.c
55 ///
56 private String outputPath;
57
58 ///
59 /// The name of FV directory
60 ///
61 private String fvDir;
62
63 ///
64 /// The base name of module or library.
65 ///
66 private ModuleIdentification moduleId;
67
68 ///
69 /// The build architecture
70 ///
71 private String arch;
72
73 ///
74 /// PcdAutogen instance which is used to manage how to generate the PCD
75 /// information.
76 ///
77 private PCDAutoGenAction myPcdAutogen;
78
79 ///
80 /// the one of type : NOT_PCD_DRIVER, PEI_PCD_DRIVER, DXE_PCD_DRIVER
81 ///
82 private CommonDefinition.PCD_DRIVER_TYPE pcdDriverType;
83
84 ///
85 /// The protocl list which records in module or library surface area and
86 /// it's dependence on library instance surface area.
87 ///
88 private Set<String> mProtocolList = new HashSet<String>();
89
90 ///
91 /// The Ppi list which recorded in module or library surface area and its
92 /// dependency on library instance surface area.
93 ///
94 private Set<String> mPpiList = new HashSet<String>();
95
96 ///
97 /// The Guid list which recoreded in module or library surface area and it's
98 /// dependence on library instance surface area.
99 ///
100 private Set<String> mGuidList = new HashSet<String>();
101
102 ///
103 /// The dependence package list which recoreded in module or library surface
104 /// area and it's dependence on library instance surface area.
105 ///
106 private List<PackageIdentification> mDepPkgList = new LinkedList<PackageIdentification>();
107
108 ///
109 /// For non library module, add its library instance's construct and destructor to
110 /// list. String[0] recode LibConstructor name, String[1] recode Lib instance
111 /// module type.
112 ///
113 private List<String[]> libConstructList = new ArrayList<String[]>();
114 private List<String[]> libDestructList = new ArrayList<String[]>();
115
116 ///
117 /// List to store SetVirtalAddressMapCallBack, ExitBootServiceCallBack
118 ///
119 private List<String> setVirtalAddList = new ArrayList<String>();
120 private List<String> exitBootServiceList = new ArrayList<String>();
121
122 private StringBuffer functionDeclarations = new StringBuffer(10240);
123
124 //
125 // flag of PcdComponentNameDisable, PcdDriverDiagnosticDisable
126 //
127 private boolean componentNamePcd = false;
128 private boolean driverDiagnostPcd = false;
129
130 //
131 // Instance of SurfaceAreaQuery
132 //
133 private SurfaceAreaQuery saq = null;
134
135 private ModuleIdentification parentId = null;
136
137 /**
138 Construct function
139
140 This function mainly initialize some member variable.
141
142 @param fvDir
143 Absolute path of FV directory.
144 @param outputPath
145 Output path of AutoGen file.
146 @param moduleId
147 Module identification.
148 @param arch
149 Target architecture.
150 **/
151 public AutoGen(String fvDir, String outputPath, ModuleIdentification moduleId, String arch, SurfaceAreaQuery saq, ModuleIdentification parentId) {
152 this.outputPath = outputPath;
153 this.moduleId = moduleId;
154 this.arch = arch;
155 this.fvDir = fvDir;
156 this.saq = saq;
157 this.parentId = parentId;
158 }
159
160 /**
161 saveFile function
162
163 This function save the content in stringBuffer to file.
164
165 @param fileName
166 The name of file.
167 @param fileBuffer
168 The content of AutoGen file in buffer.
169 @return boolean
170 "true" successful
171 "false" failed
172 **/
173 private boolean saveFile(String fileName, StringBuffer fileBuffer) {
174
175 File autoGenH = new File(fileName);
176
177 //
178 // if the file exists, compare their content
179 //
180 if (autoGenH.exists()) {
181 char[] oldFileBuffer = new char[(int) autoGenH.length()];
182 try {
183 FileReader fIn = new FileReader(autoGenH);
184 fIn.read(oldFileBuffer, 0, (int) autoGenH.length());
185 fIn.close();
186 } catch (IOException e) {
187 EdkLog.log(EdkLog.EDK_INFO, this.moduleId.getName()
188 + "'s "
189 + fileName
190 + " is exist, but can't be open!!");
191 return false;
192 }
193
194 //
195 // if we got the same file, don't re-generate it to prevent
196 // sources depending on it from re-building
197 //
198 if (fileBuffer.toString().compareTo(new String(oldFileBuffer)) == 0) {
199 return true;
200 }
201 }
202
203 try {
204 FileWriter fOut = new FileWriter(autoGenH);
205 fOut.write(fileBuffer.toString());
206 fOut.flush();
207 fOut.close();
208 } catch (IOException e) {
209 EdkLog.log(EdkLog.EDK_INFO, this.moduleId.getName()
210 + "'s "
211 + fileName
212 + " can't be create!!");
213 return false;
214 }
215 return true;
216 }
217
218 /**
219 genAutogen function
220
221 This function call libGenAutoGen or moduleGenAutogen function, which
222 dependence on generate library autogen or module autogen.
223
224 @throws BuildException
225 Failed to creat AutoGen.c & AutoGen.h.
226 **/
227 public void genAutogen() throws EdkException {
228 //
229 // If outputPath do not exist, create it.
230 //
231 File path = new File(outputPath);
232 path.mkdirs();
233
234 //
235 // Check current is library or not, then call the corresponding
236 // function.
237 //
238 if (this.moduleId.isLibrary()) {
239 libGenAutogen();
240 } else {
241 moduleGenAutogen();
242 }
243 }
244
245 /**
246 moduleGenAutogen function
247
248 This function generates AutoGen.c & AutoGen.h for module.
249
250 @throws BuildException
251 Faile to create module AutoGen.c & AutoGen.h.
252 **/
253 void moduleGenAutogen() throws EdkException {
254 setPcdComponentName();
255 setPcdDriverDiagnostic();
256 collectLibInstanceInfo();
257 moduleGenAutogenC();
258 moduleGenAutogenH();
259 }
260
261 /**
262 libGenAutogen function
263
264 This function generates AutoGen.c & AutoGen.h for library.
265
266 @throws BuildException
267 Faile to create library AutoGen.c & AutoGen.h
268 **/
269 void libGenAutogen() throws EdkException {
270 libGenAutogenC();
271 libGenAutogenH();
272 }
273
274 /**
275 moduleGenAutogenH
276
277 This function generates AutoGen.h for module.
278
279 @throws BuildException
280 Failed to generate AutoGen.h.
281 **/
282 void moduleGenAutogenH() throws EdkException {
283
284 Set<String> libClassIncludeH;
285 String moduleType;
286 // List<String> headerFileList;
287 List<String> headerFileList;
288 Iterator item;
289 StringBuffer fileBuffer = new StringBuffer(8192);
290
291 //
292 // Write Autogen.h header notation
293 //
294 fileBuffer.append(CommonDefinition.AUTOGENHNOTATION);
295
296 //
297 // Add #ifndef ${BaseName}_AUTOGENH
298 // #def ${BseeName}_AUTOGENH
299 //
300 fileBuffer.append(CommonDefinition.IFNDEF
301 + CommonDefinition.AUTOGENH
302 + this.moduleId.getGuid().replaceAll("-", "_")
303 + ToolDefinitions.LINE_SEPARATOR);
304 fileBuffer.append(CommonDefinition.DEFINE
305 + CommonDefinition.AUTOGENH
306 + this.moduleId.getGuid().replaceAll("-", "_")
307 + ToolDefinitions.LINE_SEPARATOR
308 + ToolDefinitions.LINE_SEPARATOR);
309
310 //
311 // Write the specification version and release version at the begine
312 // of autogen.h file.
313 // Note: the specification version and release version should
314 // be got from module surface area instead of hard code by it's
315 // moduleType.
316 //
317 moduleType = saq.getModuleType();
318
319 //
320 // Add "extern int __make_me_compile_correctly;" at begin of
321 // AutoGen.h.
322 //
323 fileBuffer.append(CommonDefinition.AUTOGENHBEGIN);
324
325 //
326 // Put EFI_SPECIFICATION_VERSION, and EDK_RELEASE_VERSION.
327 //
328 String[] specList = saq.getExternSpecificaiton();
329 for (int i = 0; i < specList.length; i++) {
330 fileBuffer.append(CommonDefinition.DEFINE + specList[i]
331 + "\r\n");
332 }
333 //
334 // Write consumed package's mdouleInfo related .h file to autogen.h
335 //
336 // PackageIdentification[] consumedPkgIdList = SurfaceAreaQuery
337 // .getDependencePkg(this.arch);
338 PackageIdentification[] consumedPkgIdList = saq.getDependencePkg(this.arch);
339 if (consumedPkgIdList != null) {
340 headerFileList = depPkgToAutogenH(consumedPkgIdList, moduleType);
341 item = headerFileList.iterator();
342 while (item.hasNext()) {
343 fileBuffer.append(item.next().toString());
344 }
345 }
346
347 //
348 // Write library class's related *.h file to autogen.h.
349 //
350 String[] libClassList = saq.getLibraryClasses(CommonDefinition.ALWAYSCONSUMED, this.arch, null);
351 if (libClassList.length > 0) {
352 libClassIncludeH = LibraryClassToAutogenH(libClassList);
353 item = libClassIncludeH.iterator();
354 while (item.hasNext()) {
355 fileBuffer.append(item.next().toString());
356 }
357 }
358
359 libClassList = saq.getLibraryClasses(CommonDefinition.ALWAYSPRODUCED, this.arch, null);
360 if (libClassList.length > 0) {
361 libClassIncludeH = LibraryClassToAutogenH(libClassList);
362 item = libClassIncludeH.iterator();
363 while (item.hasNext()) {
364 fileBuffer.append(item.next().toString());
365 }
366 }
367 fileBuffer.append("\r\n");
368
369 //
370 // If is TianoR8FlashMap, copy {Fv_DIR}/FlashMap.h to
371 // {DEST_DIR_DRBUG}/FlashMap.h
372 //
373 if (saq.isHaveTianoR8FlashMap()) {
374 fileBuffer.append(CommonDefinition.INCLUDE);
375 fileBuffer.append(" <");
376 fileBuffer.append(CommonDefinition.TIANOR8PLASHMAPH + ">\r\n");
377 copyFlashMapHToDebugDir();
378 }
379
380 // Write PCD autogen information to AutoGen.h.
381 //
382 if (this.myPcdAutogen != null) {
383 fileBuffer.append("\r\n");
384 fileBuffer.append(this.myPcdAutogen.getHAutoGenString());
385 }
386
387 fileBuffer.append(functionDeclarations);
388 //
389 // Append the #endif at AutoGen.h
390 //
391 fileBuffer.append("#endif\r\n");
392
393 //
394 // Save string buffer content in AutoGen.h.
395 //
396 if (!saveFile(outputPath + File.separatorChar + "AutoGen.h", fileBuffer)) {
397 throw new AutoGenException("Failed to generate AutoGen.h !!!");
398 }
399 }
400
401 /**
402 moduleGenAutogenC
403
404 This function generates AutoGen.c for module.
405
406 @throws BuildException
407 Failed to generate AutoGen.c.
408 **/
409 void moduleGenAutogenC() throws EdkException {
410
411 StringBuffer fileBuffer = new StringBuffer(8192);
412 //
413 // Write Autogen.c header notation
414 //
415 fileBuffer.append(CommonDefinition.AUTOGENCNOTATION);
416
417 //
418 // Get the native MSA file infomation. Since before call autogen,
419 // the MSA native <Externs> information were overrided. So before
420 // process <Externs> it should be set the DOC as the Native MSA info.
421 //
422 Map<String, XmlObject> doc = GlobalData.getNativeMsa(this.moduleId);
423 saq.push(doc);
424 //
425 // Write <Extern>
426 // DriverBinding/ComponentName/DriverConfiguration/DriverDialog
427 // to AutoGen.c
428 //
429
430 ExternsDriverBindingToAutoGenC(fileBuffer);
431
432 //
433 // Write DriverExitBootServicesEvent/DriverSetVirtualAddressMapEvent
434 // to Autogen.c
435 //
436 ExternCallBackToAutoGenC(fileBuffer);
437
438 //
439 // Write EntryPoint to autgoGen.c
440 //
441 String[] entryPointList = saq.getModuleEntryPointArray();
442 String[] unloadImageList = saq.getModuleUnloadImageArray();
443 EntryPointToAutoGen(CommonDefinition.remDupString(entryPointList),
444 CommonDefinition.remDupString(unloadImageList),
445 fileBuffer);
446
447 pcdDriverType = saq.getPcdDriverType();
448
449 //
450 // Restore the DOC which include the FPD module info.
451 //
452 saq.pop();
453
454 //
455 // Write Guid to autogen.c
456 //
457 String guid = CommonDefinition.formatGuidName(saq.getModuleGuid());
458 if (this.moduleId.getModuleType().equalsIgnoreCase(EdkDefinitions.MODULE_TYPE_BASE)) {
459 fileBuffer.append("GLOBAL_REMOVE_IF_UNREFERENCED GUID gEfiCallerIdGuid = {");
460 } else {
461 fileBuffer.append("GLOBAL_REMOVE_IF_UNREFERENCED EFI_GUID gEfiCallerIdGuid = {");
462 }
463
464 if (guid == null) {
465 throw new AutoGenException("Guid value must set!\n");
466 }
467
468 //
469 // Formate Guid as ANSI c form.Example:
470 // {0xd2b2b828, 0x826, 0x48a7,{0xb3, 0xdf, 0x98, 0x3c, 0x0, 0x60, 0x24,
471 // 0xf0}}
472 //
473
474 fileBuffer.append(guid);
475 fileBuffer.append("};\r\n");
476
477 //
478 // Generate library instance consumed protocol, guid, ppi, pcd list.
479 // Save those to this.protocolList, this.ppiList, this.pcdList,
480 // this.guidList. Write Consumed library constructor and desconstuct to
481 // autogen.c
482 //
483 LibInstanceToAutogenC(fileBuffer);
484
485 //
486 // Get module dependent Package identification.
487 //
488 PackageIdentification[] packages = saq.getDependencePkg(this.arch);
489 for (int i = 0; i < packages.length; i++) {
490 if (!this.mDepPkgList.contains(packages[i])) {
491 this.mDepPkgList.add(packages[i]);
492 }
493
494 }
495
496 //
497 // Write consumed ppi, guid, protocol to autogen.c
498 //
499 ProtocolGuidToAutogenC(fileBuffer);
500 PpiGuidToAutogenC(fileBuffer);
501 GuidGuidToAutogenC(fileBuffer);
502
503 //
504 // Call pcd autogen.
505 //
506 this.myPcdAutogen = new PCDAutoGenAction(moduleId,
507 arch,
508 false,
509 null,
510 pcdDriverType,
511 parentId);
512
513 this.myPcdAutogen.execute();
514 if (this.myPcdAutogen != null) {
515 fileBuffer.append("\r\n");
516 fileBuffer.append(this.myPcdAutogen.getCAutoGenString());
517 }
518
519 if (!saveFile(outputPath + File.separatorChar + "AutoGen.c", fileBuffer)) {
520 throw new AutoGenException("Failed to generate AutoGen.c !!!");
521 }
522
523 }
524
525 /**
526 libGenAutogenH
527
528 This function generates AutoGen.h for library.
529
530 @throws BuildException
531 Failed to generate AutoGen.c.
532 **/
533 void libGenAutogenH() throws EdkException {
534
535 Set<String> libClassIncludeH;
536 String moduleType;
537 List<String> headerFileList;
538 Iterator item;
539 StringBuffer fileBuffer = new StringBuffer(10240);
540
541 //
542 // Write Autogen.h header notation
543 //
544 fileBuffer.append(CommonDefinition.AUTOGENHNOTATION);
545
546 //
547 // Add #ifndef ${BaseName}_AUTOGENH
548 // #def ${BseeName}_AUTOGENH
549 //
550 fileBuffer.append(CommonDefinition.IFNDEF
551 + CommonDefinition.AUTOGENH
552 + this.moduleId.getGuid().replaceAll("-", "_")
553 + ToolDefinitions.LINE_SEPARATOR);
554 fileBuffer.append(CommonDefinition.DEFINE
555 + CommonDefinition.AUTOGENH
556 + this.moduleId.getGuid().replaceAll("-", "_")
557 + ToolDefinitions.LINE_SEPARATOR
558 + ToolDefinitions.LINE_SEPARATOR);
559
560 //
561 // Write EFI_SPECIFICATION_VERSION and EDK_RELEASE_VERSION
562 // to autogen.h file.
563 // Note: the specification version and release version should
564 // be get from module surface area instead of hard code.
565 //
566 fileBuffer.append(CommonDefinition.AUTOGENHBEGIN);
567 String[] specList = saq.getExternSpecificaiton();
568 for (int i = 0; i < specList.length; i++) {
569 fileBuffer.append(CommonDefinition.DEFINE + specList[i] + "\r\n");
570 }
571 // fileBuffer.append(CommonDefinition.autoGenHLine1);
572 // fileBuffer.append(CommonDefinition.autoGenHLine2);
573
574 //
575 // Write consumed package's mdouleInfo related *.h file to autogen.h.
576 //
577 moduleType = saq.getModuleType();
578 PackageIdentification[] cosumedPkglist = saq.getDependencePkg(this.arch);
579 headerFileList = depPkgToAutogenH(cosumedPkglist, moduleType);
580 item = headerFileList.iterator();
581 while (item.hasNext()) {
582 fileBuffer.append(item.next().toString());
583 }
584 //
585 // Write library class's related *.h file to autogen.h
586 //
587 String[] libClassList = saq.getLibraryClasses(CommonDefinition.ALWAYSCONSUMED, this.arch, null);
588 if (libClassList != null) {
589 libClassIncludeH = LibraryClassToAutogenH(libClassList);
590 item = libClassIncludeH.iterator();
591 while (item.hasNext()) {
592 fileBuffer.append(item.next().toString());
593 }
594 }
595
596 libClassList = saq.getLibraryClasses(CommonDefinition.ALWAYSPRODUCED, this.arch, null);
597 if (libClassList != null) {
598 libClassIncludeH = LibraryClassToAutogenH(libClassList);
599 item = libClassIncludeH.iterator();
600 while (item.hasNext()) {
601 fileBuffer.append(item.next().toString());
602 }
603 }
604 fileBuffer.append(ToolDefinitions.LINE_SEPARATOR);
605
606 //
607 // If is TianoR8FlashMap, copy {Fv_DIR}/FlashMap.h to
608 // {DEST_DIR_DRBUG}/FlashMap.h
609 //
610 if (saq.isHaveTianoR8FlashMap()) {
611 fileBuffer.append(CommonDefinition.INCLUDE);
612 fileBuffer.append(" <");
613 fileBuffer.append(CommonDefinition.TIANOR8PLASHMAPH + ">\r\n");
614 copyFlashMapHToDebugDir();
615 }
616
617 //
618 // Write PCD information to library AutoGen.h.
619 //
620 if (this.myPcdAutogen != null) {
621 fileBuffer.append("\r\n");
622 fileBuffer.append(this.myPcdAutogen.getHAutoGenString());
623 }
624 //
625 // generate function prototype for constructor and destructor
626 //
627 LibConstructorToAutogenH(moduleType);
628 LibDestructorToAutogenH(moduleType);
629 ExternCallBackToAutoGenH(moduleType);
630 fileBuffer.append(functionDeclarations);
631 //
632 // Append the #endif at AutoGen.h
633 //
634 fileBuffer.append("#endif\r\n");
635 //
636 // Save content of string buffer to AutoGen.h file.
637 //
638 if (!saveFile(outputPath + File.separatorChar + "AutoGen.h", fileBuffer)) {
639 throw new AutoGenException("Failed to generate AutoGen.h !!!");
640 }
641 }
642
643 /**
644 libGenAutogenC
645
646 This function generates AutoGen.h for library.
647
648 @throws BuildException
649 Failed to generate AutoGen.c.
650 **/
651 void libGenAutogenC() throws EdkException {
652 StringBuffer fileBuffer = new StringBuffer(10240);
653
654 //
655 // Write Autogen.c header notation
656 //
657 fileBuffer.append(CommonDefinition.AUTOGENCNOTATION);
658
659 fileBuffer.append(ToolDefinitions.LINE_SEPARATOR);
660 fileBuffer.append(ToolDefinitions.LINE_SEPARATOR);
661
662 //
663 // Call pcd autogen.
664 //
665 this.myPcdAutogen = new PCDAutoGenAction(moduleId,
666 arch,
667 true,
668 saq.getModulePcdEntryNameArray(this.arch),
669 pcdDriverType,
670 parentId);
671 this.myPcdAutogen.execute();
672 if (this.myPcdAutogen != null) {
673 fileBuffer.append(ToolDefinitions.LINE_SEPARATOR);
674 fileBuffer.append(this.myPcdAutogen.getCAutoGenString());
675 }
676 }
677
678 /**
679 LibraryClassToAutogenH
680
681 This function returns *.h files declared by library classes which are
682 consumed or produced by current build module or library.
683
684 @param libClassList
685 List of library class which consumed or produce by current
686 build module or library.
687 @return includeStrList List of *.h file.
688 **/
689 Set<String> LibraryClassToAutogenH(String[] libClassList)
690 throws EdkException {
691 Set<String> includeStrList = new LinkedHashSet<String>();
692 String includeName[];
693 String str = "";
694
695 //
696 // Get include file from GlobalData's SPDTable according to
697 // library class name.
698 //
699 for (int i = 0; i < libClassList.length; i++) {
700 includeName = GlobalData.getLibraryClassHeaderFiles(
701 saq.getDependencePkg(this.arch),
702 libClassList[i]);
703 if (includeName == null) {
704 throw new AutoGenException("Can not find library class ["
705 + libClassList[i] + "] declaration in any SPD package. ");
706 }
707 for (int j = 0; j < includeName.length; j++) {
708 String includeNameStr = includeName[j];
709 if (includeNameStr != null) {
710 str = CommonDefinition.INCLUDE + " " + "<";
711 str = str + includeNameStr + ">\r\n";
712 includeStrList.add(str);
713 includeNameStr = null;
714 }
715 }
716 }
717 return includeStrList;
718 }
719
720 /**
721 IncludesToAutogenH
722
723 This function add include file in AutoGen.h file.
724
725 @param packageNameList
726 List of module depended package.
727 @param moduleType
728 Module type.
729 @return
730 **/
731 List<String> depPkgToAutogenH(PackageIdentification[] packageNameList,
732 String moduleType) throws AutoGenException {
733
734 List<String> includeStrList = new LinkedList<String>();
735 String pkgHeader;
736 String includeStr = "";
737
738 //
739 // Get include file from moduleInfo file
740 //
741 for (int i = 0; i < packageNameList.length; i++) {
742 pkgHeader = GlobalData.getPackageHeaderFiles(packageNameList[i],
743 moduleType);
744 if (pkgHeader == null) {
745 throw new AutoGenException("Can not find package ["
746 + packageNameList[i]
747 + "] declaration in any SPD package. ");
748 } else if (!pkgHeader.equalsIgnoreCase("")) {
749 includeStr = CommonDefinition.INCLUDE + " <" + pkgHeader + ">\r\n";
750 includeStrList.add(includeStr);
751 }
752 }
753
754 return includeStrList;
755 }
756
757 /**
758 EntryPointToAutoGen
759
760 This function convert <ModuleEntryPoint> & <ModuleUnloadImage>
761 information in mas to AutoGen.c
762
763 @param entryPointList
764 List of entry point.
765 @param fileBuffer
766 String buffer fo AutoGen.c.
767 @throws Exception
768 **/
769 void EntryPointToAutoGen(String[] entryPointList, String[] unloadImageList, StringBuffer fileBuffer)
770 throws EdkException {
771
772 String typeStr = saq.getModuleType();
773 String debugStr = "DEBUG ((EFI_D_INFO | EFI_D_LOAD, \"Module Entry Point (%s) 0x%%p\\n\", (VOID *)(UINTN)%s));\r\n";
774 int unloadImageCount = 0;
775 int entryPointCount = 0;
776
777 //
778 // The parameters and return value of entryPoint is difference
779 // for difference module type.
780 //
781 switch (CommonDefinition.getModuleType(typeStr)) {
782
783 case CommonDefinition.ModuleTypePeiCore:
784 if (entryPointList == null ||entryPointList.length != 1 ) {
785 throw new AutoGenException("Module type = 'PEI_CORE', can have only one module entry point!");
786 } else {
787 fileBuffer.append("EFI_STATUS\r\n");
788 fileBuffer.append("EFIAPI\r\n");
789 fileBuffer.append(entryPointList[0]);
790 fileBuffer.append(" (\r\n");
791 fileBuffer.append(" IN EFI_PEI_STARTUP_DESCRIPTOR *PeiStartupDescriptor,\r\n");
792 fileBuffer.append(" IN VOID *OldCoreData\r\n");
793 fileBuffer.append(" );\r\n\r\n");
794
795 fileBuffer.append("EFI_STATUS\r\n");
796 fileBuffer.append("EFIAPI\r\n");
797 fileBuffer.append("ProcessModuleEntryPointList (\r\n");
798 fileBuffer.append(" IN EFI_PEI_STARTUP_DESCRIPTOR *PeiStartupDescriptor,\r\n");
799 fileBuffer.append(" IN VOID *OldCoreData\r\n");
800 fileBuffer.append(" )\r\n\r\n");
801 fileBuffer.append("{\r\n");
802 fileBuffer.append(" return ");
803 fileBuffer.append(entryPointList[0]);
804 fileBuffer.append(" (PeiStartupDescriptor, OldCoreData);\r\n");
805 fileBuffer.append("}\r\n\r\n");
806 }
807 break;
808
809 case CommonDefinition.ModuleTypeDxeCore:
810 fileBuffer.append("const UINT32 _gUefiDriverRevision = 0;\r\n");
811 if (entryPointList == null || entryPointList.length != 1) {
812 throw new AutoGenException("Module type = 'DXE_CORE', can have only one module entry point!");
813 } else {
814 fileBuffer.append("VOID\r\n");
815 fileBuffer.append("EFIAPI\r\n");
816 fileBuffer.append(entryPointList[0]);
817 fileBuffer.append(" (\r\n");
818 fileBuffer.append(" IN VOID *HobStart\r\n");
819 fileBuffer.append(" );\r\n\r\n");
820
821 fileBuffer.append("VOID\r\n");
822 fileBuffer.append("EFIAPI\r\n");
823 fileBuffer.append("ProcessModuleEntryPointList (\r\n");
824 fileBuffer.append(" IN VOID *HobStart\r\n");
825 fileBuffer.append(" )\r\n\r\n");
826 fileBuffer.append("{\r\n");
827 fileBuffer.append(" ");
828 fileBuffer.append(entryPointList[0]);
829 fileBuffer.append(" (HobStart);\r\n");
830 fileBuffer.append("}\r\n\r\n");
831 }
832 break;
833
834 case CommonDefinition.ModuleTypePeim:
835 entryPointCount = 0;
836 fileBuffer.append("GLOBAL_REMOVE_IF_UNREFERENCED const UINT32 _gPeimRevision = 0;\r\n");
837 if (entryPointList == null || entryPointList.length == 0) {
838 fileBuffer.append("EFI_STATUS\r\n");
839 fileBuffer.append("EFIAPI\r\n");
840 fileBuffer.append("ProcessModuleEntryPointList (\r\n");
841 fileBuffer.append(" IN EFI_FFS_FILE_HEADER *FfsHeader,\r\n");
842 fileBuffer.append(" IN EFI_PEI_SERVICES **PeiServices\r\n");
843 fileBuffer.append(" )\r\n\r\n");
844 fileBuffer.append("{\r\n");
845 fileBuffer.append(" return EFI_SUCCESS;\r\n");
846 fileBuffer.append("}\r\n\r\n");
847 break;
848 }
849 for (int i = 0; i < entryPointList.length; i++) {
850 fileBuffer.append("EFI_STATUS\r\n");
851 fileBuffer.append("EFIAPI\r\n");
852 fileBuffer.append(entryPointList[i]);
853 fileBuffer.append(" (\r\n");
854 fileBuffer.append(" IN EFI_FFS_FILE_HEADER *FfsHeader,\r\n");
855 fileBuffer.append(" IN EFI_PEI_SERVICES **PeiServices\r\n");
856 fileBuffer.append(" );\r\n");
857 entryPointCount++;
858 }
859
860 fileBuffer.append("EFI_STATUS\r\n");
861 fileBuffer.append("EFIAPI\r\n");
862 fileBuffer.append("ProcessModuleEntryPointList (\r\n");
863 fileBuffer.append(" IN EFI_FFS_FILE_HEADER *FfsHeader,\r\n");
864 fileBuffer.append(" IN EFI_PEI_SERVICES **PeiServices\r\n");
865 fileBuffer.append(" )\r\n\r\n");
866 fileBuffer.append("{\r\n");
867 if (entryPointCount == 1) {
868 fileBuffer.append(String.format(" " + debugStr, entryPointList[0], entryPointList[0]));
869 fileBuffer.append(" return ");
870 fileBuffer.append(entryPointList[0]);
871 fileBuffer.append(" (FfsHeader, PeiServices);\r\n");
872 } else {
873 fileBuffer.append(" EFI_STATUS Status;\r\n");
874 fileBuffer.append(" EFI_STATUS CombinedStatus;\r\n\r\n");
875 fileBuffer.append(" CombinedStatus = EFI_LOAD_ERROR;\r\n\r\n");
876 for (int i = 0; i < entryPointList.length; i++) {
877 if (!entryPointList[i].equals("")) {
878 fileBuffer.append(String.format(" " + debugStr, entryPointList[i], entryPointList[i]));
879 fileBuffer.append(" Status = ");
880 fileBuffer.append(entryPointList[i]);
881 fileBuffer.append(" (FfsHeader, PeiServices);\r\n");
882 fileBuffer.append(" if (!EFI_ERROR (Status) || EFI_ERROR (CombinedStatus)) {\r\n");
883 fileBuffer.append(" CombinedStatus = Status;\r\n");
884 fileBuffer.append(" }\r\n\r\n");
885 } else {
886 break;
887 }
888 }
889 fileBuffer.append(" return CombinedStatus;\r\n");
890 }
891 fileBuffer.append("}\r\n\r\n");
892 break;
893
894 case CommonDefinition.ModuleTypeDxeSmmDriver:
895 entryPointCount = 0;
896 //
897 // If entryPoint is null, create an empty ProcessModuleEntryPointList
898 // function.
899 //
900 if (entryPointList == null || entryPointList.length == 0) {
901 fileBuffer.append("GLOBAL_REMOVE_IF_UNREFERENCED const UINT8 _gDriverEntryPointCount = ");
902 fileBuffer.append(Integer.toString(entryPointCount));
903 fileBuffer.append(";\r\n");
904 fileBuffer.append("EFI_STATUS\r\n");
905 fileBuffer.append("EFIAPI\r\n");
906 fileBuffer.append("ProcessModuleEntryPointList (\r\n");
907 fileBuffer.append(" IN EFI_HANDLE ImageHandle,\r\n");
908 fileBuffer.append(" IN EFI_SYSTEM_TABLE *SystemTable\r\n");
909 fileBuffer.append(" )\r\n\r\n");
910 fileBuffer.append("{\r\n");
911 fileBuffer.append(" return EFI_SUCCESS;\r\n");
912 fileBuffer.append("}\r\n\r\n");
913
914 } else {
915 for (int i = 0; i < entryPointList.length; i++) {
916 fileBuffer.append("EFI_STATUS\r\n");
917 fileBuffer.append("EFIAPI\r\n");
918 fileBuffer.append(entryPointList[i]);
919 fileBuffer.append(" (\r\n");
920 fileBuffer.append(" IN EFI_HANDLE ImageHandle,\r\n");
921 fileBuffer.append(" IN EFI_SYSTEM_TABLE *SystemTable\r\n");
922 fileBuffer.append(" );\r\n");
923 entryPointCount++;
924 }
925 fileBuffer.append("GLOBAL_REMOVE_IF_UNREFERENCED const UINT8 _gDriverEntryPointCount = ");
926 fileBuffer.append(Integer.toString(entryPointCount));
927 fileBuffer.append(";\r\n");
928 fileBuffer.append("static BASE_LIBRARY_JUMP_BUFFER mJumpContext;\r\n");
929 fileBuffer.append("static EFI_STATUS mDriverEntryPointStatus = EFI_LOAD_ERROR;\r\n\r\n");
930
931 fileBuffer.append("EFI_STATUS\r\n");
932 fileBuffer.append("EFIAPI\r\n");
933 fileBuffer.append("ProcessModuleEntryPointList (\r\n");
934 fileBuffer.append(" IN EFI_HANDLE ImageHandle,\r\n");
935 fileBuffer.append(" IN EFI_SYSTEM_TABLE *SystemTable\r\n");
936 fileBuffer.append(" )\r\n\r\n");
937 fileBuffer.append("{\r\n");
938
939 for (int i = 0; i < entryPointList.length; i++) {
940 fileBuffer.append(" if (SetJump (&mJumpContext) == 0) {\r\n");
941 fileBuffer.append(String.format(" " + debugStr, entryPointList[i], entryPointList[i]));
942 fileBuffer.append(" ExitDriver (");
943 fileBuffer.append(entryPointList[i]);
944 fileBuffer.append(" (ImageHandle, SystemTable));\r\n");
945 fileBuffer.append(" ASSERT (FALSE);\r\n");
946 fileBuffer.append(" }\r\n");
947 }
948 fileBuffer.append(" return mDriverEntryPointStatus;\r\n");
949 fileBuffer.append("}\r\n\r\n");
950
951 fileBuffer.append("VOID\r\n");
952 fileBuffer.append("EFIAPI\r\n");
953 fileBuffer.append("ExitDriver (\r\n");
954 fileBuffer.append(" IN EFI_STATUS Status\r\n");
955 fileBuffer.append(" )\r\n\r\n");
956 fileBuffer.append("{\r\n");
957 fileBuffer.append(" if (!EFI_ERROR (Status) || EFI_ERROR (mDriverEntryPointStatus)) {\r\n");
958 fileBuffer.append(" mDriverEntryPointStatus = Status;\r\n");
959 fileBuffer.append(" }\r\n");
960 fileBuffer.append(" LongJump (&mJumpContext, (UINTN)-1);\r\n");
961 fileBuffer.append(" ASSERT (FALSE);\r\n");
962 fileBuffer.append("}\r\n\r\n");
963 }
964
965
966 //
967 // Add "ModuleUnloadImage" for DxeSmmDriver module type;
968 //
969
970 unloadImageCount = 0;
971 if (unloadImageList != null) {
972 for (int i = 0; i < unloadImageList.length; i++) {
973 fileBuffer.append("EFI_STATUS\r\n");
974 fileBuffer.append(unloadImageList[i]);
975 fileBuffer.append(" (\r\n");
976 fileBuffer.append(" IN EFI_HANDLE ImageHandle\r\n");
977 fileBuffer.append(" );\r\n");
978 unloadImageCount++;
979 }
980 }
981
982 fileBuffer.append("GLOBAL_REMOVE_IF_UNREFERENCED const UINT8 _gDriverUnloadImageCount = ");
983 fileBuffer.append(Integer.toString(unloadImageCount));
984 fileBuffer.append(";\r\n\r\n");
985
986 fileBuffer.append("EFI_STATUS\r\n");
987 fileBuffer.append("EFIAPI\r\n");
988 fileBuffer.append("ProcessModuleUnloadList (\r\n");
989 fileBuffer.append(" IN EFI_HANDLE ImageHandle\r\n");
990 fileBuffer.append(" )\r\n");
991 fileBuffer.append("{\r\n");
992
993 if (unloadImageCount == 0) {
994 fileBuffer.append(" return EFI_SUCCESS;\r\n");
995 } else if (unloadImageCount == 1) {
996 fileBuffer.append(" return ");
997 fileBuffer.append(unloadImageList[0]);
998 fileBuffer.append("(ImageHandle);\r\n");
999 } else {
1000 fileBuffer.append(" EFI_STATUS Status;\r\n\r\n");
1001 fileBuffer.append(" Status = EFI_SUCCESS;\r\n\r\n");
1002 for (int i = 0; i < unloadImageList.length; i++) {
1003 if (i == 0) {
1004 fileBuffer.append(" Status = ");
1005 fileBuffer.append(unloadImageList[i]);
1006 fileBuffer.append("(ImageHandle);\r\n");
1007 } else {
1008 fileBuffer.append(" if (EFI_ERROR (Status)) {\r\n");
1009 fileBuffer.append(" ");
1010 fileBuffer.append(unloadImageList[i]);
1011 fileBuffer.append("(ImageHandle);\r\n");
1012 fileBuffer.append(" } else {\r\n");
1013 fileBuffer.append(" Status = ");
1014 fileBuffer.append(unloadImageList[i]);
1015 fileBuffer.append("(ImageHandle);\r\n");
1016 fileBuffer.append(" }\r\n");
1017 }
1018 }
1019 fileBuffer.append(" return Status;\r\n");
1020 }
1021 fileBuffer.append("}\r\n\r\n");
1022 break;
1023
1024 case CommonDefinition.ModuleTypeDxeRuntimeDriver:
1025 case CommonDefinition.ModuleTypeDxeDriver:
1026 case CommonDefinition.ModuleTypeDxeSalDriver:
1027 case CommonDefinition.ModuleTypeUefiDriver:
1028 case CommonDefinition.ModuleTypeUefiApplication:
1029 entryPointCount = 0;
1030 fileBuffer.append("const UINT32 _gUefiDriverRevision = 0;\r\n");
1031 //
1032 // If entry point is null, create a empty ProcessModuleEntryPointList function.
1033 //
1034 if (entryPointList == null || entryPointList.length == 0) {
1035 fileBuffer.append("GLOBAL_REMOVE_IF_UNREFERENCED const UINT8 _gDriverEntryPointCount = 0;\r\n");
1036 fileBuffer.append("EFI_STATUS\r\n");
1037 fileBuffer.append("EFIAPI\r\n");
1038 fileBuffer.append("ProcessModuleEntryPointList (\r\n");
1039 fileBuffer.append(" IN EFI_HANDLE ImageHandle,\r\n");
1040 fileBuffer.append(" IN EFI_SYSTEM_TABLE *SystemTable\r\n");
1041 fileBuffer.append(" )\r\n\r\n");
1042 fileBuffer.append("{\r\n");
1043 fileBuffer.append(" return EFI_SUCCESS;\r\n");
1044 fileBuffer.append("}\r\n");
1045
1046 } else {
1047 for (int i = 0; i < entryPointList.length; i++) {
1048 fileBuffer.append("EFI_STATUS\r\n");
1049 fileBuffer.append("EFIAPI\r\n");
1050 fileBuffer.append(entryPointList[i]);
1051 fileBuffer.append(" (\r\n");
1052 fileBuffer.append(" IN EFI_HANDLE ImageHandle,\r\n");
1053 fileBuffer.append(" IN EFI_SYSTEM_TABLE *SystemTable\r\n");
1054 fileBuffer.append(" );\r\n");
1055 entryPointCount++;
1056 }
1057
1058 fileBuffer.append("GLOBAL_REMOVE_IF_UNREFERENCED const UINT8 _gDriverEntryPointCount = ");
1059 fileBuffer.append(Integer.toString(entryPointCount));
1060 fileBuffer.append(";\r\n");
1061 if (entryPointCount > 1) {
1062 fileBuffer.append("static BASE_LIBRARY_JUMP_BUFFER mJumpContext;\r\n");
1063 fileBuffer.append("static EFI_STATUS mDriverEntryPointStatus = EFI_LOAD_ERROR;\r\n");
1064 }
1065 fileBuffer.append("\r\n");
1066
1067 fileBuffer.append("EFI_STATUS\r\n");
1068 fileBuffer.append("EFIAPI\r\n");
1069 fileBuffer.append("ProcessModuleEntryPointList (\r\n");
1070 fileBuffer.append(" IN EFI_HANDLE ImageHandle,\r\n");
1071 fileBuffer.append(" IN EFI_SYSTEM_TABLE *SystemTable\r\n");
1072 fileBuffer.append(" )\r\n\r\n");
1073 fileBuffer.append("{\r\n");
1074
1075 if (entryPointCount == 1) {
1076 fileBuffer.append(String.format(" " + debugStr, entryPointList[0], entryPointList[0]));
1077 fileBuffer.append(" return ");
1078 fileBuffer.append(entryPointList[0]);
1079 fileBuffer.append(" (ImageHandle, SystemTable);\r\n");
1080 } else {
1081 for (int i = 0; i < entryPointList.length; i++) {
1082 if (!entryPointList[i].equals("")) {
1083 fileBuffer.append(" if (SetJump (&mJumpContext) == 0) {\r\n");
1084 fileBuffer.append(String.format(" " + debugStr, entryPointList[i], entryPointList[i]));
1085 fileBuffer.append(" ExitDriver (");
1086 fileBuffer.append(entryPointList[i]);
1087 fileBuffer.append(" (ImageHandle, SystemTable));\r\n");
1088 fileBuffer.append(" ASSERT (FALSE);\r\n");
1089 fileBuffer.append(" }\r\n");
1090 } else {
1091 break;
1092 }
1093 }
1094 fileBuffer.append(" return mDriverEntryPointStatus;\r\n");
1095 }
1096 fileBuffer.append("}\r\n\r\n");
1097
1098 fileBuffer.append("VOID\r\n");
1099 fileBuffer.append("EFIAPI\r\n");
1100 fileBuffer.append("ExitDriver (\r\n");
1101 fileBuffer.append(" IN EFI_STATUS Status\r\n");
1102 fileBuffer.append(" )\r\n\r\n");
1103 fileBuffer.append("{\r\n");
1104 if (entryPointCount <= 1) {
1105 fileBuffer.append(" if (EFI_ERROR (Status)) {\r\n");
1106 fileBuffer.append(" ProcessLibraryDestructorList (gImageHandle, gST);\r\n");
1107 fileBuffer.append(" }\r\n");
1108 fileBuffer
1109 .append(" gBS->Exit (gImageHandle, Status, 0, NULL);\r\n");
1110 } else {
1111 fileBuffer.append(" if (!EFI_ERROR (Status) || EFI_ERROR (mDriverEntryPointStatus)) {\r\n");
1112 fileBuffer.append(" mDriverEntryPointStatus = Status;\r\n");
1113 fileBuffer.append(" }\r\n");
1114 fileBuffer.append(" LongJump (&mJumpContext, (UINTN)-1);\r\n");
1115 fileBuffer.append(" ASSERT (FALSE);\r\n");
1116 }
1117 fileBuffer.append("}\r\n\r\n");
1118 }
1119
1120 //
1121 // Add ModuleUnloadImage for DxeDriver and UefiDriver module type.
1122 //
1123 //entryPointList = SurfaceAreaQuery.getModuleUnloadImageArray();
1124 //
1125 // Remover duplicate unload entry point.
1126 //
1127 //entryPointList = CommonDefinition.remDupString(entryPointList);
1128 //entryPointCount = 0;
1129 unloadImageCount = 0;
1130 if (unloadImageList != null) {
1131 for (int i = 0; i < unloadImageList.length; i++) {
1132 fileBuffer.append("EFI_STATUS\r\n");
1133 fileBuffer.append("EFIAPI\r\n");
1134 fileBuffer.append(unloadImageList[i]);
1135 fileBuffer.append(" (\r\n");
1136 fileBuffer.append(" IN EFI_HANDLE ImageHandle\r\n");
1137 fileBuffer.append(" );\r\n");
1138 unloadImageCount++;
1139 }
1140 }
1141
1142 fileBuffer.append("GLOBAL_REMOVE_IF_UNREFERENCED const UINT8 _gDriverUnloadImageCount = ");
1143 fileBuffer.append(Integer.toString(unloadImageCount));
1144 fileBuffer.append(";\r\n\r\n");
1145
1146 fileBuffer.append("EFI_STATUS\r\n");
1147 fileBuffer.append("EFIAPI\r\n");
1148 fileBuffer.append("ProcessModuleUnloadList (\r\n");
1149 fileBuffer.append(" IN EFI_HANDLE ImageHandle\r\n");
1150 fileBuffer.append(" )\r\n");
1151 fileBuffer.append("{\r\n");
1152
1153 if (unloadImageCount == 0) {
1154 fileBuffer.append(" return EFI_SUCCESS;\r\n");
1155 } else if (unloadImageCount == 1) {
1156 fileBuffer.append(" return ");
1157 fileBuffer.append(unloadImageList[0]);
1158 fileBuffer.append("(ImageHandle);\r\n");
1159 } else {
1160 fileBuffer.append(" EFI_STATUS Status;\r\n\r\n");
1161 fileBuffer.append(" Status = EFI_SUCCESS;\r\n\r\n");
1162 for (int i = 0; i < unloadImageList.length; i++) {
1163 if (i == 0) {
1164 fileBuffer.append(" Status = ");
1165 fileBuffer.append(unloadImageList[i]);
1166 fileBuffer.append("(ImageHandle);\r\n");
1167 } else {
1168 fileBuffer.append(" if (EFI_ERROR (Status)) {\r\n");
1169 fileBuffer.append(" ");
1170 fileBuffer.append(unloadImageList[i]);
1171 fileBuffer.append("(ImageHandle);\r\n");
1172 fileBuffer.append(" } else {\r\n");
1173 fileBuffer.append(" Status = ");
1174 fileBuffer.append(unloadImageList[i]);
1175 fileBuffer.append("(ImageHandle);\r\n");
1176 fileBuffer.append(" }\r\n");
1177 }
1178 }
1179 fileBuffer.append(" return Status;\r\n");
1180 }
1181 fileBuffer.append("}\r\n\r\n");
1182 break;
1183 }
1184 }
1185
1186 /**
1187 PpiGuidToAutogenc
1188
1189 This function gets GUIDs from SPD file accrodeing to <PPIs> information
1190 and write those GUIDs to AutoGen.c.
1191
1192 @param fileBuffer
1193 String Buffer for Autogen.c file.
1194 @throws BuildException
1195 Guid must set value!
1196 **/
1197 void PpiGuidToAutogenC(StringBuffer fileBuffer) throws AutoGenException {
1198 String[] cNameGuid = null;
1199
1200 //
1201 // Get the all PPI adn PPI Notify from MSA file,
1202 // then add those PPI ,and PPI Notify name to list.
1203 //
1204
1205 String[] ppiList = saq.getPpiArray(this.arch);
1206 for (int i = 0; i < ppiList.length; i++) {
1207 this.mPpiList.add(ppiList[i]);
1208 }
1209
1210 String[] ppiNotifyList = saq.getPpiNotifyArray(this.arch);
1211 for (int i = 0; i < ppiNotifyList.length; i++) {
1212 this.mPpiList.add(ppiNotifyList[i]);
1213 }
1214
1215 //
1216 // Find CNAME and GUID from dependence SPD file and write to Autogen.c
1217 //
1218 Iterator ppiIterator = this.mPpiList.iterator();
1219 String ppiKeyWord = null;
1220 while (ppiIterator.hasNext()) {
1221 ppiKeyWord = ppiIterator.next().toString();
1222 cNameGuid = GlobalData.getPpiGuid(this.mDepPkgList, ppiKeyWord);
1223 if (cNameGuid != null) {
1224 fileBuffer.append("\r\nGLOBAL_REMOVE_IF_UNREFERENCED EFI_GUID ");
1225 fileBuffer.append(cNameGuid[0]);
1226 fileBuffer.append(" = { ");
1227 fileBuffer.append(CommonDefinition.formatGuidName(cNameGuid[1]));
1228 fileBuffer.append(" } ;");
1229 } else {
1230 //
1231 // If can't find Ppi GUID declaration in every package
1232 //
1233 throw new AutoGenException("Can not find Ppi GUID ["
1234 + ppiKeyWord + "] declaration in any SPD package!");
1235 }
1236 }
1237 }
1238
1239 /**
1240 ProtocolGuidToAutogenc
1241
1242 This function gets GUIDs from SPD file accrodeing to <Protocol>
1243 information and write those GUIDs to AutoGen.c.
1244
1245 @param fileBuffer
1246 String Buffer for Autogen.c file.
1247 @throws BuildException
1248 Protocol name must set.
1249 **/
1250 void ProtocolGuidToAutogenC(StringBuffer fileBuffer) throws EdkException {
1251 String[] cNameGuid = null;
1252
1253 String[] protocolList = saq.getProtocolArray(this.arch);
1254
1255 //
1256 // Add result to Autogen global list.
1257 //
1258 for (int i = 0; i < protocolList.length; i++) {
1259 this.mProtocolList.add(protocolList[i]);
1260 }
1261
1262 String[] protocolNotifyList = saq.getProtocolNotifyArray(this.arch);
1263
1264 for (int i = 0; i < protocolNotifyList.length; i++) {
1265 this.mProtocolList.add(protocolNotifyList[i]);
1266 }
1267
1268 //
1269 // Get the NAME and GUID from dependence SPD and write to Autogen.c
1270 //
1271 Iterator protocolIterator = this.mProtocolList.iterator();
1272 String protocolKeyWord = null;
1273
1274
1275 while (protocolIterator.hasNext()) {
1276 protocolKeyWord = protocolIterator.next().toString();
1277 cNameGuid = GlobalData.getProtocolGuid(this.mDepPkgList, protocolKeyWord);
1278 if (cNameGuid != null) {
1279 fileBuffer.append("\r\nGLOBAL_REMOVE_IF_UNREFERENCED EFI_GUID ");
1280 fileBuffer.append(cNameGuid[0]);
1281 fileBuffer.append(" = { ");
1282 fileBuffer.append(CommonDefinition.formatGuidName(cNameGuid[1]));
1283 fileBuffer.append(" } ;");
1284 } else {
1285 //
1286 // If can't find protocol GUID declaration in every package
1287 //
1288 throw new AutoGenException("Can not find protocol Guid ["
1289 + protocolKeyWord + "] declaration in any SPD package!");
1290 }
1291 }
1292 }
1293
1294 /**
1295 GuidGuidToAutogenc
1296
1297 This function gets GUIDs from SPD file accrodeing to <Guids> information
1298 and write those GUIDs to AutoGen.c.
1299
1300 @param fileBuffer
1301 String Buffer for Autogen.c file.
1302
1303 **/
1304 void GuidGuidToAutogenC(StringBuffer fileBuffer) throws AutoGenException {
1305 String[] cNameGuid = null;
1306 String guidKeyWord = null;
1307
1308 String[] guidList = saq.getGuidEntryArray(this.arch);
1309
1310 for (int i = 0; i < guidList.length; i++) {
1311 this.mGuidList.add(guidList[i]);
1312 }
1313
1314
1315 Iterator guidIterator = this.mGuidList.iterator();
1316 while (guidIterator.hasNext()) {
1317 guidKeyWord = guidIterator.next().toString();
1318 cNameGuid = GlobalData.getGuid(this.mDepPkgList, guidKeyWord);
1319
1320 if (cNameGuid != null) {
1321 fileBuffer.append("\r\nGLOBAL_REMOVE_IF_UNREFERENCED EFI_GUID ");
1322 fileBuffer.append(cNameGuid[0]);
1323 fileBuffer.append(" = { ");
1324 fileBuffer.append(CommonDefinition.formatGuidName(cNameGuid[1]));
1325 fileBuffer.append("} ;");
1326 } else {
1327 //
1328 // If can't find GUID declaration in every package
1329 //
1330 throw new AutoGenException("Can not find Guid [" + guidKeyWord
1331 + "] declaration in any SPD package. ");
1332 }
1333
1334 }
1335 }
1336
1337 /**
1338 LibInstanceToAutogenC
1339
1340 This function adds dependent library instance to autogen.c,which
1341 includeing library's constructor, destructor, and library dependent ppi,
1342 protocol, guid, pcd information.
1343
1344 @param fileBuffer
1345 String buffer for AutoGen.c
1346 @throws BuildException
1347 **/
1348 void LibInstanceToAutogenC(StringBuffer fileBuffer) throws EdkException {
1349 String moduleType = this.moduleId.getModuleType();
1350 //
1351 // Add library constructor to AutoGen.c
1352 //
1353 LibConstructorToAutogenC(libConstructList, moduleType, fileBuffer);
1354 //
1355 // Add library destructor to AutoGen.c
1356 //
1357 LibDestructorToAutogenC(libDestructList, moduleType, fileBuffer);
1358 }
1359
1360 /**
1361 LibConstructorToAutogenH
1362
1363 This function writes library constructor declarations AutoGen.h. The library
1364 constructor's parameter and return value depend on module type.
1365
1366 @param libInstanceList
1367 List of library construct name.
1368 @param moduleType
1369 Module type.
1370 @param fileBuffer
1371 String buffer for AutoGen.c
1372 @throws Exception
1373 **/
1374 void LibConstructorToAutogenH(String moduleType) throws EdkException {
1375 boolean isFirst = true;
1376
1377 //
1378 // If not yet parse this library instance's constructor
1379 // element,parse it.
1380 //
1381 String libConstructName = saq.getLibConstructorName();
1382 if (libConstructName == null) {
1383 return;
1384 }
1385
1386 //
1387 // The library constructor's parameter and return value depend on
1388 // module type.
1389 //
1390 if (moduleType.equalsIgnoreCase(EdkDefinitions.MODULE_TYPE_BASE)) {
1391 functionDeclarations.append("RETURN_STATUS\r\n");
1392 functionDeclarations.append("EFIAPI\r\n");
1393 functionDeclarations.append(libConstructName);
1394 functionDeclarations.append(" (\r\n");
1395 functionDeclarations.append(" VOID\r\n");
1396 functionDeclarations.append(" );\r\n");
1397 } else {
1398 switch (CommonDefinition.getModuleType(moduleType)) {
1399 case CommonDefinition.ModuleTypeBase:
1400 functionDeclarations.append("RETURN_STATUS\r\n");
1401 functionDeclarations.append("EFIAPI\r\n");
1402 functionDeclarations.append(libConstructName);
1403 functionDeclarations.append(" (\r\n");
1404 functionDeclarations.append(" VOID\r\n");
1405 functionDeclarations.append(" );\r\n");
1406 break;
1407
1408 case CommonDefinition.ModuleTypePeiCore:
1409 case CommonDefinition.ModuleTypePeim:
1410 functionDeclarations.append("EFI_STATUS\r\n");
1411 functionDeclarations.append("EFIAPI\r\n");
1412 functionDeclarations.append(libConstructName);
1413 functionDeclarations.append(" (\r\n");
1414 functionDeclarations.append(" IN EFI_FFS_FILE_HEADER *FfsHeader,\r\n");
1415 functionDeclarations.append(" IN EFI_PEI_SERVICES **PeiServices\r\n");
1416 functionDeclarations.append(" );\r\n");
1417 break;
1418
1419 case CommonDefinition.ModuleTypeDxeCore:
1420 case CommonDefinition.ModuleTypeDxeDriver:
1421 case CommonDefinition.ModuleTypeDxeRuntimeDriver:
1422 case CommonDefinition.ModuleTypeDxeSmmDriver:
1423 case CommonDefinition.ModuleTypeDxeSalDriver:
1424 case CommonDefinition.ModuleTypeUefiDriver:
1425 case CommonDefinition.ModuleTypeUefiApplication:
1426 functionDeclarations.append("EFI_STATUS\r\n");
1427 functionDeclarations.append("EFIAPI\r\n");
1428 functionDeclarations.append(libConstructName);
1429 functionDeclarations.append(" (\r\n");
1430 functionDeclarations.append(" IN EFI_HANDLE ImageHandle,\r\n");
1431 functionDeclarations.append(" IN EFI_SYSTEM_TABLE *SystemTable\r\n");
1432 functionDeclarations.append(" );\r\n");
1433 break;
1434
1435 }
1436 }
1437 }
1438
1439 /**
1440 LibDestructorToAutogenH
1441
1442 This function writes library destructor declarations AutoGen.h. The library
1443 destructor's parameter and return value depend on module type.
1444
1445 @param libInstanceList
1446 List of library destructor name.
1447 @param moduleType
1448 Module type.
1449 @param fileBuffer
1450 String buffer for AutoGen.c
1451 @throws Exception
1452 **/
1453 void LibDestructorToAutogenH(String moduleType) throws EdkException {
1454 boolean isFirst = true;
1455 String libDestructName = saq.getLibDestructorName();
1456 if (libDestructName == null) {
1457 return;
1458 }
1459
1460 if (moduleType.equalsIgnoreCase(EdkDefinitions.MODULE_TYPE_BASE)) {
1461 functionDeclarations.append("RETURN_STATUS\r\n");
1462 functionDeclarations.append("EFIAPI\r\n");
1463 functionDeclarations.append(libDestructName);
1464 functionDeclarations.append(" (\r\n");
1465 functionDeclarations.append(" VOID\r\n");
1466 functionDeclarations.append(" );\r\n");
1467 } else {
1468 switch (CommonDefinition.getModuleType(moduleType)) {
1469 case CommonDefinition.ModuleTypeBase:
1470 functionDeclarations.append("RETURN_STATUS\r\n");
1471 functionDeclarations.append("EFIAPI\r\n");
1472 functionDeclarations.append(libDestructName);
1473 functionDeclarations.append(" (\r\n");
1474 functionDeclarations.append(" VOID\r\n");
1475 functionDeclarations.append(" );\r\n");
1476 break;
1477 case CommonDefinition.ModuleTypePeiCore:
1478 case CommonDefinition.ModuleTypePeim:
1479 functionDeclarations.append("EFI_STATUS\r\n");
1480 functionDeclarations.append("EFIAPI\r\n");
1481 functionDeclarations.append(libDestructName);
1482 functionDeclarations.append(" (\r\n");
1483 functionDeclarations.append(" IN EFI_FFS_FILE_HEADER *FfsHeader,\r\n");
1484 functionDeclarations.append(" IN EFI_PEI_SERVICES **PeiServices\r\n");
1485 functionDeclarations.append(" );\r\n");
1486 break;
1487 case CommonDefinition.ModuleTypeDxeCore:
1488 case CommonDefinition.ModuleTypeDxeDriver:
1489 case CommonDefinition.ModuleTypeDxeRuntimeDriver:
1490 case CommonDefinition.ModuleTypeDxeSmmDriver:
1491 case CommonDefinition.ModuleTypeDxeSalDriver:
1492 case CommonDefinition.ModuleTypeUefiDriver:
1493 case CommonDefinition.ModuleTypeUefiApplication:
1494 functionDeclarations.append("EFI_STATUS\r\n");
1495 functionDeclarations.append("EFIAPI\r\n");
1496 functionDeclarations.append(libDestructName);
1497 functionDeclarations.append(" (\r\n");
1498 functionDeclarations.append(" IN EFI_HANDLE ImageHandle,\r\n");
1499 functionDeclarations.append(" IN EFI_SYSTEM_TABLE *SystemTable\r\n");
1500 functionDeclarations.append(" );\r\n");
1501 break;
1502 }
1503 }
1504 }
1505
1506 /**
1507 LibConstructorToAutogenc
1508
1509 This function writes library constructor list to AutoGen.c. The library
1510 constructor's parameter and return value depend on module type.
1511
1512 @param libInstanceList
1513 List of library construct name.
1514 @param moduleType
1515 Module type.
1516 @param fileBuffer
1517 String buffer for AutoGen.c
1518 @throws Exception
1519 **/
1520 void LibConstructorToAutogenC(List<String[]> libInstanceList,
1521 String moduleType, StringBuffer fileBuffer) throws EdkException {
1522 boolean isFirst = true;
1523
1524 //
1525 // The library constructor's parameter and return value depend on
1526 // module type.
1527 //
1528 for (int i = 0; i < libInstanceList.size(); i++) {
1529 if (libInstanceList.get(i)[1].equalsIgnoreCase(EdkDefinitions.MODULE_TYPE_BASE)) {
1530 functionDeclarations.append("RETURN_STATUS\r\n");
1531 functionDeclarations.append("EFIAPI\r\n");
1532 functionDeclarations.append(libInstanceList.get(i)[0]);
1533 functionDeclarations.append(" (\r\n");
1534 functionDeclarations.append(" VOID\r\n");
1535 functionDeclarations.append(" );\r\n");
1536 } else {
1537 switch (CommonDefinition.getModuleType(moduleType)) {
1538 case CommonDefinition.ModuleTypeBase:
1539 functionDeclarations.append("RETURN_STATUS\r\n");
1540 functionDeclarations.append("EFIAPI\r\n");
1541 functionDeclarations.append(libInstanceList.get(i)[0]);
1542 functionDeclarations.append(" (\r\n");
1543 functionDeclarations.append(" VOID\r\n");
1544 functionDeclarations.append(" );\r\n");
1545 break;
1546
1547 case CommonDefinition.ModuleTypePeiCore:
1548 case CommonDefinition.ModuleTypePeim:
1549 functionDeclarations.append("EFI_STATUS\r\n");
1550 functionDeclarations.append("EFIAPI\r\n");
1551 functionDeclarations.append(libInstanceList.get(i)[0]);
1552 functionDeclarations.append(" (\r\n");
1553 functionDeclarations.append(" IN EFI_FFS_FILE_HEADER *FfsHeader,\r\n");
1554 functionDeclarations.append(" IN EFI_PEI_SERVICES **PeiServices\r\n");
1555 functionDeclarations.append(" );\r\n");
1556 break;
1557
1558 case CommonDefinition.ModuleTypeDxeCore:
1559 case CommonDefinition.ModuleTypeDxeDriver:
1560 case CommonDefinition.ModuleTypeDxeRuntimeDriver:
1561 case CommonDefinition.ModuleTypeDxeSmmDriver:
1562 case CommonDefinition.ModuleTypeDxeSalDriver:
1563 case CommonDefinition.ModuleTypeUefiDriver:
1564 case CommonDefinition.ModuleTypeUefiApplication:
1565 functionDeclarations.append("EFI_STATUS\r\n");
1566 functionDeclarations.append("EFIAPI\r\n");
1567 functionDeclarations.append(libInstanceList.get(i)[0]);
1568 functionDeclarations.append(" (\r\n");
1569 functionDeclarations.append(" IN EFI_HANDLE ImageHandle,\r\n");
1570 functionDeclarations.append(" IN EFI_SYSTEM_TABLE *SystemTable\r\n");
1571 functionDeclarations.append(" );\r\n");
1572 break;
1573
1574 }
1575 }
1576 }
1577
1578 //
1579 // Add ProcessLibraryConstructorList in AutoGen.c
1580 //
1581 fileBuffer.append("VOID\r\n");
1582 fileBuffer.append("EFIAPI\r\n");
1583 fileBuffer.append("ProcessLibraryConstructorList (\r\n");
1584 switch (CommonDefinition.getModuleType(moduleType)) {
1585 case CommonDefinition.ModuleTypeBase:
1586 fileBuffer.append(" VOID\r\n");
1587 break;
1588
1589 case CommonDefinition.ModuleTypePeiCore:
1590 case CommonDefinition.ModuleTypePeim:
1591 fileBuffer.append(" IN EFI_FFS_FILE_HEADER *FfsHeader,\r\n");
1592 fileBuffer
1593 .append(" IN EFI_PEI_SERVICES **PeiServices\r\n");
1594 break;
1595
1596 case CommonDefinition.ModuleTypeDxeCore:
1597 case CommonDefinition.ModuleTypeDxeDriver:
1598 case CommonDefinition.ModuleTypeDxeRuntimeDriver:
1599 case CommonDefinition.ModuleTypeDxeSmmDriver:
1600 case CommonDefinition.ModuleTypeDxeSalDriver:
1601 case CommonDefinition.ModuleTypeUefiDriver:
1602 case CommonDefinition.ModuleTypeUefiApplication:
1603 fileBuffer.append(" IN EFI_HANDLE ImageHandle,\r\n");
1604 fileBuffer.append(" IN EFI_SYSTEM_TABLE *SystemTable\r\n");
1605 break;
1606 }
1607
1608 fileBuffer.append(" )\r\n");
1609 fileBuffer.append("{\r\n");
1610 //
1611 // If no constructor function, return EFI_SUCCESS.
1612 //
1613 for (int i = 0; i < libInstanceList.size(); i++) {
1614 if (isFirst) {
1615 fileBuffer.append(" EFI_STATUS Status;\r\n");
1616 fileBuffer.append(" Status = EFI_SUCCESS;\r\n");
1617 fileBuffer.append("\r\n");
1618 isFirst = false;
1619 }
1620 if (libInstanceList.get(i)[1].equalsIgnoreCase(EdkDefinitions.MODULE_TYPE_BASE)) {
1621 fileBuffer.append(" Status = ");
1622 fileBuffer.append(libInstanceList.get(i)[0]);
1623 fileBuffer.append("();\r\n");
1624 } else {
1625 switch (CommonDefinition.getModuleType(moduleType)) {
1626 case CommonDefinition.ModuleTypeBase:
1627 fileBuffer.append(" Status = ");
1628 fileBuffer.append(libInstanceList.get(i)[0]);
1629 fileBuffer.append("();\r\n");
1630 break;
1631 case CommonDefinition.ModuleTypePeiCore:
1632 case CommonDefinition.ModuleTypePeim:
1633 fileBuffer.append(" Status = ");
1634 fileBuffer.append(libInstanceList.get(i)[0]);
1635 fileBuffer.append(" (FfsHeader, PeiServices);\r\n");
1636 break;
1637 case CommonDefinition.ModuleTypeDxeCore:
1638 case CommonDefinition.ModuleTypeDxeDriver:
1639 case CommonDefinition.ModuleTypeDxeRuntimeDriver:
1640 case CommonDefinition.ModuleTypeDxeSmmDriver:
1641 case CommonDefinition.ModuleTypeDxeSalDriver:
1642 case CommonDefinition.ModuleTypeUefiDriver:
1643 case CommonDefinition.ModuleTypeUefiApplication:
1644 fileBuffer.append(" Status = ");
1645 fileBuffer.append(libInstanceList.get(i)[0]);
1646 fileBuffer.append(" (ImageHandle, SystemTable);\r\n");
1647 break;
1648 default:
1649 EdkLog.log(EdkLog.EDK_INFO,"Autogen doesn't know how to deal with module type - " + moduleType + "!");
1650 }
1651
1652 }
1653 fileBuffer.append(" ASSERT_EFI_ERROR (Status);\r\n");
1654 }
1655 fileBuffer.append("}\r\n");
1656 }
1657
1658 /**
1659 LibDestructorToAutogenc
1660
1661 This function writes library destructor list to AutoGen.c. The library
1662 destructor's parameter and return value depend on module type.
1663
1664 @param libInstanceList
1665 List of library destructor name.
1666 @param moduleType
1667 Module type.
1668 @param fileBuffer
1669 String buffer for AutoGen.c
1670 @throws Exception
1671 **/
1672 void LibDestructorToAutogenC(List<String[]> libInstanceList,
1673 String moduleType, StringBuffer fileBuffer) throws EdkException {
1674 boolean isFirst = true;
1675 for (int i = 0; i < libInstanceList.size(); i++) {
1676 if (libInstanceList.get(i)[1].equalsIgnoreCase(EdkDefinitions.MODULE_TYPE_BASE)) {
1677 functionDeclarations.append("RETURN_STATUS\r\n");
1678 functionDeclarations.append("EFIAPI\r\n");
1679 functionDeclarations.append(libInstanceList.get(i)[0]);
1680 functionDeclarations.append(" (\r\n");
1681 functionDeclarations.append(" VOID\r\n");
1682 functionDeclarations.append(" );\r\n");
1683 } else {
1684 switch (CommonDefinition.getModuleType(moduleType)) {
1685 case CommonDefinition.ModuleTypeBase:
1686 functionDeclarations.append("RETURN_STATUS\r\n");
1687 functionDeclarations.append("EFIAPI\r\n");
1688 functionDeclarations.append(libInstanceList.get(i)[0]);
1689 functionDeclarations.append(" (\r\n");
1690 functionDeclarations.append(" VOID\r\n");
1691 functionDeclarations.append(" );\r\n");
1692 break;
1693 case CommonDefinition.ModuleTypePeiCore:
1694 case CommonDefinition.ModuleTypePeim:
1695 functionDeclarations.append("EFI_STATUS\r\n");
1696 functionDeclarations.append("EFIAPI\r\n");
1697 functionDeclarations.append(libInstanceList.get(i)[0]);
1698 functionDeclarations.append(" (\r\n");
1699 functionDeclarations.append(" IN EFI_FFS_FILE_HEADER *FfsHeader,\r\n");
1700 functionDeclarations.append(" IN EFI_PEI_SERVICES **PeiServices\r\n");
1701 functionDeclarations.append(" );\r\n");
1702 break;
1703 case CommonDefinition.ModuleTypeDxeCore:
1704 case CommonDefinition.ModuleTypeDxeDriver:
1705 case CommonDefinition.ModuleTypeDxeRuntimeDriver:
1706 case CommonDefinition.ModuleTypeDxeSmmDriver:
1707 case CommonDefinition.ModuleTypeDxeSalDriver:
1708 case CommonDefinition.ModuleTypeUefiDriver:
1709 case CommonDefinition.ModuleTypeUefiApplication:
1710 functionDeclarations.append("EFI_STATUS\r\n");
1711 functionDeclarations.append("EFIAPI\r\n");
1712 functionDeclarations.append(libInstanceList.get(i)[0]);
1713 functionDeclarations.append(" (\r\n");
1714 functionDeclarations.append(" IN EFI_HANDLE ImageHandle,\r\n");
1715 functionDeclarations.append(" IN EFI_SYSTEM_TABLE *SystemTable\r\n");
1716 functionDeclarations.append(" );\r\n");
1717 break;
1718 }
1719 }
1720 }
1721
1722 //
1723 // Write ProcessLibraryDestructor list to autogen.c
1724 //
1725 switch (CommonDefinition.getModuleType(moduleType)) {
1726 case CommonDefinition.ModuleTypeBase:
1727 case CommonDefinition.ModuleTypePeiCore:
1728 case CommonDefinition.ModuleTypePeim:
1729 break;
1730 case CommonDefinition.ModuleTypeDxeCore:
1731 case CommonDefinition.ModuleTypeDxeDriver:
1732 case CommonDefinition.ModuleTypeDxeRuntimeDriver:
1733 case CommonDefinition.ModuleTypeDxeSmmDriver:
1734 case CommonDefinition.ModuleTypeDxeSalDriver:
1735 case CommonDefinition.ModuleTypeUefiDriver:
1736 case CommonDefinition.ModuleTypeUefiApplication:
1737 fileBuffer.append("VOID\r\n");
1738 fileBuffer.append("EFIAPI\r\n");
1739 fileBuffer.append("ProcessLibraryDestructorList (\r\n");
1740 fileBuffer.append(" IN EFI_HANDLE ImageHandle,\r\n");
1741 fileBuffer.append(" IN EFI_SYSTEM_TABLE *SystemTable\r\n");
1742 fileBuffer.append(" )\r\n");
1743 fileBuffer.append("{\r\n");
1744 //
1745 // If no library destructor function, return EFI_SUCCESS.
1746 //
1747
1748 for (int i = 0; i < libInstanceList.size(); i++) {
1749 if (isFirst) {
1750 fileBuffer.append(" EFI_STATUS Status;\r\n");
1751 fileBuffer.append(" Status = EFI_SUCCESS;\r\n");
1752 fileBuffer.append("\r\n");
1753 isFirst = false;
1754 }
1755 if (libInstanceList.get(i)[1].equalsIgnoreCase(EdkDefinitions.MODULE_TYPE_BASE)) {
1756 fileBuffer.append(" Status = ");
1757 fileBuffer.append(libInstanceList.get(i)[0]);
1758 fileBuffer.append("();\r\n");
1759 fileBuffer.append(" VOID\r\n");
1760 } else {
1761 fileBuffer.append(" Status = ");
1762 fileBuffer.append(libInstanceList.get(i)[0]);
1763 fileBuffer.append("(ImageHandle, SystemTable);\r\n");
1764 fileBuffer.append(" ASSERT_EFI_ERROR (Status);\r\n");
1765 }
1766 }
1767 fileBuffer.append("}\r\n");
1768 break;
1769 }
1770 }
1771
1772 /**
1773 ExternsDriverBindingToAutoGenC
1774
1775 This function is to write DRIVER_BINDING, COMPONENT_NAME,
1776 DRIVER_CONFIGURATION, DRIVER_DIAGNOSTIC in AutoGen.c.
1777
1778 @param fileBuffer
1779 String buffer for AutoGen.c
1780 **/
1781 void ExternsDriverBindingToAutoGenC(StringBuffer fileBuffer)
1782 throws EdkException {
1783 //
1784 // Get the arry of extern. The driverBindingGroup is a 2 dimension array.
1785 // The second dimension is include following element: DriverBinding,
1786 // ComponentName, DriverConfiguration, DriverDiag;
1787 //
1788 String[][] driverBindingGroup = this.saq.getExternProtocolGroup();
1789
1790
1791 //
1792 // inital BitMask;
1793 //
1794 int BitMask = 0;
1795
1796 //
1797 // Write driver binding protocol extern to autogen.c
1798 //
1799 for (int i = 0; i < driverBindingGroup.length; i++) {
1800 if (driverBindingGroup[i][0] != null) {
1801 fileBuffer.append("extern EFI_DRIVER_BINDING_PROTOCOL ");
1802 fileBuffer.append(driverBindingGroup[i][0]);
1803 fileBuffer.append(";\r\n");
1804 }
1805 }
1806
1807 //
1808 // Write component name protocol extern to autogen.c
1809 //
1810 if (!componentNamePcd) {
1811 for (int i = 0; i < driverBindingGroup.length; i++) {
1812 if (driverBindingGroup[i][1]!= null) {
1813 if (driverBindingGroup[i][0] != null) {
1814 BitMask |= 0x01;
1815 fileBuffer.append("extern EFI_COMPONENT_NAME_PROTOCOL ");
1816 fileBuffer.append(driverBindingGroup[i][1]);
1817 fileBuffer.append(";\r\n");
1818 } else {
1819 throw new AutoGenException("DriverBinding can't be empty!!");
1820 }
1821 }
1822 }
1823 }
1824
1825 //
1826 // Write driver configration protocol extern to autogen.c
1827 //
1828 for (int i = 0; i < driverBindingGroup.length; i++) {
1829 if (driverBindingGroup[i][2] != null) {
1830 if (driverBindingGroup[i][0] != null) {
1831 BitMask |= 0x02;
1832 fileBuffer.append("extern EFI_DRIVER_CONFIGURATION_PROTOCOL ");
1833 fileBuffer.append(driverBindingGroup[i][2]);
1834 fileBuffer.append(";\r\n");
1835 } else {
1836 throw new AutoGenException("DriverBinding can't be empty!!");
1837 }
1838 }
1839 }
1840
1841 //
1842 // Write driver dignastic protocol extern to autogen.c
1843 //
1844 if (!driverDiagnostPcd) {
1845 for (int i = 0; i < driverBindingGroup.length; i++) {
1846 if (driverBindingGroup[i][3] != null) {
1847 if (driverBindingGroup[i][0] != null) {
1848 BitMask |= 0x04;
1849 fileBuffer.append("extern EFI_DRIVER_DIAGNOSTICS_PROTOCOL ");
1850 fileBuffer.append(driverBindingGroup[i][3]);
1851 fileBuffer.append(";\r\n");
1852 } else {
1853 throw new AutoGenException("DriverBinding can't be empty!!");
1854 }
1855 }
1856 }
1857 }
1858
1859
1860 //
1861 // Write driver module protocol bitmask.
1862 //
1863 fileBuffer.append("GLOBAL_REMOVE_IF_UNREFERENCED const UINT8 _gDriverModelProtocolBitmask = ");
1864 fileBuffer.append(Integer.toString(BitMask));
1865 fileBuffer.append(";\r\n");
1866
1867 //
1868 // Write driver module protocol list entry
1869 //
1870 fileBuffer.append("GLOBAL_REMOVE_IF_UNREFERENCED const UINTN _gDriverModelProtocolListEntries = ");
1871
1872 fileBuffer.append(Integer.toString(driverBindingGroup.length));
1873 fileBuffer.append(";\r\n");
1874
1875 //
1876 // Write drive module protocol list to autogen.c
1877 //
1878 if (driverBindingGroup.length > 0) {
1879 fileBuffer.append("GLOBAL_REMOVE_IF_UNREFERENCED const EFI_DRIVER_MODEL_PROTOCOL_LIST _gDriverModelProtocolList[] = {");
1880 }
1881
1882
1883 for (int i = 0; i < driverBindingGroup.length; i++) {
1884 if (i != 0) {
1885 fileBuffer.append(",");
1886 }
1887 //
1888 // DriverBinding
1889 //
1890 fileBuffer.append("\r\n {\r\n");
1891 fileBuffer.append(" &");
1892 fileBuffer.append(driverBindingGroup[i][0]);
1893 fileBuffer.append(", \r\n");
1894
1895 //
1896 // ComponentName
1897 //
1898 if (driverBindingGroup[i][1] != null && componentNamePcd != true) {
1899 fileBuffer.append(" &");
1900 fileBuffer.append(driverBindingGroup[i][1]);
1901 fileBuffer.append(", \r\n");
1902 } else {
1903 fileBuffer.append(" NULL, \r\n");
1904 }
1905
1906 //
1907 // DriverConfiguration
1908 //
1909 if (driverBindingGroup[i][2] != null) {
1910 fileBuffer.append(" &");
1911 fileBuffer.append(driverBindingGroup[i][2]);
1912 fileBuffer.append(", \r\n");
1913 } else {
1914 fileBuffer.append(" NULL, \r\n");
1915 }
1916
1917 //
1918 // DriverDiagnostic
1919 //
1920 if (driverBindingGroup[i][3] != null && driverDiagnostPcd != true) {
1921 fileBuffer.append(" &");
1922 fileBuffer.append(driverBindingGroup[i][3]);
1923 fileBuffer.append(", \r\n");
1924 } else {
1925 fileBuffer.append(" NULL, \r\n");
1926 }
1927 fileBuffer.append(" }");
1928 }
1929
1930 if (driverBindingGroup.length > 0) {
1931 fileBuffer.append("\r\n};\r\n");
1932 }
1933 }
1934
1935 /**
1936 ExternCallBackToAutoGenC
1937
1938 This function adds <SetVirtualAddressMapCallBack> and
1939 <ExitBootServicesCallBack> infomation to AutoGen.c
1940
1941 @param fileBuffer
1942 String buffer for AutoGen.c
1943 @throws BuildException
1944 **/
1945 void ExternCallBackToAutoGenH(String moduleType)
1946 throws EdkException {
1947 //
1948 // Collect module's <SetVirtualAddressMapCallBack> and
1949 // <ExitBootServiceCallBack> and add to setVirtualAddList
1950 // exitBootServiceList.
1951 //
1952 String[] setVirtuals = saq.getSetVirtualAddressMapCallBackArray();
1953 String[] exitBoots = saq.getExitBootServicesCallBackArray();
1954 //
1955 // Add c code in autogen.c which relate to <SetVirtualAddressMapCallBack>
1956 // and <ExitBootServicesCallBack>
1957 //
1958 switch (CommonDefinition.getModuleType(moduleType)) {
1959 case CommonDefinition.ModuleTypeDxeDriver:
1960 case CommonDefinition.ModuleTypeDxeRuntimeDriver:
1961 case CommonDefinition.ModuleTypeDxeSalDriver:
1962 case CommonDefinition.ModuleTypeUefiDriver:
1963 case CommonDefinition.ModuleTypeUefiApplication:
1964 //
1965 // Write SetVirtualAddressMap function definition.
1966 //
1967 for (int i = 0; setVirtuals != null && i < setVirtuals.length; i++) {
1968 if (setVirtuals[i].equalsIgnoreCase("")) {
1969 continue;
1970 }
1971 functionDeclarations.append("VOID\r\n");
1972 functionDeclarations.append("EFIAPI\r\n");
1973 functionDeclarations.append(setVirtuals[i]);
1974 functionDeclarations.append(" (\r\n");
1975 functionDeclarations.append(" IN EFI_EVENT Event,\r\n");
1976 functionDeclarations.append(" IN VOID *Context\r\n");
1977 functionDeclarations.append(" );\r\n\r\n");
1978 }
1979
1980 //
1981 // Write DriverExitBootServices function definition.
1982 //
1983 for (int i = 0; exitBoots != null && i < exitBoots.length; i++) {
1984 if (exitBoots[i].equalsIgnoreCase("")) {
1985 continue;
1986 }
1987
1988 functionDeclarations.append("VOID\r\n");
1989 functionDeclarations.append("EFIAPI\r\n");
1990 functionDeclarations.append(exitBoots[i]);
1991 functionDeclarations.append(" (\r\n");
1992 functionDeclarations.append(" IN EFI_EVENT Event,\r\n");
1993 functionDeclarations.append(" IN VOID *Context\r\n");
1994 functionDeclarations.append(" );\r\n\r\n");
1995 }
1996 break;
1997 default:
1998 break;
1999 }
2000 }
2001
2002 /**
2003 ExternCallBackToAutoGenC
2004
2005 This function adds <SetVirtualAddressMapCallBack> and
2006 <ExitBootServicesCallBack> infomation to AutoGen.c
2007
2008 @param fileBuffer
2009 String buffer for AutoGen.c
2010 @throws BuildException
2011 **/
2012 void ExternCallBackToAutoGenC(StringBuffer fileBuffer)
2013 throws EdkException {
2014 //
2015 // Collect module's <SetVirtualAddressMapCallBack> and
2016 // <ExitBootServiceCallBack> and add to setVirtualAddList
2017 // exitBootServiceList.
2018 //
2019 String[] setVirtuals = saq.getSetVirtualAddressMapCallBackArray();
2020 String[] exitBoots = saq.getExitBootServicesCallBackArray();
2021 if (setVirtuals != null) {
2022 for (int j = 0; j < setVirtuals.length; j++) {
2023 this.setVirtalAddList.add(setVirtuals[j]);
2024 }
2025 }
2026 if (exitBoots != null) {
2027 for (int k = 0; k < exitBoots.length; k++) {
2028 this.exitBootServiceList.add(exitBoots[k]);
2029 }
2030 }
2031 //
2032 // Add c code in autogen.c which relate to <SetVirtualAddressMapCallBack>
2033 // and <ExitBootServicesCallBack>
2034 //
2035 String moduleType = this.moduleId.getModuleType();
2036 switch (CommonDefinition.getModuleType(moduleType)) {
2037 case CommonDefinition.ModuleTypeDxeDriver:
2038 case CommonDefinition.ModuleTypeDxeRuntimeDriver:
2039 case CommonDefinition.ModuleTypeDxeSalDriver:
2040 case CommonDefinition.ModuleTypeUefiDriver:
2041 case CommonDefinition.ModuleTypeUefiApplication:
2042 //
2043 // If moduleType is one of above, call setVirtualAddressToAutogenC,
2044 // and setExitBootServiceToAutogenC.
2045 //
2046 setVirtualAddressToAutogenC(fileBuffer);
2047 setExitBootServiceToAutogenC(fileBuffer);
2048 break;
2049 default:
2050 break;
2051 }
2052 }
2053
2054 /**
2055 copyFlashMapHToDebugDir
2056
2057 This function is to copy the falshmap.h to debug directory and change
2058 its name to TianoR8FlashMap.h
2059
2060 @param
2061 @return
2062 **/
2063 private void copyFlashMapHToDebugDir() throws AutoGenException{
2064
2065 File inFile = new File(fvDir + File.separatorChar + CommonDefinition.FLASHMAPH);
2066 int size = (int)inFile.length();
2067 byte[] buffer = new byte[size];
2068 File outFile = new File (this.outputPath + File.separatorChar + CommonDefinition.TIANOR8PLASHMAPH);
2069 //
2070 // If TianoR8FlashMap.h existed and the flashMap.h don't change,
2071 // do nothing.
2072 //
2073 if ((!outFile.exists()) ||(inFile.lastModified() - outFile.lastModified()) >= 0) {
2074 if (inFile.exists()) {
2075 try {
2076 FileInputStream fis = new FileInputStream (inFile);
2077 fis.read(buffer);
2078 FileOutputStream fos = new FileOutputStream(outFile);
2079 fos.write(buffer);
2080 fis.close();
2081 fos.close();
2082 } catch (IOException e) {
2083 throw new AutoGenException("The file, flashMap.h can't be open!");
2084 }
2085
2086 } else {
2087 throw new AutoGenException("The file, flashMap.h doesn't exist!");
2088 }
2089 }
2090 }
2091
2092 /**
2093 This function first order the library instances, then collect
2094 library instance 's PPI, Protocol, GUID,
2095 SetVirtalAddressMapCallBack, ExitBootServiceCallBack, and
2096 Destructor, Constructor.
2097
2098 @param
2099 @return
2100 **/
2101 private void collectLibInstanceInfo() throws EdkException{
2102 int index;
2103
2104 String moduleType = moduleId.getModuleType();
2105 String libConstructName = null;
2106 String libDestructName = null;
2107 String libModuleType = null;
2108 String[] setVirtuals = null;
2109 String[] exitBoots = null;
2110
2111 ModuleIdentification[] libraryIdList = saq.getLibraryInstance(this.arch);
2112 if (libraryIdList.length <= 0) {
2113 return;
2114 }
2115 //
2116 // Reorder library instance sequence.
2117 //
2118 AutogenLibOrder libOrder = new AutogenLibOrder(libraryIdList, this.arch);
2119 List<ModuleIdentification> orderList = libOrder.orderLibInstance();
2120 //
2121 // Process library instance one by one.
2122 //
2123 for (int i = 0; i < orderList.size(); i++) {
2124 //
2125 // Get library instance basename.
2126 //
2127 ModuleIdentification libInstanceId = orderList.get(i);
2128
2129 //
2130 // Get override map
2131 //
2132
2133 Map<String, XmlObject> libDoc = GlobalData.getDoc(libInstanceId, this.arch);
2134 saq.push(libDoc);
2135 //
2136 // check if the library instance support current module
2137 //
2138 String[] libraryClassList = saq.getLibraryClasses(CommonDefinition.ALWAYSPRODUCED,
2139 this.arch,
2140 moduleType
2141 );
2142 if (libraryClassList.length <= 0) {
2143 throw new EdkException("Library instance " + libInstanceId.getName()
2144 + " doesn't support module type " + moduleType);
2145 }
2146 //
2147 // Get <PPis>, <Protocols>, <Guids> list of this library
2148 // instance.
2149 //
2150 String[] ppiList = saq.getPpiArray(this.arch);
2151 String[] ppiNotifyList = saq.getPpiNotifyArray(this.arch);
2152 String[] protocolList = saq.getProtocolArray(this.arch);
2153 String[] protocolNotifyList = saq.getProtocolNotifyArray(this.arch);
2154 String[] guidList = saq.getGuidEntryArray(this.arch);
2155 PackageIdentification[] pkgList = saq.getDependencePkg(this.arch);
2156
2157 //
2158 // Add those ppi, protocol, guid in global ppi,
2159 // protocol, guid
2160 // list.
2161 //
2162 for (index = 0; index < ppiList.length; index++) {
2163 this.mPpiList.add(ppiList[index]);
2164 }
2165
2166 for (index = 0; index < ppiNotifyList.length; index++) {
2167 this.mPpiList.add(ppiNotifyList[index]);
2168 }
2169
2170 for (index = 0; index < protocolList.length; index++) {
2171 this.mProtocolList.add(protocolList[index]);
2172 }
2173
2174 for (index = 0; index < protocolNotifyList.length; index++) {
2175 this.mProtocolList.add(protocolNotifyList[index]);
2176 }
2177
2178 for (index = 0; index < guidList.length; index++) {
2179 this.mGuidList.add(guidList[index]);
2180 }
2181 for (index = 0; index < pkgList.length; index++) {
2182 if (!this.mDepPkgList.contains(pkgList[index])) {
2183 this.mDepPkgList.add(pkgList[index]);
2184 }
2185 }
2186
2187 //
2188 // If not yet parse this library instance's constructor
2189 // element,parse it.
2190 //
2191 libConstructName = saq.getLibConstructorName();
2192 libDestructName = saq.getLibDestructorName();
2193 libModuleType = saq.getModuleType();
2194
2195 //
2196 // Collect SetVirtualAddressMapCallBack and
2197 // ExitBootServiceCallBack.
2198 //
2199 setVirtuals = saq.getSetVirtualAddressMapCallBackArray();
2200 exitBoots = saq.getExitBootServicesCallBackArray();
2201 if (setVirtuals != null) {
2202 for (int j = 0; j < setVirtuals.length; j++) {
2203 this.setVirtalAddList.add(setVirtuals[j]);
2204 }
2205 }
2206 if (exitBoots != null) {
2207 for (int k = 0; k < exitBoots.length; k++) {
2208 this.exitBootServiceList.add(exitBoots[k]);
2209 }
2210 }
2211 saq.pop();
2212 //
2213 // Add dependent library instance constructor function.
2214 //
2215 if (libConstructName != null) {
2216 this.libConstructList.add(new String[] {libConstructName, libModuleType});
2217 }
2218 //
2219 // Add dependent library instance destructor fuction.
2220 //
2221 if (libDestructName != null) {
2222 this.libDestructList.add(new String[] {libDestructName, libModuleType});
2223 }
2224 }
2225 }
2226
2227 private void setVirtualAddressToAutogenC(StringBuffer fileBuffer){
2228 //
2229 // Entry point lib for these module types needs to know the count
2230 // of entryPoint.
2231 //
2232 fileBuffer.append("\r\nGLOBAL_REMOVE_IF_UNREFERENCED const UINTN _gDriverSetVirtualAddressMapEventCount = ");
2233
2234 //
2235 // If the list is not valid or has no entries set count to zero else
2236 // set count to the number of valid entries
2237 //
2238 int Count = 0;
2239 int i = 0;
2240 if (this.setVirtalAddList != null) {
2241 for (i = 0; i < this.setVirtalAddList.size(); i++) {
2242 if (this.setVirtalAddList.get(i).equalsIgnoreCase("")) {
2243 break;
2244 }
2245 }
2246 Count = i;
2247 }
2248
2249 fileBuffer.append(Integer.toString(Count));
2250 fileBuffer.append(";\r\n\r\n");
2251 if (this.setVirtalAddList == null || this.setVirtalAddList.size() == 0) {
2252 //
2253 // No data so make a NULL list
2254 //
2255 fileBuffer.append("\r\nGLOBAL_REMOVE_IF_UNREFERENCED const EFI_EVENT_NOTIFY _gDriverSetVirtualAddressMapEvent[] = {\r\n");
2256 fileBuffer.append(" NULL\r\n");
2257 fileBuffer.append("};\r\n\r\n");
2258 } else {
2259 //
2260 // Write SetVirtualAddressMap function definition.
2261 //
2262 for (i = 0; i < this.setVirtalAddList.size(); i++) {
2263 if (this.setVirtalAddList.get(i).equalsIgnoreCase("")) {
2264 break;
2265 }
2266 functionDeclarations.append("VOID\r\n");
2267 functionDeclarations.append("EFIAPI\r\n");
2268 functionDeclarations.append(this.setVirtalAddList.get(i));
2269 functionDeclarations.append(" (\r\n");
2270 functionDeclarations.append(" IN EFI_EVENT Event,\r\n");
2271 functionDeclarations.append(" IN VOID *Context\r\n");
2272 functionDeclarations.append(" );\r\n\r\n");
2273 }
2274
2275 //
2276 // Write SetVirtualAddressMap entry point array.
2277 //
2278 fileBuffer.append("\r\nGLOBAL_REMOVE_IF_UNREFERENCED const EFI_EVENT_NOTIFY _gDriverSetVirtualAddressMapEvent[] = {");
2279 for (i = 0; i < this.setVirtalAddList.size(); i++) {
2280 if (this.setVirtalAddList.get(i).equalsIgnoreCase("")) {
2281 break;
2282 }
2283
2284 if (i == 0) {
2285 fileBuffer.append("\r\n ");
2286 } else {
2287 fileBuffer.append(",\r\n ");
2288 }
2289
2290 fileBuffer.append(this.setVirtalAddList.get(i));
2291 }
2292 //
2293 // add the NULL at the end of _gDriverSetVirtualAddressMapEvent list.
2294 //
2295 fileBuffer.append(",\r\n NULL");
2296 fileBuffer.append("\r\n};\r\n\r\n");
2297 }
2298 }
2299
2300
2301 private void setExitBootServiceToAutogenC(StringBuffer fileBuffer){
2302 //
2303 // Entry point lib for these module types needs to know the count.
2304 //
2305 fileBuffer.append("\r\nGLOBAL_REMOVE_IF_UNREFERENCED const UINTN _gDriverExitBootServicesEventCount = ");
2306
2307 //
2308 // If the list is not valid or has no entries set count to zero else
2309 // set count to the number of valid entries.
2310 //
2311 int Count = 0;
2312 int i = 0;
2313 if (this.exitBootServiceList != null) {
2314 for (i = 0; i < this.exitBootServiceList.size(); i++) {
2315 if (this.exitBootServiceList.get(i).equalsIgnoreCase("")) {
2316 break;
2317 }
2318 }
2319 Count = i;
2320 }
2321 fileBuffer.append(Integer.toString(Count));
2322 fileBuffer.append(";\r\n\r\n");
2323
2324 if (this.exitBootServiceList == null || this.exitBootServiceList.size() == 0) {
2325 //
2326 // No data so make a NULL list.
2327 //
2328 fileBuffer.append("\r\nGLOBAL_REMOVE_IF_UNREFERENCED const EFI_EVENT_NOTIFY _gDriverExitBootServicesEvent[] = {\r\n");
2329 fileBuffer.append(" NULL\r\n");
2330 fileBuffer.append("};\r\n\r\n");
2331 } else {
2332 //
2333 // Write DriverExitBootServices function definition.
2334 //
2335 for (i = 0; i < this.exitBootServiceList.size(); i++) {
2336 if (this.exitBootServiceList.get(i).equalsIgnoreCase("")) {
2337 break;
2338 }
2339
2340 functionDeclarations.append("VOID\r\n");
2341 functionDeclarations.append("EFIAPI\r\n");
2342 functionDeclarations.append(this.exitBootServiceList.get(i));
2343 functionDeclarations.append(" (\r\n");
2344 functionDeclarations.append(" IN EFI_EVENT Event,\r\n");
2345 functionDeclarations.append(" IN VOID *Context\r\n");
2346 functionDeclarations.append(" );\r\n\r\n");
2347 }
2348
2349 //
2350 // Write DriverExitBootServices entry point array.
2351 //
2352 fileBuffer.append("\r\nGLOBAL_REMOVE_IF_UNREFERENCED const EFI_EVENT_NOTIFY _gDriverExitBootServicesEvent[] = {");
2353 for (i = 0; i < this.exitBootServiceList.size(); i++) {
2354 if (this.exitBootServiceList.get(i).equalsIgnoreCase("")) {
2355 break;
2356 }
2357
2358 if (i == 0) {
2359 fileBuffer.append("\r\n ");
2360 } else {
2361 fileBuffer.append(",\r\n ");
2362 }
2363 fileBuffer.append(this.exitBootServiceList.get(i));
2364 }
2365
2366 fileBuffer.append(",\r\n NULL");
2367 fileBuffer.append("\r\n};\r\n\r\n");
2368 }
2369 }
2370 /**
2371 setPcdComponentName
2372
2373 Get the Pcd Value of ComponentName to
2374 decide whether need to disable the componentName.
2375
2376 **/
2377 public void setPcdComponentName (){
2378 String pcdValue = null;
2379 pcdValue = saq.getPcdValueBycName("PcdComponentNameDisable");
2380 if (pcdValue != null && pcdValue.equalsIgnoreCase("true")) {
2381 this.componentNamePcd = true;
2382 }
2383 }
2384
2385 /**
2386 setPcdDriverDiagnostic
2387
2388 Get the Pcd Value of DriverDiagnostic to
2389 decide whether need to disable DriverDiagnostic.
2390
2391 **/
2392 public void setPcdDriverDiagnostic (){
2393 String pcdValue = null;
2394 pcdValue = saq.getPcdValueBycName("PcdDriverDiagnosticsDisable");
2395 if (pcdValue != null && pcdValue.equalsIgnoreCase("true")) {
2396 this.driverDiagnostPcd = true;
2397 }
2398 }
2399
2400 }