| import logging |
| |
| |
| BIG_CPUS = ['A15', 'A57', 'A72'] |
| |
| |
| class Platform(object): |
| |
| @property |
| def number_of_clusters(self): |
| return len(set(self.core_clusters)) |
| |
| def __init__(self, |
| name=None, |
| core_names=None, |
| core_clusters=None, |
| big_core=None, |
| model=None, |
| modules=None, |
| ): |
| self.name = name |
| self.core_names = core_names or [] |
| self.core_clusters = core_clusters or [] |
| self.big_core = big_core |
| self.little_core = None |
| self.model = model |
| self.modules = modules or [] |
| self.logger = logging.getLogger(self.name) |
| if not self.core_clusters and self.core_names: |
| self._set_core_clusters_from_core_names() |
| |
| def init_target_connection(self, target): |
| # May be ovewritten by subclasses to provide target-specific |
| # connection initialisation. |
| pass |
| |
| def update_from_target(self, target): |
| if not self.core_names: |
| self.core_names = target.cpuinfo.cpu_names |
| self._set_core_clusters_from_core_names() |
| if not self.big_core and self.number_of_clusters == 2: |
| self.big_core = self._identify_big_core() |
| if not self.core_clusters and self.core_names: |
| self._set_core_clusters_from_core_names() |
| if not self.model: |
| self._set_model_from_target(target) |
| if not self.name: |
| self.name = self.model |
| self._validate() |
| |
| def setup(self, target): |
| # May be overwritten by subclasses to provide platform-specific |
| # setup procedures. |
| pass |
| |
| def _set_core_clusters_from_core_names(self): |
| self.core_clusters = [] |
| clusters = [] |
| for cn in self.core_names: |
| if cn not in clusters: |
| clusters.append(cn) |
| self.core_clusters.append(clusters.index(cn)) |
| |
| def _set_model_from_target(self, target): |
| if target.os == 'android': |
| self.model = target.getprop('ro.product.model') |
| elif target.is_rooted: |
| try: |
| self.model = target.execute('dmidecode -s system-version', |
| as_root=True).strip() |
| except Exception: # pylint: disable=broad-except |
| pass # this is best-effort |
| |
| def _identify_big_core(self): |
| for core in self.core_names: |
| if core.upper() in BIG_CPUS: |
| return core |
| big_idx = self.core_clusters.index(max(self.core_clusters)) |
| return self.core_names[big_idx] |
| |
| def _validate(self): |
| if len(self.core_names) != len(self.core_clusters): |
| raise ValueError('core_names and core_clusters are of different lengths.') |
| if self.big_core and self.number_of_clusters != 2: |
| raise ValueError('attempting to set big_core on non-big.LITTLE device. ' |
| '(number of clusters is not 2)') |
| if self.big_core and self.big_core not in self.core_names: |
| message = 'Invalid big_core value "{}"; must be in [{}]' |
| raise ValueError(message.format(self.big_core, |
| ', '.join(set(self.core_names)))) |
| if self.big_core: |
| for core in self.core_names: |
| if core != self.big_core: |
| self.little_core = core |
| break |