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