Home | History | Annotate | Download | only in firmware_ECBootTime
      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