Adjust GPIO CFGDATA structure header

This patch added additional information in the GPIO CFGDATA header
structure so that the full GPIO info can be extracted out later on
by tool. This additional information including GPIO SKIP bit position,
GPIO ID position and length.

Signed-off-by: Maurice Ma <maurice.ma@intel.com>
This commit is contained in:
Maurice Ma 2019-11-20 16:28:24 -08:00
parent 3a932bdf0a
commit ace9d98eb8
5 changed files with 84 additions and 29 deletions

View File

@ -171,8 +171,10 @@ class CCfgData:
('BasePlatformId', c_uint8),
('ItemSize', c_uint16),
('ItemCount', c_uint16),
('ItemValidByteOffset', c_uint8),
('ItemValidByteMask', c_uint8),
('ItemIdBitOff', c_uint8),
('ItemIdBitLen', c_uint8),
('ItemValidBitOff', c_uint8),
('ItemUnused', c_uint8),
]
def __init__ (self):
@ -231,7 +233,7 @@ class CCfgData:
PrintByteArray (CfgData[2], Indent = 5)
else:
Offset = 0
DataOffset = CCfgData.CDATA_ITEM_ARRAY.ItemValidByteOffset.offset
DataOffset = sizeof(CCfgData.CDATA_ITEM_ARRAY)
BitMaskLen = ArrayInfo.HeaderSize - DataOffset
print(" ARRAY HEADER:")
PrintByteArray (CfgData[2][:DataOffset], Indent = 5, Offset=Offset)
@ -283,7 +285,7 @@ class CCfgData:
"Invalid array item count/size field in TAG '0x%03X'!" %
Header.Tag)
BitMaskLen = ArrayInfo.HeaderSize - CCfgData.CDATA_ITEM_ARRAY.ItemValidByteOffset.offset
BitMaskLen = ArrayInfo.HeaderSize - sizeof (ArrayInfo)
ByteWidth = (ArrayInfo.ItemCount + 7) // 8
if ByteWidth < 2:
ByteWidth = 2
@ -295,8 +297,8 @@ class CCfgData:
BitMaskDat = bytearray('1' * ArrayInfo.ItemCount + '0' *
(BitMaskLen * 8 - ArrayInfo.ItemCount), 'utf-8')
ItemValidByteOffset = ArrayInfo.ItemValidByteOffset
ItemValidByteMask = ArrayInfo.ItemValidByteMask
ItemValidByteOffset = ArrayInfo.ItemValidBitOff // 8
ItemValidByteMask = 1 << (ArrayInfo.ItemValidBitOff & (8 - 1))
DataOff = ArrayInfo.HeaderSize
ArrayTagKey = '%03X' % Header.Tag
@ -336,12 +338,20 @@ class CCfgData:
self.CfgDataArrayPidDict[ArrayTagKey] = self.CfgDataPid[CfgBinFile]
# Check the invliad flag and remove those items
ItemDict = {}
RemovedItem = 0
Index = 0
DataLen = len(Data)
while DataOff < DataLen:
Remove = False
if ArrayInfo.BasePlatformId == 0x80:
# Check ItemID to make sure it is unique
ItemId = get_bits_from_bytes (Data[DataOff:DataOff + ArrayInfo.ItemSize], ArrayInfo.ItemIdBitOff, ArrayInfo.ItemIdBitLen)
if ItemId not in ItemDict.keys():
ItemDict[ItemId] = 1
else:
raise Exception("ItemId '0x%X' is not unique indicated by ItemIdBitOff/ItemIdBitLen in array header !" % ItemId)
# It is a base table, remove marker and assemble mask
if Data[DataOff + ItemValidByteOffset] & ItemValidByteMask:
Data[DataOff + ItemValidByteOffset] = Data[
@ -372,7 +382,7 @@ class CCfgData:
BitWidth = BitMaskLen * 8
MaskHexStr = '{0:0{w}x}'.format(int(BitMaskDat.decode()[::-1], 2), w=BitWidth // 4)
BinData = bytearray.fromhex(MaskHexStr)[::-1]
Offset = CCfgData.CDATA_ITEM_ARRAY.ItemValidByteOffset.offset
Offset = sizeof (CCfgData.CDATA_ITEM_ARRAY)
Data[Offset:Offset + BitMaskLen] = BinData
return DataLen

View File

@ -61,6 +61,26 @@ AUTH_TYPE_HASH_VALUE = {
"RSA3072SHA384" : 1,
}
def get_bits_from_bytes (bytes, start, length):
value = bytes_to_value (bytes)
bitlen = 8 * len(bytes)
fmt = "{0:0%db}" % bitlen
start = bitlen - start
if start < 0 or start < length:
raise Exception ('Invalid bit start and length !')
bval = fmt.format(value)[start - length : start]
return int (bval, 2)
def set_bits_to_bytes (bytes, start, length, bvalue):
value = bytes_to_value (bytes)
bitlen = 8 * len(bytes)
fmt1 = "{0:0%db}" % bitlen
fmt2 = "{0:0%db}" % length
oldval = fmt1.format(value)[::-1]
update = fmt2.format(bvalue)[-length:][::-1]
newval = oldval[:start] + update + oldval[start + length:]
bytes[:] = value_to_bytes (int(newval[::-1], 2), len(bytes))
def bytes_to_value (bytes):
return reduce(lambda x,y: (x<<8)|y, bytes[::-1] )

View File

@ -19,14 +19,28 @@
gCfgData.GpioBaseTableId | * | 0x01 | 0xFF
gCfgData.GpioItemSize | * | 0x02 | 8
gCfgData.GpioItemCount | * | 0x02 | (_LENGTH_GPIO_CFG_DATA_ - _LENGTH_GPIO_CFG_HDR_) / 8
gCfgData.GpioBaseTableBitMask | * | 38 | {3, 0x80}
# Bit start offset within each GPIO entry array to identify a GPIO pin uniquely. EX: GPIO group id + pad id
# Offset is 1st DWORD BIT0 = 0
gCfgData.GpioItemIdBitOff | * | 0x01 | 0
# Bit length within each GPIO entry array to identify a GPIO pin uniquely.
# Length is 1st DWORD BIT0 to BIT23 = 24
gCfgData.GpioItemIdBitLen | * | 0x01 | 24
# Bit offset within each GPIO entry array to indicate SKIP a GPIO programming
# Offset is 1st DWORD BIT31 = 31
gCfgData.GpioItemValidBitOff | * | 0x01 | 31
gCfgData.GpioItemUnused | * | 0x01 | 0
# Need 1 bit per GPIO. So this mask byte length needs to be at least (GpioNumber + 7) / 8
# Padding can be added to let the whole length aligned at DWORD boundary
gCfgData.GpioBaseTableBitMask | * | 38 | {0}
gCfgData.GpioTableData | * | 0 | 0
# !HDR EMBED:{GPIO_CFG_HDR:GpioCfgHdr:END}
# !HDR HEADER:{OFF}
# !BSF SUBT:{GPIO_TMPL:GPIO_0 :0x000500c5 :0x1d008008}
# !BSF SUBT:{GPIO_TMPL:GPIO_1 :0x000508c5 :0x1d008008}
# !BSF SUBT:{GPIO_TMPL:GPIO_2 :0x000510c5 :0x1d008008}
@ -36,7 +50,7 @@
# !BSF SUBT:{GPIO_TMPL:GPIO_6 :0x000530c5 :0x1d008008}
# !BSF SUBT:{GPIO_TMPL:GPIO_7 :0x000538c5 :0x1d008008}
# !BSF SUBT:{GPIO_TMPL:GPIO_8 :0x000540c5 :0x1d008008}
# !BSF SUBT:{GPIO_TMPL:GPIO_9 :0x000548c5 :0x01008008}
# !BSF SUBT:{GPIO_TMPL:GPIO_9 :0x000548c5 :0x01008008}
# !BSF SUBT:{GPIO_TMPL:GPIO_10 :0x000550c5 :0xa5001202}
# !BSF SUBT:{GPIO_TMPL:GPIO_11 :0x000558c5 :0x01008008}
# !BSF SUBT:{GPIO_TMPL:GPIO_12 :0x000560c5 :0x81008008}

View File

@ -17,14 +17,21 @@
gCfgData.GpioBaseTableId | * | 0x01 | 0xFF
gCfgData.GpioItemSize | * | 0x02 | 8
gCfgData.GpioItemCount | * | 0x02 | (_LENGTH_GPIO_CFG_DATA_ - _LENGTH_GPIO_CFG_HDR_) / 8
# Initial value is GpioValidByteOffset (bit 31 in PAD Cfg DW2) and GpioValidByteMask (0x80) in GpioBaseTableBitMask[0] and [1]
# CfgDataTool will check each GPIO table data for:
# *(UINT8 *)(GpioEntryData + GpioValidByteOffset) & GpioValidByteMask
# Ex: (GPIO DW2 >> 24) & 0x80 == if set, skip it. if 0, include it in BCT
# If the value is non-zero, a GPIO programming should be skipped.
# The CfgDataTool tool will mark a bit in GpioBaseTableBitMask array to indicate a particular GPIO should be skipped or not.
# Length = 26 because we need 1 bit per GPIO entry. If there are 165 GPIOs in the below list. So 165/8 = 21 bytes needed. Reserve 26 for future GPIO pins addition
gCfgData.GpioBaseTableBitMask | * | 34 | {7, 0x80} #7 is byte offset 7 within the 34 bytes array. 0x80 is the byte mask to indicate if the GPIO pin is used or not.
# Bit start offset within each GPIO entry array to identify a GPIO pin uniquely. EX: GPIO group id + pad id
# Offset is 2nd DWORD BIT16 = 1 * 32 + 16 = 48
gCfgData.GpioItemIdBitOff | * | 0x01 | 48
# Bit length within each GPIO entry array to identify a GPIO pin uniquely.
# Length is 2nd DWORD BIT16 to BIT28 = 13
gCfgData.GpioItemIdBitLen | * | 0x01 | 13
# Bit offset within each GPIO entry array to indicate SKIP a GPIO programming
# Offset is 2nd DWORD BIT31 = 63
gCfgData.GpioItemValidBitOff | * | 0x01 | 63
gCfgData.GpioItemUnused | * | 0x01 | 0
# Need 1 bit per GPIO. So this mask byte length needs to be at least (GpioNumber + 7) / 8
# Padding can be added to let the whole length aligned at DWORD boundary
gCfgData.GpioBaseTableBitMask | * | 34 | {0}
gCfgData.GpioTableData | * | 0 | 0
# !HDR EMBED:{GPIO_CFG_HDR:GpioCfgHdr:END}
@ -291,7 +298,7 @@
# !BSF SUBT:{GPIO_TMPL:GPP_d09: 0x07502283: 0x8B092001: N/A : N/A : N/A : N/A}
# !BSF SUBT:{GPIO_TMPL:GPP_d10: 0x07502283: 0x8B0A2001: N/A : N/A : N/A : N/A}
# !BSF SUBT:{GPIO_TMPL:GPP_d11: 0x07502283: 0x8B0B2001: N/A : N/A : N/A : N/A}
# !BSF SUBT:{GPIO_TMPL:GPP_PEC: 0x00000000: 0x80000000: N/A : N/A : N/A : N/A}
# !BSF SUBT:{GPIO_TMPL:GPP_PEC: 0x00000000: 0x8C040009: N/A : N/A : N/A : N/A}
# !HDR EMBED:{GPIO_CFG_DATA:TAG_400:END}

View File

@ -25,16 +25,20 @@
# !BSF NAME:{ } HELP:{GPIO count in the table} TYPE:{Reserved}
gCfgData.GpioItemCount | * | 0x02 | (_LENGTH_GPIO_CFG_DATA_ - _LENGTH_GPIO_CFG_HDR_) / (_OFFSET_GPIO_DATA_GPP_A1_ - _OFFSET_GPIO_DATA_GPP_A0_)
# Initial value is GpioValidByteOffset (bit 31 in PAD Cfg DW2) and GpioValidByteMask (0x80) in GpioBaseTableBitMask[0] and [1]
# CfgDataTool will check each GPIO table data for:
# *(UINT8 *)(GpioEntryData + GpioValidByteOffset) & GpioValidByteMask
# Ex: (GPIO DW1 >> 24) & 0x80 == if set, skip it. if 0, include this GPIO
# If the value is non-zero, a GPIO programming should be skipped.
# The CfgDataTool tool will mark a bit in GpioBaseTableBitMask array to indicate a particular GPIO should be skipped or not.
# Length = Need 1 bit per GPIO entry. There are 8 GPIOs in the below list.
# So 8/8 = 1 bytes needed. Minimum it needs 2 bytes. So reserve 2.
# !BSF NAME:{ } HELP:{GPIO bit mask for base table} TYPE:{Reserved}
gCfgData.GpioBaseTableBitMask | * | 2 | {7, 0x80} #7 is byte offset 7 within the each GPIO bytes array. 0x80 is the byte mask to indicate if the GPIO pin is used or not.
# Bit start offset within each GPIO entry array to identify a GPIO pin uniquely. EX: GPIO pin id
# Offset is 2nd DWORD BIT0 = 1 * 32 + 0 = 32
gCfgData.GpioItemIdBitOff | * | 0x01 | 32
# Bit length within each GPIO entry array to identify a GPIO pin uniquely.
# Length is 2nd DWORD BIT0 to BIT15 = 16
gCfgData.GpioItemIdBitLen | * | 0x01 | 16
# Bit offset within each GPIO entry array to indicate SKIP a GPIO programming
# Offset is 2nd DWORD BIT31 = 63
gCfgData.GpioItemValidBitOff | * | 0x01 | 63
gCfgData.GpioItemUnused | * | 0x01 | 0
# Need 1 bit per GPIO. So this mask byte length needs to be at least (GpioNumber + 7) / 8
# Padding can be added to let the whole length aligned at DWORD boundary
gCfgData.GpioBaseTableBitMask | * | 2 | {0}
gCfgData.GpioTableData | * | 0 | 0
# !HDR EMBED:{GPIO_CFG_HDR:GpioCfgHdr:END}