1## @file
2# Routines for generating AutoGen.h and AutoGen.c
3#
4# Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
5# SPDX-License-Identifier: BSD-2-Clause-Patent
6#
7
8## Import Modules
9#
10from __future__ import absolute_import
11import string
12import collections
13import struct
14from Common import EdkLogger
15from Common import GlobalData
16from Common.BuildToolError import *
17from Common.DataType import *
18from Common.Misc import *
19from Common.StringUtils import StringToArray
20from .StrGather import *
21from .GenPcdDb import CreatePcdDatabaseCode
22from .IdfClassObject import *
23
24## PCD type string
25gItemTypeStringDatabase  = {
26    TAB_PCDS_FEATURE_FLAG       :   TAB_PCDS_FIXED_AT_BUILD,
27    TAB_PCDS_FIXED_AT_BUILD     :   TAB_PCDS_FIXED_AT_BUILD,
28    TAB_PCDS_PATCHABLE_IN_MODULE:   'BinaryPatch',
29    TAB_PCDS_DYNAMIC            :   '',
30    TAB_PCDS_DYNAMIC_DEFAULT    :   '',
31    TAB_PCDS_DYNAMIC_VPD        :   '',
32    TAB_PCDS_DYNAMIC_HII        :   '',
33    TAB_PCDS_DYNAMIC_EX         :   '',
34    TAB_PCDS_DYNAMIC_EX_DEFAULT :   '',
35    TAB_PCDS_DYNAMIC_EX_VPD     :   '',
36    TAB_PCDS_DYNAMIC_EX_HII     :   '',
37}
38
39
40## Datum size
41gDatumSizeStringDatabase = {TAB_UINT8:'8',TAB_UINT16:'16',TAB_UINT32:'32',TAB_UINT64:'64','BOOLEAN':'BOOLEAN',TAB_VOID:'8'}
42gDatumSizeStringDatabaseH = {TAB_UINT8:'8',TAB_UINT16:'16',TAB_UINT32:'32',TAB_UINT64:'64','BOOLEAN':'BOOL',TAB_VOID:'PTR'}
43gDatumSizeStringDatabaseLib = {TAB_UINT8:'8',TAB_UINT16:'16',TAB_UINT32:'32',TAB_UINT64:'64','BOOLEAN':'Bool',TAB_VOID:'Ptr'}
44
45## AutoGen File Header Templates
46gAutoGenHeaderString = TemplateString("""\
47/**
48  DO NOT EDIT
49  FILE auto-generated
50  Module name:
51    ${FileName}
52  Abstract:       Auto-generated ${FileName} for building module or library.
53**/
54""")
55
56gAutoGenHPrologueString = TemplateString("""
57#ifndef _${File}_${Guid}
58#define _${File}_${Guid}
59
60""")
61
62gAutoGenHCppPrologueString = """\
63#ifdef __cplusplus
64extern "C" {
65#endif
66
67"""
68
69gAutoGenHEpilogueString = """
70
71#ifdef __cplusplus
72}
73#endif
74
75#endif
76"""
77
78## PEI Core Entry Point Templates
79gPeiCoreEntryPointPrototype = TemplateString("""
80${BEGIN}
81VOID
82EFIAPI
83${Function} (
84  IN CONST  EFI_SEC_PEI_HAND_OFF    *SecCoreData,
85  IN CONST  EFI_PEI_PPI_DESCRIPTOR  *PpiList,
86  IN VOID                           *Context
87  );
88${END}
89""")
90
91gPeiCoreEntryPointString = TemplateString("""
92${BEGIN}
93VOID
94EFIAPI
95ProcessModuleEntryPointList (
96  IN CONST  EFI_SEC_PEI_HAND_OFF    *SecCoreData,
97  IN CONST  EFI_PEI_PPI_DESCRIPTOR  *PpiList,
98  IN VOID                           *Context
99  )
100
101{
102  ${Function} (SecCoreData, PpiList, Context);
103}
104${END}
105""")
106
107
108## DXE Core Entry Point Templates
109gDxeCoreEntryPointPrototype = TemplateString("""
110${BEGIN}
111VOID
112EFIAPI
113${Function} (
114  IN VOID  *HobStart
115  );
116${END}
117""")
118
119gDxeCoreEntryPointString = TemplateString("""
120${BEGIN}
121VOID
122EFIAPI
123ProcessModuleEntryPointList (
124  IN VOID  *HobStart
125  )
126
127{
128  ${Function} (HobStart);
129}
130${END}
131""")
132
133## PEIM Entry Point Templates
134gPeimEntryPointPrototype = TemplateString("""
135${BEGIN}
136EFI_STATUS
137EFIAPI
138${Function} (
139  IN       EFI_PEI_FILE_HANDLE  FileHandle,
140  IN CONST EFI_PEI_SERVICES     **PeiServices
141  );
142${END}
143""")
144
145gPeimEntryPointString = [
146TemplateString("""
147GLOBAL_REMOVE_IF_UNREFERENCED const UINT32 _gPeimRevision = ${PiSpecVersion};
148
149EFI_STATUS
150EFIAPI
151ProcessModuleEntryPointList (
152  IN       EFI_PEI_FILE_HANDLE  FileHandle,
153  IN CONST EFI_PEI_SERVICES     **PeiServices
154  )
155
156{
157  return EFI_SUCCESS;
158}
159"""),
160TemplateString("""
161GLOBAL_REMOVE_IF_UNREFERENCED const UINT32 _gPeimRevision = ${PiSpecVersion};
162${BEGIN}
163EFI_STATUS
164EFIAPI
165ProcessModuleEntryPointList (
166  IN       EFI_PEI_FILE_HANDLE  FileHandle,
167  IN CONST EFI_PEI_SERVICES     **PeiServices
168  )
169
170{
171  return ${Function} (FileHandle, PeiServices);
172}
173${END}
174"""),
175TemplateString("""
176GLOBAL_REMOVE_IF_UNREFERENCED const UINT32 _gPeimRevision = ${PiSpecVersion};
177
178EFI_STATUS
179EFIAPI
180ProcessModuleEntryPointList (
181  IN       EFI_PEI_FILE_HANDLE  FileHandle,
182  IN CONST EFI_PEI_SERVICES     **PeiServices
183  )
184
185{
186  EFI_STATUS  Status;
187  EFI_STATUS  CombinedStatus;
188
189  CombinedStatus = EFI_LOAD_ERROR;
190${BEGIN}
191  Status = ${Function} (FileHandle, PeiServices);
192  if (!EFI_ERROR (Status) || EFI_ERROR (CombinedStatus)) {
193    CombinedStatus = Status;
194  }
195${END}
196  return CombinedStatus;
197}
198""")
199]
200
201## SMM_CORE Entry Point Templates
202gSmmCoreEntryPointPrototype = TemplateString("""
203${BEGIN}
204EFI_STATUS
205EFIAPI
206${Function} (
207  IN EFI_HANDLE         ImageHandle,
208  IN EFI_SYSTEM_TABLE   *SystemTable
209  );
210${END}
211""")
212
213gSmmCoreEntryPointString = TemplateString("""
214${BEGIN}
215const UINT32 _gUefiDriverRevision = ${UefiSpecVersion};
216const UINT32 _gDxeRevision = ${PiSpecVersion};
217
218EFI_STATUS
219EFIAPI
220ProcessModuleEntryPointList (
221  IN EFI_HANDLE         ImageHandle,
222  IN EFI_SYSTEM_TABLE   *SystemTable
223  )
224{
225  return ${Function} (ImageHandle, SystemTable);
226}
227${END}
228""")
229
230## MM_CORE_STANDALONE Entry Point Templates
231gMmCoreStandaloneEntryPointPrototype = TemplateString("""
232${BEGIN}
233EFI_STATUS
234EFIAPI
235${Function} (
236  IN VOID *HobStart
237  );
238${END}
239""")
240
241gMmCoreStandaloneEntryPointString = TemplateString("""
242${BEGIN}
243const UINT32 _gMmRevision = ${PiSpecVersion};
244
245VOID
246EFIAPI
247ProcessModuleEntryPointList (
248  IN VOID *HobStart
249  )
250{
251  ${Function} (HobStart);
252}
253${END}
254""")
255
256## MM_STANDALONE Entry Point Templates
257gMmStandaloneEntryPointPrototype = TemplateString("""
258${BEGIN}
259EFI_STATUS
260EFIAPI
261${Function} (
262  IN EFI_HANDLE            ImageHandle,
263  IN EFI_MM_SYSTEM_TABLE   *MmSystemTable
264  );
265${END}
266""")
267
268gMmStandaloneEntryPointString = [
269TemplateString("""
270GLOBAL_REMOVE_IF_UNREFERENCED const UINT32 _gMmRevision = ${PiSpecVersion};
271
272EFI_STATUS
273EFIAPI
274ProcessModuleEntryPointList (
275  IN EFI_HANDLE            ImageHandle,
276  IN EFI_MM_SYSTEM_TABLE   *MmSystemTable
277  )
278
279{
280  return EFI_SUCCESS;
281}
282"""),
283TemplateString("""
284GLOBAL_REMOVE_IF_UNREFERENCED const UINT32 _gMmRevision = ${PiSpecVersion};
285${BEGIN}
286EFI_STATUS
287EFIAPI
288ProcessModuleEntryPointList (
289  IN EFI_HANDLE            ImageHandle,
290  IN EFI_MM_SYSTEM_TABLE   *MmSystemTable
291  )
292
293{
294  return ${Function} (ImageHandle, MmSystemTable);
295}
296${END}
297"""),
298TemplateString("""
299GLOBAL_REMOVE_IF_UNREFERENCED const UINT32 _gMmRevision = ${PiSpecVersion};
300
301EFI_STATUS
302EFIAPI
303ProcessModuleEntryPointList (
304  IN EFI_HANDLE            ImageHandle,
305  IN EFI_MM_SYSTEM_TABLE   *MmSystemTable
306  )
307
308{
309  EFI_STATUS  Status;
310  EFI_STATUS  CombinedStatus;
311
312  CombinedStatus = EFI_LOAD_ERROR;
313${BEGIN}
314  Status = ${Function} (ImageHandle, MmSystemTable);
315  if (!EFI_ERROR (Status) || EFI_ERROR (CombinedStatus)) {
316    CombinedStatus = Status;
317  }
318${END}
319  return CombinedStatus;
320}
321""")
322]
323
324## DXE SMM Entry Point Templates
325gDxeSmmEntryPointPrototype = TemplateString("""
326${BEGIN}
327EFI_STATUS
328EFIAPI
329${Function} (
330  IN EFI_HANDLE        ImageHandle,
331  IN EFI_SYSTEM_TABLE  *SystemTable
332  );
333${END}
334""")
335
336gDxeSmmEntryPointString = [
337TemplateString("""
338const UINT32 _gUefiDriverRevision = ${UefiSpecVersion};
339const UINT32 _gDxeRevision = ${PiSpecVersion};
340
341EFI_STATUS
342EFIAPI
343ProcessModuleEntryPointList (
344  IN EFI_HANDLE        ImageHandle,
345  IN EFI_SYSTEM_TABLE  *SystemTable
346  )
347
348{
349  return EFI_SUCCESS;
350}
351"""),
352TemplateString("""
353const UINT32 _gUefiDriverRevision = ${UefiSpecVersion};
354const UINT32 _gDxeRevision = ${PiSpecVersion};
355
356static BASE_LIBRARY_JUMP_BUFFER  mJumpContext;
357static EFI_STATUS  mDriverEntryPointStatus;
358
359VOID
360EFIAPI
361ExitDriver (
362  IN EFI_STATUS  Status
363  )
364{
365  if (!EFI_ERROR (Status) || EFI_ERROR (mDriverEntryPointStatus)) {
366    mDriverEntryPointStatus = Status;
367  }
368  LongJump (&mJumpContext, (UINTN)-1);
369  ASSERT (FALSE);
370}
371
372EFI_STATUS
373EFIAPI
374ProcessModuleEntryPointList (
375  IN EFI_HANDLE        ImageHandle,
376  IN EFI_SYSTEM_TABLE  *SystemTable
377  )
378{
379  mDriverEntryPointStatus = EFI_LOAD_ERROR;
380
381${BEGIN}
382  if (SetJump (&mJumpContext) == 0) {
383    ExitDriver (${Function} (ImageHandle, SystemTable));
384    ASSERT (FALSE);
385  }
386${END}
387
388  return mDriverEntryPointStatus;
389}
390""")
391]
392
393## UEFI Driver Entry Point Templates
394gUefiDriverEntryPointPrototype = TemplateString("""
395${BEGIN}
396EFI_STATUS
397EFIAPI
398${Function} (
399  IN EFI_HANDLE        ImageHandle,
400  IN EFI_SYSTEM_TABLE  *SystemTable
401  );
402${END}
403""")
404
405gUefiDriverEntryPointString = [
406TemplateString("""
407const UINT32 _gUefiDriverRevision = ${UefiSpecVersion};
408const UINT32 _gDxeRevision = ${PiSpecVersion};
409
410EFI_STATUS
411EFIAPI
412ProcessModuleEntryPointList (
413  IN EFI_HANDLE        ImageHandle,
414  IN EFI_SYSTEM_TABLE  *SystemTable
415  )
416{
417  return EFI_SUCCESS;
418}
419"""),
420TemplateString("""
421const UINT32 _gUefiDriverRevision = ${UefiSpecVersion};
422const UINT32 _gDxeRevision = ${PiSpecVersion};
423
424${BEGIN}
425EFI_STATUS
426EFIAPI
427ProcessModuleEntryPointList (
428  IN EFI_HANDLE        ImageHandle,
429  IN EFI_SYSTEM_TABLE  *SystemTable
430  )
431
432{
433  return ${Function} (ImageHandle, SystemTable);
434}
435${END}
436VOID
437EFIAPI
438ExitDriver (
439  IN EFI_STATUS  Status
440  )
441{
442  if (EFI_ERROR (Status)) {
443    ProcessLibraryDestructorList (gImageHandle, gST);
444  }
445  gBS->Exit (gImageHandle, Status, 0, NULL);
446}
447"""),
448TemplateString("""
449const UINT32 _gUefiDriverRevision = ${UefiSpecVersion};
450const UINT32 _gDxeRevision = ${PiSpecVersion};
451
452static BASE_LIBRARY_JUMP_BUFFER  mJumpContext;
453static EFI_STATUS  mDriverEntryPointStatus;
454
455EFI_STATUS
456EFIAPI
457ProcessModuleEntryPointList (
458  IN EFI_HANDLE        ImageHandle,
459  IN EFI_SYSTEM_TABLE  *SystemTable
460  )
461{
462  mDriverEntryPointStatus = EFI_LOAD_ERROR;
463  ${BEGIN}
464  if (SetJump (&mJumpContext) == 0) {
465    ExitDriver (${Function} (ImageHandle, SystemTable));
466    ASSERT (FALSE);
467  }
468  ${END}
469  return mDriverEntryPointStatus;
470}
471
472VOID
473EFIAPI
474ExitDriver (
475  IN EFI_STATUS  Status
476  )
477{
478  if (!EFI_ERROR (Status) || EFI_ERROR (mDriverEntryPointStatus)) {
479    mDriverEntryPointStatus = Status;
480  }
481  LongJump (&mJumpContext, (UINTN)-1);
482  ASSERT (FALSE);
483}
484""")
485]
486
487
488## UEFI Application Entry Point Templates
489gUefiApplicationEntryPointPrototype = TemplateString("""
490${BEGIN}
491EFI_STATUS
492EFIAPI
493${Function} (
494  IN EFI_HANDLE        ImageHandle,
495  IN EFI_SYSTEM_TABLE  *SystemTable
496  );
497${END}
498""")
499
500gUefiApplicationEntryPointString = [
501TemplateString("""
502const UINT32 _gUefiDriverRevision = ${UefiSpecVersion};
503
504EFI_STATUS
505EFIAPI
506ProcessModuleEntryPointList (
507  IN EFI_HANDLE        ImageHandle,
508  IN EFI_SYSTEM_TABLE  *SystemTable
509  )
510{
511  return EFI_SUCCESS;
512}
513"""),
514TemplateString("""
515const UINT32 _gUefiDriverRevision = ${UefiSpecVersion};
516
517${BEGIN}
518EFI_STATUS
519EFIAPI
520ProcessModuleEntryPointList (
521  IN EFI_HANDLE        ImageHandle,
522  IN EFI_SYSTEM_TABLE  *SystemTable
523  )
524
525{
526  return ${Function} (ImageHandle, SystemTable);
527}
528${END}
529VOID
530EFIAPI
531ExitDriver (
532  IN EFI_STATUS  Status
533  )
534{
535  if (EFI_ERROR (Status)) {
536    ProcessLibraryDestructorList (gImageHandle, gST);
537  }
538  gBS->Exit (gImageHandle, Status, 0, NULL);
539}
540"""),
541TemplateString("""
542const UINT32 _gUefiDriverRevision = ${UefiSpecVersion};
543
544EFI_STATUS
545EFIAPI
546ProcessModuleEntryPointList (
547  IN EFI_HANDLE        ImageHandle,
548  IN EFI_SYSTEM_TABLE  *SystemTable
549  )
550
551{
552  ${BEGIN}
553  if (SetJump (&mJumpContext) == 0) {
554    ExitDriver (${Function} (ImageHandle, SystemTable));
555    ASSERT (FALSE);
556  }
557  ${END}
558  return mDriverEntryPointStatus;
559}
560
561static BASE_LIBRARY_JUMP_BUFFER  mJumpContext;
562static EFI_STATUS  mDriverEntryPointStatus = EFI_LOAD_ERROR;
563
564VOID
565EFIAPI
566ExitDriver (
567  IN EFI_STATUS  Status
568  )
569{
570  if (!EFI_ERROR (Status) || EFI_ERROR (mDriverEntryPointStatus)) {
571    mDriverEntryPointStatus = Status;
572  }
573  LongJump (&mJumpContext, (UINTN)-1);
574  ASSERT (FALSE);
575}
576""")
577]
578
579## UEFI Unload Image Templates
580gUefiUnloadImagePrototype = TemplateString("""
581${BEGIN}
582EFI_STATUS
583EFIAPI
584${Function} (
585  IN EFI_HANDLE        ImageHandle
586  );
587${END}
588""")
589
590gUefiUnloadImageString = [
591TemplateString("""
592GLOBAL_REMOVE_IF_UNREFERENCED const UINT8 _gDriverUnloadImageCount = ${Count};
593
594EFI_STATUS
595EFIAPI
596ProcessModuleUnloadList (
597  IN EFI_HANDLE        ImageHandle
598  )
599{
600  return EFI_SUCCESS;
601}
602"""),
603TemplateString("""
604GLOBAL_REMOVE_IF_UNREFERENCED const UINT8 _gDriverUnloadImageCount = ${Count};
605
606${BEGIN}
607EFI_STATUS
608EFIAPI
609ProcessModuleUnloadList (
610  IN EFI_HANDLE        ImageHandle
611  )
612{
613  return ${Function} (ImageHandle);
614}
615${END}
616"""),
617TemplateString("""
618GLOBAL_REMOVE_IF_UNREFERENCED const UINT8 _gDriverUnloadImageCount = ${Count};
619
620EFI_STATUS
621EFIAPI
622ProcessModuleUnloadList (
623  IN EFI_HANDLE        ImageHandle
624  )
625{
626  EFI_STATUS  Status;
627
628  Status = EFI_SUCCESS;
629${BEGIN}
630  if (EFI_ERROR (Status)) {
631    ${Function} (ImageHandle);
632  } else {
633    Status = ${Function} (ImageHandle);
634  }
635${END}
636  return Status;
637}
638""")
639]
640
641gLibraryStructorPrototype = {
642SUP_MODULE_BASE  : TemplateString("""${BEGIN}
643RETURN_STATUS
644EFIAPI
645${Function} (
646  VOID
647  );${END}
648"""),
649
650'PEI'   : TemplateString("""${BEGIN}
651EFI_STATUS
652EFIAPI
653${Function} (
654  IN       EFI_PEI_FILE_HANDLE       FileHandle,
655  IN CONST EFI_PEI_SERVICES          **PeiServices
656  );${END}
657"""),
658
659'DXE'   : TemplateString("""${BEGIN}
660EFI_STATUS
661EFIAPI
662${Function} (
663  IN EFI_HANDLE        ImageHandle,
664  IN EFI_SYSTEM_TABLE  *SystemTable
665  );${END}
666"""),
667
668'MM'   : TemplateString("""${BEGIN}
669EFI_STATUS
670EFIAPI
671${Function} (
672  IN EFI_HANDLE            ImageHandle,
673  IN EFI_MM_SYSTEM_TABLE   *MmSystemTable
674  );${END}
675"""),
676}
677
678gLibraryStructorCall = {
679SUP_MODULE_BASE  : TemplateString("""${BEGIN}
680  Status = ${Function} ();
681  ASSERT_RETURN_ERROR (Status);${END}
682"""),
683
684'PEI'   : TemplateString("""${BEGIN}
685  Status = ${Function} (FileHandle, PeiServices);
686  ASSERT_EFI_ERROR (Status);${END}
687"""),
688
689'DXE'   : TemplateString("""${BEGIN}
690  Status = ${Function} (ImageHandle, SystemTable);
691  ASSERT_EFI_ERROR (Status);${END}
692"""),
693
694'MM'   : TemplateString("""${BEGIN}
695  Status = ${Function} (ImageHandle, MmSystemTable);
696  ASSERT_EFI_ERROR (Status);${END}
697"""),
698}
699
700## Library Constructor and Destructor Templates
701gLibraryString = {
702SUP_MODULE_BASE  :   TemplateString("""
703${BEGIN}${FunctionPrototype}${END}
704
705VOID
706EFIAPI
707ProcessLibrary${Type}List (
708  VOID
709  )
710{
711${BEGIN}  RETURN_STATUS  Status;
712${FunctionCall}${END}
713}
714"""),
715
716'PEI'   :   TemplateString("""
717${BEGIN}${FunctionPrototype}${END}
718
719VOID
720EFIAPI
721ProcessLibrary${Type}List (
722  IN       EFI_PEI_FILE_HANDLE       FileHandle,
723  IN CONST EFI_PEI_SERVICES          **PeiServices
724  )
725{
726${BEGIN}  EFI_STATUS  Status;
727${FunctionCall}${END}
728}
729"""),
730
731'DXE'   :   TemplateString("""
732${BEGIN}${FunctionPrototype}${END}
733
734VOID
735EFIAPI
736ProcessLibrary${Type}List (
737  IN EFI_HANDLE        ImageHandle,
738  IN EFI_SYSTEM_TABLE  *SystemTable
739  )
740{
741${BEGIN}  EFI_STATUS  Status;
742${FunctionCall}${END}
743}
744"""),
745
746'MM'   :   TemplateString("""
747${BEGIN}${FunctionPrototype}${END}
748
749VOID
750EFIAPI
751ProcessLibrary${Type}List (
752  IN EFI_HANDLE            ImageHandle,
753  IN EFI_MM_SYSTEM_TABLE   *MmSystemTable
754  )
755{
756${BEGIN}  EFI_STATUS  Status;
757${FunctionCall}${END}
758}
759"""),
760}
761
762gBasicHeaderFile = "Base.h"
763
764gModuleTypeHeaderFile = {
765    SUP_MODULE_BASE              :   [gBasicHeaderFile, "Library/DebugLib.h"],
766    SUP_MODULE_SEC               :   ["PiPei.h", "Library/DebugLib.h"],
767    SUP_MODULE_PEI_CORE          :   ["PiPei.h", "Library/DebugLib.h", "Library/PeiCoreEntryPoint.h"],
768    SUP_MODULE_PEIM              :   ["PiPei.h", "Library/DebugLib.h", "Library/PeimEntryPoint.h"],
769    SUP_MODULE_DXE_CORE          :   ["PiDxe.h", "Library/DebugLib.h", "Library/DxeCoreEntryPoint.h"],
770    SUP_MODULE_DXE_DRIVER        :   ["PiDxe.h", "Library/BaseLib.h", "Library/DebugLib.h", "Library/UefiBootServicesTableLib.h", "Library/UefiDriverEntryPoint.h"],
771    SUP_MODULE_DXE_SMM_DRIVER    :   ["PiDxe.h", "Library/BaseLib.h", "Library/DebugLib.h", "Library/UefiBootServicesTableLib.h", "Library/UefiDriverEntryPoint.h"],
772    SUP_MODULE_DXE_RUNTIME_DRIVER:   ["PiDxe.h", "Library/BaseLib.h", "Library/DebugLib.h", "Library/UefiBootServicesTableLib.h", "Library/UefiDriverEntryPoint.h"],
773    SUP_MODULE_DXE_SAL_DRIVER    :   ["PiDxe.h", "Library/BaseLib.h", "Library/DebugLib.h", "Library/UefiBootServicesTableLib.h", "Library/UefiDriverEntryPoint.h"],
774    SUP_MODULE_UEFI_DRIVER       :   ["Uefi.h",  "Library/BaseLib.h", "Library/DebugLib.h", "Library/UefiBootServicesTableLib.h", "Library/UefiDriverEntryPoint.h"],
775    SUP_MODULE_UEFI_APPLICATION  :   ["Uefi.h",  "Library/BaseLib.h", "Library/DebugLib.h", "Library/UefiBootServicesTableLib.h", "Library/UefiApplicationEntryPoint.h"],
776    SUP_MODULE_SMM_CORE          :   ["PiDxe.h", "Library/BaseLib.h", "Library/DebugLib.h", "Library/UefiDriverEntryPoint.h"],
777    SUP_MODULE_MM_STANDALONE     :   ["PiMm.h", "Library/BaseLib.h", "Library/DebugLib.h", "Library/StandaloneMmDriverEntryPoint.h"],
778    SUP_MODULE_MM_CORE_STANDALONE :  ["PiMm.h", "Library/BaseLib.h", "Library/DebugLib.h", "Library/StandaloneMmCoreEntryPoint.h"],
779    SUP_MODULE_USER_DEFINED      :   [gBasicHeaderFile, "Library/DebugLib.h"]
780}
781
782## Autogen internal worker macro to define DynamicEx PCD name includes both the TokenSpaceGuidName
783#  the TokenName and Guid comparison to avoid define name collisions.
784#
785#   @param      Info        The ModuleAutoGen object
786#   @param      AutoGenH    The TemplateString object for header file
787#
788#
789def DynExPcdTokenNumberMapping(Info, AutoGenH):
790    ExTokenCNameList = []
791    PcdExList        = []
792    # Even it is the Library, the PCD is saved in the ModulePcdList
793    PcdList = Info.ModulePcdList
794    for Pcd in PcdList:
795        if Pcd.Type in PCD_DYNAMIC_EX_TYPE_SET:
796            ExTokenCNameList.append(Pcd.TokenCName)
797            PcdExList.append(Pcd)
798    if len(ExTokenCNameList) == 0:
799        return
800    AutoGenH.Append('\n#define COMPAREGUID(Guid1, Guid2) (BOOLEAN)(*(CONST UINT64*)Guid1 == *(CONST UINT64*)Guid2 && *((CONST UINT64*)Guid1 + 1) == *((CONST UINT64*)Guid2 + 1))\n')
801    # AutoGen for each PCD listed in a [PcdEx] section of a Module/Lib INF file.
802    # Auto generate a macro for each TokenName that takes a Guid pointer as a parameter.
803    # Use the Guid pointer to see if it matches any of the token space GUIDs.
804    TokenCNameList = set()
805    for TokenCName in ExTokenCNameList:
806        if TokenCName in TokenCNameList:
807            continue
808        Index = 0
809        Count = ExTokenCNameList.count(TokenCName)
810        for Pcd in PcdExList:
811            RealTokenCName = Pcd.TokenCName
812            for PcdItem in GlobalData.MixedPcd:
813                if (Pcd.TokenCName, Pcd.TokenSpaceGuidCName) in GlobalData.MixedPcd[PcdItem]:
814                    RealTokenCName = PcdItem[0]
815                    break
816            if Pcd.TokenCName == TokenCName:
817                Index = Index + 1
818                if Index == 1:
819                    AutoGenH.Append('\n#define __PCD_%s_ADDR_CMP(GuidPtr)  (' % (RealTokenCName))
820                    AutoGenH.Append('\\\n  (GuidPtr == &%s) ? _PCD_TOKEN_%s_%s:'
821                                    % (Pcd.TokenSpaceGuidCName, Pcd.TokenSpaceGuidCName, RealTokenCName))
822                else:
823                    AutoGenH.Append('\\\n  (GuidPtr == &%s) ? _PCD_TOKEN_%s_%s:'
824                                    % (Pcd.TokenSpaceGuidCName, Pcd.TokenSpaceGuidCName, RealTokenCName))
825                if Index == Count:
826                    AutoGenH.Append('0 \\\n  )\n')
827                TokenCNameList.add(TokenCName)
828
829    TokenCNameList = set()
830    for TokenCName in ExTokenCNameList:
831        if TokenCName in TokenCNameList:
832            continue
833        Index = 0
834        Count = ExTokenCNameList.count(TokenCName)
835        for Pcd in PcdExList:
836            RealTokenCName = Pcd.TokenCName
837            for PcdItem in GlobalData.MixedPcd:
838                if (Pcd.TokenCName, Pcd.TokenSpaceGuidCName) in GlobalData.MixedPcd[PcdItem]:
839                    RealTokenCName = PcdItem[0]
840                    break
841            if Pcd.Type in PCD_DYNAMIC_EX_TYPE_SET and Pcd.TokenCName == TokenCName:
842                Index = Index + 1
843                if Index == 1:
844                    AutoGenH.Append('\n#define __PCD_%s_VAL_CMP(GuidPtr)  (' % (RealTokenCName))
845                    AutoGenH.Append('\\\n  (GuidPtr == NULL) ? 0:')
846                    AutoGenH.Append('\\\n  COMPAREGUID (GuidPtr, &%s) ? _PCD_TOKEN_%s_%s:'
847                                    % (Pcd.TokenSpaceGuidCName, Pcd.TokenSpaceGuidCName, RealTokenCName))
848                else:
849                    AutoGenH.Append('\\\n  COMPAREGUID (GuidPtr, &%s) ? _PCD_TOKEN_%s_%s:'
850                                    % (Pcd.TokenSpaceGuidCName, Pcd.TokenSpaceGuidCName, RealTokenCName))
851                if Index == Count:
852                    AutoGenH.Append('0 \\\n  )\n')
853                    # Autogen internal worker macro to compare GUIDs.  Guid1 is a pointer to a GUID.
854                    # Guid2 is a C name for a GUID. Compare pointers first because optimizing compiler
855                    # can do this at build time on CONST GUID pointers and optimize away call to COMPAREGUID().
856                    #  COMPAREGUID() will only be used if the Guid passed in is local to the module.
857                    AutoGenH.Append('#define _PCD_TOKEN_EX_%s(GuidPtr)   __PCD_%s_ADDR_CMP(GuidPtr) ? __PCD_%s_ADDR_CMP(GuidPtr) : __PCD_%s_VAL_CMP(GuidPtr)  \n'
858                                    % (RealTokenCName, RealTokenCName, RealTokenCName, RealTokenCName))
859                TokenCNameList.add(TokenCName)
860
861## Create code for module PCDs
862#
863#   @param      Info        The ModuleAutoGen object
864#   @param      AutoGenC    The TemplateString object for C code
865#   @param      AutoGenH    The TemplateString object for header file
866#   @param      Pcd         The PCD object
867#
868def CreateModulePcdCode(Info, AutoGenC, AutoGenH, Pcd):
869    TokenSpaceGuidValue = Pcd.TokenSpaceGuidValue   #Info.GuidList[Pcd.TokenSpaceGuidCName]
870    PcdTokenNumber = Info.PlatformInfo.PcdTokenNumber
871    #
872    # Write PCDs
873    #
874    TokenCName = Pcd.TokenCName
875    for PcdItem in GlobalData.MixedPcd:
876        if (Pcd.TokenCName, Pcd.TokenSpaceGuidCName) in GlobalData.MixedPcd[PcdItem]:
877            TokenCName = PcdItem[0]
878            break
879    PcdTokenName = '_PCD_TOKEN_' + TokenCName
880    PatchPcdSizeTokenName = '_PCD_PATCHABLE_' + TokenCName +'_SIZE'
881    PatchPcdSizeVariableName = '_gPcd_BinaryPatch_Size_' + TokenCName
882    PatchPcdMaxSizeVariable = '_gPcd_BinaryPatch_MaxSize_' + TokenCName
883    FixPcdSizeTokenName = '_PCD_SIZE_' + TokenCName
884    FixedPcdSizeVariableName = '_gPcd_FixedAtBuild_Size_' + TokenCName
885
886    if Pcd.PcdValueFromComm:
887        Pcd.DefaultValue = Pcd.PcdValueFromComm
888    elif Pcd.PcdValueFromFdf:
889        Pcd.DefaultValue = Pcd.PcdValueFromFdf
890
891    if Pcd.Type in PCD_DYNAMIC_EX_TYPE_SET:
892        TokenNumber = int(Pcd.TokenValue, 0)
893        # Add TokenSpaceGuidValue value to PcdTokenName to discriminate the DynamicEx PCDs with
894        # different Guids but same TokenCName
895        PcdExTokenName = '_PCD_TOKEN_' + Pcd.TokenSpaceGuidCName + '_' + TokenCName
896        AutoGenH.Append('\n#define %s  %dU\n' % (PcdExTokenName, TokenNumber))
897    else:
898        if (Pcd.TokenCName, Pcd.TokenSpaceGuidCName) not in PcdTokenNumber:
899            # If one of the Source built modules listed in the DSC is not listed in FDF modules,
900            # and the INF lists a PCD can only use the PcdsDynamic access method (it is only
901            # listed in the DEC file that declares the PCD as PcdsDynamic), then build tool will
902            # report warning message notify the PI that they are attempting to build a module
903            # that must be included in a flash image in order to be functional. These Dynamic PCD
904            # will not be added into the Database unless it is used by other modules that are
905            # included in the FDF file.
906            # In this case, just assign an invalid token number to make it pass build.
907            if Pcd.Type in PCD_DYNAMIC_TYPE_SET:
908                TokenNumber = 0
909            else:
910                EdkLogger.error("build", AUTOGEN_ERROR,
911                                "No generated token number for %s.%s\n" % (Pcd.TokenSpaceGuidCName, TokenCName),
912                                ExtraData="[%s]" % str(Info))
913        else:
914            TokenNumber = PcdTokenNumber[Pcd.TokenCName, Pcd.TokenSpaceGuidCName]
915        AutoGenH.Append('\n#define %s  %dU\n' % (PcdTokenName, TokenNumber))
916
917    EdkLogger.debug(EdkLogger.DEBUG_3, "Creating code for " + TokenCName + "." + Pcd.TokenSpaceGuidCName)
918    if Pcd.Type not in gItemTypeStringDatabase:
919        EdkLogger.error("build", AUTOGEN_ERROR,
920                        "Unknown PCD type [%s] of PCD %s.%s" % (Pcd.Type, Pcd.TokenSpaceGuidCName, TokenCName),
921                        ExtraData="[%s]" % str(Info))
922
923    DatumSize = gDatumSizeStringDatabase[Pcd.DatumType] if Pcd.DatumType in gDatumSizeStringDatabase else gDatumSizeStringDatabase[TAB_VOID]
924    DatumSizeLib = gDatumSizeStringDatabaseLib[Pcd.DatumType] if Pcd.DatumType in gDatumSizeStringDatabaseLib else gDatumSizeStringDatabaseLib[TAB_VOID]
925    GetModeName = '_PCD_GET_MODE_' + gDatumSizeStringDatabaseH[Pcd.DatumType] + '_' + TokenCName if Pcd.DatumType in gDatumSizeStringDatabaseH else '_PCD_GET_MODE_' + gDatumSizeStringDatabaseH[TAB_VOID] + '_' + TokenCName
926    SetModeName = '_PCD_SET_MODE_' + gDatumSizeStringDatabaseH[Pcd.DatumType] + '_' + TokenCName if Pcd.DatumType in gDatumSizeStringDatabaseH else '_PCD_SET_MODE_' + gDatumSizeStringDatabaseH[TAB_VOID] + '_' + TokenCName
927    SetModeStatusName = '_PCD_SET_MODE_' + gDatumSizeStringDatabaseH[Pcd.DatumType] + '_S_' + TokenCName if Pcd.DatumType in gDatumSizeStringDatabaseH else '_PCD_SET_MODE_' + gDatumSizeStringDatabaseH[TAB_VOID] + '_S_' + TokenCName
928    GetModeSizeName = '_PCD_GET_MODE_SIZE' + '_' + TokenCName
929
930    if Pcd.Type in PCD_DYNAMIC_EX_TYPE_SET:
931        if Info.IsLibrary:
932            PcdList = Info.LibraryPcdList
933        else:
934            PcdList = Info.ModulePcdList + Info.LibraryPcdList
935        PcdExCNameTest = 0
936        for PcdModule in PcdList:
937            if PcdModule.Type in PCD_DYNAMIC_EX_TYPE_SET and Pcd.TokenCName == PcdModule.TokenCName:
938                PcdExCNameTest += 1
939            # get out early once we found > 1...
940            if PcdExCNameTest > 1:
941                break
942        # Be compatible with the current code which using PcdToken and PcdGet/Set for DynamicEx Pcd.
943        # If only PcdToken and PcdGet/Set used in all Pcds with different CName, it should succeed to build.
944        # If PcdToken and PcdGet/Set used in the Pcds with different Guids but same CName, it should failed to build.
945        if PcdExCNameTest > 1:
946            AutoGenH.Append('// Disabled the macros, as PcdToken and PcdGet/Set are not allowed in the case that more than one DynamicEx Pcds are different Guids but same CName.\n')
947            AutoGenH.Append('// #define %s  %s\n' % (PcdTokenName, PcdExTokenName))
948            AutoGenH.Append('// #define %s  LibPcdGetEx%s(&%s, %s)\n' % (GetModeName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))
949            AutoGenH.Append('// #define %s  LibPcdGetExSize(&%s, %s)\n' % (GetModeSizeName, Pcd.TokenSpaceGuidCName, PcdTokenName))
950            if Pcd.DatumType not in TAB_PCD_NUMERIC_TYPES:
951                AutoGenH.Append('// #define %s(SizeOfBuffer, Buffer)  LibPcdSetEx%s(&%s, %s, (SizeOfBuffer), (Buffer))\n' % (SetModeName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))
952                AutoGenH.Append('// #define %s(SizeOfBuffer, Buffer)  LibPcdSetEx%sS(&%s, %s, (SizeOfBuffer), (Buffer))\n' % (SetModeStatusName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))
953            else:
954                AutoGenH.Append('// #define %s(Value)  LibPcdSetEx%s(&%s, %s, (Value))\n' % (SetModeName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))
955                AutoGenH.Append('// #define %s(Value)  LibPcdSetEx%sS(&%s, %s, (Value))\n' % (SetModeStatusName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))
956        else:
957            AutoGenH.Append('#define %s  %s\n' % (PcdTokenName, PcdExTokenName))
958            AutoGenH.Append('#define %s  LibPcdGetEx%s(&%s, %s)\n' % (GetModeName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))
959            AutoGenH.Append('#define %s LibPcdGetExSize(&%s, %s)\n' % (GetModeSizeName, Pcd.TokenSpaceGuidCName, PcdTokenName))
960            if Pcd.DatumType not in TAB_PCD_NUMERIC_TYPES:
961                AutoGenH.Append('#define %s(SizeOfBuffer, Buffer)  LibPcdSetEx%s(&%s, %s, (SizeOfBuffer), (Buffer))\n' % (SetModeName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))
962                AutoGenH.Append('#define %s(SizeOfBuffer, Buffer)  LibPcdSetEx%sS(&%s, %s, (SizeOfBuffer), (Buffer))\n' % (SetModeStatusName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))
963            else:
964                AutoGenH.Append('#define %s(Value)  LibPcdSetEx%s(&%s, %s, (Value))\n' % (SetModeName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))
965                AutoGenH.Append('#define %s(Value)  LibPcdSetEx%sS(&%s, %s, (Value))\n' % (SetModeStatusName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))
966    elif Pcd.Type in PCD_DYNAMIC_TYPE_SET:
967        PcdCNameTest = 0
968        for PcdModule in Info.LibraryPcdList + Info.ModulePcdList:
969            if PcdModule.Type in PCD_DYNAMIC_TYPE_SET and Pcd.TokenCName == PcdModule.TokenCName:
970                PcdCNameTest += 1
971            # get out early once we found > 1...
972            if PcdCNameTest > 1:
973                break
974        if PcdCNameTest > 1:
975            EdkLogger.error("build", AUTOGEN_ERROR, "More than one Dynamic Pcds [%s] are different Guids but same CName. They need to be changed to DynamicEx type to avoid the confliction.\n" % (TokenCName), ExtraData="[%s]" % str(Info.MetaFile.Path))
976        else:
977            AutoGenH.Append('#define %s  LibPcdGet%s(%s)\n' % (GetModeName, DatumSizeLib, PcdTokenName))
978            AutoGenH.Append('#define %s  LibPcdGetSize(%s)\n' % (GetModeSizeName, PcdTokenName))
979            if Pcd.DatumType not in TAB_PCD_NUMERIC_TYPES:
980                AutoGenH.Append('#define %s(SizeOfBuffer, Buffer)  LibPcdSet%s(%s, (SizeOfBuffer), (Buffer))\n' %(SetModeName, DatumSizeLib, PcdTokenName))
981                AutoGenH.Append('#define %s(SizeOfBuffer, Buffer)  LibPcdSet%sS(%s, (SizeOfBuffer), (Buffer))\n' % (SetModeStatusName, DatumSizeLib, PcdTokenName))
982            else:
983                AutoGenH.Append('#define %s(Value)  LibPcdSet%s(%s, (Value))\n' % (SetModeName, DatumSizeLib, PcdTokenName))
984                AutoGenH.Append('#define %s(Value)  LibPcdSet%sS(%s, (Value))\n' % (SetModeStatusName, DatumSizeLib, PcdTokenName))
985    else:
986        PcdVariableName = '_gPcd_' + gItemTypeStringDatabase[Pcd.Type] + '_' + TokenCName
987        Const = 'const'
988        if Pcd.Type == TAB_PCDS_PATCHABLE_IN_MODULE:
989            Const = ''
990        Type = ''
991        Array = ''
992        Value = Pcd.DefaultValue
993        Unicode = False
994        ValueNumber = 0
995
996        if Pcd.DatumType == 'BOOLEAN':
997            BoolValue = Value.upper()
998            if BoolValue == 'TRUE' or BoolValue == '1':
999                Value = '1U'
1000            elif BoolValue == 'FALSE' or BoolValue == '0':
1001                Value = '0U'
1002
1003        if Pcd.DatumType in TAB_PCD_CLEAN_NUMERIC_TYPES:
1004            try:
1005                if Value.upper().endswith('L'):
1006                    Value = Value[:-1]
1007                if Value.startswith('0') and not Value.lower().startswith('0x') and len(Value) > 1 and Value.lstrip('0'):
1008                    Value = Value.lstrip('0')
1009                ValueNumber = int (Value, 0)
1010            except:
1011                EdkLogger.error("build", AUTOGEN_ERROR,
1012                                "PCD value is not valid dec or hex number for datum type [%s] of PCD %s.%s" % (Pcd.DatumType, Pcd.TokenSpaceGuidCName, TokenCName),
1013                                ExtraData="[%s]" % str(Info))
1014            if ValueNumber < 0:
1015                EdkLogger.error("build", AUTOGEN_ERROR,
1016                                "PCD can't be set to negative value for datum type [%s] of PCD %s.%s" % (Pcd.DatumType, Pcd.TokenSpaceGuidCName, TokenCName),
1017                                ExtraData="[%s]" % str(Info))
1018            elif ValueNumber > MAX_VAL_TYPE[Pcd.DatumType]:
1019                EdkLogger.error("build", AUTOGEN_ERROR,
1020                                "Too large PCD value for datum type [%s] of PCD %s.%s" % (Pcd.DatumType, Pcd.TokenSpaceGuidCName, TokenCName),
1021                                ExtraData="[%s]" % str(Info))
1022            if Pcd.DatumType == TAB_UINT64 and not Value.endswith('ULL'):
1023                Value += 'ULL'
1024            elif Pcd.DatumType != TAB_UINT64 and not Value.endswith('U'):
1025                Value += 'U'
1026
1027        if Pcd.DatumType not in TAB_PCD_NUMERIC_TYPES:
1028            if not Pcd.MaxDatumSize:
1029                EdkLogger.error("build", AUTOGEN_ERROR,
1030                                "Unknown [MaxDatumSize] of PCD [%s.%s]" % (Pcd.TokenSpaceGuidCName, TokenCName),
1031                                ExtraData="[%s]" % str(Info))
1032
1033            ArraySize = int(Pcd.MaxDatumSize, 0)
1034            if Value[0] == '{':
1035                Type = '(VOID *)'
1036                ValueSize = len(Value.split(','))
1037            else:
1038                if Value[0] == 'L':
1039                    Unicode = True
1040                Value = Value.lstrip('L')   #.strip('"')
1041                Value = eval(Value)         # translate escape character
1042                ValueSize = len(Value) + 1
1043                NewValue = '{'
1044                for Index in range(0, len(Value)):
1045                    if Unicode:
1046                        NewValue = NewValue + str(ord(Value[Index]) % 0x10000) + ', '
1047                    else:
1048                        NewValue = NewValue + str(ord(Value[Index]) % 0x100) + ', '
1049                if Unicode:
1050                    ArraySize = ArraySize // 2
1051                Value = NewValue + '0 }'
1052            if ArraySize < ValueSize:
1053                if Pcd.MaxSizeUserSet:
1054                    EdkLogger.error("build", AUTOGEN_ERROR,
1055                                "The maximum size of VOID* type PCD '%s.%s' is less than its actual size occupied." % (Pcd.TokenSpaceGuidCName, TokenCName),
1056                                ExtraData="[%s]" % str(Info))
1057                else:
1058                    ArraySize = Pcd.GetPcdSize()
1059                    if Unicode:
1060                        ArraySize = ArraySize // 2
1061            Array = '[%d]' % ArraySize
1062        #
1063        # skip casting for fixed at build since it breaks ARM assembly.
1064        # Long term we need PCD macros that work in assembly
1065        #
1066        elif Pcd.Type != TAB_PCDS_FIXED_AT_BUILD and Pcd.DatumType in TAB_PCD_NUMERIC_TYPES_VOID:
1067            Value = "((%s)%s)" % (Pcd.DatumType, Value)
1068
1069        if Pcd.Type == TAB_PCDS_PATCHABLE_IN_MODULE:
1070            PcdValueName = '_PCD_PATCHABLE_VALUE_' + TokenCName
1071        else:
1072            PcdValueName = '_PCD_VALUE_' + TokenCName
1073
1074        if Pcd.DatumType not in TAB_PCD_NUMERIC_TYPES:
1075            #
1076            # For unicode, UINT16 array will be generated, so the alignment of unicode is guaranteed.
1077            #
1078            AutoGenH.Append('#define %s  %s%s\n' %(PcdValueName, Type, PcdVariableName))
1079            if Unicode:
1080                AutoGenC.Append('GLOBAL_REMOVE_IF_UNREFERENCED %s UINT16 %s%s = %s;\n' % (Const, PcdVariableName, Array, Value))
1081                AutoGenH.Append('extern %s UINT16 %s%s;\n' %(Const, PcdVariableName, Array))
1082            else:
1083                AutoGenC.Append('GLOBAL_REMOVE_IF_UNREFERENCED %s UINT8 %s%s = %s;\n' % (Const, PcdVariableName, Array, Value))
1084                AutoGenH.Append('extern %s UINT8 %s%s;\n' %(Const, PcdVariableName, Array))
1085            AutoGenH.Append('#define %s  %s%s\n' %(GetModeName, Type, PcdVariableName))
1086
1087            PcdDataSize = Pcd.GetPcdSize()
1088            if Pcd.Type == TAB_PCDS_FIXED_AT_BUILD:
1089                AutoGenH.Append('#define %s %s\n' % (FixPcdSizeTokenName, PcdDataSize))
1090                AutoGenH.Append('#define %s  %s \n' % (GetModeSizeName, FixPcdSizeTokenName))
1091                AutoGenC.Append('GLOBAL_REMOVE_IF_UNREFERENCED const UINTN %s = %s;\n' % (FixedPcdSizeVariableName, PcdDataSize))
1092            if Pcd.Type == TAB_PCDS_PATCHABLE_IN_MODULE:
1093                AutoGenH.Append('#define %s %s\n' % (PatchPcdSizeTokenName, Pcd.MaxDatumSize))
1094                AutoGenH.Append('#define %s  %s \n' % (GetModeSizeName, PatchPcdSizeVariableName))
1095                AutoGenH.Append('extern UINTN %s; \n' % PatchPcdSizeVariableName)
1096                AutoGenC.Append('GLOBAL_REMOVE_IF_UNREFERENCED UINTN %s = %s;\n' % (PatchPcdSizeVariableName, PcdDataSize))
1097                AutoGenC.Append('GLOBAL_REMOVE_IF_UNREFERENCED const UINTN %s = %s;\n' % (PatchPcdMaxSizeVariable, Pcd.MaxDatumSize))
1098        elif Pcd.Type == TAB_PCDS_PATCHABLE_IN_MODULE:
1099            AutoGenH.Append('#define %s  %s\n' %(PcdValueName, Value))
1100            AutoGenC.Append('volatile %s %s %s = %s;\n' %(Const, Pcd.DatumType, PcdVariableName, PcdValueName))
1101            AutoGenH.Append('extern volatile %s  %s  %s%s;\n' % (Const, Pcd.DatumType, PcdVariableName, Array))
1102            AutoGenH.Append('#define %s  %s%s\n' % (GetModeName, Type, PcdVariableName))
1103
1104            PcdDataSize = Pcd.GetPcdSize()
1105            AutoGenH.Append('#define %s %s\n' % (PatchPcdSizeTokenName, PcdDataSize))
1106
1107            AutoGenH.Append('#define %s  %s \n' % (GetModeSizeName, PatchPcdSizeVariableName))
1108            AutoGenH.Append('extern UINTN %s; \n' % PatchPcdSizeVariableName)
1109            AutoGenC.Append('GLOBAL_REMOVE_IF_UNREFERENCED UINTN %s = %s;\n' % (PatchPcdSizeVariableName, PcdDataSize))
1110        else:
1111            PcdDataSize = Pcd.GetPcdSize()
1112            AutoGenH.Append('#define %s %s\n' % (FixPcdSizeTokenName, PcdDataSize))
1113            AutoGenH.Append('#define %s  %s \n' % (GetModeSizeName, FixPcdSizeTokenName))
1114
1115            AutoGenH.Append('#define %s  %s\n' %(PcdValueName, Value))
1116            AutoGenC.Append('GLOBAL_REMOVE_IF_UNREFERENCED %s %s %s = %s;\n' %(Const, Pcd.DatumType, PcdVariableName, PcdValueName))
1117            AutoGenH.Append('extern %s  %s  %s%s;\n' % (Const, Pcd.DatumType, PcdVariableName, Array))
1118            AutoGenH.Append('#define %s  %s%s\n' % (GetModeName, Type, PcdVariableName))
1119
1120        if Pcd.Type == TAB_PCDS_PATCHABLE_IN_MODULE:
1121            if Pcd.DatumType not in TAB_PCD_NUMERIC_TYPES:
1122                AutoGenH.Append('#define %s(SizeOfBuffer, Buffer)  LibPatchPcdSetPtrAndSize((VOID *)_gPcd_BinaryPatch_%s, &_gPcd_BinaryPatch_Size_%s, (UINTN)_PCD_PATCHABLE_%s_SIZE, (SizeOfBuffer), (Buffer))\n' % (SetModeName, Pcd.TokenCName, Pcd.TokenCName, Pcd.TokenCName))
1123                AutoGenH.Append('#define %s(SizeOfBuffer, Buffer)  LibPatchPcdSetPtrAndSizeS((VOID *)_gPcd_BinaryPatch_%s, &_gPcd_BinaryPatch_Size_%s, (UINTN)_PCD_PATCHABLE_%s_SIZE, (SizeOfBuffer), (Buffer))\n' % (SetModeStatusName, Pcd.TokenCName, Pcd.TokenCName, Pcd.TokenCName))
1124            else:
1125                AutoGenH.Append('#define %s(Value)  (%s = (Value))\n' % (SetModeName, PcdVariableName))
1126                AutoGenH.Append('#define %s(Value)  ((%s = (Value)), RETURN_SUCCESS) \n' % (SetModeStatusName, PcdVariableName))
1127        else:
1128            AutoGenH.Append('//#define %s  ASSERT(FALSE)  // It is not allowed to set value for a FIXED_AT_BUILD PCD\n' % SetModeName)
1129
1130## Create code for library module PCDs
1131#
1132#   @param      Info        The ModuleAutoGen object
1133#   @param      AutoGenC    The TemplateString object for C code
1134#   @param      AutoGenH    The TemplateString object for header file
1135#   @param      Pcd         The PCD object
1136#
1137def CreateLibraryPcdCode(Info, AutoGenC, AutoGenH, Pcd):
1138    PcdTokenNumber = Info.PlatformInfo.PcdTokenNumber
1139    TokenSpaceGuidCName = Pcd.TokenSpaceGuidCName
1140    TokenCName  = Pcd.TokenCName
1141    for PcdItem in GlobalData.MixedPcd:
1142        if (TokenCName, TokenSpaceGuidCName) in GlobalData.MixedPcd[PcdItem]:
1143            TokenCName = PcdItem[0]
1144            break
1145    PcdTokenName = '_PCD_TOKEN_' + TokenCName
1146    FixPcdSizeTokenName = '_PCD_SIZE_' + TokenCName
1147    PatchPcdSizeTokenName = '_PCD_PATCHABLE_' + TokenCName +'_SIZE'
1148    PatchPcdSizeVariableName = '_gPcd_BinaryPatch_Size_' + TokenCName
1149    PatchPcdMaxSizeVariable = '_gPcd_BinaryPatch_MaxSize_' + TokenCName
1150    FixedPcdSizeVariableName = '_gPcd_FixedAtBuild_Size_' + TokenCName
1151
1152    if Pcd.PcdValueFromComm:
1153        Pcd.DefaultValue = Pcd.PcdValueFromComm
1154    elif Pcd.PcdValueFromFdf:
1155        Pcd.DefaultValue = Pcd.PcdValueFromFdf
1156    #
1157    # Write PCDs
1158    #
1159    if Pcd.Type in PCD_DYNAMIC_EX_TYPE_SET:
1160        TokenNumber = int(Pcd.TokenValue, 0)
1161    else:
1162        if (Pcd.TokenCName, Pcd.TokenSpaceGuidCName) not in PcdTokenNumber:
1163            # If one of the Source built modules listed in the DSC is not listed in FDF modules,
1164            # and the INF lists a PCD can only use the PcdsDynamic access method (it is only
1165            # listed in the DEC file that declares the PCD as PcdsDynamic), then build tool will
1166            # report warning message notify the PI that they are attempting to build a module
1167            # that must be included in a flash image in order to be functional. These Dynamic PCD
1168            # will not be added into the Database unless it is used by other modules that are
1169            # included in the FDF file.
1170            # In this case, just assign an invalid token number to make it pass build.
1171            if Pcd.Type in PCD_DYNAMIC_TYPE_SET:
1172                TokenNumber = 0
1173            else:
1174                EdkLogger.error("build", AUTOGEN_ERROR,
1175                                "No generated token number for %s.%s\n" % (Pcd.TokenSpaceGuidCName, TokenCName),
1176                                ExtraData="[%s]" % str(Info))
1177        else:
1178            TokenNumber = PcdTokenNumber[Pcd.TokenCName, Pcd.TokenSpaceGuidCName]
1179
1180    if Pcd.Type not in gItemTypeStringDatabase:
1181        EdkLogger.error("build", AUTOGEN_ERROR,
1182                        "Unknown PCD type [%s] of PCD %s.%s" % (Pcd.Type, Pcd.TokenSpaceGuidCName, TokenCName),
1183                        ExtraData="[%s]" % str(Info))
1184
1185    DatumType   = Pcd.DatumType
1186    DatumSize = gDatumSizeStringDatabase[Pcd.DatumType] if Pcd.DatumType in gDatumSizeStringDatabase else gDatumSizeStringDatabase[TAB_VOID]
1187    DatumSizeLib = gDatumSizeStringDatabaseLib[Pcd.DatumType] if Pcd.DatumType in gDatumSizeStringDatabaseLib else gDatumSizeStringDatabaseLib[TAB_VOID]
1188    GetModeName = '_PCD_GET_MODE_' + gDatumSizeStringDatabaseH[Pcd.DatumType] + '_' + TokenCName if Pcd.DatumType in gDatumSizeStringDatabaseH else '_PCD_GET_MODE_' + gDatumSizeStringDatabaseH[TAB_VOID] + '_' + TokenCName
1189    SetModeName = '_PCD_SET_MODE_' + gDatumSizeStringDatabaseH[Pcd.DatumType] + '_' + TokenCName if Pcd.DatumType in gDatumSizeStringDatabaseH else '_PCD_SET_MODE_' + gDatumSizeStringDatabaseH[TAB_VOID] + '_' + TokenCName
1190    SetModeStatusName = '_PCD_SET_MODE_' + gDatumSizeStringDatabaseH[Pcd.DatumType] + '_S_' + TokenCName if Pcd.DatumType in gDatumSizeStringDatabaseH else '_PCD_SET_MODE_' + gDatumSizeStringDatabaseH[TAB_VOID] + '_S_' + TokenCName
1191    GetModeSizeName = '_PCD_GET_MODE_SIZE' + '_' + TokenCName
1192
1193    Type = ''
1194    Array = ''
1195    if Pcd.DatumType not in TAB_PCD_NUMERIC_TYPES:
1196        if Pcd.DefaultValue[0]== '{':
1197            Type = '(VOID *)'
1198        Array = '[]'
1199    PcdItemType = Pcd.Type
1200    if PcdItemType in PCD_DYNAMIC_EX_TYPE_SET:
1201        PcdExTokenName = '_PCD_TOKEN_' + TokenSpaceGuidCName + '_' + TokenCName
1202        AutoGenH.Append('\n#define %s  %dU\n' % (PcdExTokenName, TokenNumber))
1203
1204        if Info.IsLibrary:
1205            PcdList = Info.LibraryPcdList
1206        else:
1207            PcdList = Info.ModulePcdList
1208        PcdExCNameTest = 0
1209        for PcdModule in PcdList:
1210            if PcdModule.Type in PCD_DYNAMIC_EX_TYPE_SET and Pcd.TokenCName == PcdModule.TokenCName:
1211                PcdExCNameTest += 1
1212            # get out early once we found > 1...
1213            if PcdExCNameTest > 1:
1214                break
1215        # Be compatible with the current code which using PcdGet/Set for DynamicEx Pcd.
1216        # If only PcdGet/Set used in all Pcds with different CName, it should succeed to build.
1217        # If PcdGet/Set used in the Pcds with different Guids but same CName, it should failed to build.
1218        if PcdExCNameTest > 1:
1219            AutoGenH.Append('// Disabled the macros, as PcdToken and PcdGet/Set are not allowed in the case that more than one DynamicEx Pcds are different Guids but same CName.\n')
1220            AutoGenH.Append('// #define %s  %s\n' % (PcdTokenName, PcdExTokenName))
1221            AutoGenH.Append('// #define %s  LibPcdGetEx%s(&%s, %s)\n' % (GetModeName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))
1222            AutoGenH.Append('// #define %s  LibPcdGetExSize(&%s, %s)\n' % (GetModeSizeName, Pcd.TokenSpaceGuidCName, PcdTokenName))
1223            if Pcd.DatumType not in TAB_PCD_NUMERIC_TYPES:
1224                AutoGenH.Append('// #define %s(SizeOfBuffer, Buffer)  LibPcdSetEx%s(&%s, %s, (SizeOfBuffer), (Buffer))\n' % (SetModeName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))
1225                AutoGenH.Append('// #define %s(SizeOfBuffer, Buffer)  LibPcdSetEx%sS(&%s, %s, (SizeOfBuffer), (Buffer))\n' % (SetModeStatusName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))
1226            else:
1227                AutoGenH.Append('// #define %s(Value)  LibPcdSetEx%s(&%s, %s, (Value))\n' % (SetModeName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))
1228                AutoGenH.Append('// #define %s(Value)  LibPcdSetEx%sS(&%s, %s, (Value))\n' % (SetModeStatusName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))
1229        else:
1230            AutoGenH.Append('#define %s  %s\n' % (PcdTokenName, PcdExTokenName))
1231            AutoGenH.Append('#define %s  LibPcdGetEx%s(&%s, %s)\n' % (GetModeName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))
1232            AutoGenH.Append('#define %s LibPcdGetExSize(&%s, %s)\n' % (GetModeSizeName, Pcd.TokenSpaceGuidCName, PcdTokenName))
1233            if Pcd.DatumType not in TAB_PCD_NUMERIC_TYPES:
1234                AutoGenH.Append('#define %s(SizeOfBuffer, Buffer)  LibPcdSetEx%s(&%s, %s, (SizeOfBuffer), (Buffer))\n' % (SetModeName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))
1235                AutoGenH.Append('#define %s(SizeOfBuffer, Buffer)  LibPcdSetEx%sS(&%s, %s, (SizeOfBuffer), (Buffer))\n' % (SetModeStatusName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))
1236            else:
1237                AutoGenH.Append('#define %s(Value)  LibPcdSetEx%s(&%s, %s, (Value))\n' % (SetModeName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))
1238                AutoGenH.Append('#define %s(Value)  LibPcdSetEx%sS(&%s, %s, (Value))\n' % (SetModeStatusName, DatumSizeLib, Pcd.TokenSpaceGuidCName, PcdTokenName))
1239    else:
1240        AutoGenH.Append('#define _PCD_TOKEN_%s  %dU\n' % (TokenCName, TokenNumber))
1241    if PcdItemType in PCD_DYNAMIC_TYPE_SET:
1242        PcdList = []
1243        PcdCNameList = []
1244        PcdList.extend(Info.LibraryPcdList)
1245        PcdList.extend(Info.ModulePcdList)
1246        for PcdModule in PcdList:
1247            if PcdModule.Type in PCD_DYNAMIC_TYPE_SET:
1248                PcdCNameList.append(PcdModule.TokenCName)
1249        if PcdCNameList.count(Pcd.TokenCName) > 1:
1250            EdkLogger.error("build", AUTOGEN_ERROR, "More than one Dynamic Pcds [%s] are different Guids but same CName.They need to be changed to DynamicEx type to avoid the confliction.\n" % (TokenCName), ExtraData="[%s]" % str(Info.MetaFile.Path))
1251        else:
1252            AutoGenH.Append('#define %s  LibPcdGet%s(%s)\n' % (GetModeName, DatumSizeLib, PcdTokenName))
1253            AutoGenH.Append('#define %s  LibPcdGetSize(%s)\n' % (GetModeSizeName, PcdTokenName))
1254            if DatumType not in TAB_PCD_NUMERIC_TYPES:
1255                AutoGenH.Append('#define %s(SizeOfBuffer, Buffer)  LibPcdSet%s(%s, (SizeOfBuffer), (Buffer))\n' %(SetModeName, DatumSizeLib, PcdTokenName))
1256                AutoGenH.Append('#define %s(SizeOfBuffer, Buffer)  LibPcdSet%sS(%s, (SizeOfBuffer), (Buffer))\n' % (SetModeStatusName, DatumSizeLib, PcdTokenName))
1257            else:
1258                AutoGenH.Append('#define %s(Value)  LibPcdSet%s(%s, (Value))\n' % (SetModeName, DatumSizeLib, PcdTokenName))
1259                AutoGenH.Append('#define %s(Value)  LibPcdSet%sS(%s, (Value))\n' % (SetModeStatusName, DatumSizeLib, PcdTokenName))
1260    if PcdItemType == TAB_PCDS_PATCHABLE_IN_MODULE:
1261        PcdVariableName = '_gPcd_' + gItemTypeStringDatabase[TAB_PCDS_PATCHABLE_IN_MODULE] + '_' + TokenCName
1262        if DatumType not in TAB_PCD_NUMERIC_TYPES:
1263            if DatumType == TAB_VOID and Array == '[]':
1264                DatumType = [TAB_UINT8, TAB_UINT16][Pcd.DefaultValue[0] == 'L']
1265            else:
1266                DatumType = TAB_UINT8
1267            AutoGenH.Append('extern %s _gPcd_BinaryPatch_%s%s;\n' %(DatumType, TokenCName, Array))
1268        else:
1269            AutoGenH.Append('extern volatile  %s  %s%s;\n' % (DatumType, PcdVariableName, Array))
1270        AutoGenH.Append('#define %s  %s_gPcd_BinaryPatch_%s\n' %(GetModeName, Type, TokenCName))
1271        PcdDataSize = Pcd.GetPcdSize()
1272        if Pcd.DatumType not in TAB_PCD_NUMERIC_TYPES:
1273            AutoGenH.Append('#define %s(SizeOfBuffer, Buffer)  LibPatchPcdSetPtrAndSize((VOID *)_gPcd_BinaryPatch_%s, &%s, %s, (SizeOfBuffer), (Buffer))\n' % (SetModeName, TokenCName, PatchPcdSizeVariableName, PatchPcdMaxSizeVariable))
1274            AutoGenH.Append('#define %s(SizeOfBuffer, Buffer)  LibPatchPcdSetPtrAndSizeS((VOID *)_gPcd_BinaryPatch_%s, &%s, %s, (SizeOfBuffer), (Buffer))\n' % (SetModeStatusName, TokenCName, PatchPcdSizeVariableName, PatchPcdMaxSizeVariable))
1275            AutoGenH.Append('#define %s %s\n' % (PatchPcdSizeTokenName, PatchPcdMaxSizeVariable))
1276            AutoGenH.Append('extern const UINTN %s; \n' % PatchPcdMaxSizeVariable)
1277        else:
1278            AutoGenH.Append('#define %s(Value)  (%s = (Value))\n' % (SetModeName, PcdVariableName))
1279            AutoGenH.Append('#define %s(Value)  ((%s = (Value)), RETURN_SUCCESS)\n' % (SetModeStatusName, PcdVariableName))
1280            AutoGenH.Append('#define %s %s\n' % (PatchPcdSizeTokenName, PcdDataSize))
1281
1282        AutoGenH.Append('#define %s %s\n' % (GetModeSizeName, PatchPcdSizeVariableName))
1283        AutoGenH.Append('extern UINTN %s; \n' % PatchPcdSizeVariableName)
1284
1285    if PcdItemType == TAB_PCDS_FIXED_AT_BUILD or PcdItemType == TAB_PCDS_FEATURE_FLAG:
1286        key = ".".join((Pcd.TokenSpaceGuidCName, Pcd.TokenCName))
1287        PcdVariableName = '_gPcd_' + gItemTypeStringDatabase[Pcd.Type] + '_' + TokenCName
1288        if DatumType == TAB_VOID and Array == '[]':
1289            DatumType = [TAB_UINT8, TAB_UINT16][Pcd.DefaultValue[0] == 'L']
1290        if DatumType not in TAB_PCD_NUMERIC_TYPES_VOID:
1291            DatumType = TAB_UINT8
1292        AutoGenH.Append('extern const %s _gPcd_FixedAtBuild_%s%s;\n' %(DatumType, TokenCName, Array))
1293        AutoGenH.Append('#define %s  %s_gPcd_FixedAtBuild_%s\n' %(GetModeName, Type, TokenCName))
1294        AutoGenH.Append('//#define %s  ASSERT(FALSE)  // It is not allowed to set value for a FIXED_AT_BUILD PCD\n' % SetModeName)
1295
1296        ConstFixedPcd = False
1297        if PcdItemType == TAB_PCDS_FIXED_AT_BUILD and (key in Info.ConstPcd or (Info.IsLibrary and not Info.ReferenceModules)):
1298            ConstFixedPcd = True
1299            if key in Info.ConstPcd:
1300                Pcd.DefaultValue = Info.ConstPcd[key]
1301            if Pcd.DatumType not in TAB_PCD_NUMERIC_TYPES:
1302                AutoGenH.Append('#define _PCD_VALUE_%s %s%s\n' %(TokenCName, Type, PcdVariableName))
1303            else:
1304                AutoGenH.Append('#define _PCD_VALUE_%s %s\n' %(TokenCName, Pcd.DefaultValue))
1305        PcdDataSize = Pcd.GetPcdSize()
1306        if PcdItemType == TAB_PCDS_FIXED_AT_BUILD:
1307            if Pcd.DatumType not in TAB_PCD_NUMERIC_TYPES:
1308                if ConstFixedPcd:
1309                    AutoGenH.Append('#define %s %s\n' % (FixPcdSizeTokenName, PcdDataSize))
1310                    AutoGenH.Append('#define %s %s\n' % (GetModeSizeName, FixPcdSizeTokenName))
1311                else:
1312                    AutoGenH.Append('#define %s %s\n' % (GetModeSizeName, FixedPcdSizeVariableName))
1313                    AutoGenH.Append('#define %s %s\n' % (FixPcdSizeTokenName, FixedPcdSizeVariableName))
1314                    AutoGenH.Append('extern const UINTN %s; \n' % FixedPcdSizeVariableName)
1315            else:
1316                AutoGenH.Append('#define %s %s\n' % (FixPcdSizeTokenName, PcdDataSize))
1317                AutoGenH.Append('#define %s %s\n' % (GetModeSizeName, FixPcdSizeTokenName))
1318
1319## Create code for library constructor
1320#
1321#   @param      Info        The ModuleAutoGen object
1322#   @param      AutoGenC    The TemplateString object for C code
1323#   @param      AutoGenH    The TemplateString object for header file
1324#
1325def CreateLibraryConstructorCode(Info, AutoGenC, AutoGenH):
1326    #
1327    # Library Constructors
1328    #
1329    ConstructorPrototypeString = TemplateString()
1330    ConstructorCallingString = TemplateString()
1331    if Info.IsLibrary:
1332        DependentLibraryList = [Info.Module]
1333    else:
1334        DependentLibraryList = Info.DependentLibraryList
1335    for Lib in DependentLibraryList:
1336        if len(Lib.ConstructorList) <= 0:
1337            continue
1338        Dict = {'Function':Lib.ConstructorList}
1339        if Lib.ModuleType in [SUP_MODULE_BASE, SUP_MODULE_SEC]:
1340            ConstructorPrototypeString.Append(gLibraryStructorPrototype[SUP_MODULE_BASE].Replace(Dict))
1341            ConstructorCallingString.Append(gLibraryStructorCall[SUP_MODULE_BASE].Replace(Dict))
1342        if Info.ModuleType not in [SUP_MODULE_BASE, SUP_MODULE_USER_DEFINED]:
1343            if Lib.ModuleType in SUP_MODULE_SET_PEI:
1344                ConstructorPrototypeString.Append(gLibraryStructorPrototype['PEI'].Replace(Dict))
1345                ConstructorCallingString.Append(gLibraryStructorCall['PEI'].Replace(Dict))
1346            elif Lib.ModuleType in [SUP_MODULE_DXE_CORE, SUP_MODULE_DXE_DRIVER, SUP_MODULE_DXE_SMM_DRIVER, SUP_MODULE_DXE_RUNTIME_DRIVER,
1347                                    SUP_MODULE_DXE_SAL_DRIVER, SUP_MODULE_UEFI_DRIVER, SUP_MODULE_UEFI_APPLICATION, SUP_MODULE_SMM_CORE]:
1348                ConstructorPrototypeString.Append(gLibraryStructorPrototype['DXE'].Replace(Dict))
1349                ConstructorCallingString.Append(gLibraryStructorCall['DXE'].Replace(Dict))
1350            elif Lib.ModuleType in [SUP_MODULE_MM_STANDALONE, SUP_MODULE_MM_CORE_STANDALONE]:
1351                ConstructorPrototypeString.Append(gLibraryStructorPrototype['MM'].Replace(Dict))
1352                ConstructorCallingString.Append(gLibraryStructorCall['MM'].Replace(Dict))
1353
1354    if str(ConstructorPrototypeString) == '':
1355        ConstructorPrototypeList = []
1356    else:
1357        ConstructorPrototypeList = [str(ConstructorPrototypeString)]
1358    if str(ConstructorCallingString) == '':
1359        ConstructorCallingList = []
1360    else:
1361        ConstructorCallingList = [str(ConstructorCallingString)]
1362
1363    Dict = {
1364        'Type'              :   'Constructor',
1365        'FunctionPrototype' :   ConstructorPrototypeList,
1366        'FunctionCall'      :   ConstructorCallingList
1367    }
1368    if Info.IsLibrary:
1369        AutoGenH.Append("${BEGIN}${FunctionPrototype}${END}", Dict)
1370    else:
1371        if Info.ModuleType in [SUP_MODULE_BASE, SUP_MODULE_SEC, SUP_MODULE_USER_DEFINED]:
1372            AutoGenC.Append(gLibraryString[SUP_MODULE_BASE].Replace(Dict))
1373        elif Info.ModuleType in SUP_MODULE_SET_PEI:
1374            AutoGenC.Append(gLibraryString['PEI'].Replace(Dict))
1375        elif Info.ModuleType in [SUP_MODULE_DXE_CORE, SUP_MODULE_DXE_DRIVER, SUP_MODULE_DXE_SMM_DRIVER, SUP_MODULE_DXE_RUNTIME_DRIVER,
1376                                 SUP_MODULE_DXE_SAL_DRIVER, SUP_MODULE_UEFI_DRIVER, SUP_MODULE_UEFI_APPLICATION, SUP_MODULE_SMM_CORE]:
1377            AutoGenC.Append(gLibraryString['DXE'].Replace(Dict))
1378        elif Info.ModuleType in [SUP_MODULE_MM_STANDALONE, SUP_MODULE_MM_CORE_STANDALONE]:
1379            AutoGenC.Append(gLibraryString['MM'].Replace(Dict))
1380
1381## Create code for library destructor
1382#
1383#   @param      Info        The ModuleAutoGen object
1384#   @param      AutoGenC    The TemplateString object for C code
1385#   @param      AutoGenH    The TemplateString object for header file
1386#
1387def CreateLibraryDestructorCode(Info, AutoGenC, AutoGenH):
1388    #
1389    # Library Destructors
1390    #
1391    DestructorPrototypeString = TemplateString()
1392    DestructorCallingString = TemplateString()
1393    if Info.IsLibrary:
1394        DependentLibraryList = [Info.Module]
1395    else:
1396        DependentLibraryList = Info.DependentLibraryList
1397    for Index in range(len(DependentLibraryList)-1, -1, -1):
1398        Lib = DependentLibraryList[Index]
1399        if len(Lib.DestructorList) <= 0:
1400            continue
1401        Dict = {'Function':Lib.DestructorList}
1402        if Lib.ModuleType in [SUP_MODULE_BASE, SUP_MODULE_SEC]:
1403            DestructorPrototypeString.Append(gLibraryStructorPrototype[SUP_MODULE_BASE].Replace(Dict))
1404            DestructorCallingString.Append(gLibraryStructorCall[SUP_MODULE_BASE].Replace(Dict))
1405        if Info.ModuleType not in [SUP_MODULE_BASE, SUP_MODULE_USER_DEFINED]:
1406            if Lib.ModuleType in SUP_MODULE_SET_PEI:
1407                DestructorPrototypeString.Append(gLibraryStructorPrototype['PEI'].Replace(Dict))
1408                DestructorCallingString.Append(gLibraryStructorCall['PEI'].Replace(Dict))
1409            elif Lib.ModuleType in [SUP_MODULE_DXE_CORE, SUP_MODULE_DXE_DRIVER, SUP_MODULE_DXE_SMM_DRIVER, SUP_MODULE_DXE_RUNTIME_DRIVER,
1410                                    SUP_MODULE_DXE_SAL_DRIVER, SUP_MODULE_UEFI_DRIVER, SUP_MODULE_UEFI_APPLICATION, SUP_MODULE_SMM_CORE]:
1411                DestructorPrototypeString.Append(gLibraryStructorPrototype['DXE'].Replace(Dict))
1412                DestructorCallingString.Append(gLibraryStructorCall['DXE'].Replace(Dict))
1413            elif Lib.ModuleType in [SUP_MODULE_MM_STANDALONE, SUP_MODULE_MM_CORE_STANDALONE]:
1414                DestructorPrototypeString.Append(gLibraryStructorPrototype['MM'].Replace(Dict))
1415                DestructorCallingString.Append(gLibraryStructorCall['MM'].Replace(Dict))
1416
1417    if str(DestructorPrototypeString) == '':
1418        DestructorPrototypeList = []
1419    else:
1420        DestructorPrototypeList = [str(DestructorPrototypeString)]
1421    if str(DestructorCallingString) == '':
1422        DestructorCallingList = []
1423    else:
1424        DestructorCallingList = [str(DestructorCallingString)]
1425
1426    Dict = {
1427        'Type'              :   'Destructor',
1428        'FunctionPrototype' :   DestructorPrototypeList,
1429        'FunctionCall'      :   DestructorCallingList
1430    }
1431    if Info.IsLibrary:
1432        AutoGenH.Append("${BEGIN}${FunctionPrototype}${END}", Dict)
1433    else:
1434        if Info.ModuleType in [SUP_MODULE_BASE, SUP_MODULE_SEC, SUP_MODULE_USER_DEFINED]:
1435            AutoGenC.Append(gLibraryString[SUP_MODULE_BASE].Replace(Dict))
1436        elif Info.ModuleType in SUP_MODULE_SET_PEI:
1437            AutoGenC.Append(gLibraryString['PEI'].Replace(Dict))
1438        elif Info.ModuleType in [SUP_MODULE_DXE_CORE, SUP_MODULE_DXE_DRIVER, SUP_MODULE_DXE_SMM_DRIVER, SUP_MODULE_DXE_RUNTIME_DRIVER,
1439                                 SUP_MODULE_DXE_SAL_DRIVER, SUP_MODULE_UEFI_DRIVER, SUP_MODULE_UEFI_APPLICATION, SUP_MODULE_SMM_CORE]:
1440            AutoGenC.Append(gLibraryString['DXE'].Replace(Dict))
1441        elif Info.ModuleType in [SUP_MODULE_MM_STANDALONE, SUP_MODULE_MM_CORE_STANDALONE]:
1442            AutoGenC.Append(gLibraryString['MM'].Replace(Dict))
1443
1444
1445## Create code for ModuleEntryPoint
1446#
1447#   @param      Info        The ModuleAutoGen object
1448#   @param      AutoGenC    The TemplateString object for C code
1449#   @param      AutoGenH    The TemplateString object for header file
1450#
1451def CreateModuleEntryPointCode(Info, AutoGenC, AutoGenH):
1452    if Info.IsLibrary or Info.ModuleType in [SUP_MODULE_USER_DEFINED, SUP_MODULE_SEC]:
1453        return
1454    #
1455    # Module Entry Points
1456    #
1457    NumEntryPoints = len(Info.Module.ModuleEntryPointList)
1458    if 'PI_SPECIFICATION_VERSION' in Info.Module.Specification:
1459        PiSpecVersion = Info.Module.Specification['PI_SPECIFICATION_VERSION']
1460    else:
1461        PiSpecVersion = '0x00000000'
1462    if 'UEFI_SPECIFICATION_VERSION' in Info.Module.Specification:
1463        UefiSpecVersion = Info.Module.Specification['UEFI_SPECIFICATION_VERSION']
1464    else:
1465        UefiSpecVersion = '0x00000000'
1466    Dict = {
1467        'Function'       :   Info.Module.ModuleEntryPointList,
1468        'PiSpecVersion'  :   PiSpecVersion + 'U',
1469        'UefiSpecVersion':   UefiSpecVersion + 'U'
1470    }
1471
1472    if Info.ModuleType in [SUP_MODULE_PEI_CORE, SUP_MODULE_DXE_CORE, SUP_MODULE_SMM_CORE, SUP_MODULE_MM_CORE_STANDALONE]:
1473        if Info.SourceFileList:
1474          if NumEntryPoints != 1:
1475              EdkLogger.error(
1476                  "build",
1477                  AUTOGEN_ERROR,
1478                  '%s must have exactly one entry point' % Info.ModuleType,
1479                  File=str(Info),
1480                  ExtraData= ", ".join(Info.Module.ModuleEntryPointList)
1481                  )
1482    if Info.ModuleType == SUP_MODULE_PEI_CORE:
1483        AutoGenC.Append(gPeiCoreEntryPointString.Replace(Dict))
1484        AutoGenH.Append(gPeiCoreEntryPointPrototype.Replace(Dict))
1485    elif Info.ModuleType == SUP_MODULE_DXE_CORE:
1486        AutoGenC.Append(gDxeCoreEntryPointString.Replace(Dict))
1487        AutoGenH.Append(gDxeCoreEntryPointPrototype.Replace(Dict))
1488    elif Info.ModuleType == SUP_MODULE_SMM_CORE:
1489        AutoGenC.Append(gSmmCoreEntryPointString.Replace(Dict))
1490        AutoGenH.Append(gSmmCoreEntryPointPrototype.Replace(Dict))
1491    elif Info.ModuleType == SUP_MODULE_MM_CORE_STANDALONE:
1492        AutoGenC.Append(gMmCoreStandaloneEntryPointString.Replace(Dict))
1493        AutoGenH.Append(gMmCoreStandaloneEntryPointPrototype.Replace(Dict))
1494    elif Info.ModuleType == SUP_MODULE_PEIM:
1495        if NumEntryPoints < 2:
1496            AutoGenC.Append(gPeimEntryPointString[NumEntryPoints].Replace(Dict))
1497        else:
1498            AutoGenC.Append(gPeimEntryPointString[2].Replace(Dict))
1499        AutoGenH.Append(gPeimEntryPointPrototype.Replace(Dict))
1500    elif Info.ModuleType in [SUP_MODULE_DXE_RUNTIME_DRIVER, SUP_MODULE_DXE_DRIVER, SUP_MODULE_DXE_SAL_DRIVER, SUP_MODULE_UEFI_DRIVER]:
1501        if NumEntryPoints < 2:
1502            AutoGenC.Append(gUefiDriverEntryPointString[NumEntryPoints].Replace(Dict))
1503        else:
1504            AutoGenC.Append(gUefiDriverEntryPointString[2].Replace(Dict))
1505        AutoGenH.Append(gUefiDriverEntryPointPrototype.Replace(Dict))
1506    elif Info.ModuleType == SUP_MODULE_DXE_SMM_DRIVER:
1507        if NumEntryPoints == 0:
1508            AutoGenC.Append(gDxeSmmEntryPointString[0].Replace(Dict))
1509        else:
1510            AutoGenC.Append(gDxeSmmEntryPointString[1].Replace(Dict))
1511        AutoGenH.Append(gDxeSmmEntryPointPrototype.Replace(Dict))
1512    elif Info.ModuleType == SUP_MODULE_MM_STANDALONE:
1513        if NumEntryPoints < 2:
1514            AutoGenC.Append(gMmStandaloneEntryPointString[NumEntryPoints].Replace(Dict))
1515        else:
1516            AutoGenC.Append(gMmStandaloneEntryPointString[2].Replace(Dict))
1517        AutoGenH.Append(gMmStandaloneEntryPointPrototype.Replace(Dict))
1518    elif Info.ModuleType == SUP_MODULE_UEFI_APPLICATION:
1519        if NumEntryPoints < 2:
1520            AutoGenC.Append(gUefiApplicationEntryPointString[NumEntryPoints].Replace(Dict))
1521        else:
1522            AutoGenC.Append(gUefiApplicationEntryPointString[2].Replace(Dict))
1523        AutoGenH.Append(gUefiApplicationEntryPointPrototype.Replace(Dict))
1524
1525## Create code for ModuleUnloadImage
1526#
1527#   @param      Info        The ModuleAutoGen object
1528#   @param      AutoGenC    The TemplateString object for C code
1529#   @param      AutoGenH    The TemplateString object for header file
1530#
1531def CreateModuleUnloadImageCode(Info, AutoGenC, AutoGenH):
1532    if Info.IsLibrary or Info.ModuleType in [SUP_MODULE_USER_DEFINED, SUP_MODULE_BASE, SUP_MODULE_SEC]:
1533        return
1534    #
1535    # Unload Image Handlers
1536    #
1537    NumUnloadImage = len(Info.Module.ModuleUnloadImageList)
1538    Dict = {'Count':str(NumUnloadImage) + 'U', 'Function':Info.Module.ModuleUnloadImageList}
1539    if NumUnloadImage < 2:
1540        AutoGenC.Append(gUefiUnloadImageString[NumUnloadImage].Replace(Dict))
1541    else:
1542        AutoGenC.Append(gUefiUnloadImageString[2].Replace(Dict))
1543    AutoGenH.Append(gUefiUnloadImagePrototype.Replace(Dict))
1544
1545## Create code for GUID
1546#
1547#   @param      Info        The ModuleAutoGen object
1548#   @param      AutoGenC    The TemplateString object for C code
1549#   @param      AutoGenH    The TemplateString object for header file
1550#
1551def CreateGuidDefinitionCode(Info, AutoGenC, AutoGenH):
1552    if Info.ModuleType in [SUP_MODULE_USER_DEFINED, SUP_MODULE_BASE]:
1553        GuidType = TAB_GUID
1554    else:
1555        GuidType = "EFI_GUID"
1556
1557    if Info.GuidList:
1558        if not Info.IsLibrary:
1559            AutoGenC.Append("\n// Guids\n")
1560        AutoGenH.Append("\n// Guids\n")
1561    #
1562    # GUIDs
1563    #
1564    for Key in Info.GuidList:
1565        if not Info.IsLibrary:
1566            AutoGenC.Append('GLOBAL_REMOVE_IF_UNREFERENCED %s %s = %s;\n' % (GuidType, Key, Info.GuidList[Key]))
1567        AutoGenH.Append('extern %s %s;\n' % (GuidType, Key))
1568
1569## Create code for protocol
1570#
1571#   @param      Info        The ModuleAutoGen object
1572#   @param      AutoGenC    The TemplateString object for C code
1573#   @param      AutoGenH    The TemplateString object for header file
1574#
1575def CreateProtocolDefinitionCode(Info, AutoGenC, AutoGenH):
1576    if Info.ModuleType in [SUP_MODULE_USER_DEFINED, SUP_MODULE_BASE]:
1577        GuidType = TAB_GUID
1578    else:
1579        GuidType = "EFI_GUID"
1580
1581    if Info.ProtocolList:
1582        if not Info.IsLibrary:
1583            AutoGenC.Append("\n// Protocols\n")
1584        AutoGenH.Append("\n// Protocols\n")
1585    #
1586    # Protocol GUIDs
1587    #
1588    for Key in Info.ProtocolList:
1589        if not Info.IsLibrary:
1590            AutoGenC.Append('GLOBAL_REMOVE_IF_UNREFERENCED %s %s = %s;\n' % (GuidType, Key, Info.ProtocolList[Key]))
1591        AutoGenH.Append('extern %s %s;\n' % (GuidType, Key))
1592
1593## Create code for PPI
1594#
1595#   @param      Info        The ModuleAutoGen object
1596#   @param      AutoGenC    The TemplateString object for C code
1597#   @param      AutoGenH    The TemplateString object for header file
1598#
1599def CreatePpiDefinitionCode(Info, AutoGenC, AutoGenH):
1600    if Info.ModuleType in [SUP_MODULE_USER_DEFINED, SUP_MODULE_BASE]:
1601        GuidType = TAB_GUID
1602    else:
1603        GuidType = "EFI_GUID"
1604
1605    if Info.PpiList:
1606        if not Info.IsLibrary:
1607            AutoGenC.Append("\n// PPIs\n")
1608        AutoGenH.Append("\n// PPIs\n")
1609    #
1610    # PPI GUIDs
1611    #
1612    for Key in Info.PpiList:
1613        if not Info.IsLibrary:
1614            AutoGenC.Append('GLOBAL_REMOVE_IF_UNREFERENCED %s %s = %s;\n' % (GuidType, Key, Info.PpiList[Key]))
1615        AutoGenH.Append('extern %s %s;\n' % (GuidType, Key))
1616
1617## Create code for PCD
1618#
1619#   @param      Info        The ModuleAutoGen object
1620#   @param      AutoGenC    The TemplateString object for C code
1621#   @param      AutoGenH    The TemplateString object for header file
1622#
1623def CreatePcdCode(Info, AutoGenC, AutoGenH):
1624
1625    # Collect Token Space GUIDs used by DynamicEc PCDs
1626    TokenSpaceList = []
1627    for Pcd in Info.ModulePcdList:
1628        if Pcd.Type in PCD_DYNAMIC_EX_TYPE_SET and Pcd.TokenSpaceGuidCName not in TokenSpaceList:
1629            TokenSpaceList.append(Pcd.TokenSpaceGuidCName)
1630
1631    SkuMgr = Info.Workspace.Platform.SkuIdMgr
1632    AutoGenH.Append("\n// Definition of SkuId Array\n")
1633    AutoGenH.Append("extern UINT64 _gPcd_SkuId_Array[];\n")
1634    # Add extern declarations to AutoGen.h if one or more Token Space GUIDs were found
1635    if TokenSpaceList:
1636        AutoGenH.Append("\n// Definition of PCD Token Space GUIDs used in this module\n\n")
1637        if Info.ModuleType in [SUP_MODULE_USER_DEFINED, SUP_MODULE_BASE]:
1638            GuidType = TAB_GUID
1639        else:
1640            GuidType = "EFI_GUID"
1641        for Item in TokenSpaceList:
1642            AutoGenH.Append('extern %s %s;\n' % (GuidType, Item))
1643
1644    if Info.IsLibrary:
1645        if Info.ModulePcdList:
1646            AutoGenH.Append("\n// PCD definitions\n")
1647        for Pcd in Info.ModulePcdList:
1648            CreateLibraryPcdCode(Info, AutoGenC, AutoGenH, Pcd)
1649        DynExPcdTokenNumberMapping (Info, AutoGenH)
1650    else:
1651        AutoGenC.Append("\n// Definition of SkuId Array\n")
1652        AutoGenC.Append("GLOBAL_REMOVE_IF_UNREFERENCED UINT64 _gPcd_SkuId_Array[] = %s;\n" % SkuMgr.DumpSkuIdArrary())
1653        if Info.ModulePcdList:
1654            AutoGenH.Append("\n// Definition of PCDs used in this module\n")
1655            AutoGenC.Append("\n// Definition of PCDs used in this module\n")
1656        for Pcd in Info.ModulePcdList:
1657            CreateModulePcdCode(Info, AutoGenC, AutoGenH, Pcd)
1658        DynExPcdTokenNumberMapping (Info, AutoGenH)
1659        if Info.LibraryPcdList:
1660            AutoGenH.Append("\n// Definition of PCDs used in libraries is in AutoGen.c\n")
1661            AutoGenC.Append("\n// Definition of PCDs used in libraries\n")
1662        for Pcd in Info.LibraryPcdList:
1663            CreateModulePcdCode(Info, AutoGenC, AutoGenC, Pcd)
1664    CreatePcdDatabaseCode(Info, AutoGenC, AutoGenH)
1665
1666## Create code for unicode string definition
1667#
1668#   @param      Info        The ModuleAutoGen object
1669#   @param      AutoGenC    The TemplateString object for C code
1670#   @param      AutoGenH    The TemplateString object for header file
1671#   @param      UniGenCFlag     UniString is generated into AutoGen C file when it is set to True
1672#   @param      UniGenBinBuffer Buffer to store uni string package data
1673#
1674def CreateUnicodeStringCode(Info, AutoGenC, AutoGenH, UniGenCFlag, UniGenBinBuffer):
1675    WorkingDir = os.getcwd()
1676    os.chdir(Info.WorkspaceDir)
1677
1678    IncList = [Info.MetaFile.Dir]
1679    # Get all files under [Sources] section in inf file for EDK-II module
1680    EDK2Module = True
1681    SrcList = [F for F in Info.SourceFileList]
1682
1683    if 'BUILD' in Info.BuildOption and Info.BuildOption['BUILD']['FLAGS'].find('-c') > -1:
1684        CompatibleMode = True
1685    else:
1686        CompatibleMode = False
1687
1688    #
1689    # -s is a temporary option dedicated for building .UNI files with ISO 639-2 language codes of EDK Shell in EDK2
1690    #
1691    if 'BUILD' in Info.BuildOption and Info.BuildOption['BUILD']['FLAGS'].find('-s') > -1:
1692        if CompatibleMode:
1693            EdkLogger.error("build", AUTOGEN_ERROR,
1694                            "-c and -s build options should be used exclusively",
1695                            ExtraData="[%s]" % str(Info))
1696        ShellMode = True
1697    else:
1698        ShellMode = False
1699
1700    #RFC4646 is only for EDKII modules and ISO639-2 for EDK modules
1701    if EDK2Module:
1702        FilterInfo = [EDK2Module] + [Info.PlatformInfo.Platform.RFCLanguages]
1703    else:
1704        FilterInfo = [EDK2Module] + [Info.PlatformInfo.Platform.ISOLanguages]
1705    Header, Code = GetStringFiles(Info.UnicodeFileList, SrcList, IncList, Info.IncludePathList, ['.uni', '.inf'], Info.Name, CompatibleMode, ShellMode, UniGenCFlag, UniGenBinBuffer, FilterInfo)
1706    if CompatibleMode or UniGenCFlag:
1707        AutoGenC.Append("\n//\n//Unicode String Pack Definition\n//\n")
1708        AutoGenC.Append(Code)
1709        AutoGenC.Append("\n")
1710    AutoGenH.Append("\n//\n//Unicode String ID\n//\n")
1711    AutoGenH.Append(Header)
1712    if CompatibleMode or UniGenCFlag:
1713        AutoGenH.Append("\n#define STRING_ARRAY_NAME %sStrings\n" % Info.Name)
1714    os.chdir(WorkingDir)
1715
1716def CreateIdfFileCode(Info, AutoGenC, StringH, IdfGenCFlag, IdfGenBinBuffer):
1717    if len(Info.IdfFileList) > 0:
1718        ImageFiles = IdfFileClassObject(sorted (Info.IdfFileList))
1719        if ImageFiles.ImageFilesDict:
1720            Index = 1
1721            PaletteIndex = 1
1722            IncList = [Info.MetaFile.Dir]
1723            SrcList = [F for F in Info.SourceFileList]
1724            SkipList = ['.jpg', '.png', '.bmp', '.inf', '.idf']
1725            FileList = GetFileList(SrcList, IncList, SkipList)
1726            ValueStartPtr = 60
1727            StringH.Append("\n//\n//Image ID\n//\n")
1728            ImageInfoOffset = 0
1729            PaletteInfoOffset = 0
1730            ImageBuffer = pack('x')
1731            PaletteBuffer = pack('x')
1732            BufferStr = ''
1733            PaletteStr = ''
1734            FileDict = {}
1735            for Idf in ImageFiles.ImageFilesDict:
1736                if ImageFiles.ImageFilesDict[Idf]:
1737                    for FileObj in ImageFiles.ImageFilesDict[Idf]:
1738                        for sourcefile in Info.SourceFileList:
1739                            if FileObj.FileName == sourcefile.File:
1740                                if not sourcefile.Ext.upper() in ['.PNG', '.BMP', '.JPG']:
1741                                    EdkLogger.error("build", AUTOGEN_ERROR, "The %s's postfix must be one of .bmp, .jpg, .png" % (FileObj.FileName), ExtraData="[%s]" % str(Info))
1742                                FileObj.File = sourcefile
1743                                break
1744                        else:
1745                            EdkLogger.error("build", AUTOGEN_ERROR, "The %s in %s is not defined in the driver's [Sources] section" % (FileObj.FileName, Idf), ExtraData="[%s]" % str(Info))
1746
1747                    for FileObj in ImageFiles.ImageFilesDict[Idf]:
1748                        ID = FileObj.ImageID
1749                        File = FileObj.File
1750                        if not os.path.exists(File.Path) or not os.path.isfile(File.Path):
1751                            EdkLogger.error("build", FILE_NOT_FOUND, ExtraData=File.Path)
1752                        SearchImageID (FileObj, FileList)
1753                        if FileObj.Referenced:
1754                            if (ValueStartPtr - len(DEFINE_STR + ID)) <= 0:
1755                                Line = DEFINE_STR + ' ' + ID + ' ' + DecToHexStr(Index, 4) + '\n'
1756                            else:
1757                                Line = DEFINE_STR + ' ' + ID + ' ' * (ValueStartPtr - len(DEFINE_STR + ID)) + DecToHexStr(Index, 4) + '\n'
1758
1759                            if File not in FileDict:
1760                                FileDict[File] = Index
1761                            else:
1762                                DuplicateBlock = pack('B', EFI_HII_IIBT_DUPLICATE)
1763                                DuplicateBlock += pack('H', FileDict[File])
1764                                ImageBuffer += DuplicateBlock
1765                                BufferStr = WriteLine(BufferStr, '// %s: %s: %s' % (DecToHexStr(Index, 4), ID, DecToHexStr(Index, 4)))
1766                                TempBufferList = AscToHexList(DuplicateBlock)
1767                                BufferStr = WriteLine(BufferStr, CreateArrayItem(TempBufferList, 16) + '\n')
1768                                StringH.Append(Line)
1769                                Index += 1
1770                                continue
1771
1772                            TmpFile = open(File.Path, 'rb')
1773                            Buffer = TmpFile.read()
1774                            TmpFile.close()
1775                            if File.Ext.upper() == '.PNG':
1776                                TempBuffer = pack('B', EFI_HII_IIBT_IMAGE_PNG)
1777                                TempBuffer += pack('I', len(Buffer))
1778                                TempBuffer += Buffer
1779                            elif File.Ext.upper() == '.JPG':
1780                                ImageType, = struct.unpack('4s', Buffer[6:10])
1781                                if ImageType != b'JFIF':
1782                                    EdkLogger.error("build", FILE_TYPE_MISMATCH, "The file %s is not a standard JPG file." % File.Path)
1783                                TempBuffer = pack('B', EFI_HII_IIBT_IMAGE_JPEG)
1784                                TempBuffer += pack('I', len(Buffer))
1785                                TempBuffer += Buffer
1786                            elif File.Ext.upper() == '.BMP':
1787                                TempBuffer, TempPalette = BmpImageDecoder(File, Buffer, PaletteIndex, FileObj.TransParent)
1788                                if len(TempPalette) > 1:
1789                                    PaletteIndex += 1
1790                                    NewPalette = pack('H', len(TempPalette))
1791                                    NewPalette += TempPalette
1792                                    PaletteBuffer += NewPalette
1793                                    PaletteStr = WriteLine(PaletteStr, '// %s: %s: %s' % (DecToHexStr(PaletteIndex - 1, 4), ID, DecToHexStr(PaletteIndex - 1, 4)))
1794                                    TempPaletteList = AscToHexList(NewPalette)
1795                                    PaletteStr = WriteLine(PaletteStr, CreateArrayItem(TempPaletteList, 16) + '\n')
1796                            ImageBuffer += TempBuffer
1797                            BufferStr = WriteLine(BufferStr, '// %s: %s: %s' % (DecToHexStr(Index, 4), ID, DecToHexStr(Index, 4)))
1798                            TempBufferList = AscToHexList(TempBuffer)
1799                            BufferStr = WriteLine(BufferStr, CreateArrayItem(TempBufferList, 16) + '\n')
1800
1801                            StringH.Append(Line)
1802                            Index += 1
1803
1804            BufferStr = WriteLine(BufferStr, '// End of the Image Info')
1805            BufferStr = WriteLine(BufferStr, CreateArrayItem(DecToHexList(EFI_HII_IIBT_END, 2)) + '\n')
1806            ImageEnd = pack('B', EFI_HII_IIBT_END)
1807            ImageBuffer += ImageEnd
1808
1809            if len(ImageBuffer) > 1:
1810                ImageInfoOffset = 12
1811            if len(PaletteBuffer) > 1:
1812                PaletteInfoOffset = 12 + len(ImageBuffer) - 1 # -1 is for the first empty pad byte of ImageBuffer
1813
1814            IMAGE_PACKAGE_HDR = pack('=II', ImageInfoOffset, PaletteInfoOffset)
1815            # PACKAGE_HEADER_Length = PACKAGE_HEADER + ImageInfoOffset + PaletteInfoOffset + ImageBuffer Length + PaletteCount + PaletteBuffer Length
1816            if len(PaletteBuffer) > 1:
1817                PACKAGE_HEADER_Length = 4 + 4 + 4 + len(ImageBuffer) - 1 + 2 + len(PaletteBuffer) - 1
1818            else:
1819                PACKAGE_HEADER_Length = 4 + 4 + 4 + len(ImageBuffer) - 1
1820            if PaletteIndex > 1:
1821                PALETTE_INFO_HEADER = pack('H', PaletteIndex - 1)
1822            # EFI_HII_PACKAGE_HEADER length max value is 0xFFFFFF
1823            Hex_Length = '%06X' % PACKAGE_HEADER_Length
1824            if PACKAGE_HEADER_Length > 0xFFFFFF:
1825                EdkLogger.error("build", AUTOGEN_ERROR, "The Length of EFI_HII_PACKAGE_HEADER exceed its maximum value", ExtraData="[%s]" % str(Info))
1826            PACKAGE_HEADER = pack('=HBB', int('0x' + Hex_Length[2:], 16), int('0x' + Hex_Length[0:2], 16), EFI_HII_PACKAGE_IMAGES)
1827
1828            IdfGenBinBuffer.write(PACKAGE_HEADER)
1829            IdfGenBinBuffer.write(IMAGE_PACKAGE_HDR)
1830            if len(ImageBuffer) > 1 :
1831                IdfGenBinBuffer.write(ImageBuffer[1:])
1832            if PaletteIndex > 1:
1833                IdfGenBinBuffer.write(PALETTE_INFO_HEADER)
1834            if len(PaletteBuffer) > 1:
1835                IdfGenBinBuffer.write(PaletteBuffer[1:])
1836
1837            if IdfGenCFlag:
1838                TotalLength = EFI_HII_ARRAY_SIZE_LENGTH + PACKAGE_HEADER_Length
1839                AutoGenC.Append("\n//\n//Image Pack Definition\n//\n")
1840                AllStr = WriteLine('', CHAR_ARRAY_DEFIN + ' ' + Info.Module.BaseName + 'Images' + '[] = {\n')
1841                AllStr = WriteLine(AllStr, '// STRGATHER_OUTPUT_HEADER')
1842                AllStr = WriteLine(AllStr, CreateArrayItem(DecToHexList(TotalLength)) + '\n')
1843                AllStr = WriteLine(AllStr, '// Image PACKAGE HEADER\n')
1844                IMAGE_PACKAGE_HDR_List = AscToHexList(PACKAGE_HEADER)
1845                IMAGE_PACKAGE_HDR_List += AscToHexList(IMAGE_PACKAGE_HDR)
1846                AllStr = WriteLine(AllStr, CreateArrayItem(IMAGE_PACKAGE_HDR_List, 16) + '\n')
1847                AllStr = WriteLine(AllStr, '// Image DATA\n')
1848                if BufferStr:
1849                    AllStr = WriteLine(AllStr, BufferStr)
1850                if PaletteStr:
1851                    AllStr = WriteLine(AllStr, '// Palette Header\n')
1852                    PALETTE_INFO_HEADER_List = AscToHexList(PALETTE_INFO_HEADER)
1853                    AllStr = WriteLine(AllStr, CreateArrayItem(PALETTE_INFO_HEADER_List, 16) + '\n')
1854                    AllStr = WriteLine(AllStr, '// Palette Data\n')
1855                    AllStr = WriteLine(AllStr, PaletteStr)
1856                AllStr = WriteLine(AllStr, '};')
1857                AutoGenC.Append(AllStr)
1858                AutoGenC.Append("\n")
1859                StringH.Append('\nextern unsigned char ' + Info.Module.BaseName + 'Images[];\n')
1860                StringH.Append("\n#define IMAGE_ARRAY_NAME %sImages\n" % Info.Module.BaseName)
1861
1862# typedef struct _EFI_HII_IMAGE_PACKAGE_HDR {
1863#   EFI_HII_PACKAGE_HEADER  Header;          # Standard package header, where Header.Type = EFI_HII_PACKAGE_IMAGES
1864#   UINT32                  ImageInfoOffset;
1865#   UINT32                  PaletteInfoOffset;
1866# } EFI_HII_IMAGE_PACKAGE_HDR;
1867
1868# typedef struct {
1869#   UINT32   Length:24;
1870#   UINT32   Type:8;
1871#   UINT8    Data[];
1872# } EFI_HII_PACKAGE_HEADER;
1873
1874# typedef struct _EFI_HII_IMAGE_BLOCK {
1875#   UINT8    BlockType;
1876#   UINT8    BlockBody[];
1877# } EFI_HII_IMAGE_BLOCK;
1878
1879def BmpImageDecoder(File, Buffer, PaletteIndex, TransParent):
1880    ImageType, = struct.unpack('2s', Buffer[0:2])
1881    if ImageType!= b'BM': # BMP file type is 'BM'
1882        EdkLogger.error("build", FILE_TYPE_MISMATCH, "The file %s is not a standard BMP file." % File.Path)
1883    BMP_IMAGE_HEADER = collections.namedtuple('BMP_IMAGE_HEADER', ['bfSize', 'bfReserved1', 'bfReserved2', 'bfOffBits', 'biSize', 'biWidth', 'biHeight', 'biPlanes', 'biBitCount', 'biCompression', 'biSizeImage', 'biXPelsPerMeter', 'biYPelsPerMeter', 'biClrUsed', 'biClrImportant'])
1884    BMP_IMAGE_HEADER_STRUCT = struct.Struct('IHHIIIIHHIIIIII')
1885    BmpHeader = BMP_IMAGE_HEADER._make(BMP_IMAGE_HEADER_STRUCT.unpack_from(Buffer[2:]))
1886    #
1887    # Doesn't support compress.
1888    #
1889    if BmpHeader.biCompression != 0:
1890        EdkLogger.error("build", FORMAT_NOT_SUPPORTED, "The compress BMP file %s is not support." % File.Path)
1891
1892    # The Width and Height is UINT16 type in Image Package
1893    if BmpHeader.biWidth > 0xFFFF:
1894        EdkLogger.error("build", FORMAT_NOT_SUPPORTED, "The BMP file %s Width is exceed 0xFFFF." % File.Path)
1895    if BmpHeader.biHeight > 0xFFFF:
1896        EdkLogger.error("build", FORMAT_NOT_SUPPORTED, "The BMP file %s Height is exceed 0xFFFF." % File.Path)
1897
1898    PaletteBuffer = pack('x')
1899    if BmpHeader.biBitCount == 1:
1900        if TransParent:
1901            ImageBuffer = pack('B', EFI_HII_IIBT_IMAGE_1BIT_TRANS)
1902        else:
1903            ImageBuffer = pack('B', EFI_HII_IIBT_IMAGE_1BIT)
1904        ImageBuffer += pack('B', PaletteIndex)
1905        Width = (BmpHeader.biWidth + 7)//8
1906        if BmpHeader.bfOffBits > BMP_IMAGE_HEADER_STRUCT.size + 2:
1907            PaletteBuffer = Buffer[BMP_IMAGE_HEADER_STRUCT.size + 2 : BmpHeader.bfOffBits]
1908    elif BmpHeader.biBitCount == 4:
1909        if TransParent:
1910            ImageBuffer = pack('B', EFI_HII_IIBT_IMAGE_4BIT_TRANS)
1911        else:
1912            ImageBuffer = pack('B', EFI_HII_IIBT_IMAGE_4BIT)
1913        ImageBuffer += pack('B', PaletteIndex)
1914        Width = (BmpHeader.biWidth + 1)//2
1915        if BmpHeader.bfOffBits > BMP_IMAGE_HEADER_STRUCT.size + 2:
1916            PaletteBuffer = Buffer[BMP_IMAGE_HEADER_STRUCT.size + 2 : BmpHeader.bfOffBits]
1917    elif BmpHeader.biBitCount == 8:
1918        if TransParent:
1919            ImageBuffer = pack('B', EFI_HII_IIBT_IMAGE_8BIT_TRANS)
1920        else:
1921            ImageBuffer = pack('B', EFI_HII_IIBT_IMAGE_8BIT)
1922        ImageBuffer += pack('B', PaletteIndex)
1923        Width = BmpHeader.biWidth
1924        if BmpHeader.bfOffBits > BMP_IMAGE_HEADER_STRUCT.size + 2:
1925            PaletteBuffer = Buffer[BMP_IMAGE_HEADER_STRUCT.size + 2 : BmpHeader.bfOffBits]
1926    elif BmpHeader.biBitCount == 24:
1927        if TransParent:
1928            ImageBuffer = pack('B', EFI_HII_IIBT_IMAGE_24BIT_TRANS)
1929        else:
1930            ImageBuffer = pack('B', EFI_HII_IIBT_IMAGE_24BIT)
1931        Width = BmpHeader.biWidth * 3
1932    else:
1933        EdkLogger.error("build", FORMAT_NOT_SUPPORTED, "Only support the 1 bit, 4 bit, 8bit, 24 bit BMP files.", ExtraData="[%s]" % str(File.Path))
1934
1935    ImageBuffer += pack('H', BmpHeader.biWidth)
1936    ImageBuffer += pack('H', BmpHeader.biHeight)
1937    Start = BmpHeader.bfOffBits
1938    End = BmpHeader.bfSize - 1
1939    for Height in range(0, BmpHeader.biHeight):
1940        if Width % 4 != 0:
1941            Start = End + (Width % 4) - 4 - Width
1942        else:
1943            Start = End - Width
1944        ImageBuffer += Buffer[Start + 1 : Start + Width + 1]
1945        End = Start
1946
1947    # handle the Palette info,  BMP use 4 bytes for R, G, B and Reserved info while EFI_HII_RGB_PIXEL only have the R, G, B info
1948    if PaletteBuffer and len(PaletteBuffer) > 1:
1949        PaletteTemp = pack('x')
1950        for Index in range(0, len(PaletteBuffer)):
1951            if Index % 4 == 3:
1952                continue
1953            PaletteTemp += PaletteBuffer[Index:Index+1]
1954        PaletteBuffer = PaletteTemp[1:]
1955    return ImageBuffer, PaletteBuffer
1956
1957## Create common code
1958#
1959#   @param      Info        The ModuleAutoGen object
1960#   @param      AutoGenC    The TemplateString object for C code
1961#   @param      AutoGenH    The TemplateString object for header file
1962#
1963def CreateHeaderCode(Info, AutoGenC, AutoGenH):
1964    # file header
1965    AutoGenH.Append(gAutoGenHeaderString.Replace({'FileName':'AutoGen.h'}))
1966    # header file Prologue
1967    AutoGenH.Append(gAutoGenHPrologueString.Replace({'File':'AUTOGENH','Guid':Info.Guid.replace('-', '_')}))
1968    AutoGenH.Append(gAutoGenHCppPrologueString)
1969
1970    # header files includes
1971    if Info.ModuleType in gModuleTypeHeaderFile:
1972        AutoGenH.Append("#include <%s>\n" % gModuleTypeHeaderFile[Info.ModuleType][0])
1973    #
1974    # if either PcdLib in [LibraryClasses] sections or there exist Pcd section, add PcdLib.h
1975    # As if modules only uses FixedPcd, then PcdLib is not needed in [LibraryClasses] section.
1976    #
1977    if 'PcdLib' in Info.Module.LibraryClasses or Info.Module.Pcds:
1978        AutoGenH.Append("#include <Library/PcdLib.h>\n")
1979
1980    AutoGenH.Append('\nextern GUID  gEfiCallerIdGuid;')
1981    AutoGenH.Append('\nextern CHAR8 *gEfiCallerBaseName;\n\n')
1982
1983    if Info.IsLibrary:
1984        return
1985
1986    AutoGenH.Append("#define EFI_CALLER_ID_GUID \\\n  %s\n" % GuidStringToGuidStructureString(Info.Guid))
1987
1988    if Info.IsLibrary:
1989        return
1990    # C file header
1991    AutoGenC.Append(gAutoGenHeaderString.Replace({'FileName':'AutoGen.c'}))
1992    # C file header files includes
1993    if Info.ModuleType in gModuleTypeHeaderFile:
1994        for Inc in gModuleTypeHeaderFile[Info.ModuleType]:
1995            AutoGenC.Append("#include <%s>\n" % Inc)
1996    else:
1997        AutoGenC.Append("#include <%s>\n" % gBasicHeaderFile)
1998
1999    #
2000    # Publish the CallerId Guid
2001    #
2002    AutoGenC.Append('\nGLOBAL_REMOVE_IF_UNREFERENCED GUID gEfiCallerIdGuid = %s;\n' % GuidStringToGuidStructureString(Info.Guid))
2003    AutoGenC.Append('\nGLOBAL_REMOVE_IF_UNREFERENCED CHAR8 *gEfiCallerBaseName = "%s";\n' % Info.Name)
2004
2005## Create common code for header file
2006#
2007#   @param      Info        The ModuleAutoGen object
2008#   @param      AutoGenC    The TemplateString object for C code
2009#   @param      AutoGenH    The TemplateString object for header file
2010#
2011def CreateFooterCode(Info, AutoGenC, AutoGenH):
2012    AutoGenH.Append(gAutoGenHEpilogueString)
2013
2014## Create code for a module
2015#
2016#   @param      Info        The ModuleAutoGen object
2017#   @param      AutoGenC    The TemplateString object for C code
2018#   @param      AutoGenH    The TemplateString object for header file
2019#   @param      StringH     The TemplateString object for header file
2020#   @param      UniGenCFlag     UniString is generated into AutoGen C file when it is set to True
2021#   @param      UniGenBinBuffer Buffer to store uni string package data
2022#   @param      StringIdf       The TemplateString object for header file
2023#   @param      IdfGenCFlag     IdfString is generated into AutoGen C file when it is set to True
2024#   @param      IdfGenBinBuffer Buffer to store Idf string package data
2025#
2026def CreateCode(Info, AutoGenC, AutoGenH, StringH, UniGenCFlag, UniGenBinBuffer, StringIdf, IdfGenCFlag, IdfGenBinBuffer):
2027    CreateHeaderCode(Info, AutoGenC, AutoGenH)
2028
2029    CreateGuidDefinitionCode(Info, AutoGenC, AutoGenH)
2030    CreateProtocolDefinitionCode(Info, AutoGenC, AutoGenH)
2031    CreatePpiDefinitionCode(Info, AutoGenC, AutoGenH)
2032    CreatePcdCode(Info, AutoGenC, AutoGenH)
2033    CreateLibraryConstructorCode(Info, AutoGenC, AutoGenH)
2034    CreateLibraryDestructorCode(Info, AutoGenC, AutoGenH)
2035    CreateModuleEntryPointCode(Info, AutoGenC, AutoGenH)
2036    CreateModuleUnloadImageCode(Info, AutoGenC, AutoGenH)
2037
2038    if Info.UnicodeFileList:
2039        FileName = "%sStrDefs.h" % Info.Name
2040        StringH.Append(gAutoGenHeaderString.Replace({'FileName':FileName}))
2041        StringH.Append(gAutoGenHPrologueString.Replace({'File':'STRDEFS', 'Guid':Info.Guid.replace('-', '_')}))
2042        CreateUnicodeStringCode(Info, AutoGenC, StringH, UniGenCFlag, UniGenBinBuffer)
2043
2044        GuidMacros = []
2045        for Guid in Info.Module.Guids:
2046            if Guid in Info.Module.GetGuidsUsedByPcd():
2047                continue
2048            GuidMacros.append('#define %s %s' % (Guid, Info.Module.Guids[Guid]))
2049        for Guid, Value in list(Info.Module.Protocols.items()) + list(Info.Module.Ppis.items()):
2050            GuidMacros.append('#define %s %s' % (Guid, Value))
2051        # supports FixedAtBuild and FeaturePcd usage in VFR file
2052        if Info.VfrFileList and Info.ModulePcdList:
2053            GuidMacros.append('#define %s %s' % ('FixedPcdGetBool(TokenName)', '_PCD_VALUE_##TokenName'))
2054            GuidMacros.append('#define %s %s' % ('FixedPcdGet8(TokenName)', '_PCD_VALUE_##TokenName'))
2055            GuidMacros.append('#define %s %s' % ('FixedPcdGet16(TokenName)', '_PCD_VALUE_##TokenName'))
2056            GuidMacros.append('#define %s %s' % ('FixedPcdGet32(TokenName)', '_PCD_VALUE_##TokenName'))
2057            GuidMacros.append('#define %s %s' % ('FixedPcdGet64(TokenName)', '_PCD_VALUE_##TokenName'))
2058            GuidMacros.append('#define %s %s' % ('FeaturePcdGet(TokenName)', '_PCD_VALUE_##TokenName'))
2059            for Pcd in Info.ModulePcdList:
2060                if Pcd.Type in [TAB_PCDS_FIXED_AT_BUILD, TAB_PCDS_FEATURE_FLAG]:
2061                    TokenCName = Pcd.TokenCName
2062                    Value = Pcd.DefaultValue
2063                    if Pcd.DatumType == 'BOOLEAN':
2064                        BoolValue = Value.upper()
2065                        if BoolValue == 'TRUE':
2066                            Value = '1'
2067                        elif BoolValue == 'FALSE':
2068                            Value = '0'
2069                    for PcdItem in GlobalData.MixedPcd:
2070                        if (Pcd.TokenCName, Pcd.TokenSpaceGuidCName) in GlobalData.MixedPcd[PcdItem]:
2071                            TokenCName = PcdItem[0]
2072                            break
2073                    GuidMacros.append('#define %s %s' % ('_PCD_VALUE_'+TokenCName, Value))
2074
2075        if Info.IdfFileList:
2076            GuidMacros.append('#include "%sImgDefs.h"' % Info.Name)
2077
2078        if GuidMacros:
2079            StringH.Append('\n#ifdef VFRCOMPILE\n%s\n#endif\n' % '\n'.join(GuidMacros))
2080
2081        StringH.Append("\n#endif\n")
2082        AutoGenH.Append('#include "%s"\n' % FileName)
2083
2084    if Info.IdfFileList:
2085        FileName = "%sImgDefs.h" % Info.Name
2086        StringIdf.Append(gAutoGenHeaderString.Replace({'FileName':FileName}))
2087        StringIdf.Append(gAutoGenHPrologueString.Replace({'File':'IMAGEDEFS', 'Guid':Info.Guid.replace('-', '_')}))
2088        CreateIdfFileCode(Info, AutoGenC, StringIdf, IdfGenCFlag, IdfGenBinBuffer)
2089
2090        StringIdf.Append("\n#endif\n")
2091        AutoGenH.Append('#include "%s"\n' % FileName)
2092
2093    CreateFooterCode(Info, AutoGenC, AutoGenH)
2094
2095## Create the code file
2096#
2097#   @param      FilePath     The path of code file
2098#   @param      Content      The content of code file
2099#   @param      IsBinaryFile The flag indicating if the file is binary file or not
2100#
2101#   @retval     True        If file content is changed or file doesn't exist
2102#   @retval     False       If the file exists and the content is not changed
2103#
2104def Generate(FilePath, Content, IsBinaryFile):
2105    return SaveFileOnChange(FilePath, Content, IsBinaryFile)
2106
2107