## @file\r
# process FD Region generation\r
#\r
-# Copyright (c) 2007, Intel Corporation. All rights reserved.<BR>\r
+# Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>\r
#\r
# This program and the accompanying materials\r
# are licensed and made available under the terms and conditions of the BSD License\r
from GenFdsGlobalVariable import GenFdsGlobalVariable\r
import StringIO\r
from CommonDataClass.FdfClass import RegionClassObject\r
-import os\r
+import Common.LongFilePathOs as os\r
from stat import *\r
from Common import EdkLogger\r
from Common.BuildToolError import *\r
+from Common.LongFilePathSupport import OpenLongFilePath as open\r
\r
## generate Region\r
#\r
#\r
# Get Fv from FvDict\r
#\r
- RegionBlockSize = self.BlockSizeOfRegion(BlockSizeList)\r
- RegionBlockNum = self.BlockNumOfRegion(RegionBlockSize)\r
-\r
self.FvAddress = int(BaseAddress, 16) + self.Offset\r
FvBaseAddress = '0x%X' %self.FvAddress\r
FvOffset = 0\r
#\r
# Call GenFv tool\r
#\r
- BlockSize = RegionBlockSize\r
- BlockNum = RegionBlockNum\r
- if FvObj.BlockSizeList != []:\r
- if FvObj.BlockSizeList[0][0] != None:\r
- BlockSize = FvObj.BlockSizeList[0][0]\r
- if FvObj.BlockSizeList[0][1] != None:\r
- BlockNum = FvObj.BlockSizeList[0][1]\r
+ self.BlockInfoOfRegion(BlockSizeList, FvObj)\r
self.FvAddress = self.FvAddress + FvOffset\r
FvAlignValue = self.GetFvAlignValue(FvObj.FvAlignment)\r
if self.FvAddress % FvAlignValue != 0:\r
"FV (%s) is NOT %s Aligned!" % (FvObj.UiFvName, FvObj.FvAlignment))\r
FvBuffer = StringIO.StringIO('')\r
FvBaseAddress = '0x%X' %self.FvAddress\r
+ BlockSize = None\r
+ BlockNum = None\r
FvObj.AddToBuffer(FvBuffer, FvBaseAddress, BlockSize, BlockNum, ErasePolarity, vtfDict)\r
if FvBuffer.len > Size:\r
FvBuffer.close()\r
"Size of File (%s) is larger than Region Size 0x%X specified." \\r
% (RegionData, Size))\r
GenFdsGlobalVariable.InfLogger(' Region File Name = %s'%RegionData)\r
- BinFile = open (RegionData, 'r+b')\r
+ BinFile = open (RegionData, 'rb')\r
Buffer.write(BinFile.read())\r
BinFile.close()\r
Size = Size - FileLength\r
\r
AlignValue = int(Str)*Granu\r
return AlignValue\r
+ \r
## BlockSizeOfRegion()\r
#\r
# @param BlockSizeList List of block information\r
- # @retval int Block size of region\r
+ # @param FvObj The object for FV\r
#\r
- def BlockSizeOfRegion(self, BlockSizeList):\r
- Offset = 0x00\r
- BlockSize = 0\r
- for item in BlockSizeList:\r
- Offset = Offset + item[0] * item[1]\r
- GenFdsGlobalVariable.VerboseLogger ("Offset = 0x%X" %Offset)\r
- GenFdsGlobalVariable.VerboseLogger ("self.Offset 0x%X" %self.Offset)\r
-\r
- if self.Offset < Offset :\r
- if Offset - self.Offset < self.Size:\r
- EdkLogger.error("GenFds", GENFDS_ERROR,\r
- "Region at Offset 0x%X can NOT fit into Block array with BlockSize %X" \\r
- % (self.Offset, item[0]))\r
- BlockSize = item[0]\r
- GenFdsGlobalVariable.VerboseLogger ("BlockSize = %X" %BlockSize)\r
- return BlockSize\r
- return BlockSize\r
+ def BlockInfoOfRegion(self, BlockSizeList, FvObj):\r
+ Start = 0\r
+ End = 0\r
+ RemindingSize = self.Size\r
+ ExpectedList = []\r
+ for (BlockSize, BlockNum, pcd) in BlockSizeList:\r
+ End = Start + BlockSize * BlockNum\r
+ # region not started yet\r
+ if self.Offset >= End:\r
+ Start = End\r
+ continue\r
+ # region located in current blocks \r
+ else:\r
+ # region ended within current blocks\r
+ if self.Offset + self.Size <= End:\r
+ ExpectedList.append((BlockSize, (RemindingSize + BlockSize - 1)/BlockSize))\r
+ break\r
+ # region not ended yet\r
+ else:\r
+ # region not started in middle of current blocks\r
+ if self.Offset <= Start:\r
+ UsedBlockNum = BlockNum\r
+ # region started in middle of current blocks\r
+ else:\r
+ UsedBlockNum = (End - self.Offset)/BlockSize\r
+ Start = End\r
+ ExpectedList.append((BlockSize, UsedBlockNum))\r
+ RemindingSize -= BlockSize * UsedBlockNum\r
+ \r
+ if FvObj.BlockSizeList == []:\r
+ FvObj.BlockSizeList = ExpectedList\r
+ else:\r
+ # first check whether FvObj.BlockSizeList items have only "BlockSize" or "NumBlocks",\r
+ # if so, use ExpectedList\r
+ for Item in FvObj.BlockSizeList:\r
+ if Item[0] == None or Item[1] == None:\r
+ FvObj.BlockSizeList = ExpectedList\r
+ break\r
+ # make sure region size is no smaller than the summed block size in FV\r
+ Sum = 0\r
+ for Item in FvObj.BlockSizeList:\r
+ Sum += Item[0] * Item[1]\r
+ if self.Size < Sum:\r
+ EdkLogger.error("GenFds", GENFDS_ERROR, "Total Size of FV %s 0x%x is larger than Region Size 0x%x "\r
+ %(FvObj.UiFvName, Sum, self.Size))\r
+ # check whether the BlockStatements in FV section is appropriate\r
+ ExpectedListData = ''\r
+ for Item in ExpectedList:\r
+ ExpectedListData += "BlockSize = 0x%x\n\tNumBlocks = 0x%x\n\t"%Item \r
+ Index = 0\r
+ for Item in FvObj.BlockSizeList:\r
+ if Item[0] != ExpectedList[Index][0]:\r
+ EdkLogger.error("GenFds", GENFDS_ERROR, "BlockStatements of FV %s are not align with FD's, suggested FV BlockStatement"\r
+ %FvObj.UiFvName, ExtraData = ExpectedListData)\r
+ elif Item[1] != ExpectedList[Index][1]:\r
+ if (Item[1] < ExpectedList[Index][1]) and (Index == len(FvObj.BlockSizeList) - 1):\r
+ break;\r
+ else:\r
+ EdkLogger.error("GenFds", GENFDS_ERROR, "BlockStatements of FV %s are not align with FD's, suggested FV BlockStatement"\r
+ %FvObj.UiFvName, ExtraData = ExpectedListData)\r
+ else:\r
+ Index += 1\r
\r
- ## BlockNumOfRegion()\r
- #\r
- # @param BlockSize block size of region\r
- # @retval int Block number of region\r
- #\r
- def BlockNumOfRegion (self, BlockSize):\r
- if BlockSize == 0 :\r
- EdkLogger.error("GenFds", GENFDS_ERROR, "Region: %s is not in the FD address scope!" % self.Offset)\r
- BlockNum = self.Size / BlockSize\r
- GenFdsGlobalVariable.VerboseLogger ("BlockNum = 0x%X" %BlockNum)\r
- return BlockNum\r
+ \r
\r