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 5import logging 6import time 7 8from autotest_lib.client.bin import test 9from autotest_lib.client.common_lib import error, smogcheck_tpm, \ 10 smogcheck_ttci, smogcheck_util 11from autotest_lib.client.cros import service_stopper 12 13 14class 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