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