1## @file
2# process FFS generation from FILE statement
3#
4#  Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>
5#
6#  This program and the accompanying materials
7#  are licensed and made available under the terms and conditions of the BSD License
8#  which accompanies this distribution.  The full text of the license may be found at
9#  http://opensource.org/licenses/bsd-license.php
10#
11#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
13#
14
15##
16# Import Modules
17#
18import Ffs
19import Rule
20import Common.LongFilePathOs as os
21import StringIO
22import subprocess
23
24from GenFdsGlobalVariable import GenFdsGlobalVariable
25from CommonDataClass.FdfClass import FileStatementClassObject
26from Common import EdkLogger
27from Common.BuildToolError import *
28from Common.Misc import GuidStructureByteArrayToGuidString
29from GuidSection import GuidSection
30from FvImageSection import FvImageSection
31
32## generate FFS from FILE
33#
34#
35class FileStatement (FileStatementClassObject) :
36    ## The constructor
37    #
38    #   @param  self        The object pointer
39    #
40    def __init__(self):
41        FileStatementClassObject.__init__(self)
42        self.CurrentLineNum = None
43        self.CurrentLineContent = None
44        self.FileName = None
45        self.InfFileName = None
46
47    ## GenFfs() method
48    #
49    #   Generate FFS
50    #
51    #   @param  self         The object pointer
52    #   @param  Dict         dictionary contains macro and value pair
53    #   @param  FvChildAddr  Array of the inside FvImage base address
54    #   @param  FvParentAddr Parent Fv base address
55    #   @retval string       Generated FFS file name
56    #
57    def GenFfs(self, Dict = {}, FvChildAddr=[], FvParentAddr=None):
58
59        if self.NameGuid != None and self.NameGuid.startswith('PCD('):
60            PcdValue = GenFdsGlobalVariable.GetPcdValue(self.NameGuid)
61            if len(PcdValue) == 0:
62                EdkLogger.error("GenFds", GENFDS_ERROR, '%s NOT defined.' \
63                            % (self.NameGuid))
64            if PcdValue.startswith('{'):
65                PcdValue = GuidStructureByteArrayToGuidString(PcdValue)
66            RegistryGuidStr = PcdValue
67            if len(RegistryGuidStr) == 0:
68                EdkLogger.error("GenFds", GENFDS_ERROR, 'GUID value for %s in wrong format.' \
69                            % (self.NameGuid))
70            self.NameGuid = RegistryGuidStr
71
72        OutputDir = os.path.join(GenFdsGlobalVariable.FfsDir, self.NameGuid)
73        if not os.path.exists(OutputDir):
74            os.makedirs(OutputDir)
75
76        Dict.update(self.DefineVarDict)
77        SectionAlignments = None
78        if self.FvName != None :
79            Buffer = StringIO.StringIO('')
80            if self.FvName.upper() not in GenFdsGlobalVariable.FdfParser.Profile.FvDict.keys():
81                EdkLogger.error("GenFds", GENFDS_ERROR, "FV (%s) is NOT described in FDF file!" % (self.FvName))
82            Fv = GenFdsGlobalVariable.FdfParser.Profile.FvDict.get(self.FvName.upper())
83            FileName = Fv.AddToBuffer(Buffer)
84            SectionFiles = [FileName]
85
86        elif self.FdName != None:
87            if self.FdName.upper() not in GenFdsGlobalVariable.FdfParser.Profile.FdDict.keys():
88                EdkLogger.error("GenFds", GENFDS_ERROR, "FD (%s) is NOT described in FDF file!" % (self.FdName))
89            Fd = GenFdsGlobalVariable.FdfParser.Profile.FdDict.get(self.FdName.upper())
90            FileName = Fd.GenFd()
91            SectionFiles = [FileName]
92
93        elif self.FileName != None:
94            self.FileName = GenFdsGlobalVariable.ReplaceWorkspaceMacro(self.FileName)
95            #Replace $(SAPCE) with real space
96            self.FileName = self.FileName.replace('$(SPACE)', ' ')
97            SectionFiles = [GenFdsGlobalVariable.MacroExtend(self.FileName, Dict)]
98
99        else:
100            SectionFiles = []
101            Index = 0
102            SectionAlignments = []
103            for section in self.SectionList :
104                Index = Index + 1
105                SecIndex = '%d' %Index
106                # process the inside FvImage from FvSection or GuidSection
107                if FvChildAddr != []:
108                    if isinstance(section, FvImageSection):
109                        section.FvAddr = FvChildAddr.pop(0)
110                    elif isinstance(section, GuidSection):
111                        section.FvAddr = FvChildAddr
112                if FvParentAddr != None and isinstance(section, GuidSection):
113                    section.FvParentAddr = FvParentAddr
114
115                if self.KeepReloc == False:
116                    section.KeepReloc = False
117                sectList, align = section.GenSection(OutputDir, self.NameGuid, SecIndex, self.KeyStringList, None, Dict)
118                if sectList != []:
119                    for sect in sectList:
120                        SectionFiles.append(sect)
121                        SectionAlignments.append(align)
122
123        #
124        # Prepare the parameter
125        #
126        FfsFileOutput = os.path.join(OutputDir, self.NameGuid + '.ffs')
127        GenFdsGlobalVariable.GenerateFfs(FfsFileOutput, SectionFiles,
128                                         Ffs.Ffs.FdfFvFileTypeToFileType.get(self.FvFileType),
129                                         self.NameGuid,
130                                         Fixed=self.Fixed,
131                                         CheckSum=self.CheckSum,
132                                         Align=self.Alignment,
133                                         SectionAlign=SectionAlignments
134                                        )
135
136        return FfsFileOutput
137
138
139
140