blob: 25919c702604cc21e0d0421daf3da6260a6e1ec6 [file] [log] [blame]
# Copyright 2016 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
import os
from autotest_lib.client.common_lib import error
from autotest_lib.client.common_lib import utils
from autotest_lib.server.cros.faft.firmware_test import FirmwareTest
class platform_Flashrom(FirmwareTest):
Test flashrom works correctly by calling
chromeos-firmwareupdate --mode=factory.
version = 1
def initialize(self, host, cmdline_args):
# This test assume the system already have the latest RW from
# shellball. If you not sure, run chromeos-firmware --mode=factory.
# Device should have WP disable.
# Parse arguments from command line
dict_args = utils.args_to_dict(cmdline_args)
super(platform_Flashrom, self).initialize(host, cmdline_args)
def run_cmd(self, command, checkfor=''):
Log and execute command and return the output.
@param command: Command to execute on device.
@param checkfor: If not emmpty, fail test if checkfor not in output.
@returns the output of command.
command = command + ' 2>&1''Execute %s', command)
output = self.faft_client.system.run_shell_command_get_output(command)'Output >>> %s <<<', output)
if checkfor and checkfor not in '\n'.join(output):
raise error.TestFail('Expect %s in output of %s' %
(checkfor, '\n'.join(output)))
return output
def _check_wp_disable(self):
"""Check firmware is write protect disabled."""
self.run_cmd('flashrom -p host --wp-status', checkfor='is disabled')
if self.faft_config.chrome_ec:
self.run_cmd('flashrom -p ec --wp-status', checkfor='is disabled')
if self.faft_config.chrome_usbpd:
self.run_cmd('flashrom -p ec:type=pd --wp-status',
checkfor='is disabled')
def _get_region(self, fmap_filename, region):
"""Get region start and size from fmap.
@param fmap_filename: Path to dump of FMAP.
@param region: The region name.
@return tuple of start and size for the region.
output = self.run_cmd('dump_fmap -p %s %s' % (fmap_filename, region))
_, start, size = output[0].split()
return int(start), int(size)
def run_once(self, dev_mode=True):
"""Main test logic"""
# 1) Check SW WP is disabled.
# Output location on DUT.
# Set if you want to preserve output content for debug.
tmpdir = os.getenv('DUT_TMPDIR')
if not tmpdir: tmpdir = '/tmp'
# 2) Erase RW section B. Needed CL 329549 starting with R51-7989.0.0.
# before this change -E erase everything.
self.run_cmd('flashrom -E -i RW_SECTION_B', 'SUCCESS')
# 3) Reinstall RW B (Test flashrom)
self.run_cmd('chromeos-firmwareupdate --mode=factory', 'SUCCESS')
# 4) Check that device can be rebooted.
# 5) Compare flash section B vs shellball section B
# 5.1) Extract shellball RW section B form the appropriate bios.bin
# found the firmware tarball on the DUT.
shball_bios = os.path.join(
# Temp file to store a section read from the chip.
shball_rw_b = os.path.join(
'shball_rw_b.bin')'Using fw image %s, temp file %s',
shball_bios, shball_rw_b)
# Extract FMAP
fmap = os.path.join(tmpdir, 'fmap.bin')
self.run_cmd('flashrom -r -i FMAP:%s' % fmap, 'SUCCESS')
# Extract RW B, offset detail
# Figure out section B start byte and size.
(Bstart, Blen) = self._get_region(fmap, 'RW_SECTION_B')
self.run_cmd('dd bs=1 skip=%d count=%d if=%s of=%s 2>&1'
% (Bstart, Blen, shball_bios, shball_rw_b), '%d bytes' % Blen)
# 5.2) Extract flash RW section B.
# skylake cannot read only section B, see
rw_b2 = os.path.join(tmpdir, 'rw_b2.bin')
self.run_cmd('flashrom -r -i RW_SECTION_B:%s' % rw_b2, 'SUCCESS')
# 5.3) Compare output of 5.1 vs 5.2
result_output = self.run_cmd('cmp %s %s' % (shball_rw_b, rw_b2))'cmp %s %s == %s', shball_rw_b, rw_b2, result_output)
# 6) Report result.
if ''.join(result_output) != '':
raise error.TestFail('Mismatch between %s and %s' % (shball_rw_b, rw_b2))