config-tools: refine bin_gen.py and create virtual TPM2 acpi table
Create virtual acpi table of tpm2 based on the raw data if the TPM2 device is presented and the passthrough tpm2 is enabled. Refine the arguments of bin_gen.py. The --board and --scenario take the path to the XMLs as the argument. The allocation.xml is needed for bin_gen.py to generate tpm2 acpi table. Refine the condition of tpm2_acpi_gen. The tpm2 device "MSFT0101" can be present in device id or compatible_id(CID). Check both attributes and child node of tpm2 device. Tracked-On: #6320 Signed-off-by: Yang,Yu-chu <yu-chu.yang@intel.com>
This commit is contained in:
parent
53d99d2a68
commit
d997f4bbc1
|
@ -395,7 +395,7 @@ pre_build: $(HV_CONFIG_H) $(HV_CONFIG_TIMESTAMP)
|
|||
$(MAKE) -C $(PRE_BUILD_DIR) BOARD=$(BOARD) SCENARIO=$(SCENARIO) TARGET_DIR=$(HV_CONFIG_DIR)
|
||||
@$(HV_OBJDIR)/hv_prebuild_check.out
|
||||
@echo "generate the binary of ACPI tables for pre-launched VMs ..."
|
||||
python3 ../misc/config_tools/acpi_gen/bin_gen.py --board $(BOARD) --scenario $(SCENARIO) --asl $(HV_CONFIG_DIR) --out $(HV_OBJDIR)/acpi
|
||||
python3 ../misc/config_tools/acpi_gen/bin_gen.py --board $(HV_OBJDIR)/.board.xml --scenario $(HV_OBJDIR)/.scenario.xml --asl $(HV_CONFIG_DIR) --out $(HV_OBJDIR)
|
||||
|
||||
.PHONY: header
|
||||
header: $(VERSION) $(HV_CONFIG_H) $(HV_CONFIG_TIMESTAMP)
|
||||
|
|
|
@ -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):
|
||||
'''
|
||||
|
@ -61,9 +66,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' or compatible_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
|
||||
|
@ -95,11 +129,6 @@ 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[4][1]), 'rb') as asl:
|
||||
acpi_bin.write(asl.read())
|
||||
|
||||
if 'tpm2.asl' in os.listdir(dest_vm_acpi_path):
|
||||
acpi_bin.seek(ACPI_TPM2_ADDR_OFFSET)
|
||||
with open(os.path.join(dest_vm_acpi_bin_path, ACPI_TABLE_LIST[5][1]), 'rb') as asl:
|
||||
acpi_bin.write(asl.read())
|
||||
|
||||
acpi_bin.seek(ACPI_DSDT_ADDR_OFFSET)
|
||||
with open(os.path.join(dest_vm_acpi_bin_path, ACPI_TABLE_LIST[6][1]), 'rb') as asl:
|
||||
acpi_bin.write(asl.read())
|
||||
|
@ -113,6 +142,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))
|
||||
|
@ -178,16 +211,22 @@ def check_iasl():
|
|||
|
||||
def main(args):
|
||||
|
||||
board_type = args.board
|
||||
scenario_name = args.scenario
|
||||
board_etree = lxml.etree.parse(args.board)
|
||||
scenario_etree = lxml.etree.parse(args.scenario)
|
||||
|
||||
scenario_name = common.get_node("//@scenario", scenario_etree)
|
||||
|
||||
if args.asl is None:
|
||||
DEST_ACPI_PATH = os.path.join(VM_CONFIGS_PATH, 'scenarios', scenario_name)
|
||||
else:
|
||||
DEST_ACPI_PATH = os.path.join(common.SOURCE_ROOT_DIR, args.asl, 'scenarios', scenario_name)
|
||||
if args.out is None:
|
||||
DEST_ACPI_BIN_PATH = os.path.join(common.SOURCE_ROOT_DIR, 'build', 'hypervisor', 'acpi')
|
||||
hypervisor_out = os.path.join(common.SOURCE_ROOT_DIR, 'build', 'hypervisor')
|
||||
else:
|
||||
DEST_ACPI_BIN_PATH = args.out
|
||||
hypervisor_out = args.out
|
||||
DEST_ACPI_BIN_PATH = os.path.join(hypervisor_out, 'acpi')
|
||||
|
||||
allocation_etree = lxml.etree.parse(os.path.join(hypervisor_out, 'configs', 'allocation.xml'))
|
||||
|
||||
if os.path.isdir(DEST_ACPI_BIN_PATH):
|
||||
shutil.rmtree(DEST_ACPI_BIN_PATH)
|
||||
|
@ -204,20 +243,20 @@ 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
|
||||
|
||||
if __name__ == '__main__':
|
||||
parser = argparse.ArgumentParser(usage="python3 bin_gen.py --board [board] --scenario [scenario]"
|
||||
"[ --out [output dir of acpi ASL code]]",
|
||||
description="the tool to generate ACPI binary for Pre-launched VMs.")
|
||||
parser.add_argument("--board", required=True, help="the board type.")
|
||||
parser.add_argument("--scenario", required=True, help="the scenario name.")
|
||||
description="the tool to generate ACPI binary for Pre-launched VMs")
|
||||
parser.add_argument("--board", required=True, help="the XML file summarizing characteristics of the target board")
|
||||
parser.add_argument("--scenario", required=True, help="the XML file specifying the scenario to be set up")
|
||||
parser.add_argument("--asl", default=None, help="the input folder to store the ACPI ASL code. ")
|
||||
parser.add_argument("--out", default=None, help="the output folder to store the ACPI binary code. "
|
||||
"If not specified, the path for the binary code is"
|
||||
"build/acpi/")
|
||||
"build/hypervisor/acpi/")
|
||||
|
||||
args = parser.parse_args()
|
||||
rc = main(args)
|
||||
|
|
Loading…
Reference in New Issue