Home | History | Annotate | Download | only in firmware_ECLidShutdown
      1 # Copyright (c) 2015 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 time
      7 
      8 from autotest_lib.client.common_lib import error
      9 from autotest_lib.server.cros import vboot_constants as vboot
     10 from autotest_lib.server.cros.faft.firmware_test import FirmwareTest
     11 from autotest_lib.server.cros.faft.utils import mode_switcher
     12 
     13 class firmware_ECLidShutdown(FirmwareTest):
     14     """
     15     Testing GBB_FLAG_DISABLE_LID_SHUTDOWN flag
     16     """
     17     version = 1
     18 
     19     # Delay between closing and opening the lid
     20     LID_DELAY = 2
     21     # time to wait before checking if DUT booted into OS mode
     22     BOOTUP_TIME = 30
     23     # time to wait to let DUT transition into recovery mode
     24     RECOVERY_DELAY = 1
     25     # # times to check if DUT in expected power state
     26     # This accomodates if DUT needs to transition into certain states.
     27     PWR_RETRIES = 13
     28 
     29     def initialize(self, host, cmdline_args):
     30         super(firmware_ECLidShutdown, self).initialize(host, cmdline_args)
     31         self.setup_usbkey(usbkey=False)
     32 
     33     def cleanup(self):
     34         """If DUT not pingable, may be still stuck in recovery mode.
     35         Reboot it.  Also, reset GBB_FLAGS and make sure that lid set
     36         to open (in case of error).
     37         """
     38         # reset ec_uart_regexp to prevent timeouts in case there was
     39         # an error before we could reset it
     40         self._reset_ec_regexp()
     41         if self.servo.get('lid_open') == 'no':
     42             self.servo.set('lid_open', 'yes')
     43         self.clear_set_gbb_flags(vboot.GBB_FLAG_DISABLE_LID_SHUTDOWN,
     44                                  0)
     45         try:
     46             self.switcher.wait_for_client()
     47         except ConnectionError:
     48             logging.error("ERROR: client not in OS mode.  Rebooting ...")
     49             # reboot back to OS mode
     50             self.switcher.mode_aware_reboot(reboot_type='cold',
     51                                             sync_before_boot=False)
     52         super(firmware_ECLidShutdown, self).cleanup()
     53 
     54     def _reset_ec_regexp(self):
     55         """Reset ec_uart_regexp field
     56 
     57         Needs to be done for the ec_uart_regexp otherwise
     58         dut-control command will time out due to no match.
     59         """
     60         self.servo.set('ec_uart_regexp', 'None')
     61 
     62     def verify_lid_shutdown(self):
     63         """
     64         Make sure that firmware boots into OS with lid closed
     65         """
     66         self.clear_set_gbb_flags(vboot.GBB_FLAG_DISABLE_LID_SHUTDOWN,
     67                                  0)
     68         # reboot into recovery mode and wait a bit for it to actually get there
     69         self.faft_client.system.request_recovery_boot()
     70         self.switcher.mode_aware_reboot(wait_for_dut_up=False)
     71         time.sleep(self.RECOVERY_DELAY)
     72 
     73         # close/open lid
     74         self.servo.set('lid_open', 'no')
     75         time.sleep(self.LID_DELAY)
     76         if not self.wait_power_state("G3", self.PWR_RETRIES):
     77             logging.error("ERROR: EC does not shut down")
     78             return False
     79         self.servo.set('lid_open', 'yes')
     80 
     81         # ping DUT - should boot into OS now
     82         self._reset_ec_regexp()
     83         self.switcher.wait_for_client()
     84 
     85         return True
     86 
     87     def check_disable_lid_shutdown(self):
     88         """
     89         Set flag to disable shutdown of DUT when lid closed.  Then check
     90         if DUT shuts down during recovery mode screen.
     91         """
     92         # enable shutdown flag
     93         self.clear_set_gbb_flags(0,
     94                                  vboot.GBB_FLAG_DISABLE_LID_SHUTDOWN)
     95         # reboot into recovery mode and wait a bit for it to get there
     96         self.faft_client.system.request_recovery_boot()
     97         self.switcher.mode_aware_reboot(wait_for_dut_up=False)
     98         time.sleep(self.RECOVERY_DELAY)
     99 
    100         # close/open the lid
    101         self.servo.set('lid_open', 'no')
    102         time.sleep(self.LID_DELAY)
    103         if not self.wait_power_state("S0", self.PWR_RETRIES):
    104             logging.error("ERROR: EC shuts down")
    105             return False
    106         self.servo.set('lid_open', 'yes')
    107 
    108         # this should be more than enough time for system to boot up
    109         # if it was going to.
    110         time.sleep(self.BOOTUP_TIME)
    111 
    112         # should still be offline
    113         self.switcher.wait_for_client_offline()
    114 
    115         # reboot back to OS mode
    116         self.switcher.mode_aware_reboot(reboot_type='cold',
    117                                         sync_before_boot=False)
    118 
    119         # disable flag
    120         self._reset_ec_regexp()
    121         return True
    122 
    123 
    124     def run_once(self):
    125         if not self.check_ec_capability(['lid']):
    126             raise error.TestNAError("This device needs a lid to run this test")
    127 
    128         logging.info("Verify DUT with DISABLE_LID_SHUTDOWN disabled")
    129         self.check_state(self.verify_lid_shutdown)
    130 
    131         logging.info("Verify DUT with DISABLE_LID_SHUTDOWN enabled")
    132         self.check_state(self.check_disable_lid_shutdown)
    133 
    134