1# Copyright (c) 2012 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 6 7from autotest_lib.client.common_lib import error 8from autotest_lib.server.cros.faft.firmware_test import FirmwareTest 9 10 11class firmware_ECBootTime(FirmwareTest): 12 """ 13 Servo based EC boot time test. 14 """ 15 version = 1 16 17 def initialize(self, host, cmdline_args): 18 super(firmware_ECBootTime, self).initialize(host, cmdline_args) 19 # Only run in normal mode 20 self.switcher.setup_mode('normal') 21 22 def check_boot_time(self): 23 """Check EC and AP boot times""" 24 # Initialize a list of two strings, one printed by the EC when the AP 25 # is taken out of reset, and another one printed when the EC observes 26 # the AP running. These strings are used as for console output anchors 27 # when calculating the AP boot time. 28 # 29 # This is very approximate, a better long term solution would be to 30 # have the EC print the same fixed strings for these two events on all 31 # platforms. http://crosbug.com/p/21628 has been opened to track this 32 # issue. 33 if self._x86: 34 boot_anchors = ["\[([0-9\.]+) PB", "\[([0-9\.]+) Port 80"] 35 elif self._arm_legacy: 36 boot_anchors = ["\[([0-9\.]+) AP running ...", 37 "\[([0-9\.]+) XPSHOLD seen"] 38 else: 39 boot_anchors = ["\[([0-9\.]+) power state 1 = S5", 40 "\[([0-9\.]+) power state 3 = S0"] 41 # regular expression to say that EC is ready. For systems that 42 # run out of ram there is a second boot where the PMIC is 43 # asked to power cycle the EC to be 100% sure (I wish) that 44 # the code is clean. Looking for the "Inits done" generates a 45 # match after the first boot, and introduces a race between 46 # the EC booting the second time and the test sending the 47 # power_cmd. 48 if self._doubleboot: 49 ec_ready = ["\[([0-9.]+) power state 0"] 50 else: 51 ec_ready = ["([0-9.]+) Inits done"] 52 power_cmd = "powerbtn" if self._x86 or self._ryu else "power on" 53 reboot = self.ec.send_command_get_output( 54 "reboot ap-off", ec_ready) 55 power_press = self.ec.send_command_get_output( 56 power_cmd, boot_anchors) 57 reboot_time = float(reboot[0][1]) 58 power_press_time = float(power_press[0][1]) 59 firmware_resp_time = float(power_press[1][1]) 60 boot_time = firmware_resp_time - power_press_time 61 logging.info("EC cold boot time: %f s", reboot_time) 62 if reboot_time > 1.0: 63 raise error.TestFail("EC cold boot time longer than 1 second.") 64 logging.info("EC boot time: %f s", boot_time) 65 if boot_time > 1.0: 66 raise error.TestFail("Boot time longer than 1 second.") 67 68 def is_arm_legacy_board(self): 69 arm_legacy = ('Snow', 'Spring', 'Pit', 'Pi', 'Big', 'Blaze', 'Kitty') 70 output = self.faft_client.system.get_platform_name() 71 return output in arm_legacy 72 73 def is_ryu_board(self): 74 output = self.faft_client.system.get_platform_name() 75 return output == 'Ryu' 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 self._x86 = ('x86' in self.faft_config.ec_capability) 81 self._doubleboot = ('doubleboot' in self.faft_config.ec_capability) 82 self._arm_legacy = self.is_arm_legacy_board() 83 self._ryu = self.is_ryu_board() 84 dev_mode = self.checkers.crossystem_checker({'devsw_boot': '1'}) 85 logging.info("Reboot and check EC cold boot time and host boot time.") 86 self.switcher.mode_aware_reboot('custom', self.check_boot_time) 87 88 def cleanup(self): 89 # Restore the ec_uart_regexp to None 90 self.ec.set_uart_regexp('None') 91