acrn-hypervisor/misc/config_tools/board_inspector/pcieparser/caps.py
Geoffroy Van Cutsem 8b16be9185 Remove "All rights reserved" string headers
Many of the license and Intel copyright headers include the "All rights
reserved" string. It is not relevant in the context of the BSD-3-Clause
license that the code is released under. This patch removes those strings
throughout the code (hypervisor, devicemodel and misc).

Tracked-On: #7254
Signed-off-by: Geoffroy Van Cutsem <geoffroy.vancutsem@intel.com>
2022-04-06 13:21:02 +08:00

168 lines
4.9 KiB
Python

# Copyright (C) 2021 Intel Corporation.
#
# SPDX-License-Identifier: BSD-3-Clause
#
import ctypes
import copy
import inspectorlib.cdata as cdata
class Capability:
# Capability names from PCI Local Bus Specification and PCI Express Base Specification
_cap_names_ = {
0x01: "Power Management",
0x02: "AGP",
0x03: "VPD",
0x04: "Slot Identification",
0x05: "MSI",
0x06: "CompactPCI Hot Swap",
0x07: "PCI-X",
0x08: "Hyper Transport",
0x09: "Vendor-Specific",
0x0a: "Debug port",
0x0b: "CompactPCI Central Resource Control",
0x0c: "Hot Plug",
0x0d: "Subsystem ID and Subsystem Vendor ID",
0x0e: "AGP 8x",
0x0f: "Secure Device",
0x10: "PCI Express",
0x11: "MSI-X",
0x13: "Conventional PCI Advanced Features",
0x14: "Enhanced Allocation",
0x15: "FPB",
}
@property
def name(self):
if self.id in self._cap_names_.keys():
return self._cap_names_[self.id]
else:
return f"Reserved ({hex(self.id)})"
class CapabilityListRegister(cdata.Struct, Capability):
_pack_ = 1
_fields_ = [
('id', ctypes.c_uint8),
('next_cap_ptr', ctypes.c_uint8),
]
# Power Management (0x01)
class PowerManagement(cdata.Struct, Capability):
_pack_ = 1
_fields_ = copy.copy(CapabilityListRegister._fields_) + [
('version', ctypes.c_uint16, 3),
('pme_clock', ctypes.c_uint16, 1),
('immediate_readiness_on_return_to_d0', ctypes.c_uint16, 1),
('device_specific_initialization', ctypes.c_uint16, 1),
('aux_current', ctypes.c_uint16, 3),
('d1_support', ctypes.c_uint16, 1),
('d2_support', ctypes.c_uint16, 1),
('pme_support', ctypes.c_uint16, 5),
('power_state', ctypes.c_uint16, 2),
('reserved1', ctypes.c_uint16, 1),
('no_soft_reset', ctypes.c_uint16, 1),
('reserved2', ctypes.c_uint16, 4),
('pme_en', ctypes.c_uint16, 1),
('data_select', ctypes.c_uint16, 4),
('data_scale', ctypes.c_uint16, 2),
('pme_status', ctypes.c_uint16, 1),
('reserved3', ctypes.c_uint8, 6),
('undefined', ctypes.c_uint8, 2),
('data', ctypes.c_uint8),
]
def parse_power_management(buf, cap_ptr):
return PowerManagement.from_buffer_copy(buf, cap_ptr)
# MSI (0x05)
def MSI_factory(field_list):
class MSI(cdata.Struct, Capability):
_pack_ = 1
_fields_ = copy.copy(CapabilityListRegister._fields_) + [
('msi_enable', ctypes.c_uint16, 1),
('multiple_message_capable', ctypes.c_uint16, 3),
('multiple_message_enable', ctypes.c_uint16, 3),
('address_64bit', ctypes.c_uint16, 1),
('per_vector_masking_capable', ctypes.c_uint16, 1),
('reserved', ctypes.c_uint16, 7),
] + field_list
return MSI
def msi_field_list(addr):
field_list = list()
msgctrl = MSI_factory([]).from_address(addr)
if msgctrl.address_64bit == 1:
field_list.append(('message_address', ctypes.c_uint64))
else:
field_list.append(('message_address', ctypes.c_uint32))
field_list.append(('message_data', ctypes.c_uint16))
if msgctrl.per_vector_masking_capable:
field_list.append(('reserved', ctypes.c_uint16))
field_list.append(('mask_bits', ctypes.c_uint32))
field_list.append(('pending_bits', ctypes.c_uint32))
return field_list
def parse_msi(buf, cap_ptr):
addr = ctypes.addressof(buf) + cap_ptr
field_list = msi_field_list(addr)
return MSI_factory(field_list).from_buffer_copy(buf, cap_ptr)
# MSI-X (0x11)
class MSIX(cdata.Struct, Capability):
_pack_ = 1
_fields_ = copy.copy(CapabilityListRegister._fields_) + [
('table_size_z', ctypes.c_uint16, 10),
('reserved', ctypes.c_uint16, 3),
('function_mask', ctypes.c_uint16, 1),
('msix_enable', ctypes.c_uint16, 1),
('table_bir', ctypes.c_uint32, 3),
('table_offset_z', ctypes.c_uint32, 29),
('pba_bir', ctypes.c_uint32, 3),
('pba_offset_z', ctypes.c_uint32, 29),
]
@property
def table_size(self):
return self.table_size_z + 1
@property
def table_offset(self):
return self.table_offset_z << 3
@property
def pba_offset(self):
return self.pba_offset_z << 3
def parse_msix(buf, cap_ptr):
return MSIX.from_buffer_copy(buf, cap_ptr)
# Module API
capability_parsers = {
0x1: parse_power_management,
0x5: parse_msi,
0x11: parse_msix,
}
def capabilities(data, cap_ptr):
buf = ctypes.create_string_buffer(data, len(data))
acc = list()
while cap_ptr != 0:
caplist = CapabilityListRegister.from_buffer_copy(buf, cap_ptr)
if caplist.id in capability_parsers.keys():
acc.append(capability_parsers[caplist.id](buf, cap_ptr))
else:
acc.append(caplist)
cap_ptr = caplist.next_cap_ptr
return acc