1# Copyright 2019 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_Cr50WilcoEcrst(Cr50Test): 13 """Make sure Cr50's ecrst command works as intended. 14 15 EC_RST_L needs to be able to hold the EC in reset. This test verifies the 16 hardware works as intended. 17 """ 18 version = 1 19 20 # How long to hold 'ecrst on', in seconds 21 SHORT_PULSE = 1 22 23 24 def initialize(self, host, cmdline_args, full_args): 25 super(firmware_Cr50WilcoEcrst, self).initialize(host, cmdline_args, 26 full_args) 27 if not self.faft_config.gsc_can_wake_ec_with_reset: 28 raise error.TestNAError("This DUT has a hardware limitation that " 29 "prevents cr50 from waking the EC with " 30 "EC_RST_L.") 31 # This test only makes sense with a Wilco EC. 32 if self.check_ec_capability(): 33 raise error.TestNAError("Nothing needs to be tested on this device") 34 35 # Open Cr50, so the test has access to ecrst. 36 self.fast_ccd_open(True) 37 38 39 def cr50_ecrst(self, state): 40 """Set ecrst on Cr50.""" 41 self.cr50.send_command('ecrst ' + state) 42 43 44 def make_ec_reset_bring_up_ap(self): 45 """Force the AP to come back up after the next EC reset. 46 47 This is not the default behavior on Wilco. The AFTERG3_EN bit in the 48 GEN_PMCON_A register is set by default, which causes the AP to remain 49 down after an EC reset. Clearing it will cause the AP to come after the 50 next EC reset, at which point Coreboot will set it again, making the 51 change in behavior temporary. 52 """ 53 GEN_PMCON_A_ADDRESS = 0xfe001020 54 AFTERG3_EN_BIT = 0x1 55 orig_reg_string = self.faft_client.system.run_shell_command_get_output( 56 'iotools mmio_read32 %#x' % (GEN_PMCON_A_ADDRESS)) 57 logging.info('iotools output: %s', orig_reg_string) 58 orig_reg_value = int(orig_reg_string[0], 0) 59 if orig_reg_value > 0xffffffff: 60 raise error.TestError( 61 'iotools mmio_read32 returned a value larger than 32 bits') 62 new_reg_value = orig_reg_value & ~AFTERG3_EN_BIT 63 self.faft_client.system.run_shell_command('iotools mmio_write32 %#x %#x' 64 % (GEN_PMCON_A_ADDRESS, new_reg_value)) 65 66 67 def check_ecrst_on_off(self): 68 """Verify Cr50 can hold the EC in reset.""" 69 self.make_ec_reset_bring_up_ap() 70 71 self.cr50_ecrst('on') 72 # There isn't a good way to directly tell if the EC is in reset, so 73 # verify that the AP has gone down. 74 self.switcher.wait_for_client_offline() 75 time.sleep(self.SHORT_PULSE) 76 77 self.cr50_ecrst('off') 78 self.switcher.wait_for_client() 79 80 81 def check_ecrst_pulse(self): 82 """Verify Cr50 can reset the EC with a pulse.""" 83 self.make_ec_reset_bring_up_ap() 84 85 orig_boot_id = self.get_bootid() 86 self.cr50_ecrst('pulse') 87 self.switcher.wait_for_client_offline(orig_boot_id=orig_boot_id) 88 self.switcher.wait_for_client() 89 90 91 def run_once(self): 92 """Run the test.""" 93 self.check_ecrst_on_off() 94 self.check_ecrst_pulse() 95