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 5 import logging 6 7 from autotest_lib.client.common_lib import error 8 from autotest_lib.server.cros.faft.firmware_test import FirmwareTest 9 10 11 class 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 self.host = host 22 23 def check_boot_time(self): 24 """Check EC and AP boot times""" 25 # Initialize a list of two strings, one printed by the EC when the AP 26 # is taken out of reset, and another one printed when the EC observes 27 # the AP running. These strings are used as for console output anchors 28 # when calculating the AP boot time. 29 # 30 # This is very approximate, a better long term solution would be to 31 # have the EC print the same fixed strings for these two events on all 32 # platforms. http://crosbug.com/p/21628 has been opened to track this 33 # issue. 34 if self._x86: 35 boot_anchors = ["\[([0-9\.]+) PB", "\[([0-9\.]+) .*(HC 0x|Port 80|ACPI query)"] 36 elif self._arm_legacy: 37 boot_anchors = ["\[([0-9\.]+) AP running ...", 38 "\[([0-9\.]+) XPSHOLD seen"] 39 else: 40 boot_anchors = ["\[([0-9\.]+) power state 1 = S5", 41 "\[([0-9\.]+) power state 3 = S0"] 42 43 # regular expression to say that EC is ready. For systems that 44 # run out of ram there is a second boot where the PMIC is 45 # asked to power cycle the EC to be 100% sure (I wish) that 46 # the code is clean. Looking for the "Inits done" generates a 47 # match after the first boot, and introduces a race between 48 # the EC booting the second time and the test sending the 49 # power_cmd. 50 if self._doubleboot: 51 ec_ready = ["(?ms)UART.*UART.*?\[([0-9.]+) "] 52 else: 53 ec_ready = ["([0-9.]+) Inits done"] 54 55 # Really before sending the power on console command, we should wait 56 # until the console task is ready to receive input. The console task 57 # prints a string when it's ready to do so, so let's search for that 58 # too. 59 ec_ready.append("Console is enabled") 60 61 power_cmd = "powerbtn" if self.faft_config.ec_has_powerbtn_cmd else \ 62 "power on" 63 # Try the EC reboot command several times in case the console 64 # output is not clean enough for the full string to be found. 65 retry = 10 66 while retry > 0: 67 retry = retry - 1 68 try: 69 reboot = self.ec.send_command_get_output( 70 "reboot ap-off", ec_ready) 71 break 72 except error.TestFail: 73 logging.info("Unable to parse EC console output, " 74 "%d more attempts", retry) 75 if retry == 0: 76 # If the magic string was not found reboot the EC and wait 77 # for the host to come up so it is ready for the next test. 78 self.ec.reboot() 79 self.host.wait_up(timeout=30) 80 raise error.TestFail("Unable to reboot EC cleanly, " + 81 "Please try removing AC power") 82 logging.debug("reboot: %r", reboot) 83 84 power_press = self.ec.send_command_get_output( 85 power_cmd, boot_anchors) 86 reboot_time = float(reboot[0][1]) 87 power_press_time = float(power_press[0][1]) 88 firmware_resp_time = float(power_press[1][1]) 89 boot_time = firmware_resp_time - power_press_time 90 logging.info("EC cold boot time: %f s", reboot_time) 91 if reboot_time > 1.0: 92 raise error.TestFail("EC cold boot time longer than 1 second.") 93 logging.info("EC boot time: %f s", boot_time) 94 if boot_time > 1.0: 95 raise error.TestFail("Boot time longer than 1 second.") 96 97 def is_arm_legacy_board(self): 98 arm_legacy = ('Snow', 'Spring', 'Pit', 'Pi', 'Big', 'Blaze', 'Kitty') 99 output = self.faft_client.system.get_platform_name() 100 return output in arm_legacy 101 102 def run_once(self): 103 if not self.check_ec_capability(): 104 raise error.TestNAError("Nothing needs to be tested on this device") 105 self._x86 = ('x86' in self.faft_config.ec_capability) 106 self._doubleboot = ('doubleboot' in self.faft_config.ec_capability) 107 self._arm_legacy = self.is_arm_legacy_board() 108 dev_mode = self.checkers.crossystem_checker({'devsw_boot': '1'}) 109 logging.info("Reboot and check EC cold boot time and host boot time.") 110 self.switcher.mode_aware_reboot('custom', self.check_boot_time) 111 112 def cleanup(self): 113 # Restore the ec_uart_regexp to None 114 try: 115 self.ec.set_uart_regexp('None') 116 except Exception as e: 117 logging.error("Caught exception: %s", str(e)) 118 super(firmware_ECBootTime, self).cleanup() 119