2 # process FFS generation from FILE statement
4 # Copyright (c) 2007 - 2017, 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.
20 import Common
.LongFilePathOs
as os
24 from GenFdsGlobalVariable
import GenFdsGlobalVariable
25 from CommonDataClass
.FdfClass
import FileStatementClassObject
26 from Common
import EdkLogger
27 from Common
.BuildToolError
import *
28 from Common
.Misc
import GuidStructureByteArrayToGuidString
29 from GuidSection
import GuidSection
30 from FvImageSection
import FvImageSection
31 from Common
.Misc
import SaveFileOnChange
34 ## generate FFS from FILE
37 class FileStatement (FileStatementClassObject
) :
40 # @param self The object pointer
43 FileStatementClassObject
.__init
__(self
)
44 self
.CurrentLineNum
= None
45 self
.CurrentLineContent
= None
47 self
.InfFileName
= None
48 self
.SubAlignment
= None
54 # @param self The object pointer
55 # @param Dict dictionary contains macro and value pair
56 # @param FvChildAddr Array of the inside FvImage base address
57 # @param FvParentAddr Parent Fv base address
58 # @retval string Generated FFS file name
60 def GenFfs(self
, Dict
= {}, FvChildAddr
=[], FvParentAddr
=None, IsMakefile
=False, FvName
=None):
62 if self
.NameGuid
is not None and self
.NameGuid
.startswith('PCD('):
63 PcdValue
= GenFdsGlobalVariable
.GetPcdValue(self
.NameGuid
)
64 if len(PcdValue
) == 0:
65 EdkLogger
.error("GenFds", GENFDS_ERROR
, '%s NOT defined.' \
67 if PcdValue
.startswith('{'):
68 PcdValue
= GuidStructureByteArrayToGuidString(PcdValue
)
69 RegistryGuidStr
= PcdValue
70 if len(RegistryGuidStr
) == 0:
71 EdkLogger
.error("GenFds", GENFDS_ERROR
, 'GUID value for %s in wrong format.' \
73 self
.NameGuid
= RegistryGuidStr
78 OutputDir
= os
.path
.join(GenFdsGlobalVariable
.FfsDir
, Str
)
79 if not os
.path
.exists(OutputDir
):
80 os
.makedirs(OutputDir
)
82 Dict
.update(self
.DefineVarDict
)
83 SectionAlignments
= None
84 if self
.FvName
is not None :
85 Buffer
= StringIO
.StringIO('')
86 if self
.FvName
.upper() not in GenFdsGlobalVariable
.FdfParser
.Profile
.FvDict
.keys():
87 EdkLogger
.error("GenFds", GENFDS_ERROR
, "FV (%s) is NOT described in FDF file!" % (self
.FvName
))
88 Fv
= GenFdsGlobalVariable
.FdfParser
.Profile
.FvDict
.get(self
.FvName
.upper())
89 FileName
= Fv
.AddToBuffer(Buffer
)
90 SectionFiles
= [FileName
]
92 elif self
.FdName
is not None:
93 if self
.FdName
.upper() not in GenFdsGlobalVariable
.FdfParser
.Profile
.FdDict
.keys():
94 EdkLogger
.error("GenFds", GENFDS_ERROR
, "FD (%s) is NOT described in FDF file!" % (self
.FdName
))
95 Fd
= GenFdsGlobalVariable
.FdfParser
.Profile
.FdDict
.get(self
.FdName
.upper())
97 SectionFiles
= [FileName
]
99 elif self
.FileName
is not None:
100 if hasattr(self
, 'FvFileType') and self
.FvFileType
== 'RAW':
101 if isinstance(self
.FileName
, list) and isinstance(self
.SubAlignment
, list) and len(self
.FileName
) == len(self
.SubAlignment
):
105 for Index
, File
in enumerate(self
.FileName
):
109 GenFdsGlobalVariable
.ErrorLogger("Error opening RAW file %s." % (File
))
113 if self
.SubAlignment
[Index
] is not None:
114 AlignValue
= GenFdsGlobalVariable
.GetAlignment(self
.SubAlignment
[Index
])
115 if AlignValue
> MaxAlignValue
:
116 MaxAlignIndex
= Index
117 MaxAlignValue
= AlignValue
118 FileContent
+= Content
119 if len(FileContent
) % AlignValue
!= 0:
120 Size
= AlignValue
- len(FileContent
) % AlignValue
121 for i
in range(0, Size
):
122 FileContent
+= pack('B', 0xFF)
125 OutputRAWFile
= os
.path
.join(GenFdsGlobalVariable
.FfsDir
, self
.NameGuid
, self
.NameGuid
+ '.raw')
126 SaveFileOnChange(OutputRAWFile
, FileContent
, True)
127 self
.FileName
= OutputRAWFile
128 self
.SubAlignment
= self
.SubAlignment
[MaxAlignIndex
]
130 if self
.Alignment
and self
.SubAlignment
:
131 if GenFdsGlobalVariable
.GetAlignment (self
.Alignment
) < GenFdsGlobalVariable
.GetAlignment (self
.SubAlignment
):
132 self
.Alignment
= self
.SubAlignment
133 elif self
.SubAlignment
:
134 self
.Alignment
= self
.SubAlignment
136 self
.FileName
= GenFdsGlobalVariable
.ReplaceWorkspaceMacro(self
.FileName
)
137 #Replace $(SAPCE) with real space
138 self
.FileName
= self
.FileName
.replace('$(SPACE)', ' ')
139 SectionFiles
= [GenFdsGlobalVariable
.MacroExtend(self
.FileName
, Dict
)]
144 SectionAlignments
= []
145 for section
in self
.SectionList
:
147 SecIndex
= '%d' %Index
148 # process the inside FvImage from FvSection or GuidSection
149 if FvChildAddr
!= []:
150 if isinstance(section
, FvImageSection
):
151 section
.FvAddr
= FvChildAddr
.pop(0)
152 elif isinstance(section
, GuidSection
):
153 section
.FvAddr
= FvChildAddr
154 if FvParentAddr
is not None and isinstance(section
, GuidSection
):
155 section
.FvParentAddr
= FvParentAddr
157 if self
.KeepReloc
== False:
158 section
.KeepReloc
= False
159 sectList
, align
= section
.GenSection(OutputDir
, self
.NameGuid
, SecIndex
, self
.KeyStringList
, None, Dict
)
161 for sect
in sectList
:
162 SectionFiles
.append(sect
)
163 SectionAlignments
.append(align
)
166 # Prepare the parameter
168 FfsFileOutput
= os
.path
.join(OutputDir
, self
.NameGuid
+ '.ffs')
169 GenFdsGlobalVariable
.GenerateFfs(FfsFileOutput
, SectionFiles
,
170 Ffs
.Ffs
.FdfFvFileTypeToFileType
.get(self
.FvFileType
),
173 CheckSum
=self
.CheckSum
,
174 Align
=self
.Alignment
,
175 SectionAlign
=SectionAlignments