diff --git a/misc/config_tools/acpi_gen/bin_gen.py b/misc/config_tools/acpi_gen/bin_gen.py index ce781fb9b..c577cb96e 100644 --- a/misc/config_tools/acpi_gen/bin_gen.py +++ b/misc/config_tools/acpi_gen/bin_gen.py @@ -5,9 +5,14 @@ """ +import logging import os, sys, subprocess, argparse, re, shutil +sys.path.append(os.path.join(os.path.dirname(os.path.abspath(__file__)), '..', 'board_inspector')) +import lxml.etree from acpi_const import * - +import acpiparser.tpm2 +import lib.cdata +import common def asl_to_aml(dest_vm_acpi_path, dest_vm_acpi_bin_path): ''' @@ -57,9 +62,38 @@ def asl_to_aml(dest_vm_acpi_path, dest_vm_acpi_bin_path): print('compile ACPI ASL code to {} successfully'.format(dest_vm_acpi_bin_path)) return rmsg +def tpm2_acpi_gen(acpi_bin, board_etree, scenario_etree, allocation_etree): + tpm2_enabled = common.get_node("//vm[@id = '0']/mmio_resources/TPM2/text()", scenario_etree) + if tpm2_enabled is not None and tpm2_enabled == 'y': + tpm2_node = common.get_node("//device[@id = 'MSFT0101']", board_etree) + if tpm2_node is not None: + _data_len = 0x4c if common.get_node("//capability[@id = 'log_area']", board_etree) is not None else 0x40 + _data = bytearray(_data_len) + ctype_data = acpiparser.tpm2.TPM2(_data) + ctype_data.header.signature = "TPM2".encode() + ctype_data.header.length = _data_len + ctype_data.header.revision = 0x3 + ctype_data.header.oemid = "ACRN ".encode() + ctype_data.header.oemtableid = "ACRNTPM2".encode() + ctype_data.header.oemrevision = 0x1 + ctype_data.header.creatorid = "INTL".encode() + ctype_data.header.creatorrevision = 0x20190703 + ctype_data.address_of_control_area = 0xFED40040 + ctype_data.start_method = int(common.get_node("//capability[@id = 'start_method']/value/text()", tpm2_node), 16) + start_method_parameters = tpm2_node.xpath("//parameter/text()") + for i in range(len(start_method_parameters)): + ctype_data.start_method_specific_parameters[i] = int(start_method_parameters[i], 16) + if common.get_node("//capability[@id = 'log_area']", board_etree) is not None: + ctype_data.log_area_minimum_length = int(common.get_node("//log_area_minimum_length/text()", allocation_etree), 16) + ctype_data.log_area_start_address = int(common.get_node("//log_area_start_address/text()", allocation_etree), 16) + ctype_data.header.checksum = (~(sum(lib.cdata.to_bytes(ctype_data))) + 1) & 0xFF + acpi_bin.seek(ACPI_TPM2_ADDR_OFFSET) + acpi_bin.write(lib.cdata.to_bytes(ctype_data)) + else: + logging.warning("Passtrhough tpm2 is enabled in scenario but the device is not presented on board.") + logging.warning("Check there is tpm2 device on board and re-generate the xml using board inspector with --advanced option.") - -def aml_to_bin(dest_vm_acpi_path, dest_vm_acpi_bin_path, acpi_bin_name): +def aml_to_bin(dest_vm_acpi_path, dest_vm_acpi_bin_path, acpi_bin_name, board_etree, scenario_etree, allocation_etree): ''' create the binary of ACPI table. :param dest_vm_acpi_bin_path: the path of the aml code of ACPI tables @@ -109,6 +143,10 @@ def aml_to_bin(dest_vm_acpi_path, dest_vm_acpi_bin_path, acpi_bin_name): with open(os.path.join(dest_vm_acpi_bin_path, ACPI_TABLE_LIST[8][1]), 'rb') as asl: acpi_bin.write(asl.read()) + vm_id = acpi_bin_name.split('.')[0].split('ACPI_VM')[1] + if vm_id == '0': + tpm2_acpi_gen(acpi_bin, board_etree, scenario_etree, allocation_etree) + acpi_bin.seek(0xfffff) acpi_bin.write(b'\0') shutil.move(acpi_bin_file, os.path.join(dest_vm_acpi_bin_path, '..', acpi_bin_name)) @@ -176,6 +214,12 @@ def main(args): board_type = args.board scenario_name = args.scenario + board_path = os.path.join(VM_CONFIGS_PATH, 'data', board_type, board_type + '.xml') + board_etree = lxml.etree.parse(board_path) + scenario_path = os.path.join(VM_CONFIGS_PATH, 'data', board_type, scenario_name + '.xml') + scenario_etree = lxml.etree.parse(scenario_path) + allocation_path = os.path.join(common.SOURCE_ROOT_DIR, 'build', 'hypervisor', 'configs' ,'allocation.xml') + allocation_etree = lxml.etree.parse(allocation_path) if args.asl is None: DEST_ACPI_PATH = os.path.join(VM_CONFIGS_PATH, 'scenarios', scenario_name) else: @@ -200,7 +244,7 @@ def main(args): os.makedirs(dest_vm_acpi_bin_path) if asl_to_aml(dest_vm_acpi_path, dest_vm_acpi_bin_path): return 1 - aml_to_bin(dest_vm_acpi_path, dest_vm_acpi_bin_path, config+'.bin') + aml_to_bin(dest_vm_acpi_path, dest_vm_acpi_bin_path, config+'.bin', board_etree, scenario_etree, allocation_etree) return 0