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