mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-06-22 21:47:22 +00:00
board_inspector: add GPIO and generic serial connection parsers
GPIO and generic serial connection resources in ACPI resource descriptors usually encode resource sources which are important in detecting cross-device dependencies. This patch adds parsers for GPIO and generic serial connection descriptors. Tracked-On: #6287 Signed-off-by: Junjie Mao <junjie.mao@intel.com>
This commit is contained in:
parent
52c3ed7e09
commit
a2e9a05737
@ -259,7 +259,7 @@ def LargeResourceItemQWordAddressSpace_factory(_len=43):
|
|||||||
] + ([
|
] + ([
|
||||||
('reserved2', ctypes.c_uint8)
|
('reserved2', ctypes.c_uint8)
|
||||||
] if (_len > 43) else []) + ([
|
] if (_len > 43) else []) + ([
|
||||||
('source', ctypes.c_char * (_len - 44))
|
('resource_source_opt', ctypes.c_char * (_len - 44))
|
||||||
] if (_len > 44) else [])
|
] if (_len > 44) else [])
|
||||||
_formats = {
|
_formats = {
|
||||||
'_TYP': unpack.format_table("{}", resource_type),
|
'_TYP': unpack.format_table("{}", resource_type),
|
||||||
@ -267,6 +267,11 @@ def LargeResourceItemQWordAddressSpace_factory(_len=43):
|
|||||||
'_MIF': unpack.format_table("{}", min_address_fixed),
|
'_MIF': unpack.format_table("{}", min_address_fixed),
|
||||||
'_MAF': unpack.format_table("{}", max_address_fixed),
|
'_MAF': unpack.format_table("{}", max_address_fixed),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@property
|
||||||
|
def resource_source(self):
|
||||||
|
return getattr(self, "resource_source_opt", None)
|
||||||
|
|
||||||
return LargeResourceItemQWordAddressSpace
|
return LargeResourceItemQWordAddressSpace
|
||||||
|
|
||||||
# 6.4.3.5.2 DWord Address Space Descriptor
|
# 6.4.3.5.2 DWord Address Space Descriptor
|
||||||
@ -290,7 +295,7 @@ def LargeResourceItemDWordAddressSpace_factory(_len=23):
|
|||||||
] + ([
|
] + ([
|
||||||
('reserved2', ctypes.c_uint8)
|
('reserved2', ctypes.c_uint8)
|
||||||
] if (_len > 23) else []) + ([
|
] if (_len > 23) else []) + ([
|
||||||
('source', ctypes.c_char * (_len - 24))
|
('resource_source_opt', ctypes.c_char * (_len - 24))
|
||||||
] if (_len > 24) else [])
|
] if (_len > 24) else [])
|
||||||
_formats = {
|
_formats = {
|
||||||
'_TYP': unpack.format_table("{}", resource_type),
|
'_TYP': unpack.format_table("{}", resource_type),
|
||||||
@ -298,6 +303,11 @@ def LargeResourceItemDWordAddressSpace_factory(_len=23):
|
|||||||
'_MIF': unpack.format_table("{}", min_address_fixed),
|
'_MIF': unpack.format_table("{}", min_address_fixed),
|
||||||
'_MAF': unpack.format_table("{}", max_address_fixed),
|
'_MAF': unpack.format_table("{}", max_address_fixed),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@property
|
||||||
|
def resource_source(self):
|
||||||
|
return getattr(self, "resource_source_opt", None)
|
||||||
|
|
||||||
return LargeResourceItemDWordAddressSpace
|
return LargeResourceItemDWordAddressSpace
|
||||||
|
|
||||||
# 6.4.3.5.3 Word Address Space Descriptor
|
# 6.4.3.5.3 Word Address Space Descriptor
|
||||||
@ -321,7 +331,7 @@ def LargeResourceItemWordAddressSpace_factory(_len=13):
|
|||||||
] + ([
|
] + ([
|
||||||
('reserved2', ctypes.c_uint8)
|
('reserved2', ctypes.c_uint8)
|
||||||
] if (_len > 13) else []) + ([
|
] if (_len > 13) else []) + ([
|
||||||
('source', ctypes.c_char * (_len - 14))
|
('resource_source_opt', ctypes.c_char * (_len - 14))
|
||||||
] if (_len > 14) else [])
|
] if (_len > 14) else [])
|
||||||
_formats = {
|
_formats = {
|
||||||
'_TYP': unpack.format_table("{}", resource_type),
|
'_TYP': unpack.format_table("{}", resource_type),
|
||||||
@ -329,6 +339,11 @@ def LargeResourceItemWordAddressSpace_factory(_len=13):
|
|||||||
'_MIF': unpack.format_table("{}", min_address_fixed),
|
'_MIF': unpack.format_table("{}", min_address_fixed),
|
||||||
'_MAF': unpack.format_table("{}", max_address_fixed),
|
'_MAF': unpack.format_table("{}", max_address_fixed),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@property
|
||||||
|
def resource_source(self):
|
||||||
|
return getattr(self, "resource_source_opt", None)
|
||||||
|
|
||||||
return LargeResourceItemWordAddressSpace
|
return LargeResourceItemWordAddressSpace
|
||||||
|
|
||||||
# 6.4.3.5.4 Extended Address Space Descriptor
|
# 6.4.3.5.4 Extended Address Space Descriptor
|
||||||
@ -361,14 +376,15 @@ class LargeResourceItemExtendedAddressSpace(cdata.Struct):
|
|||||||
|
|
||||||
# 6.4.3.6 Extended Interrupt Descriptor
|
# 6.4.3.6 Extended Interrupt Descriptor
|
||||||
|
|
||||||
class LargeResourceItemExtendedInterruptHeader(cdata.Struct):
|
def LargeResourceItemExtendedInterrupt_factory(_addr):
|
||||||
|
class LargeResourceItemExtendedInterruptLayout(cdata.Struct):
|
||||||
_pack_ = 1
|
_pack_ = 1
|
||||||
_fields_ = LargeResourceDataTag._fields_ + [
|
_fields_ = LargeResourceDataTag._fields_ + [
|
||||||
('flags', ctypes.c_uint8),
|
('flags', ctypes.c_uint8),
|
||||||
('_LEN', ctypes.c_uint8),
|
('_LEN', ctypes.c_uint8),
|
||||||
]
|
]
|
||||||
|
|
||||||
def LargeResourceItemExtendedInterrupt_factory(_len, _it_len):
|
def aux(layout):
|
||||||
class LargeResourceItemExtendedInterrupt(cdata.Struct):
|
class LargeResourceItemExtendedInterrupt(cdata.Struct):
|
||||||
_pack_ = 1
|
_pack_ = 1
|
||||||
_fields_ = LargeResourceDataTag._fields_ + [
|
_fields_ = LargeResourceDataTag._fields_ + [
|
||||||
@ -379,14 +395,21 @@ def LargeResourceItemExtendedInterrupt_factory(_len, _it_len):
|
|||||||
('_WKC', ctypes.c_uint8, 1),
|
('_WKC', ctypes.c_uint8, 1),
|
||||||
('reserved1', ctypes.c_uint8, 3),
|
('reserved1', ctypes.c_uint8, 3),
|
||||||
('_LEN', ctypes.c_uint8),
|
('_LEN', ctypes.c_uint8),
|
||||||
('_INT', ctypes.c_uint32 * _it_len),
|
('_INT', ctypes.c_uint32 * layout._LEN),
|
||||||
] + ([
|
] + ([
|
||||||
('reserved2', ctypes.c_uint8),
|
('reserved2', ctypes.c_uint8),
|
||||||
] if (_len > 2 + _it_len * 4) else []) + ([
|
] if (layout.length > 2 + layout._LEN * 4) else []) + ([
|
||||||
('source', ctypes.c_char * (_len - _it_len * 4 - 3))
|
('resource_source_opt', ctypes.c_char * (layout.length - layout._LEN * 4 - 3))
|
||||||
] if (_len > 2 + _it_len * 4 + 1) else [])
|
] if (layout.length > 2 + layout._LEN * 4 + 1) else [])
|
||||||
|
|
||||||
|
@property
|
||||||
|
def resource_source(self):
|
||||||
|
return getattr(self, "resource_source_opt", None)
|
||||||
|
|
||||||
return LargeResourceItemExtendedInterrupt
|
return LargeResourceItemExtendedInterrupt
|
||||||
|
|
||||||
|
return aux(LargeResourceItemExtendedInterruptLayout.from_address(_addr))
|
||||||
|
|
||||||
# 6.4.3.7 Generic Register Descriptor
|
# 6.4.3.7 Generic Register Descriptor
|
||||||
|
|
||||||
class LargeResourceItemGenericRegister(cdata.Struct):
|
class LargeResourceItemGenericRegister(cdata.Struct):
|
||||||
@ -399,31 +422,108 @@ class LargeResourceItemGenericRegister(cdata.Struct):
|
|||||||
('_ADR', ctypes.c_uint64),
|
('_ADR', ctypes.c_uint64),
|
||||||
]
|
]
|
||||||
|
|
||||||
# 6.4.3.8.1 GPIO Connection Descriptor (TODO)
|
# 6.4.3.8.1 GPIO Connection Descriptor
|
||||||
|
|
||||||
|
def LargeResourceItemGPIOConnection_factory(_addr):
|
||||||
|
class LargeResourceItemGPIOConnectionLayout(cdata.Struct):
|
||||||
|
_pack_ = 1
|
||||||
|
_fields_ = LargeResourceDataTag._fields_ + [
|
||||||
|
('revision_id', ctypes.c_uint8),
|
||||||
|
('connection_type', ctypes.c_uint8),
|
||||||
|
# Byte 5 to 13 (both inclusive) are not involved in detecting the layout of the descriptor
|
||||||
|
('data1', ctypes.c_uint8 * 9),
|
||||||
|
('pin_table_offset', ctypes.c_uint16),
|
||||||
|
('data2', ctypes.c_uint8),
|
||||||
|
('resource_source_name_offset', ctypes.c_uint16),
|
||||||
|
('vendor_data_offset', ctypes.c_uint16),
|
||||||
|
('vendor_data_length', ctypes.c_uint16),
|
||||||
|
]
|
||||||
|
|
||||||
|
def aux(layout):
|
||||||
|
if layout.connection_type == 0: # Interrupt connection
|
||||||
|
interrupt_and_io_flags_fields = [
|
||||||
|
('_MOD', ctypes.c_uint16, 1),
|
||||||
|
('_POL', ctypes.c_uint16, 2),
|
||||||
|
('_SHR', ctypes.c_uint16, 1),
|
||||||
|
('_WKC', ctypes.c_uint16, 1),
|
||||||
|
('reserved2', ctypes.c_uint16, 11),
|
||||||
|
]
|
||||||
|
elif layout.connection_type == 1: # I/O connection
|
||||||
|
interrupt_and_io_flags_fields = [
|
||||||
|
('_IOR', ctypes.c_uint16, 1),
|
||||||
|
('reserved2_1', ctypes.c_uint16, 2),
|
||||||
|
('_SHR', ctypes.c_uint16, 1),
|
||||||
|
('reserved2_2', ctypes.c_uint16, 12),
|
||||||
|
]
|
||||||
|
else:
|
||||||
|
interrupt_and_io_flags_fields = [('interrupt_and_io_flags', ctypes.c_uint16)]
|
||||||
|
|
||||||
|
pre_pin_table_length = layout.pin_table_offset - 23
|
||||||
|
pin_count = (layout.resource_source_name_offset - layout.pin_table_offset) // 2
|
||||||
|
resource_source_name_length = layout.vendor_data_offset - layout.resource_source_name_offset
|
||||||
|
|
||||||
def LargeResourceItemGPIOConnection_factory(_len):
|
|
||||||
class LargeResourceItemGPIOConnection(cdata.Struct):
|
class LargeResourceItemGPIOConnection(cdata.Struct):
|
||||||
_pack_ = 1
|
_pack_ = 1
|
||||||
_fields_ = LargeResourceDataTag._fields_ + [
|
_fields_ = LargeResourceDataTag._fields_ + [
|
||||||
('_REV', ctypes.c_uint8),
|
('revision_id', ctypes.c_uint8),
|
||||||
('_TYP', ctypes.c_uint8),
|
('connection_type', ctypes.c_uint8),
|
||||||
('data', ctypes.c_uint8 * (_len - 2)),
|
('consumer_producer', ctypes.c_uint16, 1),
|
||||||
]
|
('reserved1', ctypes.c_uint16, 15),
|
||||||
|
] + interrupt_and_io_flags_fields + [
|
||||||
|
('_PPI', ctypes.c_uint8),
|
||||||
|
('_DRS', ctypes.c_uint16),
|
||||||
|
('_DBT', ctypes.c_uint16),
|
||||||
|
('pin_table_offset', ctypes.c_uint16),
|
||||||
|
('resource_source_index', ctypes.c_uint8),
|
||||||
|
('resource_source_name_offset', ctypes.c_uint16),
|
||||||
|
('vendor_data_offset', ctypes.c_uint16),
|
||||||
|
('vendor_data_length', ctypes.c_uint16),
|
||||||
|
] + ([
|
||||||
|
('reserved3', ctypes.c_uint8 * pre_pin_table_length),
|
||||||
|
] if pre_pin_table_length > 0 else []) + [
|
||||||
|
('pin_numbers', ctypes.c_uint16 * pin_count),
|
||||||
|
('resource_source', ctypes.c_char * resource_source_name_length)
|
||||||
|
] + ([
|
||||||
|
('_VEN', ctypes.c_uint8 * layout.vendor_data_length)
|
||||||
|
] if layout.vendor_data_length > 0 else [])
|
||||||
|
|
||||||
return LargeResourceItemGPIOConnection
|
return LargeResourceItemGPIOConnection
|
||||||
|
|
||||||
# 6.4.3.8.2 GenericSerialBus Connection Descriptors (TODO)
|
return aux(LargeResourceItemGPIOConnectionLayout.from_address(_addr))
|
||||||
|
|
||||||
def LargeResourceItemGenericSerialBusConnection_factory(_len):
|
# 6.4.3.8.2 GenericSerialBus Connection Descriptors
|
||||||
|
|
||||||
|
def LargeResourceItemGenericSerialBusConnection_factory(_addr):
|
||||||
|
class LargeResourceItemGenericSerialBusConnectionLayout(cdata.Struct):
|
||||||
|
_pack_ = 1
|
||||||
|
_fields_ = LargeResourceDataTag._fields_ + [
|
||||||
|
# Byte 3 to 9 (both inclusive) are not involved in detecting the layout of the descriptor
|
||||||
|
('data', ctypes.c_uint8 * 7),
|
||||||
|
('type_data_length', ctypes.c_uint16),
|
||||||
|
]
|
||||||
|
|
||||||
|
def aux(layout):
|
||||||
class LargeResourceItemGenericSerialBusConnection(cdata.Struct):
|
class LargeResourceItemGenericSerialBusConnection(cdata.Struct):
|
||||||
_pack_ = 1
|
_pack_ = 1
|
||||||
_fields_ = LargeResourceDataTag._fields_ + [
|
_fields_ = LargeResourceDataTag._fields_ + [
|
||||||
('_REV', ctypes.c_uint8),
|
('revision_id', ctypes.c_uint8),
|
||||||
('_RSI', ctypes.c_uint8),
|
('resource_source_index', ctypes.c_uint8),
|
||||||
('_TYP', ctypes.c_uint8),
|
('serial_bus_type', ctypes.c_uint8),
|
||||||
('data', ctypes.c_uint8 * (_len - 3)),
|
('_SLV', ctypes.c_uint8, 1),
|
||||||
|
('consumer_producer', ctypes.c_uint8, 1),
|
||||||
|
('_SHR', ctypes.c_uint8, 1),
|
||||||
|
('reserved', ctypes.c_uint8, 5),
|
||||||
|
('type_specific_flags', ctypes.c_uint16),
|
||||||
|
('type_specific_revision_id', ctypes.c_uint8),
|
||||||
|
('type_data_length', ctypes.c_uint16),
|
||||||
|
('type_specific_data', ctypes.c_uint8 * layout.type_data_length),
|
||||||
|
('resource_source', ctypes.c_char * (layout.length - 9 - layout.type_data_length)),
|
||||||
]
|
]
|
||||||
|
|
||||||
return LargeResourceItemGenericSerialBusConnection
|
return LargeResourceItemGenericSerialBusConnection
|
||||||
|
|
||||||
|
return aux(LargeResourceItemGenericSerialBusConnectionLayout.from_address(_addr))
|
||||||
|
|
||||||
# 6.4.3.9 Pin Function Descriptor
|
# 6.4.3.9 Pin Function Descriptor
|
||||||
|
|
||||||
def LargeResourceItemPinFunction_factory(_len):
|
def LargeResourceItemPinFunction_factory(_len):
|
||||||
@ -573,18 +673,17 @@ def rdt_item_list(addr, length):
|
|||||||
elif tag.name == LARGE_RESOURCE_ITEM_WORD_ADDRESS_SPACE:
|
elif tag.name == LARGE_RESOURCE_ITEM_WORD_ADDRESS_SPACE:
|
||||||
cls = LargeResourceItemWordAddressSpace_factory(tag.length)
|
cls = LargeResourceItemWordAddressSpace_factory(tag.length)
|
||||||
elif tag.name == LARGE_RESOURCE_ITEM_EXTENDED_INTERRUPT:
|
elif tag.name == LARGE_RESOURCE_ITEM_EXTENDED_INTERRUPT:
|
||||||
hdr = LargeResourceItemExtendedInterruptHeader.from_address(addr)
|
cls = LargeResourceItemExtendedInterrupt_factory(addr)
|
||||||
cls = LargeResourceItemExtendedInterrupt_factory(tag.length, hdr._LEN)
|
|
||||||
elif tag.name == LARGE_RESOURCE_ITEM_QWORD_ADDRESS_SPACE:
|
elif tag.name == LARGE_RESOURCE_ITEM_QWORD_ADDRESS_SPACE:
|
||||||
cls = LargeResourceItemQWordAddressSpace_factory(tag.length)
|
cls = LargeResourceItemQWordAddressSpace_factory(tag.length)
|
||||||
elif tag.name == LARGE_RESOURCE_ITEM_EXTENDED_ADDRESS_SPACE:
|
elif tag.name == LARGE_RESOURCE_ITEM_EXTENDED_ADDRESS_SPACE:
|
||||||
cls = LargeResourceItemExtendedAddressSpace
|
cls = LargeResourceItemExtendedAddressSpace
|
||||||
elif tag.name == LARGE_RESOURCE_ITEM_GPIO_CONNECTION:
|
elif tag.name == LARGE_RESOURCE_ITEM_GPIO_CONNECTION:
|
||||||
cls = LargeResourceItemGPIOConnection_factory(tag.length)
|
cls = LargeResourceItemGPIOConnection_factory(addr)
|
||||||
elif tag.name == LARGE_RESOURCE_ITEM_PIN_FUNCTION:
|
elif tag.name == LARGE_RESOURCE_ITEM_PIN_FUNCTION:
|
||||||
cls = LargeResourceItemPinFunction_factory(tag.length)
|
cls = LargeResourceItemPinFunction_factory(tag.length)
|
||||||
elif tag.name == LARGE_RESOURCE_ITEM_GENERIC_SERIAL_BUS_CONNECTION:
|
elif tag.name == LARGE_RESOURCE_ITEM_GENERIC_SERIAL_BUS_CONNECTION:
|
||||||
cls = LargeResourceItemGenericSerialBusConnection_factory(tag.length)
|
cls = LargeResourceItemGenericSerialBusConnection_factory(addr)
|
||||||
elif tag.name == LARGE_RESOURCE_ITEM_PIN_CONFIGURATION:
|
elif tag.name == LARGE_RESOURCE_ITEM_PIN_CONFIGURATION:
|
||||||
cls = LargeResourceItemPinConfiguration_factory(tag.length)
|
cls = LargeResourceItemPinConfiguration_factory(tag.length)
|
||||||
elif tag.name == LARGE_RESOURCE_ITEM_PIN_GROUP:
|
elif tag.name == LARGE_RESOURCE_ITEM_PIN_GROUP:
|
||||||
|
Loading…
Reference in New Issue
Block a user