1# Copyright 2022 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.client.common_lib.cros import cr50_utils 10from autotest_lib.server.cros.faft.cr50_test import Cr50Test 11 12 13class firmware_GSCSetAPROV1(Cr50Test): 14 """ 15 Verify a dut can set the AP RO hash when board id type is erased. 16 """ 17 version = 1 18 19 TEST_AP_RO_VER = 1 20 21 # gsctool errors. 22 ERR_UNPROGRAMMED = 'AP RO hash unprogrammed' 23 ERR_BID_PROGRAMMED = 'BID already programmed' 24 25 # ap_ro_hash.py errors. 26 AP_RO_ERR_ALREADY_PROGRAMMED = 'Already programmed' 27 AP_RO_ERR_BID_PROGRAMMED = 'BID programmed' 28 29 def initialize(self, host, cmdline_args, full_args={}): 30 """Initialize servo""" 31 super(firmware_GSCSetAPROV1, 32 self).initialize(host, 33 cmdline_args, 34 full_args, 35 restore_cr50_image=True, 36 restore_cr50_board_id=True) 37 38 if not self.cr50.ap_ro_version_is_supported(self.TEST_AP_RO_VER): 39 raise error.TestNAError('GSC does not support AP RO v%s' % 40 self.TEST_AP_RO_VER) 41 42 def get_hash(self): 43 """Get the hash.""" 44 time.sleep(10) 45 result = cr50_utils.GSCTool(self.host, ['-a', '-A']) 46 saved_hash = result.stdout.split(':')[-1].strip() 47 logging.info('hash: %s', saved_hash) 48 return None if self.ERR_UNPROGRAMMED in saved_hash else saved_hash 49 50 def clear_hash(self, expect_error=False): 51 """Clear the Hash.""" 52 result = cr50_utils.GSCTool(self.host, ['-a', '-H'], 53 ignore_status=expect_error) 54 if expect_error and (result.exit_status != 3 55 or self.ERR_BID_PROGRAMMED not in result.stderr): 56 raise error.TestFail('Unexpected error clearing hash %r', 57 result.stderr) 58 self.get_hash() 59 60 def set_hash(self, expected_error=None): 61 """Set the Hash.""" 62 result = self.host.run('ap_ro_hash.py -v True GBB', 63 ignore_status=not not expected_error) 64 if expected_error: 65 if expected_error not in result.stderr: 66 raise error.TestFail('Did not find %r in error' % 67 expected_error) 68 elif result.exit_status: 69 raise error.TestFail('Error saving hash') 70 return self.get_hash() 71 72 def run_once(self): 73 """Verify the AP RO hash can be updated when the BID type isn't set""" 74 brand = self.get_device_brand() 75 if not brand: 76 raise error.TestNAError('Cannot run without brand') 77 78 # Erase the board id if its set. 79 if not self.cr50.get_board_id()[1]: 80 logging.info('Erasing BID') 81 self.eraseflashinfo_and_restore_image() 82 bid = self.get_saved_cr50_original_version()[2] 83 flags = int(bid.split(':')[-1] if bid else '0', 16) 84 85 self.clear_hash() 86 self.set_hash() 87 self.set_hash(expected_error=self.AP_RO_ERR_ALREADY_PROGRAMMED) 88 89 cr50_utils.SetChipBoardId(self.host, '0xffffffff', flags) 90 91 self.clear_hash() 92 self.set_hash() 93 self.set_hash(expected_error=self.AP_RO_ERR_ALREADY_PROGRAMMED) 94 self.clear_hash() 95 96 cr50_utils.SetChipBoardId(self.host, brand, flags) 97 98 self.clear_hash(expect_error=True) 99 self.set_hash(expected_error=self.AP_RO_ERR_BID_PROGRAMMED) 100