1
0
mirror of https://github.com/ARM-software/workload-automation.git synced 2024-10-06 10:51:13 +01:00
workload-automation/wa/framework/target/info.py
Sergei Trofimov ce94638436 fw/target: record page size as part of TargetInfo
Record target.page_size_kb as part of target info.
2018-11-02 12:11:00 +00:00

344 lines
11 KiB
Python

# Copyright 2018 ARM Limited
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# pylint: disable=protected-access
import os
from copy import copy
from devlib import AndroidTarget, TargetError
from devlib.target import KernelConfig, KernelVersion, Cpuinfo
from devlib.utils.android import AndroidProperties
from wa.framework.configuration.core import settings
from wa.framework.exception import ConfigError
from wa.utils.serializer import read_pod, write_pod
def cpuinfo_from_pod(pod):
cpuinfo = Cpuinfo('')
cpuinfo.sections = pod['cpuinfo']
lines = []
for section in cpuinfo.sections:
for key, value in section.items():
line = '{}: {}'.format(key, value)
lines.append(line)
lines.append('')
cpuinfo.text = '\n'.join(lines)
return cpuinfo
def kernel_version_from_pod(pod):
release_string = pod['kernel_release']
version_string = pod['kernel_version']
if release_string:
if version_string:
kernel_string = '{} #{}'.format(release_string, version_string)
else:
kernel_string = release_string
else:
kernel_string = '#{}'.format(version_string)
return KernelVersion(kernel_string)
def kernel_config_from_pod(pod):
config = KernelConfig('')
config._config = pod['kernel_config']
lines = []
for key, value in config._config.items():
if value == 'n':
lines.append('# {} is not set'.format(key))
else:
lines.append('{}={}'.format(key, value))
config.text = '\n'.join(lines)
return config
class CpufreqInfo(object):
@staticmethod
def from_pod(pod):
return CpufreqInfo(**pod)
def __init__(self, **kwargs):
self.available_frequencies = kwargs.pop('available_frequencies', [])
self.available_governors = kwargs.pop('available_governors', [])
self.related_cpus = kwargs.pop('related_cpus', [])
self.driver = kwargs.pop('driver', None)
def to_pod(self):
return copy(self.__dict__)
def __repr__(self):
return 'Cpufreq({} {})'.format(self.driver, self.related_cpus)
__str__ = __repr__
class IdleStateInfo(object):
@staticmethod
def from_pod(pod):
return IdleStateInfo(**pod)
def __init__(self, **kwargs):
self.name = kwargs.pop('name', None)
self.desc = kwargs.pop('desc', None)
self.power = kwargs.pop('power', None)
self.latency = kwargs.pop('latency', None)
def to_pod(self):
return copy(self.__dict__)
def __repr__(self):
return 'IdleState({}/{})'.format(self.name, self.desc)
__str__ = __repr__
class CpuidleInfo(object):
@staticmethod
def from_pod(pod):
instance = CpuidleInfo()
instance.governor = pod['governor']
instance.driver = pod['driver']
instance.states = [IdleStateInfo.from_pod(s) for s in pod['states']]
return instance
@property
def num_states(self):
return len(self.states)
def __init__(self):
self.governor = None
self.driver = None
self.states = []
def to_pod(self):
pod = {}
pod['governor'] = self.governor
pod['driver'] = self.driver
pod['states'] = [s.to_pod() for s in self.states]
return pod
def __repr__(self):
return 'Cpuidle({}/{} {} states)'.format(
self.governor, self.driver, self.num_states)
__str__ = __repr__
class CpuInfo(object):
@staticmethod
def from_pod(pod):
instance = CpuInfo()
instance.id = pod['id']
instance.name = pod['name']
instance.architecture = pod['architecture']
instance.features = pod['features']
instance.cpufreq = CpufreqInfo.from_pod(pod['cpufreq'])
instance.cpuidle = CpuidleInfo.from_pod(pod['cpuidle'])
return instance
def __init__(self):
self.id = None
self.name = None
self.architecture = None
self.features = []
self.cpufreq = CpufreqInfo()
self.cpuidle = CpuidleInfo()
def to_pod(self):
pod = {}
pod['id'] = self.id
pod['name'] = self.name
pod['architecture'] = self.architecture
pod['features'] = self.features
pod['cpufreq'] = self.cpufreq.to_pod()
pod['cpuidle'] = self.cpuidle.to_pod()
return pod
def __repr__(self):
return 'Cpu({} {})'.format(self.id, self.name)
__str__ = __repr__
def get_target_info(target):
info = TargetInfo()
info.target = target.__class__.__name__
info.os = target.os
info.os_version = target.os_version
info.system_id = target.system_id
info.abi = target.abi
info.is_rooted = target.is_rooted
info.kernel_version = target.kernel_version
info.kernel_config = target.config
try:
info.sched_features = target.read_value('/sys/kernel/debug/sched_features').split()
except TargetError:
# best effort -- debugfs might not be mounted
pass
hostid_string = target.execute('{} hostid'.format(target.busybox)).strip()
info.hostid = int(hostid_string, 16)
info.hostname = target.execute('{} hostname'.format(target.busybox)).strip()
for i, name in enumerate(target.cpuinfo.cpu_names):
cpu = CpuInfo()
cpu.id = i
cpu.name = name
cpu.features = target.cpuinfo.get_cpu_features(i)
cpu.architecture = target.cpuinfo.architecture
if target.has('cpufreq'):
cpu.cpufreq.available_governors = target.cpufreq.list_governors(i)
cpu.cpufreq.available_frequencies = target.cpufreq.list_frequencies(i)
cpu.cpufreq.related_cpus = target.cpufreq.get_related_cpus(i)
cpu.cpufreq.driver = target.cpufreq.get_driver(i)
if target.has('cpuidle'):
cpu.cpuidle.driver = target.cpuidle.get_driver()
cpu.cpuidle.governor = target.cpuidle.get_governor()
for state in target.cpuidle.get_states(i):
state_info = IdleStateInfo()
state_info.name = state.name
state_info.desc = state.desc
state_info.power = state.power
state_info.latency = state.latency
cpu.cpuidle.states.append(state_info)
info.cpus.append(cpu)
info.page_size_kb = target.page_size_kb
if isinstance(target, AndroidTarget):
info.screen_resolution = target.screen_resolution
info.prop = target.getprop()
info.android_id = target.android_id
return info
def read_target_info_cache():
if not os.path.exists(settings.cache_directory):
os.makedirs(settings.cache_directory)
if not os.path.isfile(settings.target_info_cache_file):
return {}
return read_pod(settings.target_info_cache_file)
def write_target_info_cache(cache):
if not os.path.exists(settings.cache_directory):
os.makedirs(settings.cache_directory)
write_pod(cache, settings.target_info_cache_file)
def get_target_info_from_cache(system_id):
cache = read_target_info_cache()
pod = cache.get(system_id, None)
if not pod:
return None
pod_version = pod.get('format_version', 0)
if pod_version != TargetInfo.format_version:
msg = 'Target info version mismatch. Expected {}, but found {}.\nTry deleting {}'
raise ConfigError(msg.format(TargetInfo.format_version, pod_version,
settings.target_info_cache_file))
return TargetInfo.from_pod(pod)
def cache_target_info(target_info, overwrite=False):
cache = read_target_info_cache()
if target_info.system_id in cache and not overwrite:
raise ValueError('TargetInfo for {} is already in cache.'.format(target_info.system_id))
cache[target_info.system_id] = target_info.to_pod()
write_target_info_cache(cache)
class TargetInfo(object):
format_version = 2
@staticmethod
def from_pod(pod):
instance = TargetInfo()
instance.target = pod['target']
instance.abi = pod['abi']
instance.cpus = [CpuInfo.from_pod(c) for c in pod['cpus']]
instance.os = pod['os']
instance.os_version = pod['os_version']
instance.system_id = pod['system_id']
instance.hostid = pod['hostid']
instance.hostname = pod['hostname']
instance.abi = pod['abi']
instance.is_rooted = pod['is_rooted']
instance.kernel_version = kernel_version_from_pod(pod)
instance.kernel_config = kernel_config_from_pod(pod)
instance.sched_features = pod['sched_features']
instance.page_size_kb = pod.get('page_size_kb')
if instance.os == 'android':
instance.screen_resolution = pod['screen_resolution']
instance.prop = AndroidProperties('')
instance.prop._properties = pod['prop']
instance.android_id = pod['android_id']
return instance
def __init__(self):
self.target = None
self.cpus = []
self.os = None
self.os_version = None
self.system_id = None
self.hostid = None
self.hostname = None
self.abi = None
self.is_rooted = None
self.kernel_version = None
self.kernel_config = None
self.sched_features = None
self.screen_resolution = None
self.prop = None
self.android_id = None
self.page_size_kb = None
def to_pod(self):
pod = {}
pod['format_version'] = self.format_version
pod['target'] = self.target
pod['abi'] = self.abi
pod['cpus'] = [c.to_pod() for c in self.cpus]
pod['os'] = self.os
pod['os_version'] = self.os_version
pod['system_id'] = self.system_id
pod['hostid'] = self.hostid
pod['hostname'] = self.hostname
pod['abi'] = self.abi
pod['is_rooted'] = self.is_rooted
pod['kernel_release'] = self.kernel_version.release
pod['kernel_version'] = self.kernel_version.version
pod['kernel_config'] = dict(self.kernel_config.iteritems())
pod['sched_features'] = self.sched_features
pod['page_size_kb'] = self.page_size_kb
if self.os == 'android':
pod['screen_resolution'] = self.screen_resolution
pod['prop'] = self.prop._properties
pod['android_id'] = self.android_id
return pod