1import logging 2 3 4BIG_CPUS = ['A15', 'A57', 'A72'] 5 6 7class Platform(object): 8 9 @property 10 def number_of_clusters(self): 11 return len(set(self.core_clusters)) 12 13 def __init__(self, 14 name=None, 15 core_names=None, 16 core_clusters=None, 17 big_core=None, 18 model=None, 19 modules=None, 20 ): 21 self.name = name 22 self.core_names = core_names or [] 23 self.core_clusters = core_clusters or [] 24 self.big_core = big_core 25 self.little_core = None 26 self.model = model 27 self.modules = modules or [] 28 self.logger = logging.getLogger(self.name) 29 if not self.core_clusters and self.core_names: 30 self._set_core_clusters_from_core_names() 31 32 def init_target_connection(self, target): 33 # May be ovewritten by subclasses to provide target-specific 34 # connection initialisation. 35 pass 36 37 def update_from_target(self, target): 38 if not self.core_names: 39 self.core_names = target.cpuinfo.cpu_names 40 self._set_core_clusters_from_core_names() 41 if not self.big_core and self.number_of_clusters == 2: 42 self.big_core = self._identify_big_core() 43 if not self.core_clusters and self.core_names: 44 self._set_core_clusters_from_core_names() 45 if not self.model: 46 self._set_model_from_target(target) 47 if not self.name: 48 self.name = self.model 49 self._validate() 50 51 def setup(self, target): 52 # May be overwritten by subclasses to provide platform-specific 53 # setup procedures. 54 pass 55 56 def _set_core_clusters_from_core_names(self): 57 self.core_clusters = [] 58 clusters = [] 59 for cn in self.core_names: 60 if cn not in clusters: 61 clusters.append(cn) 62 self.core_clusters.append(clusters.index(cn)) 63 64 def _set_model_from_target(self, target): 65 if target.os == 'android': 66 self.model = target.getprop('ro.product.model') 67 elif target.is_rooted: 68 try: 69 self.model = target.execute('dmidecode -s system-version', 70 as_root=True).strip() 71 except Exception: # pylint: disable=broad-except 72 pass # this is best-effort 73 74 def _identify_big_core(self): 75 for core in self.core_names: 76 if core.upper() in BIG_CPUS: 77 return core 78 big_idx = self.core_clusters.index(max(self.core_clusters)) 79 return self.core_names[big_idx] 80 81 def _validate(self): 82 if len(self.core_names) != len(self.core_clusters): 83 raise ValueError('core_names and core_clusters are of different lengths.') 84 if self.big_core and self.number_of_clusters != 2: 85 raise ValueError('attempting to set big_core on non-big.LITTLE device. ' 86 '(number of clusters is not 2)') 87 if self.big_core and self.big_core not in self.core_names: 88 message = 'Invalid big_core value "{}"; must be in [{}]' 89 raise ValueError(message.format(self.big_core, 90 ', '.join(set(self.core_names)))) 91 if self.big_core: 92 for core in self.core_names: 93 if core != self.big_core: 94 self.little_core = core 95 break 96