1## @file
2# process APRIORI file data and generate PEI/DXE APRIORI file
3#
4#  Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
5#
6#  SPDX-License-Identifier: BSD-2-Clause-Patent
7#
8
9##
10# Import Modules
11#
12from __future__ import absolute_import
13from struct import pack
14import Common.LongFilePathOs as os
15from io import BytesIO
16from .FfsFileStatement import FileStatement
17from .GenFdsGlobalVariable import GenFdsGlobalVariable
18from Common.StringUtils import NormPath
19from Common.Misc import SaveFileOnChange, PathClass
20from Common.EdkLogger import error as EdkLoggerError
21from Common.BuildToolError import RESOURCE_NOT_AVAILABLE
22from Common.DataType import TAB_COMMON
23
24DXE_APRIORI_GUID = "FC510EE7-FFDC-11D4-BD41-0080C73C8881"
25PEI_APRIORI_GUID = "1B45CC0A-156A-428A-AF62-49864DA0E6E6"
26
27## process APRIORI file data and generate PEI/DXE APRIORI file
28#
29#
30class AprioriSection (object):
31    ## The constructor
32    #
33    #   @param  self        The object pointer
34    #
35    def __init__(self):
36        self.DefineVarDict = {}
37        self.FfsList = []
38        self.AprioriType = ""
39
40    ## GenFfs() method
41    #
42    #   Generate FFS for APRIORI file
43    #
44    #   @param  self        The object pointer
45    #   @param  FvName      for whom apriori file generated
46    #   @param  Dict        dictionary contains macro and its value
47    #   @retval string      Generated file name
48    #
49    def GenFfs (self, FvName, Dict = None, IsMakefile = False):
50        if Dict is None:
51            Dict = {}
52        Buffer = BytesIO()
53        if self.AprioriType == "PEI":
54            AprioriFileGuid = PEI_APRIORI_GUID
55        else:
56            AprioriFileGuid = DXE_APRIORI_GUID
57
58        OutputAprFilePath = os.path.join (GenFdsGlobalVariable.WorkSpaceDir, \
59                                   GenFdsGlobalVariable.FfsDir,\
60                                   AprioriFileGuid + FvName)
61        if not os.path.exists(OutputAprFilePath):
62            os.makedirs(OutputAprFilePath)
63
64        OutputAprFileName = os.path.join( OutputAprFilePath, \
65                                       AprioriFileGuid + FvName + '.Apri' )
66        AprFfsFileName = os.path.join (OutputAprFilePath,\
67                                    AprioriFileGuid + FvName + '.Ffs')
68
69        Dict.update(self.DefineVarDict)
70        InfFileName = None
71        for FfsObj in self.FfsList:
72            Guid = ""
73            if isinstance(FfsObj, FileStatement):
74                Guid = FfsObj.NameGuid
75            else:
76                InfFileName = NormPath(FfsObj.InfFileName)
77                Arch = FfsObj.GetCurrentArch()
78
79                if Arch:
80                    Dict['$(ARCH)'] = Arch
81                InfFileName = GenFdsGlobalVariable.MacroExtend(InfFileName, Dict, Arch)
82
83                if Arch:
84                    Inf = GenFdsGlobalVariable.WorkSpace.BuildObject[PathClass(InfFileName, GenFdsGlobalVariable.WorkSpaceDir), Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]
85                    Guid = Inf.Guid
86                else:
87                    Inf = GenFdsGlobalVariable.WorkSpace.BuildObject[PathClass(InfFileName, GenFdsGlobalVariable.WorkSpaceDir), TAB_COMMON, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]
88                    Guid = Inf.Guid
89
90                    if not Inf.Module.Binaries:
91                        EdkLoggerError("GenFds", RESOURCE_NOT_AVAILABLE,
92                                        "INF %s not found in build ARCH %s!" \
93                                        % (InfFileName, GenFdsGlobalVariable.ArchList))
94
95            GuidPart = Guid.split('-')
96            Buffer.write(pack('I', int(GuidPart[0], 16)))
97            Buffer.write(pack('H', int(GuidPart[1], 16)))
98            Buffer.write(pack('H', int(GuidPart[2], 16)))
99
100            for Num in range(2):
101                Char = GuidPart[3][Num*2:Num*2+2]
102                Buffer.write(pack('B', int(Char, 16)))
103
104            for Num in range(6):
105                Char = GuidPart[4][Num*2:Num*2+2]
106                Buffer.write(pack('B', int(Char, 16)))
107
108        SaveFileOnChange(OutputAprFileName, Buffer.getvalue())
109
110        RawSectionFileName = os.path.join( OutputAprFilePath, \
111                                       AprioriFileGuid + FvName + '.raw' )
112        MakefilePath = None
113        if IsMakefile:
114            if not InfFileName:
115                return None
116            MakefilePath = InfFileName, Arch
117        GenFdsGlobalVariable.GenerateSection(RawSectionFileName, [OutputAprFileName], 'EFI_SECTION_RAW', IsMakefile=IsMakefile)
118        GenFdsGlobalVariable.GenerateFfs(AprFfsFileName, [RawSectionFileName],
119                                        'EFI_FV_FILETYPE_FREEFORM', AprioriFileGuid, MakefilePath=MakefilePath)
120
121        return AprFfsFileName
122