mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-04-28 19:54:01 +00:00
1. "make clean && make BOARD=nuc11tnbi5 SCENARIO=shared" will generate the acrn debian package. 2. "make clean && make board_inspector" will generate the acrn board_inspector debian package Tracked-On: #6688 Signed-off-by: Hu Fenglin <fenglin.hu@intel.com>
190 lines
5.8 KiB
Python
190 lines
5.8 KiB
Python
# Copyright (C) 2021 Intel Corporation. All rights reserved.
|
|
#
|
|
# SPDX-License-Identifier: BSD-3-Clause
|
|
#
|
|
|
|
import ctypes
|
|
import copy
|
|
import inspectorlib.cdata as cdata
|
|
|
|
class Common(cdata.Struct):
|
|
_pack_ = 1
|
|
_fields_ = [
|
|
('vendor_id', ctypes.c_uint16),
|
|
('device_id', ctypes.c_uint16),
|
|
('command', ctypes.c_uint16),
|
|
('status', ctypes.c_uint16),
|
|
('revision_id', ctypes.c_uint32, 8),
|
|
('class_code', ctypes.c_uint32, 24),
|
|
('cacheline_size', ctypes.c_uint8),
|
|
('latency_timer', ctypes.c_uint8),
|
|
('header_type', ctypes.c_uint8, 7),
|
|
('multi_function', ctypes.c_uint8, 1),
|
|
('bist', ctypes.c_uint8),
|
|
]
|
|
|
|
class MemoryBar32(cdata.Struct):
|
|
_pack_ = 1
|
|
_fields_ = [
|
|
('indicator', ctypes.c_uint8, 1),
|
|
('type', ctypes.c_uint8, 2),
|
|
('prefetchable', ctypes.c_uint8, 1),
|
|
('base_z', ctypes.c_uint32, 28),
|
|
]
|
|
|
|
resource_type = "memory"
|
|
|
|
@property
|
|
def base(self):
|
|
return self.base_z << 4
|
|
|
|
class MemoryBar64(cdata.Struct):
|
|
_pack_ = 1
|
|
_fields_ = [
|
|
('indicator', ctypes.c_uint8, 1),
|
|
('type', ctypes.c_uint8, 2),
|
|
('prefetchable', ctypes.c_uint8, 1),
|
|
('base_z', ctypes.c_uint64, 60),
|
|
]
|
|
|
|
resource_type = "memory"
|
|
|
|
@property
|
|
def base(self):
|
|
return self.base_z << 4
|
|
|
|
class IOBar(cdata.Struct):
|
|
_pack_ = 1
|
|
_fields_ = [
|
|
('indicator', ctypes.c_uint8, 1),
|
|
('reserved', ctypes.c_uint8, 1),
|
|
('base_z', ctypes.c_uint32, 30),
|
|
]
|
|
|
|
resource_type = "io_port"
|
|
|
|
@property
|
|
def base(self):
|
|
return self.base_z << 2
|
|
|
|
PCIE_BAR_SPACE_MASK = 0x1
|
|
PCIE_BAR_MEMORY_SPACE = 0x0
|
|
PCIE_BAR_IO_SPACE = 0x1
|
|
|
|
PCIE_BAR_TYPE_MASK = 0x6
|
|
PCIE_BAR_TYPE_32_BIT = 0x0
|
|
PCIE_BAR_TYPE_64_BIT = 0x4
|
|
|
|
def header_type_0_field_list(addr):
|
|
bar_list = list()
|
|
bar_addr = addr
|
|
bar_end = addr + 0x18
|
|
while bar_addr < bar_end:
|
|
bar = ctypes.c_uint32.from_address(bar_addr).value
|
|
idx = int((bar_addr - addr) / 4)
|
|
if (bar & PCIE_BAR_SPACE_MASK) == PCIE_BAR_MEMORY_SPACE:
|
|
if (bar & PCIE_BAR_TYPE_MASK) == PCIE_BAR_TYPE_64_BIT:
|
|
bar_list.append((f"bar{idx}", MemoryBar64))
|
|
bar_addr += 0x8
|
|
else:
|
|
bar_list.append((f"bar{idx}", MemoryBar32))
|
|
bar_addr += 0x4
|
|
else:
|
|
bar_list.append((f"bar{idx}", IOBar))
|
|
bar_addr += 0x4
|
|
|
|
class Bars(cdata.Struct):
|
|
_pack_ = 1
|
|
_fields_ = bar_list
|
|
|
|
def __iter__(self):
|
|
for f in self._fields_:
|
|
yield getattr(self, f[0])
|
|
|
|
return [
|
|
('bars', Bars),
|
|
('cardbus_cis_pointer', ctypes.c_uint32),
|
|
('subsystem_vendor_id', ctypes.c_uint16),
|
|
('subsystem_device_id', ctypes.c_uint16),
|
|
('expansion_rom_base_address', ctypes.c_uint32),
|
|
('capability_pointer', ctypes.c_uint8),
|
|
('reserved', ctypes.c_uint8 * 7),
|
|
('interrupt_line', ctypes.c_uint8),
|
|
('interrupt_pin', ctypes.c_uint8),
|
|
('min_gnt', ctypes.c_uint8),
|
|
('max_lat', ctypes.c_uint8),
|
|
]
|
|
|
|
def header_type_1_field_list(addr):
|
|
bar_list = list()
|
|
bar_addr = addr
|
|
bar_end = addr + 0x08
|
|
while bar_addr < bar_end:
|
|
bar = ctypes.c_uint32.from_address(addr).value
|
|
idx = int((bar_addr - addr) / 4)
|
|
if (bar & PCIE_BAR_SPACE_MASK) == PCIE_BAR_MEMORY_SPACE:
|
|
if (bar & PCIE_BAR_TYPE_MASK) == PCIE_BAR_TYPE_64_BIT:
|
|
bar_list.append((f"bar{idx}", MemoryBar64))
|
|
bar_addr += 0x8
|
|
else:
|
|
bar_list.append((f"bar{idx}", MemoryBar32))
|
|
bar_addr += 0x4
|
|
else:
|
|
bar_list.append((f"bar{idx}", IOBar))
|
|
bar_addr += 0x4
|
|
|
|
class Bars(cdata.Struct):
|
|
_pack_ = 1
|
|
_fields_ = bar_list
|
|
|
|
def __iter__(self):
|
|
for f in self._fields_:
|
|
yield getattr(self, f[0])
|
|
|
|
return [
|
|
('bars', Bars),
|
|
('primary_bus_number', ctypes.c_uint8),
|
|
('secondary_bus_number', ctypes.c_uint8),
|
|
('subordinate_bus_number', ctypes.c_uint8),
|
|
('secondary_latency_timer', ctypes.c_uint8),
|
|
('io_base', ctypes.c_uint8),
|
|
('io_limit', ctypes.c_uint8),
|
|
('secondary_status', ctypes.c_uint16),
|
|
('memory_base', ctypes.c_uint16),
|
|
('memory_limit', ctypes.c_uint16),
|
|
('prefetchable_memory_base', ctypes.c_uint16),
|
|
('prefetchable_memory_limit', ctypes.c_uint16),
|
|
('prefetchable_base_upper_32_bits', ctypes.c_uint32),
|
|
('prefetchable_limit_upper_32_bits', ctypes.c_uint32),
|
|
('io_base_upper_16_bits', ctypes.c_uint16),
|
|
('io_limit_upper_16_bits', ctypes.c_uint16),
|
|
('capability_pointer', ctypes.c_uint8),
|
|
('reserved', ctypes.c_uint8 * 3),
|
|
('expansion_rom_base_address', ctypes.c_uint32),
|
|
('interrupt_line', ctypes.c_uint8),
|
|
('interrupt_pin', ctypes.c_uint8),
|
|
('bridge_control', ctypes.c_uint16),
|
|
]
|
|
|
|
def header_field_list(addr):
|
|
common_header = Common.from_address(addr)
|
|
if common_header.header_type == 0x00:
|
|
return header_type_0_field_list(addr + ctypes.sizeof(Common))
|
|
elif common_header.header_type == 0x01:
|
|
return header_type_1_field_list(addr + ctypes.sizeof(Common))
|
|
else:
|
|
return [('data', ctypes.c_uint8 * 0x30)]
|
|
|
|
def header_factory(field_list):
|
|
class Header(cdata.Struct):
|
|
_pack_ = 1
|
|
_fields_ = copy.copy(Common._fields_) + field_list
|
|
return Header
|
|
|
|
def header(data):
|
|
"""Create class based on decode of a PCI configuration space header from raw data."""
|
|
buf = ctypes.create_string_buffer(data, len(data))
|
|
addr = ctypes.addressof(buf)
|
|
field_list = header_field_list(addr)
|
|
return header_factory(field_list).from_buffer_copy(data)
|