# Copyright (c) 2015 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 time from autotest_lib.client.common_lib import error from autotest_lib.server.cros import vboot_constants as vboot from autotest_lib.server.cros.faft.firmware_test import FirmwareTest from autotest_lib.server.cros.faft.utils import mode_switcher class firmware_ECLidShutdown(FirmwareTest): """ Testing GBB_FLAG_DISABLE_LID_SHUTDOWN flag """ version = 1 # Delay between closing and opening the lid LID_DELAY = 2 # time to wait before checking if DUT booted into OS mode BOOTUP_TIME = 30 # # times to check if DUT in expected power state # This accomodates if DUT needs to transition into certain states. PWR_RETRIES = 13 def initialize(self, host, cmdline_args): super(firmware_ECLidShutdown, self).initialize(host, cmdline_args) self.setup_usbkey(usbkey=False) def cleanup(self): """If DUT not pingable, may be still stuck in recovery mode. Reboot it. Also, reset GBB_FLAGS and make sure that lid set to open (in case of error). """ # reset ec_uart_regexp to prevent timeouts in case there was # an error before we could reset it self._reset_ec_regexp() if self.servo.get('lid_open') == 'no': self.servo.set('lid_open', 'yes') self.clear_set_gbb_flags(vboot.GBB_FLAG_DISABLE_LID_SHUTDOWN, 0) try: self.switcher.wait_for_client() except ConnectionError: logging.error("ERROR: client not in OS mode. Rebooting ...") # reboot back to OS mode self.switcher.mode_aware_reboot(reboot_type='cold', sync_before_boot=False) super(firmware_ECLidShutdown, self).cleanup() def _reset_ec_regexp(self): """Reset ec_uart_regexp field Needs to be done for the ec_uart_regexp otherwise dut-control command will time out due to no match. """ self.servo.set('ec_uart_regexp', 'None') def verify_lid_shutdown(self): """ Make sure that firmware boots into OS with lid closed """ self.clear_set_gbb_flags(vboot.GBB_FLAG_DISABLE_LID_SHUTDOWN, 0) # reboot into recovery mode and wait a bit for it to actually get there self.faft_client.system.request_recovery_boot() self.switcher.simple_reboot() time.sleep(self.faft_config.firmware_screen) # close/open lid self.servo.set('lid_open', 'no') time.sleep(self.LID_DELAY) if not self.wait_power_state("G3", self.PWR_RETRIES): logging.error("ERROR: EC does not shut down") return False self.servo.set('lid_open', 'yes') # ping DUT - should boot into OS now self._reset_ec_regexp() self.switcher.wait_for_client() return True def check_disable_lid_shutdown(self): """ Set flag to disable shutdown of DUT when lid closed. Then check if DUT shuts down during recovery mode screen. """ # enable shutdown flag self.clear_set_gbb_flags(0, vboot.GBB_FLAG_DISABLE_LID_SHUTDOWN) # reboot into recovery mode and wait a bit for it to get there self.faft_client.system.request_recovery_boot() self.switcher.simple_reboot() time.sleep(self.faft_config.firmware_screen) # close/open the lid self.servo.set('lid_open', 'no') time.sleep(self.LID_DELAY) if not self.wait_power_state("S0", self.PWR_RETRIES): logging.error("ERROR: EC shuts down") return False self.servo.set('lid_open', 'yes') # this should be more than enough time for system to boot up # if it was going to. time.sleep(self.BOOTUP_TIME) # should still be offline self.switcher.wait_for_client_offline() # reboot back to OS mode self.switcher.mode_aware_reboot(reboot_type='cold', sync_before_boot=False) # disable flag self._reset_ec_regexp() return True def run_once(self): if not self.check_ec_capability(['lid']): raise error.TestNAError("This device needs a lid to run this test") logging.info("Verify DUT with DISABLE_LID_SHUTDOWN disabled") self.check_state(self.verify_lid_shutdown) logging.info("Verify DUT with DISABLE_LID_SHUTDOWN enabled") self.check_state(self.check_disable_lid_shutdown)