mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-05-13 19:04:31 +00:00
This patch ports the ACPI parsing module from BITS (BIOS Implementation Test Suite) in order to ease the access to ACPI tables during board XML generation. This library allows accessing ACPI table fields as Python class members, getting rid of hard coding or calculating offsets within tables. Compared to the original library, this port makes the following changes. * Extract only the scripts and functions that contribute to ACPI parsing. * Separate the parser of each ACPI table into different files. * Read raw ACPI tables from Linux sysfs. * Adapt to Python 3. Tracked-On: #5649 Signed-off-by: Junjie Mao <junjie.mao@intel.com>
131 lines
4.2 KiB
Python
131 lines
4.2 KiB
Python
# Copyright (C) 2021 Intel Corporation. All rights reserved.
|
|
#
|
|
# SPDX-License-Identifier: BSD-3-Clause
|
|
#
|
|
|
|
import ctypes
|
|
import copy
|
|
|
|
import acpiparser.cdata as cdata
|
|
from acpiparser._utils import TableHeader
|
|
|
|
class RTCTSubtable(cdata.Struct):
|
|
_pack_ = 1
|
|
_fields_ = [
|
|
('size', ctypes.c_uint16),
|
|
('format', ctypes.c_uint16),
|
|
('type', ctypes.c_uint32),
|
|
]
|
|
|
|
class RTCTSubtableRTCMBinary(cdata.Struct):
|
|
_pack_ = 1
|
|
_fields_ = copy.copy(RTCTSubtable._fields_) + [
|
|
('address', ctypes.c_uint64),
|
|
('size', ctypes.c_uint32),
|
|
]
|
|
|
|
def RTCTSubtableWRCL3Waymasks_factory(data_len):
|
|
class RTCTSubtableWRCL3Waymasks(cdata.Struct):
|
|
_pack_ = 1
|
|
_fields_ = copy.copy(RTCTSubtable._fields_) + [
|
|
('waskmask', ctypes.c_uint32 * (data_len // 4)),
|
|
]
|
|
return RTCTSubtableWRCL3Waymasks
|
|
|
|
def RTCTSubtableGTL3Waymasks_factory(data_len):
|
|
class RTCTSubtableGTL3Waymasks(cdata.Struct):
|
|
_pack_ = 1
|
|
_fields_ = copy.copy(RTCTSubtable._fields_) + [
|
|
('waskmask', ctypes.c_uint32 * (data_len // 4)),
|
|
]
|
|
return RTCTSubtableGTL3Waymasks
|
|
|
|
def RTCTSubtableSoftwareSRAM_factory(data_len):
|
|
class RTCTSubtableSoftwareSRAM(cdata.Struct):
|
|
_pack_ = 1
|
|
_fields_ = copy.copy(RTCTSubtable._fields_) + [
|
|
('cache_level', ctypes.c_uint32),
|
|
('base', ctypes.c_uint64),
|
|
('ways', ctypes.c_uint32),
|
|
('size', ctypes.c_uint32),
|
|
('apic_id_tbl', ctypes.c_uint32 * ((data_len - 20) // 4)),
|
|
]
|
|
return RTCTSubtableSoftwareSRAM
|
|
|
|
def RTCTSubtableMemoryHierarchyLatency_factory(data_len):
|
|
class RTCTSubtableMemoryHierarchyLatency(cdata.Struct):
|
|
_pack_ = 1
|
|
_fields_ = copy.copy(RTCTSubtable._fields_) + [
|
|
('hierarchy', ctypes.c_uint32),
|
|
('clock_cycles', ctypes.c_uint32),
|
|
('apic_id_tbl', ctypes.c_uint32 * ((data_len - 8) // 4)),
|
|
]
|
|
return RTCTSubtableMemoryHierarchyLatency
|
|
|
|
def RTCTSubtableUnknown_factory(data_len):
|
|
class RTCTSubtableUnknown(cdata.Struct):
|
|
_pack_ = 1
|
|
_fields_ = copy.copy(RTCTSubtable._fields_) + [
|
|
('data', ctypes.c_uint8 * data_len),
|
|
]
|
|
return RTCTSubtableUnknown
|
|
|
|
ACPI_RTCT_TYPE_RTCM_BINARY = 2
|
|
ACPI_RTCT_TYPE_WRC_L3Waymasks = 3
|
|
ACPI_RTCT_TYPE_GT_L3Waymasks = 4
|
|
ACPI_RTCT_TYPE_SoftwareSRAM = 5
|
|
ACPI_RTCT_TYPE_Memory_Hierarchy_Latency = 9
|
|
|
|
def rtct_subtable_list(addr, length):
|
|
end = addr + length
|
|
field_list = list()
|
|
subtable_num = 0
|
|
while addr < end:
|
|
subtable_num += 1
|
|
subtable = RTCTSubtable.from_address(addr)
|
|
data_len = subtable.size - ctypes.sizeof(RTCTSubtable)
|
|
if subtable.type == ACPI_RTCT_TYPE_RTCM_BINARY:
|
|
cls = RTCTSubtableRTCMBinary
|
|
elif subtable.type == ACPI_RTCT_TYPE_WRC_L3Waymasks:
|
|
cls = RTCTSubtableWRCL3Waymasks_factory(data_len)
|
|
elif subtable.type == ACPI_RTCT_TYPE_GT_L3Waymasks:
|
|
cls = RTCTSubtableGTL3Waymasks_factory(data_len)
|
|
elif subtable.type == ACPI_RTCT_TYPE_SoftwareSRAM:
|
|
cls = RTCTSubtableSoftwareSRAM_factory(data_len)
|
|
elif subtable.type == ACPI_RTCT_TYPE_Memory_Hierarchy_Latency:
|
|
cls = RTCTSubtableMemoryHierarchyLatency_factory(data_len)
|
|
else:
|
|
cls = RTCTSubtableUnknown_factory(data_len)
|
|
addr += subtable.size
|
|
field_list.append( ('subtable{}'.format(subtable_num), cls) )
|
|
return field_list
|
|
|
|
def rtct_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 RTCT(cdata.Struct):
|
|
_pack_ = 1
|
|
_fields_ = [
|
|
('header', TableHeader),
|
|
('entries', subtables),
|
|
]
|
|
|
|
return RTCT
|
|
|
|
def RTCT(val):
|
|
"""Create class based on decode of an RTCT table from filename."""
|
|
base_length = ctypes.sizeof(rtct_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 = rtct_subtable_list(addr + base_length, hdr.length - base_length)
|
|
return rtct_factory(field_list).from_buffer_copy(data)
|