2 # process FFS generation from FILE statement
4 # Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
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
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.
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
31 ## generate FFS from FILE
34 class FileStatement (FileStatementClassObject
):
37 # @param self The object pointer
40 FileStatementClassObject
.__init
__(self
)
41 self
.CurrentLineNum
= None
42 self
.CurrentLineContent
= None
44 self
.InfFileName
= None
45 self
.SubAlignment
= None
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
57 def GenFfs(self
, Dict
= {}, FvChildAddr
=[], FvParentAddr
=None, IsMakefile
=False, FvName
=None):
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.' \
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.' \
70 self
.NameGuid
= RegistryGuidStr
75 OutputDir
= os
.path
.join(GenFdsGlobalVariable
.FfsDir
, Str
)
76 if not os
.path
.exists(OutputDir
):
77 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
):
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
+= 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)
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
]
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