config-tools: add tpm2 acpi parser to board_inspector

Create python script tpm2 which parse the tpm2 acpi table datas. Add
this parsed data to the <device id="MSFT0101" description="TPM 2.0 Device"> of board.xml.

Tracked-On: #6320
Signed-off-by: Yang,Yu-chu <yu-chu.yang@intel.com>
This commit is contained in:
Yang,Yu-chu 2021-07-14 14:46:49 -07:00 committed by Xie, Nanlin
parent 3c707408ec
commit 40eaff9569
3 changed files with 75 additions and 2 deletions

View File

@ -11,6 +11,7 @@ from acpiparser.dmar import DMAR
from acpiparser.dsdt import DSDT
from acpiparser.facp import FACP
from acpiparser.rtct import RTCT
from acpiparser.tpm2 import TPM2
def parse_table(signature, path=None):
if not path:
@ -29,6 +30,7 @@ parse_asf = make_parser('ASF!')
parse_dsdt = make_parser('DSDT')
parse_dmar = make_parser('DMAR')
parse_facp = make_parser('FACP')
parse_tpm2 = make_parser('TPM2')
def parse_rtct(path=None):
if not path:

View File

@ -0,0 +1,51 @@
# Copyright (C) 2021 Intel Corporation. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
import ctypes
import logging
import lib.cdata as cdata
from acpiparser._utils import TableHeader
def tpm2_optional_data(data_len):
start_method_data_len = 0
has_log_area = False
if data_len <= 12:
start_method_data_len = data_len
elif data_len == 24:
start_method_data_len = 12
has_log_area = True
else:
start_method_data_len = 12
logging.warning(f"TPM2 data length: {data_len + 52} is greater than 64 bytes but less than 76 bytes.")
logging.warning(f"The TPM2 data is still processed but the 65 to {data_len + 52} bytes are discard.")
return start_method_data_len, has_log_area
def tpm2_factory(start_method_data_len, has_log_area):
class TPM2(cdata.Struct):
_pack_ = 1
_fields_ = [
('header', TableHeader),
('platform_class', ctypes.c_uint16),
('reserved', ctypes.c_uint16),
('address_of_control_area', ctypes.c_uint64),
('start_method', ctypes.c_uint32),
('start_method_specific_parameters', ctypes.c_ubyte * start_method_data_len),
] + ([
('log_area_minimum_length', ctypes.c_uint32),
('log_area_start_address', ctypes.c_uint64),
] if has_log_area else [])
return TPM2
def TPM2(val):
"""Create class based on decode of a TPM2 table from filename."""
if isinstance(val, str):
base_length = 52
data = open(val, mode='rb').read()
start_method_data_len, has_log_area = tpm2_optional_data(len(data) - base_length)
return tpm2_factory(start_method_data_len, has_log_area).from_buffer_copy(data)
elif isinstance(val, bytearray):
return tpm2_factory(12, True).from_buffer(val) if len(val) > 64 else tpm2_factory(12, False).from_buffer(val)

View File

@ -3,10 +3,10 @@
# SPDX-License-Identifier: BSD-3-Clause
#
import ctypes
import logging
import lxml.etree
from acpiparser import parse_dsdt
from acpiparser import parse_dsdt, parse_tpm2
from acpiparser.aml.interpreter import ConcreteInterpreter
from acpiparser.aml.exception import UndefinedSymbol, FutureWork
from acpiparser.rdt import *
@ -95,6 +95,23 @@ def parse_extended_irq(item, elem):
for irq in item._INT:
add_child(elem, "resource", type="irq", int=hex(irq))
def parse_tpm(elem):
try:
tpm2 = parse_tpm2()
control_area = add_child(elem, "capability", None, id="control_area")
add_child(control_area, "address_of_control_area", hex(tpm2.address_of_control_area))
start_method = add_child(elem, "capability", None, id="start_method")
add_child(start_method, "value", hex(tpm2.start_method))
for parameter in tpm2.start_method_specific_parameters:
add_child(start_method, "parameter", hex(parameter))
if hasattr(tpm2, "log_area_minimum_length"):
add_child(elem, "capability", None, id="log_area")
except Exception as e:
logging.info(f"Parse ACPI TPM2 failed: {str(e)}")
logging.info(f"Will not extract information from ACPI TPM2")
return
resource_parsers = {
(0, SMALL_RESOURCE_ITEM_IRQ_FORMAT): parse_irq,
(0, SMALL_RESOURCE_ITEM_IO_PORT): parse_io_port,
@ -145,6 +162,9 @@ def fetch_device_info(devices_node, interpreter, namepath):
element.tag = "bus"
element.set("type", buses[hid])
if hid == "MSFT0101":
parse_tpm(element)
# Address
if interpreter.context.has_symbol(f"{namepath}._ADR"):
adr = interpreter.interpret_method_call(f"{namepath}._ADR").get()