1# Copyright 2016 The Chromium OS Authors. All rights reserved. 2# Use of this source code is governed by a BSD-style license that can be 3# found in the LICENSE file. 4 5import logging 6import re 7import os 8 9from autotest_lib.client.common_lib import error 10from autotest_lib.client.common_lib import utils 11from autotest_lib.server.cros.faft.firmware_test import FirmwareTest 12 13 14class platform_Flashrom(FirmwareTest): 15 """ 16 Test flashrom works correctly by calling 17 chromeos-firmwareupdate --mode=factory. 18 """ 19 version = 1 20 21 22 def initialize(self, host, cmdline_args): 23 # This test assume the system already have the latest RW from 24 # shellball. If you not sure, run chromeos-firmware --mode=factory. 25 # Device should have WP disable. 26 27 # Parse arguments from command line 28 dict_args = utils.args_to_dict(cmdline_args) 29 super(platform_Flashrom, self).initialize(host, cmdline_args) 30 31 def run_cmd(self, command, checkfor=''): 32 """ 33 Log and execute command and return the output. 34 35 @param command: Command to execute on device. 36 @param checkfor: If not emmpty, fail test if checkfor not in output. 37 @returns the output of command. 38 """ 39 command = command + ' 2>&1' 40 logging.info('Execute %s', command) 41 output = self.faft_client.system.run_shell_command_get_output(command) 42 logging.info('Output >>> %s <<<', output) 43 if checkfor and checkfor not in '\n'.join(output): 44 raise error.TestFail('Expect %s in output of %s' % 45 (checkfor, '\n'.join(output))) 46 return output 47 48 def _check_wp_disable(self): 49 """Check firmware is write protect disabled.""" 50 self.run_cmd('flashrom -p host --wp-status', checkfor='is disabled') 51 if self.faft_config.chrome_ec: 52 self.run_cmd('flashrom -p ec --wp-status', checkfor='is disabled') 53 if self.faft_config.chrome_usbpd: 54 self.run_cmd('flashrom -p ec:dev=1 --wp-status', 55 checkfor='is disabled') 56 57 def _get_eeprom(self, fmap): 58 """Get fmap start and size. 59 60 @return tuple for start and size for fmap. 61 """ 62 # $ mosys eeprom map | grep RW_SECTION_B 63 # host_firmware | RW_SECTION_B | 0x005f0000 | 0x003f0000 | static 64 output = self.run_cmd('mosys eeprom map | grep %s' % fmap) 65 fmap_data = map(lambda s:s.strip(), output[0].split('|')) 66 logging.info('fmap %s', fmap_data) 67 return (int(fmap_data[2], 16), int(fmap_data[3], 16)) 68 69 def run_once(self, dev_mode=True): 70 # 1) Check SW WP is disabled. 71 self._check_wp_disable() 72 73 # Output location on DUT. 74 # Set if you want to preserve output content for debug. 75 tmpdir = os.getenv('DUT_TMPDIR') 76 if not tmpdir: tmpdir = '/tmp' 77 78 # 2) Erase RW section B. Needed CL 329549 starting with R51-7989.0.0. 79 # before this change -E erase everything. 80 self.run_cmd('flashrom -E -i RW_SECTION_B', 'SUCCESS') 81 82 # 3) Reinstall RW B (Test flashrom) 83 self.run_cmd('chromeos-firmwareupdate --mode=factory', 84 '(factory_install) completed.') 85 86 # 4) Check that device can be rebooted. 87 self.switcher.mode_aware_reboot() 88 89 # 5) Compare flash section B vs shellball section B 90 # 5.1) Extract shellball RW section B. 91 outdir = self.run_cmd('chromeos-firmwareupdate --sb_extract')[-1] 92 shball_path = outdir.split()[-1] 93 shball_bios = os.path.join(shball_path, 'bios.bin') 94 shball_rw_b = os.path.join(shball_path, 'shball_rw_b.bin') 95 96 # Extract RW B, offset detail 97 # Figure out section B start byte and size. 98 (Bstart, Blen) = self._get_eeprom('RW_SECTION_B') 99 self.run_cmd('dd bs=1 skip=%d count=%d if=%s of=%s 2>&1' 100 % (Bstart, Blen, shball_bios, shball_rw_b), '%d bytes' % Blen) 101 102 # 5.2) Extract flash RW section B. 103 # skylake cannot read only section B, see http://crosbug.com/p/52061 104 rw_b2 = os.path.join(tmpdir, 'rw_b2.bin') 105 self.run_cmd('flashrom -r -i RW_SECTION_B:%s' % rw_b2, 'SUCCESS') 106 107 # 5.3) Compare output of 5.1 vs 5.2 108 result_output = self.run_cmd('cmp %s %s' % (shball_rw_b, rw_b2)) 109 logging.info('cmp %s %s == %s', shball_rw_b, rw_b2, result_output) 110 111 # 6) Report result. 112 if ''.join(result_output) != '': 113 raise error.TestFail('Mismatch between %s and %s' % (shball_rw_b, rw_b2)) 114