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 re 7import time 8 9from autotest_lib.client.common_lib import error 10from autotest_lib.server.cros.faft.cr50_test import Cr50Test 11 12 13class firmware_Cr50WPG3(Cr50Test): 14 """Verify WP in G3.""" 15 version = 1 16 17 WAIT_FOR_STATE = 10 18 WP_REGEX = r'write protect is ((en|dis)abled)\.' 19 FLASHROM_WP_CMD = ('sudo flashrom -p raiden_debug_spi:target=AP,serial=%s ' 20 '--wp-status') 21 22 def cleanup(self): 23 """Reenable servo wp.""" 24 self.cr50.send_command('rddkeepalive disable') 25 self.cr50.send_command('ccdblock IGNORE_SERVO disable') 26 self.servo.enable_main_servo_device() 27 try: 28 if hasattr(self, '_start_fw_wp_vref'): 29 self.servo.set_nocheck('fw_wp_state', self._start_fw_wp_state) 30 self.servo.set_nocheck('fw_wp_vref', self._start_fw_wp_vref) 31 finally: 32 super(firmware_Cr50WPG3, self).cleanup() 33 34 35 def generate_flashrom_wp_cmd(self): 36 """Use the cr50 serialname to generate the flashrom command.""" 37 self._flashrom_wp_cmd = self.FLASHROM_WP_CMD % self.cr50.get_serial() 38 39 40 def get_wp_state(self): 41 """Returns 'on' if write protect is enabled. 'off' if it's disabled.""" 42 flashrom_output = self.servo.system_output(self._flashrom_wp_cmd) 43 match = re.search(self.WP_REGEX, flashrom_output) 44 logging.info('WP is %s', match.group(1) if match else 'UKNOWN') 45 logging.info('flashrom output\n%s', flashrom_output) 46 if not match: 47 raise error.TestError('Unable to find WP status in flashrom output') 48 return match.group(1) 49 50 51 def run_once(self): 52 """Verify WP in G3.""" 53 if self.check_cr50_capability(['wp_on_in_g3'], suppress_warning=True): 54 raise error.TestNAError('WP not pulled up in G3') 55 if not self.servo.dts_mode_is_valid(): 56 raise error.TestNAError('Type-C servo v4 required to check wp.') 57 try: 58 self.cr50.ccd_enable(True) 59 except: 60 raise error.TestNAError('CCD required to check wp.') 61 self.generate_flashrom_wp_cmd() 62 63 self.fast_ccd_open(True) 64 # faft-cr50 runs with servo micro and type c servo v4. Use ccdblock to 65 # get cr50 to ignore the fact servo is connected and allow the test to 66 # use ccd to check wp status. 67 self.cr50.send_command('ccdblock IGNORE_SERVO enable') 68 self.cr50.send_command('rddkeepalive enable') 69 self.cr50.get_ccdstate() 70 71 if self.servo.main_device_is_flex(): 72 self._start_fw_wp_state = self.servo.get('fw_wp_state') 73 self._start_fw_wp_vref = self.servo.get('fw_wp_vref') 74 # Stop forcing wp using servo, so we can set it with ccd. 75 self.servo.set_nocheck('fw_wp_state', 'reset') 76 self.servo.set_nocheck('fw_wp_vref', 'off') 77 78 # disable write protect 79 self.cr50.send_command('wp disable atboot') 80 81 # Verify we can see it's disabled. This should always work. If it 82 # doesn't, it may be a setup issue. 83 logging.info('Checking WP from DUT') 84 if self.checkers.crossystem_checker({'wpsw_cur': '1'}): 85 raise error.TestError("WP isn't disabled in S0") 86 87 self.faft_client.system.run_shell_command('poweroff') 88 time.sleep(self.WAIT_FOR_STATE) 89 if hasattr(self, 'ec'): 90 self.ec.send_command('hibernate') 91 time.sleep(self.WAIT_FOR_STATE) 92 93 servo_wp_g3 = self.get_wp_state() 94 self._try_to_bring_dut_up() 95 # Some boards don't power the EC_WP signal in G3, so it can't be 96 # disabled by cr50 in G3. 97 if servo_wp_g3 == 'enabled': 98 raise error.TestFail("WP can't be disabled by Cr50 in G3") 99