Home | History | Annotate | Download | only in firmware_Cr50GetName
      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 
      5 import logging
      6 import re
      7 
      8 from autotest_lib.client.common_lib import error
      9 from autotest_lib.client.common_lib.cros import cr50_utils
     10 from autotest_lib.server.cros.faft.cr50_test import Cr50Test
     11 
     12 
     13 class firmware_Cr50GetName(Cr50Test):
     14     """Verify cr50-get-name.sh
     15 
     16     Verify cr50-get-name sets the correct board id and flags based on the
     17     given stage.
     18     """
     19     version = 1
     20 
     21     GET_NAME_SCRIPT = '/usr/share/cros/cr50-get-name.sh'
     22     # This translates to 'TEST'
     23     TEST_BRAND = 0x54455354
     24     MAX_VAL = 0xffffffff
     25 
     26 
     27     def initialize(self, host, cmdline_args, dev_path=''):
     28         # Restore the original image, rlz code, and board id during cleanup.
     29         super(firmware_Cr50GetName, self).initialize(host, cmdline_args,
     30             restore_cr50_state=True, cr50_dev_path=dev_path)
     31 
     32         if not self.host.path_exists(self.GET_NAME_SCRIPT):
     33             raise error.TestNAError('Device does not have "cr50-get-name"')
     34 
     35         # Update to the dev image so we can erase the board id after we set it.
     36         # This test is verifying cr50-get-name, so it is ok if cr50 is running a
     37         # dev image.
     38         self.cr50_update(self.get_saved_cr50_dev_path())
     39 
     40         # Stop trunksd so it wont interfere with the update
     41         cr50_utils.StopTrunksd(self.host)
     42 
     43         # Get the current cr50 update messages. The test will keep track of the
     44         # last message and separate the current output from actual test results.
     45         self.get_result()
     46 
     47 
     48     def erase_bid(self):
     49         """Erase the cr50 board id"""
     50         self.cr50.send_command('eraseflashinfo')
     51 
     52 
     53     def get_result(self):
     54         """Return the new cr50 update messages from /var/log/messages"""
     55         # Get the cr50 messages
     56         result = self.host.run('grep cr50 /var/log/messages').stdout.strip()
     57 
     58         if hasattr(self, '_last_message'):
     59             result = result.rsplit(self._last_message, 1)[-1]
     60 
     61         # Save the last line. It will be used to separate the current results
     62         # from later runs.
     63         self._last_message = result.rsplit('\n', 1)[-1]
     64         logging.debug('last cr50 update message: "%s"', self._last_message)
     65         return result
     66 
     67 
     68     def get_expected_result_re(self, brand, flags, erased):
     69         """Return the expected update message re given the test flags
     70 
     71         Args:
     72             brand: The board id value to test.
     73             flags: The flag value to test.
     74             erased: True if the board id is erased
     75 
     76         Returns:
     77             A string with info that must be found in /var/log/messages for valid
     78             update results.
     79         """
     80         expected_result = []
     81 
     82         if erased:
     83             board_id = 'ffffffff:ffffffff:ffffffff'
     84             # If the board id is erased, the device should update to the prod
     85             # image.
     86             ext = 'prod'
     87             expected_result.append('board ID is erased using prod image')
     88         else:
     89             board_id = '%08x:%08x:%08x' % (brand, brand ^ self.MAX_VAL, flags)
     90             ext = 'prepvt' if flags & 0x10 else 'prod'
     91 
     92         flag_str = board_id.rsplit(':', 1)[-1]
     93 
     94         expected_result.append("board_id: '%s' board_flags: '0x%s', extension: "
     95                 "'%s'" % (board_id, flag_str, ext))
     96         expected_result.append('hashing /opt/google/cr50/firmware/cr50.bin.%s' %
     97                 ext)
     98         return '(%s)' % '\n.*'.join(expected_result)
     99 
    100 
    101     def check_result(self, brand, flags, erased):
    102         """Verify the expected result string is found in the update messages
    103 
    104         Args:
    105             brand: The board id value to test.
    106             flags: The flag value to test.
    107             erased: True if the board id is erased
    108 
    109         Raises:
    110             TestFail if the expected result message did not match the update
    111             output
    112         """
    113         expected_result_re = self.get_expected_result_re(brand, flags, erased)
    114         result = self.get_result()
    115         match = re.search(expected_result_re, result)
    116 
    117         logging.debug('EXPECT: %s', expected_result_re)
    118         logging.debug('GOT: %s', result)
    119 
    120         if not match:
    121             raise error.TestFail('Unexpected result during update with %s' %
    122                     ('erased board id' if erased else '%x:%x' % (brand, flags)))
    123 
    124         logging.info('FOUND UPDATE RESULT:\n%s', match.groups()[0])
    125 
    126 
    127     def run_update(self, brand, flags, clear_bid=False):
    128         """Set the board id then run cr50-update
    129 
    130         Args:
    131             brand: The board id int to test.
    132             flags: The flag int to test.
    133             clear_bid: True if the board id should be erased and not reset.
    134         """
    135         # Set the board id
    136         self.erase_bid()
    137 
    138         if not clear_bid:
    139             self.cr50.send_command('bid 0x%x 0x%x' % (brand, flags))
    140 
    141         # Run the update script script
    142         self.host.run('start cr50-update')
    143 
    144         # Make sure cr50 used the right image.
    145         self.check_result(brand, flags, clear_bid)
    146 
    147 
    148     def run_once(self):
    149         """Verify cr50-get-name.sh"""
    150         # Test the MP flags
    151         self.run_update(self.TEST_BRAND, 0x7f00)
    152 
    153         # Test the pre-PVT flags
    154         self.run_update(self.TEST_BRAND, 0x7f10)
    155 
    156         # Erase the board id
    157         self.run_update(0, 0, clear_bid=True)
    158 
    159         # Make sure the script can tell the difference between an erased board
    160         # id and one set to 0xffffffff:0xffffffff.
    161         self.run_update(self.MAX_VAL, self.MAX_VAL)
    162