mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-06-22 05:30:24 +00:00
board_inspector: parse SR-IOV capability structure properly
This patch adds the logic needed to fully parse an SR-IOV extended capability structure. Such information will later be used to extract all information about physical and virtual functions. Tracked-On: #7301 Signed-off-by: Junjie Mao <junjie.mao@intel.com>
This commit is contained in:
parent
0a77891f1c
commit
93ccc0f473
@ -6,6 +6,9 @@
|
||||
import ctypes
|
||||
import copy
|
||||
import inspectorlib.cdata as cdata
|
||||
from .header import MemoryBar32, MemoryBar64, IOBar, \
|
||||
PCIE_BAR_SPACE_MASK, PCIE_BAR_MEMORY_SPACE, PCIE_BAR_IO_SPACE, \
|
||||
PCIE_BAR_TYPE_MASK, PCIE_BAR_TYPE_32_BIT, PCIE_BAR_TYPE_64_BIT
|
||||
|
||||
class ExtendedCapability:
|
||||
# Capability names from PCI Express Base Specification, mostly Table 9-23
|
||||
@ -62,6 +65,11 @@ class ExtendedCapability:
|
||||
else:
|
||||
return f"Reserved Extended ({hex(self.id)})"
|
||||
|
||||
@property
|
||||
def next_cap_ptr(self):
|
||||
# Classes inherit ExtendedCapability must implement the attribute next_cap_ptr_raw
|
||||
return self.next_cap_ptr_raw & 0xffc
|
||||
|
||||
class ExtendedCapabilityListRegister(cdata.Struct, ExtendedCapability):
|
||||
_pack_ = 1
|
||||
_fields_ = [
|
||||
@ -70,12 +78,90 @@ class ExtendedCapabilityListRegister(cdata.Struct, ExtendedCapability):
|
||||
('next_cap_ptr_raw', ctypes.c_uint32, 12),
|
||||
]
|
||||
|
||||
@property
|
||||
def next_cap_ptr(self):
|
||||
return self.next_cap_ptr_raw & 0xffc
|
||||
# SR-IOV (0x10)
|
||||
|
||||
class SRIOVBase(cdata.Struct, ExtendedCapability):
|
||||
_pack_ = 1
|
||||
_fields_ = copy.copy(ExtendedCapabilityListRegister._fields_) + [
|
||||
# SR-IOV Capabilities Register
|
||||
('vf_migration_capable', ctypes.c_uint32, 1),
|
||||
('ari_capable_hierarchy_preserved', ctypes.c_uint32, 1),
|
||||
('vf_10_bit_tag_requester_supported', ctypes.c_uint32, 1),
|
||||
('reserved1', ctypes.c_uint32, 18),
|
||||
('vf_migration_interrupt_message_number', ctypes.c_uint32, 11),
|
||||
|
||||
# SR-IOV Control Register
|
||||
('vf_enable', ctypes.c_uint32, 1),
|
||||
('vf_migration_enable', ctypes.c_uint32, 1),
|
||||
('vf_migration_interrupt_enable', ctypes.c_uint32, 1),
|
||||
('vf_mse', ctypes.c_uint32, 1),
|
||||
('ari_capable_hierarchy', ctypes.c_uint32, 1),
|
||||
('vf_10_bit_tag_requester_enable', ctypes.c_uint32, 1),
|
||||
('reserved2', ctypes.c_uint32, 10),
|
||||
|
||||
# SR-IOV Status Register
|
||||
('vf_migration_status', ctypes.c_uint32, 1),
|
||||
('reserved3', ctypes.c_uint32, 15),
|
||||
|
||||
('initial_vfs', ctypes.c_uint16),
|
||||
('total_vfs', ctypes.c_uint16),
|
||||
('num_vfs', ctypes.c_uint16),
|
||||
('function_dependency_link', ctypes.c_uint8),
|
||||
('reserved4', ctypes.c_uint8),
|
||||
('first_vf_offset', ctypes.c_uint16),
|
||||
('vf_stride', ctypes.c_uint16),
|
||||
('reserved5', ctypes.c_uint16),
|
||||
('vf_device_id', ctypes.c_uint16),
|
||||
|
||||
('supported_page_sizes', ctypes.c_uint32),
|
||||
('system_page_size', ctypes.c_uint32),
|
||||
]
|
||||
|
||||
def SRIOV_factory(addr):
|
||||
vf_bars_list = list()
|
||||
bar_base = addr + ctypes.sizeof(SRIOVBase)
|
||||
bar_addr = bar_base
|
||||
bar_end = bar_base + 0x18
|
||||
while bar_addr < bar_end:
|
||||
bar = ctypes.c_uint32.from_address(bar_addr).value
|
||||
idx = int((bar_addr - bar_base) / 4)
|
||||
if (bar & PCIE_BAR_SPACE_MASK) == PCIE_BAR_MEMORY_SPACE:
|
||||
if (bar & PCIE_BAR_TYPE_MASK) == PCIE_BAR_TYPE_64_BIT:
|
||||
vf_bars_list.append((f"vf_bar{idx}", MemoryBar64))
|
||||
bar_addr += 0x8
|
||||
else:
|
||||
vf_bars_list.append((f"vf_bar{idx}", MemoryBar32))
|
||||
bar_addr += 0x4
|
||||
else:
|
||||
vf_bars_list.append((f"vf_bar{idx}", IOBar))
|
||||
bar_addr += 0x4
|
||||
|
||||
class SRIOV(cdata.Struct, ExtendedCapability):
|
||||
class VFBars(cdata.Struct):
|
||||
_pack_ = 1
|
||||
_fields_ = vf_bars_list
|
||||
|
||||
def __iter__(self):
|
||||
for f in self._fields_:
|
||||
yield getattr(self, f[0])
|
||||
|
||||
_pack_ = 1
|
||||
_fields_ = copy.copy(SRIOVBase._fields_) + [
|
||||
('vf_bars', VFBars),
|
||||
('vf_migration_state_array_offset', ctypes.c_uint32),
|
||||
]
|
||||
|
||||
return SRIOV
|
||||
|
||||
def parse_sriov(buf, cap_ptr):
|
||||
return SRIOV_factory(ctypes.addressof(buf) + cap_ptr).from_buffer_copy(buf, cap_ptr)
|
||||
|
||||
# Module API
|
||||
|
||||
capability_parsers = {
|
||||
0x10: parse_sriov,
|
||||
}
|
||||
|
||||
def extended_capabilities(data):
|
||||
buf = ctypes.create_string_buffer(data, len(data))
|
||||
cap_ptr = 0x100
|
||||
@ -83,7 +169,9 @@ def extended_capabilities(data):
|
||||
acc = list()
|
||||
while cap_ptr != 0:
|
||||
caplist = ExtendedCapabilityListRegister.from_buffer_copy(buf, cap_ptr)
|
||||
if caplist.id != 0:
|
||||
if caplist.id in capability_parsers.keys():
|
||||
acc.append(capability_parsers[caplist.id](buf, cap_ptr))
|
||||
elif caplist.id != 0:
|
||||
acc.append(caplist)
|
||||
cap_ptr = caplist.next_cap_ptr
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user