diff --git a/misc/config_tools/acpi_gen/acpi_const.py b/misc/config_tools/acpi_gen/acpi_const.py index 024d25b7d..f7e7171a6 100644 --- a/misc/config_tools/acpi_gen/acpi_const.py +++ b/misc/config_tools/acpi_gen/acpi_const.py @@ -15,7 +15,7 @@ TEMPLATE_ACPI_PATH = os.path.join(VM_CONFIGS_PATH, 'acpi_template', 'template') ACPI_TABLE_LIST = [('rsdp.asl', 'rsdp.aml'), ('xsdt.asl', 'xsdt.aml'), ('facp.asl', 'facp.aml'), ('mcfg.asl', 'mcfg.aml'), ('apic.asl', 'apic.aml'), ('tpm2.asl', 'tpm2.aml'), - ('dsdt.aml', 'dsdt.aml'), ('PTCT', 'ptct.aml'), ('RTCT', 'rtct.aml')] + ('dsdt.aml', 'dsdt.aml'), ('ptct.aml', 'ptct.aml'), ('rtct.aml', 'rtct.aml')] ACPI_BASE = 0x7fe00000 @@ -49,5 +49,3 @@ ACPI_MADT_TYPE_LOCAL_APIC_NMI = 4 TSN_DEVICE_LIST = ['8086:4ba0', '8086:4bb0', '8086:4b32'] - -RTCT = ['RTCT', 'PTCT'] diff --git a/misc/config_tools/acpi_gen/asl_gen.py b/misc/config_tools/acpi_gen/asl_gen.py index 5a9748a67..4693f0680 100644 --- a/misc/config_tools/acpi_gen/asl_gen.py +++ b/misc/config_tools/acpi_gen/asl_gen.py @@ -12,6 +12,8 @@ import collections import lxml.etree sys.path.append(os.path.join(os.path.dirname(os.path.abspath(__file__)), '..', 'board_inspector')) +from acpiparser._utils import TableHeader +from acpiparser import rtct from acpiparser import rdt from acpiparser.dsdt import parse_tree from acpiparser.aml import builder @@ -764,6 +766,87 @@ def gen_dsdt(board_etree, scenario_etree, allocation_etree, vm_id, dest_path): dest.write(binary) +def gen_rtct(board_etree, scenario_etree, allocation_etree, vm_id, dest_path): + def cpu_id_to_lapic_id(cpu_id): + return common.get_node(f"//thread[cpu_id = '{cpu_id}']/apic_id/text()", board_etree) + + vm_node = common.get_node(f"//vm[@id='{vm_id}']", scenario_etree) + if vm_node is None: + return False + + vcpus = ",".join(map(cpu_id_to_lapic_id, vm_node.xpath("cpu_affinity//pcpu_id/text()"))) + rtct_entries = [] + + # ACPI table header + + common_header = create_object( + TableHeader, + signature = b'RTCT', + revision = 1, + oemid = b'ACRN ', + oemtableid = b'ACRNRTCT', + oemrevision = 5, + creatorid = b'INTL', + creatorrevision = 0x100000d + ) + rtct_entries.append(common_header) + + # Compatibility entry + + compat_entry = create_object( + rtct.RTCTSubtableCompatibility, + subtable_size = ctypes.sizeof(rtct.RTCTSubtableCompatibility), + format_or_version = 1, + type = rtct.ACPI_RTCT_TYPE_COMPATIBILITY, + rtct_version_major = 2, + rtct_version_minor = 0, + rtcd_version_major = 0, + rtcd_version_minor = 0 + ) + rtct_entries.append(compat_entry) + + # SSRAM entries + + # Look for the cache blocks that are visible to this VM and have software SRAM in it. Those software SRAM will be + # exposed to the VM in RTCT. + for cache in board_etree.xpath(f"//caches/cache[count(processors/processor[contains('{vcpus}', .)]) and capability[@id = 'Software SRAM']]"): + ssram_cap = common.get_node("capability[@id = 'Software SRAM']", cache) + + ssram_entry = create_object( + rtct.RTCTSubtableSoftwareSRAM_v2, + subtable_size = ctypes.sizeof(rtct.RTCTSubtableSoftwareSRAM_v2), + format_or_version = 2, + type = rtct.ACPI_RTCT_V2_TYPE_SoftwareSRAM, + level = int(cache.get("level")), + cache_id = int(cache.get("id"), base=16), + base = int(ssram_cap.find("start").text, base=16), + size = int(ssram_cap.find("size").text), + shared = 0 + ) + rtct_entries.append(ssram_entry) + + if ssram_cap.find("waymask") is not None: + ssram_waymask_entry = create_object( + rtct.RTCTSubtableSSRAMWayMask, + subtable_size = ctypes.sizeof(rtct.RTCTSubtableSSRAMWayMask), + format_or_version = 1, + type = rtct.ACPI_RTCT_V2_TYPE_SSRAM_WayMask, + level = int(cache.get("level")), + cache_id = int(cache.get("id"), base=16), + waymask = int(ssram_cap.find("waymask").text, base=16) + ) + rtct_entries.append(ssram_waymask_entry) + + with open(dest_path, "wb") as dest: + length = sum(map(ctypes.sizeof, rtct_entries)) + common_header.length = length + binary = bytearray().join(map(bytearray, rtct_entries)) + + checksum = (256 - (sum(binary) % 256)) % 256 + binary[9] = checksum + + dest.write(binary) + def main(args): err_dic = {} @@ -846,12 +929,8 @@ def main(args): if not os.path.isdir(dest_vm_acpi_path): os.makedirs(dest_vm_acpi_path) if PASSTHROUGH_RTCT is True and vm_id == PRELAUNCHED_RTVM_ID: - for f in RTCT: - if os.path.isfile(os.path.join(VM_CONFIGS_PATH, 'acpi_template', board_type, f)): - passthru_devices.append(f) - shutil.copy(os.path.join(VM_CONFIGS_PATH, 'acpi_template', board_type, f), - dest_vm_acpi_path) - break + passthru_devices.append("RTCT") + gen_rtct(board_etree, scenario_etree, allocation_etree, vm_id, os.path.join(dest_vm_acpi_path, "rtct.aml")) gen_rsdp(dest_vm_acpi_path) gen_xsdt(dest_vm_acpi_path, passthru_devices) gen_fadt(dest_vm_acpi_path, board_root) diff --git a/misc/config_tools/acpi_gen/bin_gen.py b/misc/config_tools/acpi_gen/bin_gen.py index 57ef01ad5..8d8cec462 100644 --- a/misc/config_tools/acpi_gen/bin_gen.py +++ b/misc/config_tools/acpi_gen/bin_gen.py @@ -70,7 +70,7 @@ def asl_to_aml(dest_vm_acpi_path, dest_vm_acpi_bin_path, scenario_etree, allocat os.remove(os.path.join(dest_vm_acpi_path, acpi_table[1])) rmsg = 'failed to compile {}'.format(acpi_table[0]) break - elif acpi_table[0] in ['PTCT', 'RTCT']: + elif acpi_table[0] in ['ptct.aml', 'rtct.aml']: if acpi_table[0] in os.listdir(dest_vm_acpi_path): rtct = acpiparser.rtct.RTCT(os.path.join(dest_vm_acpi_path, acpi_table[0])) outfile = os.path.join(dest_vm_acpi_bin_path, acpi_table[1]) @@ -95,7 +95,7 @@ def asl_to_aml(dest_vm_acpi_path, dest_vm_acpi_bin_path, scenario_etree, allocat os.remove(os.path.join(dest_vm_acpi_path, acpi_table[1])) rmsg = 'failed to compile {}'.format(acpi_table[0]) break - elif acpi_table[0].endswith(".aml"): + elif acpi_table[0].endswith(".aml") and acpi_table[0] in os.listdir(dest_vm_acpi_path): shutil.copy(os.path.join(dest_vm_acpi_path, acpi_table[0]), os.path.join(dest_vm_acpi_bin_path, acpi_table[1])) @@ -171,11 +171,11 @@ def aml_to_bin(dest_vm_acpi_path, dest_vm_acpi_bin_path, acpi_bin_name, board_et with open(os.path.join(dest_vm_acpi_bin_path, ACPI_TABLE_LIST[6][1]), 'rb') as asl: acpi_bin.write(asl.read()) - if 'PTCT' in os.listdir(dest_vm_acpi_path): + if ACPI_TABLE_LIST[7][1] in os.listdir(dest_vm_acpi_path): acpi_bin.seek(ACPI_RTCT_ADDR_OFFSET) with open(os.path.join(dest_vm_acpi_bin_path, ACPI_TABLE_LIST[7][1]), 'rb') as asl: acpi_bin.write(asl.read()) - elif 'RTCT' in os.listdir(dest_vm_acpi_path): + elif ACPI_TABLE_LIST[8][1] in os.listdir(dest_vm_acpi_path): acpi_bin.seek(ACPI_RTCT_ADDR_OFFSET) with open(os.path.join(dest_vm_acpi_bin_path, ACPI_TABLE_LIST[8][1]), 'rb') as asl: acpi_bin.write(asl.read()) diff --git a/misc/config_tools/board_inspector/acpiparser/rdt.py b/misc/config_tools/board_inspector/acpiparser/rdt.py index 308c76e66..c4fc5e35b 100644 --- a/misc/config_tools/board_inspector/acpiparser/rdt.py +++ b/misc/config_tools/board_inspector/acpiparser/rdt.py @@ -30,7 +30,7 @@ SMALL_RESOURCE_ITEM_END_TAG = 0x0F # 6.4.2.1 IRQ Descriptor -def SmallResourceItemIRQ_factory(_len): +def SmallResourceItemIRQ_factory(_len=2): class SmallResourceItemIRQ(cdata.Struct): _pack_ = 1 _fields_ = SmallResourceDataTag._fields_ + [