]> git.proxmox.com Git - mirror_edk2.git/blob - BaseTools/Source/Python/GenFds/FfsFileStatement.py
BaseTools/GenFds: cleanup GenFds
[mirror_edk2.git] / BaseTools / Source / Python / GenFds / FfsFileStatement.py
1 ## @file
2 # process FFS generation from FILE statement
3 #
4 # Copyright (c) 2007 - 2018, 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 #
18 from __future__ import absolute_import
19 from io import BytesIO
20 from struct import pack
21 from CommonDataClass.FdfClass import FileStatementClassObject
22 from Common import EdkLogger
23 from Common.BuildToolError import GENFDS_ERROR
24 from Common.Misc import GuidStructureByteArrayToGuidString, SaveFileOnChange
25 import Common.LongFilePathOs as os
26 from .GuidSection import GuidSection
27 from .FvImageSection import FvImageSection
28 from .Ffs import FdfFvFileTypeToFileType
29 from .GenFdsGlobalVariable import GenFdsGlobalVariable
30
31 ## generate FFS from FILE
32 #
33 #
34 class FileStatement (FileStatementClassObject):
35 ## The constructor
36 #
37 # @param self The object pointer
38 #
39 def __init__(self):
40 FileStatementClassObject.__init__(self)
41 self.CurrentLineNum = None
42 self.CurrentLineContent = None
43 self.FileName = None
44 self.InfFileName = None
45 self.SubAlignment = 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, IsMakefile=False, FvName=None):
58
59 if self.NameGuid 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 Str = self.NameGuid
73 if FvName:
74 Str += FvName
75 OutputDir = os.path.join(GenFdsGlobalVariable.FfsDir, Str)
76 if not os.path.exists(OutputDir):
77 os.makedirs(OutputDir)
78
79 Dict.update(self.DefineVarDict)
80 SectionAlignments = None
81 if self.FvName:
82 Buffer = BytesIO('')
83 if self.FvName.upper() not in GenFdsGlobalVariable.FdfParser.Profile.FvDict:
84 EdkLogger.error("GenFds", GENFDS_ERROR, "FV (%s) is NOT described in FDF file!" % (self.FvName))
85 Fv = GenFdsGlobalVariable.FdfParser.Profile.FvDict.get(self.FvName.upper())
86 FileName = Fv.AddToBuffer(Buffer)
87 SectionFiles = [FileName]
88
89 elif self.FdName:
90 if self.FdName.upper() not in GenFdsGlobalVariable.FdfParser.Profile.FdDict:
91 EdkLogger.error("GenFds", GENFDS_ERROR, "FD (%s) is NOT described in FDF file!" % (self.FdName))
92 Fd = GenFdsGlobalVariable.FdfParser.Profile.FdDict.get(self.FdName.upper())
93 FileName = Fd.GenFd()
94 SectionFiles = [FileName]
95
96 elif self.FileName:
97 if hasattr(self, 'FvFileType') and self.FvFileType == 'RAW':
98 if isinstance(self.FileName, list) and isinstance(self.SubAlignment, list) and len(self.FileName) == len(self.SubAlignment):
99 FileContent = ''
100 MaxAlignIndex = 0
101 MaxAlignValue = 1
102 for Index, File in enumerate(self.FileName):
103 try:
104 f = open(File, 'rb')
105 except:
106 GenFdsGlobalVariable.ErrorLogger("Error opening RAW file %s." % (File))
107 Content = f.read()
108 f.close()
109 AlignValue = 1
110 if self.SubAlignment[Index]:
111 AlignValue = GenFdsGlobalVariable.GetAlignment(self.SubAlignment[Index])
112 if AlignValue > MaxAlignValue:
113 MaxAlignIndex = Index
114 MaxAlignValue = AlignValue
115 FileContent += Content
116 if len(FileContent) % AlignValue != 0:
117 Size = AlignValue - len(FileContent) % AlignValue
118 for i in range(0, Size):
119 FileContent += pack('B', 0xFF)
120
121 if FileContent:
122 OutputRAWFile = os.path.join(GenFdsGlobalVariable.FfsDir, self.NameGuid, self.NameGuid + '.raw')
123 SaveFileOnChange(OutputRAWFile, FileContent, True)
124 self.FileName = OutputRAWFile
125 self.SubAlignment = self.SubAlignment[MaxAlignIndex]
126
127 if self.Alignment and self.SubAlignment:
128 if GenFdsGlobalVariable.GetAlignment (self.Alignment) < GenFdsGlobalVariable.GetAlignment (self.SubAlignment):
129 self.Alignment = self.SubAlignment
130 elif self.SubAlignment:
131 self.Alignment = self.SubAlignment
132
133 self.FileName = GenFdsGlobalVariable.ReplaceWorkspaceMacro(self.FileName)
134 #Replace $(SAPCE) with real space
135 self.FileName = self.FileName.replace('$(SPACE)', ' ')
136 SectionFiles = [GenFdsGlobalVariable.MacroExtend(self.FileName, Dict)]
137
138 else:
139 SectionFiles = []
140 Index = 0
141 SectionAlignments = []
142 for section in self.SectionList:
143 Index = Index + 1
144 SecIndex = '%d' %Index
145 # process the inside FvImage from FvSection or GuidSection
146 if FvChildAddr != []:
147 if isinstance(section, FvImageSection):
148 section.FvAddr = FvChildAddr.pop(0)
149 elif isinstance(section, GuidSection):
150 section.FvAddr = FvChildAddr
151 if FvParentAddr and isinstance(section, GuidSection):
152 section.FvParentAddr = FvParentAddr
153
154 if self.KeepReloc == False:
155 section.KeepReloc = False
156 sectList, align = section.GenSection(OutputDir, self.NameGuid, SecIndex, self.KeyStringList, None, Dict)
157 if sectList != []:
158 for sect in sectList:
159 SectionFiles.append(sect)
160 SectionAlignments.append(align)
161
162 #
163 # Prepare the parameter
164 #
165 FfsFileOutput = os.path.join(OutputDir, self.NameGuid + '.ffs')
166 GenFdsGlobalVariable.GenerateFfs(FfsFileOutput, SectionFiles,
167 FdfFvFileTypeToFileType.get(self.FvFileType),
168 self.NameGuid,
169 Fixed=self.Fixed,
170 CheckSum=self.CheckSum,
171 Align=self.Alignment,
172 SectionAlign=SectionAlignments
173 )
174
175 return FfsFileOutput