Home | History | Annotate | Download | only in hardware_TPMTakeOwnership
      1 # Copyright (c) 2011 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 time
      7 
      8 from autotest_lib.client.bin import test
      9 from autotest_lib.client.common_lib import error, smogcheck_tpm, \
     10     smogcheck_ttci, smogcheck_util
     11 from autotest_lib.client.cros import service_stopper
     12 
     13 
     14 class hardware_TPMTakeOwnership(test.test):
     15     version = 1
     16 
     17 
     18     def initialize(self):
     19         smogcheck_util.enableI2C()
     20         self.ttci_obj = None
     21         self.tpm_obj = None
     22         self.attr_dict = dict()  # Attributes to output
     23         self.perf_dict = dict()  # Performance measures to output
     24         self._services = service_stopper.ServiceStopper(['cryptohomed',
     25                                                          'chapsd', 'tcsd'])
     26         self._services.stop_services()
     27 
     28 
     29     def _prepareTpmController(self):
     30         """Prepare a TpmController instance for use.
     31 
     32         Returns:
     33           an operational TpmControler instance, ready to use.
     34 
     35         Raises:
     36           TestFail: if error creating a new TpmController instance.
     37         """
     38         try:
     39             self.tpm_obj = smogcheck_tpm.TpmController()
     40         except smogcheck_tpm.SmogcheckError as e:
     41             raise error.TestFail('Error creating a TpmController: %s', e)
     42 
     43 
     44     def _prepareTtciController(self):
     45         """Prepare TtciController instances for use.
     46 
     47         Returns:
     48           an operational TtciController instance, ready to use.
     49 
     50         Raises:
     51           TestFail: if error creating a new TtciController instance.
     52         """
     53         try:
     54             self.ttci_obj = smogcheck_ttci.TtciController()
     55         except smogcheck_ttci.TtciError as e:
     56             raise error.TestFail('Error creating a TtciController: %s' % e)
     57 
     58 
     59     def _sleep(self, amount):
     60         """Sleeps for 'amount' of time and logs a message.
     61 
     62         Args:
     63           amount: an integer or float in seconds.
     64         """
     65         time.sleep(amount)
     66         if amount >= 1:
     67             logging.debug('Slept for %0.2f second', amount)
     68         elif amount >= 0.001:
     69             logging.debug('Slept for %0.2f millisecond', (amount * 1000))
     70         else:
     71             logging.debug('Slept for %0.2f microsecond', (amount * 1000000))
     72 
     73 
     74     def run_once(self, loop=-1, max_acceptable_delay=-1):
     75         self._prepareTtciController()
     76         self._prepareTpmController()
     77 
     78         timestamps = dict()
     79         time_list = []
     80         try:
     81             # Verify TPM is operational before triggering hardware Reset
     82             self.tpm_obj.runTpmSelfTest()
     83 
     84             # Activate hardware Reset signal
     85             if self.ttci_obj.TTCI_Set_Reset_Control(turn_on=True):
     86                 raise error.TestFail('TTCI_Set_Reset_Control() error: %s' %
     87                                      self.ttci_obj.err)
     88             logging.info('TPM hardware Reset signal activated')
     89 
     90             # Wait for 100 milisec
     91             self._sleep(0.1)
     92 
     93             # Deactivate hardware Reset signal
     94             if self.ttci_obj.TTCI_Set_Reset_Control(turn_on=False):
     95                 raise error.TestFail('TTCI_Set_Reset_Control() error: %s' %
     96                                      self.ttci_obj.err)
     97             logging.info('TPM hardware Reset signal DEactivated')
     98 
     99             # Run TPM_Starup
    100             smogcheck_util.runInSubprocess(['tpmc', 'startup'])
    101 
    102             # Run TPM_SelfTestFull
    103             smogcheck_util.runInSubprocess(['tpmc', 'test'])
    104 
    105             # Run TPM_AssertPhysicalPresence
    106             smogcheck_util.runInSubprocess(['tpmc', 'ppon'])
    107 
    108             # Run TPM_OwnerClear
    109             smogcheck_util.runInSubprocess(['tpmc', 'clear'])
    110 
    111             for i in range(loop):
    112                 smogcheck_util.runInSubprocess(['start', 'tcsd'])
    113                 # Wait 3 sec for tcsd to start
    114                 self._sleep(3)
    115 
    116                 # Run TPM_TakeOwnership and record elapsed time
    117                 timestamps[i] = self.tpm_obj.takeTpmOwnership()
    118 
    119                 smogcheck_util.runInSubprocess(['stop', 'tcsd'])
    120                 # Wait for 1 sec for tcsd to stop
    121                 self._sleep(1)
    122 
    123                 # Run TPM_OwnerClear
    124                 smogcheck_util.runInSubprocess(['tpmc', 'clear'])
    125 
    126             # Output timing measurements
    127             for k, v in timestamps.iteritems():
    128                 sec, ms = divmod(v/1000, 1000)
    129                 key = 'iteration_%d_delay_in_sec' % k
    130                 delay_float = float(v)/1000000
    131                 self.perf_dict[key] = delay_float
    132                 time_list.append(delay_float)
    133             self.perf_dict['num_total_iterations'] = len(timestamps)
    134             # TODO(tgao): modify generate_test_report to support attr_dict
    135             #self.attr_dict['timing_measurement_for'] = 'TPM_TakeOwnership'
    136             time_list.sort()
    137             time_list.reverse()
    138             count = 0
    139             for i in time_list:
    140                 if i <= max_acceptable_delay:
    141                     break
    142                 logging.debug('Actual value (%0.2f) exceeds max (%0.2f)',
    143                               i, max_acceptable_delay)
    144                 count += 1
    145             self.perf_dict['num_iterations_exceeding_max_delay'] = count
    146             self.perf_dict['max_acceptable_delay_in_sec'] = max_acceptable_delay
    147             self.perf_dict['min_delay_in_sec_actual'] = time_list[-1]
    148             # Set this attribute last. If it exceeds user-specified limit in
    149             # test suite control file, output report would still be complete
    150             self.perf_dict['max_delay_in_sec_actual'] = time_list[0]
    151 
    152         except smogcheck_tpm.SmogcheckError as e:
    153             raise error.TestFail('Error: %r' % e)
    154         finally:
    155             # Output attibutes and performance keyval pairs
    156             self.write_iteration_keyval(self.attr_dict, self.perf_dict)
    157 
    158             # Close TPM context
    159             if self.tpm_obj.closeContext():
    160                 raise error.TestFail('Error closing tspi context')
    161 
    162 
    163     def cleanup(self):
    164         self._services.restore_services()
    165