mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-05-15 11:51:15 +00:00
This patch reorganize the files of the board inspector as follows. 1. Rename the directory name from `target` to `board_inspector`, in order to align with the name used in ACRN documentation. 2. Move the scripts that generate the current board XML into the `legacy` sub-directory. The legacy nodes will be removed after transitioning to the new board XML schema completely, 3. Add the main script `cli.py` which is the command line interface of the board inspector. v1 -> v2: - Rename `run.py` to `cli.py`. Tracked-On: #5922 Signed-off-by: Junjie Mao <junjie.mao@intel.com>
253 lines
7.7 KiB
Python
253 lines
7.7 KiB
Python
# Copyright (C) 2021 Intel Corporation. All rights reserved.
|
|
#
|
|
# SPDX-License-Identifier: BSD-3-Clause
|
|
#
|
|
|
|
import ctypes
|
|
import copy
|
|
|
|
import lib.cdata as cdata
|
|
from acpiparser._utils import TableHeader
|
|
|
|
class DMARSubtable(cdata.Struct):
|
|
_pack_ = 1
|
|
_fields_ = [
|
|
('subtype', ctypes.c_uint16),
|
|
('length', ctypes.c_uint16),
|
|
]
|
|
|
|
class DMARDeviceScopePath(cdata.Struct):
|
|
_pack_ = 1
|
|
_fields_ = [
|
|
('pci_device', ctypes.c_uint8),
|
|
('pci_function', ctypes.c_uint8),
|
|
]
|
|
|
|
def DMARDeviceScope_factory(num_dev_scope_path):
|
|
class DMARDeviceScope(cdata.Struct):
|
|
_pack_ = 1
|
|
_fields_ = [
|
|
('type', ctypes.c_uint8),
|
|
('length', ctypes.c_uint8),
|
|
('reserved', ctypes.c_uint16),
|
|
('enumeration_id', ctypes.c_uint8),
|
|
('start_bus_number', ctypes.c_uint8),
|
|
('paths', DMARDeviceScopePath * num_dev_scope_path),
|
|
]
|
|
return DMARDeviceScope
|
|
|
|
def dmar_device_scope_list(addr, length):
|
|
end = addr + length
|
|
field_list = list()
|
|
subtable_num = 0
|
|
base_len_DMARDeviceScope = ctypes.sizeof(DMARDeviceScope_factory(0))
|
|
len_DMARDeviceScopePath = ctypes.sizeof(DMARDeviceScopePath)
|
|
while addr < end:
|
|
subtable_num += 1
|
|
subtable = DMARDeviceScope_factory(0).from_address(addr)
|
|
num_dev_scope_path = (subtable.length - base_len_DMARDeviceScope) // len_DMARDeviceScopePath
|
|
cls = DMARDeviceScope_factory(num_dev_scope_path)
|
|
addr += subtable.length
|
|
field_list.append( ('subtable{}'.format(subtable_num), cls) )
|
|
return field_list
|
|
|
|
class drhd_flags_bits(cdata.Struct):
|
|
_pack_ = 1
|
|
_fields_ = [
|
|
('include_pci_all', ctypes.c_uint8, 1),
|
|
]
|
|
|
|
class drhd_flags(cdata.Union):
|
|
_pack_ = 1
|
|
_anonymous_ = ("bits",)
|
|
_fields_ = [
|
|
('data', ctypes.c_uint8),
|
|
('bits', drhd_flags_bits),
|
|
]
|
|
|
|
def DMARSubtableDRHD_factory(field_list):
|
|
|
|
class subtables(cdata.Struct):
|
|
_pack_ = 1
|
|
_fields_ = field_list
|
|
|
|
def __iter__(self):
|
|
for f in self._fields_:
|
|
yield getattr(self, f[0])
|
|
|
|
class DMARSubtableDRHD(cdata.Struct):
|
|
_pack_ = 1
|
|
_fields_ = copy.copy(DMARSubtable._fields_) + [
|
|
('flags', drhd_flags),
|
|
('reserved', ctypes.c_uint8),
|
|
('segment_number', ctypes.c_uint16),
|
|
('base_address', ctypes.c_uint64),
|
|
('device_scopes', subtables)
|
|
]
|
|
return DMARSubtableDRHD
|
|
|
|
def DMARSubtableRMRR_factory(field_list):
|
|
|
|
class subtables(cdata.Struct):
|
|
_pack_ = 1
|
|
_fields_ = field_list
|
|
|
|
def __iter__(self):
|
|
for f in self._fields_:
|
|
yield getattr(self, f[0])
|
|
|
|
class DMARSubtableRMRR(cdata.Struct):
|
|
_pack_ = 1
|
|
_fields_ = copy.copy(DMARSubtable._fields_) + [
|
|
('reserved', ctypes.c_uint16),
|
|
('segment_number', ctypes.c_uint16),
|
|
('base_address', ctypes.c_uint64),
|
|
('limit_address', ctypes.c_uint64),
|
|
('device_scopes', subtables),
|
|
]
|
|
|
|
return DMARSubtableRMRR
|
|
|
|
class atsr_flags_bits(cdata.Struct):
|
|
_pack_ = 1
|
|
_fields_ = [
|
|
('all_ports', ctypes.c_uint8, 1),
|
|
]
|
|
|
|
class atsr_flags(cdata.Union):
|
|
_pack_ = 1
|
|
_anonymous_ = ("bits",)
|
|
_fields_ = [
|
|
('data', ctypes.c_uint8),
|
|
('bits', atsr_flags_bits),
|
|
]
|
|
|
|
def DMARSubtableATSR_factory(field_list):
|
|
|
|
class subtables(cdata.Struct):
|
|
_pack_ = 1
|
|
_fields_ = field_list
|
|
|
|
def __iter__(self):
|
|
for f in self._fields_:
|
|
yield getattr(self, f[0])
|
|
|
|
class DMARSubtableATSR(cdata.Struct):
|
|
_pack = 1
|
|
_fields_ = copy.copy(DMARSubtable._fields_) + [
|
|
('flags', atsr_flags),
|
|
('reserved', ctypes.c_uint8),
|
|
('segment_number', ctypes.c_uint16),
|
|
('device_scopes', subtables),
|
|
]
|
|
return DMARSubtableATSR
|
|
|
|
class DMARSubtableRHSA(cdata.Struct):
|
|
_pack = 1
|
|
_fields_ = copy.copy(DMARSubtable._fields_) + [
|
|
('reserved', ctypes.c_uint32),
|
|
('base_address', ctypes.c_uint64),
|
|
('proximity_domain', ctypes.c_uint32),
|
|
]
|
|
|
|
def DMARSubTableANDD_factory(obj_name_len):
|
|
class DMARSubTableANDD(cdata.Struct):
|
|
_pack = 1
|
|
_fields_ = copy.copy(DMARSubtable._fields_) + [
|
|
('reserved', ctypes.c_uint8 * 3),
|
|
('device_num', ctypes.c_uint8),
|
|
('object_name', ctypes.c_char * obj_name_len),
|
|
]
|
|
return DMARSubTableANDD
|
|
|
|
def DMARSubtableUnknown_factory(data_len):
|
|
class DMARSubtableUnknown(cdata.Struct):
|
|
_pack = 1
|
|
_fields_ = copy.copy(DMARSubtable._fields_) + [
|
|
('data', ctypes.c_uint8 * data_len),
|
|
]
|
|
return DMARSubtableUnknown
|
|
|
|
ACPI_DMAR_TYPE_DRHD = 0
|
|
ACPI_DMAR_TYPE_RMRR = 1
|
|
ACPI_DMAR_TYPE_ATSR = 2
|
|
ACPI_DMAR_TYPE_RHSA = 3
|
|
ACPI_DMAR_TYPE_ANDD = 4
|
|
|
|
def dmar_subtable_list(addr, length):
|
|
end = addr + length
|
|
field_list = list()
|
|
subtable_num = 0
|
|
base_len_DRHD = ctypes.sizeof(DMARSubtableDRHD_factory(list()))
|
|
base_len_RMRR = ctypes.sizeof(DMARSubtableRMRR_factory(list()))
|
|
base_len_ATSR = ctypes.sizeof(DMARSubtableATSR_factory(list()))
|
|
base_len_ANDD = ctypes.sizeof(DMARSubTableANDD_factory(0))
|
|
while addr < end:
|
|
subtable_num += 1
|
|
subtable = DMARSubtable.from_address(addr)
|
|
if subtable.subtype == ACPI_DMAR_TYPE_DRHD:
|
|
next_field_list = dmar_device_scope_list(addr + base_len_DRHD, subtable.length - base_len_DRHD)
|
|
cls = DMARSubtableDRHD_factory(next_field_list)
|
|
elif subtable.subtype == ACPI_DMAR_TYPE_RMRR:
|
|
next_field_list = dmar_device_scope_list(addr + base_len_RMRR, subtable.length - base_len_RMRR)
|
|
cls = DMARSubtableRMRR_factory(next_field_list)
|
|
elif subtable.subtype == ACPI_DMAR_TYPE_ATSR:
|
|
next_field_list = dmar_device_scope_list(addr + base_len_ATSR, subtable.length - base_len_ATSR)
|
|
cls = DMARSubtableATSR_factory(next_field_list)
|
|
elif subtable.subtype == ACPI_DMAR_TYPE_RHSA:
|
|
cls = DMARSubtableRHSA
|
|
elif subtable.subtype == ACPI_DMAR_TYPE_ANDD:
|
|
cls = DMARSubTableANDD_factory(subtable.length - base_len_ANDD)
|
|
else:
|
|
cls = DMARSubtableUnknown_factory(subtable.length - ctypes.sizeof(DMARSubtable))
|
|
addr += subtable.length
|
|
field_list.append( ('subtable{}'.format(subtable_num), cls) )
|
|
return field_list
|
|
|
|
class dmar_flags_bits(cdata.Struct):
|
|
_pack_ = 1
|
|
_fields_ = [
|
|
('intr_remap', ctypes.c_uint8, 1),
|
|
('x2apic_opt_out', ctypes.c_uint8, 1),
|
|
]
|
|
|
|
class dmar_flags(cdata.Union):
|
|
_pack_ = 1
|
|
_anonymous_ = ("bits",)
|
|
_fields_ = [
|
|
('data', ctypes.c_uint8),
|
|
('bits', dmar_flags_bits),
|
|
]
|
|
|
|
def dmar_factory(field_list):
|
|
|
|
class subtables(cdata.Struct):
|
|
_pack_ = 1
|
|
_fields_ = field_list
|
|
|
|
def __iter__(self):
|
|
for f in self._fields_:
|
|
yield getattr(self, f[0])
|
|
|
|
class DMAR_v1(cdata.Struct):
|
|
_pack = 1
|
|
_fields_ = [
|
|
('header', TableHeader),
|
|
('host_addr_width', ctypes.c_uint8),
|
|
('flags', ctypes.c_uint8),
|
|
('reserved', ctypes.c_uint8 * 10),
|
|
('remapping_structures', subtables),
|
|
]
|
|
|
|
return DMAR_v1
|
|
|
|
def DMAR(val):
|
|
"""Create class based on decode of an DMAR table from filename."""
|
|
base_length = ctypes.sizeof(dmar_factory(list()))
|
|
data = open(val, mode='rb').read()
|
|
buf = ctypes.create_string_buffer(data, len(data))
|
|
addr = ctypes.addressof(buf)
|
|
hdr = TableHeader.from_address(addr)
|
|
field_list = dmar_subtable_list(addr + base_length, hdr.length - base_length)
|
|
return dmar_factory(field_list).from_buffer_copy(data)
|