blob: 308147e483a2b1b84e0eb5ae1955d786fb7c832e [file] [log] [blame]
# Copyright 2019 The ChromiumOS Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Check the board ID of the Cr50 firmware.
Description
-----------
This test checks the board ID in the Cr50 firmware matched the given
expectation or not. The test gains the board ID by invoking `gsctool`
utility on DUT.
See https://chrome-internal.googlesource.com/ti50/common/ti50/+/main/docs/\
board_id_flags.md#values-in-info-pages for available flags.
Test Procedure
--------------
This is an automatic test that doesn't need any user interaction.
1. Firstly, this test gets the board ID from the Cr50 firmware.
2. If the argument ``board_id_type`` is set, the test checks if the
board ID type field is equal to the argument value or not.
3. If the argument ``board_id_flags`` is set, the test checks if the
board ID flags field is equal to the argument value or not.
Dependency
----------
- DUT link must be ready before running this test.
- `gsctool` on DUT.
Examples
--------
To check if the board ID is still unprogrammed, add this in test list:
.. test_list::
generic_tpm_examples:CommonTests.AssertGSCBoardIDIsUnset
To check if the board ID flags is set to normal prePVT, you can set the argument
``board_id_flags`` to `PHASE_PREPVT`:
.. test_list::
generic_tpm_examples:CommonTests.AssertGSCBoardIDIsPrePVT
"""
from cros.factory.device import device_utils
from cros.factory.test import session
from cros.factory.test import test_case
from cros.factory.testlog import testlog
from cros.factory.utils.arg_utils import Arg
from cros.factory.external.chromeos_cli import gsctool
_non_inclusive_label = bytes.fromhex('57484954454c4142454c').decode('utf-8')
class CheckCr50FirmwareBoardIDTest(test_case.TestCase):
related_components = (test_case.TestCategory.SECURE_ELEMENT, )
_PREDEFINED_PHASES = {
'PHASE_UNSET': 0xffffffff,
'PHASE_UNKNOWN': 0x0000ff00,
'PHASE_PREPVT': 0x00007f7f,
'PHASE_PVT': 0x00007f80,
f'PHASE_{_non_inclusive_label}_PREPVT': 0x00003f7f,
f'PHASE_{_non_inclusive_label}': 0x00003f80,
'PHASE_CUSTOM_LABEL_PREPVT': 0x00003f7f,
'PHASE_CUSTOM_LABEL': 0x00003f80,
}
ARGS = [
Arg(
'board_id_type', (int, str), 'The expected board ID type, can be '
'either an integer or a string of hex code.', default=None),
Arg(
'board_id_flags', (int, str), 'The expected board ID flags, can be '
'either an integer or a string. If the value is a string, '
'the value can be either the hex code of the board ID flags or' +
', '.join(f'{k} for {v:08x}' for k, v in _PREDEFINED_PHASES.items()),
default=None),
]
def setUp(self):
# Preprocesses the arguments.
# yapf: disable
if isinstance(self.args.board_id_type, str): # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
# yapf: enable
# yapf: disable
self.args.board_id_type = int(self.args.board_id_type, 16) # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
# yapf: enable
# yapf: disable
if isinstance(self.args.board_id_flags, str): # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
# yapf: enable
# yapf: disable
if self.args.board_id_flags.startswith('PHASE_'): # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
# yapf: enable
# yapf: disable
self.args.board_id_flags = self._PREDEFINED_PHASES[ # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
# yapf: enable
# yapf: disable
self.args.board_id_flags] # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
# yapf: enable
else:
# yapf: disable
self.args.board_id_flags = int(self.args.board_id_flags, 16) # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
# yapf: enable
# Setups the DUT environments.
self.dut = device_utils.CreateDUTInterface()
self.gsctool = gsctool.GSCTool(dut=self.dut)
# Setups the logging framework.
testlog.UpdateParam('board_id_type',
description='Board ID type in hex code')
testlog.UpdateParam('board_id_flags',
description='Board ID flags in hex code')
def runTest(self):
board_id = self.gsctool.GetBoardID()
board_id_type_str = f'{board_id.type:08x}'
board_id_flags_str = f'{board_id.flags:08x}'
session.console.info('Board ID type: %s; Board ID flags: %s.',
board_id_type_str, board_id_flags_str)
testlog.LogParam('board_id_type', board_id_type_str)
testlog.LogParam('board_id_flags', board_id_flags_str)
succ = True
# yapf: disable
if self.args.board_id_type is not None: # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
# yapf: enable
# yapf: disable
if board_id.type != self.args.board_id_type: # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
# yapf: enable
testlog.AddFailure('BoardIDTypeMismatch', '')
succ = False
# yapf: disable
if self.args.board_id_flags is not None: # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
# yapf: enable
# yapf: disable
if board_id.flags != self.args.board_id_flags: # type: ignore #TODO(b/338318729) Fixit! # pylint: disable=line-too-long
# yapf: enable
testlog.AddFailure('BoardIDFlagsMismatch', '')
succ = False
if not succ:
self.FailTask('Board ID mismatched.')