blob: b695c92b6774071cb52bb81bd249b2679aa072e9 [file] [log] [blame]
# Copyright 2017 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import logging
from autotest_lib.client.common_lib import error
from autotest_lib.client.common_lib.cros import cr50_utils
from autotest_lib.server.cros.faft.cr50_test import Cr50Test
class firmware_Cr50SetBoardId(Cr50Test):
"""Verify cr50-set-board-id.sh
Verify cr50-set-board-id sets the correct board id and flags based on the
given stage.
"""
version = 1
BID_SCRIPT = '/usr/share/cros/cr50-set-board-id.sh'
# the command to get the brand name
GET_BRAND = 'mosys platform brand'
# Used when the flags were not initialized in the factory.
UNKNOWN_FLAGS = 0xff00
# Used for dev, proto, EVT, and DVT phases.
DEVELOPMENT_FLAGS = 0x7f7f
# Used for PVT and MP builds.
RELEASE_FLAGS = 0x7f80
PHASE_FLAGS_DICT = {
'unknown' : UNKNOWN_FLAGS,
'dev' : DEVELOPMENT_FLAGS,
'proto' : DEVELOPMENT_FLAGS,
'evt' : DEVELOPMENT_FLAGS,
'dvt' : DEVELOPMENT_FLAGS,
'mp' : RELEASE_FLAGS,
'pvt' : RELEASE_FLAGS,
}
# The response strings from cr50-set-board-id
SUCCESS = ["Successfully updated board ID to 'BID' with phase 'PHASE'.",
0]
ERROR_UNKNOWN_PHASE = ['Unknown phase (PHASE)', 1]
ERROR_INVALID_RLZ = ['Invalid RLZ brand code (BID).', 1]
ERROR_ALREADY_SET = ['Board ID and flag have already been set.', 2]
ERROR_BID_SET_DIFFERENTLY = ['Board ID has been set differently.', 3]
ERROR_FLAG_SET_DIFFERENTLY = ['Flag has been set differently.', 3]
def initialize(self, host, cmdline_args, full_args, dev_path='', bid=''):
# Restore the original image, rlz code, and board id during cleanup.
super(firmware_Cr50SetBoardId, self).initialize(host, cmdline_args,
full_args, restore_cr50_state=True, cr50_dev_path=dev_path)
if self.servo.running_through_ccd():
raise error.TestNAError('Use a flex cable instead of CCD cable.')
# Update to the dev image so we can erase the board id after we set it.
# This test is verifying cr50-set-board-id and not the actual getting/
# setting of the board id on the cr50 side, so it is ok if the cr50 is
# running a dev image.
self.cr50_update(self.get_saved_cr50_dev_path())
if not self.cr50.has_command('bid'):
raise error.TestNAError('Cr50 image does not support board id')
if not self.host.path_exists(self.BID_SCRIPT):
raise error.TestNAError('Device does not have "cr50-set-board-id"')
result = self.host.run(self.GET_BRAND, ignore_status=True)
platform_brand = result.stdout.strip()
if result.exit_status or not platform_brand:
raise error.TestNAError('Could not get "mosys platform brand"')
self.platform_brand = platform_brand
self.erase_bid()
cr50_utils.StopTrunksd(self.host)
def erase_bid(self):
"""Erase the current board id"""
self.cr50.send_command('eraseflashinfo')
def run_script(self, expected_result, phase, board_id=''):
"""Run the bid script with the given phase and board id
Args:
expected_result: a list with the result message and exit status
phase: The phase string.
board_id: The board id string.
Raises:
TestFail if the expected result message did not match the script
output
"""
message, exit_status = expected_result
# If we expect an error ignore the exit status
ignore_status = not not exit_status
# Run the script with the phase and board id
cmd = '%s %s %s' % (self.BID_SCRIPT, phase, board_id)
result = self.host.run(cmd, ignore_status=ignore_status)
# If we don't give the script a board id, it will use the platform
# brand
expected_board_id = board_id if board_id else self.platform_brand
# Replace the placeholders with the expected board id and phase
message = message.replace('BID', expected_board_id)
message = message.replace('PHASE', phase)
# Compare the expected script output to the actual script result
if message not in result.stdout or exit_status != result.exit_status:
logging.debug(result)
raise error.TestFail('Expected "%s" got "%s"' % (message,
result.stdout))
logging.info(result.stdout)
def run_once(self):
"""Verify cr50-set-board-id.sh"""
# 'A' is too short to be a valid rlz code
self.run_script(self.ERROR_INVALID_RLZ, 'dvt', 'A')
# dummy_phase is not a valid phase
self.run_script(self.ERROR_UNKNOWN_PHASE, 'dummy_phase')
# The rlz code is checked before the phase
self.run_script(self.ERROR_INVALID_RLZ, 'dummy_phase', 'A')
# Set the board id so we can verify cr50-set-board-id has the correct
# response to the board id already being set.
self.run_script(self.SUCCESS, 'dvt', 'TEST')
# mp has different flags than dvt
self.run_script(self.ERROR_FLAG_SET_DIFFERENTLY, 'mp', 'TEST')
# try setting the dvt flags with a different board id
self.run_script(self.ERROR_BID_SET_DIFFERENTLY, 'dvt', 'test')
# running with the same phase and board id will raise an error that the
# board id is already set
self.run_script(self.ERROR_ALREADY_SET, 'dvt', 'TEST')
# Verify each stage sets the right flags
for phase, flags in self.PHASE_FLAGS_DICT.iteritems():
# Erase the board id so we can change it.
self.erase_bid()
# Run the script to set the board id and flags for the given phase.
self.run_script(self.SUCCESS, phase)
# Check that the board id and flags are actually set.
cr50_utils.CheckChipBoardId(self.host, self.platform_brand, flags)