1 # Copyright (c) 2013 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 5 import logging 6 import re 7 8 from autotest_lib.client.common_lib import error 9 from autotest_lib.server.cros.faft.firmware_test import FirmwareTest 10 11 12 class firmware_ECHash(FirmwareTest): 13 """ 14 Servo based EC hash recompute test. 15 16 This test ensures that the AP will ask the EC to recompute the hash if 17 the current hash isn't the right size/offset. Use the 'echash' command 18 of EC tool to request the hash of some other part of EC EEPROM, then 19 warm-reboot the AP and check what hash the EC has after booting. 20 AP-RW should have requested the EC recompute the hash of EC-RW. 21 """ 22 version = 1 23 24 def initialize(self, host, cmdline_args): 25 super(firmware_ECHash, self).initialize(host, cmdline_args) 26 self.backup_firmware() 27 self.switcher.setup_mode('normal') 28 self.setup_usbkey(usbkey=False) 29 self.setup_rw_boot() 30 31 def cleanup(self): 32 try: 33 self.restore_firmware() 34 except Exception as e: 35 logging.error("Caught exception: %s", str(e)) 36 super(firmware_ECHash, self).cleanup() 37 38 def get_echash(self): 39 """Get the current EC hash via ectool/fwtool.""" 40 if self.faft_client.system.has_host(): 41 command = 'fwtool ec echash' 42 else: 43 command = 'ectool echash' 44 lines = self.faft_client.system.run_shell_command_get_output(command) 45 pattern = re.compile('hash: ([0-9a-f]{64})') 46 for line in lines: 47 matched = pattern.match(line) 48 if matched: 49 return matched.group(1) 50 raise error.TestError("Wrong output of '%s': \n%s" % 51 (command, '\n'.join(lines))) 52 53 def invalidate_echash(self): 54 """Invalidate the EC hash by requesting hashing some other part.""" 55 if self.faft_client.system.has_host(): 56 command = 'fwtool ec echash recalc 0 4' 57 else: 58 command = 'ectool echash recalc 0 4' 59 self.faft_client.system.run_shell_command(command) 60 61 def save_echash_and_invalidate(self): 62 """Save the current EC hash and invalidate it.""" 63 self.original_echash = self.get_echash() 64 logging.info("Original EC hash: %s", self.original_echash) 65 self.invalidate_echash() 66 invalid_echash = self.get_echash() 67 logging.info("Invalid EC hash: %s", invalid_echash) 68 if invalid_echash == self.original_echash: 69 raise error.TestFail("Failed to invalidate EC hash") 70 71 def compare_echashes(self): 72 """Compare the current EC with the original one.""" 73 recomputed_echash = self.get_echash() 74 logging.info("Recomputed EC hash: %s", recomputed_echash) 75 return recomputed_echash == self.original_echash 76 77 def run_once(self): 78 if not self.check_ec_capability(): 79 raise error.TestNAError("Nothing needs to be tested on this device") 80 logging.info("Save the EC hash, invalidate it, and warm reboot.") 81 self.save_echash_and_invalidate() 82 self.switcher.mode_aware_reboot() 83 84 logging.info("Compare the recomputed EC hash with the original one.") 85 self.check_state(self.compare_echashes) 86