# Copyright (c) 2013 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 re from autotest_lib.client.common_lib import error from autotest_lib.server.cros.faft.firmware_test import FirmwareTest class firmware_ECHash(FirmwareTest): """ Servo based EC hash recompute test. This test ensures that the AP will ask the EC to recompute the hash if the current hash isn't the right size/offset. Use the 'echash' command of EC tool to request the hash of some other part of EC EEPROM, then warm-reboot the AP and check what hash the EC has after booting. AP-RW should have requested the EC recompute the hash of EC-RW. """ version = 1 def initialize(self, host, cmdline_args): super(firmware_ECHash, self).initialize(host, cmdline_args) self.backup_firmware() self.switcher.setup_mode('normal') self.setup_usbkey(usbkey=False) self.setup_rw_boot() def cleanup(self): try: self.restore_firmware() except Exception as e: logging.error("Caught exception: %s", str(e)) super(firmware_ECHash, self).cleanup() def get_echash(self): """Get the current EC hash via ectool/fwtool.""" if self.faft_client.system.has_host(): command = 'fwtool ec echash' else: command = 'ectool echash' lines = self.faft_client.system.run_shell_command_get_output(command) pattern = re.compile('hash: ([0-9a-f]{64})') for line in lines: matched = pattern.match(line) if matched: return matched.group(1) raise error.TestError("Wrong output of '%s': \n%s" % (command, '\n'.join(lines))) def invalidate_echash(self): """Invalidate the EC hash by requesting hashing some other part.""" if self.faft_client.system.has_host(): command = 'fwtool ec echash recalc 0 4' else: command = 'ectool echash recalc 0 4' self.faft_client.system.run_shell_command(command) def save_echash_and_invalidate(self): """Save the current EC hash and invalidate it.""" self.original_echash = self.get_echash() logging.info("Original EC hash: %s", self.original_echash) self.invalidate_echash() invalid_echash = self.get_echash() logging.info("Invalid EC hash: %s", invalid_echash) if invalid_echash == self.original_echash: raise error.TestFail("Failed to invalidate EC hash") def compare_echashes(self): """Compare the current EC with the original one.""" recomputed_echash = self.get_echash() logging.info("Recomputed EC hash: %s", recomputed_echash) return recomputed_echash == self.original_echash def run_once(self): if not self.check_ec_capability(): raise error.TestNAError("Nothing needs to be tested on this device") logging.info("Save the EC hash, invalidate it, and warm reboot.") self.save_echash_and_invalidate() self.switcher.mode_aware_reboot() logging.info("Compare the recomputed EC hash with the original one.") self.check_state(self.compare_echashes)