• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Copyright 2018 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
5from __future__ import print_function
6
7import logging
8import time
9
10from autotest_lib.client.common_lib import error
11from autotest_lib.server.cros.faft.cr50_test import Cr50Test
12from autotest_lib.server.cros.servo import servo
13
14
15class firmware_Cr50ECReset(Cr50Test):
16    """Make sure 'cr50 ecrst' works as intended
17
18    EC_RST_L needs to be able to wake the EC from hibernate and hold the EC in
19    reset. This test verifies the hardware works as intended
20    """
21    version = 1
22
23    # Delays used by the test. Time is given in seconds
24    # Used to wait long enough for the EC to enter/resume from hibernate
25    EC_SETTLE_TIME = 10
26    RELEASE_RESET_DELAY = 3
27    SHORT_PULSE = 1
28
29
30    def initialize(self, host, cmdline_args, full_args):
31        super(firmware_Cr50ECReset, self).initialize(host, cmdline_args,
32                                                     full_args)
33        if not self.faft_config.gsc_can_wake_ec_with_reset:
34            raise error.TestNAError("This DUT has a hardware limitation that "
35                                    "prevents cr50 from waking the EC with "
36                                    "EC_RST_L.")
37        # Don't bother if there is no Chrome EC or if EC hibernate doesn't work.
38        if not self.check_ec_capability():
39            raise error.TestNAError("Nothing needs to be tested on this device")
40        self.check_ec_hibernate()
41
42
43    def cleanup(self):
44        """Make sure the EC is on, if there is a Chrome EC."""
45        if self.check_ec_capability():
46            self.guarantee_ec_is_up()
47        super(firmware_Cr50ECReset, self).cleanup()
48
49
50    def ec_is_up(self):
51        """If the console is responsive, then the EC is awake"""
52        time.sleep(self.EC_SETTLE_TIME)
53        try:
54            self.ec.send_command_get_output('time', ['.*>'])
55        except servo.UnresponsiveConsoleError as e:
56            logging.info(str(e))
57            return False
58        else:
59            return True
60
61
62    def cold_reset(self, state):
63        """Set cold reset"""
64        self.servo.set('cold_reset', state)
65
66
67    def power_button(self, state):
68        """Press or release the power button"""
69        self.servo.set('pwr_button', 'press' if state == 'on' else 'release')
70
71
72    def cr50_ecrst(self, state):
73        """Set ecrst on cr50"""
74        self.cr50.send_command('ecrst ' + state)
75
76
77    def wake_ec(self, wake_method):
78        """Pulse the wake method to wake the EC
79
80        Args:
81            wake_method: a function that takes in 'on' or 'off' to control the
82                         wake source.
83        """
84        wake_method('on')
85        time.sleep(self.SHORT_PULSE)
86        wake_method('off')
87
88
89    def ec_hibernate(self):
90        """Put the EC in hibernate"""
91        self.ec.send_command('hibernate')
92        if self.ec_is_up():
93            raise error.TestError('Could not put the EC into hibernate')
94
95
96    def guarantee_ec_is_up(self):
97        """Make sure ec isn't held in reset. Use the power button to wake it
98
99        The power button wakes the EC on all systems. Use that to wake the EC
100        and make sure all versions of ecrst are released.
101        """
102        self.cold_reset('off')
103        self.cr50_ecrst('off')
104        time.sleep(self.RELEASE_RESET_DELAY)
105        self.wake_ec(self.power_button)
106        if not self.ec_is_up():
107            raise error.TestError('Could not recover EC')
108
109
110    def can_wake_ec(self, wake_method):
111        """Put the EC in hibernate and verify it can wake up with wake_method
112
113        Args:
114            wake_method: a function that takes in 'on' or 'off' to control the
115                         wake source.
116        Returns:
117            True if wake_method can be used to wake the EC from hibernate
118        """
119        self.ec_hibernate()
120        self.wake_ec(self.cold_reset)
121        wake_successful = self.ec_is_up()
122        self.guarantee_ec_is_up()
123        return wake_successful
124
125
126    def check_basic_ecrst(self):
127        """Verify cr50 can hold the EC in reset"""
128        self.cr50_ecrst('on')
129        if self.ec_is_up():
130            raise error.TestFail('Could not use cr50 ecrst to hold the EC in '
131                                 'reset')
132        # Verify cr50 can release the EC from reset
133        self.cr50_ecrst('off')
134        if not self.ec_is_up():
135            raise error.TestFail('Could not release the EC from reset')
136        self.guarantee_ec_is_up()
137
138    def check_ec_hibernate(self):
139        """Verify EC hibernate"""
140        try:
141            self.ec_hibernate()
142        except error.TestError as e:
143            if 'Could not put the EC into hibernate' in str(e):
144                raise error.TestNAError("EC hibernate doesn't work.")
145        finally:
146            self.guarantee_ec_is_up()
147
148
149    def run_once(self):
150        """Make sure 'cr50 ecrst' works as intended."""
151        failed_wake = []
152
153        # Open cr50 so the test has access to ecrst
154        self.fast_ccd_open(True)
155
156        self.check_basic_ecrst()
157
158        if not self.can_wake_ec(self.cr50_ecrst):
159            failed_wake.append('cr50 ecrst')
160
161        if not self.can_wake_ec(self.cold_reset):
162            failed_wake.append('servo cold_reset')
163
164        if failed_wake:
165            raise error.TestFail('Failed to wake EC with %s' %
166                                 ' and '.join(failed_wake))
167