2 # process FFS generation from FILE statement
4 # Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
6 # SPDX-License-Identifier: BSD-2-Clause-Patent
12 from __future__
import absolute_import
13 from io
import BytesIO
14 from struct
import pack
15 from CommonDataClass
.FdfClass
import FileStatementClassObject
16 from Common
import EdkLogger
17 from Common
.BuildToolError
import GENFDS_ERROR
18 from Common
.Misc
import GuidStructureByteArrayToGuidString
, SaveFileOnChange
19 import Common
.LongFilePathOs
as os
20 from .GuidSection
import GuidSection
21 from .FvImageSection
import FvImageSection
22 from .Ffs
import FdfFvFileTypeToFileType
23 from .GenFdsGlobalVariable
import GenFdsGlobalVariable
26 ## generate FFS from FILE
29 class FileStatement (FileStatementClassObject
):
32 # @param self The object pointer
35 FileStatementClassObject
.__init
__(self
)
36 self
.CurrentLineNum
= None
37 self
.CurrentLineContent
= None
39 self
.InfFileName
= None
40 self
.SubAlignment
= None
46 # @param self The object pointer
47 # @param Dict dictionary contains macro and value pair
48 # @param FvChildAddr Array of the inside FvImage base address
49 # @param FvParentAddr Parent Fv base address
50 # @retval string Generated FFS file name
52 def GenFfs(self
, Dict
= None, FvChildAddr
=[], FvParentAddr
=None, IsMakefile
=False, FvName
=None):
54 if self
.NameGuid
and self
.NameGuid
.startswith('PCD('):
55 PcdValue
= GenFdsGlobalVariable
.GetPcdValue(self
.NameGuid
)
56 if len(PcdValue
) == 0:
57 EdkLogger
.error("GenFds", GENFDS_ERROR
, '%s NOT defined.' \
59 if PcdValue
.startswith('{'):
60 PcdValue
= GuidStructureByteArrayToGuidString(PcdValue
)
61 RegistryGuidStr
= PcdValue
62 if len(RegistryGuidStr
) == 0:
63 EdkLogger
.error("GenFds", GENFDS_ERROR
, 'GUID value for %s in wrong format.' \
65 self
.NameGuid
= RegistryGuidStr
70 OutputDir
= os
.path
.join(GenFdsGlobalVariable
.FfsDir
, Str
)
71 if os
.path
.exists(OutputDir
):
72 shutil
.rmtree(OutputDir
)
73 if not os
.path
.exists(OutputDir
):
74 os
.makedirs(OutputDir
)
79 Dict
.update(self
.DefineVarDict
)
80 SectionAlignments
= None
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
]
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())
94 SectionFiles
= [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
= BytesIO()
102 for Index
, File
in enumerate(self
.FileName
):
106 GenFdsGlobalVariable
.ErrorLogger("Error opening RAW file %s." % (File
))
110 if self
.SubAlignment
[Index
]:
111 AlignValue
= GenFdsGlobalVariable
.GetAlignment(self
.SubAlignment
[Index
])
112 if AlignValue
> MaxAlignValue
:
113 MaxAlignIndex
= Index
114 MaxAlignValue
= AlignValue
115 FileContent
.write(Content
)
116 if len(FileContent
.getvalue()) % AlignValue
!= 0:
117 Size
= AlignValue
- len(FileContent
.getvalue()) % AlignValue
118 for i
in range(0, Size
):
119 FileContent
.write(pack('B', 0xFF))
121 if FileContent
.getvalue() != b
'':
122 OutputRAWFile
= os
.path
.join(GenFdsGlobalVariable
.FfsDir
, self
.NameGuid
, self
.NameGuid
+ '.raw')
123 SaveFileOnChange(OutputRAWFile
, FileContent
.getvalue(), True)
124 self
.FileName
= OutputRAWFile
125 self
.SubAlignment
= self
.SubAlignment
[MaxAlignIndex
]
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
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
)]
141 SectionAlignments
= []
142 for section
in self
.SectionList
:
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
154 if self
.KeepReloc
== False:
155 section
.KeepReloc
= False
156 sectList
, align
= section
.GenSection(OutputDir
, self
.NameGuid
, SecIndex
, self
.KeyStringList
, None, Dict
)
158 for sect
in sectList
:
159 SectionFiles
.append(sect
)
160 SectionAlignments
.append(align
)
163 # Prepare the parameter
165 FfsFileOutput
= os
.path
.join(OutputDir
, self
.NameGuid
+ '.ffs')
166 GenFdsGlobalVariable
.GenerateFfs(FfsFileOutput
, SectionFiles
,
167 FdfFvFileTypeToFileType
.get(self
.FvFileType
),
170 CheckSum
=self
.CheckSum
,
171 Align
=self
.Alignment
,
172 SectionAlign
=SectionAlignments