156 lines
6.9 KiB
Python
156 lines
6.9 KiB
Python
# 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
|
|
|
|
|
|
class firmware_ECLidShutdown(FirmwareTest):
|
|
"""
|
|
Exercises the GBB_FLAG_DISABLE_LID_SHUTDOWN flag: confirms that when the
|
|
flag is enabled, a closed lid will not prevent booting.
|
|
"""
|
|
version = 1
|
|
|
|
# Delay to allow for a power state change after closing or opening the lid.
|
|
# This value is determined experimentally.
|
|
LID_POWER_STATE_DELAY = 5
|
|
POWER_STATE_CHECK_TRIES = 3
|
|
POWER_STATE_CHECK_DELAY = 10
|
|
IGNORE_LID_IN_USERSPACE_CMD = 'echo 0 > /var/lib/power_manager/use_lid'
|
|
CHECK_POWER_MANAGER_CFG_DEFAULT = '[ ! -f /var/lib/power_manager/use_lid ]'
|
|
|
|
def initialize(self, host, cmdline_args):
|
|
super(firmware_ECLidShutdown, self).initialize(host, cmdline_args)
|
|
self.setup_usbkey(usbkey=False)
|
|
|
|
def cleanup(self):
|
|
"""Reopens the lid, boots the DUT to normal mode, and clears the GBB
|
|
flag manipulated in this test.
|
|
"""
|
|
try:
|
|
self._reset_ec_regexp()
|
|
logging.info('The screen should turn back on now, during cleanup.')
|
|
self.servo.set_nocheck('lid_open', 'yes')
|
|
time.sleep(self.LID_POWER_STATE_DELAY)
|
|
if self.servo.get('lid_open') != 'yes':
|
|
raise error.TestFail('The device did not stay in a mechanical'
|
|
'on state after a lid open.')
|
|
self.switcher.simple_reboot(sync_before_boot=False)
|
|
self.switcher.wait_for_client()
|
|
self.clear_set_gbb_flags(vboot.GBB_FLAG_DISABLE_LID_SHUTDOWN, 0)
|
|
self.faft_client.system.run_shell_command(
|
|
self.CHECK_POWER_MANAGER_CFG_DEFAULT)
|
|
except Exception as exc:
|
|
logging.debug(
|
|
'Exception during cleanup considered non-fatal. '
|
|
'Traceback:', exc_info=True)
|
|
super(firmware_ECLidShutdown, self).cleanup()
|
|
|
|
def _reset_ec_regexp(self):
|
|
"""Resets 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 _check_lid_shutdown(self):
|
|
"""
|
|
Checks behavior with GBB_FLAG_DISABLE_LID_SHUTDOWN disabled.
|
|
|
|
Clears the flag that disables listening to the lid for shutdown (when
|
|
the lid is closed at boot), boots into recovery mode and confirms that
|
|
the device stays in a mechanical off state. Reopens the lid and
|
|
restores the device.
|
|
"""
|
|
self.clear_set_gbb_flags(vboot.GBB_FLAG_DISABLE_LID_SHUTDOWN, 0)
|
|
# TODO(kmshelton): Simplify to not use recovery mode.
|
|
self.faft_client.system.request_recovery_boot()
|
|
self.servo.set('lid_open', 'no')
|
|
time.sleep(self.LID_POWER_STATE_DELAY)
|
|
self.switcher.simple_reboot(sync_before_boot=False)
|
|
# Some boards may reset the lid_open state when AP reboot,
|
|
# check b/137612865
|
|
time.sleep(self.faft_config.ec_boot_to_console)
|
|
if self.servo.get('lid_open') != 'no':
|
|
self.servo.set('lid_open', 'no')
|
|
time.sleep(self.LID_POWER_STATE_DELAY)
|
|
time.sleep(self.faft_config.firmware_screen)
|
|
if not self.wait_power_state('G3',
|
|
self.POWER_STATE_CHECK_TRIES,
|
|
self.POWER_STATE_CHECK_DELAY):
|
|
raise error.TestFail('The device did not stay in a mechanical off '
|
|
'state after a lid close and a warm reboot.')
|
|
# kukui resets EC on opening the lid in some cases, so
|
|
# using servo.set('lid_open', 'yes') would verify the set result
|
|
# immediately by getting the control back, and this results a failure of
|
|
# console-no-response due to EC reset. We should use set_nocheck
|
|
# instead.
|
|
self.servo.set_nocheck('lid_open', 'yes')
|
|
time.sleep(self.LID_POWER_STATE_DELAY)
|
|
if self.servo.get('lid_open') != 'yes':
|
|
raise error.TestFail('The device did not stay in a mechanical on '
|
|
'state after a lid open.')
|
|
|
|
time.sleep(self.faft_config.firmware_screen)
|
|
self.switcher.simple_reboot(sync_before_boot=False)
|
|
self._reset_ec_regexp()
|
|
self.switcher.wait_for_client()
|
|
|
|
return True
|
|
|
|
def _check_lid_shutdown_disabled(self):
|
|
"""
|
|
Checks behavior with GBB_FLAG_DISABLE_LID_SHUTDOWN enabled.
|
|
|
|
Sets the flag that disables listening to the lid for shutdown (when
|
|
the lid is closed at boot), disables the power daemon, closes the lid,
|
|
boots to a firmware screen.
|
|
"""
|
|
self.clear_set_gbb_flags(0, vboot.GBB_FLAG_DISABLE_LID_SHUTDOWN)
|
|
self.faft_client.system.request_recovery_boot()
|
|
self.faft_client.system.run_shell_command(
|
|
self.IGNORE_LID_IN_USERSPACE_CMD)
|
|
self.servo.set('lid_open', 'no')
|
|
if not self.wait_power_state('S0', self.POWER_STATE_CHECK_TRIES):
|
|
raise error.TestError(
|
|
'The device did not stay in S0 when the lid was closed '
|
|
'with powerd ignoring lid state. Maybe userspace power '
|
|
'management behaviors have changed.')
|
|
self.switcher.simple_reboot(sync_before_boot=False)
|
|
time.sleep(self.faft_config.ec_boot_to_console)
|
|
if self.servo.get('lid_open') != 'no':
|
|
self.servo.set('lid_open', 'no')
|
|
time.sleep(self.LID_POWER_STATE_DELAY)
|
|
logging.info('The screen will remain black, even though we are at a '
|
|
'recovery screen.')
|
|
time.sleep(self.faft_config.firmware_screen)
|
|
if not self.wait_power_state('S0', self.POWER_STATE_CHECK_TRIES):
|
|
raise error.TestFail(
|
|
'The device did get to an active state when warm reset '
|
|
'with the lid off and GBB_FLAG_DISABLE_LID_SHUTDOWN '
|
|
'enabled.')
|
|
|
|
return True
|
|
|
|
def run_once(self):
|
|
"""Runs a single iteration of the test."""
|
|
if not self.check_ec_capability(['lid']):
|
|
raise error.TestNAError('This device needs a lid to run this test')
|
|
|
|
logging.info('Verify the device does shutdown when verified boot '
|
|
'starts while the lid is closed and '
|
|
'GBB_FLAG_DISABLE_LID_SHUTDOWN disabled.')
|
|
self.check_state(self._check_lid_shutdown)
|
|
|
|
logging.info('Verify the device does not shutdown when verified boot '
|
|
'starts while the lid is closed with '
|
|
'GBB_FLAG_DISABLE_LID_SHUTDOWN enabled.')
|
|
self.check_state(self._check_lid_shutdown_disabled)
|